如何关联两个SVG元素,实现鼠标悬停一个时联动另一个?
解决方案
因为你已经把文本和矩形放在同一个<g>容器里了,直接通过矩形的父元素定位对应文本是最高效的方式,不用全局遍历所有文本元素。
修改你的事件处理代码如下:
settings.g.selectAll(".labels") .data(data) .join( enter => { let g = enter.append("g"); let text = g.append("text") .text(d => d.name) // 初始设置默认字体样式 .style("font-weight", "normal"); let rect = g.append("rect") .attr("width", (d) => d.bbox.width) .attr("height", (d) => d.bbox.height) .attr("fill", "transparent") .on('mouseover', function () { // 通过父g元素直接找到对应的text d3.select(this.parentNode).select("text") .style("font-weight", "bold"); }) .on('mouseout', function () { // 鼠标移出后恢复样式 d3.select(this.parentNode).select("text") .style("font-weight", "normal"); }); } );
为什么这种方式高效?
- 无需全局调用
selectAll("text")遍历所有文本元素,而是通过DOM的父子关系直接定位到当前矩形对应的文本,时间复杂度是O(1),数据量越大优势越明显。 - 利用D3的事件上下文
this(指向当前触发事件的rect元素),通过parentNode拿到共同的父容器<g>,再在这个容器内选择唯一的text元素,精准且快速。
如果担心容器内有其他text元素干扰,可以在创建text时添加专属类名,进一步明确选择范围:
// 创建text时添加类名 let text = g.append("text") .attr("class", "label-text") .text(d => d.name); // 事件处理时指定类名选择 d3.select(this.parentNode).select(".label-text")
内容的提问来源于stack exchange,提问作者Tania
相关产品推荐
相关产品推荐

