Buscar..


Sintaxis

  • d3 seleccionar (selector)
  • d3 seleccionarAll (selector)
  • seleccion seleccionar (selector)
  • seleccion seleccionarAll (selector)
  • seleccion filtro (filtro)
  • seleccion fusionar (otro)

Observaciones

Lecturas relacionadas:

Selección básica y modificaciones.

Si está familiarizado con la sintaxis de jQuery y Sizzle, las selecciones de d3 no deberían ser muy diferentes. d3 imita la API de selectores de W3C para facilitar la interacción con los elementos.

Para un ejemplo básico, seleccionar todos <p> y agregar un cambio a cada uno de ellos:

d3.selectAll('p')
  .attr('class','textClass') 
  .style('color', 'white');

En pocas palabras, esto es relativamente lo mismo que hacer en jQuery

$('p')
  .attr('class','textClass') 
  .css('color, 'white')

En general, comenzará con una sola selección en su contenedor div para agregar un elemento SVG que se asignará a una variable (comúnmente llamada svg).

var svg = d3.select('#divID').append('svg');

Desde aquí podemos solicitar a svg que realice nuestras subselecciones de múltiples objetos (incluso si aún no existen).

svg.selectAll('path')

Diferentes selectores

Puede seleccionar elementos con diferentes selectores:

  • por etiqueta: "div"
  • por clase: ".class"
  • por id: "#id"
  • por atributo: "[color=blue]"
  • Selectores múltiples (OR): "div1, div2, class1"
  • selectores múltiples (AND): "div1 div2 class1"

Selección simple de datos limitados

var myData = [
    { name: "test1", value: "ok" },
    { name: "test2", value: "nok" }
]

// We have to select elements (here div.samples)
// and assign data. The second parameter of data() is really important,
// it will determine the "key" to identify part of data (datum) attached to an 
// element.
var mySelection = d3.select(document.body).selectAll("div.samples") // <- a selection
                   .data(myData, function(d){ return d.name; }); // <- data binding

// The "update" state is when a datum of data array has already
// an existing element associated.
mySelection.attr("class", "samples update")

// A datum is in the "enter" state when it's not assigned
// to an existing element (based on the key param of data())
// i.e. new elements in data array with a new key (here "name")
mySelection.enter().append("div")
    .attr("class", "samples enter")
    .text(function(d){ return d.name; });

// The "exit" state is when the bounded datum of an element
// is not in the data array
// i.e. removal of a row (or modifying "name" attribute)
// if we change "test1" to "test3", "test1" bounded
//          element will figure in exit() selection
// "test3" bounded element will be created in the enter() selection
mySelection.exit().attr("class", "samples remove");

El papel de los marcadores de posición en las selecciones "entrar"

¿Qué es una selección de entrada?

En D3.js, cuando uno enlaza datos a elementos DOM, son posibles tres situaciones:

  1. El número de elementos y el número de puntos de datos son los mismos;
  2. Hay más elementos que puntos de datos;
  3. Hay más puntos de datos que elementos;

En la situación # 3, todos los puntos de datos sin un elemento DOM correspondiente pertenecen a la selección de entrada . Por lo tanto, en D3.js, ingrese selecciones son selecciones que, después de unir elementos a los datos, contienen todos los datos que no coinciden con ningún elemento DOM. Si usamos una función de append en una selección de ingreso , D3 creará nuevos elementos que vincularán esos datos para nosotros.

Este es un diagrama de Venn que explica las posibles situaciones con respecto a la cantidad de puntos de datos / cantidad de elementos DOM:

introduzca la descripción de la imagen aquí

Como podemos ver, la selección de ingreso es el área azul a la izquierda: puntos de datos sin los elementos DOM correspondientes.

La estructura de la selección enter.

Normalmente, una selección de entrada tiene estos 4 pasos:

  1. selectAll : Seleccionar elementos en el DOM;
  2. data : cuenta y analiza los datos;
  3. enter : comparando la selección con los datos, crea nuevos elementos;
  4. append : append los elementos reales en el DOM;

Este es un ejemplo muy básico (mire los 4 pasos en los var divs ):

var data = [40, 80, 150, 160, 230, 260];

var body = d3.select("body");

var divs = body.selectAll("div")
    .data(data)
    .enter()
    .append("div");

divs.style("width", function(d) { return d + "px"; })
    .attr("class", "divchart")
    .text(function(d) { return d; });

Y este es el resultado ( jsfiddle aquí ):

introduzca la descripción de la imagen aquí

Observe que, en este caso, usamos selectAll("div") como la primera línea en nuestra variable de selección "enter". Tenemos un conjunto de datos con 6 valores, y D3 creó 6 divs para nosotros.

El papel de los marcadores de posición

Pero supongamos que ya tenemos un div en nuestro documento, algo como <div>This is my chart</div> en la parte superior. En ese caso, cuando escribamos:

body.selectAll("div")

Estamos seleccionando ese div existente. Por lo tanto, nuestra selección de entrada tendrá solo 5 datos sin elementos coincidentes. Por ejemplo, en este jsfiddle , donde ya existe una división en el HTML ("Este es mi gráfico"), este será el resultado:

introduzca la descripción de la imagen aquí

Ya no vemos el valor "40": nuestra primera "barra" desapareció, y el motivo es que nuestra selección "enter" ahora tiene solo 5 elementos.

Lo que tenemos que entender aquí es que en la primera línea de nuestra variable de selección de ingreso, selectAll("div") , esos divs son solo marcadores de posición . No tenemos que seleccionar todos los divs si estamos agregando divs , o todo el circle si estamos agregando circle . Podemos seleccionar diferentes cosas. Y, si no planeamos tener una "actualización" o una selección de "salida", podemos seleccionar cualquier cosa :

var divs = body.selectAll(".foo")//this class doesn't exist, and never will!
    .data(data)
    .enter()
    .append("div");

Haciendo esto, estamos seleccionando todo el ".foo". Aquí, "foo" es una clase que no solo no existe, sino que nunca se creó en ninguna otra parte del código. Pero no importa, esto es sólo un marcador de posición. La lógica es esta:

Si en su selección "enter" selecciona algo que no existe, su selección "enter" siempre contendrá todos sus datos.

Ahora, seleccionando .foo , nuestra selección "enter" tiene 6 elementos, incluso si ya tenemos un div en el documento:

introduzca la descripción de la imagen aquí

Y aquí está el jsfiddle correspondiente .

Seleccionando null

Por mucho, la mejor manera de garantizar que no está seleccionando nada es seleccionando null . No solo eso, sino que esta alternativa es mucho más rápida que cualquier otra.

Por lo tanto, para una selección de entrada, simplemente haga:

selection.selectAll(null)
    .data(data)
    .enter()
    .append(element);

Aquí hay un violín de demostración: https://jsfiddle.net/gerardofurtado/th6s160p/

Conclusión

Cuando se trata de selecciones de "ingreso", tenga mucho cuidado de no seleccionar algo que ya existe. Puede usar cualquier cosa en su selección de selectAll , incluso cosas que no existen y que nunca existirán (si no planea tener una selección de "actualización" o "salida").

El código de los ejemplos se basa en este código de Mike Bostock: https://bl.ocks.org/mbostock/7322386

Usando "esto" con una función de flecha

La mayoría de las funciones en D3.js aceptan una función anónima como argumento. Los ejemplos comunes son .attr , .style , .text , .on y .data , pero la lista es mucho más grande que eso.

En tales casos, la función anónima se evalúa para cada elemento seleccionado, en orden, que se pasa:

  1. El dato actual ( d )
  2. El índice actual ( i )
  3. El grupo actual ( nodes )
  4. this como el elemento DOM actual.

El dato, el índice y el grupo actual se pasan como argumentos, el famoso primer, segundo y tercer argumento en D3.js (cuyos parámetros son tradicionalmente llamado d , i y p en D3 v3.x). Para usar this , sin embargo, uno no necesita usar ningún argumento:

.on("mouseover", function(){
    d3.select(this);
});

El código anterior seleccionará this cuando el mouse esté sobre el elemento. Compruébalo funcionando en este fiddle: https://jsfiddle.net/y5fwgopx/

La función de flecha

Como una nueva sintaxis de ES6, una función de flecha tiene una sintaxis más corta en comparación con la expresión de función. Sin embargo, para un programador D3 que utiliza this constante, hay una trampa: una función de la flecha no crea su propia this contexto. Eso significa que, en una función de flecha, this tiene su significado original del contexto adjunto.

Esto puede ser útil en varias circunstancias, pero es un problema para un codificador acostumbrado a usar this en D3. Por ejemplo, usando el mismo ejemplo en el violín anterior, esto no funcionará:

.on("mouseover", ()=>{
    d3.select(this);
});

Si tiene dudas, aquí está el violín: https://jsfiddle.net/tfxLsv9u/

Bueno, eso no es un gran problema: uno simplemente puede usar una expresión de función tradicional y antigua cuando sea necesario. ¿Pero qué pasa si quieres escribir todo tu código usando las funciones de flecha? ¿Es posible tener un código con funciones de dirección y seguir utilizando adecuadamente this en D3?

Los argumentos segundo y tercero combinados

La respuesta es , porque this es lo mismo de los nodes[i] . La sugerencia está realmente presente en toda la API D3, cuando describe esto:

... con this como el elemento DOM actual ( nodes[i] )

La explicación es simple: dado que los nodes son el grupo actual de elementos en el DOM i es el índice de cada elemento, los nodes[i] refieren al elemento DOM actual. Es decir, this .

Por lo tanto, uno puede utilizar:

.on("mouseover", (d, i, nodes) => {
    d3.select(nodes[i]);
});

Y aquí está el violín correspondiente: https://jsfiddle.net/2p2ux38s/



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow