Affiche un classement visuel (top N) avec rang numerote, label, barre de progression proportionnelle et valeur formatee.

Attributs

AttributTypeDéfautDescription
sourceString""Id de la source (ou du transformateur) dont ce composant consomme les données.
label-fieldString""Chemin vers le champ label
value-fieldString""Chemin vers le champ valeur (numérique)
subtitleString""Texte fixe affiché sous chaque label
subtitle-fieldString""Chemin vers un champ pour le sous-titre (prioritaire sur subtitle)
value-unitString""Unité affichée après la valeur
selected-paletteStringsequentialDescendingPalette de couleurs pour la bordure gauche
max-itemsNumber5Nombre maximum d'items affichés
no-sortBooleanfalseDesactive le tri automatique (desc par valeur)
bar-maxNumber—Valeur max forcee pour le calcul des barres (ex: 100 pour des %)
idle-messageStringIDLE_MESSAGE_DEFAULTMessage rendu quand l'amont attend un filtre (require-where, #690). Distinct de « aucune donnée » : aucune requête n'a été faite. Vide, le libellé par défaut est utilisé.

Vignette : image, pictogramme ou icône

Une vignette de 40 px se pose entre le rang et le libellé. Les trois voies sont exclusives — si plusieurs sont posées, l'image l'emporte, puis le pictogramme, puis l'icône, et le cumul est signalé en console.

Ce qui vient de la donnée est contraint, jamais assaini après coup. Une classe d'icône doit répondre à ^(fr-icon|ri)-[a-z0-9-]+$ : la donnée ne pose qu'une classe CSS, jamais du balisage. Un nom de pictogramme doit répondre à ^[a-z0-9-]+(/[a-z0-9-]+)*$ et l'URL est construite en le concaténant à picto-base, attribut de la balise donc écrit par l'intégrateur — ce découpage exclut ../ et javascript: par construction. Une URL d'image-field passe par la même liste blanche de schémas que le format {{champ:url}}. Dans les trois cas, une valeur refusée n'affiche rien et avertit en console en nommant le champ et la valeur — une fois par valeur, pas une fois par ligne.

