Visualisation de données
Huit composants Astro dessinent des graphiques en SVG statique, au build, sans JavaScript. Chacun écrit son résumé, lie son tableau de valeurs et ne s’appuie jamais sur la couleur seule.
Les exemples utilisent des jeux fictifs, lus dansapps/docs/src/components/examples/chart-data.json. Le cadre de décision est l’ADR-0007.
Les huit composants
LineChart
Courbe de une à six séries. Une valeur manquante rompt le trait, elle n’est jamais ramenée à zéro.
Données du graphique
| Mois | Visites (visites) |
|---|---|
| 1 janvier 2025 | 820 |
| 1 février 2025 | 790 |
| 1 mars 2025 | 880 |
| 1 avril 2025 | 940 |
| 1 mai 2025 | 1 010 |
| 1 juin 2025 | 980 |
| 1 juillet 2025 | 870 |
| 1 août 2025 | 810 |
| 1 septembre 2025 | 1 050 |
| 1 octobre 2025 | 1 180 |
| 1 novembre 2025 | 1 240 |
| 1 décembre 2025 | 1 190 |
import LineChart from '@paulperigault/astro/LineChart.astro';
<LineChart id="visites-mensuelles" title="Visites mensuelles en 2025" dataset={visites} />Fiche LineChart : propriétés, limites et contrôles d’accessibilité.
BarChart
Barres verticales ou horizontales, simples ou groupées, toujours depuis zéro. Quarante catégories au plus.
import BarChart from '@paulperigault/astro/BarChart.astro';
<BarChart id="visites-rubrique" title="Visites par rubrique" dataset={rubriques} showValues />Fiche BarChart : propriétés, limites et contrôles d’accessibilité.
AreaChart
Aire d’un total, ou de deux à six couches empilées. L’empilement refuse les valeurs négatives.
- Recherche
- Direct
- Référents
Données du graphique
| Mois | Recherche (visites) | Direct (visites) | Référents (visites) |
|---|---|---|---|
| 1 janvier 2025 | 410 | 260 | 150 |
| 1 février 2025 | 400 | 250 | 140 |
| 1 mars 2025 | 450 | 270 | 160 |
| 1 avril 2025 | 480 | 290 | 170 |
| 1 mai 2025 | 520 | 310 | 180 |
| 1 juin 2025 | 500 | 300 | 180 |
| 1 juillet 2025 | 430 | 270 | 170 |
| 1 août 2025 | 400 | 250 | 160 |
| 1 septembre 2025 | 540 | 320 | 190 |
| 1 octobre 2025 | 600 | 350 | 230 |
| 1 novembre 2025 | 640 | 380 | 220 |
| 1 décembre 2025 | 610 | 360 | 220 |
import AreaChart from '@paulperigault/astro/AreaChart.astro';
<AreaChart id="visites-source" title="Visites par source en 2025" dataset={sources} />Fiche AreaChart : propriétés, limites et contrôles d’accessibilité.
GaugeChart
Une valeur dans un intervalle et des zones nommées, en demi-cercle ou en cercle complet. La valeur et la zone atteinte sont écrites au centre.
- Critique : de 0 % à 40 %
- Vigilance : de 40 % à 80 %
- Nominal : de 80 % à 100 %
Données du graphique
| Zone | De | À | Valeur actuelle |
|---|---|---|---|
| Critique | 0 % | 40 % | |
| Vigilance | 40 % | 80 % | 72 % |
| Nominal | 80 % | 100 % |
import GaugeChart from '@paulperigault/astro/GaugeChart.astro';
<GaugeChart
id="remplissage"
title="Taux de remplissage de la salle"
value={72}
unit="%"
label="Taux de remplissage"
zones={[
{ label: 'Critique', to: 40, tone: 'bad' },
{ label: 'Vigilance', to: 80, tone: 'warning' },
{ label: 'Nominal', tone: 'good' },
]}
/>Fiche GaugeChart : propriétés, limites et contrôles d’accessibilité.
KpiCard
Valeur et unité en grand, variation dite en mots avec son signe, tendance en option.
Visites du mois
1 190 visites
Baisse de 4,03 % (−50 visites) par rapport au mois précédent
Données du graphique
| Mois | Visites (visites) |
|---|---|
| 1 janvier 2025 | 820 |
| 1 février 2025 | 790 |
| 1 mars 2025 | 880 |
| 1 avril 2025 | 940 |
| 1 mai 2025 | 1 010 |
| 1 juin 2025 | 980 |
| 1 juillet 2025 | 870 |
| 1 août 2025 | 810 |
| 1 septembre 2025 | 1 050 |
| 1 octobre 2025 | 1 180 |
| 1 novembre 2025 | 1 240 |
| 1 décembre 2025 | 1 190 |
import KpiCard from '@paulperigault/astro/KpiCard.astro';
<KpiCard
id="visites-mois"
title="Visites du mois"
value={1190}
unit="visites"
reference={1240}
referenceLabel="par rapport au mois précédent"
trend={{ title: 'Visites par mois en 2025', dataset: visites }}
/>Fiche KpiCard : propriétés, limites et contrôles d’accessibilité.
Sparkline
Tendance d’une série en un trait, sans axes. Le point final, le plus haut et le plus bas sont écrits.
- Dernière valeur : 1 190 visites (1 décembre 2025)
- Plus haut : 1 240 visites (1 novembre 2025)
- Plus bas : 790 visites (1 février 2025)
Données du graphique
| Mois | Visites (visites) |
|---|---|
| 1 janvier 2025 | 820 |
| 1 février 2025 | 790 |
| 1 mars 2025 | 880 |
| 1 avril 2025 | 940 |
| 1 mai 2025 | 1 010 |
| 1 juin 2025 | 980 |
| 1 juillet 2025 | 870 |
| 1 août 2025 | 810 |
| 1 septembre 2025 | 1 050 |
| 1 octobre 2025 | 1 180 |
| 1 novembre 2025 | 1 240 |
| 1 décembre 2025 | 1 190 |
import Sparkline from '@paulperigault/astro/Sparkline.astro';
<Sparkline id="visites-trait" title="Visites mensuelles en 2025" dataset={visites} />Fiche Sparkline : propriétés, limites et contrôles d’accessibilité.
DataTable
Toutes les valeurs en tableau, en-têtes associés. Des cases à cocher masquent des colonnes sans JavaScript.
| Mois | Recherche (visites) | Direct (visites) | Référents (visites) |
|---|---|---|---|
| 1 janvier 2025 | 410 | 260 | 150 |
| 1 février 2025 | 400 | 250 | 140 |
| 1 mars 2025 | 450 | 270 | 160 |
| 1 avril 2025 | 480 | 290 | 170 |
| 1 mai 2025 | 520 | 310 | 180 |
| 1 juin 2025 | 500 | 300 | 180 |
| 1 juillet 2025 | 430 | 270 | 170 |
| 1 août 2025 | 400 | 250 | 160 |
| 1 septembre 2025 | 540 | 320 | 190 |
| 1 octobre 2025 | 600 | 350 | 230 |
| 1 novembre 2025 | 640 | 380 | 220 |
| 1 décembre 2025 | 610 | 360 | 220 |
import DataTable from '@paulperigault/astro/DataTable.astro';
<DataTable id="visites-tableau" title="Visites par source en 2025" dataset={sources} />Fiche DataTable : propriétés, limites et contrôles d’accessibilité.
Legend
Un échantillon à forme propre et un libellé par série, pour un graphique dessiné ailleurs.
- Recherche
- Direct
- Référents
import Legend from '@paulperigault/astro/Legend.astro';
<Legend id="sources" items={['Recherche', 'Direct', 'Référents']} />Fiche Legend : propriétés, limites et contrôles d’accessibilité.
Contrat de données
Tous les composants lisent le même Dataset, défini par l’ADR-0007 (décision 1). Il est validé à la frontière : un jeu invalide fait échouer le build avec un code d’erreur, il n’est jamais dessiné de travers.
import type { Dataset } from '@paulperigault/dataviz';
const visites: Dataset = {
schema: 1,
x: { kind: 'time', label: 'Mois', values: ['2025-01-01', '2025-02-01', '2025-03-01'] },
series: [{ id: 'visites', label: 'Visites', unit: 'visites', values: [820, 790, null] }],
};- Format : colonnaire et versionné (
schema: 1). Un axexde genrecategory,timeounumber, et des séries avecid,label,unitetvalues. - Valeur manquante :
null, jamais0niNaN. La courbe se rompt, les barres laissent un vide, le tableau écrit « donnée manquante ». - Unité : une par série, séparée de la valeur. Deux unités différentes sur un même axe sont refusées (
dataset.unit-mismatch). - Dates : ISO 8601, lues en UTC, sans fuseau implicite.
- Locale :
frpar défaut, parIntl: virgule décimale, espace fine insécable entre les milliers (convention typographique). - Plafonds : six séries au plus, 40 catégories de barres, 500 points par courbe (sous-échantillonnage LTTB au build), 400 nœuds SVG et 10 ko par graphique. Ce sont des conventions de l’ADR-0007, mesurées par les tests du dépôt.
Accessibilité
La cible est WCAG 2.2 AA. Les garanties ci-dessous viennent de l’ADR-0007 (décision 3) et sont testées dans packages/astro/test/.
- Alternative textuelle : chaque graphique est une
figureavec unfigcaption. Le SVG porterole="img", untitleet undescqui résume la donnée : début, fin, tendance chiffrée, extrêmes, valeurs manquantes. - Tableau lié : toutes les valeurs sont dans un tableau sous le graphique, avec des
th scope, dans undetailsfermé que le clavier déplie. - Pas de couleur seule (WCAG 1.4.1) : chaque rang de série a un motif de trait ou de remplissage et un marqueur de forme propre, repris par
Legend. Une variation deKpiCards’écrit en mots avec son signe. - Contraste : tracés et barres à 3:1 au moins contre le fond (WCAG 1.4.11), texte à 4,5:1 au moins (1.4.3), jamais en couleur de série. Les six jetons
--pp-chart-1..6ont été mesurés le 2026-10-29 à 3,07:1 au minimum, en clair et en sombre (.claude/skills/encre-design/SKILL.md). - Mouvement, contraste forcé, impression : aucune animation, tracés en
CanvasTextsousforced-colors, motifs et tableau conservés à l’impression. - Mesure : axe sans violation sur
LineChart(2 thèmes, 2 fenêtres,apps/docs/e2e/line-chart.spec.ts) et sur cette page :apps/docs/e2e/donnees.spec.ts.
Teinte d’accent
Un projet fournit une teinte OKLCH en degrés ; le système fixe la clarté et le chroma. Les six couleurs de graphique sont dérivées de cette teinte et contrôlées en daltonisme : écart CIEDE2000 d’au moins 10 entre deux couleurs de la catégorielle (seuil de convention, ADR-0007, décision 4). Les motifs et les marqueurs restent exigés en plus.
npm create @paulperigault mon-site -- --accent-hue 150Ce site garde la teinte par défaut (270,7). Le tableau des jetons pour une autre teinte est dans la section « Teinte d’accent » de la fiche LineChart. La commande complète et ses refus sont décrits sur la page Utiliser.