diff --git a/static/src/app/statistic/highscore/highscore.component.css b/static/src/app/statistic/highscore/highscore.component.css new file mode 100644 index 0000000..2666e75 --- /dev/null +++ b/static/src/app/statistic/highscore/highscore.component.css @@ -0,0 +1,31 @@ +.slide-chart-container { + width: 90%; + min-width: 880px; + height: 650px; + margin: auto; + padding-left: 5%; +} + +:host /deep/ .carousel-indicators { + display: none; +} + +:host /deep/ .carousel-control { + width: 5%; + cursor: pointer; +} + +:host /deep/ .chart-legend { + position: absolute; + margin-top: -60px; + margin-left: -220px; +} + +:host /deep/ .chart-legend .legend-labels { + width: 200px; +} + +:host /deep/ .chart-legend .legend-label { + float: left; + padding-left: 14px; +} diff --git a/static/src/app/statistic/highscore/highscore.component.html b/static/src/app/statistic/highscore/highscore.component.html new file mode 100644 index 0000000..6bdb3fc --- /dev/null +++ b/static/src/app/statistic/highscore/highscore.component.html @@ -0,0 +1,5 @@ +
+

{{title}}

+ +
+ diff --git a/static/src/app/statistic/highscore/highscore.component.ts b/static/src/app/statistic/highscore/highscore.component.ts new file mode 100644 index 0000000..7e2756c --- /dev/null +++ b/static/src/app/statistic/highscore/highscore.component.ts @@ -0,0 +1,157 @@ +import {Component} from "@angular/core"; +import {ActivatedRoute} from "@angular/router"; +import {CarouselConfig} from "ngx-bootstrap"; +import {CampaignService} from "../../services/logs/campaign.service"; +import {ChartUtils} from "../../utils/chart-utils"; +import {Fraction} from "../../utils/fraction.enum"; + + +@Component({ + selector: 'stats-highscore', + templateUrl: './highscore.component.html', + styleUrls: ['./highscore.component.css', '../../style/list-entry.css', '../../style/overview.css'], + inputs: ['campaigns'], + providers: [{provide: CarouselConfig, useValue: {interval: false}}] +}) +export class StatisticHighScoreComponent { + + id = ""; + title = ""; + + pointData: any[] = []; + pointSumData: any[] = []; + playerData: any[] = []; + currentData: any[] = []; + activeSlideIndex; + + colorScheme = { + domain: [Fraction.COLOR_BLUFOR, Fraction.COLOR_OPFOR] + }; + gradient = false; + xAxis = true; + yAxis = true; + roundDomains = true; + legend = true; + legendTitle = ''; + showXAxisLabel = true; + showYAxisLabel = true; + yAxisLabel = ""; + autoscale = true; + timeline = false; + + constructor(private route: ActivatedRoute, + private campaignService: CampaignService) { + } + + ngOnInit() { + this.route.params + .map(params => params['id']) + .subscribe((id) => { + this.id = id; + if (this.campaignService.campaigns) { + this.initWars(this.campaignService.campaigns); + } else { + this.campaignService.getAllCampaigns().subscribe(campaigns => { + this.initWars(campaigns); + }) + } + }); + } + + initWars(campaigns) { + let wars = []; + let itemsProcessed = 0; + campaigns = campaigns.filter(campaign => this.id === 'all' || campaign._id === this.id); + campaigns.forEach(campaign => { + wars = wars.concat(campaign.wars); + itemsProcessed++; + if (itemsProcessed === campaigns.length) { + if (this.id === 'all') { + this.title = "Gesamtübersicht"; + wars.sort((a, b) => { + // sort by dates, because older campaign can contain newer war + if (a['date'] > (b['date'])) return -1; + if (a['date'] < (b['date'])) return 1; + return 0; + }) + } else { + this.title = campaign.title; + } + this.initChart(wars); + } + }) + } + + goToSlide(index: number) { + switch (index) { + case 0: + this.currentData = this.pointSumData; + this.yAxisLabel = "Gesamtpunkte"; + break; + case 1: + this.currentData = this.pointData; + this.yAxisLabel = "Punkte"; + break; + case 2: + this.currentData = this.playerData; + this.yAxisLabel = "Anzahl Spieler"; + break; + } + this.activeSlideIndex = index; + } + + 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); + + for (let i = wars.length - 1; i >= 0; i--) { + const j = wars.length - i - 1; + const warDateString = ChartUtils.getShortDateString(wars[i].date); + + pointsObj[0].series.push({ + name: warDateString, + value: wars[i].ptBlufor + }); + pointsObj[1].series.push({ + name: warDateString, + value: wars[i].ptOpfor + }); + pointsSumObj[0].series.push({ + name: warDateString, + value: pointsSumObj[0].series[j - 1] ? + pointsSumObj[0].series[j - 1].value + wars[i].ptBlufor : + wars[i].ptBlufor + }); + pointsSumObj[1].series.push({ + name: warDateString, + value: pointsSumObj[1].series[j - 1] + ? pointsSumObj[1].series[j - 1].value + wars[i].ptOpfor : + wars[i].ptOpfor + }); + playersObj[0].series.push({ + name: warDateString, + value: wars[i].playersBlufor + }); + playersObj[1].series.push({ + name: warDateString, + value: wars[i].playersOpfor + }); + } + + this.pointData = pointsObj; + this.pointSumData = pointsSumObj; + this.playerData = playersObj; + if (this.id != 'all') { + this.goToSlide(0); + } else { + this.goToSlide(1); + } + Object.assign(this, this.currentData); + } + + isActiveSlide(index) { + return this.activeSlideIndex === index ? '#d9edf7' : 'white' + } + +} diff --git a/static/src/app/statistic/stats.routing.ts b/static/src/app/statistic/stats.routing.ts index db263b9..dba063b 100644 --- a/static/src/app/statistic/stats.routing.ts +++ b/static/src/app/statistic/stats.routing.ts @@ -10,6 +10,7 @@ import {WarDetailComponent} from "./war-detail/war-detail.component"; import {ScoreboardComponent} from "./war-detail/scoreboard/scoreboard.component"; import {WarSubmitComponent} from "./war-submit/war-submit.component"; import {FractionStatsComponent} from "./war-detail/fraction-stats/fraction-stats.component"; +import {StatisticHighScoreComponent} from "./highscore/highscore.component"; export const statsRoutes: Routes = [{ @@ -26,6 +27,11 @@ export const statsRoutes: Routes = [{ component: StatisticOverviewComponent, outlet: 'right' }, + { + path: 'highscore/:id', + component: StatisticHighScoreComponent, + outlet: 'right' + }, { path: 'new-campaign', component: CampaignSubmitComponent, @@ -49,7 +55,7 @@ export const statsRoutes: Routes = [{ export const statsRouterModule: ModuleWithProviders = RouterModule.forChild(statsRoutes); -export const statsRoutingComponents = [StatisticComponent, StatisticOverviewComponent, CampaignSubmitComponent, - WarListComponent, WarSubmitComponent, WarDetailComponent, ScoreboardComponent, FractionStatsComponent, - CampaignPlayerDetailComponent, WarItemComponent]; +export const statsRoutingComponents = [StatisticComponent, StatisticOverviewComponent, StatisticHighScoreComponent, + CampaignSubmitComponent, WarListComponent, WarSubmitComponent, WarDetailComponent, ScoreboardComponent, + FractionStatsComponent, CampaignPlayerDetailComponent, WarItemComponent]; diff --git a/static/src/app/statistic/war-list/war-list.component.ts b/static/src/app/statistic/war-list/war-list.component.ts index 85338e4..d4af553 100644 --- a/static/src/app/statistic/war-list/war-list.component.ts +++ b/static/src/app/statistic/war-list/war-list.component.ts @@ -71,7 +71,7 @@ export class WarListComponent implements OnInit { selectHighscore(campaignId) { if (this.selectedWarId != campaignId + this.highscore) { this.selectedWarId = campaignId + this.highscore; - //this.router.navigate([{outlets: {'right': ['highscore', campaignId]}}], {relativeTo: this.route}); + this.router.navigate([{outlets: {'right': ['highscore', campaignId]}}], {relativeTo: this.route}); } }