2012-03-27 28 views
31

Tengo problemas para entender el uso de eventos D3 y funciones de envío. Tengo un ejemplo de gráfico en el que he estado trabajando llamado: "Vertical Bar Charts With Legends".¿Cómo agregar y utilizar D3 Events correctamente?

Dibujar los cuadros y las leyendas era bastante fácil, pero me gustaría agregar la capacidad de resaltar cada barra cuando muevo sobre su leyenda de texto correlativo, ubicada a la derecha del gráfico.

He leído toda la documentación del evento e incluso he visto varios ejemplos, la mayoría de los cuales son bastante complicados, pero parece que me falta algo. ¿Alguien sabría cómo realizar mejor la función de mouseover de leyenda de texto que distribuye eventos para cambiar automáticamente los colores de las barras verticales correspondientes?

Respuesta

60

Esta pregunta es similar al one you posted en el Grupo de Google d3-js. Sin duplicar lo que escribí allí, reiteraría que probablemente no desee d3.dispatch; que está destinado a abstracciones de eventos personalizados (como pinceladas y comportamientos). Será más simple usar eventos nativos.

Si desea que su leyenda para cambiar el color de la barra correspondiente al pasar el ratón, a continuación, la descomposición del problema en pasos:

  1. Detectar encima del ratón en la leyenda.
  2. Seleccione la barra correspondiente.
  3. Cambie el color de relleno de la barra.

En primer lugar, use selection.on para escuchar eventos de "mouseover" en los elementos de la leyenda. Se llamará a su función de escucha cuando el mouse vaya sobre un elemento de leyenda, y se le llamará con dos argumentos: los datos (d) y el índice (i). Puede usar esta información para seleccionar la barra correspondiente a través del d3.select. Por último, use selection.style para cambiar el estilo de "relleno" con el nuevo color.

Si no está seguro de cómo seleccionar la barra correspondiente en mouseover leyenda, por lo general hay varias opciones. El más sencillo es seleccionar por índice, suponiendo que el número de elementos de leyenda y el número de elementos rect son los mismos, y están en el mismo orden. En ese caso, si una variable local rect contiene los elementos rect, se podría decir:

function mouseover(d, i) { 
    d3.select(rect[0][i]).style("fill", "red"); 
} 

Si no quiere depender de índice, es otra opción para buscar la barra de juego basado en datos idénticos. Esto utiliza selection.filter:

function mouseover(d, i) { 
    rect.filter(function(p) { return d === p; }).style("fill", "red"); 
} 

Otra opción es dar a cada Rect un identificador único, y luego seleccione por id. Por ejemplo, en la inicialización, se podría decir:

rect.attr("id", function(d, i) { return "rect-" + i; }); 

A continuación, puede seleccionar el rect por id en mouseover:

function mouseover(d, i) { 
    d3.select("#rect-" + i).style("fill", "red"); 
} 

El ejemplo anterior se ideó desde que utiliza el índice para generar el id atributo (en cuyo caso, es más simple y más rápido usar la primera técnica de selección por índice). Un ejemplo más realista sería si sus datos tienen una propiedad de nombre; luego puede usar d.name para generar el atributo id, y también seleccionar por id. También puede seleccionar por otros atributos o clases, si no desea generar una identificación única.

+0

Hola Mike, gracias por toda su ayuda en esta materia. D3 es una gran tecnología y estoy disfrutando el tiempo aprendiéndola. - Frank –

+0

FWIW Este ejemplo podría implementarse simplemente agregando una regla CSS: hover a los elementos SVG en cuestión. –

+1

@HerbCaudill A: la regla de desplazamiento es demasiado restrictiva en este caso: este ejemplo muestra cómo modificar elementos distintos al que está siendo desplazado (por ejemplo, leyenda a barra). A: la regla de desplazamiento solo funciona si los elementos que desea modificar son los mismos que están suspendidos (por ejemplo, leyenda). Vea mi otra respuesta el [seleccionando y modificando elementos relacionados] (http://stackoverflow.com/questions/11206015/clicking-a-node-in-d3-from-a-button-outside-the-svg/11211391). – mbostock

6

La respuesta de Mike es genial.

que lo usaron llegar a este para la selección de una celda en una cuadrícula estaba dibujando:

.on('click', (d, i) -> 
     console.log("X:" + d.x, "Y:" + d.y) #displays the cell x y location 
     d3.select(this).style("fill", "red"); 

Así que cuando estoy entrando en los datos en añadí el detector de eventos y el uso de d3.select (este) .

ver el código en el contexto de abajo:

vis.selectAll("rect") 
    .data(singleArray) 
    .enter().append("svg:rect") 
    .attr("stroke", "none") 
    .attr("fill", (d) -> 
     if d.lifeForm 
     return "green" 
     else 
     return "white") 
    .attr("x", (d) -> xs(d.x)) 
    .attr("y", (d) -> ys(d.y)) 
    .attr("width", cellWidth) 
    .attr("height", cellHeight) 
    .on('click', (d, i) -> 
     console.log("X:" + d.x, "Y:" + d.y) 
     d3.select(this).style("fill", "red"); 
     return 
    ) 
Cuestiones relacionadas