d3.js:单击事件缩放

6

我试图在d3.js版本4上实现与Wil Linssen实现的相同行为,但是我对版本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

谢谢帮助。

3个回答

3

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

此版本还包括平移功能,如果您不需要,请删除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);
}

2

这段代码并不能解决所有问题,但可以作为一个起点。在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替换为selection.node()


为了让代码更简洁,我想你可以省略 var self = this; 这句话。 - mgc

0

我已经使用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);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接