2012-10-20 18 views
21

Sto utilizzando uno degli esempi di layout forza (http://bl.ocks.org/1153292) per mostrare una rete sul mio sito web.Come aggiornare gli elementi del layout di forza D3 quando i dati sottostanti cambiano

Consente all'utente di scegliere il tipo di collegamenti da visualizzare in qualsiasi momento. Ho notato che quando scelgo di vedere il tipo di collegamento A, quindi aggiungo il tipo di collegamento B e quindi rimuovo il tipo di collegamento A i collegamenti rimanenti di tipo B sono presentati con i colori A.

Questo è il codice che viene eseguito per aggiungere i collegamenti al diagramma svg. Sto modificando l'array this.links aggiungendo e rimuovendo i collegamenti da esso. Come potete vedere ho impostato l'attributo di classe, ma non è l'aggiornamento - rimane di tipo di collegamento A.

var path = svg.append("svg:g") 
    .selectAll("path") 
    .data(this.links) 
    .enter() 
    .append("svg:path") 
    .attr("class", function(d) { return "link " + d.type; }) 
    .attr("marker-end", function(d) { return "url(#" + d.type + ")"; }); 

Attualmente lavoro a questo problema aggiornando l'attributo class all'interno della funzione tick ma questo fuori rotta causa molto lavoro non necessario.

Ho letto che l'operazione di invio restituisce una selezione unita degli elementi esistenti e anche di quelli nuovi in ​​modo che l'operazione attr aggiorni quella esistente e imposta quella nuova.

Cosa mi manca?

risposta

19

ho trovato il answer in this post

var circle = svg.selectAll("circle") 
    .data(data); 

circle.enter().append("circle") 
    .attr("r", 2.5); 

circle 
    .attr("cx", function(d) { return d.x; }) 
    .attr("cy", function(d) { return d.y; }); 

circle.exit().remove(); 

La risposta è che ho bisogno di chiamare attr operatore sul risultato di selectAll.data e non sul risultato dell'operatore accodamento.

+1

Ido, so che questo è un vecchio post, ma credo che sto vivendo lo stesso problema che eri, e ancora non capisco questa soluzione. Potresti spiegare come funziona - come risolve il tuo problema originale? Grazie. – Mars

+3

La soluzione funziona perché gli aggiornamenti attr di cx e cy sono al di fuori del contesto enter(), quindi si verificano ogni volta. Nel codice originale, le funzioni attr sono chiamate all'interno del contesto enter(), quindi vengono create una sola volta in base all'identità dell'oggetto. Quello che per me è stato conoscere le funzioni chiave come secondo argomento di data(): http://bost.ocks.org/mike/constancy/ – velotron

4

C'è un esempio su http://bl.ocks.org/1095795 che mostra l'aggiunta e la rimozione di nodi da un layout forzato. I collegamenti e i nodi devono essere gestiti separatamente e quindi il layout della forza deve essere riavviato.

function restart() { 
    var link = vis.selectAll("line.link") 
     .data(links, function(d) { return d.source.id + "-" + d.target.id; }); 

    link.enter().insert("svg:line", "g.node") 
     .attr("class", "link"); 

    link.exit().remove(); 

    var node = vis.selectAll("g.node") 
     .data(nodes, function(d) { return d.id;}); 

    var nodeEnter = node.enter().append("svg:g") 
     .attr("class", "node") 
     .call(force.drag); 

    nodeEnter.append("svg:image") 
     .attr("class", "circle") 
     .attr("xlink:href", "https://d3nwyuy0nl342s.cloudfront.net/images/icons/public.png") 
     .attr("x", "-8px") 
     .attr("y", "-8px") 
     .attr("width", "16px") 
     .attr("height", "16px"); 

    nodeEnter.append("svg:text") 
     .attr("class", "nodetext") 
     .attr("dx", 12) 
     .attr("dy", ".35em") 
     .text(function(d) { return d.id }); 

    node.exit().remove(); 

    force.start(); 
} 
+1

Questo non è abbastanza. Sto aggiungendo e rimuovendo link e il problema è che non è in ordine. Quando scelgo di vedere i collegamenti di tipo A l'array di collegamenti è [A1, A2, A3], quindi scelgo di vedere i collegamenti di tipo B l'array è [A1, A2, A3, B1, B2], quindi scelgo di non vedere il tipo Una matrice è [B1, B2]. D3 quindi scegliere di lasciare 2 elementi e rimuovere 3, ma poi devo aggiornare i due elementi perché sono attualmente legati ad A1 e A2 e ho bisogno che vengano associati a B1 e B2. Riesco a farlo salvando i dati vis.selectAll ("g.Node"). (Nodi) e aggiornandolo. –

+0

Se crei un jsfiddle che mostra ciò che stai facendo e qual è il problema, potremmo essere in grado di aiutarti a trovare una soluzione migliore. – Bill

Problemi correlati