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