D3JS - Premiers Pas

Les formes de base, le style et le chargement de données
d3js7.x
Sources :

Les formes de base

Dans ce premier tutoriel, nous allons prendre en main la librairie D3JS au travers de quelques exemples simples. Voici la trame de base d'un fichier HTML permettant d'utiliser la librairie D3JS dans sa version 7.

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr">
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
		<script src="https://d3js.org/d3.v7.min.js"></script>
		<style type="text/css">
			#svg1 {
				height: 75px;
			}
		</style>
	</head>
 
	<body>
		<div id="svg1"></div>
	</body>
</html>
<script type="text/javascript">
	// Notre code viendra ici
</script>

D3JS est particulièrement fort pour manipuler du SVG. Ainsi il est très facile de créer un rectangle. On commence par sélectionner le DIV dans lequel on va créer notre SVG en utilisant son ID :

var svg = d3.select("#svg1").append("svg");

Il faut bien sûr que cet ID soit déclaré dans la page. Ensuite, nous ajoutons l'objet rect à ce SVG. Nous le positionnons de manière relative par les attributs x et y exprimés en pixels. Une des propriétée de D3JS est que chaque fonction retourne l'objet qui l'a exécuté, ce qui permet d'enchainer les appels de méthodes (method chaining pattern en anglais). On en profite pour définir la largeur et la hauteur de notre rectangle.

svg.append("rect")
	.attr("x",20)
	.attr("y",20)
	.attr("width",200)
	.attr("height",50);

Ce qui nous donne ce superbe rectangle noir :

Pourquoi ne pas s'amuser un peu en utilisant une boucle pour créer plusieurs rectangles de dimensions variables. Nous allons pour cela utiliser la balise G pour grouper nos rectangle

svg = d3.select("#svg2").append("svg");
var group = svg.append("g");
for (var i = 0; i < 3; ++i) {
    group.append("rect")
        .attr("x",20 + 100 * i)
        .attr("y",20)
        .attr("width",10 + 10 * i)
        .attr("height",50)
        .style("fill", "lightgrey")
        .style("stroke","black")
        .style("stroke-width","3");
}

Nous voyons aussi qu'il est possible de modifier le style par défaut de la même façon que nous avons créé notre rectangle.
Notons également que nous aurions pu directement écrire dans notre DOM le code HTML suivant pour obtenir le premier rectangle :

<svg width="200" height="50">
	<rect x="20" y="20" width="200" height="50" fill="black" />
</svg>

Il existe par ailleurs d'autres formes basiques :

svg.append("circle")
	.attr("cx",150)
	.attr("cy",50)
	.attr("r",30);
svg.append("ellipse")
	.attr("cx",150)
	.attr("cy",50)
	.attr("rx",30)
	.attr("ry",20);
svg.append("line")
	.attr("x1",150)
	.attr("y1",50)
	.attr("x2",180)
	.attr("y2",100)
	.style("stroke","black")
	.style("stroke-width","5");
svg.append("polyline")
	.attr("points","150,20 200,20 250,50 200,70 130,40")
	.style("fill", "none")
	.style("stroke","black")
	.style("stroke-width","2");
svg.append("polyline")
	.attr("points","150,20 200,20 250,50 200,70 200,30 150,30");

Nous venons de parcourir rapidement les formes de base que D3JS permet de manipuler.
Nous verrons dans les chapitres suivants que cette librairie permet une manipulation beaucoup plus avancée des SVG.

Les données

Toute la puissance de D3JS réside dans la facilité avec laquelle il permet la manipulation de données au format JSON. Prenons par exemple l'ensemble de données suivant :

const data = [
	{"position":1, "country":"Chine", "population":1355045511},
	{"position":2, "country":"Inde", "population":1210193422},
	{"position":3, "country":"États-Unis", "population":315664478},
	{"position":4, "country":"Indonésie", "population":237641326},
	{"position":5, "country":"Brésil", "population":193946886},
	{"position":6, "country":"Pakistan", "population":182614855},	
	{"position":7, "country":"Nigeria", "population":174507539},
	{"position":8, "country":"Bangladesh", "population":152518015},	
	{"position":9, "country":"Russie", "population":143056383},
	{"position":10, "country":"Japon", "population":127650000}
];

Il s'agit de la liste des 10 pays les plus peuplés au monde.
Après avoir sélectionné le noeud DOM sur lequel nous souhaitons ajouter notre SVG, nous ajoutons un groupe qui contiendra tous les rectangles.

var group = svg.append("g");

Le code est ici un peu délicat à saisir au premier abord car la méthode selectAll() ne peut rien sélectionner directement puisqu'il n'existe aucun noeud DOM dans notre noeud G. C'est la combinaison de la méthode data() (2) qui va lire notre tableau et de la méthode enter() (3) qui va être exécutée pour chaque entrée du tableau qui va permettre l'ajout d'un rectangle au niveau du noeud G (4). Chaque barre est placé tous les 30px (5) et d'une largeur de 20px (7). A la vertical, les barres commencent toutes au même endroit (6) et font une hauteur qui correspond à un ratio de la population des données (8).

