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; } }