Aki
Aki

Reputation: 179

In d3 Force-Directed Graph, pull similar nodes together.

Stuck at the following output

In the output shown each node is named like this [city, state] and randomly placed. I was wondering if there is a way to pull cities with same states nearer or closer to each other with respect to other states.

Link to the data array (links): http://pastebin.com/rrYkv7HN

code till now:

var nodes = {};
// Compute the distinct nodes from the links.
  links.forEach(function(link) {
  link.source = nodes[link.source] || (nodes[link.source] = {name:link.source+", "+link.cstate});
  link.target = nodes[link.target] || (nodes[link.target] = {name: link.target+", "+link.sstate});
});
   var force = d3.layout.force()
    .nodes(d3.values(nodes))
    .links(links)
    .size([w, h])
    .linkDistance(200)
    .charge(-300)
    .on("tick", tick)
    .start();

var g3 = d3.select("#graph").append("svg")
    .attr("width", w)
    .attr("height", h);

var link = g3.selectAll(".link")
    .data(force.links())
    .enter().append("line")
    .attr("class", "link");

var node = g3.selectAll(".node")
    .data(force.nodes())
    .enter().append("g")
    .attr("class", "node")
    .call(force.drag);

node.append("circle")
    .style("fill", "red")
    .attr("r", 8);

node.append("text")
    .attr("x", 12)
    .attr("dy", ".35em")
    .text(function(d) { return d.name; });

function tick() {
    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("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
}

Upvotes: 2

Views: 812

Answers (2)

Cyril Cherian
Cyril Cherian

Reputation: 32327

You can update the distance as per the node's state.

.linkDistance(function(d){
      if(d.cstate == d.sstate)
        return 80;//similar state will be close
      else 
        return 200;//non similar state will be far
    })

working example here

Upvotes: 1

eko
eko

Reputation: 40647

You can give the nodes a group property and then use that data to put them together inside a path.

Take a look at this example: http://bl.ocks.org/GerHobbelt/3071239

When you click on the bigger nodes, it will expand into smaller nodes with the same group clustered inside a path.

Upvotes: 1

Related Questions