Compare commits
	
		
			2 Commits 
		
	
	
		
			9c6f74c14f
			...
			2fffad3c60
		
	
	| Author | SHA1 | Date | 
|---|---|---|
|  | 2fffad3c60 | |
|  | 79aec147e3 | 
|  | @ -85,7 +85,7 @@ const PlayerSchema = new Schema({ | |||
|   performance: { | ||||
|     type: mongoose.Schema.Types.ObjectId, | ||||
|     ref: 'LogServerFpsSchema', | ||||
|     required: true, | ||||
|     required: false, | ||||
|   }, | ||||
| }, { | ||||
|   collection: 'player', | ||||
|  |  | |||
|  | @ -74,16 +74,27 @@ wars.route('/') | |||
|               if (err) { | ||||
|                 return next(err); | ||||
|               } | ||||
|               LogKillModel.create(statsResult.kills, () => { | ||||
|                 LogVehicleKillModel.create(statsResult.vehicles, () => { | ||||
|                   LogRespawnModel.create(statsResult.respawn, () => { | ||||
|                     LogReviveModel.create(statsResult.revive, () => { | ||||
|                       LogFlagModel.create(statsResult.flag, () => { | ||||
|                         LogBudgetModel.create(statsResult.budget, () => { | ||||
|                           LogTransportModel.create(statsResult.transport, () => { | ||||
|                             LogPlayerCountModel.create(statsResult.playerCount, () => { | ||||
|                               LogPointsModel.create(statsResult.points, () => { | ||||
|               LogKillModel.create(statsResult.kills, (err) => { | ||||
|                 if (err) console.log(err); | ||||
|                 LogVehicleKillModel.create(statsResult.vehicles, (err) => { | ||||
|                   if (err) console.log(err); | ||||
|                   LogRespawnModel.create(statsResult.respawn, (err) => { | ||||
|                     if (err) console.log(err); | ||||
|                     LogReviveModel.create(statsResult.revive, (err) => { | ||||
|                       if (err) console.log(err); | ||||
|                       LogFlagModel.create(statsResult.flag, (err) => { | ||||
|                         if (err) console.log(err); | ||||
|                         LogBudgetModel.create(statsResult.budget, (err) => { | ||||
|                           if (err) console.log(err); | ||||
|                           LogTransportModel.create(statsResult.transport, (err) => { | ||||
|                             if (err) console.log(err); | ||||
|                             LogPlayerCountModel.create(statsResult.playerCount, (err) => { | ||||
|                               if (err) console.log(err); | ||||
|                               LogPointsModel.create(statsResult.points, (err) => { | ||||
|                                 if (err) console.log(err); | ||||
|                                 LogServerFpsModel.create(statsResult.serverFps, (err, serverPerformanceEntries) => { | ||||
|                                   if (err) console.log(err); | ||||
|                                   if (serverPerformanceEntries) { | ||||
|                                     serverPerformanceEntries.forEach((entry) => { | ||||
|                                       const idx = statsResult.players | ||||
|                                                              .findIndex((player) => player.name === entry.entityName); | ||||
|  | @ -93,6 +104,7 @@ wars.route('/') | |||
|                                         statsResult.players[idx] = player; | ||||
|                                       } | ||||
|                                     }); | ||||
|                                   } | ||||
|                                   PlayerModel.create(statsResult.players, (err) => { | ||||
|                                     if (err) { | ||||
|                                       return next(err); | ||||
|  |  | |||
|  | @ -127,6 +127,7 @@ const parseWarLog = (lineArray, war) => { | |||
|         const kill = { | ||||
|           war: war._id, | ||||
|           time: getFullTimeDate(war.date, line.split(WHITESPACE)[5]), | ||||
|           friendlyFire: false, | ||||
|         }; | ||||
|         if (shooter) { | ||||
|           kill.shooter = shooter.name; | ||||
|  |  | |||
|  | @ -9,9 +9,10 @@ | |||
|     </mat-button-toggle> | ||||
|   </mat-button-toggle-group> | ||||
| 
 | ||||
|   <div class="chart-container"> | ||||
|   <div class="chart-container" *ngIf="showBarChart"> | ||||
|     <ngx-charts-bar-vertical | ||||
|       [results]="barChartData" | ||||
|       [scheme]="colorScheme" | ||||
|       [gradient]="gradient" | ||||
|       [xAxis]="xAxis" | ||||
|       [yAxis]="yAxis" | ||||
|  | @ -25,20 +26,21 @@ | |||
|     </ngx-charts-bar-vertical> | ||||
|   </div> | ||||
| 
 | ||||
|   <!--<div class="chart-container">--> | ||||
|     <!--<ngx-charts-line-chart--> | ||||
|       <!--[results]="barChartData"--> | ||||
|       <!--[gradient]="gradient"--> | ||||
|       <!--[xAxis]="xAxis"--> | ||||
|       <!--[yAxis]="yAxis"--> | ||||
|       <!--[legend]="legend"--> | ||||
|       <!--[legendTitle]="legendTitle"--> | ||||
|       <!--[showXAxisLabel]="showXAxisLabel"--> | ||||
|       <!--[showYAxisLabel]="showYAxisLabel"--> | ||||
|       <!--[yAxisLabel]="barChartLabel"--> | ||||
|       <!--[autoScale]="autoscale"--> | ||||
|       <!--[timeline]="timeline"--> | ||||
|       <!--[roundDomains]="roundDomains">--> | ||||
|     <!--</ngx-charts-line-chart>--> | ||||
|   <!--</div>--> | ||||
|   <div class="chart-container" *ngIf="!showBarChart"> | ||||
|     <ngx-charts-line-chart | ||||
|       [results]="lineChartData" | ||||
|       [scheme]="colorScheme" | ||||
|       [gradient]="gradient" | ||||
|       [xAxis]="xAxis" | ||||
|       [yAxis]="yAxis" | ||||
|       [legend]="legend" | ||||
|       [legendTitle]="legendTitle" | ||||
|       [showXAxisLabel]="showXAxisLabel" | ||||
|       [showYAxisLabel]="showYAxisLabel" | ||||
|       [yAxisLabel]="lineChartLabel" | ||||
|       [autoScale]="autoscale" | ||||
|       [timeline]="timeline" | ||||
|       [roundDomains]="roundDomains"> | ||||
|     </ngx-charts-line-chart> | ||||
|   </div> | ||||
| </div> | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| import {Component, ElementRef, Input, OnChanges, OnInit, SimpleChanges, ViewChild} from '@angular/core'; | ||||
| import {War} from '../../../models/model-interfaces'; | ||||
| import {TranslateService} from '@ngx-translate/core'; | ||||
| import {ChartUtils} from '../../../utils/chart-utils'; | ||||
| 
 | ||||
| 
 | ||||
| @Component({ | ||||
|  | @ -20,11 +21,9 @@ export class ServerStatsComponent implements OnInit, OnChanges { | |||
| 
 | ||||
|   public activeChartSelect: string; | ||||
| 
 | ||||
|   barChartData: any[] = []; | ||||
| 
 | ||||
|   lineChartData: any[] = []; | ||||
| 
 | ||||
|   showBarChart = true; | ||||
|   barChartData: any[] = []; | ||||
|   lineChartData: any[] = []; | ||||
| 
 | ||||
|   tmpSingleAvg; | ||||
|   tmpSingleMin; | ||||
|  | @ -32,6 +31,8 @@ export class ServerStatsComponent implements OnInit, OnChanges { | |||
|   tmpMinTimeline; | ||||
|   tmpServerTimeline; | ||||
| 
 | ||||
|   barChartLabel: string; | ||||
|   lineChartLabel: string; | ||||
|   readonly labels = { | ||||
|     singleAvg: 'stats.performance.select.single.avg', | ||||
|     singleMin: 'stats.performance.select.single.min', | ||||
|  | @ -42,9 +43,6 @@ export class ServerStatsComponent implements OnInit, OnChanges { | |||
|   readonly labelsAsString = Object.keys(this.labels) | ||||
|                                   .map((key) => this.labels[key]); | ||||
| 
 | ||||
|   barChartLabel: string; | ||||
|   lineChartLabel: string; | ||||
| 
 | ||||
|   gradient = false; | ||||
|   yAxis = true; | ||||
|   xAxis = true; | ||||
|  | @ -55,6 +53,15 @@ export class ServerStatsComponent implements OnInit, OnChanges { | |||
|   autoscale = true; | ||||
|   timeline = false; | ||||
|   roundDomains = true; | ||||
|   colorScheme =  { | ||||
|     name: 'nightLights', | ||||
|     selectable: false, | ||||
|     group: 'Ordinal', | ||||
|     domain: [ | ||||
|       '#4e31a5', '#9c25a7', '#3065ab', '#57468b', '#904497', '#46648b', | ||||
|       '#32118d', '#a00fb3', '#1052a2', '#6e51bd', '#b63cc3', '#6c97cb', '#8671c1', '#b455be', '#7496c3' | ||||
|     ] | ||||
|   }; | ||||
| 
 | ||||
|   constructor(private translate: TranslateService) { | ||||
|   } | ||||
|  | @ -64,19 +71,16 @@ export class ServerStatsComponent implements OnInit, OnChanges { | |||
|   } | ||||
| 
 | ||||
|   ngOnChanges(changes: SimpleChanges) { | ||||
|     if (changes.war || changes.performanceData) { | ||||
|     if ((changes.war || changes.performanceData) && this.performanceData) { | ||||
|       this.initializeChartData(); | ||||
|       Object.assign(this, [this.barChartData]); | ||||
|       this.activeChartSelect = this.labels.singleAvg; | ||||
|       this.startDateObj = new Date(this.war.date); | ||||
|       this.startDateObj.setHours(0); | ||||
|       this.startDateObj.setMinutes(1); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   selectChart(newSelection) { | ||||
|     this.activeChartSelect = newSelection; | ||||
|     if (this.activeChartSelect !== this.labels.serverFps) { | ||||
|     if (this.activeChartSelect === this.labels.singleAvg || this.activeChartSelect === this.labels.singleMin) { | ||||
|       this.showBarChart = true; | ||||
|       this.setBarChartLabel(this.activeChartSelect); | ||||
|       switch (this.activeChartSelect) { | ||||
|  | @ -104,9 +108,52 @@ export class ServerStatsComponent implements OnInit, OnChanges { | |||
|   } | ||||
| 
 | ||||
|   initializeChartData() { | ||||
|     this.tmpAvgTimeline = ChartUtils.getMultiDataArray('min', 'avg', 'max'); | ||||
|     this.tmpMinTimeline = ChartUtils.getMultiDataArray('min', 'avg', 'max'); | ||||
|     this.tmpServerTimeline = ChartUtils.getMultiDataArray('min', 'avg'); | ||||
| 
 | ||||
|     const diffMs = (new Date(this.war.endDate).getTime() - new Date(this.war.date).getTime()); | ||||
|     const warDurationMinutes = Math.round(diffMs / 60000); | ||||
| 
 | ||||
|     const dateObj = new Date(this.war.date); | ||||
|     dateObj.setHours(0); | ||||
|     dateObj.setMinutes(1); | ||||
| 
 | ||||
|     this.tmpSingleAvg = []; | ||||
|     this.tmpSingleMin = []; | ||||
|     const maxAvgIdx = Math.min(this.performanceData.map(p => p.avgFps.length) | ||||
|                                    .sort((a, b) => b - a)[0], warDurationMinutes); | ||||
|     const maxMinIdx = Math.min(this.performanceData.map(p => p.avgFps.length) | ||||
|                                    .sort((a, b) => b - a)[0], warDurationMinutes); | ||||
|     let tmpAvgArray = new Array(maxAvgIdx).fill(0); | ||||
|     const tmpAvgMin = new Array(maxAvgIdx).fill(1000); | ||||
|     const tmpAvgMax = new Array(maxAvgIdx).fill(0); | ||||
|     let tmpMinArray = new Array(maxMinIdx).fill(0); | ||||
|     const tmpMinMin = new Array(maxMinIdx).fill(1000); | ||||
|     const tmpMinMax = new Array(maxMinIdx).fill(0); | ||||
| 
 | ||||
|     this.performanceData.forEach((entry) => { | ||||
|       if (entry.entityName !== 'SERVER') { | ||||
|         // PLAYER AVERAGE TIMELINE DATA
 | ||||
|         for (let i = 0; i < entry.avgFps.length && i < tmpAvgArray.length; i++) { | ||||
|           tmpAvgArray[i] = tmpAvgArray[i] + entry.avgFps[i]; | ||||
|           tmpAvgMin[i] = Math.round(Math.min(tmpAvgMin[i], entry.avgFps[i])); | ||||
|           tmpAvgMax[i] = Math.round(Math.max(tmpAvgMax[i], entry.avgFps[i])); | ||||
|         } | ||||
|         // PLAYER MINIMUM TIMELINE DATA
 | ||||
|         for (let i = 0; i < entry.minFps.length && i < tmpMinArray.length; i++) { | ||||
|           tmpMinArray[i] = tmpMinArray[i] + entry.minFps[i]; | ||||
|           tmpMinMin[i] = Math.round(Math.min(tmpMinMin[i], entry.minFps[i])); | ||||
|           tmpMinMax[i] = Math.round(Math.max(tmpMinMax[i], entry.minFps[i])); | ||||
|         } | ||||
|       } else { | ||||
|         // SERVER TIMELINE DATA
 | ||||
|         for (let i = 0; i < entry.avgFps.length && i < warDurationMinutes; i++) { | ||||
|           const currDate = new Date(dateObj.getTime() + i * 60000); | ||||
|           this.tmpServerTimeline[0].series.push(ChartUtils.getSeriesEntry(currDate, entry.minFps[i])); | ||||
|           this.tmpServerTimeline[1].series.push(ChartUtils.getSeriesEntry(currDate, entry.avgFps[i])); | ||||
|         } | ||||
|       } | ||||
|       this.tmpSingleAvg.push({ | ||||
|         name: entry.entityName, | ||||
|         value: entry.singleAvgFps | ||||
|  | @ -116,6 +163,21 @@ export class ServerStatsComponent implements OnInit, OnChanges { | |||
|         value: entry.singleMinFps | ||||
|       }); | ||||
|     }); | ||||
| 
 | ||||
|     tmpAvgArray = tmpAvgArray.map(x => Math.round(x / this.performanceData.length)); | ||||
|     for (let i = 0; i < tmpAvgArray.length; i++) { | ||||
|       const currDate = new Date(dateObj.getTime() + i * 60000); | ||||
|       this.tmpAvgTimeline[0].series.push(ChartUtils.getSeriesEntry(currDate, tmpAvgMin[i])); | ||||
|       this.tmpAvgTimeline[1].series.push(ChartUtils.getSeriesEntry(currDate, tmpAvgArray[i])); | ||||
|       this.tmpAvgTimeline[2].series.push(ChartUtils.getSeriesEntry(currDate, tmpAvgMax[i])); | ||||
|     } | ||||
|     tmpMinArray = tmpMinArray.map(x => Math.round(x / this.performanceData.length)); | ||||
|     for (let i = 0; i < tmpMinArray.length; i++) { | ||||
|       const currDate = new Date(dateObj.getTime() + i * 60000); | ||||
|       this.tmpMinTimeline[0].series.push(ChartUtils.getSeriesEntry(currDate, tmpMinMin[i])); | ||||
|       this.tmpMinTimeline[1].series.push(ChartUtils.getSeriesEntry(currDate, tmpMinArray[i])); | ||||
|       this.tmpMinTimeline[2].series.push(ChartUtils.getSeriesEntry(currDate, tmpMinMax[i])); | ||||
|     } | ||||
|     this.tmpSingleAvg.sort((a, b) => a.value - b.value); | ||||
|     this.tmpSingleMin.sort((a, b) => a.value - b.value); | ||||
|     this.barChartData = this.tmpSingleAvg; | ||||
|  |  | |||
|  | @ -48,7 +48,8 @@ | |||
|         {{'stats.scoreboard.tab.player' | translate}} | ||||
|       </a> | ||||
|     </li> | ||||
|     <li class="nav-item" [ngClass]="{active :tab === 3}" (click)="switchTab(3)" *ngIf="war && war.players[0].performance"> | ||||
|     <li class="nav-item" [ngClass]="{active :tab === 3}" (click)="switchTab(3)" | ||||
|         *ngIf="war && war.players && war.players[0] &&  war.players[0].performance"> | ||||
|     <a class="nav-link"> | ||||
|         <mat-icon svgIcon="stats-performance" class="mat-icon-stats-performance"></mat-icon> | ||||
|         {{'stats.scoreboard.tab.performance' | translate}} | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue