D3 + React hooks + useEffect() - 防止在 mouseout

如何解决D3 + React hooks + useEffect() - 防止在 mouseout

大家好,这里有一个有趣的 D3、topojson 和 React 钩子。

我想删除在鼠标悬停时创建并在鼠标悬停时持续存在的工具提示实例——使用 D3 的“反应钩子”方式是使用 useEffect(),svg 是用useRef(),这工作正常,但每个连续的鼠标悬停事件都会触发一个新的 .append,它会添加一个 div,因此工具提示内容只会不断堆积。

我认为使用 D3 的 selection.join() 可能是处理此问题的方法,但尚未奏效。我确实考虑过在 React 中实现一个完全独立的工具提示组件,该组件与图表组件共享上下文,但首先我希望有人可能知道如何使用 D3 做到这一点,因为它很接近。

如何在使用 D3 鼠标移出时删除使用 div 添加的“额外”.append 内容

Working example on Codesandbox here.

相关代码

    svg
      .append("g")
      .selectAll("path")
      .data(features)
      .join(
        (enter) =>
          enter
            .append("path")
            .attr("fill",(d) =>
              colorScale(turnoutPerc.get(d.properties.GEOID))
            )
            .attr("d",path)
            .on("mouSEOver",(event,d) => {
              d3.select(event.currentTarget)
                .raise()
                .style("stroke","#000")
                .style("stroke-width",2)
                .style("cursor","pointer");
              event.preventDefault();
              let [x,y] = d3.pointer(event);
              let ttPos = positionTooltip(x,y);
              let countyData = {
                showTT: true,FIPS: d.properties.GEOID,mouse: { x: ttPos.x,y: ttPos.y }
              };
              updateCurrentCounty(countyData);
              let countyProps = getCountyProps(countyData,data);
              container
                .style("visibility","visible")
                .style("top",() => {
                  let ttHeight = 400;
                  if (y < ttHeight / 2) {
                    return event.pageY - 50 + "px";
                  } else if (y >= ttHeight / 2 && y < height - ttHeight / 2) {
                    return event.pageY - ttHeight / 2 + "px";
                  } else {
                    return event.pageY - ttHeight + "px";
                  }
                })
                .style("left",event.pageX + 60 + "px");

                // Header
                const header = container
                  .append("div")
                  .attr("class","tt-header");
                const location = header
                  .append("div")
                  .attr("class","tt-location");
                location
                  .append("h1")
                  .attr("class","tt-county")
                  .html(countyProps.countyName);
                location
                  .append("h2")
                  .attr("class","tt-state")
                  .html(countyProps.state);
            })
            .on("mouSEOut",d) => {
              updateCurrentCounty({
                showTT: false,FIPS: null
              });
              d3.select(event.currentTarget)
                .style("stroke","none")
                .style("cursor","default");
            }),(update) => update.call((update) => update.transition(t)),(exit) => exit.remove()
      );

enter image description here

解决方法

添加:

container.selectAll(".tt-header").remove();

之前:

const header = container.append("div").attr("class","tt-header");

这是一个 fixed sandbox

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?