I'm having some issues with my forceSimulation in React (using Hooks). The problem is that whenever data is changed the position of each bubble is translated into the middle of the screen, rather than considering its previous position (see gif), making the bubbles jump in an annoying way.
I do not have much experience with forceSimulation, d3 and react-hooks in conjunction, and its hard to find any similar examples; so I would really appreciate any guidance.
import React, { useEffect, useRef } from 'react'
import { forceSimulation, forceX, forceY, forceCollide, select } from 'd3'
export default function Bubbles({ data, width, height }) {
const ref = useRef()
const svg = select(ref.current)
useEffect(() => {
const simulation = forceSimulation(data)
.force('x', forceX().strength(0.02))
.force('y', forceY().strength(0.02))
.force(
'collide',
forceCollide((d) => {
return d.value * 20 + 3
}).strength(0.3)
)
simulation.on('tick', () =>
svg
.selectAll('circle')
.data(data)
.join('circle')
.style('fill', () => 'red')
.attr('cx', (d) => d.x)
.attr('cy', (d) => d.y)
.attr('r', (d) => d.value * 20)
)
}, [data])
return (
<svg
viewBox={`${-width / 2} ${-height / 2} ${height} ${width}`}
width={width}
height={height}
ref={ref}
style={{
marginRight: '0px',
marginLeft: '0px'
}}
></svg>
)
}
