D3 Tree layout with all leaves same distance from root - javascript

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

Related

Setting variable width on d3 tree nodes

I'm using d3 to create an Org Chart, which has some nodes with longer names.
I've managed to modify the width of longer nodes, but have trouble properly placing their children and the lines (paths) to their children.
I tried calculating myself with determineChildXValue(), but that didn't work properly.
Is there a way to initialize the tree with variable widths so it will take care of the calculations of translations for child nodes?
Currently, I'm initializing it with hard-coded node sizes:
var tree = d3.layout.tree().nodeSize([70, 40]);
I've replicated the behavior in this example - expand Departments, then DEPARTMENT STORES to see the overlap.
Thanks in advance!
I consulted a colleague who was able to build a proper fix:
Define the source and target properties (before the projection is set) for the diagonal (paths)
Track the tierDisplacementX and cumulativeDisplacementX
Use these when translating the positions of the child nodes and their paths
See this fiddle to see the working code.

Force positions of some nodes with CoSE Bilkent layout

I'm working with compound graphs. I know the positions (e.g.: geographic coordinates) of the parent nodes and I want to layout the children nodes in order to minimize the intersection of the edges. The final position of the children does not matter, provided that they are close to each other.
The CoSE Bilkent algorithm with Cytoscape.js gives me the right kind of layout but I would like to set the positions of the parent nodes and lock them in place.
What I've done:
Started with this example but with less nodes;
Set the position for each group:
Only the parent;
Same coordinates for parent and its children;
Adjusted some options of the layout;
Tried the attribute locked with no luck
The best I got is this.
So far, the relative positions of the groups is correct but if I add a new group g5 I got this.
The desired result would be something like this:
I'm open to use another library if needed.
(1) A parent's position and dimensions are implied by the positions and dimensions of its children.
(2) You can run a layout on a subset of the graph (e.g. children only): http://js.cytoscape.org/#collection/layout
(3) Avoiding edges from overlapping each other in a layout in a performant way is an active, unsolved research problem. Additionally, some graphs just aren't planar.
Try using (2) to run a layout on the subgraph of each parent's descendants:
var topLvlParents = cy.nodes().orphans(':parent');
topLvlParents.forEach(function( parent ){
var descendants = parent.descendants();
var edges = nodes.edgesWith( nodes );
descendants.union( edges ).layout( someLayoutOptions );
});
You can use cose-bilkent as the subgraph layout and adjust the positions to your desired bounding box on layoutstop (and this would be easier with boundingBox natively supported in cose-bilkent). Or you could use cose -- which isn't as sophisticated as cose-bilkent but allows for direct boundingBox placement today.
If your compound parent-child hierarchy is only one level, then you could try using any of the noncompound layouts on the children with boundingBox as well.
My understanding is that CoSE Bilkent is the most state of the art algorithm for compound node layout. It's from a university lab that specialises in graph theory, layouts, etc.

D3 Force Layout - No overlapping links

I have a D3 visualization with nodes using the force-layouts as seen below. Some of the lines cross each other, which makes the visualization more difficult to understand. How can I ensure that the lines do not overlap?
I've tried modifying the parameters of the force-layout (charge, friction, gravity), but without any luck. The current code is below. Perhaps I need to do something other than modifying the force-layout to achieve the result?
force = d3.layout.force()
.nodes(data_nodes)
.links(data_links)
.charge(-3000)0
.friction(0.6)
.gravity(0.6)
.size([width,height])
.start();
As Lars Kotthoff stated it can be done manually (I found http://bl.ocks.org/mbostock/3231298#index.html as inspiration), but actually it could be done a lot simpler if I just changed the force-layout a bit.
If I let the central node have a quite strong charge compared to the remaining nodes, they will align nicely in a circle around the node, removing any overlaps:
.charge(function(d, i) { return i==0 ? -10000 : -500; })
You can put extra nodes on the edges to reduce overlap.
E.g: http://bl.ocks.org/couchand/7190660

Setting Max Length of Links in D3 Tree Layout

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.
})

How modify space between node in collapsible tree using d3.js ?

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

Categories

Resources