Search code examples
d3.jscollision-detectionforce-layout

Maximum distance limit for D3 Force Layout?


I'm using a force layout with a small negative charge to avoid having SVG elements on top of each other. However, I need the items to remain within ~20px of their original location. Is there any means of limiting to the total net X/Y distance the items move?

Each SVG element represents a bus stop, so it's important that items do not overlap but also do not move too far from their original location.


Solution

  • There's no option for this in the force layout itself, but you can do that quite easily yourself in the function that handles the tick event:

    force.on("tick", function() {
      nodes.attr("transform", function(d) {
        return "translate(" + Math.min(0, d.x) + "," + Math.min(0, d.y) + ")";
      });
    });
    

    This would bound the positions to be to the top right of (0,0). You can obviously modify that to bound in any other way as well (potentially with a nested Math.min/Math.max). You could even do that dynamically by storing allowed position ranges with the element and referencing that.

    See here for an example that uses this technique to restrict the position of labels floated using the force layout.