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.
68 lines
1.6 KiB
TypeScript
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();
|
|
}
|
|
}
|