258 lines
7.5 KiB
TypeScript
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;
|
|
}
|
|
}
|