Je lis la documentation D3.js et j'ai du mal à comprendre la méthode selection.data
de la documentation.
Voici l'exemple de code donné dans la documentation:
var matrix = [
[11975, 5871, 8916, 2868],
[ 1951, 10048, 2060, 6171],
[ 8010, 16145, 8090, 8045],
[ 1013, 990, 940, 6907]
];
var tr = d3.select("body").append("table").selectAll("tr")
.data(matrix)
.enter().append("tr");
var td = tr.selectAll("td")
.data(function(d) { return d; })
.enter().append("td")
.text(function(d) { return d; });
Je comprends la plupart de cela, mais que se passe-t-il avec la section .data(function(d) { return d; })
de l'instruction var td
?
Ma meilleure supposition est la suivante:
var tr
A lié un tableau à quatre éléments à chaque nœud trvar td
Utilise ensuite ce tableau à quatre éléments comme données, d'une manière ou d'une autreMais comment .data(function(d) { return d; })
obtient-il réellement ces données, et que renvoie-t-il?
Lorsque vous écrivez:
….data(someArray).enter().append('foo');
D3 crée un tas de <foo>
éléments, un pour chaque entrée du tableau. Plus important encore, il associe également les données de chaque entrée du tableau à cet élément DOM, sous la forme d'un __data__
propriété.
Essaye ça:
var data = [ {msg:"Hello",cats:42}, {msg:"World",cats:17} ];
d3.select("body").selectAll("q").data(data).enter().append("q");
console.log( document.querySelector('q').__data__ );
Ce que vous verrez (dans la console), c'est l'objet {msg:"Hello",cats:42}
, car il était associé au premier élément q
créé.
Si vous le faites plus tard:
d3.selectAll('q').data(function(d){
// stuff
});
la valeur de d
s'avère être que __data__
propriété. (À ce stade, c'est à vous de vous assurer de remplacer // stuff
avec un code qui renvoie un nouveau tableau de valeurs.)
Voici un autre exemple montrant les données liées à l'élément HTML et la possibilité de relier des sous-ensembles de données sur les éléments inférieurs:
La clé pour comprendre ce que fait ce code est de reconnaître que les sélections sont des tableaux de tableaux des éléments DOM. Le tableau le plus externe est appelé "sélection", le ou les tableaux internes sont appelés "groupes" et ces groupes contiennent les éléments DOM. Vous pouvez tester cela en allant dans la console à d3js.org et en faisant une sélection comme d3.selectAll ('p'), vous verrez un tableau contenant un tableau contenant des éléments 'p'.
Dans votre exemple, lorsque vous appelez pour la première fois selectAll ('tr'), vous obtenez une sélection avec un seul groupe qui contient tous les éléments 'tr'. Ensuite, chaque élément de matrix
est associé à chaque élément 'tr'.
Mais lorsque vous appelez selectAll ('td') sur cette sélection, la sélection contient déjà un groupe d'éléments 'tr'. Cette fois, chacun de ces éléments deviendra chacun un groupe d'éléments 'td'. Un groupe n'est qu'un tableau, mais il possède également une propriété parentNode qui fait référence à l'ancienne sélection, dans ce cas les éléments "tr".
Désormais, lorsque vous appelez data(function(d) { return d; })
sur cette nouvelle sélection d'éléments 'td', d
représente les données liées au nœud parent de chaque groupe. Ainsi, dans l'exemple, les 'td du premier groupe seront liés au tableau [11975, 5871, 8916, 2868]. Le deuxième groupe de 'td est lié à [1951, 10048, 2060, 6171].
Vous pouvez lire l'excellente explication de mike bostock sur les sélections et la liaison de données ici: http://bost.ocks.org/mike/selection/
Utilisez le compteur i pour afficher l'index des données utilisées.
var tr = d3.select("body").append("table").selectAll("tr")
.data(matrix)
.enter().append("tr") //create a row for each data entry, first index
.text(function(d, i) { return i}); // show the index i.e. d[0][] then d[1][] etc.
var td = tr.selectAll("td")
.data(function(d) { return d; })
.enter().append("td")
.style("background-color", "yellow") //show each cell
.text(function(d,i) { return i + " " + d; }); // i.e d[from the tr][0] then d[from the tr][1]...