I'm trying to use the D3 Tree Layout to create a family tree of sorts and one of the things I noticed is that when I have many children nodes, it would stretch out horizontally across the screen. Ideally I would like a more vertical layout for these nodes so that people don't have to scroll across the screen and can just keep looking down the tree.
Here is what I currently see:
Now it might not be that bad, but if I had say 20 children, it would span across the whole screen and that is something I kind of want to avoid.
I have seen questions like this but this doesn't help me because I want a specific layout and not simply a resize... I have large nodes and they begin to collide with one another if I try to dynamically resize the tree -- shrinking the tree does not do me any good. I specifically need a different layout for situations where there are more than a certain number of children.
Here is kind of what I was envisioning/hoping for. Notice the root does not make this format because it has only 4 children. Ideally I want it so that if a parent has 5 or more children, it would result in the layout below. If the root had 5 children, it would result in this layout and the layout should simply stretch out vertically if users wanted to see the root's grandchildren (the A, B, C... nodes). If necessary I can get a diagram of that going:
I found a semi-similar question regarding custom children layouts and he said he had to play around with the actual d3js code. I kind of want to avoid this so I am hoping to find out if this is possible with d3js as it is right now and, if so, how to go about it? I don't need a complete answer, but a snippet of code proving that this is possible would be very helpful.
If necessary I can upload a JSFiddle for people to play around with.
Check out this fiddle:
http://jsfiddle.net/dyXzu/
I took the sample code from http://bl.ocks.org/mbostock/4339083 and made some modifications. Note that in the example, x and y are switched when drawing so the layout appears as a vertical tree.
The important thing I did was modifying the depth calculator:
Original:
Fixed:
Basically, I manually calculate the position of each node, overriding d3's default node positioning. Note that now there's no auto-scaling for x. You could probably figure this out manually by first going through and counting open nodes (d.children is not null if they exist, d._children stores the nodes when they are closed), and then adding up the total x.
Nodes with children in the two-column layout look a little funky, but changing the line-drawing method should improve things.
You could dynamically count the children and adjust the width/height of the DOM element accordingly. I would recommend counting the maximum number of children in any level, which can be calculated using the
depth
property provided by d3.tree.nodes(), or just by recursively going down the tree. Modifying some code which was in a previous SO answer, you could have something like this:Or using the
nodes()
method.