diff --git a/server/models/player.js b/server/models/player.js
index 85bd6f3..da3f07d 100644
--- a/server/models/player.js
+++ b/server/models/player.js
@@ -85,7 +85,7 @@ const PlayerSchema = new Schema({
performance: {
type: mongoose.Schema.Types.ObjectId,
ref: 'LogServerFpsSchema',
- required: true,
+ required: false,
},
}, {
collection: 'player',
diff --git a/server/routes/wars.js b/server/routes/wars.js
index 62984b4..0ec1ef9 100644
--- a/server/routes/wars.js
+++ b/server/routes/wars.js
@@ -74,25 +74,37 @@ wars.route('/')
if (err) {
return next(err);
}
- LogKillModel.create(statsResult.kills, () => {
- LogVehicleKillModel.create(statsResult.vehicles, () => {
- LogRespawnModel.create(statsResult.respawn, () => {
- LogReviveModel.create(statsResult.revive, () => {
- LogFlagModel.create(statsResult.flag, () => {
- LogBudgetModel.create(statsResult.budget, () => {
- LogTransportModel.create(statsResult.transport, () => {
- LogPlayerCountModel.create(statsResult.playerCount, () => {
- LogPointsModel.create(statsResult.points, () => {
+ LogKillModel.create(statsResult.kills, (err) => {
+ if (err) console.log(err);
+ LogVehicleKillModel.create(statsResult.vehicles, (err) => {
+ if (err) console.log(err);
+ LogRespawnModel.create(statsResult.respawn, (err) => {
+ if (err) console.log(err);
+ LogReviveModel.create(statsResult.revive, (err) => {
+ if (err) console.log(err);
+ LogFlagModel.create(statsResult.flag, (err) => {
+ if (err) console.log(err);
+ LogBudgetModel.create(statsResult.budget, (err) => {
+ if (err) console.log(err);
+ LogTransportModel.create(statsResult.transport, (err) => {
+ if (err) console.log(err);
+ LogPlayerCountModel.create(statsResult.playerCount, (err) => {
+ if (err) console.log(err);
+ LogPointsModel.create(statsResult.points, (err) => {
+ if (err) console.log(err);
LogServerFpsModel.create(statsResult.serverFps, (err, serverPerformanceEntries) => {
- serverPerformanceEntries.forEach((entry) => {
- const idx = statsResult.players
- .findIndex((player) => player.name === entry.entityName);
- if (idx !== -1) {
- const player = statsResult.players[idx];
- player['performance'] = entry._id;
- statsResult.players[idx] = player;
- }
- });
+ if (err) console.log(err);
+ if (serverPerformanceEntries) {
+ serverPerformanceEntries.forEach((entry) => {
+ const idx = statsResult.players
+ .findIndex((player) => player.name === entry.entityName);
+ if (idx !== -1) {
+ const player = statsResult.players[idx];
+ player['performance'] = entry._id;
+ statsResult.players[idx] = player;
+ }
+ });
+ }
PlayerModel.create(statsResult.players, (err) => {
if (err) {
return next(err);
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 09192f3..bb1f534 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
@@ -9,9 +9,10 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
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 68724e4..ea224c1 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
@@ -1,6 +1,7 @@
import {Component, ElementRef, Input, OnChanges, OnInit, SimpleChanges, ViewChild} from '@angular/core';
import {War} from '../../../models/model-interfaces';
import {TranslateService} from '@ngx-translate/core';
+import {ChartUtils} from '../../../utils/chart-utils';
@Component({
@@ -20,11 +21,9 @@ export class ServerStatsComponent implements OnInit, OnChanges {
public activeChartSelect: string;
- barChartData: any[] = [];
-
- lineChartData: any[] = [];
-
showBarChart = true;
+ barChartData: any[] = [];
+ lineChartData: any[] = [];
tmpSingleAvg;
tmpSingleMin;
@@ -32,6 +31,8 @@ export class ServerStatsComponent implements OnInit, OnChanges {
tmpMinTimeline;
tmpServerTimeline;
+ barChartLabel: string;
+ lineChartLabel: string;
readonly labels = {
singleAvg: 'stats.performance.select.single.avg',
singleMin: 'stats.performance.select.single.min',
@@ -42,9 +43,6 @@ export class ServerStatsComponent implements OnInit, OnChanges {
readonly labelsAsString = Object.keys(this.labels)
.map((key) => this.labels[key]);
- barChartLabel: string;
- lineChartLabel: string;
-
gradient = false;
yAxis = true;
xAxis = true;
@@ -55,6 +53,15 @@ export class ServerStatsComponent implements OnInit, OnChanges {
autoscale = true;
timeline = false;
roundDomains = true;
+ colorScheme = {
+ name: 'nightLights',
+ selectable: false,
+ group: 'Ordinal',
+ domain: [
+ '#4e31a5', '#9c25a7', '#3065ab', '#57468b', '#904497', '#46648b',
+ '#32118d', '#a00fb3', '#1052a2', '#6e51bd', '#b63cc3', '#6c97cb', '#8671c1', '#b455be', '#7496c3'
+ ]
+ };
constructor(private translate: TranslateService) {
}
@@ -64,19 +71,16 @@ export class ServerStatsComponent implements OnInit, OnChanges {
}
ngOnChanges(changes: SimpleChanges) {
- if (changes.war || changes.performanceData) {
+ if ((changes.war || changes.performanceData) && this.performanceData) {
this.initializeChartData();
Object.assign(this, [this.barChartData]);
this.activeChartSelect = this.labels.singleAvg;
- this.startDateObj = new Date(this.war.date);
- this.startDateObj.setHours(0);
- this.startDateObj.setMinutes(1);
}
}
selectChart(newSelection) {
this.activeChartSelect = newSelection;
- if (this.activeChartSelect !== this.labels.serverFps) {
+ if (this.activeChartSelect === this.labels.singleAvg || this.activeChartSelect === this.labels.singleMin) {
this.showBarChart = true;
this.setBarChartLabel(this.activeChartSelect);
switch (this.activeChartSelect) {
@@ -104,9 +108,52 @@ export class ServerStatsComponent implements OnInit, OnChanges {
}
initializeChartData() {
+ this.tmpAvgTimeline = ChartUtils.getMultiDataArray("min", "avg", "max");
+ this.tmpMinTimeline = ChartUtils.getMultiDataArray("min", "avg", "max");
+ this.tmpServerTimeline = ChartUtils.getMultiDataArray("min", "avg");
+
+ const diffMs = (new Date(this.war.endDate).getTime() - new Date(this.war.date).getTime());
+ const warDurationMinutes = Math.round(diffMs / 60000);
+
+ let dateObj = new Date(this.war.date);
+ dateObj.setHours(0);
+ dateObj.setMinutes(1);
+
this.tmpSingleAvg = [];
this.tmpSingleMin = [];
+ const maxAvgIdx = Math.min(this.performanceData.map(p => p.avgFps.length)
+ .sort((a, b) => b - a)[0], warDurationMinutes);
+ const maxMinIdx = Math.min(this.performanceData.map(p => p.avgFps.length)
+ .sort((a, b) => b - a)[0], warDurationMinutes);
+ let tmpAvgArray = new Array(maxAvgIdx).fill(0);
+ let tmpAvgMin = new Array(maxAvgIdx).fill(1000);
+ let tmpAvgMax = new Array(maxAvgIdx).fill(0);
+ let tmpMinArray = new Array(maxMinIdx).fill(0);
+ let tmpMinMin = new Array(maxMinIdx).fill(1000);
+ let tmpMinMax = new Array(maxMinIdx).fill(0);
+
this.performanceData.forEach((entry) => {
+ if (entry.entityName !== 'SERVER') {
+ // PLAYER AVERAGE TIMELINE DATA
+ for (let i = 0; i < entry.avgFps.length && i < tmpAvgArray.length; i++) {
+ tmpAvgArray[i] = tmpAvgArray[i] + entry.avgFps[i];
+ tmpAvgMin[i] = Math.round(Math.min(tmpAvgMin[i], entry.avgFps[i]));
+ tmpAvgMax[i] = Math.round(Math.max(tmpAvgMax[i], entry.avgFps[i]));
+ }
+ // PLAYER MINIMUM TIMELINE DATA
+ for (let i = 0; i < entry.minFps.length && i < tmpMinArray.length; i++) {
+ tmpMinArray[i] = tmpMinArray[i] + entry.minFps[i];
+ tmpMinMin[i] = Math.round(Math.min(tmpMinMin[i], entry.minFps[i]));
+ tmpMinMax[i] = Math.round(Math.max(tmpMinMax[i], entry.minFps[i]));
+ }
+ } else {
+ // SERVER TIMELINE DATA
+ for (let i = 0; i < entry.avgFps.length && i < warDurationMinutes; i++) {
+ const currDate = new Date(dateObj.getTime() + i * 60000);
+ this.tmpServerTimeline[0].series.push(ChartUtils.getSeriesEntry(currDate, entry.minFps[i]));
+ this.tmpServerTimeline[1].series.push(ChartUtils.getSeriesEntry(currDate, entry.avgFps[i]));
+ }
+ }
this.tmpSingleAvg.push({
name: entry.entityName,
value: entry.singleAvgFps
@@ -116,6 +163,21 @@ export class ServerStatsComponent implements OnInit, OnChanges {
value: entry.singleMinFps
});
});
+
+ tmpAvgArray = tmpAvgArray.map(x => Math.round(x / this.performanceData.length));
+ for (let i = 0; i < tmpAvgArray.length; i++) {
+ const currDate = new Date(dateObj.getTime() + i * 60000);
+ this.tmpAvgTimeline[0].series.push(ChartUtils.getSeriesEntry(currDate, tmpAvgMin[i]));
+ this.tmpAvgTimeline[1].series.push(ChartUtils.getSeriesEntry(currDate, tmpAvgArray[i]));
+ this.tmpAvgTimeline[2].series.push(ChartUtils.getSeriesEntry(currDate, tmpAvgMax[i]));
+ }
+ tmpMinArray = tmpMinArray.map(x => Math.round(x / this.performanceData.length));
+ for (let i = 0; i < tmpMinArray.length; i++) {
+ const currDate = new Date(dateObj.getTime() + i * 60000);
+ this.tmpMinTimeline[0].series.push(ChartUtils.getSeriesEntry(currDate, tmpMinMin[i]));
+ this.tmpMinTimeline[1].series.push(ChartUtils.getSeriesEntry(currDate, tmpMinArray[i]));
+ this.tmpMinTimeline[2].series.push(ChartUtils.getSeriesEntry(currDate, tmpMinMax[i]));
+ }
this.tmpSingleAvg.sort((a, b) => a.value - b.value);
this.tmpSingleMin.sort((a, b) => a.value - b.value);
this.barChartData = this.tmpSingleAvg;
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 e922d3d..673a9a6 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
@@ -48,8 +48,9 @@
{{'stats.scoreboard.tab.player' | translate}}
-
-
+
+
{{'stats.scoreboard.tab.performance' | translate}}