2012-07-04 10 views
43

Estoy tratando de acceder a los atributos cx & cy de algunos círculos svg específicos que ya he dibujado a la pantalla utilizando la función .data() de d3.js, ¿alguien puede ayudar? El código que está intentando acceder está debajo.¿Cómo acceder a los atributos del elemento d3.js desde el datum?

d3.selectAll(".mynode").each(function(d, i){ 
    if(d.someId == targetId){ 
    console.log(d.attr("cx")); // just trying to demo my point, doesn't work 
    } 
} 

Soy bastante nuevo en d3.js & Javascript, así que no estoy seguro si estoy abordar esta atrás hacia adelante de todos modos o tal vez me hayan pasado una solución incorporada?

+0

¿Has probado d.cx? Si llamaras a .data en d3.selectAll (". Mynode"), y al argumento de los datos que contengan objetos con un campo cx, eso debería funcionar. – mathheadinclouds

Respuesta

65

Su código está tratando de obtener un atributo SVG de un elemento de datos, cuando lo que realmente quiere es conseguir ese atributo del elemento DOM SVG, como en:

console.log(d3.selectAll(".mynode").attr("cx")); 

Esto sólo le dará el atributo para el primer elemento no nulo de su selección; Puede también filter su selección para obtener el elemento DOM que buscas:

console.log(d3.selectAll(".mynode").filter(_conditions_).attr("cx")); 

O, si desea acceder a los atributos de todos los elementos seleccionados, utilice en su this cada función:

d3.selectAll(".mynode").each(function(d, i){ 
    if(d.someId == targetId){ 
    console.log(d3.select(this).attr("cx")); 
    } 
} 
+1

estaba usando 'd3.select (this) .attr (" cx ")' antes, pero estaba devolviendo 'null', me di cuenta de que finalmente estaba solicitando el atributo' cx' de un elemento de grupo svg (doh!) Yi tuve que modificarlo a 'd3.select (this.firstChild) .attr (" cx ")' para obtener acceso a mi elemento de círculo dentro del elemento de grupo, no me gusta usar firstChild/lastChild, etc., pero funciona por ahora . Además, no habría pensado en el método de filtro si no lo hubiera sugerido, aún no estoy completamente seguro de cómo implementarlo mientras busco valores de referencia específicos, ¡pero gracias! –

+0

También agregaré que puede devolver nulo si intenta acceder a él temprano en una cadena de comandos y aún no se ha establecido el valor particular. – greg

12

El método de filtro en la respuesta aceptada es correcto. El segundo enfoque en la respuesta aceptada (utilizando .each) es incorrecto y contiene el mismo error que el cuestionario: si no se llama a .data() (que es el caso aquí), entonces el primer argumento d pasó a .each será indefinido (y no el "nodo dom actual", como esperarían todos los novatos, incluido yo mismo); el nodo dom actual se obtiene a través de d3.select (this), que es correcto dentro de la instrucción if al final - el error está en la condición if test. La versión correcta sigue.

d3.selectAll(".mynode").each(function(d,i){ 
    var elt = d3.select(this); 
    if (elt.attr("id") == "yourTargetIdGoesHere"){ 
     console.log(elt.attr("cx")); 
    } 
}); 

violín: fiddle (código que contiene para ambas versiones, es decir, el filtro y cada una)

ACTUALIZACIÓN: mi respuesta fue el supuesto de que no se ha utilizado .data(), ya que usted no dio el código para eso; más tarde vi que escribiste que usaste .data()

en ese caso, dependiendo de tu estructura de datos, reemplazar d.attr ("cx") por d.cx podría funcionar.

11

No hay manera aún más simple: (índice de proporcionar i se da)

d3.selectAll("circle")[0][i].attributes.cx.value 

como se puede observar here.