首页 > 解决方案 > 为什么 D3 Brush 不清除 React App 中的多个图形

问题描述

我在同一个 React 组件中的不同元素的同一页面上显示了多个图表。每个图表使用相同的代码位,但只有第一个图表在选择后清除画笔。js所有图表在没有 React的常规文件中都能正常工作。

const plotArea = async (props: any) => {
    ...

    // Handler for the end of a brush event from D3.
    const brushEnded = (event: any) => {
      const s = event.selection;
      // Consume the brush action
      if (s) {
        d3.select('.brush').call(brush.move, null);
      }
    }

    // Create a brush for selecting regions to zoom on.
    const brush: any = d3
      .brushX()
      .extent([
        [0, 0],
        [width, height - 1],
      ])
      .on('end', brushEnded);

    // Zoom brush
    svg.append('g').attr('class', 'brush').call(brush);
}


useEffect(() => {
    // plotArea() occurs for each graph, there are multiple graphs
    plotArea(...);
    ...

}, []);

标签: reactjsd3.js

解决方案


当 d3 在 中运行选择时d3.select('.brush').call(brush.move, null);,它不会将搜索限制在组件中。它将在整个文档中搜索一个.brush元素,并在找到第一个元素后立即停止。

作为快速修复,您可以保存组件的特定画笔,这样您就已经有了参考,并且不需要运行 ad3.select来取回它:

const plotArea = async (props: any) => {
    ...

    // Create brushElement first
    const brushElement = svg.append('g').attr('class', 'brush');
    
    // Handler for the end of a brush event from D3.
    const brushEnded = (event: any) => {
      const s = event.selection;
      // Consume the brush action
      if (s) {
        brushElement.call(brush.move, null); // Now uses the variable
      }
    }

    // Create a brush for selecting regions to zoom on.
    const brush: any = d3
      .brushX()
      .extent([
        [0, 0],
        [width, height - 1],
      ])
      .on('end', brushEnded);

    
    brushElement.call(brush);

}

推荐阅读