D3 缩放事件在 Angular 中拖动时触发

Nei*_*rty 4 javascript svg d3.js angular


太棒了;拖动 SVG 会导致其旋转和平移。


我正在尝试使用 D3 (v.4) 作为 Angular 服务的一部分在 SVG 组上实现拖动和缩放事件。

this.unitGroup = this.svg.append('g')
  .attr('id', 'unitGroup')
  .call(this.drag)
  .call(this.zoom);
Run Code Online (Sandbox Code Playgroud)

拖动可平移 SVG。

drag = d3.drag()
.on('start', () => {
  console.log('drag start');
  this.setClickOrigin(d3.event);
})
.on('drag', (d, i, n) => {
  const target = d3.select(n[i]).node() as any;
  const m = target.getCTM();
  const x = d3.event.x - this.clickOrigin.x;
  const y = d3.event.y - this.clickOrigin.y;
  this.setClickOrigin(d3.event);
  this.translate(target, x, y);
});
Run Code Online (Sandbox Code Playgroud)

缩放时会旋转 SVG。

zoom = d3.zoom()
.on('zoom', (d, i, n) => {
  const target = d3.select(n[i]).node() as any;
  const m = target.getCTM();
  const b = target.getBBox();
  const dir = (d3.event.sourceEvent.deltaY > 0) ? 1 : -1;
  this.rotate(target, dir);
});
Run Code Online (Sandbox Code Playgroud)

我原来的代码工作得很好。然而,将其集成到 Angular 中却引发了一些问题。

当前的问题是,当您拖动它时,它会随着事件一起unitGroup触发该事件。zoomdrag

预期的行为是:

  • “单击并拖动”会在 x 和 y 维度上平移深灰色小框。
  • “鼠标滚轮滚动”使深灰色的小框绕其中心旋转。

这是一个笨蛋:https ://embed.plnkr.co/0GrGG7T79ubpjYa2ChYp/

Ger*_*ado 5

实际上,您在这里看到的是预期的行为。

在 D3 中,d3.zoom()不仅处理缩放,还处理平移。d3.drag()因此,鼠标移动也由缩放功能处理。

正如 Bostock(D3 创建者)曾经说过的:

结合这两种行为*意味着手势解释是不明确的并且对位置高度敏感。(*缩放和拖动)

在我的脑海中,最简单的解决方案就是检查缩放功能中是否有“真正的”缩放(鼠标滚轮),如果没有(没有鼠标滚轮),则返回:

if(!d3.event.sourceEvent.deltaY) return;
Run Code Online (Sandbox Code Playgroud)

这是您仅进行了更改的插件:https://plnkr.co/edit/jz5X4Vm9wIzbKmTQLBAT ?p=preview

  • 事实上,d3.js 库中有“stopImmediatePropagation()”。但是 Angular 在处理它时存在一些问题 https://github.com/angular/angular/pull/19222 这也是 zone js 问题 例如让我们看看示例 https://jsfiddle.net/hv5tLx9L/ 然后包含 zonejs https ://jsfiddle.net/08jzzjd5/ (2认同)
  • 提交https://github.com/angular/zone.js/commit/dcc285aab37bdd90b6d7133fc73045100861c61c已合并,所以也许只需要等待新版本的zonejs (2认同)