import { trigger, state, style, animate, transition } from '@angular/animations'; import { Component, DestroyRef, inject, OnInit, OnDestroy } from '@angular/core'; import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; import { ActivatedRoute } from '@angular/router'; import { CommonModule } from '@angular/common'; import { MatButtonModule } from '@angular/material/button'; import { MatCardModule } from '@angular/material/card'; import { MatDividerModule } from '@angular/material/divider'; import { MatExpansionModule } from '@angular/material/expansion'; import { MatIconModule } from '@angular/material/icon'; import { MatMenuModule } from '@angular/material/menu'; import { Observable, Subscription } from 'rxjs'; import { MenuItems } from '@components/shared'; import { BarsChartComponent, CircleChartComponent, LineChartComponent, LineAreaChartComponent } from '@components/shared/helpers-chart'; import { UtilitiesService } from '@services'; import { Jump, JumpByCategorie, JumpByDate, JumpByDateByModule, JumpByModule, JumpsPageData, JumpYears } from '@models'; @Component({ selector: 'app-jumps', standalone: true, imports: [ CommonModule, MatButtonModule, MatCardModule, MatDividerModule, MatExpansionModule, MatIconModule, MatMenuModule, BarsChartComponent, CircleChartComponent, LineChartComponent, LineAreaChartComponent ], templateUrl: './jumps.component.html', styleUrl: './jumps.component.scss', animations: [ trigger('flyInOut', [ state('in', style({ transform: 'translateX(0)' })), transition('void => *', [ style({ transform: 'translateX(-100%)' }), animate(200) ]), transition('* => void', [ style({ transform: 'translateX(100%)' }), animate(200) ]) ]) ] }) export class JumpsComponent implements OnInit, OnDestroy { private _data: Subscription = new Subscription(); private _jumpsByCategorie: Array = []; private _jumpsByModule: Array = []; private _jumpsByDate: Array = []; public lastJump: Jump = {} as Jump; public title: string = 'Sauts'; public subtitle: string = 'Nombre total de sauts par mois'; public displayCharts = false; public destroyRef = inject(DestroyRef); public min = 0; public max = 0; public grandAvg = 0; public grandAvgLastYears = 0; public grandTotal = 0; public seriesHeader: string[] = []; public seriesName: string[] = []; public seriesRow: Array> = []; public seriesColor: { backgroundColor: string[], borderColor: string[] } = { backgroundColor: this._utilitiesService.getSeriesColors(0.8, 'all'), borderColor: this._utilitiesService.getSeriesColors(1, 'all') }; public seriesTypesHeader: string[] = []; public seriesTypesName: string[] = []; public seriesTypesRow: Array> = []; public seriesTypesRowCumulated: Array> = []; public seriesTypesColor: { backgroundColor: string[], borderColor: string[] } = { backgroundColor: this._utilitiesService.getSeriesColors(0.8, 'pastels'), borderColor: this._utilitiesService.getSeriesColors(1, 'pastels') }; public seriesColorClass: string[] = this._utilitiesService.getChartColors(); public seriesRowTotal: number[] = []; public seriesRowAvg: number[] = []; public seriesRowAvgLastYears: number[] = []; public seriesColTotal: number[] = []; public seriesColTotalClosed: number[] = []; public seriesColTotalLastYears: number[] = []; constructor( private route: ActivatedRoute, private _utilitiesService: UtilitiesService, public menuItems: MenuItems ) { } ngOnInit() { const data$: Observable<{ pageData: JumpsPageData }> = this.route.data as Observable<{ pageData: JumpsPageData }>; this._data = data$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: { pageData: JumpsPageData }) => { const pageData: JumpsPageData = data.pageData; this.lastJump = pageData.lastjump; const currentYear: number = new Date().getFullYear(); const types: Array = ['FF', 'Solo', 'VR', 'Wingsuit']; const verticals: Array = ['Chutas', 'Head Up', 'Head Down']; const others: Array = ['Track', 'Trace']; const modules: Array = [...verticals, ...others]; const minoration = 2; // -2 pour ne pas compter la première année this.min = pageData.jumpsByYears[0].year; this.max = pageData.jumpsByYears[(pageData.jumpsByYears.length-1)].year; this.seriesHeader = this._utilitiesService.getMonthsList(); const values: Array = this.seriesHeader.map(() => 0); this.seriesColTotal = [...values]; this.seriesColTotalClosed = [...values]; this.seriesColTotalLastYears = [...values]; this.seriesName = pageData.jumpsByYears.map((row: JumpYears) => { this.seriesRow.push([...values]); return row.year.toString(); }); this._jumpsByDate = pageData.jumpsByDate.map((row: JumpByDate) => { this.seriesRow[(row.year-this.min)][(row.month-1)] = row.count; this.seriesColTotal[(row.month-1)] += row.count; if (row.year < currentYear) { this.seriesColTotalClosed[(row.month-1)] += row.count; } if (row.year >= (currentYear-3) && row.year < currentYear) { this.seriesColTotalLastYears[(row.month-1)] += row.count; } return row; }); this.seriesRow.forEach((row: number[]) => { const total = row.reduce((partialSum, a) => partialSum + a, 0); this.seriesRowTotal.push(total); }); this.seriesColTotalClosed.forEach((row: number) => { const value: number = (row/(this.seriesName.length-minoration)); this.seriesRowAvg.push(parseInt(value.toFixed(0))); }); this.seriesColTotalLastYears.forEach((row: number) => { const value: number = (row/3); // Les 3 dernières années this.seriesRowAvgLastYears.push(parseInt(value.toFixed(0))); }); this.grandAvg = this.seriesRowAvg.reduce((partialSum, accumulated) => partialSum + accumulated, 0); this.grandAvgLastYears = this.seriesRowAvgLastYears.reduce((partialSum, accumulated) => partialSum + accumulated, 0); this.grandTotal = this.seriesColTotal.reduce((partialSum, accumulated) => partialSum + accumulated, 0); pageData.jumpsByCategory.forEach((row: JumpByCategorie) => { if (types.indexOf(row.categorie) !== -1) { this._jumpsByCategorie.push(row); } }); //const focus: Array = ['FF', 'Solo']; // ['FF'] let verticalCount:number = 0; let otherCount:number = 0; pageData.jumpsByModule.forEach((row: JumpByModule) => { //if (focus.indexOf(row.categorie) !== -1 && modules.indexOf(row.module) !== -1) { if (modules.indexOf(row.module) !== -1) { if (verticals.indexOf(row.module) !== -1) { verticalCount += row.count; } else { otherCount += row.count; } } }); if (verticalCount > 0) { const row:JumpByModule = { categorie: 'FF', module: 'Vertical', count: verticalCount } this._jumpsByModule.push(row); } if (otherCount > 0) { const row:JumpByModule = { categorie: 'FF', module: 'Track/Trace', count: otherCount } this._jumpsByModule.push(row); } for (let year = 0; year < pageData.jumpsByYears.length; year++) { for (let index = 0; index < 12; index++) { const month: string = ((index+1) < 10) ? `0${(index+1)}` : `${(index+1)}`; this.seriesTypesHeader.push(`${month}-${pageData.jumpsByYears[year].year}`); } } const emptyValues: Array = this.seriesTypesHeader.map(() => 0); this.seriesTypesName = types; this.seriesTypesName.forEach(() => { this.seriesTypesRow.push([...emptyValues]); }); pageData.jumpsByDateByModule.forEach((row: JumpByDateByModule) => { const indexOf: number = this.seriesTypesName.indexOf(row.categorie); if (indexOf !== -1) { this.seriesTypesRow[indexOf][(((row.year-this.min)*12)+row.month-1)] += row.count; } }); this.seriesTypesRowCumulated = this.seriesTypesRow.map((row: Array) => { let accumulated: number = 0; return row.map((value: number) => { accumulated += value; return accumulated; }); }); this.seriesTypesHeader = this.seriesTypesHeader.slice((pageData.jumpsByDateByModule[0].month+1), -(pageData.jumpsByDateByModule[(pageData.jumpsByDateByModule.length-1)].month)); this.seriesTypesRow = this.seriesTypesRow.map((row: Array) => { return row.slice((pageData.jumpsByDateByModule[0].month+1), -(pageData.jumpsByDateByModule[(pageData.jumpsByDateByModule.length-1)].month)); }); this.seriesTypesRowCumulated = this.seriesTypesRowCumulated.map((row: Array) => { return row.slice((pageData.jumpsByDateByModule[0].month+1), -(pageData.jumpsByDateByModule[(pageData.jumpsByDateByModule.length-1)].month)); }); /* console.log('this.min', this.min); console.log('this.max', this.max); console.log('this.lastJump', this.lastJump); console.log('this.seriesHeader', this.seriesHeader); console.log('this.seriesName', this.seriesName); console.log('this.seriesRow', this.seriesRow); console.log('this.seriesRowTotal', this.seriesRowTotal); console.log('this.seriesRowAvg', this.seriesRowAvg); console.log('this.seriesRowAvgLastYears', this.seriesRowAvgLastYears); console.log('this._jumpsByCategorie', this._jumpsByCategorie); console.log('this._jumpsByModule', this._jumpsByModule); console.log('this.seriesTypesHeader', this.seriesTypesHeader); console.log('this.seriesTypesName', this.seriesTypesName); console.log('this.seriesTypesRow', this.seriesTypesRow); console.log('this.seriesTypesRowCumulated', this.seriesTypesRowCumulated); */ this.displayCharts = true; }); } ngOnDestroy() { this._data.unsubscribe(); } public getCategories(): Array { return this._jumpsByCategorie; } public getModules(): Array { return this._jumpsByModule; } public getModuleColor(index: number): number { return (this._jumpsByCategorie.length + index); } }