par @ThomasG77, WebGeoDataVore
Consultant SIG, OpenData et visualisation de données, proposant conseil, formation et développement.
Auteur d'un livre sur OpenLayers 3 (en anglais), spécialiste JavaScript et Python.
Contact: thomas.gratier(at)webgeodatavore.com
1) D3: possibilités de représentations et écosystème
2) Contextualisation: pourquoi D3? La visualisation de données
3) Quel(s) intérêt(s) pour la cartographie ?
4) Rappels pratiques
5) Travaux pratiques avec mise en ligne de votre démo
Pour faire une première visualisation en ligne
En passant depuis un autre language de programmation
Deux phénomènes liés à un changement de vision du rapport au citoyen
Quelques raccourcis explicatifs sur ces sujets
Plusieurs visions possibles:
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>Titre de la page</title>
<style></style>
<script></script>
</head>
<body>
<!-- Le reste du contenu -->
</body>
</html>
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>Exemple SVG</title>
<style></style>
<script></script>
</head>
<body>
<svg height="100" width="100">
<circle cx="50" cy="50" r="40" stroke="black" stroke-width="0.5" fill="#F89C43" />
Navigateur sans support SVG "inline".
</svg>
</body>
</html>
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>Exemple CSS</title>
<style>
body {
background-color: #F89C43;
}
</style>
<script src="script.js"></script>
</head>
<body>
<!-- Le reste du contenu -->
</body>
</html>
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>Exemple JavaScript</title>
<style></style>
<script>
console.log([5, 10, 15, 20, 25]);
</script>
</head>
<body>
<!-- Le reste du contenu -->
</body>
</html>
Le JavaScript peut être considéré comme la glue dans D3:
rien ne marche sans lui.
Il faut donc le maîtriser correctement pour pouvoir produire des visualisations personnalisées ou personnaliser les outils utilisant D3.
Pour cela, ouvrez la console/le debuggeur de votre navigateur soit:
Avec Ctrl + Shift + I soit avec F12
soit un clic droit sur une page web et cherchez dans le menu "Inspectez l'élément" (la dénomination peut changer selon le navigateur)
Les chaînes
console.log('Bonjour');
Les entiers et les réels
console.log(parseInt('14', 10));
console.log(14);
console.log(14.76);
console.log(parseFloat(14.76));
console.log(+14.76);
Les tableaux (array)
console.log(["A", "B", "C", "D"]);
var obj = {letterA: "A", letterB: "B", number3: 3};
console.log(obj);
console.log(obj['letterB']);
console.log(obj.number3);
function helloWorld() {
return 'Bonjour le monde';
}
console.log(helloWorld());
var helloWorld2 = function helloWorld2(nom) {
console.log('Bonjour le monde 2 ' + nom);
}
helloWorld2('Thomas');
Sur un tableau
var arr = ["A", "B", "C", "D"];
for (var i = 0, len = arr.length; i < len; i++) {
console.log(arr[i]);
}
Sur un objet
var obj = {letterA: "A", letterB: "B", number3: 3};
for (var prop in obj) {
console.log("o." + prop + " = " + obj[prop]);
}
var arr = ["A", "B", "C", "D"];
arr.forEach(function(el, i) {
console.log(el, i);
})
var arr = ["A", "B", "C", "D"];
console.log(arr.filter(function(el, i) {
return ["B","C"].indexOf(el) == -1
}).map(function(el) {
return {
"letter": el
}
}))
Un éditeur de texte. Cela peut être Notepad++ sous Windows, Gedit sous Linux (Par défaut sous Ubuntu), SublimeText (version d'essai, pas opensource), Atom, Brackets
Un serveur web. de nombreuses solutions mais le plus simple est d' utiliser Python pour cela en lançant en ligne de commande python -m SimpleHTTPServer
(version 2.x) ou python3 -m http.server
(version 3.x)
d3.select('body')
d3.selectAll('path')
C'est similaire à document.querySelector
et document.querySelectorAll
Exemple pour ajouter une balise SVG
d3.select('body').append('svg')
Ou définir des attributs
.attr('width', width)
.attr('height', height);
La manière classique de D3 pour Ajax
d3.json('geofla-departements.geojson', function(error, depts) {
console.log(depts);
})
enter
: pour faire la correspondance initialement
exit
: si on refait un enter
avec moins de données que d'élements DOM, exit
permet de récupérer les élements DOM ne correspondant pas
remove
permet de "nettoyer" les éléments qu'on lui passe
Fondamentalement, ce n'est pas vraiment différent sauf qu'on définit une classe en fonction d'une discrétisation plutôt qu'avec un seul nom land
.
On introduit la notion de domain
et range
dans D3
Ils sont utilisés via l'intermédiaire des fonctions d3.scale.*
Un domain
c'est l'étendue de la donnée du type min, max généralement
Un range
c'est la dimension pour ce qu'on va dessiner
En réalité, il s'agit de faire correspondre une valeur de la donnée à une autre valeur, généralement les mesures sur l'écran mais pas uniquement.
Par exemple, d3.scale.threshold fait une correspondance valeur et information discrète.
Pour des calculs pour discrétiser dans le navigateur, on utilise geostats. D3 embarque quelques méthodes comme d3.min
, d3.max
, d3.mean
, d3.median
, d3.quantile
, d3.deviation
, d3.variance
(...) si vous êtes sur des statistiques descriptives. Voir la documentation sur la manipulation des tableaux à ce propos.
Plutôt que de réinventer, nosu avons retenu un composant pour affichage de l'information au survol. En bindant ce composant lors des l'événement mouseout
et mouseover
sur nos éléments du DOM, on répond au besoin.
On utilise un hash pour joindre les données carto et CSV (attributaires)
On crée des cercles proportionnels avec les échelles via d3.scale.sqrt()
pour garder une proportionnalité à la surface.
On gère l'ajout d'une légende
Utilisation d'une bibliothèque nommé queue
par le même auteur que D3 qui présente l'intérêt de de chainer des appels Ajax imbriqués. C'est plus lisible. C'est assez similaire à des promesses ("Promise" JavaScript).
queue()
.defer(d3.json, "geofla-departements-light-4p.topojson")
.defer(d3.csv, "données-vin-2014-volume-recoltes.csv")
.await(ready);
Un simple DIV avec un fond CSS permet d'avoir des diagrammes en barre. Pas besoin de SVG obligatoirement.
d3.max
et un d3.scale.linear
pour calculer la largeur de manière dynamique plutôt qu'avec une valeur en dur (5000)Plutôt qu'utilisez des DIV, on utilise un élement de type rect.
Il est nécessaire d'utiliser des groupes: il n'est pas possible d'aligner les textes avec les rectangles sans cela.
On utilise les fonctions natives de SVG (transform) pour décaler les barres avec .attr("transform", function(d, i) { return "translate(0," + i * barHeight + ")"; });
transform
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(10);
Voir la documentation officielle sur les axes
text
avec (indice: il existe un moyen de faire une rotation en SVG)Une méthode des plus simples grâce à des sélections SVG en utilisant des identifiants et des "listeners": ce qui permet de surveiller si on survole un élément. C'est un autre terme déjà utilisé pour réagir au mouseout
, mouseover
de l'infobulle
Pour pouvoir générer des graphes, ils permettent de spécifier les relations graphiques entre les élements d'un graphe. Généralement, il faut une structure de données précises en entrée. Un layout est un algorithme qui génère une structure de données. On réutilise cette structure pour construire la visualisation.
On préfère arrêter les exemples "à la Prévert". N'hésitez pas explorer les exemples D3 tellement les choix sont nombreux.
On peut explorer quelques cas avec l'application RAW
Explorer l'outil RAW pour découvrir quelques autres layout
En Français
En anglais