首页 > 解决方案 > 如何使用 redux 操作更新 d3 图?

问题描述

我正在尝试使用在鼠标事件(mouseenter、mouseleave)中调用的 redux 操作来存储来自工具提示的数据。

问题:当鼠标光标位于元素(g 元素)上时,我只期望mouseenter事件但mouseleave也被触发。这会导致更新 redux 存储并在循环中重新渲染 react 组件。

我有一个 svg 元素,然后我附加 g 元素,它是圆形和文本的包装器。我在 g 元素上添加了事件监听器。

这是我的代码:

const SomeReactComponent =() => {
const dispatch = useDispatch();

const createChart = () => {

    const svg = d3
      .select(svgNode)
      .attr('width', width + margin.left + margin.right)
      .attr('height', height + margin.top + margin.bottom)
      .style('border', '2px solid black')
      .append('g')
      .attr(
        'transform',
        `translate(${width / 2 + margin.left / 2},${height / 2 + margin.top})`
      );

const Tooltip = d3
        .select('.polar-scatter-chart')
        .append('div')
        .attr('class', 'tooltip');

const wrapper = svg
      .selectAll('Points')
      .data(newData)
      .enter()
      .append('g')
      .on('mouseenter', ({ id, name, themeName }) => {
        Tooltip.html(name)
          .style('visibility', 'visible')
          .style('top', `${d3.event.pageY - 350}px`)
          .style('left', `${d3.event.pageX}px`);
          dispatch(handleTooltip({ id, themeName }));
        }
      })
      .on('mouseleave', () => {
        Tooltip.style('visibility', 'hidden');
          dispatch(handleTooltip({ id: '', themeName: '' }));
      });
    wrapper
      .append('circle')
      .attr('class', 'point')
      .attr('transform', (d, i) => {})
      .attr('r',7)

    wrapper
      .append('text')
      .attr('transform', (d) => {})
      .text((d) => some_text);
  };
 }

 createChart();

  return (
    <div className="polar-scatter-chart">
      <svg ref={svgRef} />
    </div>
  );
}

如何使用 redux 操作正确更新 d3 图?

感谢您的回答

标签: reactjsd3.jsreduxredux-toolkit

解决方案


您在每次渲染时调用 createChart,创建一组全新的元素,这些元素可能位于已经存在的元素之上。因此,每次,您“离开”旧元素,因为您“进入”了在顶部绘制的元素。

如果你想这样做,你应该createChart在一个useEffect调用中包装并且只执行一次。

但更好的主意是使用 D3 库进行反应。


推荐阅读