République
française
dsfr-data
Documentation — Web Components DSFR pour la dataviz
Couche de données d'une carte dsfr-data-map :
markers, zones géographiques (geoshape), cercles proportionnels ou heatmap.
Chaque couche est connectée à sa propre source — le multi-source est naturel.
Enfant de dsfr-data-map : le composant est invisible,
il projette les enregistrements de sa source sur la carte hôte.
L'affichage au clic passe de préférence par le compagnon
dsfr-data-map-popup
(les attributs popup-template/popup-fields sont le mode legacy).
| Attribut | Type | Défaut | Description |
|---|---|---|---|
source | String | "" | Id de la source (ou du transformateur) dont cette couche consomme les données. |
type | marker · geoshape · circle · heatmap | marker | Rendu de la couche : marker (epingles), geoshape (polygones/lignes GeoJSON), circle (cercles proportionnels), heatmap (carte de chaleur). |
lat-field | String | "" | Chemin vers le champ latitude (mode coordonnées séparées). |
lon-field | String | "" | Chemin vers le champ longitude (mode coordonnées séparées). |
geo-field | String | "" | Champ geometrie : objet GeoJSON, {lat, lon}, [lat, lon] ou chaîne JSON serialisee (#426). Vide sur une couche geoshape : la première colonne geo_shape, geometry ou geom qui porte du GeoJSON est détectée, et nommée dans l'avertissement des lignes ignorées (#1053). |
shape-class | String | "" | Classe CSS appliquee aux traces SVG de la couche (geoshape/circle) — permet un style page (motif hachure, pointilles...) via CSS/SVG <pattern> |
no-interactive | Boolean | false | Couche decorative : aucune interaction (pas de clic, tooltip ni popup) — contours administratifs, habillage |
Sans lat-field/geo-field, la couche auto-détecte les champs
geo_point_2d, geopoint, geo_point (points) puis
geo_shape, geometry, geom (formes).
Couche geoshape sans geo-field (#1053) : la couche
trace la première colonne geo_shape, geometry ou geom
qui porte du GeoJSON, objet ou chaîne sérialisée, sur l'une des vingt premières lignes.
geo_point_2d n'est jamais retenu pour tracer des formes : un jeu Opendatasoft
porte le point et la forme, et c'est la forme qui est dessinée. Les
Feature d'une source transform="features" sont lues par leur
geometry. La colonne détectée est nommée dans l'avertissement des lignes
ignorées. Si aucune ne convient, la couche ne trace rien et le dit en console
(« aucune colonne géométrique détectée ») : poser alors geo-field.
Le calcul d'emprise (bbox) garde sa propre détection, qui commence par
geo_point_2d : voir bbox-field.
| Attribut | Type | Défaut | Description |
|---|---|---|---|
popup-template | String | "" | Template du contenu de la popup, avec substitution de champs. Ex: "{nom} — {val} kW". |
popup-fields | String | "" | Champs a presenter en tableau automatique dans la popup. Ex: "nom,adresse". |
tooltip-field | String | "" | Champ affiché au survol de l'élément. |
color | String | #000091 | Couleur de la couche (défaut : blue-france DSFR). Sert aussi de repli quand color-map ne matche pas. |
color-field | String | "" | Champ dont la valeur détermine la couleur (mapping catégoriel via color-map). |
color-map | String | "" | Paires valeur:#couleur séparées par des virgules. Ex: "1:#00A95F,2:#FF9940,3:#E1000F". Une virgule ou un deux-points dans une valeur s'écrit %2C ou %3A. |
color-other-label | String | COLOR_OTHER_LABEL_DEFAULT | Libellé, dans la légende, des valeurs de color-field ABSENTES de color-map — celles qui prennent la couleur de repli color. L'entrée n'apparaît que si le repli a servi au dernier rendu. Ex. : color-other-label="Autres secteurs". Vide, le libellé par défaut est utilisé. À ne pas confondre avec l'empty-label d'autres composants, qui nomme une valeur VIDE : une valeur hors color-map peut être renseignée, et l'appeler « Non renseigné » mentirait dès qu'une modalité nouvelle apparaît dans le jeu. Pour nommer les valeurs vides seulement, leur donner une paire dans color-map après un recodage amont (dsfr-data-normalize). |
fill-field | String | "" | Champ numérique utilisé pour le remplissage en choroplèthe, sur une couche geoshape ou circle (#768) — avec classes, method, breaks et selected-palette. Posé avec color-field, il gagne pour le REMPLISSAGE ; color-field / color donnent alors le contour, et la légende décrit les classes. Sans effet sur marker et heatmap. |
fill-opacity | Number | 0.6 | Opacite du remplissage (0-1). |
selected-palette | String | "" | Palette DSFR utilisée pour le dégradé choroplèthe (fill-field) : sequentialAscending (défaut), sequentialDescending, divergentAscending, divergentDescending, neutral, categorical. |
method | quantile · equal · manual | quantile | Méthode de discrétisation de la choroplèthe : quantile (défaut, effectifs égaux par classe), equal (intervalles de même largeur), manual (bornes de breaks). |
classes | Number | 0 | Nombre de classes de la choroplèthe (fill-field). 0 (défaut) = autant de classes que de couleurs dans l'échelle (9). Plafonné à la taille de l'échelle (#685). |
breaks | String | "" | Bornes supérieures manuelles des classes, séparées par des virgules : "10,50,100" donne 4 classes (jusqu'à 10, 10 à 50, 50 à 100, plus de 100). Implique method="manual". |
radius | Number | 8 | Rayon fixe des cercles (type="circle"). |
radius-field | String | "" | Champ numérique pilotant un rayon variable (type="circle"). L'échelle est celle de radius-scale : linéaire entre radius-min et radius-max par défaut, en aire avec sqrt. |
radius-scale | linear · sqrt | linear | Échelle du rayon variable (radius-field, radius-unit="px"). linear (défaut) : le RAYON suit la valeur, de radius-min pour la plus petite à radius-max pour la plus grande. sqrt : l'AIRE du cercle est proportionnelle à la valeur — c'est l'échelle des symboles proportionnels, à préférer dès que le lecteur compare des tailles. Elle est ancrée à zéro : rayon = radius-max × √(valeur / plus grande valeur), une valeur quatre fois plus grande a un rayon double, la plus grande prend radius-max. Une valeur nulle, négative ou absente a un rayon nul (le cercle se réduit à un point d'un pixel, qui reste cliquable) ; les valeurs négatives sont signalées en console. radius-min est sans effet en sqrt : un plancher fausserait le rapport des petites valeurs. Sans effet avec radius-unit="m", où le champ donne le rayon en mètres. |
radius-unit | px · m | px | Unité du rayon : px (constant à l'écran) ou m (mètres, suit le zoom). |
radius-min | Number | 4 | Rayon de la plus petite valeur en échelle linéaire, en pixels. Sans effet avec radius-scale="sqrt". |
radius-max | Number | 30 | Rayon de la plus grande valeur, en pixels (les deux échelles de radius-scale). |
radius-field fait varier le rayon des cercles (type="circle") selon un champ
numérique. radius-scale dit comment :
linear (défaut) — le rayon suit la valeur, de
radius-min pour la plus petite à radius-max pour la plus grande. La plus
petite valeur a donc toujours un cercle, même quand elle vaut zéro, et une valeur dix fois plus grande
peut occuper jusqu'à cent fois plus de surface. Convient à un indice ou à un rang, pas à une quantité.
sqrt — l'aire du cercle est proportionnelle à la valeur, et l'échelle
est ancrée à zéro : rayon = radius-max × √(valeur / plus grande valeur). Une valeur quatre
fois plus grande a un rayon double ; la plus grande prend radius-max.
Pour des symboles proportionnels, utilisez radius-scale="sqrt" : l'œil compare
des surfaces, pas des rayons. L'échelle linéaire reste le défaut pour que les cartes existantes ne bougent pas.
En sqrt :
radius-min est sans effet : un plancher fausserait le rapport des petites
valeurs. Si les plus petits cercles sont illisibles, relevez radius-max ;radius-max="30", les valeurs 1, 4 et 100
donnent 3, 6 et 30 px ;max-items) et se recalcule à chaque
nouvelle donnée : un filtre amont change la plus grande valeur, donc la taille de tous les cercles.
radius-scale ne s'applique pas avec radius-unit="m", où le champ donne directement
un rayon en mètres. Une valeur inconnue (radius-scale="log") est signalée en console et
l'échelle linéaire s'applique.
<dsfr-data-map-layer source="musees" type="circle" geo-field="position" radius-field="entrees" radius-scale="sqrt" radius-max="30" color="#000091" fill-opacity="0.4" tooltip-field="nom"></dsfr-data-map-layer>
color-map
Une valeur de color-field qui n'a pas de paire dans color-map prend la couleur de
repli color, et la légende (dsfr-data-map-legend)
lui ajoute une entrée dès que le repli a servi. Son libellé est celui de color-other-label,
« Autres valeurs » par défaut :
<dsfr-data-map-layer id="reseau" source="communes" type="circle" geo-field="position" color-field="etat" color-map="Fermé:#00A95F,En cours:#FF9940" color="#929292" color-other-label="État inconnu"></dsfr-data-map-layer> <dsfr-data-map-legend for="reseau" label="Fermeture du réseau"></dsfr-data-map-legend>
Ce libellé nomme des valeurs hors de la table des couleurs, pas des valeurs vides : c'est
pourquoi l'attribut ne s'appelle pas empty-label, qui sur
dsfr-data-chart, dsfr-data-facets et dsfr-data-a11y nomme une valeur
absente. Sur un champ ouvert, une modalité nouvelle du jeu tombe elle aussi dans le repli : l'appeler
« Non renseigné » serait faux. Pour distinguer les valeurs vides, les recoder en amont
(dsfr-data-normalize) et leur donner leur propre paire dans color-map.
| Attribut | Type | Défaut | Description |
|---|---|---|---|
refine-on-click | String | "" | Champ dont la valeur de l'objet cliqué devient un filtre eq (#681). Premier clic = filtre, second clic sur le même objet = retrait, clic sur un autre objet = remplacement. Avec context="id" (recommandé), la couche s'enregistre comme filtre du dsfr-data-context : diffusion à toutes ses sources cibles au dialecte de chacune, tag dans dsfr-data-context-tags, URL portée par le contexte. Sans context, la clause part directement à source (whereKey map-select-ID) — sans tag ni URL. Attention : si source est aussi une cible du contexte, la carte se filtre elle-même (seul l'objet cliqué reste, jusqu'au second clic) ; pour garder tous les points, ne pas lister cette source dans sources du contexte (ou donner à la carte sa propre source). |
context | String | "" | Id du dsfr-data-context auquel s'enregistrer en refine-on-click (#681, ADR-104). Le contexte peut être déclaré après la couche dans la page. Vide = commande directe à source (chemin dégradé). |
label | String | "" | Libellé de la couche — sert de libellé au tag du contexte en refine-on-click (#681 ; vide = le nom du champ), et nomme la couche dans la ligne d'état de la carte quand sa source est en panne (#1288) : « Couche « Bornes de recharge » : données momentanément indisponibles. » (vide = le libellé de sa légende, sinon la couche n'est pas nommée). |
Quand les données sont au format long — une ligne par couple ville × aide,
coordonnées répétées sur chaque ligne —, group-field="Ville" trace
un seul marqueur (ou cercle, ou forme) par valeur distincte du champ, au lieu
de N marqueurs empilés. Au clic, la popup, le volet (panel-left /
panel-right) ou la modale de dsfr-data-map-popup reçoivent
toutes les lignes du groupe : en titre la valeur du groupe (ou le
title-field du compagnon, lu sur le premier enregistrement), puis un tableau des
popup-fields avec une ligne par enregistrement. Si popup-template (ou
le <template> du compagnon) est posé, il s'applique à chaque ligne, en liste.
Sans popup-fields ni gabarit, le compagnon montre les colonnes scalaires du jeu,
hors géométrie et hors champ de regroupement. Au plus 200 lignes, puis « … et N autres ».
Toutes les valeurs sont échappées.
geoshape). Des coordonnées
différentes au sein d'un groupe sont signalées une fois en console.tooltip-field, color-field, radius-field,
fill-field : la valeur de ce même premier enregistrement. Pour un
rayon ou une couleur proportionnels à un total par groupe, agréger en amont
(dsfr-data-query group-by) sur une seconde couche.max-items, getRenderedCount(), le bandeau de
troncature et le total de dsfr-data-map-layer-render comptent des
groupes.refine-on-click : à poser sur le même champ, il filtre sur la
valeur du groupe. L'événement dsfr-data-map-select porte en plus
group et records (toutes les lignes).cluster : compatible, chaque groupe est un point de la
grappe. Une ligne sans valeur de regroupement reste un élément à part.heatmap : group-field est sans effet (chaque
ligne reste un point de chaleur) et un avertissement le dit en console.<dsfr-data-map center="46.6,2.3" zoom="6"> <dsfr-data-map-layer id="aides" source="src-aides" type="marker" lat-field="Latitude" lon-field="Longitude" group-field="Ville" popup-fields="Action,Domaine"></dsfr-data-map-layer> <dsfr-data-map-popup for="aides" mode="panel-right"></dsfr-data-map-popup> </dsfr-data-map>
| Attribut | Type | Défaut | Description |
|---|---|---|---|
group-field | String | "" | Regroupement (#1108) : un seul élément tracé par valeur distincte de ce champ — données au format LONG, une ligne par couple ville × aide avec les coordonnées répétées. Au clic, la popup, le volet ou la modale reçoivent TOUTES les lignes du groupe : titre = valeur du groupe (ou title-field du dsfr-data-map-popup), puis un tableau des popup-fields avec une ligne par enregistrement ; popup-template (ou le <template> du compagnon) s'applique alors à chaque ligne, en liste. Au plus 200 lignes rendues, « … et N autres » au-delà. Position, tooltip-field, color-field, radius-field, fill-field : ceux du PREMIER enregistrement du groupe qui porte des coordonnées exploitables (le premier tout court pour geoshape). Des coordonnées qui diffèrent au sein d'un groupe sont signalées une fois en console. max-items, getRenderedCount() et le bandeau comptent des GROUPES ; refine-on-click (à poser sur le même champ) filtre sur la valeur du groupe ; en cluster, chaque groupe est un point de la grappe. Une ligne sans valeur de regroupement reste un élément à part. Sans effet sur heatmap (chaque ligne reste un point de chaleur, avertissement en console). |
| Attribut | Type | Défaut | Description |
|---|---|---|---|
heat-radius | Number | 25 | Rayon d'influence de chaque point de la heatmap, en pixels. |
heat-blur | Number | 15 | Flou applique a la heatmap, en pixels. |
heat-field | String | "" | Champ de ponderation des points de la heatmap. |
| Attribut | Type | Défaut | Description |
|---|---|---|---|
cluster | Boolean | false | Regroupe les marqueurs proches en clusters. |
cluster-radius | Number | 80 | Rayon de regroupement des clusters, en pixels. |
| Attribut | Type | Défaut | Description |
|---|---|---|---|
min-zoom | Number | 0 | Niveau de zoom en deca duquel la couche est masquee. |
max-zoom | Number | 18 | Niveau de zoom au-delà duquel la couche est masquee. |
bbox | Boolean | false | Chargement par viewport : réinterroge la source à chaque déplacement de la carte, et une première fois dès que la carte est prête (#652). Le tout premier fetch de la source reste NON filtre (elle charge des sa connexion, avant que la carte — différée a la visibilité — ait un viewport) : sur un gros jeu, poser un limit ou un where initial sur la source. La clause de zone visible est écrite par l'adaptateur de la source (adaptateurs déclarant serverGeo, #1149), sur bbox-field ou, à défaut, sur lat-field / lon-field ; sinon, les lignes déjà reçues sont filtrées dans le navigateur. |
bbox-debounce | Number | 300 | Délai d'anti-rebond avant le re-fetch bbox, en millisecondes. |
bbox-field | String | "" | Champ géographique utilisé pour la requête bbox. Vide : geo-field, sinon détecté sur les premières lignes reçues — la clause serveur attend ces lignes, aucun nom de colonne n'est supposé (#1139). |
| Attribut | Type | Défaut | Description |
|---|---|---|---|
time-field | String | "" | Champ date/heure activant l'animation temporelle (pilotee par <dsfr-data-map-timeline>). |
time-bucket | none · hour · day · month · year | none | Granularite des pas de temps : none, hour, day, month, year. |
time-mode | snapshot · cumulative | snapshot | Rendu temporel : snapshot (seulement le pas courant) ou cumulative (tout jusqu'au pas courant). |
| Attribut | Type | Défaut | Description |
|---|---|---|---|
max-items | Number | 5000 | Plafond du nombre d'éléments rendus sur la carte (défaut 5000). Il protège les marqueurs DOM (divIcon), le fit et les popups. Un bandeau (role="status") donne les deux chiffres — éléments affichés et total connu — dès que la carte n'en montre qu'une partie : plafond max-items dépassé, OU source qui n'a chargé qu'une partie du jeu (limit, max-records, plafond de pages : le total vient alors de la source, #1020). Il précise que les premiers enregistrements suivent l'ordre du fichier (ou le tri order-by de la source) : leur répartition n'est pas représentative. Aligner le limit de la source sur max-items évite de charger des lignes que la couche ne dessinera pas. Avec cluster, max-items="20000" est sans risque : les marqueurs regroupés ne pèsent pas sur le DOM. En mode bbox, zoomer recharge la zone visible ; hors bbox, seul un plafond plus haut (ou un filtre amont) affiche le reste. |
Bandeau « N affichés sur M » (#1020). Dès que la carte ne montre qu'une
partie du jeu, la couche pose sous la carte un bandeau role="status", sans
aucun contrôle interactif, qui donne les deux chiffres — éléments affichés
et total connu — et le biais : ce sont les premiers enregistrements, dans
l'ordre du fichier (ou du tri order-by de la source), leur répartition n'est donc
pas représentative. Deux cas le déclenchent :
max-items ; le total est le nombre de lignes reçues ;limit, max-records, plafond de pages de l'adaptateur) ; la couche
lit la meta de la source, et le total est celui que l'API annonce.
C'est ce second cas qui rend sûr d'aligner le limit de la source sur
max-items : la source ne charge plus de lignes que la couche ne
dessinerait pas, et le bandeau reste là. Le Builder Carto le fait par défaut, avec un
plafond de 1 000 points (la bibliothèque garde 5 000). Pas de bandeau sur une carte
verrouillée (encarts) ; plusieurs couches tronquées empilent leurs bandeaux.
<dsfr-data-source id="elus" api-type="tabular" resource="…" limit="1000"></dsfr-data-source>
<dsfr-data-map>
<dsfr-data-map-layer source="elus" lat-field="lat" lon-field="lon" max-items="1000"></dsfr-data-map-layer>
</dsfr-data-map>
<!-- Bandeau : « 1 000 premiers enregistrements affichés sur 34 826, dans l'ordre du fichier :
la répartition affichée n'est pas représentative. La source n'a chargé qu'une partie du jeu. » -->
Attribut retiré : filter (retiré en #297, warn console s'il est
présent) — filtrer en amont avec dsfr-data-query ou l'attribut where
de la source.
La couche résout les coordonnées dans cet ordre de priorité :
lat-field + lon-field — coordonnées séparées (CSV, API)geo-field vers un Point — GeoJSON Point, objet {lat, lon} ou tableau [lat, lon]geo-field vers Polygon/MultiPolygon — rendu via L.geoJSON()geo_point_2d, geopoint, geo_point, puis geo_shape, geometry, geomÀ chaque étape, une chaîne JSON sérialisée est acceptée et parsée automatiquement (#426) — le cas des colonnes Text de Grist ou d'un CSV embarquant du GeoJSON.
| Événement | detail | Description |
|---|---|---|
dsfr-data-map-layer-time-ready |
{ steps: string[] } |
Émis (CustomEvent, bubbles) quand le découpage temporel est prêt : steps = pas de temps triés chronologiquement. Écouté par dsfr-data-map-timeline. |
| Méthode | Description |
|---|---|
setTimelineFrame(index) | Affiche le pas de temps d'index donné |
resetTimeline() | Revient à l'affichage complet (hors animation) |
getTimeSteps() | Retourne la liste des pas de temps découverts |
<dsfr-data-source id="bornes" api-type="opendatasoft" base-url="https://odre.opendatasoft.com" dataset-id="bornes-irve" select="geo_point_2d,nom_station,puissance_nominale,adresse" limit="5000"> </dsfr-data-source> <dsfr-data-map center="46.6,2.3" zoom="6" tiles="ign-plan" fit-bounds> <dsfr-data-map-layer source="bornes" type="marker" geo-field="geo_point_2d" tooltip-field="nom_station" cluster cluster-radius="60"> </dsfr-data-map-layer> </dsfr-data-map>
Régions en choroplèthe au zoom national, communes chargées par viewport
(bbox) au zoom local. Le contour de référence est une couche
no-interactive : ni clic, ni tooltip, ni influence sur le fit.
<dsfr-data-source id="regions" api-type="opendatasoft" base-url="https://public.opendatasoft.com" dataset-id="georef-france-region" select="geo_shape,reg_name,population" limit="20"> </dsfr-data-source> <dsfr-data-source id="communes" api-type="opendatasoft" base-url="https://public.opendatasoft.com" dataset-id="georef-france-commune" select="geo_shape,com_name,population" limit="500" server-side page-size="500"> </dsfr-data-source> <dsfr-data-map center="46.6,2.3" zoom="6" tiles="ign-plan" height="600px"> <!-- Contours de référence, purement décoratifs --> <dsfr-data-map-layer source="regions" type="geoshape" geo-field="geo_shape" no-interactive color="#7b7b7b" fill-opacity="0"> </dsfr-data-map-layer> <!-- Zoom 1-9 : régions --> <dsfr-data-map-layer source="regions" type="geoshape" geo-field="geo_shape" fill-field="population" selected-palette="sequentialAscending" tooltip-field="reg_name" min-zoom="1" max-zoom="9"> </dsfr-data-map-layer> <!-- Zoom 10+ : communes dans le viewport (in_bbox côté ODS) --> <dsfr-data-map-layer source="communes" type="geoshape" geo-field="geo_shape" fill-field="population" selected-palette="sequentialAscending" tooltip-field="com_name" min-zoom="10" bbox bbox-debounce="500"> </dsfr-data-map-layer> </dsfr-data-map>
<!-- Rayon écran : l'aire suit la valeur (radius-scale="sqrt"), radius-max en pixels --> <dsfr-data-map-layer source="villes" type="circle" lat-field="latitude" lon-field="longitude" radius-field="population" radius-unit="px" radius-scale="sqrt" radius-max="35" color="#000091" fill-opacity="0.4" tooltip-field="nom"> </dsfr-data-map-layer> <!-- Rayon terrain : la valeur du champ est un rayon en mètres (L.circle) --> <dsfr-data-map-layer source="antennes" type="circle" lat-field="lat" lon-field="lon" radius-field="portee_m" radius-unit="m" color="#C9191E" fill-opacity="0.15"> </dsfr-data-map-layer>
<dsfr-data-source id="bornes-trim" data='[ {"region":"Paris","lat":48.85,"lon":2.35,"bornes":120,"date":"2025-T1"}, {"region":"Lyon","lat":45.76,"lon":4.83,"bornes":85,"date":"2025-T1"}, {"region":"Paris","lat":48.85,"lon":2.35,"bornes":250,"date":"2025-T2"}, {"region":"Lyon","lat":45.76,"lon":4.83,"bornes":160,"date":"2025-T2"} ]'></dsfr-data-source> <dsfr-data-map center="46.6,2.3" zoom="6" height="550px"> <dsfr-data-map-layer source="bornes-trim" type="circle" lat-field="lat" lon-field="lon" radius-field="bornes" radius-min="6" radius-max="35" color="#000091" fill-opacity="0.5" tooltip-field="region" time-field="date" time-mode="snapshot"> </dsfr-data-map-layer> <dsfr-data-map-timeline speed="1" interval="1500"></dsfr-data-map-timeline> </dsfr-data-map>
dsfr-data-map — le conteneur et la vue d'ensemble de la familledsfr-data-map-popup — l'affichage au clic déclaratifdsfr-data-map-timeline — les contrôles de lecture temporelle