You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何关联两个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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 11:07:11