2012-07-31 7 views
13

Ich arbeite mit einem d3-Zwangslayout mit HTML-Knotenbeschriftungen, die mit SVG foreignObject-Elementen implementiert wurden. Ich möchte diese Elemente zu verschiedenen Zeiten auswählen, um ihre Positionen und andere Eigenschaften zu aktualisieren (und verfolgen sie, wie sie erstellt und mit und exit() destoryed), aber ich kann sie nicht wie andere SVG-Elemente auswählen .Ich kann kein SVG-Element foreignObject in d3 auswählen

Hier ist ein kompaktes Beispiel:

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

Dies auch bei http://bl.ocks.org/3217448 oben ist. Die Konsole Ausgabe ist:

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

wobei das erste Array den circle Element enthält, während der zweite leer ist. Warum ist das circle Objekt auswählbar, aber das foreignObject ist nicht? Ich nehme an, es hat mit der ungewöhnlichen Natur der foreignObject zu tun. Wie würde ich es auswählen, um es in meinem Code zu manipulieren? Vielen Dank.

+0

(aktualisiert, um zusätzliches Komma Tippfehler zu entfernen) –

Antwort

19

Streng genommen ist SVG Groß-und Kleinschreibung, so dass Sie <foreignObject> anstelle von <foreignobject> verwenden sollten.

Noch ernster ist, dass es eine offene bug in WebKit gibt, die verhindert, dass camelCase-Elemente ausgewählt werden.

Eine mögliche Abhilfe verwenden:

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

(Dies kann nicht älter WebKit-Versionen funktionieren in obwohl, finden Sie in der inzwischen geschlossenen WebKit bug 46800.)

Alternativ können Sie CSS-Klassen oder IDs verwenden und wählen Sie stattdessen Ihre Elemente aus. Ich würde diese Herangehensweise im Moment empfehlen, wenn es möglich ist, angesichts der verschiedenen oben genannten Fehler.

+2

Vielen Dank - zu wissen, dass es ein Fehler ist, macht mich besser fühlen. :-) Ich verwende nur die Klassenauswahl als Workaround. –

+0

Ich bekomme den Fehler "Uncaught SyntaxError: Fehler beim Ausführen der Abfrage: '[Objekt NodeList]' ist kein gültiger Selektor." bei Verwendung von d3.selectAll (document.getElementsByTagName ("foreignObject")). Aber die Auswahl nach dem Klassennamen funktioniert perfekt. Vielen Dank. Es scheint immer noch ein Bug in Chrome 31 zu sein. –

+0

Eigentlich gab es einen Fehler in meiner vorgeschlagenen Problemumgehung. Ich habe es aktualisiert, um eine Funktion zu verwenden, die für jedes Element der Auswahl aufgerufen wird. Mein ursprünglicher Vorschlag funktionierte nur für d3.selectAll, nicht für selection.selectAll. –

-2

Sie sollten in der Lage sein, d3.selectAll ("foreignObject") oder svg.selectAll ("foreignObject") zu verwenden. Möglicherweise ist dieses zusätzliche Komma in Ihren foreignObject-Attributen (zwischen x und y) enthalten. Ich habe FremdeObjekt-Elemente nur mit D3 eingefügt, also ist vielleicht etwas daran, sie anders einzubetten.