Merge branch 'feature/statistic-charts' of hardi/opt-cc into master
commit
e8f8936b5e
|
@ -24,6 +24,18 @@ const WarSchema = new Schema({
|
||||||
set: v => Math.round(v),
|
set: v => Math.round(v),
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
|
playersBlufor: {
|
||||||
|
type: Number,
|
||||||
|
get: v => Math.round(v),
|
||||||
|
set: v => Math.round(v),
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
playersOpfor: {
|
||||||
|
type: Number,
|
||||||
|
get: v => Math.round(v),
|
||||||
|
set: v => Math.round(v),
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
bestPlayerId: {
|
bestPlayerId: {
|
||||||
type: mongoose.Schema.Types.ObjectId,
|
type: mongoose.Schema.Types.ObjectId,
|
||||||
ref: 'Player',
|
ref: 'Player',
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -51,11 +51,11 @@ wars.route('/')
|
||||||
const war = new WarModel(body);
|
const war = new WarModel(body);
|
||||||
|
|
||||||
if (req.file) {
|
if (req.file) {
|
||||||
war.save((err, item) => {
|
war.save((err, war) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
const folderName = __dirname + '/../resource/logs/' + item._id;
|
const folderName = __dirname + '/../resource/logs/' + war._id;
|
||||||
mkdirp(folderName, function (err) {
|
mkdirp(folderName, function (err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return next(err);
|
return next(err);
|
||||||
|
@ -65,7 +65,7 @@ wars.route('/')
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
//TODO: combine run and clean in one script, so log file gets touched only once
|
//TODO: combine run and clean in one script, so log file gets touched only once
|
||||||
exec(__dirname + '/../war-parser/run.sh ' + folderName + ' ' + item._id, (error, stdout) => {
|
exec(__dirname + '/../war-parser/run.sh ' + folderName + ' ' + war._id, (error, stdout) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
return next(error);
|
return next(error);
|
||||||
}
|
}
|
||||||
|
@ -74,14 +74,33 @@ wars.route('/')
|
||||||
return next(error);
|
return next(error);
|
||||||
}
|
}
|
||||||
let obj = JSON.parse(`${stdout}`);
|
let obj = JSON.parse(`${stdout}`);
|
||||||
PlayerModel.create(obj, function (err) {
|
for (let i = 0; i < obj.length; i++) {
|
||||||
if (err) {
|
if (obj[i].fraction === 'BLUFOR') {
|
||||||
return next(err);
|
war.playersBlufor++;
|
||||||
|
} else {
|
||||||
|
war.playersOpfor++;
|
||||||
}
|
}
|
||||||
res.status(codes.created);
|
}
|
||||||
res.locals.items = item;
|
|
||||||
return next();
|
WarModel.findByIdAndUpdate(war._id, war, {new: true}, (err, item) => {
|
||||||
});
|
if (err) {
|
||||||
|
err.status = codes.wrongrequest;
|
||||||
|
}
|
||||||
|
else if (!item) {
|
||||||
|
err = new Error("item not found");
|
||||||
|
err.status = codes.notfound;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PlayerModel.create(obj, function (err) {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
res.status(codes.created);
|
||||||
|
res.locals.items = war;
|
||||||
|
return next();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -11,19 +11,22 @@
|
||||||
"e2e": "ng e2e --serve=false"
|
"e2e": "ng e2e --serve=false"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/cli": "1.0.5",
|
"@angular/animations": "^4.3.2",
|
||||||
"@angular/common": "^4.1.1",
|
"@angular/cli": "^1.2.6",
|
||||||
"@angular/compiler": "^4.1.1",
|
"@angular/common": "^4.3.2",
|
||||||
"@angular/compiler-cli": "^4.1.1",
|
"@angular/compiler": "^4.3.2",
|
||||||
"@angular/core": "^4.1.1",
|
"@angular/compiler-cli": "^4.3.2",
|
||||||
"@angular/forms": "^4.1.1",
|
"@angular/core": "^4.3.2",
|
||||||
"@angular/http": "^4.1.1",
|
"@angular/forms": "^4.3.2",
|
||||||
"@angular/platform-browser": "^4.1.1",
|
"@angular/http": "^4.3.2",
|
||||||
"@angular/platform-browser-dynamic": "^4.1.1",
|
"@angular/platform-browser": "^4.3.2",
|
||||||
"@angular/router": "^4.1.1",
|
"@angular/platform-browser-dynamic": "^4.3.2",
|
||||||
|
"@angular/router": "^4.3.2",
|
||||||
|
"@swimlane/ngx-charts": "^6.0.1",
|
||||||
"angular2-datatable": "^0.6.0",
|
"angular2-datatable": "^0.6.0",
|
||||||
"bootstrap": "^3.3.7",
|
"bootstrap": "^3.3.7",
|
||||||
"core-js": "^2.4.1",
|
"core-js": "^2.4.1",
|
||||||
|
"d3": "^4.10.0",
|
||||||
"jquery": "^3.1.0",
|
"jquery": "^3.1.0",
|
||||||
"jquery-ui": "^1.12.0",
|
"jquery-ui": "^1.12.0",
|
||||||
"jquery-ui-bundle": "^1.11.4",
|
"jquery-ui-bundle": "^1.11.4",
|
||||||
|
@ -31,6 +34,7 @@
|
||||||
"rxjs": "^5.2.0",
|
"rxjs": "^5.2.0",
|
||||||
"ts-helpers": "^1.1.1",
|
"ts-helpers": "^1.1.1",
|
||||||
"typescript": "^2.3.2",
|
"typescript": "^2.3.2",
|
||||||
|
"webpack": "^3.4.1",
|
||||||
"zone.js": "^0.8.5"
|
"zone.js": "^0.8.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
@ -24,13 +24,16 @@
|
||||||
<li class="dropdown">
|
<li class="dropdown">
|
||||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
|
||||||
aria-expanded="false">
|
aria-expanded="false">
|
||||||
Schlacht Statistik
|
Statistik
|
||||||
<span class="caret"></span>
|
<span class="caret"></span>
|
||||||
</a>
|
</a>
|
||||||
<ul class="dropdown-menu scrollable-menu">
|
<ul class="dropdown-menu scrollable-menu">
|
||||||
<li *ngIf="loginService.hasPermission(3)">
|
<li *ngIf="loginService.hasPermission(3)">
|
||||||
<a routerLink='/cc-wars' class="link">Hinzufügen...</a>
|
<a routerLink='/cc-wars' class="link">Hinzufügen...</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<a routerLink='/cc-statistic' class="link">Übersicht</a>
|
||||||
|
</li>
|
||||||
<li *ngFor="let war of wars">
|
<li *ngFor="let war of wars">
|
||||||
<a [routerLink]="['/cc-wars/' + war._id]">{{war.title}}
|
<a [routerLink]="['/cc-wars/' + war._id]">{{war.title}}
|
||||||
<small>{{war.date | date: 'dd.MM.yy'}}</small>
|
<small>{{war.date | date: 'dd.MM.yy'}}</small>
|
||||||
|
|
|
@ -33,9 +33,12 @@ import {PromotionService} from "./services/promotion-service/promotion.service";
|
||||||
import {FilterRankPipe} from "./filter/filter.pipe";
|
import {FilterRankPipe} from "./filter/filter.pipe";
|
||||||
import {WarService} from "./services/war-service/war.service";
|
import {WarService} from "./services/war-service/war.service";
|
||||||
import {DataTableModule} from "angular2-datatable";
|
import {DataTableModule} from "angular2-datatable";
|
||||||
|
import {NgxChartsModule} from "@swimlane/ngx-charts";
|
||||||
|
import {BrowserAnimationsModule} from "@angular/platform-browser/animations";
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [BrowserModule, FormsModule, ReactiveFormsModule, appRouting, HttpModule, ClipboardModule, DataTableModule],
|
imports: [BrowserModule, FormsModule, ReactiveFormsModule, appRouting, HttpModule, ClipboardModule, DataTableModule,
|
||||||
|
BrowserAnimationsModule, NgxChartsModule],
|
||||||
providers: [
|
providers: [
|
||||||
HttpClient,
|
HttpClient,
|
||||||
LoginService,
|
LoginService,
|
||||||
|
|
|
@ -14,6 +14,7 @@ import {RequestPromotionComponent} from "./request/promotion/req-promotion.compo
|
||||||
import {ConfirmPromotionComponent} from "./request/confirm-promotion/confirm-promotion.component";
|
import {ConfirmPromotionComponent} from "./request/confirm-promotion/confirm-promotion.component";
|
||||||
import {ConfirmAwardComponent} from "./request/confirm-award/confirm-award.component";
|
import {ConfirmAwardComponent} from "./request/confirm-award/confirm-award.component";
|
||||||
import {warRoutes, warsRoutingComponents} from "./wars/wars.routing";
|
import {warRoutes, warsRoutingComponents} from "./wars/wars.routing";
|
||||||
|
import {StatisticComponent} from "./statistic/statistic.component";
|
||||||
|
|
||||||
|
|
||||||
export const appRoutes: Routes = [
|
export const appRoutes: Routes = [
|
||||||
|
@ -22,6 +23,7 @@ export const appRoutes: Routes = [
|
||||||
{path: '', redirectTo: '/cc-overview', pathMatch: 'full'},
|
{path: '', redirectTo: '/cc-overview', pathMatch: 'full'},
|
||||||
|
|
||||||
{path: 'cc-wars', children: warRoutes},
|
{path: 'cc-wars', children: warRoutes},
|
||||||
|
{path: 'cc-statistic', component: StatisticComponent},
|
||||||
|
|
||||||
{path: 'login', component: LoginComponent},
|
{path: 'login', component: LoginComponent},
|
||||||
{path: 'signup', component: SignupComponent},
|
{path: 'signup', component: SignupComponent},
|
||||||
|
@ -46,7 +48,7 @@ export const appRoutes: Routes = [
|
||||||
export const appRouting = RouterModule.forRoot(appRoutes);
|
export const appRouting = RouterModule.forRoot(appRoutes);
|
||||||
|
|
||||||
export const routingComponents = [LoginComponent, SignupComponent, RequestAwardComponent, RequestPromotionComponent, ConfirmAwardComponent,
|
export const routingComponents = [LoginComponent, SignupComponent, RequestAwardComponent, RequestPromotionComponent, ConfirmAwardComponent,
|
||||||
ConfirmPromotionComponent, AdminComponent, ...armyRoutingComponents, NotFoundComponent, ...usersRoutingComponents,
|
ConfirmPromotionComponent, StatisticComponent, AdminComponent, ...armyRoutingComponents, NotFoundComponent, ...usersRoutingComponents,
|
||||||
...squadsRoutingComponents, ...decorationsRoutingComponents, ...ranksRoutingComponents, ...warsRoutingComponents];
|
...squadsRoutingComponents, ...decorationsRoutingComponents, ...ranksRoutingComponents, ...warsRoutingComponents];
|
||||||
|
|
||||||
export const routingProviders = [LoginGuardSQL, LoginGuardHL, LoginGuardMT, LoginGuardAdmin];
|
export const routingProviders = [LoginGuardSQL, LoginGuardHL, LoginGuardMT, LoginGuardAdmin];
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
h3 {
|
||||||
|
width: 920px;
|
||||||
|
margin-left: 25%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-container {
|
||||||
|
width: 1200px;
|
||||||
|
margin-left: 25%;
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
<h3>Punkte</h3>
|
||||||
|
|
||||||
|
<div class="chart-container">
|
||||||
|
|
||||||
|
<ngx-charts-line-chart
|
||||||
|
[view]="[1050, 400]"
|
||||||
|
[scheme]="colorScheme"
|
||||||
|
[results]="playerData"
|
||||||
|
[gradient]="false"
|
||||||
|
[xAxis]="true"
|
||||||
|
[yAxis]="true"
|
||||||
|
[legend]="true"
|
||||||
|
[legendTitle]="''"
|
||||||
|
[showXAxisLabel]="true"
|
||||||
|
[showYAxisLabel]="true"
|
||||||
|
[xAxisLabel]="'Schlachtdatum'"
|
||||||
|
[yAxisLabel]="'Punkte'"
|
||||||
|
[autoScale]="false"
|
||||||
|
(select)="onSelect($event)">
|
||||||
|
</ngx-charts-line-chart>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3 style="margin-top: 370px;">Spielerzahlen</h3>
|
||||||
|
|
||||||
|
<div class="chart-container">
|
||||||
|
|
||||||
|
<ngx-charts-line-chart
|
||||||
|
[view]="[1050, 350]"
|
||||||
|
[scheme]="colorScheme"
|
||||||
|
[results]="pointData"
|
||||||
|
[gradient]="false"
|
||||||
|
[xAxis]="true"
|
||||||
|
[yAxis]="true"
|
||||||
|
[legend]="true"
|
||||||
|
[legendTitle]="''"
|
||||||
|
[showXAxisLabel]="true"
|
||||||
|
[showYAxisLabel]="true"
|
||||||
|
[xAxisLabel]="'Schlachtdatum'"
|
||||||
|
[yAxisLabel]="'Anzahl Spieler'"
|
||||||
|
[autoScale]="true"
|
||||||
|
(select)="onSelect($event)">
|
||||||
|
</ngx-charts-line-chart>
|
||||||
|
|
||||||
|
</div>
|
|
@ -0,0 +1,92 @@
|
||||||
|
import {Component} from "@angular/core";
|
||||||
|
import {AppComponent} from "../app.component";
|
||||||
|
import {WarService} from "../services/war-service/war.service";
|
||||||
|
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'statistic',
|
||||||
|
templateUrl: './statistic.component.html',
|
||||||
|
styleUrls: ['./statistic.component.css']
|
||||||
|
})
|
||||||
|
export class StatisticComponent {
|
||||||
|
|
||||||
|
pointData: any[] = [];
|
||||||
|
playerData: any[] = [];
|
||||||
|
|
||||||
|
colorScheme = {
|
||||||
|
domain: ['#0000FF', '#B22222']
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor(private appComponent: AppComponent,
|
||||||
|
private warService: WarService) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
let wars = this.appComponent.wars;
|
||||||
|
if (wars.length === 0) {
|
||||||
|
this.warService.getAllWars().subscribe(items => {
|
||||||
|
this.initChart(items);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.initChart(wars);
|
||||||
|
}
|
||||||
|
|
||||||
|
initChart(wars: any[]) {
|
||||||
|
let pointsObj = [
|
||||||
|
{
|
||||||
|
"name": "NATO",
|
||||||
|
"series": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "CSAT",
|
||||||
|
"series": []
|
||||||
|
}];
|
||||||
|
let playersObj = [
|
||||||
|
{
|
||||||
|
"name": "NATO",
|
||||||
|
"series": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "CSAT",
|
||||||
|
"series": []
|
||||||
|
}
|
||||||
|
];
|
||||||
|
for (let i = wars.length - 1; i >= 0; i--) {
|
||||||
|
const isoDate = wars[i].date.slice(0, 10);
|
||||||
|
const dayDate = parseInt(isoDate.slice(8, 10)) + 1;
|
||||||
|
const warDateString = (dayDate < 10 ? "0" + dayDate : dayDate) + '.'
|
||||||
|
+ isoDate.slice(5, 7) + '.' + isoDate.slice(0, 4);
|
||||||
|
|
||||||
|
const bluforData = {
|
||||||
|
name: warDateString,
|
||||||
|
value: wars[i].ptBlufor
|
||||||
|
};
|
||||||
|
const opforData = {
|
||||||
|
name: warDateString,
|
||||||
|
value: wars[i].ptOpfor
|
||||||
|
};
|
||||||
|
const bluforPlayers = {
|
||||||
|
name: warDateString,
|
||||||
|
value: wars[i].playersBlufor
|
||||||
|
};
|
||||||
|
const opforPlayers = {
|
||||||
|
name: warDateString,
|
||||||
|
value: wars[i].playersOpfor
|
||||||
|
};
|
||||||
|
|
||||||
|
playersObj[0].series.push(bluforData);
|
||||||
|
playersObj[1].series.push(opforData);
|
||||||
|
pointsObj[0].series.push(bluforPlayers);
|
||||||
|
pointsObj[1].series.push(opforPlayers);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.pointData = pointsObj;
|
||||||
|
this.playerData = playersObj;
|
||||||
|
Object.assign(this, [this.playerData, this.pointData])
|
||||||
|
}
|
||||||
|
|
||||||
|
onSelect(event) {
|
||||||
|
console.log(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -55,7 +55,7 @@ export class WarSubmitComponent {
|
||||||
this.router.navigate([war._id], {relativeTo: this.route});
|
this.router.navigate([war._id], {relativeTo: this.route});
|
||||||
},
|
},
|
||||||
error => {
|
error => {
|
||||||
this.error = error._body;
|
this.error = error._body.error.message;
|
||||||
this.showErrorLabel = true;
|
this.showErrorLabel = true;
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue