2012-07-31 8 views
13

Estoy trabajando con un diseño dirigido por fuerza d3 con etiquetas de nodo HTML implementadas con elementos SVG foreignObject. Me gustaría seleccionar estos elementos en varias ocasiones para actualizar sus posiciones y otras propiedades (y rastrearlas a medida que se crean y borran con enter() y exit()), pero no parece poder seleccionarlas como otros elementos SVG .No se puede seleccionar el elemento foreignObject de SVG en d3

Aquí está un ejemplo compacta:

HTML:

<html> 
    <head> 
     <title>Cannot Select SVG Foreign Object</title> 
     <script src="http://d3js.org/d3.v2.js"></script> 
     <script src = "fo_select.js"></script> 
    </head> 
    <body> 
     <svg id="example_svg" width="600" height="600"> 
       <g> 
        <circle r="40" cx = "80" cy="80"></circle> 
        <foreignObject width = "100" height = "100" x = "200" y="200"> 
         <body>Hello, world</body> 
        </foreignObject> 
       </g> 
     </svg> 
     <script>run()</script> 
    </body> 
</html> 

Javascript:

function run() { 
    svg = d3.select("#example_svg"); 
    console.log(svg.selectAll("circle")); 
    console.log(svg.selectAll("foreignObject")); 
} 

Esto también corresponde a http://bl.ocks.org/3217448. La salida de la consola es:

[Array[1]] 
[Array[0]] 

donde la primera matriz contiene el elemento circle, mientras que el segundo está vacía. ¿Por qué es el objeto circle seleccionable, pero el foreignObject no? Supongo que tiene que ver con la naturaleza inusual del foreignObject. ¿Cómo lo seleccionaría para manipularlo en mi código? Muchas gracias.

+0

(Actualizado para eliminar el error de coma adicional) –

Respuesta

19

Estrictamente hablando, SVG distingue entre mayúsculas y minúsculas, por lo que debe usar <foreignObject> en lugar de <foreignobject>.

Más en serio, es que hay un bug in WebKit abierto que impide que los elementos camelCase sean seleccionados.

Una posible solución es utilizar:

.selectAll(function() { return this.getElementsByTagName("foreignObject"); }) 

(Esto puede no funcionar en versiones anteriores de WebKit, aunque, ver el WebKit bug 46800 ahora cerrada.)

Como alternativa, puede utilizar clases CSS o ID y seleccione sus elementos de esa manera en su lugar. Recomendaría este enfoque por el momento si es posible, dados los varios errores mencionados anteriormente.

+2

Muchas gracias, saber que es un error me hace sentir mejor. :-) Usaré la selección de clase como solución alternativa. –

+0

Aparece el error "Uncaught SyntaxError: Error al ejecutar la consulta: '[object NodeList]' no es un selector válido." cuando se usa d3.selectAll (document.getElementsByTagName ("foreignObject")). Pero seleccionar por el nombre de la clase funciona perfectamente. Gracias. Todavía parece ser un error en Chrome 31. –

+0

En realidad, hubo un error en mi solución alternativa sugerida. Lo he actualizado para usar una función que se llama para cada elemento de la selección. Mi sugerencia original solo funcionó para d3.selectAll, not selection.selectAll. –

-2

Debería poder d3.selectAll ("foreignObject") o svg.selectAll ("foreignObject"). Puede ser esa coma adicional en los atributos de foreignObject (entre xey). Solo inserté elementos ForeignObject usando D3, por lo que tal vez haya algo diferente en incluirlos así.

Cuestiones relacionadas