Companion d'accessibilité unifie pour les visualisations. Offre trois alternatives activables independamment : tableau de données, téléchargement CSV et description textuelle. Le contenu est replie dans un accordeon DSFR par défaut.

Accessibilité

Les graphiques (canvas, SVG) sont difficilement accessibles aux lecteurs d'écran. dsfr-data-a11y offre trois alternatives complementaires : un tableau HTML, un téléchargement CSV et une description textuelle. Via l'attribut for, il injecte un skip link dans le graphique, pose aria-describedby et aria-details pour créer un lien sémantique complet.

Attributs

AttributTypeDescription
sourceStringId de la source (ou du transformateur) dont ce complément accessible consomme les données.
forStringId de l'élément cible (graphique, carte) pour la liaison ARIA et le lien d'évitement.
tableBooleanAffiche le tableau de données équivalent au graphique.
downloadBooleanAffiche le bouton de téléchargement CSV.
filenameStringNom du fichier CSV téléchargé.
descriptionStringDescription textuelle du graphique, lue par les lecteurs d'écran.
label-fieldStringColonne utilisée pour les labels du tableau. Alias inline champ:Libellé (#1230, PG-032 du banc), la grammaire de dsfr-data-chart (#668) : label-field="dep_nom:Département" lit la colonne dep_nom et affiche « Département » en en-tête du tableau et du CSV. Sans deux-points, l'en-tête reste le nom de la colonne. Un : littéral dans un nom de colonne ou un libellé s'échappe en %3A (escapeColonValue) ; une colonne qui existe telle quelle dans les données, deux-points compris, est lue telle quelle. La colonne se lit par chemin pointé, comme sur dsfr-data-chart (#1244) : label-field="fields.dep".
value-fieldStringColonne(s) utilisée(s) pour les valeurs du tableau (séparées par des virgules). Alias inline champ:Libellé par colonne (#1230, PG-032 du banc), la grammaire de value-field / value-fields de dsfr-data-chart (#668) : value-field="v_fede:Fédération sélectionnée, v_all:Ensemble" lit v_fede et v_all, et les en-têtes du tableau et du CSV portent les libellés — ceux que la légende du graphique affiche déjà. Sans deux-points, l'en-tête reste le nom de la colonne. Une virgule ou un deux-points littéral s'échappe en %2C ou %3A. Chaque colonne se lit par CHEMIN POINTÉ, comme sur dsfr-data-chart (#1244) : value-field="fields.total" lit total sous fields, et fields.total:Total lui donne un en-tête. Une colonne à plat dont le nom contient réellement un point (taux.brut) reste lue telle quelle. Une colonne absente des données reçues est signalée en console : le tableau garde ses lignes mais la colonne est vide, et un tableau vide passe toutes les recettes qui comptent des lignes.
empty-labelStringLibellé substitué aux cellules VIDES (null, undefined ou "") de la colonne de libellé du tableau, et aux noms de série vides en mode series-field (#933). Même rôle que l'empty-label de dsfr-data-chart (#647) : sans lui, la barre du groupe non renseigné porte un nom sur l'axe alors que sa ligne dans le tableau équivalent a une cellule vide — le tableau dit autre chose que le graphique. Colonne de libellé = label-field s'il est posé, sinon la PREMIÈRE colonne rendue. Les colonnes de valeur ne sont jamais touchées : une mesure absente reste une cellule vide, on n'invente pas un libellé. Absent (défaut), le rendu est inchangé : la cellule reste vide. La valeur n'est PAS reprise du graphique visé par for — l'écrire sur les deux balises est volontaire, pour qu'aucune page existante ne voie son tableau changer. Le CSV téléchargé porte le même libellé que le tableau affiché.
series-fieldStringChamp « clé de série » d'un jeu au format long/tidy — typiquement l'origin-field d'un dsfr-data-concat (#807), ou le champ que dsfr-data-chart series-field consomme déjà côté graphique (#930). Posé, le tableau équivalent PIVOTE : une ligne par valeur de label-field, une colonne par valeur distincte de ce champ (dans leur ordre d'apparition), au lieu d'une ligne par couple (libellé, série) sans colonne disant de quelle série la valeur provient. Le CSV téléchargé suit la même structure. Exige label-field ET value-field : sans eux on ne sait pas quelle colonne porte la mesure. Le manque est signalé (data-dsfr-config-error) et le tableau retombe sur le rendu à plat, jamais un pivot silencieusement faux. Seul le PREMIER champ de value-field est pivoté. Un couple (libellé, série) absent des données rend une cellule vide : dsfr-data-chart y trace 0, le tableau ne l'affirme pas. Absent (défaut), le rendu est inchangé. La valeur n'est PAS reprise du graphique visé par for.
labelStringLibellé personnalisé de la section accessible.
decimalsNumberNombre de décimales des cellules numériques du tableau (#666). Absent : au plus 2 décimales, format fr-FR — sauf pour une valeur non nulle inférieure à 0,01 en valeur absolue, qui garde deux chiffres significatifs (0,00123 → « 0,0012 ») au lieu de s'afficher « 0 » (#1282). Posé, ce nombre de décimales est tenu tel quel : decimals="2" rend « 0,00 ». Le CSV n'est pas concerné : il porte la valeur brute.
no-auto-ariaBooleanDesactive la pose automatique des attributs ARIA et du lien d'évitement.
idle-messageStringMessage annoncé quand l'amont attend un filtre (require-where, #690). Remplace « aucune donnée disponible » dans la description lue par les lecteurs d'écran : rien n'a été chargé, rien n'a échoué.

Si ni table, ni download, ni description ne sont définis, les trois sont actives par défaut.

Source en panne

Quand la source échoue, le tableau est retiré et le téléchargement désactivé : les lignes du dernier chargement ne sont ni montrées ni exportées. La section dit « Données momentanément indisponibles. Le tableau et le téléchargement reviendront avec les données. » (ou la phrase de la cause ; error-message de la source la remplace). Le bouton reste atteignable au clavier, aria-disabled, et désigne cette phrase comme sa raison (aria-describedby) ; la description liée au graphique devient « Données du graphique momentanément indisponibles. » Tout revient au chargement réussi. Voir Quand la source est en panne.

Quand la source porte stale-if-error, le tableau reste pendant une panne passagère : sa légende devient visible — « Données du graphique — « Non actualisé » chiffres relevés aujourd'hui à 14 h 32 » — et la description liée au graphique se termine par « Chiffres relevés aujourd'hui à 14 h 32, non actualisés. » Le téléchargement reste possible : le bouton dit « Télécharger en CSV (chiffres relevés à 14 h 32) » et le fichier s'appelle données_relevé-2026-10-13-14h32.csv (la date du relevé avant l'extension de filename). Son contenu reste brut. Voir Le dernier relevé, sur demande.

En attente d'un filtre

Sur une page d'exploration, l'amont peut refuser de charger tant qu'aucun filtre n'est posé (require-where sur <dsfr-data-source> ou <dsfr-data-query>). Le complément accessible annonce alors idle-message à la place de « aucune donnée disponible » : rien n'a été chargé, rien n'a échoué, et c'est cette nuance qu'un lecteur d'écran doit entendre. Le tableau et le bouton de téléchargement restent masqués tant que la source attend. Le mécanisme est décrit sur dsfr-data-source.

Le groupe non renseigné

Quand <dsfr-data-chart> porte empty-label, la barre du groupe vide (null, undefined ou chaîne vide) est nommée sur l'axe et dans la légende. Poser le même empty-label ici nomme la ligne correspondante du tableau équivalent, qui sinon a une cellule de libellé vide : le tableau dirait autre chose que le graphique qu'il double. Seule la colonne de libellé est concernée — label-field s'il est posé, sinon la première colonne rendue ; une mesure absente reste une cellule vide. Le CSV téléchargé porte le même libellé. Sans cet attribut, le rendu est celui d'avant : la valeur n'est pas reprise du graphique visé par for.

Un graphique multi-séries

En-têtes lisibles. label-field et value-field acceptent l'alias inline champ:Libellé, la grammaire de value-field et value-fields de dsfr-data-chart : la colonne lue est champ, le libellé va en en-tête du tableau et du CSV téléchargé. Les champs du graphique se recopient donc tels quels — value-field="v_fede:Fédération sélectionnée, v_all:Ensemble des fédérations" — et le tableau équivalent dit « Fédération sélectionnée » là où le graphique le dit. Sans deux-points, l'en-tête reste le nom de la colonne. Une colonne nommée qui n'existe dans aucune ligne reçue est signalée en console (« colonne … introuvable », avec les colonnes disponibles) : sa colonne du tableau serait vide alors que le tableau a le bon nombre de lignes. Les colonnes se lisent par chemin pointé, comme sur le graphique : sur des lignes imbriquées, value-field="fields.total" se recopie tel quel.

Un jeu au format long — celui que produit dsfr-data-concat avec origin-field, et que <dsfr-data-chart series-field> consomme déjà — a une ligne par couple (libellé, série). Rendu tel quel, le tableau équivalent répète chaque libellé sans jamais dire de quelle série vient la valeur. Poser ici le même series-field pivote le tableau : une ligne par libellé, une colonne par série, la cellule de libellé en <th scope="row"> pour que chaque valeur garde ses deux coordonnées. Le CSV suit la même structure. L'attribut exige label-field et value-field : sans eux, le manque est signalé en console et le tableau reste à plat plutôt que pivoté de travers. Un couple absent des données laisse une cellule vide — le graphique y trace 0, le tableau ne l'affirme pas.

Fonctionnement ARIA

  1. Le composant génère automatiquement un id s'il n'en a pas
  2. Un skip link est injecte dans le graphique cible (visible au focus clavier)
  3. aria-describedby pointe vers un resume concis dans le composant
  4. aria-details pointe vers le tableau de données (si table est active), seulement quand le tableau est affiché : il est retiré pendant le premier chargement et pendant une panne, et gardé pendant un dernier relevé stale-if-error
  5. A la deconnexion, tout est nettoye automatiquement

Exemples

1. Tableau + téléchargement CSV

<dsfr-data-chart id="mon-graph" source="data" type="bar"
  label-field="statut" value-field="total">
</dsfr-data-chart>
<dsfr-data-a11y for="mon-graph" source="data" table download></dsfr-data-a11y>

2. Avec description textuelle

<dsfr-data-a11y for="mon-graph" source="data"
  table download
  description="Ce graphique montre la repartition des sites par statut.">
</dsfr-data-a11y>

3. Cohabitation avec DataBox

Quand le graphique cible utilise l'attribut databox, ne PAS ajouter table ni download sur dsfr-data-a11y (DataBox les fournit déjà avec un meilleur rendu : switch chart/tableau integre, CSV natif). Conserver uniquement description :

<dsfr-data-chart id="mon-graph" source="data" type="bar"
  label-field="region" value-field="total"
  databox databox-title="Population par region"
  databox-download databox-screenshot>
</dsfr-data-chart>
<!-- Avec DataBox : pas de table ni download -->
<dsfr-data-a11y for="mon-graph" source="data"
  description="L'Ile-de-France concentre la majorite de la population.">
</dsfr-data-a11y>

4. Mode manuel (no-auto-aria)

Si vous gerez manuellement les attributs ARIA :

<dsfr-data-a11y source="data"
  no-auto-aria table download>
</dsfr-data-a11y>