Add bar chart per player fps visualization (CC-80)
parent
03073f5436
commit
9c6f74c14f
|
@ -4,6 +4,9 @@
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
const async = require('async');
|
const async = require('async');
|
||||||
|
|
||||||
|
// HTTP status codes by name
|
||||||
|
const codes = require('./http-codes');
|
||||||
|
|
||||||
const routerHandling = require('../middleware/router-handling');
|
const routerHandling = require('../middleware/router-handling');
|
||||||
|
|
||||||
// Mongoose Model using mongoDB
|
// Mongoose Model using mongoDB
|
||||||
|
@ -16,6 +19,7 @@ const LogTransportModel = require('../models/logs/transport');
|
||||||
const LogFlagModel = require('../models/logs/flag');
|
const LogFlagModel = require('../models/logs/flag');
|
||||||
const LogPointsModel = require('../models/logs/points');
|
const LogPointsModel = require('../models/logs/points');
|
||||||
const LogPlayerCountModel = require('../models/logs/player-count');
|
const LogPlayerCountModel = require('../models/logs/player-count');
|
||||||
|
const LogServerFpsModel = require('../models/logs/server-fps');
|
||||||
|
|
||||||
const logsRouter = new express.Router();
|
const logsRouter = new express.Router();
|
||||||
|
|
||||||
|
@ -24,7 +28,7 @@ const processLogRequest = (model, filter, res, next) => {
|
||||||
if (err) return next(err);
|
if (err) return next(err);
|
||||||
if (!log || log.length === 0) {
|
if (!log || log.length === 0) {
|
||||||
const err = new Error('No logs found');
|
const err = new Error('No logs found');
|
||||||
err.status = require('./http-codes').notfound;
|
err.status = codes.notfound;
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
res.locals.items = log;
|
res.locals.items = log;
|
||||||
|
@ -154,6 +158,24 @@ logsRouter.route('/:warId/points')
|
||||||
routerHandling.httpMethodNotAllowed
|
routerHandling.httpMethodNotAllowed
|
||||||
);
|
);
|
||||||
|
|
||||||
|
logsRouter.route('/:warId/performance')
|
||||||
|
.get((req, res, next) => {
|
||||||
|
const filter = {war: req.params.warId};
|
||||||
|
LogServerFpsModel.find(filter, (err, items) => {
|
||||||
|
if (err) return next(err);
|
||||||
|
if (!items) {
|
||||||
|
const err = new Error('No logs found');
|
||||||
|
err.status = codes.notfound;
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
res.locals.items = items;
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.all(
|
||||||
|
routerHandling.httpMethodNotAllowed
|
||||||
|
);
|
||||||
|
|
||||||
logsRouter.use(routerHandling.emptyResponse);
|
logsRouter.use(routerHandling.emptyResponse);
|
||||||
|
|
||||||
module.exports = logsRouter;
|
module.exports = logsRouter;
|
||||||
|
|
|
@ -35,6 +35,7 @@ export interface Player {
|
||||||
revive?: number;
|
revive?: number;
|
||||||
respawn?: number;
|
respawn?: number;
|
||||||
flagTouch?: number;
|
flagTouch?: number;
|
||||||
|
performance?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CampaignPlayer {
|
export interface CampaignPlayer {
|
||||||
|
|
|
@ -68,4 +68,8 @@ export class LogsService {
|
||||||
params.append('defend', defendOnly ? 'true' : '');
|
params.append('defend', defendOnly ? 'true' : '');
|
||||||
return this.httpGateway.get(this.config.apiLogsPath + '/' + warId + '/flag', params);
|
return this.httpGateway.get(this.config.apiLogsPath + '/' + warId + '/flag', params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getPerformanceLogs(warId: string) {
|
||||||
|
return this.httpGateway.get(this.config.apiLogsPath + '/' + warId + '/performance');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,8 @@
|
||||||
</mat-button-toggle-group>
|
</mat-button-toggle-group>
|
||||||
|
|
||||||
<div class="chart-container">
|
<div class="chart-container">
|
||||||
<ngx-charts-line-chart
|
<ngx-charts-bar-vertical
|
||||||
[results]="lineChartData"
|
[results]="barChartData"
|
||||||
[gradient]="gradient"
|
[gradient]="gradient"
|
||||||
[xAxis]="xAxis"
|
[xAxis]="xAxis"
|
||||||
[yAxis]="yAxis"
|
[yAxis]="yAxis"
|
||||||
|
@ -19,10 +19,26 @@
|
||||||
[legendTitle]="legendTitle"
|
[legendTitle]="legendTitle"
|
||||||
[showXAxisLabel]="showXAxisLabel"
|
[showXAxisLabel]="showXAxisLabel"
|
||||||
[showYAxisLabel]="showYAxisLabel"
|
[showYAxisLabel]="showYAxisLabel"
|
||||||
[yAxisLabel]="lineChartLabel"
|
[yAxisLabel]="barChartLabel"
|
||||||
[autoScale]="autoscale"
|
[barPadding]="2"
|
||||||
[timeline]="timeline"
|
|
||||||
[roundDomains]="roundDomains">
|
[roundDomains]="roundDomains">
|
||||||
</ngx-charts-line-chart>
|
</ngx-charts-bar-vertical>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!--<div class="chart-container">-->
|
||||||
|
<!--<ngx-charts-line-chart-->
|
||||||
|
<!--[results]="barChartData"-->
|
||||||
|
<!--[gradient]="gradient"-->
|
||||||
|
<!--[xAxis]="xAxis"-->
|
||||||
|
<!--[yAxis]="yAxis"-->
|
||||||
|
<!--[legend]="legend"-->
|
||||||
|
<!--[legendTitle]="legendTitle"-->
|
||||||
|
<!--[showXAxisLabel]="showXAxisLabel"-->
|
||||||
|
<!--[showYAxisLabel]="showYAxisLabel"-->
|
||||||
|
<!--[yAxisLabel]="barChartLabel"-->
|
||||||
|
<!--[autoScale]="autoscale"-->
|
||||||
|
<!--[timeline]="timeline"-->
|
||||||
|
<!--[roundDomains]="roundDomains">-->
|
||||||
|
<!--</ngx-charts-line-chart>-->
|
||||||
|
<!--</div>-->
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import {Component, ElementRef, Input, OnChanges, OnInit, SimpleChanges, ViewChild} from '@angular/core';
|
import {Component, ElementRef, Input, OnChanges, OnInit, SimpleChanges, ViewChild} from '@angular/core';
|
||||||
import {ChartUtils} from '../../../utils/chart-utils';
|
|
||||||
import {War} from '../../../models/model-interfaces';
|
import {War} from '../../../models/model-interfaces';
|
||||||
import {TranslateService} from '@ngx-translate/core';
|
import {TranslateService} from '@ngx-translate/core';
|
||||||
|
|
||||||
|
@ -19,21 +18,19 @@ export class ServerStatsComponent implements OnInit, OnChanges {
|
||||||
|
|
||||||
startDateObj: Date;
|
startDateObj: Date;
|
||||||
|
|
||||||
initialized: any;
|
|
||||||
|
|
||||||
public activeChartSelect: string;
|
public activeChartSelect: string;
|
||||||
|
|
||||||
|
barChartData: any[] = [];
|
||||||
|
|
||||||
lineChartData: any[] = [];
|
lineChartData: any[] = [];
|
||||||
|
|
||||||
tmpPointData;
|
showBarChart = true;
|
||||||
tmpBudgetData;
|
|
||||||
tmpKillData;
|
tmpSingleAvg;
|
||||||
tmpFrienlyFireData;
|
tmpSingleMin;
|
||||||
tmpVehicleData;
|
tmpAvgTimeline;
|
||||||
tmpTransportData;
|
tmpMinTimeline;
|
||||||
tmpReviveData;
|
tmpServerTimeline;
|
||||||
tmpStabilizeData;
|
|
||||||
tmpFlagCaptureData;
|
|
||||||
|
|
||||||
readonly labels = {
|
readonly labels = {
|
||||||
singleAvg: 'stats.performance.select.single.avg',
|
singleAvg: 'stats.performance.select.single.avg',
|
||||||
|
@ -45,6 +42,7 @@ export class ServerStatsComponent implements OnInit, OnChanges {
|
||||||
readonly labelsAsString = Object.keys(this.labels)
|
readonly labelsAsString = Object.keys(this.labels)
|
||||||
.map((key) => this.labels[key]);
|
.map((key) => this.labels[key]);
|
||||||
|
|
||||||
|
barChartLabel: string;
|
||||||
lineChartLabel: string;
|
lineChartLabel: string;
|
||||||
|
|
||||||
gradient = false;
|
gradient = false;
|
||||||
|
@ -62,21 +60,14 @@ export class ServerStatsComponent implements OnInit, OnChanges {
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.setLineChartLabel(this.labels.singleAvg);
|
this.setBarChartLabel(this.labels.singleAvg);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges(changes: SimpleChanges) {
|
ngOnChanges(changes: SimpleChanges) {
|
||||||
if (changes.war || changes.performanceData) {
|
if (changes.war || changes.performanceData) {
|
||||||
this.initialized = {
|
this.initializeChartData();
|
||||||
budget: false,
|
Object.assign(this, [this.barChartData]);
|
||||||
kill: false,
|
|
||||||
revive: false,
|
|
||||||
transport: false,
|
|
||||||
flag: false
|
|
||||||
};
|
|
||||||
Object.assign(this, [this.lineChartData]);
|
|
||||||
this.activeChartSelect = this.labels.singleAvg;
|
this.activeChartSelect = this.labels.singleAvg;
|
||||||
|
|
||||||
this.startDateObj = new Date(this.war.date);
|
this.startDateObj = new Date(this.war.date);
|
||||||
this.startDateObj.setHours(0);
|
this.startDateObj.setHours(0);
|
||||||
this.startDateObj.setMinutes(1);
|
this.startDateObj.setMinutes(1);
|
||||||
|
@ -85,31 +76,60 @@ export class ServerStatsComponent implements OnInit, OnChanges {
|
||||||
|
|
||||||
selectChart(newSelection) {
|
selectChart(newSelection) {
|
||||||
this.activeChartSelect = newSelection;
|
this.activeChartSelect = newSelection;
|
||||||
this.setLineChartLabel(this.activeChartSelect);
|
if (this.activeChartSelect !== this.labels.serverFps) {
|
||||||
console.log('############### apply data ##################');
|
this.showBarChart = true;
|
||||||
}
|
this.setBarChartLabel(this.activeChartSelect);
|
||||||
|
switch (this.activeChartSelect) {
|
||||||
addFinalTimeData(tmpCollection) {
|
case this.labels.singleAvg:
|
||||||
const endDate = new Date(this.war.endDate);
|
this.barChartData = this.tmpSingleAvg;
|
||||||
if (tmpCollection === this.tmpBudgetData) {
|
break;
|
||||||
this.tmpBudgetData[0].series.push(ChartUtils.getSeriesEntry(endDate, this.war.endBudgetBlufor));
|
case this.labels.singleMin:
|
||||||
this.tmpBudgetData[1].series.push(ChartUtils.getSeriesEntry(endDate, this.war.endBudgetOpfor));
|
this.barChartData = this.tmpSingleMin;
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
for (let j = 0; j < tmpCollection.length; j++) {
|
this.showBarChart = false;
|
||||||
// mayBe check is needed for logs that are simply not existent in older wars, i.e. vehicleKills
|
this.setLineChartLabel(this.activeChartSelect);
|
||||||
const maybeLast = tmpCollection[j].series[tmpCollection[j].series.length - 1];
|
switch (this.activeChartSelect) {
|
||||||
if (maybeLast && maybeLast.name < endDate) {
|
case this.labels.avgTimeline:
|
||||||
tmpCollection[j].series.push(
|
this.lineChartData = this.tmpAvgTimeline;
|
||||||
ChartUtils.getSeriesEntry(endDate, tmpCollection[j].series[tmpCollection[j].series.length - 1].value)
|
break;
|
||||||
);
|
case this.labels.minTimeline:
|
||||||
}
|
this.lineChartData = this.tmpMinTimeline;
|
||||||
|
break;
|
||||||
|
case this.labels.serverFps:
|
||||||
|
this.lineChartData = this.tmpServerTimeline;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initializeChartData() {
|
||||||
|
this.tmpSingleAvg = [];
|
||||||
|
this.tmpSingleMin = [];
|
||||||
|
this.performanceData.forEach((entry) => {
|
||||||
|
this.tmpSingleAvg.push({
|
||||||
|
name: entry.entityName,
|
||||||
|
value: entry.singleAvgFps
|
||||||
|
});
|
||||||
|
this.tmpSingleMin.push({
|
||||||
|
name: entry.entityName,
|
||||||
|
value: entry.singleMinFps
|
||||||
|
});
|
||||||
|
});
|
||||||
|
this.tmpSingleAvg.sort((a, b) => a.value - b.value);
|
||||||
|
this.tmpSingleMin.sort((a, b) => a.value - b.value);
|
||||||
|
this.barChartData = this.tmpSingleAvg;
|
||||||
|
}
|
||||||
|
|
||||||
setLineChartLabel(i18n: string) {
|
setLineChartLabel(i18n: string) {
|
||||||
this.translate.get(i18n).subscribe((translated) => {
|
this.translate.get(i18n).subscribe((translated) => {
|
||||||
this.lineChartLabel = translated;
|
this.lineChartLabel = translated;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setBarChartLabel(i18n: string) {
|
||||||
|
this.translate.get(i18n).subscribe((translated) => {
|
||||||
|
this.barChartLabel = translated;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
{{'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)">
|
<li class="nav-item" [ngClass]="{active :tab === 3}" (click)="switchTab(3)" *ngIf="war && war.players[0].performance">
|
||||||
<a class="nav-link">
|
<a class="nav-link">
|
||||||
<mat-icon svgIcon="stats-performance" class="mat-icon-stats-performance"></mat-icon>
|
<mat-icon svgIcon="stats-performance" class="mat-icon-stats-performance"></mat-icon>
|
||||||
{{'stats.scoreboard.tab.performance' | translate}}
|
{{'stats.scoreboard.tab.performance' | translate}}
|
||||||
|
@ -109,7 +109,7 @@
|
||||||
<cc-server-statistics
|
<cc-server-statistics
|
||||||
*ngIf="tab === 3"
|
*ngIf="tab === 3"
|
||||||
[war]="war"
|
[war]="war"
|
||||||
[performanceData]="[]">
|
[performanceData]="performanceData">
|
||||||
</cc-server-statistics>
|
</cc-server-statistics>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -23,14 +23,18 @@ export class WarHeaderComponent implements OnInit {
|
||||||
|
|
||||||
logData;
|
logData;
|
||||||
|
|
||||||
|
fractionStatsInitialized: boolean;
|
||||||
|
|
||||||
|
performanceData;
|
||||||
|
|
||||||
|
performanceStatsInitialized: boolean;
|
||||||
|
|
||||||
singlePlayerView: number;
|
singlePlayerView: number;
|
||||||
|
|
||||||
playerDetailName: string;
|
playerDetailName: string;
|
||||||
|
|
||||||
tab: number;
|
tab: number;
|
||||||
|
|
||||||
fractionStatsInitialized: boolean;
|
|
||||||
|
|
||||||
fractionFilterSelected: string;
|
fractionFilterSelected: string;
|
||||||
|
|
||||||
playerChart: any[] = [];
|
playerChart: any[] = [];
|
||||||
|
@ -70,6 +74,12 @@ export class WarHeaderComponent implements OnInit {
|
||||||
this.fractionStatsInitialized = true;
|
this.fractionStatsInitialized = true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (index === 3 && !this.performanceStatsInitialized) {
|
||||||
|
this.logsService.getPerformanceLogs(this.war._id).subscribe(log => {
|
||||||
|
this.performanceData = log;
|
||||||
|
this.performanceStatsInitialized = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue