No se puede seleccionar el elemento SVG outsiderObject en d3

Estoy trabajando con un diseño de dirección forzada d3 con etiquetas de nodo HTML implementadas con SVG foreignObject elementos. Me gustaría seleccionar estos elementos en varios momentos para actualizar sus posiciones y otras propiedades (y rastrearlos a medida que se crean y se eliminan con enter() y exit() ), pero parece que no puedo seleccionarlos como otros elementos SVG.

Aquí hay un ejemplo compacto:

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 está en http://bl.ocks.org/3217448 . La salida de la consola es:

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

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

preguntado el 31 de julio de 12 a las 15:07

(Actualizado para eliminar el error tipográfico de coma adicional) -

2 Respuestas

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

Sin embargo, lo más serio es que hay una puerta abierta error en WebKit que evita que se seleccionen elementos camelCase.

Una posible solución es utilizar:

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

(Sin embargo, es posible que esto no funcione en versiones anteriores de WebKit; consulte el ahora cerrado Error de WebKit 46800.)

Alternativamente, puede usar clases o ID de CSS y seleccionar sus elementos de esa manera. Recomendaría este enfoque en este momento si es posible, dados los diversos errores antes mencionados.

Respondido el 12 de diciembre de 13 a las 13:12

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

Aparece el error "Error de sintaxis no detectado: no se pudo ejecutar la consulta: '[object NodeList]' no es un selector válido". al usar 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. - Alex KeySmith

En realidad, hubo un error en mi solución sugerida. Lo actualicé para usar una función que se llama para cada elemento de la selección. Mi sugerencia original solo funcionó para d3.selectAll, no para selection.selectAll. - jason davies

Hace un año se envió un parche para esto. No contenga la respiración para arreglarlo en WebKit. - jcollum

Debería poder d3.selectAll("foreignObject") o svg.selectAll("foreignObject"). Puede ser esa coma adicional en sus atributos de objeto extranjero (entre x e y). Solo he insertado elementos de ForeignObject usando D3, por lo que quizás haya algo diferente en incrustarlos de esta manera.

Respondido 31 Jul 12, 16:07

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.