score:46

So when you set the "size" of the tree layout all you are doing is setting the value the tree layout will interpolate the x and y values to. So there is no reason you can't compute the width or height you want and change it in the layout on each update call.

I copied the example you gave to a jsFiddle and added the following to the update function:

// compute the new height
var levelWidth = [1];
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) * 20; // 20 pixels per line  
tree = tree.size([newHeight, w]);

Note that this is a pretty rough calculation and does not factor in where the children are w.r.t their parents or anything - but you get the idea.

As for manipulating the x values of the nodes the easiest is probably to simply modify the nodes after the layout has done it's thing. In fact you can see that this is already done in the example with the y coordinate:

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

He does this so that even if children are hidden a given level of nodes stays at the same y position, otherwise if you collapsed all the children the remaining levels would stretch to take up the whole width (try commenting that line out and see what happens as you toggle whole levels invisible).

As for going top down I think you can pretty much just flip everywhere you see x and y (and x0 and y0). Don't forget to do the same to the diagonal projection to make sure your lines flip too.


Related Query