import { Component, DestroyRef, inject, OnInit, OnDestroy } from '@angular/core'; import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; 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 { ChartistModule, Configuration } from 'ng-chartist'; import { AxisOptions, Label } from 'chartist'; import { Observable, Subscription } from 'rxjs'; import { MenuItems } from 'src/app/components/shared'; import { UtilitiesService, JumpsService } from 'src/app/core/services'; import { JumpByDate } from 'src/app/core/models'; @Component({ selector: 'app-jumps-by-month', standalone: true, imports: [ CommonModule, MatButtonModule, MatCardModule, MatDividerModule, MatExpansionModule, MatIconModule, MatMenuModule, ChartistModule ], templateUrl: './jumps-by-month.component.html' }) export class JumpsByMonthComponent implements OnInit, OnDestroy { private _jumpByDate: Subscription = new Subscription(); private _jumpsByDate!: Array; private _jumpsByDateCount = 0; public title: string = 'Volume mensuel'; public subtitle: string = 'Nombre total de sauts par mois'; 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 seriesColorClass: string[] = this._utilitiesService.getChartColors(); public seriesRowTotal: number[] = []; public seriesRowAvg: number[] = []; public seriesRowAvgLastYears: number[] = []; public seriesColTotal: number[] = []; public seriesColTotalClosed: number[] = []; public seriesColTotalLastYears: number[] = []; public displayCharts = false; public barChartJumps: Configuration = this._utilitiesService.getBarConfig(); public destroyRef = inject(DestroyRef); constructor( private _jumpsService: JumpsService, private _utilitiesService: UtilitiesService, public menuItems: MenuItems ) { } ngOnInit() { this._loadJumpByDate(); } ngOnDestroy() { this._jumpByDate.unsubscribe(); } private _loadJumpByDate() { this.seriesHeader = this._utilitiesService.getMonthsList(); const values: Array = this.seriesHeader.map(() => 0); this.seriesColTotal = [...values]; this.seriesColTotalClosed = [...values]; this.seriesColTotalLastYears = [...values]; const jumps$: Observable> = this._jumpsService.getAllByDate().pipe(takeUntilDestroyed(this.destroyRef)); this._jumpByDate = jumps$.subscribe((aggregate: Array) => { this._jumpsByDateCount = aggregate.length; this._jumpsByDate = aggregate.map((row: JumpByDate) => { const currentYear: number = new Date().getFullYear(); const year = row.year.toString(); const month = row.month; if (this.seriesName.indexOf(year) < 0) { this.seriesName.push(year); if (row.year < this.min || this.min == 0) { this.min = row.year; } if (row.year > this.max) { this.max = row.year; } this.seriesRow.push([...values]); } this.seriesRow[(this.seriesRow.length-1)][(month-1)] = row.count; this.seriesColTotal[(month-1)] += row.count; if (row.year < currentYear) { this.seriesColTotalClosed[(month-1)] += row.count; } if (row.year >= (currentYear-3) && row.year < currentYear) { this.seriesColTotalLastYears[(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-2)); // -2 pour ne pas compter la première année 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); const axisX: AxisOptions = { labelInterpolationFnc: function(value: Label, index: number): string { return index % 1 === 0 ? `${value.toString()}` : ''; } } this.barChartJumps = { type: 'Bar', data: { 'labels': this.seriesHeader, 'series': this.seriesRow }, options: { seriesBarDistance: 15, high: 70, axisX: { showGrid: false, offset: 20 }, axisY: { showGrid: true, offset: 40 }, height: 300 }, responsiveOptions: [ ['screen and (min-width: 1024px)', { axisX: axisX }], ['screen and (min-width: 641px) and (max-width: 1024px)', { seriesBarDistance: 10, axisY: { offset: 30 }, axisX: axisX }], ['screen and (max-width: 640px)', { seriesBarDistance: 5, axisY: { offset: 20 }, axisX: axisX }] ] }; this.displayCharts = true; }); } }