diff --git a/package.json b/package.json index a0c1cf6..0f7aab8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "opt-cc", - "version": "1.9.5", + "version": "1.9.6", "author": "Florian Hartwich ", "private": true, "scripts": { diff --git a/server/routes/players.js b/server/routes/players.js index 3ec0610..fd2bd23 100644 --- a/server/routes/players.js +++ b/server/routes/players.js @@ -26,92 +26,100 @@ campaignPlayer.route('/ranking/:campaignId') const warIds = wars.map((obj) => { return obj._id; }); - PlayerModel.find({warId: {'$in': warIds}}, (err, items) => { - if (err) return next(err); - if (!items || items.length === 0) { - const err = new Error('No players for given campaignId'); - err.status = codes.notfound; - return next(err); - } - - const rankingItems = []; - - // check only first player to have valid steamUUID - then decide if tracked by name or by ID - const usesUUID = isSteamUUID(items[0].steamUUID); - - new Set(items.map(usesUUID ? (x) => x.steamUUID : (x) => x.name)) - .forEach((player) => { - const playerInstances = items.filter( - usesUUID ? (p) => p.steamUUID === player : (p) => p.name === player); - const resItem = { - name: usesUUID ? playerInstances[playerInstances.length - 1].name : player, - kill: 0, - vehicleLight: 0, - vehicleHeavy: 0, - vehicleAir: 0, - death: 0, - friendlyFire: 0, - revive: 0, - respawn: 0, - flagTouch: 0, - travelDistance: 0, - driverDistance: 0, - }; - for (let i = 0; i < playerInstances.length; i++) { - const player = playerInstances[i]; - resItem.kill += player.kill; - resItem.death += player.death; - resItem.friendlyFire += player.friendlyFire; - resItem.vehicleLight += player.vehicleLight; - resItem.vehicleHeavy += player.vehicleHeavy; - resItem.vehicleAir += player.vehicleAir; - resItem.revive += player.revive; - resItem.respawn += player.respawn; - resItem.flagTouch += player.flagTouch; - if (player.travelDistance) { - resItem.travelDistance += Math.round(player.travelDistance / 1000); // meters -> km - } - if (player.driverDistance) { - resItem.driverDistance += Math.round(player.driverDistance / 1000); // meters -> km - } - } - resItem.warCount = playerInstances.length; - resItem.fraction = playerInstances[playerInstances.length - 1].fraction; - rankingItems.push(resItem); - }); - - const getSortedField = (fieldName) => { - let num = 1; - const filteredSortResult = rankingItems.map((item) => { - return { - name: item.name, - fraction: item.fraction, - [fieldName]: item[fieldName], - }; - }) - .sort((a, b) => b[fieldName] - a[fieldName]); - const res = JSON.parse(JSON.stringify(filteredSortResult)); - for (const entity of res) { - entity.num = num++; + WarModel.findOne({campaign: req.params.campaignId}, {}, {sort: {'date': -1}}, (err, latestWar) => { + PlayerModel.find({warId: {'$in': warIds}}, (err, items) => { + if (err) return next(err); + if (!items || items.length === 0) { + const err = new Error('No players for given campaignId'); + err.status = codes.notfound; + return next(err); } - return res; - }; - res.locals.items = { - kill: getSortedField('kill'), - death: getSortedField('death'), - friendlyFire: getSortedField('friendlyFire'), - vehicleLight: getSortedField('vehicleLight'), - vehicleHeavy: getSortedField('vehicleHeavy'), - vehicleAir: getSortedField('vehicleAir'), - revive: getSortedField('revive'), - respawn: getSortedField('respawn'), - flagTouch: getSortedField('flagTouch'), - travelDistance: getSortedField('travelDistance'), - driverDistance: getSortedField('driverDistance'), - warCount: getSortedField('warCount'), - }; - next(); + const rankingItems = []; + + // check only first player to have valid steamUUID - then decide if tracked by name or by ID + const usesUUID = isSteamUUID(items[0].steamUUID); + + new Set(items.map(usesUUID ? (x) => x.steamUUID : (x) => x.name)) + .forEach((player) => { + const playerInstances = items.filter( + usesUUID ? (p) => p.steamUUID === player : (p) => p.name === player); + const resItem = { + name: usesUUID ? playerInstances[playerInstances.length - 1].name : player, + kill: 0, + vehicleLight: 0, + vehicleHeavy: 0, + vehicleAir: 0, + death: 0, + friendlyFire: 0, + revive: 0, + respawn: 0, + flagTouch: 0, + travelDistance: 0, + driverDistance: 0, + }; + for (let i = 0; i < playerInstances.length; i++) { + const player = playerInstances[i]; + resItem.kill += player.kill; + resItem.death += player.death; + resItem.friendlyFire += player.friendlyFire; + resItem.vehicleLight += player.vehicleLight; + resItem.vehicleHeavy += player.vehicleHeavy; + resItem.vehicleAir += player.vehicleAir; + resItem.revive += player.revive; + resItem.respawn += player.respawn; + resItem.flagTouch += player.flagTouch; + if (player.travelDistance) { + resItem.travelDistance += Math.round(player.travelDistance / 1000); // meters -> km + } + if (player.driverDistance) { + resItem.driverDistance += Math.round(player.driverDistance / 1000); // meters -> km + } + } + resItem.warCount = playerInstances.length; + + const latestPlayerFraction = playerInstances[playerInstances.length - 1].fraction; + resItem.fraction = + (latestPlayerFraction === 'OPFOR') ? + latestWar.fractionMappingOpfor : + latestWar.fractionMappingBlufor; + + rankingItems.push(resItem); + }); + + const getSortedField = (fieldName) => { + let num = 1; + const filteredSortResult = rankingItems.map((item) => { + return { + name: item.name, + fraction: item.fraction, + [fieldName]: item[fieldName], + }; + }) + .sort((a, b) => b[fieldName] - a[fieldName]); + const res = JSON.parse(JSON.stringify(filteredSortResult)); + for (const entity of res) { + entity.num = num++; + } + return res; + }; + + res.locals.items = { + kill: getSortedField('kill'), + death: getSortedField('death'), + friendlyFire: getSortedField('friendlyFire'), + vehicleLight: getSortedField('vehicleLight'), + vehicleHeavy: getSortedField('vehicleHeavy'), + vehicleAir: getSortedField('vehicleAir'), + revive: getSortedField('revive'), + respawn: getSortedField('respawn'), + flagTouch: getSortedField('flagTouch'), + travelDistance: getSortedField('travelDistance'), + driverDistance: getSortedField('driverDistance'), + warCount: getSortedField('warCount'), + }; + next(); + }); }); }); }) diff --git a/static/src/app/manage/decorations/edit-decoration/edit-decoration.component.html b/static/src/app/manage/decorations/edit-decoration/edit-decoration.component.html index cf312ab..7e20beb 100644 --- a/static/src/app/manage/decorations/edit-decoration/edit-decoration.component.html +++ b/static/src/app/manage/decorations/edit-decoration/edit-decoration.component.html @@ -19,8 +19,8 @@ [(ngModel)]="decoration.fraction"> - - + + diff --git a/static/src/app/models/model-interfaces.ts b/static/src/app/models/model-interfaces.ts index ea7837f..3aadd33 100644 --- a/static/src/app/models/model-interfaces.ts +++ b/static/src/app/models/model-interfaces.ts @@ -1,4 +1,5 @@ import {Observable} from 'rxjs'; +import {Fraction} from '../utils/fraction.enum'; export interface AppUser { _id?: string; @@ -59,6 +60,8 @@ export interface War { endDate?: string; ptBlufor?: number; ptOpfor?: number; + fractionMappingBlufor?: Fraction.SWORD | Fraction.ARF | 'BLUFOR' | 'OPFOR'; + fractionMappingOpfor?: Fraction.SWORD | Fraction.ARF | 'BLUFOR' | 'OPFOR'; playersBlufor?: number; playersOpfor?: number; budgetBlufor?: number; diff --git a/static/src/app/statistic/campaign/highscore/highscore.component.html b/static/src/app/statistic/campaign/highscore/highscore.component.html index 6992cc8..05aae0e 100644 --- a/static/src/app/statistic/campaign/highscore/highscore.component.html +++ b/static/src/app/statistic/campaign/highscore/highscore.component.html @@ -28,7 +28,7 @@ {{'stats.highscore.header.name' | translate}} + [style.color]="fractionHelpers.getFractionColor(element['fraction'])"> {{element.name}} diff --git a/static/src/app/statistic/campaign/highscore/highscore.component.ts b/static/src/app/statistic/campaign/highscore/highscore.component.ts index 26d5509..944d3b0 100644 --- a/static/src/app/statistic/campaign/highscore/highscore.component.ts +++ b/static/src/app/statistic/campaign/highscore/highscore.component.ts @@ -1,11 +1,11 @@ import {Component, OnInit} from '@angular/core'; import {ActivatedRoute} from '@angular/router'; import {PlayerService} from '../../../services/logs/player.service'; -import {Fraction} from '../../../utils/fraction.enum'; import {FormControl} from '@angular/forms'; import {Observable} from 'rxjs/Observable'; import {Player} from '../../../models/model-interfaces'; import {PlayerUtils} from '../../../utils/player-utils'; +import {FractionHelpers} from '../../../utils/global.helpers'; @Component({ @@ -25,7 +25,7 @@ export class StatisticHighScoreComponent implements OnInit { playerAttributeDisplayNames = PlayerUtils.attributeDisplayNames.slice(2, PlayerUtils.attributeDisplayNames.length); - readonly fraction = Fraction; + readonly fractionHelpers = FractionHelpers; constructor(private route: ActivatedRoute, private playerService: PlayerService) { diff --git a/static/src/app/statistic/campaign/overview/campaign-overview.component.ts b/static/src/app/statistic/campaign/overview/campaign-overview.component.ts index 0a9a338..982635b 100644 --- a/static/src/app/statistic/campaign/overview/campaign-overview.component.ts +++ b/static/src/app/statistic/campaign/overview/campaign-overview.component.ts @@ -4,6 +4,8 @@ import {CampaignService} from '../../../services/logs/campaign.service'; import {ChartUtils} from '../../../utils/chart-utils'; import {Fraction} from '../../../utils/fraction.enum'; import {WarService} from '../../../services/logs/war.service'; +import {FractionHelpers} from '../../../utils/global.helpers'; +import {War} from '../../../models/model-interfaces'; @Component({ @@ -22,9 +24,7 @@ export class StatisticOverviewComponent implements OnInit { playerData: any[] = []; currentData: any[] = []; - colorScheme = { - domain: [Fraction.COLOR_BLUFOR, Fraction.COLOR_OPFOR] - }; + colorScheme; gradient = false; xAxis = true; yAxis = true; @@ -81,44 +81,71 @@ export class StatisticOverviewComponent implements OnInit { } } - initChart(wars: any[]) { - const pointsObj = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR); - const pointsSumObj = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR); - const playersObj = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR); + initChart(wars: War[]) { + const fractions: string[] = []; + this.colorScheme = { + domain: [] + }; + + if (wars.find(war => war.fractionMappingBlufor === 'BLUFOR' || war.fractionMappingOpfor === 'BLUFOR')) { + fractions.push(Fraction.BLUFOR); + this.colorScheme.domain.push(FractionHelpers.getFractionColor('BLUFOR')); + } + if (wars.find(war => war.fractionMappingBlufor === 'OPFOR' || war.fractionMappingOpfor === 'OPFOR')) { + fractions.push(Fraction.OPFOR); + this.colorScheme.domain.push(FractionHelpers.getFractionColor('OPFOR')); + } + if (wars.find(war => war.fractionMappingBlufor === Fraction.ARF || war.fractionMappingOpfor === Fraction.ARF)) { + fractions.push(Fraction.ARF); + this.colorScheme.domain.push(FractionHelpers.getFractionColor(Fraction.ARF)); + } + if (wars.find(war => war.fractionMappingBlufor === Fraction.SWORD || war.fractionMappingOpfor === Fraction.SWORD)) { + fractions.push(Fraction.SWORD); + this.colorScheme.domain.push(FractionHelpers.getFractionColor(Fraction.SWORD)); + } + + const pointsObj = ChartUtils.getMultiDataArray(...fractions); + const pointsSumObj = ChartUtils.getMultiDataArray(...fractions); + const playersObj = ChartUtils.getMultiDataArray(...fractions); for (let i = wars.length - 1; i >= 0; i--) { const war = wars[i]; if (!war) { continue; } + + const bluforIndex = fractions.findIndex(fraction => + fraction === FractionHelpers.getFractionName(war, 'BLUFOR')); + const opforIndex = fractions.findIndex( + fraction => fraction === FractionHelpers.getFractionName(war, 'OPFOR')); + const j = wars.length - i - 1; const warDate = (this.id === 'all') ? new Date(war.date) : ChartUtils.getShortDateString(war.date); - - pointsObj[0].series.push({ + pointsObj[bluforIndex].series.push({ name: warDate, value: war.ptBlufor }); - pointsObj[1].series.push({ + pointsObj[opforIndex].series.push({ name: warDate, value: war.ptOpfor }); - pointsSumObj[0].series.push({ + pointsSumObj[bluforIndex].series.push({ name: warDate, - value: pointsSumObj[0].series[j - 1] ? - pointsSumObj[0].series[j - 1].value + war.ptBlufor : + value: pointsSumObj[bluforIndex].series[j - 1] ? + pointsSumObj[bluforIndex].series[j - 1].value + war.ptBlufor : war.ptBlufor }); - pointsSumObj[1].series.push({ + pointsSumObj[opforIndex].series.push({ name: warDate, - value: pointsSumObj[1].series[j - 1] - ? pointsSumObj[1].series[j - 1].value + war.ptOpfor : + value: pointsSumObj[opforIndex].series[j - 1] + ? pointsSumObj[opforIndex].series[j - 1].value + war.ptOpfor : war.ptOpfor }); - playersObj[0].series.push({ + playersObj[bluforIndex].series.push({ name: warDate, value: war.playersBlufor }); - playersObj[1].series.push({ + playersObj[opforIndex].series.push({ name: warDate, value: war.playersOpfor }); 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 4e8b498..c24543d 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 @@ -1,8 +1,8 @@ import {Component, ElementRef, Input, OnChanges, OnInit, SimpleChanges, ViewChild} from '@angular/core'; import {ChartUtils} from '../../../utils/chart-utils'; -import {Fraction} from '../../../utils/fraction.enum'; import {War} from '../../../models/model-interfaces'; import {TranslateService} from '@ngx-translate/core'; +import {FractionHelpers} from '../../../utils/global.helpers'; @Component({ @@ -12,8 +12,6 @@ import {TranslateService} from '@ngx-translate/core'; }) export class FractionStatsComponent implements OnInit, OnChanges { - readonly fraction = Fraction; - @ViewChild('overview') private overviewContainer: ElementRef; @Input() war: War; @@ -41,10 +39,9 @@ export class FractionStatsComponent implements OnInit, OnChanges { tmpStabilizeData; tmpPlayerCountData; - colorScheme = { - domain: [Fraction.COLOR_BLUFOR, Fraction.COLOR_OPFOR, Fraction.COLOR_BLUFOR_LIGHT, Fraction.COLOR_OPFOR_LIGHT, - Fraction.COLOR_BLUFOR_DARK, Fraction.COLOR_OPFOR_DARK, Fraction.COLOR_BLUFOR_GREY, Fraction.COLOR_OPFOR_GREY] - }; + colorScheme; + fractionNameBlufor; + fractionNameOpfor; labels; labelsKeys; @@ -77,6 +74,21 @@ export class FractionStatsComponent implements OnInit, OnChanges { ngOnChanges(changes: SimpleChanges) { if (changes.war || changes.logData) { + this.fractionNameBlufor = FractionHelpers.getFractionName(this.war, 'BLUFOR'); + this.fractionNameOpfor = FractionHelpers.getFractionName(this.war, 'OPFOR'); + this.colorScheme = { + domain: [ + FractionHelpers.getFractionColor('BLUFOR', this.war), + FractionHelpers.getFractionColor('OPFOR', this.war), + FractionHelpers.getFractionColor('BLUFOR', this.war, 'LIGHT'), + FractionHelpers.getFractionColor('OPFOR', this.war, 'LIGHT'), + FractionHelpers.getFractionColor('BLUFOR', this.war, 'DARK'), + FractionHelpers.getFractionColor('OPFOR', this.war, 'DARK'), + FractionHelpers.getFractionColor('BLUFOR', this.war, 'GREY'), + FractionHelpers.getFractionColor('OPFOR', this.war, 'GREY'), + ] + }; + this.initialized = { budget: false, kill: false, @@ -433,7 +445,7 @@ export class FractionStatsComponent implements OnInit, OnChanges { name: t, series: [ { - name: Fraction.BLUFOR, + name: this.fractionNameBlufor, value: flagStatusMap.blufor[lastExistingIdx] ? 1 : 0 } ] @@ -442,7 +454,7 @@ export class FractionStatsComponent implements OnInit, OnChanges { name: t, series: [ { - name: Fraction.OPFOR, + name: this.fractionNameOpfor, value: flagStatusMap.opfor[lastExistingIdx] ? -1 : 0 } ] @@ -453,17 +465,17 @@ export class FractionStatsComponent implements OnInit, OnChanges { } initializeTempCollections() { - this.tmpPointData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR); - this.tmpBudgetData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR); - this.tmpKillData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR); - this.tmpFrienlyFireData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR); - this.tmpVehicleData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR, - Fraction.BLUFOR.concat(' Leicht'), Fraction.OPFOR.concat(' Leicht'), Fraction.BLUFOR.concat(' Schwer'), - Fraction.OPFOR.concat(' Schwer'), Fraction.BLUFOR.concat(' Luft'), Fraction.OPFOR.concat(' Luft')); - 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.tmpPlayerCountData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR); + this.tmpPointData = ChartUtils.getMultiDataArray(this.fractionNameBlufor, this.fractionNameOpfor); + this.tmpBudgetData = ChartUtils.getMultiDataArray(this.fractionNameBlufor, this.fractionNameOpfor); + this.tmpKillData = ChartUtils.getMultiDataArray(this.fractionNameBlufor, this.fractionNameOpfor); + this.tmpFrienlyFireData = ChartUtils.getMultiDataArray(this.fractionNameBlufor, this.fractionNameOpfor); + this.tmpVehicleData = ChartUtils.getMultiDataArray(this.fractionNameBlufor, this.fractionNameOpfor, + this.fractionNameBlufor.concat(' Leicht'), this.fractionNameOpfor.concat(' Leicht'), this.fractionNameBlufor.concat(' Schwer'), + this.fractionNameOpfor.concat(' Schwer'), this.fractionNameBlufor.concat(' Luft'), this.fractionNameOpfor.concat(' Luft')); + this.tmpTransportData = ChartUtils.getMultiDataArray(this.fractionNameBlufor, this.fractionNameOpfor); + this.tmpReviveData = ChartUtils.getMultiDataArray(this.fractionNameBlufor, this.fractionNameOpfor); + this.tmpStabilizeData = ChartUtils.getMultiDataArray(this.fractionNameBlufor, this.fractionNameOpfor); + this.tmpPlayerCountData = ChartUtils.getMultiDataArray(this.fractionNameBlufor, this.fractionNameOpfor); [this.tmpKillData, this.tmpFrienlyFireData, this.tmpVehicleData, this.tmpReviveData, this.tmpStabilizeData, this.tmpTransportData].forEach(tmp => { @@ -509,10 +521,10 @@ export class FractionStatsComponent implements OnInit, OnChanges { axisFormatY(val) { if (val === 1) { - return Fraction.BLUFOR; + return this.fractionNameBlufor; } if (val === -1) { - return Fraction.OPFOR; + return this.fractionNameOpfor; } return ''; } diff --git a/static/src/app/statistic/war/scoreboard/scoreboard.component.html b/static/src/app/statistic/war/scoreboard/scoreboard.component.html index 94dfdec..74f4d40 100644 --- a/static/src/app/statistic/war/scoreboard/scoreboard.component.html +++ b/static/src/app/statistic/war/scoreboard/scoreboard.component.html @@ -8,7 +8,7 @@ {{tableHead[0].head | translate}} + [style.color]="fractionHelpers.getFractionColor(element['fraction'],war)"> {{element.name}} @@ -16,7 +16,7 @@ {{tableHead[1].head | translate}} - {{element.fraction === 'BLUFOR' ? fraction.BLUFOR : fraction.OPFOR}} + {{fractionHelpers.getFractionName(war, element.fraction)}} diff --git a/static/src/app/statistic/war/scoreboard/scoreboard.component.ts b/static/src/app/statistic/war/scoreboard/scoreboard.component.ts index e7e0138..b9517fb 100644 --- a/static/src/app/statistic/war/scoreboard/scoreboard.component.ts +++ b/static/src/app/statistic/war/scoreboard/scoreboard.component.ts @@ -6,6 +6,7 @@ import {saveAs} from 'file-saver/FileSaver'; import {MatSort} from '@angular/material'; import {SortUtils} from '../../../utils/sort-utils'; import {TranslateService} from '@ngx-translate/core'; +import {FractionHelpers} from '../../../utils/global.helpers'; @Component({ selector: 'cc-scoreboard', @@ -16,6 +17,8 @@ export class ScoreboardComponent implements OnChanges { readonly fraction = Fraction; + readonly fractionHelpers = FractionHelpers; + @Input() war: War; @Input() fractionFilterSelected: string; diff --git a/static/src/app/statistic/war/war-header/war-header.component.html b/static/src/app/statistic/war/war-header/war-header.component.html index 0664a55..1bcb15f 100644 --- a/static/src/app/statistic/war/war-header/war-header.component.html +++ b/static/src/app/statistic/war/war-header/war-header.component.html @@ -2,20 +2,28 @@

{{'stats.scoreboard.standings' | translate}}

- {{fraction.BLUFOR}} {{war.ptBlufor}} + + {{fractionHelpers.getFractionName(war, 'BLUFOR')}} {{war.ptBlufor}} + | - {{war.ptOpfor}} {{fraction.OPFOR}} + + {{war.ptOpfor}} {{fractionHelpers.getFractionName(war, 'OPFOR')}} +

{{'stats.scoreboard.participants' | translate}}

- {{fraction.BLUFOR}} {{war.playersBlufor}} + + {{fractionHelpers.getFractionName(war, 'BLUFOR')}} {{war.playersBlufor}} + vs - {{war.playersOpfor}} {{fraction.OPFOR}} + + {{war.playersOpfor}} {{fractionHelpers.getFractionName(war, 'OPFOR')}} +
diff --git a/static/src/app/statistic/war/war-header/war-header.component.ts b/static/src/app/statistic/war/war-header/war-header.component.ts index 32bb852..25cb8c8 100644 --- a/static/src/app/statistic/war/war-header/war-header.component.ts +++ b/static/src/app/statistic/war/war-header/war-header.component.ts @@ -8,6 +8,7 @@ import {LogsService} from '../../../services/logs/logs.service'; import {ScoreboardComponent} from '../scoreboard/scoreboard.component'; import {BaseConfig} from '../../../app.config'; import {Observable} from 'rxjs'; +import {FractionHelpers} from '../../../utils/global.helpers'; @Component({ @@ -19,6 +20,8 @@ export class WarHeaderComponent implements OnInit { readonly fraction = Fraction; + readonly fractionHelpers = FractionHelpers; + war: War; @ViewChild('scoreboard') scoreBoardComponent: ScoreboardComponent; @@ -43,9 +46,7 @@ export class WarHeaderComponent implements OnInit { playerChart: any[] = []; - colorScheme = { - domain: [Fraction.COLOR_OPFOR, Fraction.COLOR_BLUFOR] - }; + colorScheme; constructor(private route: ActivatedRoute, private warService: WarService, @@ -64,8 +65,18 @@ export class WarHeaderComponent implements OnInit { this.fractionStatsInitialized = false; this.fractionFilterSelected = undefined; + this.colorScheme = { + domain: [ + FractionHelpers.getFractionColor('OPFOR', war), + FractionHelpers.getFractionColor('BLUFOR', war) + ] + }; + this.playerChart = - ChartUtils.getSingleDataArray(Fraction.OPFOR, war.playersOpfor, Fraction.BLUFOR, war.playersBlufor); + ChartUtils.getSingleDataArray( + FractionHelpers.getFractionName(war, 'OPFOR'), war.playersOpfor, + FractionHelpers.getFractionName(war, 'BLUFOR'), war.playersBlufor + ); Object.assign(this, [this.playerChart]); }); diff --git a/static/src/app/statistic/war/war-submit/war-submit.component.html b/static/src/app/statistic/war/war-submit/war-submit.component.html index 0f633eb..585ee0f 100644 --- a/static/src/app/statistic/war/war-submit/war-submit.component.html +++ b/static/src/app/statistic/war/war-submit/war-submit.component.html @@ -25,6 +25,33 @@
+
+ + + +
+ +
+ + + +
+ +
- + -
- + -
diff --git a/static/src/app/statistic/war/war-submit/war-submit.component.ts b/static/src/app/statistic/war/war-submit/war-submit.component.ts index ac6d54d..e25183a 100644 --- a/static/src/app/statistic/war/war-submit/war-submit.component.ts +++ b/static/src/app/statistic/war/war-submit/war-submit.component.ts @@ -9,6 +9,7 @@ import {SpinnerService} from '../../../services/user-interface/spinner/spinner.s import {Subscription} from 'rxjs'; import {Fraction} from '../../../utils/fraction.enum'; import {TranslateService} from '@ngx-translate/core'; +import {FractionHelpers} from '../../../utils/global.helpers'; @Component({ @@ -28,6 +29,8 @@ export class WarSubmitComponent { readonly fraction = Fraction; + readonly fractionHelpers = FractionHelpers; + showFileError = false; loading = false; diff --git a/static/src/app/utils/fraction.enum.ts b/static/src/app/utils/fraction.enum.ts index a3f28bf..34df209 100644 --- a/static/src/app/utils/fraction.enum.ts +++ b/static/src/app/utils/fraction.enum.ts @@ -1,17 +1,23 @@ export enum Fraction { + COLOR_NEUTRAL = '#222222', ARF = 'ARF', COLOR_ARF = '#336699', + COLOR_ARF_LIGHT = '#6666dd', + COLOR_ARF_DARK = '#0C0CA6', + COLOR_ARF_GREY = '#515179', SWORD = 'SWORD', COLOR_SWORD = '#8b8b8b', + COLOR_SWORD_GREY = '#282828', + COLOR_SWORD_DARK = '#101010', + COLOR_SWORD_LIGHT = '#b8b8b8', BLUFOR = 'NATO', - OPFOR = 'CSAT', COLOR_BLUFOR = '#3c5fa1', COLOR_BLUFOR_LIGHT = '#6666dd', COLOR_BLUFOR_DARK = '#0C0CA6', COLOR_BLUFOR_GREY = '#515179', + OPFOR = 'CSAT', COLOR_OPFOR = '#a90100', COLOR_OPFOR_DARK = '#890F0F', COLOR_OPFOR_LIGHT = '#fb5555', COLOR_OPFOR_GREY = '#955c5f', - COLOR_NEUTRAL = '#222222', } diff --git a/static/src/app/utils/global.helpers.ts b/static/src/app/utils/global.helpers.ts index ec0a2e7..aaa346f 100644 --- a/static/src/app/utils/global.helpers.ts +++ b/static/src/app/utils/global.helpers.ts @@ -1,4 +1,6 @@ import {MatButtonToggleGroup} from '@angular/material'; +import {War} from '../models/model-interfaces'; +import {Fraction} from './fraction.enum'; export const CSSHelpers = { getBackgroundCSS: (imageUrl) => { @@ -10,6 +12,90 @@ export const CSSHelpers = { } }; +export const FractionHelpers = { + getFractionColor: (fraction, war?: War, style?) => { + let switchInput; + if (war) { + switchInput = (fraction === 'BLUFOR' ? war.fractionMappingBlufor : war.fractionMappingOpfor); + } else { + switchInput = fraction; + } + + switch (switchInput) { + case Fraction.ARF: + switch (style) { + case 'LIGHT': + return Fraction.COLOR_ARF_LIGHT; + case 'DARK': + return Fraction.COLOR_ARF_DARK; + case 'GREY': + return Fraction.COLOR_ARF_GREY; + default: + return Fraction.COLOR_ARF; + } + case 'BLUFOR': + switch (style) { + case 'LIGHT': + return Fraction.COLOR_BLUFOR_LIGHT; + case 'DARK': + return Fraction.COLOR_BLUFOR_DARK; + case 'GREY': + return Fraction.COLOR_BLUFOR_GREY; + default: + return Fraction.COLOR_BLUFOR; + } + case 'OPFOR': + switch (style) { + case 'LIGHT': + return Fraction.COLOR_OPFOR_LIGHT; + case 'DARK': + return Fraction.COLOR_OPFOR_DARK; + case 'GREY': + return Fraction.COLOR_OPFOR_GREY; + default: + return Fraction.COLOR_OPFOR; + } + case Fraction.SWORD: + switch (style) { + case 'LIGHT': + return Fraction.COLOR_SWORD_LIGHT; + case 'DARK': + return Fraction.COLOR_SWORD_DARK; + case 'GREY': + return Fraction.COLOR_SWORD_GREY; + default: + return Fraction.COLOR_SWORD; + } + } + }, + + getFractionColors: (war: War, fraction) => { + switch (fraction === 'BLUFOR' ? war.fractionMappingBlufor : war.fractionMappingOpfor) { + case Fraction.ARF: + return Fraction.COLOR_ARF; + case 'BLUFOR': + return Fraction.COLOR_BLUFOR; + case 'OPFOR': + return Fraction.COLOR_OPFOR; + case Fraction.SWORD: + return Fraction.COLOR_SWORD; + } + }, + + getFractionName: (war: War, fraction) => { + switch (fraction === 'BLUFOR' ? war.fractionMappingBlufor : war.fractionMappingOpfor) { + case Fraction.ARF: + return Fraction.ARF; + case 'BLUFOR': + return Fraction.BLUFOR; + case 'OPFOR': + return Fraction.OPFOR; + case Fraction.SWORD: + return Fraction.SWORD; + } + } +}; + export const UIHelpers = { toggleReleaseButton: (currentVal, group?: MatButtonToggleGroup) => { if (group) { diff --git a/static/src/assets/i18n/statistics/de.json b/static/src/assets/i18n/statistics/de.json index 85ec42c..461b7cd 100644 --- a/static/src/assets/i18n/statistics/de.json +++ b/static/src/assets/i18n/statistics/de.json @@ -88,6 +88,8 @@ "stats.war.submit.button.submit": "Bestätigen", "stats.war.submit.button.cancel": "Abbrechen", "stats.war.submit.error.file.format": "Logfile muss im Format RPT, LOG oder TXT vorliegen", + "stats.war.submit.mapping.blufor": "Fraktion Zuordnung NATO", + "stats.war.submit.mapping.opfor": "Fraktion Zuordnung CSAT", "stats.campaign.submit.headline.new": "Neue Kampagne hinzufügen", "stats.campaign.submit.headline.edit": "Kampagne editieren", diff --git a/static/src/assets/i18n/statistics/en.json b/static/src/assets/i18n/statistics/en.json index 0e161f3..07a3a64 100644 --- a/static/src/assets/i18n/statistics/en.json +++ b/static/src/assets/i18n/statistics/en.json @@ -95,6 +95,8 @@ "stats.war.submit.button.submit": "Submit", "stats.war.submit.button.cancel": "Cancel", "stats.war.submit.error.file.format": "Logfile requires RPT, LOG or TXT format", + "stats.war.submit.mapping.blufor": "Fraction Mapping NATO", + "stats.war.submit.mapping.opfor": "Fraction Mapping CSAT", "stats.campaign.submit.headline.new": "Add new campaign", "stats.campaign.submit.headline.edit": "Edit campaign",