web-dev-qa-db-fra.com

Comprendre comment D3.js lie les données aux nœuds

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:

  • L'instruction var tr A lié un tableau à quatre éléments à chaque nœud tr
  • L'instruction var td Utilise ensuite ce tableau à quatre éléments comme données, d'une manière ou d'une autre

Mais comment .data(function(d) { return d; }) obtient-il réellement ces données, et que renvoie-t-il?

68
Richard

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:

 no description

65
Phrogz

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/

19
allen kim

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]...
1
Mortis