I am using the D3.js
library and looking at the force-directed graph demo:
http://mbostock.github.com/d3/ex/force.html
I am also looking at the node-link tree:
http://mbostock.github.com/d3/ex/tree.html
What I would like to do is:
- Start with the force-directed graph and when the user clicks on a
node, have it animated smoothly into a tree, with the selected node
in the center.
- Then, when the user clicks on any empty space in the canvas, it
should animate back to the force-directed graph.
Has anyone done anything like this before, or have any advice as to the best approach to take? I am new to D3.js and have no idea if this is even supported by the framework.
What you need to do is stop the force and apply a transformation of the existing nodes to the x-y derived from the other layout. So your function would look like this:
force.stop();
d3.selectAll("g.nodes").transtion().duration(500)
.attr("translate","transform("+newLayoutX+","+newLayoutY+")"
Then iterate through your nodes array and set the x
, y
, px
, py
values to reflect the new X
and Y
. This will set your nodes to know the current x
and y
position for the force layout when you run force.start()
You can take a look at the plotLayout()
function in this example:
https://gist.github.com/emeeks/4588962
This does not rely on a second d3.layout, though. The problem you'll run into is that you need a hierarchical dataset for the tree layout, which requires you to transform your nodes and edges data into an array of node.children as expected in the hierarchical layouts. The way that I would do it is to duplicate the dataset and manually flatten it, but there may be a more elegant solution that I'm unaware of.