[英]Update d3 data react hooks
得到了这段代码:
export default function Chart({ data, changeData}) {
console.log(data);
const ref = useRef();
const createGraph = (data) => {
var margin = { top: 20, right: 20, bottom: 30, left: 40 },
width = 1360 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x = d3.scaleBand().range([0, width]).padding(0.1);
var y = d3.scaleLinear().range([height, 0]);
var svg = d3
.select(ref.current)
.append("svg")
.attr("id", "chart")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
x.domain(
data.map(function (d) {
return d.name;
})
);
y.domain([
0,
d3.max(data, function (d) {
return d.number;
}),
]);
// append the rectangles for the bar chart
const bars = svg.selectAll().data(data).enter().append("rect");
bars
.attr("class", "bar")
.attr("x", function (d) {
return x(d.name);
})
.attr("width", x.bandwidth())
.attr("y", function (d) {
return y(d.number);
})
.attr("fill", "pink")
.attr("height", function (d) {
return height - y(d.number);
})
.on("mouseenter", function (actual, i) {
d3.select(this).attr("opacity", 0.5);
d3.select(this)
.transition()
.duration(300)
.attr("opacity", 0.6)
.attr("x", (a) => x(a.name) - 5)
.attr("width", x.bandwidth() + 10);
})
.on("mouseleave", function (actual, i) {
d3.select(this).attr("opacity", 1);
d3.select(this)
.transition()
.duration(300)
.attr("opacity", 1)
.attr("x", (a) => x(a.name))
.attr("width", x.bandwidth());
});
bars
.append("text")
.attr("class", "value")
.attr("x", (a) => x(a.name) + x.bandwidth() / 2)
.attr("y", (a) => y(a.number) + 30)
.attr("fill", "blue")
.attr("text-anchor", "middle")
.text((a) => `${a.number}%`);
d3.selectAll("bars").append("text").attr("class", "divergence");
// add the x Axis
svg
.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
// add the y Axis
svg.append("g").call(d3.axisLeft(y));
};
useEffect(() => {
createGraph(data);
}, [data]);
return (
<React.Fragment>
<Filter>
<h2>By</h2>
<span>Popularity</span>
<span onClick={() => changeData()}>Following</span>
</Filter>
<div style={{ marginLeft: "100px" }} ref={ref}></div>
</React.Fragment>
);
}
如何在每次渲染时更新数据?
我尝试创建一个 function 删除 SVG 并添加一个新但位置在第一次渲染后搞砸了,我也尝试在 useEffect 中使用 exit() 和 remove() 但没有结果。
我试图实现的结果是我有一个图表,数据被提取并传递到这个组件中,每当我按下按钮时,数据都会改变。 我现在不看任何动画,我只想看看如何更改数据。
这有点晚了,但万一有人在搜索时遇到这个问题。
useEffect(() => {
*// your d3 code here*
instead of using .enter().append('rect')
use .join('rect')
}, [data]) *// runs the d3 code every time the data changes*
更多 about.join() https://observablehq.com/@d3/selection-join
在返回语句中指定 svg 和 g 标签。
代替 div 上的 ref,在 svg 标签上做 useRef
而不是.append(g),do.select('.x-axis') 等
这样你就不会在每次运行 useEffect 时 append new g
<svg ref={d3Container}>
<g className="chart">
<g className="x-axis" />
<g className="y-axis" />
</g>
</svg>
我在看了这个系列的第 1 和第 3 个视频https://muratorium.com/using-react-hooks-with-d3后了解了以上内容
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.