Search code examples
javascriptd3.jsforce-layoutdirected-graphd3-force-directed

D3.js - How to keep force directed layout in bounds when radius has been scaled


Currently, I have a force directed layout where nodes and links go out of my svg boundaries if data is too large. My tick function includes:

node
    .attr('cx', function(d) {return d.x})
    .attr('cy', function(d) {return d.y})

I do see references suggesting:

node
    .attr("cx", function(d) { return d.x = Math.max(radius, Math.min(width - radius, d.x)); })
    .attr("cy", function(d) { return d.y = Math.max(radius, Math.min(height - radius, d.y)); });

The radius of my nodes are using the following scale:

var scaleR = d3.scaleSqrt()
                .domain(d3.extent(graph.nodes, function(d) {return d.frequency})
                .range([1,20])

How would I be able to reference each node's radius in the tick function?

Thank you in advance


Solution

  • Use the following, which replaces the radius value with the scaleR function:

    node
        .attr("cx", function(d) { return d.x = Math.max(scaleR(d.frequency) , Math.min(width - scaleR(d.frequency), d.x)); })
        .attr("cy", function(d) { return d.y = Math.max(scaleR(d.frequency) , Math.min(height - scaleR(d.frequency), d.y)); });