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

D3.js v6:缩放平移下线条跟随光标及事件绑定差异问题

D3 v6 鼠标事件与缩放平移相关问题

运行D3 v6版本。
这是一个多部分技术问题,在实现需求时遇到了D3鼠标事件相关疑问。示例代码中按下ESC键可清除线条绘制行为。

问题列表

  • 如何实现从节点到光标位置的线条绘制,使其不受缩放级别和平移位置影响?
  • 为何将.on('mousemove')绑定到svg元素与g元素时,绘制的线条表现不同?

问题1详情

当前遇到的问题是,平移和缩放操作后,线条终点无法准确跟随光标,原因是被缩放的容器进行了x和y轴平移。放大后点击节点即可复现该问题。

未进行缩放平移时,线条可正常跟随光标。已通过d3.zoomTransform()获取当前[x,y]偏移量解决了平移问题,但无法适配缩放级别。尝试使用transform(scale(zoomLevel.k))效果不佳。复现步骤:

  • 无缩放平移时点击节点,线条跟随光标;
  • 缩放后点击节点,线条无法跟随。

问题2详情

曾尝试将鼠标事件绑定到用于缩放定位的g元素而非父svg元素来解决上述问题。此时线条可在任意缩放平移下跟随光标,但出现严重卡顿,不清楚原因。

代码概述

let sourceNode;

const svg = d3.select("#chart")
  .attr("viewBox", [0, 0, width, height]);
const g = svg.append('g');
const drawLine = g.append('line').attr('stroke', 'red').attr('stroke-width', 5).attr('visibility', 'hidden')
const nodes = g.append(//do node stuff)
const links = g.append(//do link stuff)

svg.call(d3.zoom().on('zoom', (event) => {
    g.attr('transform', `translate(${event.transform.x}, ${event.transform.y}) scale(${event.transform.k})`)
  }))

node.on('click', (event, d) => {
    sourceNode = d
})

svg.on('mousemove', (event) => {
  if (sourceNode) {
  const currentZoom = d3.zoomTransform(svg.node());
    drawLine
      .attr('visibility', 'visible')
      .attr('x1', sourceNode.x)
      .attr('y1', sourceNode.y)
      // Remove the currentZoom offset and observe the line being jank
      .attr('x2', d3.pointer(event)[0] - currentZoom.x)
      .attr('y2', d3.pointer(event)[1] - currentZoom.y);
  }
})

内容的提问来源于stack exchange,提问作者Syed Jafri

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 09:45:28