2012-02-28 22 views
60

Estoy leyendo la documentación de D3.js y me es difícil comprender the selection.data method de la documentación.Comprender cómo D3.js vincula los datos a los nodos

Este es el código de ejemplo que se da en la documentación:

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; }); 

entiendo la mayor parte de esto, pero lo que está pasando con la sección .data(function(d) { return d; }) de la declaración var td?

Mi mejor conjetura es como sigue:

  • La declaración var tr ha atado una matriz de cuatro elementos a cada nodo tr
  • La declaración var td utiliza entonces ese conjunto de cuatro elementos como sus datos, de alguna manera

¿Pero cómo obtiene .data(function(d) { return d; }) realmente esa información y qué devuelve?

+2

Puede ser útil leer [este tutorial] (http://bost.ocks.org/mike/join/). – Phrogz

+0

¡Gracias! Ahora entiendo lo que está pasando con las partes '.enter()' del código. Sin embargo, creo que podría necesitar esperar el futuro tutorial para comprender qué está pasando con la función de clave de datos. – Richard

+4

Espero escribir pronto un nuevo tutorial que cubra la función clave y también las selecciones jerárquicas (selectAll.selectAll). – mbostock

Respuesta

62

Cuando se escribe:

….data(someArray).enter().append('foo'); 

D3 crea un montón de <foo> elementos, uno para cada entrada en la matriz. Más importante aún, también asocia los datos de cada entrada en la matriz con ese elemento DOM, como una propiedad __data__.

Prueba esto:

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__); 

Lo que usted verá (en la consola) es el objeto {msg:"Hello",cats:42}, ya que se asoció con el primer elemento de q creado.

Si posteriormente hacer:

d3.selectAll('q').data(function(d){ 
    // stuff 
}); 

el valor de d resulta ser que __data__ propiedad. (En este punto, le toca a usted para asegurar que reemplace // stuff con código que devuelve una nueva matriz de valores.)

Here's another example mostrando los datos con destino al elemento HTML y la posibilidad de volver a enlazar subconjuntos de datos en la parte inferior elementos:

  no description

+2

+1 para compartir D3.js Playground! Buena herramienta! – oluckyman

16

la clave para entender lo que este código está haciendo es reconocer que las selecciones son matrices de matrices de elementos DOM. La matriz más externa se denomina 'selección', la matriz interna (s) se llama 'grupos' y esos grupos contienen los elementos DOM. Puedes probar esto yendo a la consola en d3js.org y haciendo una selección como d3.selectAll ('p'), verás una matriz que contiene una matriz que contiene elementos 'p'.

En su ejemplo, cuando llama por primera vez a selectAll ('tr') obtiene una selección con un solo grupo que contiene todos los elementos 'tr'. Luego, cada elemento de matrix se combina con cada elemento 'tr'.

Pero cuando llama a selectAll ('td') en esa selección, la selección ya contiene un grupo de elementos 'tr'.Esta vez, cada uno de esos elementos se convertirá en en un grupo de elementos 'td'. Un grupo es solo una matriz, pero también tiene una propiedad parentNode que hace referencia a la selección anterior, en este caso los elementos 'tr'.

Ahora cuando llama al data(function(d) { return d; }) en esta nueva selección de elementos 'td', d representa los datos vinculados al nodo padre de cada grupo. Entonces en el ejemplo, los 'td's en el primer grupo estarán vinculados con la matriz [11975, 5871, 8916, 2868]. El segundo grupo de 'td's está vinculado con [1951, 10048, 2060, 6171].

Usted puede leer propia excelente explicación de Mike Bostock de selecciones y el enlace de datos aquí: http://bost.ocks.org/mike/selection/

+0

¡Gracias! Creo que esta respuesta es muy clara, va directo al grano; más que otra respuesta (que también ofrece información útil, sin ofender) – wires

+0

Gracias al enlace Kim. Eso es lo suficientemente detallado como para que lo entienda. Además, eso me empujó a http://bost.ocks.org/mike/nest/ – VivekDev

+1

Si bien el comentario de Phrogz tiene información excelente y es muy útil, esta respuesta explica claramente la pregunta ** exacta **. Tuve la misma confusión, y hizo clic cuando vi la parte que 'return d;' devuelve el nodo ** parent **. La confusión es que ciertos métodos funcionan en diferentes niveles jerárquicos. Por ejemplo, 'attr' funciona en los elementos individuales, a diferencia de' datos'. ¡Gracias! –

1

utilizar el contador i para mostrar el índice de los datos que se utiliza.

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