Use stacked bar chart for flag capture visualization (CC-72)
							parent
							
								
									20321def38
								
							
						
					
					
						commit
						90510eac93
					
				|  | @ -28,20 +28,25 @@ | ||||||
|   </div> |   </div> | ||||||
| 
 | 
 | ||||||
|   <div *ngIf="!showLineChart" class="chart-container"> |   <div *ngIf="!showLineChart" class="chart-container"> | ||||||
|     <ngx-charts-area-chart |     <ngx-charts-bar-vertical-stacked | ||||||
|       [scheme]="colorScheme" |       [scheme]="colorScheme" | ||||||
|       [results]="areaChartData" |       [results]="barChartData" | ||||||
|       [xAxis]="xAxis" |       [xAxis]="xAxis" | ||||||
|       [yAxis]="yAxis" |       [yAxis]="barShowYAxis" | ||||||
|       [curve]="stepCurve" |  | ||||||
|       [legend]="legend" |       [legend]="legend" | ||||||
|       [legendTitle]="legendTitle" |       [legendTitle]="legendTitle" | ||||||
|       [showXAxisLabel]="showXAxisLabel" |       [showXAxisLabel]="barShowXAxisLabel" | ||||||
|       [showYAxisLabel]="showYAxisLabel" |       [showYAxisLabel]="showYAxisLabel" | ||||||
|       [yAxisLabel]="labelFlag" |       [animations]="barAnimations" | ||||||
|       [autoScale]="autoscale" |       [barPadding]="barPadding" | ||||||
|       [timeline]="timeline" |       [xAxisTickFormatting]="axisFormat" | ||||||
|       [roundDomains]="false"> |       [xAxisLabel]="'Minute'"> | ||||||
|     </ngx-charts-area-chart> |       <ng-template #tooltipTemplate let-model="model"> | ||||||
|  |         <small>{{'stats.fraction.tooltip.flag.minute' | translate}} {{model.series}}</small> | ||||||
|  |         <div>{{model.name}} {{'stats.fraction.tooltip.flag.flag' | translate}}</div> | ||||||
|  |         <div *ngIf="model.value === 0">{{'stats.fraction.tooltip.flag.lost' | translate}}</div> | ||||||
|  |         <div *ngIf="model.value !== 0">{{'stats.fraction.tooltip.flag.safe' | translate}}</div> | ||||||
|  |       </ng-template> | ||||||
|  |     </ngx-charts-bar-vertical-stacked> | ||||||
|   </div> |   </div> | ||||||
| </div> | </div> | ||||||
|  |  | ||||||
|  | @ -9,7 +9,7 @@ import {TranslateService} from '@ngx-translate/core'; | ||||||
| @Component({ | @Component({ | ||||||
|   selector: 'war-detail-fraction', |   selector: 'war-detail-fraction', | ||||||
|   templateUrl: './fraction-stats.component.html', |   templateUrl: './fraction-stats.component.html', | ||||||
|   styleUrls: ['./fraction-stats.component.css', '../../../style/list-entry.css', '../../../style/hide-scrollbar.css'] |   styleUrls: ['./fraction-stats.component.scss', '../../../style/list-entry.css', '../../../style/hide-scrollbar.css'] | ||||||
| }) | }) | ||||||
| export class FractionStatsComponent implements OnInit, OnChanges { | export class FractionStatsComponent implements OnInit, OnChanges { | ||||||
| 
 | 
 | ||||||
|  | @ -28,7 +28,7 @@ export class FractionStatsComponent implements OnInit, OnChanges { | ||||||
|   public activeChartSelect: string; |   public activeChartSelect: string; | ||||||
| 
 | 
 | ||||||
|   lineChartData: any[] = []; |   lineChartData: any[] = []; | ||||||
|   areaChartData: any[] = []; |   barChartData: any[] = []; | ||||||
| 
 | 
 | ||||||
|   tmpPointData; |   tmpPointData; | ||||||
|   tmpBudgetData; |   tmpBudgetData; | ||||||
|  | @ -38,7 +38,6 @@ export class FractionStatsComponent implements OnInit, OnChanges { | ||||||
|   tmpTransportData; |   tmpTransportData; | ||||||
|   tmpReviveData; |   tmpReviveData; | ||||||
|   tmpStabilizeData; |   tmpStabilizeData; | ||||||
|   tmpFlagCaptureData; |  | ||||||
|   tmpPlayerCountData; |   tmpPlayerCountData; | ||||||
| 
 | 
 | ||||||
|   colorScheme = { |   colorScheme = { | ||||||
|  | @ -64,6 +63,11 @@ export class FractionStatsComponent implements OnInit, OnChanges { | ||||||
|   timeline = false; |   timeline = false; | ||||||
|   roundDomains = true; |   roundDomains = true; | ||||||
| 
 | 
 | ||||||
|  |   barPadding = 0; | ||||||
|  |   barAnimations = false; | ||||||
|  |   barShowYAxis = false; | ||||||
|  |   barShowXAxisLabel = true; | ||||||
|  | 
 | ||||||
|   constructor(private translate: TranslateService) { |   constructor(private translate: TranslateService) { | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | @ -84,7 +88,7 @@ export class FractionStatsComponent implements OnInit, OnChanges { | ||||||
| 
 | 
 | ||||||
|       this.initializeToggleButtons(); |       this.initializeToggleButtons(); | ||||||
| 
 | 
 | ||||||
|       Object.assign(this, [this.lineChartData, this.areaChartData]); |       Object.assign(this, [this.lineChartData, this.barChartData]); | ||||||
|       this.activeChartSelect = this.labels.points; |       this.activeChartSelect = this.labels.points; | ||||||
| 
 | 
 | ||||||
|       this.startDateObj = new Date(this.war.date); |       this.startDateObj = new Date(this.war.date); | ||||||
|  | @ -175,7 +179,6 @@ export class FractionStatsComponent implements OnInit, OnChanges { | ||||||
|     } else { |     } else { | ||||||
|       this.initFlagHoldData(); |       this.initFlagHoldData(); | ||||||
|       this.showLineChart = false; |       this.showLineChart = false; | ||||||
|       this.areaChartData = this.tmpFlagCaptureData; |  | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | @ -402,21 +405,49 @@ export class FractionStatsComponent implements OnInit, OnChanges { | ||||||
|     } |     } | ||||||
|     let flagStatusBlufor = true; |     let flagStatusBlufor = true; | ||||||
|     let flagStatusOpfor = true; |     let flagStatusOpfor = true; | ||||||
|     this.tmpFlagCaptureData[0].series.push(ChartUtils.getSeriesEntry(this.startDateObj, flagStatusBlufor)); |     const flagStatusMap = { | ||||||
|     this.tmpFlagCaptureData[1].series.push(ChartUtils.getSeriesEntry(this.startDateObj, flagStatusOpfor)); |       blufor: {0: flagStatusBlufor}, | ||||||
|  |       opfor: {0: flagStatusOpfor}, | ||||||
|  |     }; | ||||||
| 
 | 
 | ||||||
|     this.logData.flag.forEach(flagEntry => { |     this.logData.flag.forEach((flagEntry) => { | ||||||
|       if (flagEntry.flagFraction === 'BLUFOR') { |       if (flagEntry.flagFraction === 'BLUFOR') { | ||||||
|         flagStatusBlufor = !flagEntry.capture; |         flagStatusBlufor = !flagEntry.capture; | ||||||
|       } else { |       } else { | ||||||
|         flagStatusOpfor = !flagEntry.capture; |         flagStatusOpfor = !flagEntry.capture; | ||||||
|       } |       } | ||||||
|       this.tmpFlagCaptureData[flagEntry.flagFraction === 'BLUFOR' ? 0 : 1].series.push( |       const entryMinute = Math.round((new Date(flagEntry.time).getTime() - new Date(this.war.date).getTime()) / 60000); | ||||||
|         ChartUtils.getSeriesEntry(new Date(flagEntry.time), flagEntry.flagFraction === 'BLUFOR' ? flagStatusBlufor : flagStatusOpfor) |       flagStatusMap.blufor[entryMinute] = flagStatusBlufor; | ||||||
|       ); |       flagStatusMap.opfor[entryMinute] = flagStatusOpfor; | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     this.addFinalTimeData(this.tmpFlagCaptureData); |     const data = []; | ||||||
|  |     let lastExistingIdx = 0; | ||||||
|  |     const finishMinute = Math.round((new Date(this.war.endDate).getTime() - new Date(this.war.date).getTime()) / 60000); | ||||||
|  |     for (let t = 0; t <= finishMinute; t++) { | ||||||
|  |       if (flagStatusMap.blufor.hasOwnProperty(t) && flagStatusMap.opfor.hasOwnProperty(t)) { | ||||||
|  |         lastExistingIdx = t; | ||||||
|  |       } | ||||||
|  |       data.push({ | ||||||
|  |         name: t, | ||||||
|  |         series: [ | ||||||
|  |           { | ||||||
|  |             name: Fraction.BLUFOR, | ||||||
|  |             value: flagStatusMap.blufor[lastExistingIdx] ? 1 : 0 | ||||||
|  |           } | ||||||
|  |         ] | ||||||
|  |       }); | ||||||
|  |       data.push({ | ||||||
|  |         name: t, | ||||||
|  |         series: [ | ||||||
|  |           { | ||||||
|  |             name: Fraction.OPFOR, | ||||||
|  |             value: flagStatusMap.opfor[lastExistingIdx] ? -1 : 0 | ||||||
|  |           } | ||||||
|  |         ] | ||||||
|  |       }); | ||||||
|  |     } | ||||||
|  |     this.barChartData = data; | ||||||
|     this.initialized.flag = true; |     this.initialized.flag = true; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | @ -435,7 +466,6 @@ export class FractionStatsComponent implements OnInit, OnChanges { | ||||||
|     this.tmpTransportData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR); |     this.tmpTransportData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR); | ||||||
|     this.tmpReviveData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR); |     this.tmpReviveData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR); | ||||||
|     this.tmpStabilizeData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR); |     this.tmpStabilizeData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR); | ||||||
|     this.tmpFlagCaptureData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR); |  | ||||||
|     this.tmpPlayerCountData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR); |     this.tmpPlayerCountData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR); | ||||||
| 
 | 
 | ||||||
|     [this.tmpKillData, this.tmpFrienlyFireData, this.tmpVehicleData, this.tmpReviveData, this.tmpStabilizeData, |     [this.tmpKillData, this.tmpFrienlyFireData, this.tmpVehicleData, this.tmpReviveData, this.tmpStabilizeData, | ||||||
|  | @ -471,4 +501,12 @@ export class FractionStatsComponent implements OnInit, OnChanges { | ||||||
|       this.lineChartLabel = translated; |       this.lineChartLabel = translated; | ||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
|  | 
 | ||||||
|  |   axisFormat(val) { | ||||||
|  |     if (val % 10 === 0) { | ||||||
|  |       return val | ||||||
|  |     } else { | ||||||
|  |       return '' | ||||||
|  |     } | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -21,7 +21,7 @@ | ||||||
|       [showXAxisLabel]="showXAxisLabel" |       [showXAxisLabel]="showXAxisLabel" | ||||||
|       [showYAxisLabel]="showYAxisLabel" |       [showYAxisLabel]="showYAxisLabel" | ||||||
|       [yAxisLabel]="barChartLabel" |       [yAxisLabel]="barChartLabel" | ||||||
|       [barPadding]="2" |       [barPadding]="barPadding" | ||||||
|       [roundDomains]="roundDomains"> |       [roundDomains]="roundDomains"> | ||||||
|     </ngx-charts-bar-vertical> |     </ngx-charts-bar-vertical> | ||||||
|   </div> |   </div> | ||||||
|  |  | ||||||
|  | @ -54,6 +54,7 @@ export class ServerStatsComponent implements OnInit, OnChanges { | ||||||
|   autoscale = true; |   autoscale = true; | ||||||
|   timeline = false; |   timeline = false; | ||||||
|   roundDomains = true; |   roundDomains = true; | ||||||
|  |   barPadding = 2; | ||||||
|   colorScheme = { |   colorScheme = { | ||||||
|     name: 'nightLights', |     name: 'nightLights', | ||||||
|     selectable: false, |     selectable: false, | ||||||
|  |  | ||||||
|  | @ -28,6 +28,10 @@ | ||||||
|   "stats.fraction.select.stabilize": "Stabilisiert", |   "stats.fraction.select.stabilize": "Stabilisiert", | ||||||
|   "stats.fraction.select.flag": "Flaggenbesitz", |   "stats.fraction.select.flag": "Flaggenbesitz", | ||||||
|   "stats.fraction.select.player.count": "Spieleranzahl", |   "stats.fraction.select.player.count": "Spieleranzahl", | ||||||
|  |   "stats.fraction.tooltip.flag.minute": "Minute", | ||||||
|  |   "stats.fraction.tooltip.flag.flag": "Flagge", | ||||||
|  |   "stats.fraction.tooltip.flag.safe": "Gesichert", | ||||||
|  |   "stats.fraction.tooltip.flag.lost": "Verloren", | ||||||
| 
 | 
 | ||||||
|   "stats.performance.select.single.avg": "Spieler FPS Durchschnitt", |   "stats.performance.select.single.avg": "Spieler FPS Durchschnitt", | ||||||
|   "stats.performance.select.single.min": "Spieler FPS Minimum", |   "stats.performance.select.single.min": "Spieler FPS Minimum", | ||||||
|  |  | ||||||
|  | @ -36,6 +36,10 @@ | ||||||
|   "stats.fraction.select.stabilize": "Stabilized", |   "stats.fraction.select.stabilize": "Stabilized", | ||||||
|   "stats.fraction.select.flag": "Flag Possession", |   "stats.fraction.select.flag": "Flag Possession", | ||||||
|   "stats.fraction.select.player.count": "Player Count", |   "stats.fraction.select.player.count": "Player Count", | ||||||
|  |   "stats.fraction.tooltip.flag.minute": "Minute", | ||||||
|  |   "stats.fraction.tooltip.flag.flag": "Flag", | ||||||
|  |   "stats.fraction.tooltip.flag.safe": "Safe", | ||||||
|  |   "stats.fraction.tooltip.flag.lost": "Lost", | ||||||
| 
 | 
 | ||||||
|   "stats.performance.select.single.avg": "Player FPS Average", |   "stats.performance.select.single.avg": "Player FPS Average", | ||||||
|   "stats.performance.select.single.min": "Player FPS Minimum", |   "stats.performance.select.single.min": "Player FPS Minimum", | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue