Search code examples
force-layoutwindow-resizebubble-chartd3.js

Resize D3 ForceSimulation on d3.vs4


I am trying to update the simulation of a bubble chart when the window resizes. So far, the radius of the bubbles resize but the cx coordinates do not update and the bubbles stay where they were first rendered.

var simulation=d3.forceSimulation()
            .force('x',d3.forceX(function(d){return xScale(d.n);}))
            .force('y',d3.forceY(height))
            .force('collide',d3.forceCollide(function(d){return rScale(d.m);}));
simulation.nodes(data)
    .on('tick',ticked);
function ticked(){
    dot
        .attr('cx',function(d){return d.x;})
        .attr('cy',function(d){return d.y;})
}

d3.select(window).on('resize',resize);
function resize(){
    //get width of window
    //update xScale and rScale
    //update radius of bubbles 
    simulation
        .force('x',d3.forceX(function(d){return xScale(d.n);}))
        .force('y',d3.forceY(height))
        .force('collide',d3.forceCollide(function(d){return rScale(d.m);}));
    simulation.nodes(data)
        .on('tick',ticked);
    function ticked(){
        dot
            .attr('cx',function(d){return d.x;})
            .attr('cy',function(d){return d.y;})
    }
}

Solution

  • you will need to restart your force simulation with the .restart() method, and play around with the .alpha() or .alphaTarget() value. Your code has some unnecessary duplication.

    Maybe something like the following may work for your use-case?

    var simulation=d3.forceSimulation()
                .force('x',d3.forceX(function(d){return xScale(d.n);}))
                .force('y',d3.forceY(height))
                .force('collide',d3.forceCollide(function(d){return rScale(d.m);}));
    simulation.nodes(data)
        .on('tick',ticked);
        
    function ticked(){
        dot
            .attr('cx',function(d){return d.x;})
            .attr('cy',function(d){return d.y;})
    }
    
    d3.select(window).on('resize',resize);
    function resize(){
        //get width of window
        //update xScale and rScale
        //update radius of bubbles 
        simulation
            .force('x',d3.forceX(function(d){return xScale(d.n);}))
            .force('collide',d3.forceCollide(function(d){return rScale(d.m);}))
            // 0.3 is arbitrary
            .alpha(0.3)
            .restart()
    
    }