I have the same problem as this topic : D3 Tree Layout Separation Between Nodes using NodeSize
I have tried the solution, but there is another problem, the root is always on the left and when I collapse nodes, they are out of the screen.
the solution is based ond d3.js and on http://bl.ocks.org/mbostock/4339083 but when I set a nodeSize, the root doesn't dynamically move to optimized position.
So How can I have space between my "rect" nodes and a dynamically replace of root node to optimize display ?
Sorry for my bad english !
Thanks for your help
You can try something like this :
// Normalize for fixed-depth.
nodes.forEach(function(d) { d.y = d.depth * 450; });
Modify the value 450 to increase/decrease the x axis distance between the nodes
Related
I was wondering if anyone could help with this:
I have a simple d3 force diagram (here). I was wondering if I programmatically can get a node (fixed node C1) and shift it to a different position with transition animation like in the follwoing example:
var mySquare=svg.append("rect")
.attr("x",60)
.attr("y",60)
.attr("width",60)
.attr("height",60);
mySquare
.transition()
.attr("x",320);
So in a nutshell - once a diagram completes I would like to pick a node (C1) and give different x and y using a transition animation.
I am trying to implement a radial force layout in D3.js , I saw a similar example but i am stuck on how to initiate the node positions in the layout.
http://bl.ocks.org/vlandham/5087480
Thanks in Advance
Initialising a position is just done by setting the cx and cy positions. The most logical place is where the radius is currently being set i.e.
.attr("r", 10)
.attr("cx", 5) //added
.attr("cy", 5) //added
Of course, you can do something more exotic if you are using the bound data to initialise position.
This will only set the starting point though - the force layout will then take over and position elements. The advantage is that you can potentially reduce some of the initial node movement if you get it right.
I'm using this example as a base D3.js Drag and Drop, Zoomable, Panning, Collapsible Tree with auto-sizing.
What I need is a tree where all the leaf nodes are the same distance from the root.
It should look something like the Cluster Dendrogram.
I would use the Cluster Dendrogram but it lacks the zooming, panning and collapsibilty options (I've cut out node dragging). Also the difference between the two examples is that one uses tree layout whereas the other cluster layout.
All your help and suggestions would be much appreciated.
It likely won't be easy to implement because the tree layout likes it's depth but you could do something like this.
nodes.forEach(function(d) {if(!d.children){
d.depth = 3; //3 should be replaced with whatever your lowest depth is
//you could write a function to find it too. let me know if you need that
}})
nodes.forEach(function (d) {d.y = d.depth * 300;});
this will accomplish part of what you are talking about but there is nothing to prevent the nodes from overlapping here. This post: Avoid overlapping of nodes in tree layout in d3.js about node spacing could potentially help
I have a tree graph very similar to the one here: http://bl.ocks.org/mbostock/999346 and I would like to limit the spacing vertically of the nodes; if you look at the tree you will see that when there are just two nodes, they take up the entire canvas (the link between the two nodes is very long), and as other nodes are inserted, the link(s) are resized to fit. I would like to limit the link length to some max number so that the tree is more compact with fewer nodes.
Jason Davies' approach of looping over the nodes after d3.layout.tree has run and overwriting each node's y-value works well for me. (described in this d3 github issue comment)
So, something like
nodes.forEach(function(node){
node.y = (node.depth * 90); // 90px per level.
})
Thanks to this earlier question, I produced a static fixed-layout graph as below using force layout in d3.js:
and I have two specific questions to further customize the layout:
First, I notice that initializing nodes positions deterministically (e.g. done diagonally here, see the script for details) fixes the positions of the nodes, and the orientation of the nodes seem to depend on this initialization as well as the dimensions of the force graph*. I wonder how can I make the nodes A, D, E, F, I in the graph above aligned horizontally? In other words, I want to turn the orientation of the graph anti-clockwise for roughly 45 degrees. I have tried to initialize the nodes horizontally in the middle:
nodes.forEach(function(d, i) { d.x = w / size * i; d.y = h / 2; });
but the produced output has all the nodes and edges horizontally at where they were initialized.
Second, is it true that the force graph is automatically centered within the svg element? If no, how can we make it so? If yes, how can we specify a center for the force graph within the svg element?
(* Note: strangely, when setting .size([w, h]) where w = h for the force graph, and deterministically initializing the nodes along a diagonal, all the nodes and edges are positioned along that diagonal in the output, why?)
Try adding a custom gravity force applied on each tick which pulls the nodes towards the horizontal line. Something like this:
force.on('tick', function(e) {
nodes.forEach(function(d) {
d.y += (height/2 - d.y) * e.alpha;
});
})
To your second question, I believe, it is not centered, but there is a small gravity force by default which pulls the nodes towards the center.