koersepublicfrontend/src/app/content/poule/poule.component.ts

258 lines
7.5 KiB
TypeScript

import {Component, Input, OnChanges, OnInit, SimpleChanges} from '@angular/core';
import {ChampionshipService} from '../../championship.service';
import {ActivatedRoute} from '@angular/router';
import {distinct, distinctUntilChanged, map} from 'rxjs/operators';
import {combineLatest, Subscription, timer} from 'rxjs';
import {TopmenuService} from '../../topmenu.service';
@Component({
selector: 'app-poule',
templateUrl: './poule.component.html',
styleUrls: ['./poule.component.scss']
})
export class PouleComponent implements OnInit {
public teams: any[] = [];
public times: any[] = [];
public teamtotaltimes: {};
public maxRaces = 0;
private timesIndexed: {};
// these are the best two times for each team, indexed by their id
public bestTwo: {};
public maxLaps = 0;
private subscription: Subscription;
constructor(private championshipService: ChampionshipService, private route: ActivatedRoute, private topmenuService: TopmenuService) {
}
ngOnInit() {
const tier$ = this.route.params.pipe(map(v => v['tier']), distinctUntilChanged());
const poule$ = this.route.params.pipe(map(v => v['poule']), distinctUntilChanged());
const championship$ = this.route.parent.params.pipe(map(v => v['idchampionship']), distinctUntilChanged());
combineLatest(tier$, poule$, championship$).subscribe(([tier, poule, championship]) => {
console.log('tier/poule/champ changed');
console.log(tier);
console.log(poule);
console.log(championship);
if(this.subscription) {
this.subscription.unsubscribe();
this.subscription = undefined;
}
this.championshipService.getPoules(tier, championship).subscribe(poules => {
this.topmenuService.setPoules(poules);
});
this.topmenuService.setPoule(poule);
this.topmenuService.setTier(tier);
// load the data
this.subscription = timer(0, 5000).subscribe(t => {
this.loadData();
});
});
}
get poule() {
return this.topmenuService.poule$.value;
}
get tier() {
return this.topmenuService.tier$.value;
}
private loadData() {
// this.teams = [];
// this.times = [];
console.log('loading data.');
// fetch the poule data
this.championshipService.getTeamsInPoule(this.topmenuService.championship$.value, this.topmenuService.tier$.value,
this.topmenuService.poule$.value)
.subscribe(val => {
this.teams = val;
// calculate the maximum of the racecounts... this influences the amount of columns in the table
let maxRaces = 0;
this.teams.forEach(t => {
if (t.racecount > maxRaces) {
maxRaces = t.racecount;
}
});
this.maxRaces = maxRaces;
});
this.championshipService.getTimesInPoule(this.topmenuService.championship$.value, this.topmenuService.tier$.value,
this.topmenuService.poule$.value).subscribe(val => {
this.times = val;
// preprocess this array -> map idteam on the laptime array so we can index it using 0..n-1
this.timesIndexed = {};
this.teamtotaltimes = {};
this.maxLaps = 0;
this.bestTwo = {};
this.times.forEach(t => {
if (!this.timesIndexed[t.idteam]) {
this.timesIndexed[t.idteam] = [];
}
this.timesIndexed[t.idteam].push({laptimesms: t.laptimesms, penaltysum: t.penaltysum});
if (t.laptimesms.length > this.maxLaps) {
this.maxLaps = t.laptimesms.length;
}
// get the list of times, sorted, for each team
if (!this.teamtotaltimes[t.idteam]) {
this.teamtotaltimes[t.idteam] = [];
}
const sum = t.laptimesms.reduce((prev, next) => {
return prev + next;
});
this.teamtotaltimes[t.idteam].push(+(sum + (t.penaltysum * 1000)));
// calculate the best two
this.bestTwo[t.idteam] = this.getBestTwo(t.idteam);
});
console.log('totaltimes');
console.log(this.teamtotaltimes);
Object.keys(this.teamtotaltimes).forEach(key => {
this.teamtotaltimes[key].sort((a, b) => {
if (a < b) {
return -1;
} else if (a === b) {
return 0;
} else {
return 1;
}
}
);
});
});
}
getPenaltySum(raceNr: number, idTeam: number) {
if (!this.timesIndexed
|| !this.timesIndexed[idTeam]
|| !this.timesIndexed[idTeam][raceNr]
|| !this.timesIndexed[idTeam][raceNr].penaltysum) {
return null;
}
const penaltysum = this.timesIndexed[idTeam][raceNr].penaltysum;
if (!penaltysum) {
return null;
}
return penaltysum;
}
/**
* Get the best two racetimes (including penalties)
* @param idTeam
*/
private getBestTwo(idTeam: number): number[] {
if (!this.timesIndexed) {
return null;
}
// first take all the values... calculate the averages
// each time is the total of a race
const teamTimes = this.timesIndexed[idTeam];
if (!teamTimes || teamTimes.length < 2) {
return null;
}
const totalTimes: number[] = [];
for (let raceNr = 0; raceNr < this.maxRaces; raceNr++) {
const raceTime = this.getRaceTime(raceNr, idTeam);
if (raceTime) {
// ADD THE PENALTY HERE!
const items = raceTime + this.getPenaltySum(raceNr, idTeam) * 1000;
totalTimes.push(items);
}
}
// averages are calculated... sort them
totalTimes.sort((a, b) => {
if (a < b) {
return -1;
} else if (a === b) {
return 0;
} else {
return 1;
}
}
);
// take the two lowest
totalTimes.splice(2);
return totalTimes;
}
/**
* Get avg of best two in milliseconds.
* @param idTeam
*/
getAvgOfBestTwo(idTeam: number) {
if (this.bestTwo && this.bestTwo[idTeam] && this.bestTwo[idTeam].length === 2) {
return (this.bestTwo[idTeam][0] + this.bestTwo[idTeam][1]) / 2;
} else {
return null;
}
}
getPenalisedRaceTime(raceNr: number, idTeam: number): number {
return this.getRaceTime(raceNr, idTeam) + (this.getPenaltySum(raceNr, idTeam) * 1000);
}
getRaceTime(raceNr: number, idTeam: number): number {
const time = this.getLapTimes(raceNr, idTeam);
if (!time) {
return null;
}
return time.reduce((previousValue, currentValue) => {
return currentValue + previousValue;
});
}
getRaceTimeMinutes(raceNr: number, idTeam: number): number {
return Math.floor(this.getRaceTime(raceNr, idTeam) / 1000 / 60);
}
getRaceTimeSeconds(raceNr: number, idTeam: number): string {
const raceTime = this.getRaceTime(raceNr, idTeam);
return ((raceTime / 1000) % 60).toFixed(2);
}
getLapTimes(raceNr: number, idTeam: number): number[] {
if (!this.timesIndexed
|| !this.timesIndexed[idTeam]
|| !this.timesIndexed[idTeam][raceNr]
|| !this.timesIndexed[idTeam][raceNr].laptimesms) {
return null;
}
return this.timesIndexed[idTeam][raceNr].laptimesms;
}
getLapTime(idTeam: number, raceNr: number, lapNr: number) {
const lapTime = this.getLapTimes(raceNr, idTeam);
if (lapTime) {
return lapTime[lapNr];
} else {
return null;
}
}
getTimeRank(raceindex, idteam: any) {
if (!this.teamtotaltimes || !this.teamtotaltimes[idteam]) {
return -1;
}
let penalisedRaceTime = this.getPenalisedRaceTime(raceindex, idteam);
let indexOf = this.teamtotaltimes[idteam].indexOf(penalisedRaceTime);
return indexOf;
}
}