Add new server performance stats page

pull/51/head
HardiReady 2019-02-07 21:05:58 +01:00
parent 818e99e973
commit b99825b01a
11 changed files with 218 additions and 4 deletions

2
.gitignore vendored
View File

@ -45,7 +45,7 @@ Thumbs.db
.directory .directory
# Internal Data # Internal Data
public/ /public/
mongodb-data/ mongodb-data/
server/resource/ server/resource/
server/apib/dredd/data/tmp-resource server/apib/dredd/data/tmp-resource

View File

@ -52,6 +52,7 @@ export class AppComponent implements OnInit {
'stats-fraction': 'stats/fraction-btn', 'stats-fraction': 'stats/fraction-btn',
'stats-player': 'stats/player-stats-btn', 'stats-player': 'stats/player-stats-btn',
'stats-scoreboard': 'stats/scoreboard-btn', 'stats-scoreboard': 'stats/scoreboard-btn',
'stats-performance': 'stats/performance-stats-btn',
// --SCOREBOARD-- // --SCOREBOARD--
'death': 'stats/scoreboard/death', 'death': 'stats/scoreboard/death',
'flagTouch': 'stats/scoreboard/flag-touch', 'flagTouch': 'stats/scoreboard/flag-touch',

View File

@ -13,6 +13,7 @@ import {WarHeaderComponent} from './war/war-header/war-header.component';
import {LoginGuardMT} from '../login'; import {LoginGuardMT} from '../login';
import {CampaignNavigationComponent} from './campaign/campaign-navigation/campaign-navigation.component'; import {CampaignNavigationComponent} from './campaign/campaign-navigation/campaign-navigation.component';
import {StatisticOverviewComponent} from './campaign/overview/campaign-overview.component'; import {StatisticOverviewComponent} from './campaign/overview/campaign-overview.component';
import {ServerStatsComponent} from './war/server-stats/server-stats.component';
export const statsRoutes: Routes = [ export const statsRoutes: Routes = [
@ -69,5 +70,6 @@ export const statsRouterModule: ModuleWithProviders = RouterModule.forChild(stat
export const statsRoutingComponents = [StatisticComponent, StatisticOverviewComponent, StatisticHighScoreComponent, export const statsRoutingComponents = [StatisticComponent, StatisticOverviewComponent, StatisticHighScoreComponent,
CampaignSubmitComponent, WarListComponent, WarSubmitComponent, WarHeaderComponent, ScoreboardComponent, CampaignSubmitComponent, WarListComponent, WarSubmitComponent, WarHeaderComponent, ScoreboardComponent,
FractionStatsComponent, CampaignPlayerDetailComponent, WarItemComponent, CampaignNavigationComponent]; FractionStatsComponent, CampaignPlayerDetailComponent, WarItemComponent, CampaignNavigationComponent,
ServerStatsComponent];

View File

@ -0,0 +1,37 @@
.chart-select-group {
display: flex;
width: fit-content;
margin: auto;
}
:host /deep/ mat-button-toggle {
color: #666666;
background: #e7e7e7;
}
:host /deep/ mat-button-toggle:hover {
background: #afafaf;
}
:host /deep/ mat-button-toggle.mat-button-toggle-checked {
background: #ffffff;
}
:host /deep/ label.mat-button-toggle-label {
margin: 2px 0;
}
:host /deep/ div.mat-button-toggle-label-content {
line-height: 25px;
margin-bottom: 0;
font-weight: normal;
}
.chart-container {
width: 95%;
margin: 2%;
min-width: 900px;
height: 50vh;
padding: 15px;
float: left;
}

View File

@ -0,0 +1,28 @@
<div class="fade-in" style="border-top: 1px solid #dadada; padding-top:25px;" xmlns="http://www.w3.org/1999/html">
<mat-button-toggle-group class="chart-select-group"
#group="matButtonToggleGroup"
[(ngModel)]="activeChartSelect"
(change)="selectChart(group.value)">
<mat-button-toggle *ngFor="let label of labelsAsString" value="{{label}}">
{{label | translate}}
</mat-button-toggle>
</mat-button-toggle-group>
<div class="chart-container">
<ngx-charts-line-chart
[results]="lineChartData"
[gradient]="gradient"
[xAxis]="xAxis"
[yAxis]="yAxis"
[legend]="legend"
[legendTitle]="legendTitle"
[showXAxisLabel]="showXAxisLabel"
[showYAxisLabel]="showYAxisLabel"
[yAxisLabel]="lineChartLabel"
[autoScale]="autoscale"
[timeline]="timeline"
[roundDomains]="roundDomains">
</ngx-charts-line-chart>
</div>
</div>

View File

@ -0,0 +1,115 @@
import {Component, ElementRef, Input, OnChanges, OnInit, SimpleChanges, ViewChild} from '@angular/core';
import {ChartUtils} from '../../../utils/chart-utils';
import {War} from '../../../models/model-interfaces';
import {TranslateService} from '@ngx-translate/core';
@Component({
selector: 'cc-server-statistics',
templateUrl: './server-stats.component.html',
styleUrls: ['./server-stats.component.css', '../../../style/list-entry.css', '../../../style/hide-scrollbar.css']
})
export class ServerStatsComponent implements OnInit, OnChanges {
@ViewChild('overview') private overviewContainer: ElementRef;
@Input() war: War;
@Input() performanceData: any;
startDateObj: Date;
initialized: any;
public activeChartSelect: string;
lineChartData: any[] = [];
tmpPointData;
tmpBudgetData;
tmpKillData;
tmpFrienlyFireData;
tmpVehicleData;
tmpTransportData;
tmpReviveData;
tmpStabilizeData;
tmpFlagCaptureData;
readonly labels = {
points: 'stats.fraction.select.points',
budget: 'stats.fraction.select.budget',
kill: 'stats.fraction.select.kills',
friendlyFire: 'stats.fraction.select.friendly.fire',
vehicle: 'stats.fraction.select.vehicle.kills',
};
readonly labelsAsString = Object.keys(this.labels)
.map((key) => this.labels[key]);
lineChartLabel: string;
gradient = false;
yAxis = true;
xAxis = true;
legend = false;
legendTitle = false;
showXAxisLabel = false;
showYAxisLabel = true;
autoscale = true;
timeline = false;
roundDomains = true;
constructor(private translate: TranslateService) {
}
ngOnInit() {
this.setLineChartLabel(this.labels.points);
}
ngOnChanges(changes: SimpleChanges) {
if (changes.war || changes.performanceData) {
this.initialized = {
budget: false,
kill: false,
revive: false,
transport: false,
flag: false
};
Object.assign(this, [this.lineChartData]);
this.activeChartSelect = this.labels.points;
this.startDateObj = new Date(this.war.date);
this.startDateObj.setHours(0);
this.startDateObj.setMinutes(1);
}
}
selectChart(newSelection) {
this.activeChartSelect = newSelection;
this.setLineChartLabel(this.activeChartSelect);
console.log('############### apply data ##################');
}
addFinalTimeData(tmpCollection) {
const endDate = new Date(this.war.endDate);
if (tmpCollection === this.tmpBudgetData) {
this.tmpBudgetData[0].series.push(ChartUtils.getSeriesEntry(endDate, this.war.endBudgetBlufor));
this.tmpBudgetData[1].series.push(ChartUtils.getSeriesEntry(endDate, this.war.endBudgetOpfor));
} else {
for (let j = 0; j < tmpCollection.length; j++) {
// mayBe check is needed for logs that are simply not existent in older wars, i.e. vehicleKills
const maybeLast = tmpCollection[j].series[tmpCollection[j].series.length - 1];
if (maybeLast && maybeLast.name < endDate) {
tmpCollection[j].series.push(
ChartUtils.getSeriesEntry(endDate, tmpCollection[j].series[tmpCollection[j].series.length - 1].value)
);
}
}
}
}
setLineChartLabel(i18n: string) {
this.translate.get(i18n).subscribe((translated) => {
this.lineChartLabel = translated;
});
}
}

View File

@ -16,7 +16,7 @@ form.tab-control {
} }
span.tab-control { span.tab-control {
margin: 4px 67px; margin: 4px 30px 4px 55px;
padding: 4px 16px; padding: 4px 16px;
} }
@ -39,8 +39,12 @@ span.tab-control {
vertical-align: middle; vertical-align: middle;
} }
:host/deep/.mat-icon-stats-performance g {
stroke: #666666;
}
.nav-tabs { .nav-tabs {
width: 920px; width: 1000px;
margin: auto; margin: auto;
clear: both; clear: both;
border-bottom: 0; border-bottom: 0;

View File

@ -48,6 +48,12 @@
{{'stats.scoreboard.tab.player' | translate}} {{'stats.scoreboard.tab.player' | translate}}
</a> </a>
</li> </li>
<li class="nav-item" [ngClass]="{active :tab === 3}" (click)="switchTab(3)">
<a class="nav-link">
<mat-icon svgIcon="stats-performance" class="mat-icon-stats-performance"></mat-icon>
{{'stats.scoreboard.tab.performance' | translate}}
</a>
</li>
<li> <li>
<div *ngIf="tab === 0"> <div *ngIf="tab === 0">
<form class="pull-left tab-control"> <form class="pull-left tab-control">
@ -100,6 +106,11 @@
[playerName]="playerDetailName" [playerName]="playerDetailName"
(switchTab)="switchTab($event)"> (switchTab)="switchTab($event)">
</campaign-player-detail> </campaign-player-detail>
<cc-server-statistics
*ngIf="tab === 3"
[war]="war"
[performanceData]="[]">
</cc-server-statistics>
</div> </div>
</div> </div>

View File

@ -41,6 +41,7 @@
"stats.scoreboard.tab.scoreboard": "Scoreboard", "stats.scoreboard.tab.scoreboard": "Scoreboard",
"stats.scoreboard.tab.fractions": "Fraktionen", "stats.scoreboard.tab.fractions": "Fraktionen",
"stats.scoreboard.tab.player": "Spieler", "stats.scoreboard.tab.player": "Spieler",
"stats.scoreboard.tab.performance": "Performance",
"stats.scoreboard.fraction.filter.all": "Alle", "stats.scoreboard.fraction.filter.all": "Alle",
"stats.scoreboard.header.player": "Spieler", "stats.scoreboard.header.player": "Spieler",
"stats.scoreboard.header.fraction": "Fraktion", "stats.scoreboard.header.fraction": "Fraktion",

View File

@ -49,6 +49,7 @@
"stats.scoreboard.tab.scoreboard": "Scoreboard", "stats.scoreboard.tab.scoreboard": "Scoreboard",
"stats.scoreboard.tab.fractions": "Fractions", "stats.scoreboard.tab.fractions": "Fractions",
"stats.scoreboard.tab.player": "Player", "stats.scoreboard.tab.player": "Player",
"stats.scoreboard.tab.performance": "Performance",
"stats.scoreboard.fraction.filter.all": "All", "stats.scoreboard.fraction.filter.all": "All",
"stats.scoreboard.header.player": "Player", "stats.scoreboard.header.player": "Player",
"stats.scoreboard.header.fraction": "Fraction", "stats.scoreboard.header.fraction": "Fraction",

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="5.3327in" height="5in" version="1.1" viewBox="0 0 512 490" xmlns="http://www.w3.org/2000/svg">
<g fill="none" stroke="#000" stroke-width="20">
<path id="outline"
d="m328.5 435.5 71.5 0.5 3.5 28.5-289-1.5 10-28.5 62.5 0.5s11-37.5 12.72-53.36c-82.82 0.2-152.22 0.36-152.22 0.36-39.96-4.54-37-34.5-37-34.5l-2-282.5s-0.32-18.24 7-26c9-9.55 26-9 26-9s426.5-1 426.5-1c39.96 4.54 37 34.5 37 34.5l2 282.5s-1.22 15.25-9 23.5c-8.67 9.2-24 11.5-24 11.5s-71.37 0.17-155.73 0.37c8.23 38.63 10.23 54.13 10.23 54.13z"/>
</g>
<g fill="none" stroke="#000" stroke-width="14">
<path id="inline" d="m457 79v230h-400v-233h400z"/>
</g>
<g fill="none" stroke="#000" stroke-width="30">
<path id="arrow"
d="m133.68 258.51 59.2-52.57 54.05 49.13 131.67-131.18m-47.66-0.98s38.33-4.18 48.64-0.49c5.9 5.65-0.24 49.62-0.24 49.62"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 909 B