2011-11-21 12 views
13

originale: http://mbostock.github.com/d3/ex/force.htmlD3 Forza diretti grafico utilizzando testi invece di nodi

Nel suo esempio, come previsto nel link qui sopra, sto semplicemente cercando di sostituire i nodi cerchio con i loro nomi, invece. Non so molto di D3 né di js/jquery, ma sto cercando di capire come funziona.

Sono stato in grado di sostituire i nodi con svg: text, ma quando lo faccio, si limitano a "spawn" ovunque avviano e non si animano.

Non so se dovrei usare i gruppi qui. Se lo faccio, insegnami come.

Finora, questo è il mio codice modificato:

<div id="chart"> 
</div> 

<script type="text/javascript"> 
<!-- 

var w = 960, 
    h = 500, 
    fill = d3.scale.category20(); 

var vis = d3.select("#chart").append("svg:svg") 
    .attr("width", w) 
    .attr("height", h); 

d3.json("http://fourthdraft.com/ext/dataviz/miserables.json", function(json) { 
    var force = d3.layout.force() 
     .charge(-120) 
     .linkDistance(70) 
     .nodes(json.nodes) 
     .links(json.links) 
     .size([w, h]) 
     .start(); 

    var link = vis.selectAll("line.link") 
     .data(json.links) 
    .enter().append("svg:line") 
     .attr("class", "link") 
     .style("stroke-width", function(d) { return Math.sqrt(d.value); }) 
     .attr("x1", function(d) { return d.source.x; }) 
     .attr("y1", function(d) { return d.source.y; }) 
     .attr("x2", function(d) { return d.target.x; }) 
     .attr("y2", function(d) { return d.target.y; }); 

    var node = vis.selectAll("circle.node") 
     .data(json.nodes) 
    .enter().append("svg:text") 
     .attr("class", "node") 
     .attr("x", function(d) { return d.x; }) 
     .attr("y", function(d) { return d.y; }) 
     .text(function(d) { return d.name; }) 
     .style("fill", function(d) { return fill(d.group); }) 
     .call(force.drag); 

    node.append("svg:title") 
     .text(function(d) { return d.name; }); 

    force.on("tick", function() { 
    link.attr("x1", function(d) { return d.source.x; }) 
     .attr("y1", function(d) { return d.source.y; }) 
     .attr("x2", function(d) { return d.target.x; }) 
     .attr("y2", function(d) { return d.target.y; }); 

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

//--> 
</script> 

risposta

20

Vedi questo violino: http://jsfiddle.net/nrabinowitz/QMKm3/6/

Il problema principale con il codice di cui sopra è che è stato modificato in modo corretto gli attributi cx e cy (che sono specifici all'elemento svg:circle) a x e nella parte in cui sono stati aggiunti gli elementi svg:text, ma non sono stati modificati nel gestore tick, che è il punto in cui l'aggiornamento iterativo del layout è stato eseguito. ns:

force.on("tick", function() { 
    // snip 

    node.attr("x", function(d) { return d.x; }) 
     .attr("y", function(d) { return d.y; }); 
}); 

È inoltre necessario modificare la selezione-e-aggiungendo da

var node = vis.selectAll("circle.node") 
    .data(json.nodes) 
.enter().append("svg:text") 

a

var node = vis.selectAll("text.node") 
    .data(json.nodes) 
.enter().append("svg:text") 

Anche se io non credo che questo fa alcuna differenza nel contesto di questo codice, finirà per farti saltare in aria - in D3, as explained here, generalmente usi lo schema "seleziona con un selettore, aggiungi nodi mancanti che corrispondono a questo selettore, rimuovi nodi extra che corrispondono a questo selettore". Nel tuo codice, il selettore e i nodi che aggiungi non corrispondono, il che è un problema concettuale anche se non ha alcuna ramificazione per il tuo codice come scritto. (Devo notare che trovo questo pattern un po 'confuso e strano, ma come minimo renderà il tuo codice più leggibile agli altri sviluppatori.)

+1

GRAZIE MOLTO. attualmente sto provando proprio ora. anche il violino è molto apprezzato! – user657896

+0

funziona e non sai quanto questo significhi per me – user657896

+0

+1 eccellente esempio. – noiv