0

I'm recreating a D3 Tidy Tree with this example. I generate my own JSON and feed it to the tree. This works fine, except I can't figure out a way to adjust the width of the tree to the depth of the data.

Even in the examples and in the documentation, the width of the SVG graphic is just hardcoded. From the Observable example:

let width = 1954

// create the D3 hierarchy using width
tree = data => {
   const root = d3.hierarchy(data);
   root.dx = 10;
   root.dy = width / (root.height + 1);
   return d3.tree().nodeSize([root.dx, root.dy])(root);
}

// create the SVG graphic using width
const svg = d3.create("svg")
  .attr("viewBox", [0, 0, width, x1 - x0 + root.dx * 2]);

But this looks very weird if the data is much smaller or larger than expected. Is this a glitch in D3? How can I adjust the size of a D3 SVG to its own contents? Am I overlooking something in the documentation?

Kokodoko
  • 26,167
  • 33
  • 120
  • 197
  • 1
    So you want to give your tree a set number of pixels (say 300 * 100) per node, and let the size of the entire tree depend on the amount of nodes and the depth? – Ruben Helsloot Nov 24 '20 at 16:33
  • Yes, the width variable should depend on how much width the tree actually needs to display itself. If I just put a hardcoded number, it's often displayed either too wide or too narrow. – Kokodoko Nov 24 '20 at 19:17
  • And `.nodeSize([200, 40])` is not what you're looking for? – Ruben Helsloot Nov 24 '20 at 19:55
  • No, because that’s still not adjusted to the number of branches in the tree. I can hardcode a width but I don’t know how many branches the tree will have beforehand. The tree data is generated dynamically. – Kokodoko Nov 25 '20 at 20:49
  • Do you realise that if a tree has 5 layers and the widest layer has 10 nodes, `.nodeSize([100, 10])` automatically makes the tree 500 * 100 pixels? See [this example](https://observablehq.com/@d3/collapsible-tree), where every layer is always exactly the same distance away from the previous layer, no matter how many layers there are – Ruben Helsloot Nov 25 '20 at 20:54
  • Thanks for the link! But the problem is I don't know the amount of layers beforehand. So if there are 25 layers, there simply isn't enough room to display them all horizontally. And when I make the width default 10.000 pixels, it looks weird when there are only 3 layers. – Kokodoko Nov 26 '20 at 16:40
  • So you want to use `.size([])` until the number of nodes becomes too large, then you want to use `.nodeSize([])`? – Ruben Helsloot Nov 26 '20 at 16:59
  • I need a way to get rid of that first line of code: `size = 1954` because I don't know that number. – Kokodoko Nov 26 '20 at 17:28
  • @RubenHelsloot Thanks for your comments. I was able to find a solution here: this answer calculates the number of nodes in the tree so then you can know what the width should be: https://stackoverflow.com/questions/13103748/dynamically-resize-the-d3-tree-layout-based-on-number-of-childnodes – Kokodoko Nov 29 '20 at 14:33

0 Answers0