Avoiding nodes overlapping in d3 trees

This is a simple example to avoid overlapping between siblings in a d3 tree.

I have been working a lot with d3 trees lately and dynamic node resizing, which is cool to have a
complex representation for you data.

When using simple d3 trees with different node sizes, they sometimes overlap with each other. I knew there is
a separation method, but I couldn't get it working for my case, so using an example designed for d3 force element
I could adapt to my current simple tree.


    function collide(node, node_sibling) {
      var r = node.size,
          n1y1 = node.x - r,
          n1y2 = node.x + r;
      var r2 = node_sibling.size,
          n2y1 = node_sibling.x - r2,
          n2y2 = node_sibling.x + r2;
      result = (n1y1 < n2y2 && n1y1 > n2y1) || (n1y2 > n2y2 && n1y2 < n2y1);

      return result;
    }

The size property doesn't exist in nodes, so it will be whatever property you want
to control the size of them.

I'm just checking in one dimension (x) because I want to control only siblings in my tree and they are aligned
across the y axis. You could do the same with the y property in this function.

This kind of function could be approximately the same for other d3 elements.

To use it in a tree we could use it inside a forEach loop in nodes.


    function detectCollisions(nodes) {
      nodes.forEach(function(d, index) {
        for (var i=0; i < siblings.length; i++)
        {
            if(d.id != siblings[i].id) {
                if(collide(d, sibligns[i])) {
                    // Do something, like change the position
                    // of the current sibling
                }
            }
        }
      });
    }

This is it by now, I will get more deeply into it soon if I think there is something worth to comment.

Javier Aguirre

Read more posts by this author.

comments powered by Disqus