district-politics/projects/speech-statistics/src/app/statistics/session-statistics/session-statistics.componen...

120 lines
5.7 KiB
TypeScript

import {Component, OnDestroy, OnInit} from '@angular/core';
import {ActivatedRoute} from '@angular/router';
import {Observable, Subscription} from 'rxjs';
import {Speech} from '../../shared/speech';
import {AngularFireDatabase, SnapshotAction} from '@angular/fire/compat/database';
import {map} from 'rxjs/operators';
import {FactionInBodyService} from '../../auth/shared/faction-in-body.service';
import {SpeechType} from '../../shared/speech-type';
import {Session} from '../../auth/edit/session';
@Component({
selector: 'app-session-statistics',
templateUrl: './session-statistics.component.html',
styleUrls: ['./session-statistics.component.scss']
})
export class SessionStatisticsComponent implements OnInit, OnDestroy {
public totalSpeechTime: number = 0;
public totalCommentaryTime: number = 0;
public longestSpeech: Speech | undefined;
public shortestSpeech: Speech | undefined;
public readonly speechTimesPerFaction: Map<string, number> = new Map<string, number>();
public readonly commentaryTimesPerFaction: Map<string, number> = new Map<string, number>();
public readonly shortestSpeechPerFaction: Map<string, Speech> = new Map<string, Speech>();
public readonly longestSpeechPerFaction: Map<string, Speech> = new Map<string, Speech>();
public readonly proportionOfSpeechTimePerFaction: Map<string, number> = new Map<string, number>();
public readonly proportionOfCommentaryTimePerFaction: Map<string, number> = new Map<string, number>();
public session: Observable<SnapshotAction<Session>> = new Observable<SnapshotAction<Session>>();
private sessionKey: string | undefined;
private speechTimes: Observable<SnapshotAction<Speech>[]> = new Observable<SnapshotAction<Speech>[]>();
private subscriptions: Subscription[] = [];
constructor(private database: AngularFireDatabase,
private route: ActivatedRoute,
public factionInBodyService: FactionInBodyService) {
}
ngOnInit(): void {
this.sessionKey = this.route.snapshot.params['sessionKey'];
const speechTimesRef = this.database.list<Speech>('speechTimes');
const sessionRef = this.database.object<Session>('sessions/' + this.sessionKey);
this.session = sessionRef.snapshotChanges();
this.speechTimes = speechTimesRef.snapshotChanges().pipe(
map(speechTimesList => {
return speechTimesList.filter(speechTime => speechTime.payload.val()?.sessionKey == this.sessionKey);
})
);
this.subscriptions.push(
this.speechTimes.subscribe((speechTimes) => this.calculateStatistics(speechTimes)),
);
}
ngOnDestroy(): void {
this.subscriptions.forEach(sub => sub.unsubscribe());
}
private calculateStatistics(speechTimes: SnapshotAction<Speech>[]): void {
this.totalCommentaryTime = 0;
this.totalSpeechTime = 0;
this.speechTimesPerFaction.clear();
this.commentaryTimesPerFaction.clear();
this.shortestSpeechPerFaction.clear();
this.longestSpeechPerFaction.clear();
this.proportionOfCommentaryTimePerFaction.clear();
this.proportionOfSpeechTimePerFaction.clear();
this.shortestSpeech = undefined;
this.longestSpeech = undefined;
for (const speechTime of speechTimes) {
const speech = speechTime.payload.val();
if (speech == null) {
continue;
}
if (speech.type == SpeechType.SPEECH) {
this.totalSpeechTime += speech.timeInMilliseconds;
const speechTime = this.speechTimesPerFaction.get(speech.factionKey);
this.speechTimesPerFaction.set(speech.factionKey, speech.timeInMilliseconds + (speechTime ? speechTime : 0));
if (this.shortestSpeech != null && speech.timeInMilliseconds < this.shortestSpeech.timeInMilliseconds) {
this.shortestSpeech = speech;
} else if (this.shortestSpeech == null) {
this.shortestSpeech = speech;
}
if (this.longestSpeech != null && speech.timeInMilliseconds > this.longestSpeech.timeInMilliseconds) {
this.longestSpeech = speech;
} else if (this.longestSpeech == null) {
this.longestSpeech = speech;
}
const shortestSpeechFaction = this.shortestSpeechPerFaction.get(speech.factionKey);
if (shortestSpeechFaction != null && speech.timeInMilliseconds < shortestSpeechFaction.timeInMilliseconds) {
this.shortestSpeechPerFaction.set(speech.factionKey, speech);
} else if (shortestSpeechFaction == null) {
this.shortestSpeechPerFaction.set(speech.factionKey, speech);
}
const longestSpeechFaction = this.longestSpeechPerFaction.get(speech.factionKey);
if (longestSpeechFaction != null && speech.timeInMilliseconds > longestSpeechFaction.timeInMilliseconds) {
this.longestSpeechPerFaction.set(speech.factionKey, speech);
} else if (longestSpeechFaction == null) {
this.longestSpeechPerFaction.set(speech.factionKey, speech);
}
} else if (speech.type == SpeechType.COMMENTARY) {
this.totalCommentaryTime += speech.timeInMilliseconds;
const commentaryTime = this.commentaryTimesPerFaction.get(speech.factionKey);
this.commentaryTimesPerFaction.set(speech.factionKey, speech.timeInMilliseconds + (commentaryTime ? commentaryTime : 0));
}
}
for (const factionKey of this.speechTimesPerFaction.keys()) {
const speechTimeFaction = this.speechTimesPerFaction.get(factionKey);
this.proportionOfSpeechTimePerFaction.set(factionKey, (speechTimeFaction ? speechTimeFaction : 0) / this.totalSpeechTime);
}
for (const factionKey of this.commentaryTimesPerFaction.keys()) {
const commentaryTimeFaction = this.commentaryTimesPerFaction.get(factionKey);
this.proportionOfCommentaryTimePerFaction.set(factionKey, (commentaryTimeFaction ? commentaryTimeFaction : 0) / this.totalCommentaryTime);
}
}
}