2012-07-31 13 views
13

Sto lavorando con un layout d3 force-directed con etichette di nodo HTML implementate con elementi SVG foreignObject. Vorrei selezionare questi elementi in momenti diversi per aggiornare le loro posizioni e altre proprietà (e tenerne traccia mentre vengono creati e scaricati con enter() e exit()), ma non mi sembra possibile selezionarli come altri elementi SVG .Impossibile selezionare l'elemento SVG foreignObject in d3

Ecco un esempio compatta:

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")); 
} 

Questo è anche fino a http://bl.ocks.org/3217448. L'output della console è:

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

dove il primo array contiene l'elemento circle, mentre la seconda è vuoto. Perché l'oggetto circle è selezionabile, ma lo foreignObject non lo è? Presumo che abbia a che fare con la natura insolita di foreignObject. Come lo selezionerei per manipolarlo nel mio codice? Grazie mille.

+0

(aggiornato per rimuovere l'errore di battitura extra) –

risposta

19

In senso stretto, SVG distingue tra maiuscole e minuscole, pertanto è necessario utilizzare <foreignObject> anziché <foreignobject>.

Più seriamente, tuttavia, c'è uno bug in WebKit aperto che impedisce la selezione degli elementi di camelCase.

Una possibile soluzione consiste nell'utilizzare:

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

(questo potrebbe non funzionare nelle versioni WebKit vecchie però, vedi l'ormai chiuso WebKit bug 46800.)

In alternativa, è possibile utilizzare le classi CSS o gli ID e seleziona i tuoi elementi in questo modo. Vorrei raccomandare questo approccio al momento, se possibile, dati i vari bug di cui sopra.

+2

Grazie mille - sapere che è un bug mi fa sentire meglio. :-) Userò semplicemente la selezione della classe come soluzione alternativa. –

+0

Viene visualizzato l'errore "Uncaught SyntaxError: impossibile eseguire la query: '[object NodeList]' non è un selettore valido." quando si utilizza d3.selectAll (document.getElementsByTagName ("foreignObject")). Ma selezionare con il nome della classe funziona perfettamente. Grazie. Sembra ancora un bug in Chrome 31. –

+0

In realtà, c'era un bug nella mia soluzione suggerita. L'ho aggiornato per utilizzare una funzione chiamata per ogni elemento della selezione. Il mio suggerimento originale funzionava solo per d3.selectAll, non selection.selectAll. –

-2

Dovresti essere in grado di d3.selectAll ("foreignObject") o svg.selectAll ("foreignObject"). Potrebbe essere quella virgola extra nei tuoi attributi foreignObject (tra xey). Ho inserito solo elementi ForeignObject usando D3, quindi forse c'è qualcosa che li incorpori in questo modo è diverso.

Problemi correlati