Utiliser la bibliothèque Chart.js dans un projet Angular 20


Dans cet article, je vous présente Chart.js à travers un exemple concret que j’ai développé. Comme à mon habitude, je privilégie une approche pratique pour faciliter la compréhension.
C’es quoi Chart.js ?
Chart.js est une bibliothèque JavaScript simple qui permet d’afficher des graphiques interactifs dans une page web. Elle est souvent utilisé avec Angular, React ou du JavaScript pur.
Exemple 1 : intégrer un diagramme en anneau (donut chart) dans mon projet Angular 20
Dans cette exemple je vous montre comment avoir le graphique suivant:
Installation des outils
Dans le terminal à la racine du projet Angular, on exécute les commandes suivantes pour installer chart.js et ng2-charts
npm install chart.js
npm install ng2-charts
Le fichier HTML
Dans le fichier HTML de votre composant, où vous voulez créer votre diagramme, on ajoute le code suivant:
⇒ <canvas> est un élément HTML spécial utilisé pour dessiner des graphiques ou des animations
⇒ Il est vide au départ
⇒ C’est dessus que Chart.js va dessiner le diagramme en anneau
⇒ #donutCanvas est une référence locale Angular
Le fichier TypeScript
Dans le fichier TS du composant dans lequel vous ajoutez le diagramme,
on ajoute les importations suivantes :
Dans la section suivante, vous aurez le code à mettre dans le fichier TS
Le contenu TS
On créé la méthode suivante
Le fichier CSS
On peut également ajouter du CSS, dans le fichier CSS de votre composant.
Exemple 2 : Comment j’ai intégré un diagramme en anneau (donut chart) dans mon projet Angular 20
Dans cette partie on va réaliser ce qui suit
Avant de commencer, voici un rappel de la commande pour créer un projet Angular 20
\==> J’ai créé un projet appelé : algostyle-chart
On ouvre le terminal dans le répertoire de notre projet Angular pour installer Chart.js
npm install chart.js
On remarque que « chart.js » a été ajouté dans « dependencies » dans « package.json »
Dans le fichier TypeScript, on importe ce qui suit :
Et voici la suite du contenu TS
On implémente aussi la fonction createDonutChart()
mport { Component, ViewChild, ElementRef, OnInit, signal } from '@angular/core';
import { Chart, ChartConfiguration, ChartType } from 'chart.js';
//Enregistrement de tous les modules de Chart.js
// Cela permet d'utiliser toutes les fonctionnalités de Chart.js (graphiques, axes, légendes ...)
import { registerables } from 'chart.js';
Chart.register(...registerables);
@Component({
selector: 'app-root',
imports: [],
templateUrl: './app.html',
styleUrl: './app.css'
})
export class App implements OnInit{
// Titre
protected readonly title = signal('algostyle-chart');
// Référence au canvas HTML (#donutCanvas dans le template)
@ViewChild('donutCanvas', { static: true }) donutCanvas!: ElementRef<HTMLCanvasElement>;
// Instance du graphique Chart.js
private chart: Chart | undefined;
// Au chargement du composant
ngOnInit(): void {
this.createDonutChart();
}
private createDonutChart(): void {
// Récupère le contexte 2D du canvas
const ctx = this.donutCanvas.nativeElement.getContext('2d');
// Vérifie si le contexte existe
if (!ctx) {
console.error('Erreur: Contexte canvas non trouvé');
return;
}
// Configuration du graphique en donut
const config: ChartConfiguration = {
type: 'doughnut', // Type de graphique
data: {
labels: ['Ventes', 'Marketing', 'Développement', 'Support', 'Autres'], // Étiquettes
datasets: [{ // Données du graphique
label: 'Répartition du budget',
data: [30, 25, 20, 15, 10], // Valeurs
backgroundColor: [ // Couleurs de fond
'#FF6384', // Rose
'#36A2EB', // Bleu
'#FFCE56', // Jaune
'#4BC0C0', // Turquoise
'#9966FF' // Violet
],
borderColor: [ // Couleurs des bordures
'#FF6384',
'#36A2EB',
'#FFCE56',
'#4BC0C0',
'#9966FF'
],
borderWidth: 2, // Épaisseur bordure
hoverOffset: 4 // Effet survol
}]
},
options: {
responsive: true, // Adaptatif
maintainAspectRatio: false, // Ignore ratio par défaut
plugins: {
legend: { // Configuration légende
position: 'bottom', // Position
labels: {
padding: 20, // Espacement
font: {
size: 14 // Taille texte
}
}
},
tooltip: { // Infobulles
callbacks: {
label: function(context) { // Formatage tooltip
const label = context.label || '';
const value = context.parsed;
const data = context.dataset.data;
const total = data.reduce((a: number, b: any) => {
const numB = typeof b === 'number' ? b : 0;
return a + numB;
}, 0);
const percentage = ((value / total) * 100).toFixed(1);
return `${label}: ${value}% (${percentage}% du total)`;
}
}
}
},
animation: { // Animation
duration: 1000, // Durée 1s
easing: 'easeOutBounce' // Effet rebond
}
}
};
// Crée le graphique avec la config
this.chart = new Chart(ctx, config);
}
// Met à jour les données du graphique
updateChartData(newData: number[]): void {
if (this.chart) { // Vérifie si le graphique existe
this.chart.data.datasets[0].data = newData; // Remplace les données
this.chart.update(); // Rafraîchit l'affichage
}
}
// Nettoie le graphique avant la destruction du composant
ngOnDestroy(): void {
if (this.chart) { // Vérifie si le graphique existe
this.chart.destroy(); // Détruit l'instance pour libérer la mémoire
}
}
Voici le code HTML ( si vous voulez copier )
<!-- donut-chart.component.html -->
<div class="chart-container">
<h2>Répartition du Budget</h2>
<div class="chart-wrapper">
<canvas #donutCanvas></canvas>
</div>
<!-- Contrôles pour tester les fonctionnalités -->
<div class="controls">
<div class="control-group">
<h3>Changer les données</h3>
<button (click)="updateChartData([40, 20, 15, 15, 10])" class="btn">
Données Set 1
</button>
<button (click)="updateChartData([25, 30, 20, 15, 10])" class="btn">
Données Set 2
</button>
<button (click)="updateChartData([35, 25, 25, 10, 5])" class="btn">
Données Set 3
</button>
</div>
</div>
</div>
Voici le code CSS ( si vous voulez copier )
/* donut-chart.component.css */
.chart-container {
max-width: 800px;
margin: 0 auto;
padding: 20px;
font-family: Arial, sans-serif;
}
.chart-container h2 {
text-align: center;
color: #333;
margin-bottom: 30px;
}
.chart-wrapper {
position: relative;
height: 400px;
margin-bottom: 30px;
padding: 20px;
background: #f8f9fa;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
.controls {
display: flex;
flex-direction: column;
gap: 20px;
}
.control-group {
text-align: center;
}
.control-group h3 {
margin-bottom: 15px;
color: #333;
font-size: 18px;
}
.control-group .btn {
margin: 5px;
}
.btn {
padding: 10px 20px;
background-color: #007bff;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 14px;
transition: all 0.3s ease;
}
📌 Besoin d’aide ? Posez vos questions en commentaires !
Subscribe to my newsletter
Read articles from Aouassar Asmae directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
