D3 折线图组件未在 React 中的 useEffect 内更新

问题描述

我正在从 API 接收我的折线图数据。每次更新数据时,它不会以平滑的过渡重新绘制,而是在现有图表的顶部绘制新线。看起来很乱。我在唱 useEffect 时没有生命周期。是否与line().remove().merge()有关?我做错了什么?

CodeSandbbox

useEffect(() => {
    const svg = d3
      .select(svgRef.current)
      .append("g")
      .attr("transform","translate(0," + -130 + ")");
    const xScale = d3.scaleTime();
    const yScale = d3.scaleLinear();
    const xAxisDateFormat = d3.timeFormat("%b");
    
    // line generator
    const line = d3
      .line()
      .curve(d3.curveCatmullRom.alpha(1))
      .x((d) => xScale(new Date(d.date)))
      .y((d) => yScale(d.value));

    // draw line chart
    const lines = svg.append("g").attr("class","lines");
    lines
      .selectAll(".line-group")
      .data(lineChartData.values)
      .enter()
      .append("g")
      .attr("class","line-group")
      .append("path")
      .attr("class","line")
      .attr("stroke",(d,i) => colorScale(d.lineColor))
      .attr("d",(d) => line(d.dataset));
  },[lineChartData]);

解决方法

您的代码中缺少

exit()

const lines = svg.append("g")
  .classed("lines",true);
const groups = lines
  .selectAll(".line-group")
  .data(lineChartData.values);

const newGroups = groups.enter()
  .append("g")
  .classed("line-group",true);

newGroups.append("path")
  .classed("line",true)
  .attr("stroke",(d,i) => colorScale(d.lineColor))
  .attr("d",(d) => line(d.dataset));

const oldGroups = groups.exit();
oldGroups.remove();
,

您可以在添加新元素之前清除 svg 内容。

代替:

const svg = d3
      .select(svgRef.current)
      .append("g")

做:

 const svgEl = d3.select(svgRef.current);

 svgEl.selectAll('*').remove();

 const svg = svgEl
      .append('g')

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...