D3JS - Map

Un premier essai tout simple

Dernière mise à jour le 16/08/2018

Avertissement sur la qualité

Info: Cette carte a été optimisé pour l'usage qui en est fait dans ce tutoriel, merci de consulter le tutoriel Map - Optimisation pour plus d'information.

Construction de la carte

Cette carte représente les départements français. Elle est construite à partir d'un fichier geoJSON. Ce fichier, en plus de contenir les polygones de chaque département, fournit également le nom du département ainsi que sa région que nous utilisons pour présenter un tooltip.

Nous commençons par définir les dimensions de notre SVG.

const width = 550, height = 550;

Ensuite, nous créons un objet path pour manipuler nos données geoJSON.

const path = d3.geoPath();

La partie la plus délicate de ce tutoriel, la définition de la projection utilisée. Ici, nous choisissons une projection assez habituelle pour la cartographie (une liste des projections est disponible sur le site de D3JS). Nous centrons cette projection sur la France (latitude & longitude) et l'agrandissons pour finalement la centrer.

const projection = d3.geoConicConformal()
	.center([2.454071, 46.279229])
	.scale(2600)
	.translate([width / 2, height / 2]);

La projection est ensuite assignée au path, le SVG est ajouté sur le DOM avec les dimensions pré-définies (l'id ne sert que pour le CSS) et un groupe est ajouté au SVG pour contenir tous les path. Attention, votre DOM doit déjà posséder un DIV dont l'ID est map, le code d3.select('#map') permet de récupérer ce DIV.

path.projection(projection);

const svg = d3.select('#map').append("svg")
	.attr("id", "svg")
	.attr("width", width)
	.attr("height", height);

const deps = svg.append("g");

Le code suivant (et il n'y en a pas d'autres pour afficher la carte) charge le fichier geoJSON et pour chaque entrée de ce fichier ajoute un noeud path associé à un CSS particulier. Il est finalement rattaché au path que nous avions précédement déclaré.

d3.json('d3js/map-firststep/departments.json').then(function(geojson) {
	deps.selectAll("path")
		.data(geojson.features)
		.enter()
		.append("path")
		.attr("d", path);
});

Le code qui précède permet d'afficher la carte sans avoir rien à écrire de plus. Le plus incroyable est que nous n'avons même pas eu à nous occuper des données geoJSON, auncune manipulation n'a été nécessaire. C'est l'intérêt d'utiliser un format qui est naturellement reconnu par D3JS. Le fichier utilisé peut-être récupéré via firebug dans l'onglet réseau ou directement sur ce lien : departments.json.

Problème de chargement du fichier JSON

Vous êtes nombreux à rencontrer des difficultés pour charger votre fichier JSON suivant votre contexte. Dans l'exemple au-dessus nous utilisons un serveur HTTP. Il peut s'agit d'un serveur Apache, WAMP, uWAMP, EasyPHP ou tout autre serveur. Pour indiquer le bon chemin il faut tenir compte du chemin relatif de votre fichier. Par exemple notre site est situé dans un dossier www/DataVis3. Le chemin que nous précisons à la fonction d3.json correspond au chemin à partir de ce dossier : d3js/map-firststep/departments.json.

Chemin vers notre dossier contenant le JSON

Si cela ne fonctionne pas pensez à regarder dans la console les erreurs (c'est à cela que sert la ligne 2). Vous devriez avoir une première erreur 404 :

Erreur 404, failed to load ressource

Mais également une seconde erreur plus explicite cette fois :

Erreur explicite de mauvais chemin

Le chemin mentionné dans le champ responseURL n'est pas le bon, il manque le dossier d3js avant map-firststep.

Aujourd'hui il n'est plus possible de charger directement votre fichier JSON sans passer par un serveur web, c'est l'erreur que rencontre glopez3326 avec la mention CORS Request. C'est pour des raisons de sécurité, le navigateur vous protège des scripts qui voudraient lire sur votre disque dur. Si vous ne voulez pas utiliser de serveur web il faut copier le contenu du fichier geoJSON et le coller directement dans une variable javascript, voir le code source de cet exemple.

Ajout du tooltip

L'exemple de cette page possède un tooltip que nous allons maintenant étudier. Commençons par ajouter un DIV à notre DOM qui contiendra ce tooltip.

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

Ensuite, nous reprenons la méthode qui parse le fichier geoJSON pour ajouter le comportement du tooltip.

d3.json('d3js/map-firststep/departments.json').then(function(geojson) {			
	deps.selectAll("path")
		.data(geojson.features)
		.enter()
		.append("path")
		.attr('class', 'department')
		.attr("d", path)
		.on("mouseover", function(d) {
			div.transition()        
				.duration(200)
				.style("opacity", .9);      
			div.html("Département : " + d.properties.NOM_DEPT + "<br/>"
				  +  "Région : " + d.properties.NOM_REGION)  
				.style("left", (d3.event.pageX + 30) + "px")     
				.style("top", (d3.event.pageY - 30) + "px")
		})
		.on("mouseout", function(d) {
			div.style("opacity", 0);
			div.html("")
				.style("left", "-500px")
				.style("top", "-500px");
		});
});

Ce code ajoute simplement les méthodes mouseover et mouseout. Ces deux méthodes s'appliquent sur chaque path que contient le SVG.
Le mouseover déclenche une transition sur 200ms visant à faire apparaître le rectangle décrivant le département puis définit le contenu html de ce rectangle (éditez le fichier geoJSON pour voir les champs qui sont accessible). Ce rectangle est légèrement décalé pour ne pas gêner la souris.
Le mouseout fait disparaitre ce rectangle. Il est également vidé de son contenu et déplacé en dehors de la zone visible afin de ne pas gêner la sélection d'un autre département (car même avec une opacité à 0 il reste au dessus des départements).

Le CSS utilisé pour le tooltip est un peu travaillé pour convenir à la situation.

div.tooltip {
	position: absolute;
	text-align: center;
	color: black;
	width: 275px;
	height: 37px;
	padding: 2px;
	font: 12px sans-serif;
	background: grey;
	border: 0px;
	border-radius: 8px;
	pointer-events: none;
}

Autres fichiers geoJSON pour la France

Suite à la remarque d'une internaute, nous rajoutons un lien vers le github suivant : https://github.com/gregoiredavid/france-geojson. Il permet de récupérer au format geoJSON les communes, départements et régions au niveau de la France entière ainsi que les communes et départements spécifiques à chaque région ou département.

A suivre : Carte choroplèthe Voir le tutoriel

comments powered by Disqus