D3JS - Histogramme (Bar Chart)

Pays les plus peuplés au monde

Dernière mise à jour le 13/06/2018

La préparation

Nous commençons par établir les dimensions et les marges de notre graphique.

const margin = {top: 20, right: 20, bottom: 90, left: 120},
	width = 800 - margin.left - margin.right,
	height = 400 - margin.top - margin.bottom;

Les marges à gauche et en bas ont été augmenté pour l'affichage de la population et du pays.
Ensuite, nous définissons la fonction permettant le remplissage de l'axe des abcisses et celui des ordonnées.

const x = d3.scaleBand()
	.range([0, width])
	.padding(0.1);

const y = d3.scaleLinear()
	.range([height, 0]);

Le détails de ces méthodes peut être consulté sur cette page : d3-scale. Pour l'axe X, nous utilisons une échelle ordinale qui permet de représenter une liste de données ordonnées (ici le nom de nos pays). Nous précisons que cet axe va s'étendre sur toute la largeur de notre graphique grâce à la méthode range. Nous définissons ensuite l'espacement entre nos barres via la méthode padding. Pour l'axe Y, nous utilisons une échelle linéaire sur un range égal à la hauteur de notre graphique.

Il nous reste maintenant à créer notre SVG sur le noeud DOM avec l'ID chart. Nous précisons la taille de ce SVG ainsi qu'une fonction de transformation sur le noeud G permettant de tenir compte des marges et de positionner correctement l'ensemble.

const svg = d3.select("#chart").append("svg")
	.attr("id", "svg")
	.attr("width", width + margin.left + margin.right)
	.attr("height", height + margin.top + margin.bottom)
	.append("g")
	.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

Il nous faut également ajouter un DIV pour notre tooltip.

const div = d3.select("body").append("div")
	.attr("class", "tooltip")         
	.style("opacity", 0);

N'oubliez pas de regarder le code source pour récupérer le CSS associé à ce tooltip et au graphique.

Le traitement des données

Contrairement à l'introduction précédente dans laquelle nous avons utilisé un objet JSON, nous utiliserons cette fois-ci un fichier data.tsv (Tab Separated Values, il peut-être récupéré via firebug dans l'onglet réseau ou directement sur ce lien : data.tsv)

// On demande à D3JS de charger notre fichier
d3.tsv("d3js/barchart/data.tsv", function(error, data) {
	// Conversion des caractères en nombres
	data.forEach(function(d) {
		d.population = +d.population;
	});

	// Mise en relation du scale avec les données de notre fichier
	// Pour l'axe X, c'est la liste des pays
	// Pour l'axe Y, c'est le max des populations
	x.domain(data.map(function(d) { return d.country; }));
	y.domain([0, d3.max(data, function(d) { return d.population; })]);
	
	// Ajout de l'axe X au SVG
	// Déplacement de l'axe horizontal et du futur texte (via la fonction translate) au bas du SVG
	// Selection des noeuds text, positionnement puis rotation
	svg.append("g")
		.attr("transform", "translate(0," + height + ")")
		.call(d3.axisBottom(x).tickSize(0))
		.selectAll("text")	
			.style("text-anchor", "end")
			.attr("dx", "-.8em")
			.attr("dy", ".15em")
			.attr("transform", "rotate(-65)");
	
	// Ajout de l'axe Y au SVG avec 6 éléments de légende en utilisant la fonction ticks (sinon D3JS en place autant qu'il peut).
	svg.append("g")
		.call(d3.axisLeft(y).ticks(6));

	// Ajout des bars en utilisant les données de notre fichier data.tsv
	// La largeur de la barre est déterminée par la fonction x
	// La hauteur par la fonction y en tenant compte de la population
	// La gestion des events de la souris pour le popup
	svg.selectAll(".bar")
		.data(data)
	.enter().append("rect")
		.attr("class", "bar")
		.attr("x", function(d) { return x(d.country); })
		.attr("width", x.bandwidth())
		.attr("y", function(d) { return y(d.population); })
		.attr("height", function(d) { return height - y(d.population); })					
		.on("mouseover", function(d) {
			div.transition()        
				.duration(200)      
				.style("opacity", .9);
			div.html("Population : " + d.population)
				.style("left", (d3.event.pageX + 10) + "px")     
				.style("top", (d3.event.pageY - 50) + "px");
		})
		.on("mouseout", function(d) {
			div.transition()
				.duration(500)
				.style("opacity", 0);
		});
});

A suivre : Ligne (Linear Chart) Voir le tutoriel

comments powered by Disqus