user2058285
user2058285

Reputation: 51

how to vary distance between d3 nodes in force layout

I have searched a lot in d3 for visualization. I am able to visualize my data from database. And now, I want to vary distance between different d3 nodes.There is a function force.linkdistance() which is used to specify the distance between nodes. at the moment i am providing constant distance of 100. I want to vary this distance for each link depending upon a column in database. which is a numeric column. I am attaching my code also. please help, if any one can.

    var okCounter=0;
var width = 960,
height = 500;

console.log("still ok here:",okCounter++);

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);
console.log("still ok here:",okCounter++);
var force = d3.layout.force()
    .gravity(.05)
    .distance(100)
    .charge(-100)
    .size([width, height]);
console.log("still ok here:",okCounter++);
d3.json("getdata.php", function(error,json) {
   force
      .nodes(json.nodes)
      .links(json.links)
      .start();
console.log("still ok here:",okCounter++);
  var link = svg.selectAll(".link")
      .data(json.links)
      .enter().append("path")
      .attr("class", "link");
console.log("still ok here:",okCounter++);
  var node = svg.selectAll(".node")
      .data(json.nodes)
    .enter().append("g")
      .attr("class", "node")
     // .call(force.drag);
console.log("still ok here:",okCounter++);
  node.append("image")
      .attr("xlink:href", "http://www.clker.com/cliparts/5/6/3    /a/1194984675331456830utente_singolo_architett_01.svg.med.png")
      .attr("x", -8)
      .attr("y", -8)
      .attr("width", 24)
      .attr("height", 24);
console.log("still ok here:",okCounter++);
  node.append("text")
      .attr("dx", 24)
      .attr("dy", ".35em")
      .text(function(d) { return d.name });
console.log("still ok here:",okCounter++);
  force.on("tick", function() {
    link.attr("d", function(d) {
var dx = d.target.x - d.source.x,
    dy = d.target.y - d.source.y,
    dr = Math.sqrt(dx * dx + dy * dy); 
return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " +     d.target.x + "," + d.target.y;
});
console.log("still ok here:",okCounter++);
    node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")";   });
 });
});</script> 

Upvotes: 3

Views: 8779

Answers (2)

mrienstra
mrienstra

Reputation: 622

If you want force.linkDistance to vary, use a function rather than a constant.

If distance is a constant, then all links are the same distance. Otherwise, if distance is a function, then the function is evaluated for each link (in order), being passed the link and its index, with the this context as the force layout; the function's return value is then used to set each link's distance. The function is evaluated whenever the layout starts.

(from https://github.com/d3/d3-3.x-api-reference/blob/master/Force-Layout.md#linkDistance)

You might also wish to experiment with passing a function to force.linkStrength, although I suspect the effect will be subtle (haven't tried it yet myself).

Upvotes: 6

Storm
Storm

Reputation: 4445

var force = d3.layout.force()
    .linkDistance(function(d) { 
          return(/* whatever computation you want the distance of each link to be */); 
    }
    .start();

Upvotes: 2

Related Questions