group.selectAll(".node")
	.data(data) // 2
	.enter() // 3
		.append("rect") // 4
		.attr("x", d => d.position * 30) // 5
		.attr("y", 0) //6
		.attr("width", 20) // 7
		.attr("height", d => d.population / 10000000); // 8

Le résultat obtenu n'est pas extraordinaire mais permet de voir comment D3JS associe la manipulation d'une liste de noeuds auxquels sont rattachés des données. Il nous a suffit de déclarer des fonctions pour accéder aux données de notre JSON.

Dans un chapitre ultérieur nous verrons comment utiliser ces mêmes données pour créer un graphique de type Bar Chart un peu plus élégant que celui-ci.

COMMENTAIRES

bastien louvel


Salut très bon tuto et visuel sympa, mais tu as oublié de mettre :
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
à la fin de ton code dans le tuto pour que le mouse event s'affiche

ericfrigot


Bonjour, je reviens un peu tardivement vers toi mais je pense que ce n'est pas le bon tutoriel. Ici tu es sur le tutoriel premier pas ou alors je me suis trompé dans la clé disqus. Peux-tu me dire à quel tutoriel tu fais référence ? Merci, Eric

bastien louvel


oui, c'est dans le tutoriel de l'histo des populations de pays, tu ne définie pas la div du tooltip dans ton tutoriel, mais tu la définie bien dans ton code source après le mouse out

ericfrigot


Ok, je comprends j'avais laissé l'identifiant du tutoriel Premier Pas, j'ai bien ajouté la partie manquante. Merci encore !

Djibrina Barry


Simplement excellent! je suis un "beginner" sur le theme D3, et j'ai essayer d'utiliser votre code avec un fichier Json que j'appelle d'un URL. Cependant je n'arrive pas a voir un resultat concret. Merci de me donner un coup de main.

Voici mon objct json que je obtiens de mon url:

[{"frequenzbereich":1,"amplitude_max":20000},{"frequenzbereich":2,"amplitude_max":20000},{"frequenzbereich":3,"amplitude_max":20000}, {"frequenzbereich":4,"amplitude_max":20000},{"frequenzbereich":5,"amplitude_max":20000}]

frequenzbereich correspond a country
amplitude_max correspond a population max

Mon index.html se differencie du votre juste par ces lignes:
<html>
....
.....
....
....

<body>
<script>

var url= "http://10.0.1.164/d3json/getJsonFromTable.php";
d3.json(url,function(data){.......

}
</script>
</body>
</html>

ericfrigot


Bonjour, j'en déduis que vous n'avez pas modifié le contenu de la fonction d3.json (entre les accolades). Si c'est bien le cas c'est logique que cela ne fonctionne pas. Vous devez remplacer partout d.country par d.frequenzbereich et d.population par d.amplitude_max. Afin de vérifier qu'il ne manque rien. Je ne serais trop vous conseiller d'utiliser le debugger de votre navigateur, sans lui impossible de vérifier que vous n'avez pas fait de fautes de frappes. Pour Firefox, il y a Firebug (un module à installer), pour Chrome et Internet Explorer c'est intégré au navigateur. Par ailleurs, si vous voulez me partager tout votre code utilisez plutôt un site comme http://pastebin.com/ qui permet de partager facilement du texte sur Internet.

Djibrina Barry


Encore une question:
Je voudrais bien en bas de chaque bar ecrire un text: Frequenzbereich 1, frequenzbereich 2........ comme chine .....
je ne vois que 1 2 3 4 5.

Voici le code que j'ai essayer de faire:

var text = svg.selectAll("text")

.data(data)
.enter()
.append("text")
.attr("fill","red")

.attr("x", function(d,i){return i*height+25;})
.text(function(d){return "frequenzbereich :" + d.frequenzbereich;});

Djibrina Barry


Je viens de m'appercevoir de mes erreurs.
1.J'avais d3.tsv(....) au lieu de d3.json(...)
2.d3.json(url="http://10.0.1.164/d3json/getJsonFromTable.php",type,function(error, data): json ne supporte pas le type car il ne "parse" pas les donnees comme en tsv. Les donnees sont deja parser.
Grand merci.

Djibrina Barry


Bonjour, mon ordinateur etait en panne. J'ai verifie la synthax et elle est bien appropriee. Je vous partage mon fichier html via pastebin.Merci encore.

user account on pastebin: barry-djibrina

url: http://pastebin.com/j8zVH6Wc

Olivier C


Merci pour la découverte de ce fabuleux script (D3JS), les exemples de démonstration sont vraiment impressionnants.

ericfrigot


Avec plaisir, n'hésitez pas à repasser de temps en temps pour voir les nouveautés et surtout posez des questions si vous êtes perdu sur un tutoriel.