Add new server performance stats page
							parent
							
								
									818e99e973
								
							
						
					
					
						commit
						b99825b01a
					
				| 
						 | 
					@ -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
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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',
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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>
 | 
				
			||||||
| 
						 | 
					@ -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;
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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  | 
		Loading…
	
		Reference in New Issue