我在React (使用钩子)中的forceSimulation遇到了一些问题。问题是,每当数据改变时,每个气泡的位置都会转换到屏幕的中间,而不是考虑它之前的位置(参见gif),这使得气泡以一种恼人的方式跳跃。
我没有太多将forceSimulation、d3和react-hooks结合使用的经验,而且很难找到任何类似的示例;因此,如果有任何指导,我将非常感激。
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>
)
}

发布于 2021-08-06 19:51:14
我认为这里的问题是React呈现了SVG,而D3呈现了圆圈。当React在更新时重新呈现时,它会创建SVG并丢弃任何子对象,因为它不知道这些子对象。
因此,数据不能以通常的D3方式绑定到DOM,而应该存储在React组件的状态中。
https://stackoverflow.com/questions/66855913
复制相似问题