La librairie D3
Visusalisation des données avec la librairie D3
D3, ou D3.js, signifie Data Driven Documents, c'est une librairie Javascript permettant de créer des visualisation de données dynamiques et interactives dans ton navigateur. Elle est très populaire, robuste et avec de nombreuses fonctionnalités. Apprendre à l'utiliser sera un réel plus sur ton cv.
D3 est conçu pour fonctionner avec les normes Web courantes, à savoir HTML, CSS et Scalable Vector Graphics (SVG).
D3 prend en charge de nombreux types de formats de données d'entrée. Ensuite, à l'aide de ses puissantes méthodes intégrées, tu peux transformer ces données en différents tableaux, graphiques et cartes.
La visualisation des données est une représentation graphique et logique de données afin que ces dernières puissent être mise en valeur et les rendre plus parlantes qu'uniquement des chiffres qui sont plus difficiles à interprêter quand la quantité est énorme.
Installation
Il existe plusieurs manière de mettre en oeuvre cette librairie. Ici, tu vas utiliser le CDN. Si tu souhaites utiliser une autre mnanière tu peux aller lire la documentation Installation
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>D3.js Project</title>
<script src="https://cdn.jsdelivr.net/npm/d3@7" defer></script>
<script src="main.js" defer></script>
</head>
<body>
<div class = "box"></div>
</body>
</html>
Tu implémentes les balises scripts pour appeler le CDN
et la page de ton code javascript main.js
dans le head
de ton HTML en ajoutant l'attribut defer
qui permet d'indiquer au navigateur de ne pas attendre le script pour charger le reste du DOM.
C'est la meilleure manière et la plus rapide de faire appelle à du script.
Tu as aussi mis une div
avec une class
.
Select et SelectAll
D3 dispose de plusieurs méthodes qui te permettent d'ajouter et de modifier des éléments dans ton document.
La méthode select()
sélectionne un élément du document. Il prend un argument pour le nom de l'élément souhaité et renvoie un nœud HTML pour le premier élément du document qui correspond au nom.
Tu vas maintenant essentiellement travailler dans ta page javascript main.js
.
const box = d3.select(`.box`);
const div = d3.selectAll("div");
Append
La méthode append()
prend un argument pour l'élément que vous souhaitez ajouter au document. Il ajoute un nœud HTML à un élément sélectionné et renvoie un descripteur à ce nœud.
append
te permet d'ajouter des éléments. Ici, tu déclares trois éléments, un rectangle, une ligne et un cercle.
const box = d3.select(`.box`);
const svg = box.append('svg');
svg.append('rect');
svg.append('line');
svg.append('circle');
La méthode attr
C'est la méthode attribut attr
, qui permet d'ajouter des attributs par exemple à tes svg.
const box = d3.select(`.box`);
const svg = box.append('svg');
svg.attr('height', 500);
svg.attr('width', 500);
svg.append('rect');
svg.append('line');
svg.append('circle');
Enchaîner les méthodes
Pour gagner de la place et des lignes, tu peux enchaîner les méthodes comme dans l'exemple suivant.
const box = d3.select(`.box`);
const svg = box.append('svg').attr('height', 500).attr('width', 500);
svg.append('rect');
svg.append('line');
svg.append('circle');
Une meilleure manière d'écrire la même chose pour que ça soit plus lisible.
const box = d3.select(`.box`);
const svg = box.append('svg')
.attr('height', 500)
.attr('width', 500);
svg.append('rect');
svg.append('line');
svg.append('circle');
Maintenant, tu vas ajouter des attributs à tes éléments svg.
const box = d3.select(`.box`);
const svg = box.append('svg')
.attr('height', 500)
.attr('width', 500);
svg.append('rect')
.attr('height', 75)
.attr('width', 100)
.attr('fill', 'blue')
.attr('x', 100)
.attr('y', 100);
svg.append('line');
.attr('x1', 50)
.attr('y1', 200)
.attr('x2', 150)
.attr('y2', 250)
.attr('stroke', 'green');
svg.append('circle');
.attr('r', 75)
.attr('cx', 100)
.attr('cy', 150)
.attr('fill', 'orange');
La méthode text
La méthode text() définit le texte du nœud sélectionné ou obtient le texte actuel. Pour définir la valeur, tu passes une chaîne comme argument entre les parenthèses de la méthode.
d3.select("ul")
.append("li")
.text("Very important item");
Les groupes de SVG
Tu vas voir qu'il est intéressant de faire des groupes de svg.
const box = d3.select(`.box`);
const svg = box.append('svg')
.attr('height', 500)
.attr('width', 500);
const groupe = svg.append('g');
groupe.append('rect')
.attr('height', 75)
.attr('width', 100)
.attr('fill', 'blue')
.attr('x', 100)
.attr('y', 100);
groupe.append('line');
.attr('x1', 50)
.attr('y1', 200)
.attr('x2', 150)
.attr('y2', 250)
.attr('stroke', 'green');
groupe.append('circle');
.attr('r', 75)
.attr('cx', 100)
.attr('cy', 150)
.attr('fill', 'orange');
C'est très pratique, car tu peux ainsi ajouter des attributs à l'ensemble des formes dessinées en svg
en les ajoutant directement au groupe.
Dans l'exemple suivant, tu vas déplacer ainsi tous tes éléments en une ligne.
const box = d3.select(`.box`);
const svg = box.append('svg')
.attr('height', 500)
.attr('width', 500);
const groupe = svg.append('g')
.attr('transform', 'translate(0, 100');
groupe.append('rect')
.attr('height', 75)
.attr('width', 100)
.attr('fill', 'blue')
.attr('x', 100)
.attr('y', 100);
groupe.append('line');
.attr('x1', 50)
.attr('y1', 200)
.attr('x2', 150)
.attr('y2', 250)
.attr('stroke', 'green');
groupe.append('circle');
.attr('r', 75)
.attr('cx', 100)
.attr('cy', 150)
.attr('fill', 'orange');
Manipulation de nos premières données
La bibliothèque D3 se concentre sur une approche axée sur les données. Lorsque tu disposes d'un ensemble de données, tu peux appliquer des méthodes D3 pour l'afficher sur la page. Les données se présentent sous de nombreux formats.
La première étape consiste à informer D3 des données. La méthode data()
est utilisée sur une sélection d'éléments DOM pour attacher les données à ces éléments. L'ensemble de données est passé en argument à la méthode.
Un modèle de workflow courant consiste à créer un nouvel élément dans le document pour chaque donnée de l'ensemble. D3 a la méthode enter()
à cet effet.
Lorsque enter()
est combiné avec la méthode data()
, il examine les éléments sélectionnés de la page et les compare au nombre d'éléments de données dans l'ensemble. S'il y a moins d'éléments que d'éléments de données, il crée les éléments manquants.
Voici un exemple qui sélectionne un élément ul et crée un nouvel élément de liste en fonction du nombre d'entrées dans le tableau :
<body>
<ul></ul>
<script>
const dataset = ["a", "b", "c"];
d3.select("ul").selectAll("li")
.data(dataset)
.enter()
.append("li")
.text("New item");
</script>
</body>
Il peut sembler déroutant de sélectionner des éléments qui n'existent pas encore. Ce code indique à D3 de sélectionner d'abord l'ul sur la page. Ensuite, sélectionnez tous les éléments de la liste, ce qui renvoie une sélection vide. Ensuite, la méthode data()
examine l'ensemble de données et exécute le code suivant trois fois, une fois pour chaque élément du tableau. La méthode enter()
voit qu'il n'y a pas d'éléments li sur la page, mais il en faut 3 (un pour chaque élément de données dans l'ensemble de données). Les nouveaux éléments li
sont ajoutés à l'ul
et ont le texte New item
.
const dataset = [12, 31, 22, 17, 25, 18, 29, 14, 9];
d3.select("body").selectAll("h2")
.data(dataset)
.enter()
.append("h2")
.text((dataset) => dataset + " USD");
Ajouter un style en ligne aux éléments
D3 te permet d'ajouter des styles CSS en ligne sur des éléments dynamiques avec la méthode style()
.
La méthode style()
prend une paire clé-valeur séparée par des virgules comme argument. Voici un exemple pour définir la couleur du texte de la sélection sur bleu :
selection.style("couleur","bleu");
Modifier les styles en fonction des données
D3 concerne la visualisation et la présentation des données. Il est probable que tu souhaities modifier le style des éléments en fonction des données. tu peux utiliser une fonction de rappel dans la méthode style()
pour modifier le style de différents éléments.
Tu peux souhaiter colorer un point de données en bleu s'il a une valeur inférieure à 20, et en rouge dans le cas contraire. tu peux utiliser une fonction de rappel dans la méthode style()
et inclure la logique conditionnelle. La fonction de rappel utilise le paramètre d
pour représenter le point de données.
selection.style("color", (d) => {
});
La méthode style()
ne se limite pas à définir la couleur - elle peut également être utilisée avec d'autres propriétés CSS.
const dataset = [12, 31, 22, 17, 25, 18, 29, 14, 9];
d3.select("body").selectAll("h2")
.data(dataset)
.enter()
.append("h2")
.text((d) => (d + " USD"))
// Add your code below this line
.style("color", (d) => {
if(d > 20){
return "green";
}else{
return "red";
}
});
Ajouter des classes avec D3
L'utilisation de nombreux styles en ligne sur les éléments HTML devient difficile à gérer, même pour les petites applications. Il est plus facile d'ajouter une classe aux éléments et de styler cette classe une fois en utilisant les règles CSS. D3 a la méthode attr()
pour ajouter n'importe quel attribut HTML à un élément, y compris un nom de classe.
La méthode attr()
fonctionne de la même manière que style()
. Il prend des valeurs séparées par des virgules et peut utiliser une fonction de rappel. Voici un exemple pour ajouter une classe de conteneur à une sélection.
selection.attr("class", "container");
Notes que le paramètre de classe restera le même chaque fois que tu auras besoin d'ajouter une classe et que seul le paramètre de conteneur changera.
<style>
.bar {
width: 25px;
height: 100px;
display: inline-block;
background-color: blue;
}
</style>
<body>
<script>
const dataset = [12, 31, 22, 17, 25, 18, 29, 14, 9];
d3.select("body").selectAll("div")
.data(dataset)
.enter()
.append("div")
.attr("class", "bar");
</script>
</body>
Mettre à jour dynamiquement la hauteur d'un élément
Tu as vu comment afficher les données d'un tableau et comment ajouter des classes CSS. Tu peux combiner ces leçons pour créer un graphique à barres simple. Il y a deux étapes pour cela :
- Créer une div pour chaque point de données dans le tableau
- Donnes à chaque div une hauteur dynamique, en utilisant une fonction de rappel dans la méthode
style()
qui définit la hauteur égale à la valeur des données
Rappele, le format pour définir un style à l'aide d'une fonction de rappel :
selection.style("cssProperty", (d) => d)
<style>
.bar {
width: 25px;
height: 100px;
display: inline-block;
background-color: blue;
}
</style>
<body>
<script>
const dataset = [12, 31, 22, 17, 25, 18, 29, 14, 9];
d3.select("body").selectAll("div")
.data(dataset)
.enter()
.append("div")
.attr("class", "bar")
.style("height", (dataset) => dataset + "px")
</script>
</body>
Modifier la présentation d'un graphique à barres
Ci-dessus, tu as créé un graphique à barres, mais quelques modifications de formatage pourraient l'améliorer :
- Ajoutes un espace entre chaque barre pour les séparer visuellement, ce qui se fait en ajoutant une marge au CSS pour la classe de barre.
- Augmentes la hauteur des barres pour mieux montrer la différence de valeurs, ce qui se fait en multipliant la valeur par un nombre pour mettre à l'échelle la hauteur.
En savoir plus sur SVG dans D3
SVG signifie Scalable Vector Graphics.
Ici, "scalable" signifie que, si tu effectues un zoom avant ou arrière sur un objet, il n'apparaîtra pas pixelisé. Il évolue avec le système d'affichage, que ce soit sur un petit écran mobile ou un grand écran de télévision.
SVG est utilisé pour créer des formes géométriques courantes. Étant donné que D3 mappe les données dans une représentation visuelle, il utilise SVG pour créer les formes de la visualisation. Les formes SVG pour une page Web doivent aller dans une balise SVG HTML.
CSS peut être évolutif lorsque les styles utilisent des unités relatives (telles que vh, vw ou des pourcentages), mais l'utilisation de SVG est plus flexible pour créer des visualisations de données.
Afficher les formes avec SVG
Tu as créé un élément svg avec une largeur et une hauteur données, qui était visible car une couleur d'arrière-plan lui était appliquée dans la balise de style. Le code a fait de la place pour la largeur et la hauteur données.
L'étape suivante consiste à créer une forme à mettre dans la zone svg. Il existe un certain nombre de formes prises en charge dans SVG, telles que les rectangles et les cercles. Ils sont utilisés pour afficher des données. Par exemple, une forme SVG rectangulaire <rect>
pourrait créer une barre dans un graphique à barres.
Lorsque tu places une forme dans la zone svg, tu peux spécifier où elle va avec les coordonnées x et y. Le point d'origine de (0, 0) se trouve dans le coin supérieur gauche. Les valeurs positives pour x poussent la forme vers la droite et les valeurs positives pour y poussent la forme vers le bas à partir du point d'origine.
Modifier dynamiquement la hauteur de chaque barre
La hauteur de chaque barre peut être définie sur la valeur du point de données dans le tableau, de la même manière que la valeur x a été définie dynamiquement.
<body>
<script>
const dataset = [12, 31, 22, 17, 25, 18, 29, 14, 9];
const w = 500;
const h = 100;
const svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
svg.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.attr("x", (d, i) => i * 30)
.attr("y", 0)
.attr("width", 25)
.attr("height", (d, i) => {
return d * 3;
});
</script>
</body>
Inverser les éléments SVG
Tu as peut-être remarqué que le graphique à barres semblait être à l'envers ou inversé. Cela est dû à la façon dont SVG utilise les coordonnées (x, y).
En SVG, le point d'origine des coordonnées se trouve dans le coin supérieur gauche. Une coordonnée x de 0 place une forme sur le bord gauche de la zone SVG. Une coordonnée y de 0 place une forme sur le bord supérieur de la zone SVG. Des valeurs x plus élevées poussent le rectangle vers la droite. Des valeurs y plus élevées poussent le rectangle vers le bas.
Pour que les barres soient à l'endroit, tu dois modifier la façon dont la coordonnée y est calculée. Il doit tenir compte à la fois de la hauteur de la barre et de la hauteur totale de la zone SVG.
La hauteur de la zone SVG est de 100. Si tu as un point de données de 0 dans l'ensemble, tu aimerais que la barre commence en bas de la zone SVG (pas en haut). Pour ce faire, la coordonnée y a besoin d'une valeur de 100. Si la valeur du point de données était 1, tu commencerais avec une coordonnée y de 100 pour placer la barre en bas. Ensuite, tu dois tenir compte de la hauteur de la barre de 1, donc la coordonnée finale y serait 99.
La coordonnée y qui est y = heightOfSVG - heightOfBar
placerait les barres à l'endroit.
<body>
<script>
const dataset = [12, 31, 22, 17, 25, 18, 29, 14, 9];
const w = 500;
const h = 100;
const svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
svg.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.attr("x", (d, i) => i * 30)
.attr("y", (d, i) => {
return h - 3 * d
})
.attr("width", 25)
.attr("height", (d, i) => 3 * d);
</script>
</body>
Changer la couleur d'un élément SVG
Les barres sont dans la bonne position, mais elles sont toutes de la même couleur noire. SVG a un moyen de changer la couleur des barres.
En SVG, une forme rectiligne est colorée avec l'attribut fill. Il prend en charge les codes hexadécimaux, les noms de couleurs et les valeurs RVB, ainsi que des options plus complexes telles que les dégradés et la transparence.
<body>
<script>
const dataset = [12, 31, 22, 17, 25, 18, 29, 14, 9];
const w = 500;
const h = 100;
const svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
svg.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.attr("x", (d, i) => i * 30)
.attr("y", (d, i) => h - 3 * d)
.attr("width", 25)
.attr("height", (d, i) => 3 * d)
.attr("fill", "navy");
</script>
</body>
Ajouter des étiquettes aux éléments D3
D3 vous permet d'étiqueter un élément de graphique, comme une barre, à l'aide de l'élément de texte SVG.
Comme l'élément rect, un élément de texte doit avoir des attributs x et y, pour le placer sur le canevas SVG. Il doit également accéder aux données pour afficher ces valeurs.
D3 vous donne un haut niveau de contrôle sur la façon dont vous étiquetez vos barres.
<body>
<script>
const dataset = [12, 31, 22, 17, 25, 18, 29, 14, 9];
const w = 500;
const h = 100;
const svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
svg.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.attr("x", (d, i) => i * 30)
.attr("y", (d, i) => h - 3 * d)
.attr("width", 25)
.attr("height", (d, i) => 3 * d)
.attr("fill", "navy");
svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.attr("x", (d, i) => i * 30)
.attr("y", (d, i) => h - 3 * d - 3)
.text((d, i) => d);
</script>
<body>
Étiquettes de style D3
Les méthodes D3 peuvent ajouter des styles aux étiquettes des barres. L'attribut fill définit la couleur du texte pour un nœud de texte. La méthode style()
définit des règles CSS pour d'autres styles, tels que font-family ou font-size.
<body>
<script>
const dataset = [12, 31, 22, 17, 25, 18, 29, 14, 9];
const w = 500;
const h = 100;
const svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
svg.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.attr("x", (d, i) => i * 30)
.attr("y", (d, i) => h - 3 * d)
.attr("width", 25)
.attr("height", (d, i) => d * 3)
.attr("fill", "navy");
svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text((d) => d)
.attr("x", (d, i) => i * 30)
.attr("y", (d, i) => h - (3 * d) - 3)
.style("font-size", (dataset) => 25 + "px")
.style("fill", (dataset) => "red");
</script>
</body>
Ajouter un effet de survol
Il est possible d'ajouter des effets qui mettent en évidence une barre lorsque l'utilisateur la survole avec la souris. Jusqu'à présent, le style des rectangles est appliqué avec les méthodes intégrées D3 et SVG, mais vous pouvez également utiliser CSS.
Vous définissez la classe CSS sur les éléments SVG avec la méthode attr()
. Ensuite, la pseudo-classe :hover
de ta nouvelle classe contient les règles de style pour tous les effets de survol.
<style>
.bar:hover {
fill: brown;
}
</style>
<body>
<script>
const dataset = [12, 31, 22, 17, 25, 18, 29, 14, 9];
const w = 500;
const h = 100;
const svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
svg.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.attr("x", (d, i) => i * 30)
.attr("y", (d, i) => h - 3 * d)
.attr("width", 25)
.attr("height", (d, i) => 3 * d)
.attr("fill", "navy")
.attr("class", "bar");
svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text((d) => d)
.attr("x", (d, i) => i * 30)
.attr("y", (d, i) => h - (3 * d) - 3);
</script>
</body>
Créer un nuage de points avec des cercles SVG
Un nuage de points est un autre type de visualisation. Il utilise généralement des cercles pour cartographier les points de données, qui ont chacun deux valeurs. Ces valeurs sont liées aux axes x et y et sont utilisées pour positionner le cercle dans la visualisation.
SVG a une étiquette de cercle pour créer la forme du cercle. Cela fonctionne un peu comme les éléments rect que tu as utilisé pour le graphique à barres.
<body>
<script>
const dataset = [
[ 34, 78 ],
[ 109, 280 ],
[ 310, 120 ],
[ 79, 411 ],
[ 420, 220 ],
[ 233, 145 ],
[ 333, 96 ],
[ 222, 333 ],
[ 78, 320 ],
[ 21, 123 ]
];
const w = 500;
const h = 500;
const svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
svg.selectAll("circle")
.data(dataset)
.enter()
.append("circle")
.attr('r', 5)
.attr('cx',(d) => d[0])
.attr("cy", (d) => h - d[1])
</script>
</body>
Ajouter des étiquettes aux cercles de nuage de points
Tu peux ajouter du texte pour créer des étiquettes pour les points d'un nuage de points.
L'objectif est d'afficher les valeurs séparées par des virgules pour les premier (x) et deuxième (y) champs de chaque élément de l'ensemble de données.
Les nœuds de texte ont besoin des attributs x et y pour le positionner sur le canevas SVG.
<body>
<script>
const dataset = [
[ 34, 78 ],
[ 109, 280 ],
[ 310, 120 ],
[ 79, 411 ],
[ 420, 220 ],
[ 233, 145 ],
[ 333, 96 ],
[ 222, 333 ],
[ 78, 320 ],
[ 21, 123 ]
];
const w = 500;
const h = 500;
const svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
svg.selectAll("circle")
.data(dataset)
.enter()
.append("circle")
.attr("cx", (d, i) => d[0])
.attr("cy", (d, i) => h - d[1])
.attr("r", 5);
svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.attr("x", (d) => d[0] +5)
.attr("y", (d) => h - d[1])
.text((d) => d[0]+ ", " + d[1]);
</script>
</body>
Les échelles
Créer une échelle linéaire
Les graphiques à barres et à nuage de points ont tous deux tracé des données directement sur le canevas SVG. Cependant, si la hauteur d'une barre ou de l'un des points de données était supérieure aux valeurs de hauteur ou de largeur SVG, elle sortirait de la zone SVG.
Dans D3, il y a des échelles pour aider à tracer les données. les échelles sont des fonctions qui indiquent au programme comment mapper un ensemble de points de données brutes sur les pixels du canevas SVG.
Par exemple, supposons que tu as un canevas SVG de 100 x 500 et que tu souhaites tracer le produit intérieur brut (PIB) pour un certain nombre de pays. L'ensemble des nombres serait de l'ordre du milliard ou du billion de dollars. Tu fournis à D3 un type d'échelle pour lui indiquer comment placer les grandes valeurs du PIB dans cette zone de 100x500.
Il est peu probable que tu traces des données brutes telles quelles. Avant de le tracer, tu définisses l'échelle pour l'ensemble de ton ensemble de données, de sorte que les valeurs x et y correspondent à la largeur et à la hauteur de ta toile.
D3 a plusieurs types d'échelle. Pour une échelle linéaire (généralement utilisée avec des données quantitatives), il existe la méthode D3 scaleLinear().
const scale = d3.scaleLinear()
Par défaut, une échelle utilise la relation d'identité. La valeur de l'entrée est la même que la valeur de la sortie.
Définir un domaine et une plage sur une échelle
Par défaut, les échelles utilisent la relation d'identité. Cela signifie que la valeur d'entrée correspond à la valeur de sortie. Cependant, les échelles peuvent être beaucoup plus flexibles et intéressantes.
Supposons qu'un ensemble de données ait des valeurs allant de 50 à 480. Il s'agit des informations d'entrée pour une échelle, également appelée domaine.
Tu souhaites mapper ces points le long de l'axe x sur le canevas SVG, entre 10 et 500 unités. Il s'agit des informations de sortie, également appelées plage.
Les méthodes domain()
et range()
définissent ces valeurs pour l'échelle. Les deux méthodes prennent un tableau d'au moins deux éléments comme argument. Voici un exemple :
scale.domain([50, 480]);
scale.range([10, 500]);
scale(50)
scale(480)
scale(325)
scale(750)
d3.scaleLinear()
Dans l'ordre, les valeurs suivantes s'afficheraient dans la console : 10, 500, 323,37 et 807,67.
Notes que l'échelle utilise la relation linéaire entre les valeurs de domaine et de plage pour déterminer ce que la sortie devrait être pour un nombre donné. La valeur minimale dans le domaine (50) correspond à la valeur minimale (10) dans la plage.
Utilises les fonctions d3.max et d3.min pour rechercher des valeurs minimales et maximales dans un ensemble de données
Les méthodes D3 domain()
et range()
définissent ces informations pour ton échelle en fonction des données. Il existe plusieurs méthodes pour rendre cela plus facile.
Souvent, lorsque tu définis le domaine, tu souhaites utiliser les valeurs minimales et maximales dans l'ensemble de données. Essayes de trouver ces valeurs manuellement, en particulier dans un grand ensemble de données, peut provoquer des erreurs.
D3 a deux méthodes - min()
et max()
pour renvoyer ces informations. Voici un exemple :
const exampleData = [34, 234, 73, 90, 6, 52];
d3.min(exampleData)
d3.max(exampleData)
Un jeu de données peut avoir des tableaux imbriqués, comme les paires de coordonnées [x, y] qui étaient dans l'exemple de nuage de points. Dans ce cas, tu dois indiquer à D3 comment calculer le maximum et le minimum. Heureusement, les deux méthodes min()
et max()
acceptent une fonction callback. Dans cet exemple, l'argument d
de la fonction callback concerne le tableau interne actuel. Le callback doit renvoyer l'élément du tableau interne (la valeur x ou y) sur lequel tu souhaites calculer le maximum ou le minimum. Voici un exemple pour savoir comment trouver les valeurs min et max avec un tableau de tableaux.
const locationData = [[1, 7],[6, 3],[8, 3]];
const minX = d3.min(locationData, (d) => d[0]);
minX aurait la valeur 1.
Utiliser des échelles dynamiques
Les méthodes D3 min()
et max()
sont utiles pour aider à définir l'échelle.
Étant donné un ensemble de données complexe, une priorité est de définir l'échelle de sorte que la visualisation s'adapte à la largeur et à la hauteur du conteneur SVG. Tu veux que toutes les données soient tracées à l'intérieur du canevas SVG afin qu'elles soient visibles sur la page Web.
L'exemple ci-dessous définit l'échelle de l'axe des X pour les données du nuage de points. La méthode domain()
transmet des informations sur les valeurs de données brutes du tracé. La méthode range()
lui donne des informations sur l'espace réel sur la page Web pour la visualisation.
Dans l'exemple, le domaine va de 0 au maximum dans l'ensemble. Il utilise la méthode max()
avec une fonction callback basée sur les valeurs x dans les tableaux. La plage utilise la largeur (w) du canevas SVG, mais elle inclut également un peu de remplissage. Cela place un espace entre les points du nuage de points et le bord du canevas SVG.
const dataset = [
[ 34, 78 ],
[ 109, 280 ],
[ 310, 120 ],
[ 79, 411 ],
[ 420, 220 ],
[ 233, 145 ],
[ 333, 96 ],
[ 222, 333 ],
[ 78, 320 ],
[ 21, 123 ]
];
const w = 500;
const h = 500;
const padding = 30;
const xScale = d3.scaleLinear()
.domain([0, d3.max(dataset, (d) => d[0])])
.range([padding, w - padding]);
Utiliser une échelle prédéfinie pour placer des éléments
Une fois les échelles configurées, il est temps de cartographier à nouveau le nuage de points. Les échelles sont comme des fonctions de traitement qui transforment les données brutes x
et y
en valeurs qui s'adaptent et s'affichent correctement sur le canevas SVG. Ils conservent les données dans la zone de traçage de l'écran.
Tu définis les valeurs d'attribut de coordonnées pour une forme SVG avec la fonction de mise à l'échelle. Cela inclut les attributs x
et y
pour les éléments rect
ou text
, ou cx
et cy
pour les cercles
.
shape
.attr("x", (d) => xScale(d[0]))
Les échelles définissent les attributs de coordonnées de forme pour placer les points de données sur le canevas SVG. Tu n'as pas besoin d'appliquer des échelles lorsque tu affiches la valeur réelle des données, par exemple, dans la méthode text()
pour une info-bulle ou une étiquette.
<body>
<script>
const dataset = [
[ 34, 78 ],
[ 109, 280 ],
[ 310, 120 ],
[ 79, 411 ],
[ 420, 220 ],
[ 233, 145 ],
[ 333, 96 ],
[ 222, 333 ],
[ 78, 320 ],
[ 21, 123 ]
];
const w = 500;
const h = 500;
const padding = 60;
const xScale = d3.scaleLinear()
.domain([0, d3.max(dataset, (d) => d[0])])
.range([padding, w - padding]);
const yScale = d3.scaleLinear()
.domain([0, d3.max(dataset, (d) => d[1])])
.range([h - padding, padding]);
const svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
svg.selectAll("circle")
.data(dataset)
.enter()
.append("circle")
.attr("cx", (d) => xScale(d[0]))
.attr("cy", (d) => yScale(d[1]))
.attr('r', 5);
svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text((d) => (d[0] + ", "
+ d[1]))
.attr('r', 5)
.attr("x", (d) => xScale(d[0] + 10))
.attr("y", (d) => yScale(d[1]));
</script>
</body>
Ajouter des axes à une visualisation
Une autre façon d'améliorer le nuage de points consiste à ajouter un axe x
et un axe y
.
D3 a deux méthodes, axisLeft()
et axisBottom()
, pour restituer l'axe des y
et l'axe des x
, respectivement. Voici un exemple pour créer l'axe x
basé sur le xScale
dans les défis précédents.
const xAxis = d3.axisBottom(xScale);
L'étape suivante consiste à rendre l'axe sur le canevas SVG. Pour ce faire, vous pouvez utiliser un composant SVG général, l'élément g
. Le g
signifie groupe comme tu l'as vu plus haut. Contrairement au rect
, au circle
et au text
, un axe n'est qu'une ligne droite lorsqu'il est rendu. Parce que c'est une forme simple, l'utilisation de g
fonctionne. La dernière étape consiste à appliquer un attribut de transformation pour positionner l'axe sur le canevas SVG au bon endroit. Sinon, la ligne serait rendue le long de la bordure du canevas SVG et ne serait pas visible. SVG prend en charge différents types de transforms
, mais le positionnement d'un axe nécessite un translate
. Lorsqu'il est appliqué à l'élément g
, il déplace tout le groupe de haut en bas.
const xAxis = d3.axisBottom(xScale);
svg.append("g")
.attr("transform", "translate(0, " + (h - padding) + ")")
.call(xAxis);
Le code ci-dessus place l'axe des x
en bas du canevas SVG. Ensuite, il est passé en argument à la méthode call()
. L'axe des y
fonctionne de la même manière, sauf que l'argument translate
est sous la forme (x, 0)
. Parce que translate
est une chaîne dans la méthode attr()
ci-dessus, tu peux utiliser la concaténation pour inclure des valeurs de variable pour ses arguments.
<body>
<script>
const dataset = [
[ 34, 78 ],
[ 109, 280 ],
[ 310, 120 ],
[ 79, 411 ],
[ 420, 220 ],
[ 233, 145 ],
[ 333, 96 ],
[ 222, 333 ],
[ 78, 320 ],
[ 21, 123 ]
];
const w = 500;
const h = 500;
const padding = 60;
const xScale = d3.scaleLinear()
.domain([0, d3.max(dataset, (d) => d[0])])
.range([padding, w - padding]);
const yScale = d3.scaleLinear()
.domain([0, d3.max(dataset, (d) => d[1])])
.range([h - padding, padding]);
const svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
svg.selectAll("circle")
.data(dataset)
.enter()
.append("circle")
.attr("cx", (d) => xScale(d[0]))
.attr("cy",(d) => yScale(d[1]))
.attr("r", (d) => 5);
svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text((d) => (d[0] + "," + d[1]))
.attr("x", (d) => xScale(d[0] + 10))
.attr("y", (d) => yScale(d[1]))
const xAxis = d3.axisBottom(xScale);
// Add your code below this line
const yAxis = d3.axisLeft(yScale);
// Add your code above this line
svg.append("g")
.attr("transform", "translate(0," + (h - padding) + ")")
.call(xAxis);
// Add your code below this line
svg.append("g")
.attr("transform", "translate(" + padding + ",0)")
.call(yAxis);
</script>
</body>