Files
ENI-projet-piscine/apps/frontend/src/app/shared/components/consumption-gauge/consumption-gauge.ts
T
Johan LEROY 0259f66b62 fix(frontend): detruit les graphiques avec leur composant
Chart.js conserve chaque instance dans un registre lie au canvas et lui
attache un observateur de redimensionnement. Sans destroy, tout survit a la
destruction du composant, et une re-creation sur le meme canvas echoue avec
"Canvas is already in use".

Les doubles de test gagnent destroy : TestBed detruit les fixtures apres
chaque test, un mock sans cette methode fait tomber les specs existantes.
2026-09-16 09:20:17 +02:00

68 lines
1.6 KiB
TypeScript

import {
Component,
ElementRef,
ViewChild,
input,
effect,
AfterViewInit,
OnDestroy,
} from '@angular/core';
import { Chart, registerables } from 'chart.js';
Chart.register(...registerables);
@Component({
selector: 'app-consumption-gauge',
standalone: true,
templateUrl: './consumption-gauge.html',
styleUrl: './consumption-gauge.scss',
})
export class ConsumptionGauge implements AfterViewInit, OnDestroy {
consumption = input.required<number>();
capacity = input.required<number>();
@ViewChild('canvas') private canvasRef!: ElementRef<HTMLCanvasElement>;
private chart?: Chart;
constructor() {
effect(() => {
const used = this.consumption();
const remaining = Math.max(0, this.capacity() - used);
if (this.chart) {
this.chart.data.datasets[0].data = [used, remaining];
this.chart.update('none');
}
});
}
ngAfterViewInit(): void {
const used = this.consumption();
const remaining = Math.max(0, this.capacity() - used);
this.chart = new Chart(this.canvasRef.nativeElement, {
type: 'doughnut',
data: {
labels: ['Utilisé', 'Disponible'],
datasets: [
{
data: [used, remaining],
backgroundColor: ['#3b82f6', '#e5e7eb'],
borderWidth: 0,
},
],
},
options: {
responsive: true,
maintainAspectRatio: false,
cutout: '70%',
animation: { duration: 300 },
plugins: { legend: { display: false } },
},
});
}
ngOnDestroy(): void {
this.chart?.destroy();
}
}