Use stacked bar chart for flag capture visualization (CC-72)

pull/54/head
HardiReady 2019-02-17 00:43:17 +01:00
parent 20321def38
commit 90510eac93
7 changed files with 76 additions and 24 deletions

View File

@ -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>

View File

@ -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 ''
}
}
} }

View File

@ -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>

View File

@ -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,

View File

@ -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",

View File

@ -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",