AttributTypeDéfautDescription
image-fieldString""Chemin vers un champ contenant l'URL d'une image (logo, blason), rendue en vignette 40 px entre le rang et le libellé. L'URL vient de la donnée : elle passe par la même liste blanche de schémas que le format {{champ:url}} (http:, https:, mailto:, tel: ou URL relative). Une URL refusée n'affiche rien et avertit en console, une fois par valeur. Exclusif avec icon-field / icon et picto / picto-field (l'image l'emporte, et le cumul est signalé).
image-shapeStringsquareForme de la vignette d'image-field : square (défaut) ou circle.
icon-fieldString""Chemin vers un champ contenant une classe d'icône DSFR ou Remix (fr-icon-building-line, ri-map-pin-line), rendue 40 px en Bleu France. Liste blanche stricte ^(fr-icon|ri)-[a-z0-9-]+$ : ce qui vient de la donnée ne pose qu'une classe CSS, jamais du balisage. Une valeur hors motif est ignorée avec un avertissement nommant le champ et la valeur (dédupliqué : une fois par valeur refusée). ⚠️ 40 px sort de l'échelle documentée du DSFR, qui s'arrête à fr-icon--lg = 32 px ; au-delà le DSFR parle de pictogramme. Le rendu marche (le masque d'une fr-icon-* est en 1em, donc pilotable par font-size), mais c'est un usage hors échelle : picto est la voie conforme pour une illustration de cette taille.
iconString""Même classe d'icône pour tous les items. Même liste blanche qu'icon-field.
pictoString""Nom d'un pictogramme DSFR, identique pour tous les items. L'URL est construite en concaténant picto-base et ce nom (<base><nom>.svg) : la donnée ne fournit jamais qu'un nom, contraint à ^[a-z0-9-]+(/[a-z0-9-]+)*$. Le balisage rendu est le fr-artwork standard du DSFR, donc les couleurs viennent des classes DSFR et le mode sombre suit sans travail.
picto-fieldString""Chemin vers un champ contenant le nom du pictogramme. Même contrainte que picto.
picto-baseString""Préfixe d'URL des pictogrammes, écrit par l'intégrateur (jamais par la donnée) — par exemple /dsfr/artwork/pictograms/. Sans lui, picto et picto-field ne rendent rien et avertissent : c'est ce découpage nom / base qui exclut ../ et javascript: par construction.

Rang, orientation et estrade

AttributTypeDéfautDescription
rankStringnumberRendu du rang : number (chiffre, défaut), medal (pastille de la couleur de l'item) ou none (masqué — l'ordre et la barre suffisent). En medal, la couleur d'encre du chiffre est choisie par calcul de luminance relative WCAG : la rampe s'éclaircit, et du blanc dès son **4e ton** serait illisible. Le chiffre reste aria-hidden : l'ordre est porté par la position dans la liste, le chiffre n'en est qu'un rappel. ⚠️ La rampe est CHOROPLETH_SCALES.sequentialDescending (9 tons), de constants/choropleth-scales.ts — **pas** PALETTE_COLORS.sequentialDescending (5 tons), de constants/palette-colors.ts, qui porte le même nom de clé. Lire la seconde donne un tableau de contraste plausible et faux — c'est arrivé trois fois quand les deux vivaient dans le même fichier (#969). Ratios sur les 5 premiers tons, encre retenue en gras : | Rang | Couleur | vs blanc | vs #161616 | |------|-----------|-----------|--------------| | 1 | #000091 | **14,91** | 1,21 | | 2 | #2323B4 | **10,65** | 1,70 | | 3 | #4747E5 | **6,36** | 2,84 | | 4 | #6A6AF4 | 4,22 | **4,29** | | 5 | #8585F6 | 3,14 | **5,76** | Le point bas est le **rang 4** : 4,29:1, sous AA texte normal (4,5:1) et au-dessus de AA texte large (3:1). Aucune des deux encres n'atteint 4,5 sur #6A6AF4. Ces chiffres sont figés par tests/dsfr-data-podium-evolutions.test.ts.
orientationStringhorizontalhorizontal (défaut) ou vertical : barres verticales en colonnes, une par item, dans l'ordre du classement.
layoutStringlistlist (défaut) ou podium : estrade 2‑1‑3, le premier au centre. L'inversion est **purement visuelle** (order CSS sur les éléments de grille) : le DOM reste dans l'ordre 1‑2‑3, donc un lecteur d'écran et la navigation clavier parcourent le classement dans l'ordre. Les items au‑delà du 3e passent en liste compacte sous l'estrade, dans le même <ol>.

Contraste de la pastille (rank="medal")

L'encre du chiffre est choisie au rendu par calcul de luminance relative WCAG sur la couleur réellement servie. La rampe par défaut est CHOROPLETH_SCALES.sequentialDescending — et non PALETTE_COLORS.sequentialDescending, qui porte le même nom dans le même fichier avec cinq tons différents. Recalculer sur la mauvaise donne un tableau plausible et faux.

RangCouleur servievs blancvs gris de titreEncre retenue
1#00009114,91:11,21:1blanc
2#2323B410,65:11,70:1blanc
3#4747E56,36:12,84:1blanc
4#6A6AF44,22:14,29:1gris de titre
5#8585F63,14:15,76:1gris de titre

Le point bas est le rang 4 : 4,29:1, sous le seuil AA « texte normal » (4,5:1) et au-dessus du seuil AA « texte large » (3:1). Aucune des deux encres n'atteint 4,5:1 sur #6A6AF4 — c'est le meilleur des deux choix possibles, pas un oubli. Le chiffre reste aria-hidden et l'ordre est porté par la position dans le <ol> : la pastille n'en est qu'un rappel. Ces cinq couples (couleur, encre) et ces ratios sont figés par un test, pour qu'un changement de palette casse la recette au lieu de faire mentir cette page.

Barre de données, liseré et arrondis

Trois axes séparés, pas un attribut multivalué. bar dit ce que porte la barre, bar-position dit où elle est, border pose un liseré purement décoratif. Les trois se combinent librement : bar="proportional" bar-position="top" border="left" est une combinaison valide, et non une valeur composée.

AttributTypeDéfautDescription
barStringproportionalCe que porte la barre de donnée : proportional (longueur = la donnée, défaut), full (pleine largeur, la couleur seule distingue les rangs) ou none (aucune barre). Indépendant de bar-position et de border.
bar-positionStringinlineOù la barre se place : inline (6 px sous le libellé, défaut), between (16 px entre un libellé de 130 px et la valeur, façon graphique en barres horizontal), top ou bottom (trait de 4 px en haut ou en bas de l'item, façon liseré mais proportionnel). Indépendant de bar et de border.
borderStringleftLiseré gauche purement décoratif, à la couleur de l'item : left (défaut) ou none. Indépendant de bar et de bar-position — la barre porte la donnée, le liseré ne porte que la couleur.
squareBooleanfalseSupprime les arrondis (0 px), conforme DSFR strict. **C'est le rendu par défaut depuis la 0.34** : l'attribut n'existe que pour l'écrire explicitement. L'échappatoire est rounded, qui rétablit les anciens arrondis (4 px sur l'item, 3 px sur la barre) ; si les deux sont posés, square l'emporte.
roundedBooleanfalseRétablit les arrondis d'avant la 0.34 (item 4 px, barre 3 px).

Les arrondis sont à 0 depuis la 0.34

L'item passe de 4 px à 0, la barre de 3 px à 0 : c'est le rendu square, devenu le défaut, plus conforme au DSFR. C'est le seul changement visuel qui s'applique sans qu'aucun attribut soit posé. rounded rétablit les anciens arrondis ; si square et rounded sont posés tous les deux, square l'emporte.

En attente d'un filtre

Un classement n'a pas de sens avant qu'un périmètre soit choisi. Quand l'amont porte require-where (<dsfr-data-source> ou <dsfr-data-query>), le podium ne rend ni barres ni « aucune donnée » mais le texte de idle-message — « Choisissez un filtre pour afficher les données » par défaut. Le message dit que rien n'a été demandé, là où « aucune donnée » dirait qu'une requête est revenue vide. Le mécanisme est décrit sur dsfr-data-source.

Palettes disponibles

PaletteDescription
sequentialDescendingBleu fonce vers bleu clair (défaut) — ideal pour les classements
sequentialAscendingBleu clair vers bleu fonce
categoricalCouleurs contrastees — ideal quand les items ne sont pas ordonnes
neutralNiveaux de gris

Exemples

1. Top 5 des sites par score RGAA

<dsfr-data-podium
  source="sites"
  label-field="nom"
  value-field="score_rgaa"
  subtitle="Site gouvernemental"
  value-unit="/ 100"
  selected-palette="sequentialDescending"
  max-items="5"
  bar-max="100">
</dsfr-data-podium>

2. Top 3 avec palette catégorielle

<dsfr-data-podium
  source="sites"
  label-field="nom"
  value-field="score_dsfr"
  subtitle="Conformite DSFR"
  value-unit="%"
  selected-palette="categorical"
  max-items="3"
  bar-max="100">
</dsfr-data-podium>

3. Avec sous-titres dynamiques (subtitle-field)

<dsfr-data-podium
  source="sites"
  label-field="nom"
  value-field="score_rgaa"
  subtitle-field="ministere"
  value-unit="/ 100"
  bar-max="100"
  max-items="5">
</dsfr-data-podium>

4. Sans tri (ordre de la source) + palette neutre

<dsfr-data-podium
  source="sites"
  label-field="nom"
  value-field="score_rgaa"
  value-unit="/ 100"
  selected-palette="neutral"
  max-items="5"
  bar-max="100"
  no-sort>
</dsfr-data-podium>

5. Avec dsfr-data-query (agrégation par ministere)

<dsfr-data-query id="par-ministere" source="sites"
  group-by="ministere"
  aggregate="score_rgaa:avg:score_moyen"
  order-by="score_moyen:desc">
</dsfr-data-query>

<dsfr-data-podium
  source="par-ministere"
  label-field="ministere"
  value-field="score_moyen"
  subtitle="Score RGAA moyen"
  value-unit="/ 100"
  bar-max="100"
  max-items="5">
</dsfr-data-podium>

6. Vignette image (image-field, 3a)

Une image issue d'un champ de la donnée, 40 px, entre le rang et le libellé. image-shape="circle" la rend ronde.

<dsfr-data-podium
  source="sites"
  label-field="nom"
  value-field="score_rgaa"
  value-unit="/ 100"
  bar-max="100"
  max-items="5"
  image-field="logo"
  image-shape="square">
</dsfr-data-podium>

7. Icône par item et rang en pastille (icon-field + rank, 3b)

L'icône vient de la donnée, validée par liste blanche ; le rang chiffré migre en pastille de la couleur de l'item, dont l'encre est choisie par luminance.

<dsfr-data-podium
  source="sites"
  label-field="nom"
  value-field="score_rgaa"
  value-unit="/ 100"
  bar-max="100"
  max-items="5"
  icon-field="icone"
  rank="medal">
</dsfr-data-podium>

8. Pastille seule, sans liseré (rank + border, 3c)

Le rang dans un disque de 32 px à la couleur de l'item ; le liseré gauche devient facultatif.

<dsfr-data-podium
  source="sites"
  label-field="nom"
  value-field="score_rgaa"
  value-unit="/ 100"
  bar-max="100"
  max-items="5"
  rank="medal"
  border="none">
</dsfr-data-podium>

9. Sans rang (rank="none", 3d)

Le rang disparaît : l'ordre de la liste et la barre suffisent. Utile avec no-sort (étapes, progression).

<dsfr-data-podium
  source="sites"
  label-field="nom"
  value-field="score_dsfr"
  value-unit="%"
  bar-max="100"
  max-items="4"
  rank="none"
  no-sort>
</dsfr-data-podium>

10. Colonnes (orientation="vertical", 3e)

Barres verticales, une colonne par item, dans l'ordre du classement.

<dsfr-data-podium
  source="sites"
  label-field="nom"
  value-field="score_rgaa"
  value-unit="/ 100"
  bar-max="100"
  max-items="5"
  orientation="vertical">
</dsfr-data-podium>

11. Estrade 2-1-3 (layout="podium", 3f)

Le podium au sens propre : trois marches, le premier au centre, les suivants en liste compacte dessous. Le DOM reste dans l'ordre 1‑2‑3 — l'inversion est faite par order en CSS, pour qu'un lecteur d'écran et la navigation clavier parcourent le classement dans l'ordre.

<dsfr-data-podium
  source="sites"
  label-field="nom"
  value-field="score_rgaa"
  value-unit="/ 100"
  bar-max="100"
  max-items="5"
  layout="podium"
  icon-field="icone">
</dsfr-data-podium>

12. Barre proportionnelle en haut, avec liseré (3g et 3h)

La barre de données remplace le liseré haut : sa longueur est la donnée. Avec border="left" on garde en plus le liseré décoratif (3h) ; avec border="none" on a la vignette 3g.

<dsfr-data-podium
  source="sites"
  label-field="nom"
  value-field="score_rgaa"
  value-unit="/ 100"
  bar-max="100"
  max-items="5"
  bar="proportional"
  bar-position="top"
  border="left">
</dsfr-data-podium>

13. Barre dans la ligne (bar-position="between", 3i)

La barre de 16 px prend la place entre un libellé de 130 px et la valeur, comme un graphique en barres horizontal. À distinguer d'inline, qui est le rendu historique : barre de 6 px sous le libellé.

<dsfr-data-podium
  source="sites"
  label-field="nom"
  value-field="score_rgaa"
  value-unit="/ 100"
  bar-max="100"
  max-items="5"
  bar="proportional"
  bar-position="between"
  border="none">
</dsfr-data-podium>

14. Barre pleine en haut (bar="full", 3j)

Liseré haut non proportionnel : la couleur seule distingue les rangs. Pour un top N où l'écart chiffré ne doit pas être surinterprété.

<dsfr-data-podium
  source="sites"
  label-field="nom"
  value-field="score_rgaa"
  value-unit="/ 100"
  bar-max="100"
  max-items="5"
  bar="full"
  bar-position="top">
</dsfr-data-podium>

15. Sans barre, liseré gauche (bar="none", 3k)

Liste compacte : le liseré seul porte la couleur, aucune information de proportion.

<dsfr-data-podium
  source="sites"
  label-field="nom"
  value-field="score_rgaa"
  value-unit="/ 100"
  bar-max="100"
  max-items="5"
  bar="none"
  border="left">
</dsfr-data-podium>

16. Barre proportionnelle en bas (bar-position="bottom", 3l)

Variante de 3g : la barre souligne l'item. Convient quand le libellé est long ou sur deux lignes.

<dsfr-data-podium
  source="sites"
  label-field="nom"
  value-field="score_rgaa"
  value-unit="/ 100"
  bar-max="100"
  max-items="5"
  bar="proportional"
  bar-position="bottom">
</dsfr-data-podium>