d3.js:放大点击事件

d3.js: Zoom on click event

本文关键字:事件 放大 js d3      更新时间:2023-09-26

我试图得到相同的行为威尔林森的实现但在d3.js版本4。我对版本4中的缩放api很困惑。

我在原始实现中所做的更改是:zoom.translate()替换为d3.zoomTransform(selection.node())和适当的点添加代替:

svg.attr("transform",
    "translate(" + t.x + "," + t.y + ")" +
    "scale(" + t.k + ")"
);
这个

:

zoom
  .scale(iScale(t))
  .translate(iTranslate(t));

替换

var foo = iTranslate(t);
zoom.
  translateBy(selection, foo[0], foo[1]);
zoom
  .scaleBy(selection, iScale(t));

但它仍然有一个问题,看起来像缩放,缩小…

示例:以d3为例。V4 - jsfiddle

Thanks for the help

在研究了最简单的方法后,使用d3 v4 api,提供插值等开箱即用。在从头开始实现的原始问题缩放中,这在版本4中没有意义。解决方案类似于@Nixie的答案,并且只有几行代码。

这个版本包括pan,如果你不需要,删除svg.call(zoom);

最后一个例子:Zoom D3 v4 - jsfiddle

一个有趣的提示:功能:

function transition() {
  svg.transition()
      .delay(100)
      .duration(700)
      .call(zoom.scaleTo, zoomLevel);
      //.on("end", function() { canvas.call(transition); });
}

call(zoom.ScaleTo, zoomLevel) -将缩放到页面中心。但如果你需要一个图像的中心,使用这个:call(zoom.transform, transform);

其中transform是设置图像中心的函数。函数示例:

function transform() {
  return d3.zoomIdentity
      .translate(width / 2.75, height / 2.75)
      .scale(zoomLevel)
      .translate(-width/2.75, -height/2.75);
}

这段代码并不能解决所有问题,但可以作为一个起点。在D3 v4中,您可以在一行代码中过渡缩放(参见https://github.com/d3/d3-zoom/blob/master/README.md#zoom_transform)

function interpolateZoom (translate, scale) {
    return selection.transition().duration(350)
              .call(zoom.transform, 
                    d3.zoomIdentity.translate(translate[0], translate[1]).scale(scale))
}

修改示例:https://jsfiddle.net/2yx1cLrq/。此外,在对d3.zoomTransform

的所有调用中,您需要用selection.node()替换selection

我使用了Angular,在我看来,它是目前为止最简单、最干净的。我已经有了滚动缩放的行为,添加鼠标点击很容易。请注意,我使用ES6模块导入我的d3函数。例子:

import { event as d3event, zoom, scaleExtent, selectAll, transition, duration } from 'd3';

我现有的缩放(鼠标滚动)

this.zoom = zoom().scaleExtent([1, 8]).on('zoom', this.zoomed.bind(this));
// this.chart is my map chart svg created by d3
this.chart.call(this.zoom)
zoomed() {
// this.g is a <g> element appended to the chart that contains all countries in my case.
    this.g
      .selectAll('path') // To prevent stroke width from scaling
      .attr('transform', d3event.transform);
  }

缩放按钮添加的内容:

<!-- My markup -->
<button (click)="zoomClick(1.5)">Zoom in</button>
<button (click)="zoomClick(0.5)">Zoom out</button>
zoomClick(level): void {
  this.chart.transition().duration(200).call(this.zoom.scaleBy, level);
}