From 90510eac93b51bd5cbd5bd14ba243427f40275a5 Mon Sep 17 00:00:00 2001 From: HardiReady Date: Sun, 17 Feb 2019 00:43:17 +0100 Subject: [PATCH] Use stacked bar chart for flag capture visualization (CC-72) --- .../fraction-stats.component.html | 25 +++++--- ...nent.css => fraction-stats.component.scss} | 0 .../fraction-stats.component.ts | 64 +++++++++++++++---- .../server-stats/server-stats.component.html | 2 +- .../server-stats/server-stats.component.ts | 1 + static/src/assets/i18n/statistics/de.json | 4 ++ static/src/assets/i18n/statistics/en.json | 4 ++ 7 files changed, 76 insertions(+), 24 deletions(-) rename static/src/app/statistic/war/fraction-stats/{fraction-stats.component.css => fraction-stats.component.scss} (100%) diff --git a/static/src/app/statistic/war/fraction-stats/fraction-stats.component.html b/static/src/app/statistic/war/fraction-stats/fraction-stats.component.html index 54285f1..f6e829a 100644 --- a/static/src/app/statistic/war/fraction-stats/fraction-stats.component.html +++ b/static/src/app/statistic/war/fraction-stats/fraction-stats.component.html @@ -28,20 +28,25 @@
- - + [animations]="barAnimations" + [barPadding]="barPadding" + [xAxisTickFormatting]="axisFormat" + [xAxisLabel]="'Minute'"> + + {{'stats.fraction.tooltip.flag.minute' | translate}} {{model.series}} +
{{model.name}} {{'stats.fraction.tooltip.flag.flag' | translate}}
+
{{'stats.fraction.tooltip.flag.lost' | translate}}
+
{{'stats.fraction.tooltip.flag.safe' | translate}}
+
+
diff --git a/static/src/app/statistic/war/fraction-stats/fraction-stats.component.css b/static/src/app/statistic/war/fraction-stats/fraction-stats.component.scss similarity index 100% rename from static/src/app/statistic/war/fraction-stats/fraction-stats.component.css rename to static/src/app/statistic/war/fraction-stats/fraction-stats.component.scss diff --git a/static/src/app/statistic/war/fraction-stats/fraction-stats.component.ts b/static/src/app/statistic/war/fraction-stats/fraction-stats.component.ts index 2625b39..29e1baf 100644 --- a/static/src/app/statistic/war/fraction-stats/fraction-stats.component.ts +++ b/static/src/app/statistic/war/fraction-stats/fraction-stats.component.ts @@ -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 '' + } + } } diff --git a/static/src/app/statistic/war/server-stats/server-stats.component.html b/static/src/app/statistic/war/server-stats/server-stats.component.html index bb1f534..6fe3135 100644 --- a/static/src/app/statistic/war/server-stats/server-stats.component.html +++ b/static/src/app/statistic/war/server-stats/server-stats.component.html @@ -21,7 +21,7 @@ [showXAxisLabel]="showXAxisLabel" [showYAxisLabel]="showYAxisLabel" [yAxisLabel]="barChartLabel" - [barPadding]="2" + [barPadding]="barPadding" [roundDomains]="roundDomains"> diff --git a/static/src/app/statistic/war/server-stats/server-stats.component.ts b/static/src/app/statistic/war/server-stats/server-stats.component.ts index d5356e0..c9a424c 100644 --- a/static/src/app/statistic/war/server-stats/server-stats.component.ts +++ b/static/src/app/statistic/war/server-stats/server-stats.component.ts @@ -54,6 +54,7 @@ export class ServerStatsComponent implements OnInit, OnChanges { autoscale = true; timeline = false; roundDomains = true; + barPadding = 2; colorScheme = { name: 'nightLights', selectable: false, diff --git a/static/src/assets/i18n/statistics/de.json b/static/src/assets/i18n/statistics/de.json index 00fbfd3..85ec42c 100644 --- a/static/src/assets/i18n/statistics/de.json +++ b/static/src/assets/i18n/statistics/de.json @@ -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", diff --git a/static/src/assets/i18n/statistics/en.json b/static/src/assets/i18n/statistics/en.json index 0e4838a..0e161f3 100644 --- a/static/src/assets/i18n/statistics/en.json +++ b/static/src/assets/i18n/statistics/en.json @@ -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",