【发布时间】:2020-08-02 11:40:55
【问题描述】:
我正在使用 react 和 d3,试图创建一个简单的条形图,在数据刷新时更新图表。当数据更改时,图表正在更新,但它似乎在旧图表之上分层。我认为问题出在 d3 exit().remove() 函数上。
据我了解,d3 的退出方法应该返回一个要删除的项目数组,但是当我控制台记录它时,我看到一个“未定义”数组。我非常感谢任何帮助!
这里是代码框: https://codesandbox.io/s/gifted-field-n66hw?file=/src/Barchart.js
这里是sn-p的代码:
import React, { useEffect, useRef } from "react";
import * as d3 from "d3";
const BarChart = props => {
const { randomData, width, height, padding } = props;
const ref = useRef(null);
function colorGradient(v) {
return "rgb(0, " + v * 5 + ", 0";
}
//insert & remove elements using D3
useEffect(() => {
if (randomData.length > 0 && ref.current) {
const group = d3.select(ref.current);
// the data operator binds data items with DOM elements
// the resulting selection contains the enter and exit subselections
const update = group
.append("g")
.selectAll("rect")
.data(randomData);
let bars = update
.enter() // create new dom elements for added data items
.append("rect")
.merge(update)
.attr("x", (d, i) => i * (width / randomData.length))
.attr("y", d => height - d * 5)
.attr("width", width / randomData.length - padding)
.attr("height", d => d * 5)
.attr("fill", d => colorGradient(d));
let labels = update
.enter()
.append("text")
.text(d => d)
.attr("text-anchor", "middle")
.attr(
"x",
(d, i) =>
i * (width / randomData.length) +
(width / randomData.length - padding) / 2
)
.attr("y", d => height - d * 5 + 12)
.style("font-family", "sans-serif")
.style("font-size", 12)
.style("fill", "#ffffff");
update.exit().remove();
}
}, [randomData, height, padding, width]);
return (
<svg width={width} height={height}>
<g ref={ref} />
</svg>
);
};
export default BarChart;
【问题讨论】:
-
发生这种行为是因为您每次进行更新选择时都附加一个
g:它将为空且没有要退出的矩形,并且输入选择将导致输入数据数组中的所有项目.如果group已经只是一个g没有别的,你可以跳过附加一个额外的。否则,您可以将g仅附加一次并在更新函数中使用它。 -
你能解释一下在别处附加 g 是什么意思吗?我尝试将它移到 useEffect 之外,现在它适用于第一次渲染,但如果我更新数据,图表就会消失。此外,我认为该组只是一个 g(它有条形和文本,但没有其他内容)但我不完全确定你的意思。抱歉,我是 D3 的新手。我更新了代码框:codesandbox.io/s/gifted-field-n66hw?file=/src/Barchart.js
标签: reactjs d3.js react-hooks