import { Component, OnInit, ViewChild } from '@angular/core'; import { ToastrService } from 'ngx-toastr'; import { TranslateService } from '@ngx-translate/core'; import { ApiClientService } from 'src/app/_services/api-client.service'; import { MapComponent } from 'src/app/_components/map/map.component'; import { LatLngTuple, Marker } from 'leaflet'; @Component({ selector: 'app-stats', templateUrl: './stats-services.component.html', styleUrls: ['./stats-services.component.scss'] }) export class StatsServicesComponent implements OnInit { services: any[] = []; serviceNumber = 0; servicesFilterStart: Date | undefined; servicesFilterEnd: Date | undefined; chartServicesByUserData: any; chartServicesByChiefData: any; chartServicesByDriverData: any; chartServicesByTypeData: any; chartServicesByVillageData: any; @ViewChild("servicesMap") servicesMap!: MapComponent; users: any[] = []; types: any[] = []; range: (Date | undefined)[] | undefined = undefined; lastRange: (Date | undefined)[] | undefined = undefined; constructor( private toastr: ToastrService, private api: ApiClientService, private translate: TranslateService ) { } ngOnInit(): void { Promise.all([ this.api.get("list"), this.api.get("service_types") ]).then((values: any[]) => { this.users = values[0]; this.types = values[1]; this.loadServices(); }).catch((err) => { this.translate.get('edit_service.users_load_failed').subscribe((res: string) => { this.toastr.error(res); }); }); } getUserNameById(id: number) { let user = this.users.find((user) => user.id === id); if (user) { if(user.surname === null) return user.name; return user.surname + " " + user.name; } return ""; } getTypeNameById(id: number) { let type = this.types.find((type) => type.id === id); if (type) { return type.name; } return ""; } extractStatsFromServices() { let people: Record = {}; let chiefs: Record = {}; let drivers: Record = {}; let types: Record = {}; let villages: Record = {}; let municipalities: Record = {}; for (let service of this.services) { let currPeople: Set = new Set(); currPeople.add(service.chief_id); chiefs[service.chief_id] = (chiefs[service.chief_id] || 0) + 1; for (let person of service.drivers) { currPeople.add(person.id); drivers[person.id] = (drivers[person.id] || 0) + 1; } for (let person of service.crew) { currPeople.add(person.id); } for (let person of currPeople) { if (!people[person]) { people[person] = 0; } people[person]++; } if (!types[service.type_id]) { types[service.type_id] = 0; } types[service.type_id]++; if (service.place.village === null) service.place.village = this.translate.instant("unknown"); // Capitalize first letter service.place.village = service.place.village.charAt(0).toUpperCase() + service.place.village.slice(1); if (!villages[service.place.village]) { villages[service.place.village] = 0; } villages[service.place.village]++; } console.log(people, chiefs, drivers, types, villages, municipalities); let peopleLabels: string[] = [], peopleValues: number[] = []; Object.entries(people).sort(([,a],[,b]) => b-a).forEach(([key, value]) => { peopleLabels.push(this.getUserNameById(parseInt(key))); peopleValues.push(value); }); this.chartServicesByUserData = { labels: peopleLabels, datasets: [ { data: peopleValues, } ] }; let chiefsLabels: string[] = [], chiefsValues: number[] = []; Object.entries(chiefs).sort(([,a],[,b]) => b-a).forEach(([key, value]) => { chiefsLabels.push(this.getUserNameById(parseInt(key))); chiefsValues.push(value); }); this.chartServicesByChiefData = { labels: chiefsLabels, datasets: [ { data: chiefsValues, } ] }; let driversLabels: string[] = [], driversValues: number[] = []; Object.entries(drivers).sort(([,a],[,b]) => b-a).forEach(([key, value]) => { driversLabels.push(this.getUserNameById(parseInt(key))); driversValues.push(value); }); this.chartServicesByDriverData = { labels: driversLabels, datasets: [ { data: driversValues, } ] }; let typesLabels: string[] = [], typesValues: number[] = []; Object.entries(types).sort(([,a],[,b]) => b-a).forEach(([key, value]) => { typesLabels.push(this.getTypeNameById(parseInt(key))); typesValues.push(value); }); this.chartServicesByTypeData = { labels: typesLabels, datasets: [ { data: typesValues, } ] }; let villagesLabels: string[] = [], villagesValues: number[] = []; Object.entries(villages).sort(([,a],[,b]) => b-a).forEach(([key, value]) => { villagesLabels.push(key); villagesValues.push(value); }); this.chartServicesByVillageData = { labels: villagesLabels, datasets: [ { data: villagesValues, } ] }; } loadServices() { this.api.get("stats/services", { from: this.servicesFilterStart ? this.servicesFilterStart.toISOString() : undefined, to: this.servicesFilterEnd ? this.servicesFilterEnd.toISOString() : undefined }).then((response: any) => { this.services = response; console.log(this.services); this.serviceNumber = this.services.length; let serviceMapFitBoundsTuple = []; this.servicesMap.removeAllMarkers(); for (let service of this.services) { const pos: LatLngTuple = [service.place.lat, service.place.lon]; serviceMapFitBoundsTuple.push(pos); let marker = new Marker(pos, { title: service.code }).on("click", (e) => { console.log(e); }); this.servicesMap.addMarker(marker); } this.servicesMap.setBounds(serviceMapFitBoundsTuple); this.extractStatsFromServices(); }).catch((error: any) => { console.error(error); this.toastr.error(this.translate.instant("Error while loading services")); }); } filterDateRangeChanged($event: Date[]) { console.log($event); if (typeof($event) !== "object" || ($event !== null && $event.length === 0)) { this.servicesFilterStart = undefined; this.servicesFilterEnd = undefined; } else { this.servicesFilterStart = $event[0]; this.servicesFilterEnd = $event[1]; } if(this.lastRange !== this.range) this.loadServices(); this.lastRange = this.range; } }