score:7

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:

``````// Normalize for fixed-depth.
nodes.forEach(function(d) { d.y = d.depth * 180; });
``````

Fixed:

``````// Normalize for fixed-depth.
nodes.forEach(function (d) {
d.y = d.depth * 180;
if (d.parent != null) {
d.x =  d.parent.x - (d.parent.children.length-1)*30/2
+ (d.parent.children.indexOf(d))*30;
}
// if the node has too many children, go in and fix their positions to two columns.
if (d.children != null && d.children.length > 4) {
d.children.forEach(function (d, i) {
d.y = (d.depth * 180 + i % 2 * 100);
d.x =  d.parent.x - (d.parent.children.length-1)*30/4
+ (d.parent.children.indexOf(d))*30/2 - i % 2 * 15;
});
}
});
``````

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.

score:0

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:

``````    var levelWidth = ;
var childCount = function (level, n) {
if (n.children && n.children.length > 0) {
if (levelWidth.length <= level + 1) levelWidth.push(0);
levelWidth[level + 1] += n.children.length;
n.children.forEach(function (d) {
childCount(level + 1, d);
});
}
};
childCount(0, root);
var newHeight = d3.max(levelWidth) * 40;
tree = tree.size([Math.max(newHeight, 660), w]);
document.getElementById("#divID").setAttribute("height", Math.max(newHeight, 660) + 50);
``````

Or using the `nodes()` method.

``````var nodes = tree.nodes(root), arr = [];
for(i = 0; i < nodes.length; i++)
arr[nodes[i].depth]++;
var max = 0;
for(i = 0; i <nodes.length; i++)
if(arr[i] > max)
max = arr[i];
\$('#elementOfChoice').css("height", max*40);
var newHeight = max * 40;
tree = tree.size([Math.max(newHeight, 660), w]);
``````