使用 React 在 D3 中复制元素而不是移动元素
Elements are duplicated instead of moved in D3 with React
我正在尝试在您单击按钮时移动 D3 中的元素。此代码复制元素而不是移动它们。
import React, { useRef, useEffect, useState } from "react";
import { select } from "d3";
const svgSize = 500;
const initData = [
{ value: 3, x: 60, y: 60 },
{ value: 2, x: 40, y: 40 },
{ value: 1, x: 20, y: 20 },
];
export default function Home() {
const [data, setData] = useState(initData);
const svgRef = useRef();
const animate = () => {
setData(
data.map((item) => {
return {
value: item.value,
x: item.x + 20,
y: item.y + 20,
};
})
);
};
useEffect(() => {
const svg = select(svgRef.current);
svg
.selectAll("circle")
.data(data)
.join("text")
.text((value) => value.value)
.attr("x", (value) => value.x)
.attr("y", (value) => value.y);
}, [data]);
return (
<div>
<button onClick={animate}>Animate</button>
<div>
<svg width={svgSize} height={svgSize} ref={svgRef} />
</div>
</div>
);
}
页面加载时:
点击按钮后:
我认为您的 svg
select 个节点有问题,您正在尝试 selectAll('circle')
但您需要 select selectAll('text')
。因此,您绘制一个新的 text
节点而不是移动它们。
尝试将 useEffect
更改为:
useEffect(() => {
const svg = select(svgRef.current);
svg.selectAll('text')
.data(data)
.join('text')
.text(({ value }) => value)
.attr('x', ({ x }) => x)
.attr('y', ({ y }) => y);
}, [data]);
如果要为动作添加动画,请添加:
useEffect(() => {
const svg = select(svgRef.current);
svg.selectAll('text')
.data(data)
.join('text')
.text(({ value }) => value)
.transition()
.duration(1000)
.attr('x', ({ x }) => x)
.attr('y', ({ y }) => y);
}, [data]);
我正在尝试在您单击按钮时移动 D3 中的元素。此代码复制元素而不是移动它们。
import React, { useRef, useEffect, useState } from "react";
import { select } from "d3";
const svgSize = 500;
const initData = [
{ value: 3, x: 60, y: 60 },
{ value: 2, x: 40, y: 40 },
{ value: 1, x: 20, y: 20 },
];
export default function Home() {
const [data, setData] = useState(initData);
const svgRef = useRef();
const animate = () => {
setData(
data.map((item) => {
return {
value: item.value,
x: item.x + 20,
y: item.y + 20,
};
})
);
};
useEffect(() => {
const svg = select(svgRef.current);
svg
.selectAll("circle")
.data(data)
.join("text")
.text((value) => value.value)
.attr("x", (value) => value.x)
.attr("y", (value) => value.y);
}, [data]);
return (
<div>
<button onClick={animate}>Animate</button>
<div>
<svg width={svgSize} height={svgSize} ref={svgRef} />
</div>
</div>
);
}
页面加载时:
点击按钮后:
我认为您的 svg
select 个节点有问题,您正在尝试 selectAll('circle')
但您需要 select selectAll('text')
。因此,您绘制一个新的 text
节点而不是移动它们。
尝试将 useEffect
更改为:
useEffect(() => {
const svg = select(svgRef.current);
svg.selectAll('text')
.data(data)
.join('text')
.text(({ value }) => value)
.attr('x', ({ x }) => x)
.attr('y', ({ y }) => y);
}, [data]);
如果要为动作添加动画,请添加:
useEffect(() => {
const svg = select(svgRef.current);
svg.selectAll('text')
.data(data)
.join('text')
.text(({ value }) => value)
.transition()
.duration(1000)
.attr('x', ({ x }) => x)
.attr('y', ({ y }) => y);
}, [data]);