如何解决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()
);
解决方法
添加:
container.selectAll(".tt-header").remove();
之前:
const header = container.append("div").attr("class","tt-header");
这是一个 fixed sandbox。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。