2012-10-23 15 views
21

Ho un problema con l'inserimento di nuovi fratelli su elementi esistenti.d3.js - come inserire nuovi elementi di pari livello

ho questa struttura

<svg> 
    <g> 
    <path class="data"></path> 
    <path class="data"></path> 
    </g> 
</svg> 

e voglio questo struttura

<svg> 
    <g> 
    <path class="data"></path> 
    <text></text> 
    <path class="data"></path> 
    <text></text> 
    </g> 
</svg> 

ma se uso le d3.js funzione di inserimento

d3.select("g").insert("text", "path.data"); 

ottengo il seguente (nonostante la selezione per nome della classe)

<svg> 
    <g> 
    <text></text> 
    <path class="data"></path> 
    <path class="data"></path> 
    </g> 
</svg> 

qualche idea?

risposta

27

Prima di tutto, vale la pena notare che il secondo argomento nella funzione di inserimento è un prima del selettore. Inoltre, le operazioni concatenate agiscono sul risultato della mano sinistra.

Così avete fatto

// select all the g elements (only 1) 
d3.select("g") 
    // For each g, insert a text element before "path.data" 
    .insert("text", "path.data"); 

Si desidera eseguire un'operazione per ogni bambino ".data", quindi è necessario selezionare ogni degli elementi ".data" ed eseguire un'azione per ciascuno di essi . Non sono del tutto sicuro di come d3 si aspetti di inserire un elemento dopo un bambino specifico. Trovo molto più facile usare l'API DOM per fare la creazione e l'inserimento degli elementi, ma usando la funzione d3.each per scorrere su una selezione.

d3.selectAll("g > .data").each(function() { 
    var t = document.createElement('text'); 
    this.parentNode.insertBefore(t, this.nextSibling);  
});​ 
+0

Grazie Matt. Questo fa quello che voglio. Questa è probabilmente la soluzione migliore in ogni caso, poiché la funzione di inserimento di d3.js supporta solo le costanti come selettori (al momento). Quindi non puoi usare "this.nextSibling" come selettore. In un mondo ideale, la funzione d3.js corrispondente dovrebbe assomigliare a questa: d3.select (this.parentNode) .insert ("text", this); – Codetoffel

+0

L'aggiunta di nuovi elementi con '.each' e' document.createElement 'aggiunge il nodo al documento, ma viene rimosso dalla visualizzazione per qualche motivo. Presumibilmente, è possibile usare d3's 'insert() per farlo, ma il selettore" before "passato a' insert() 'selezionerà solo un singolo elemento. –