我试图获得相同的行为Wil Linssen's implementation 但是在d3.js版本4上。 我对版本4中的zoom 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));
但它仍有问题,看起来像是缩放,缩小......
示例:Example on d3.v4 - jsfiddle
感谢您的帮助
答案 0 :(得分: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);
}
答案 1 :(得分: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/。此外,您需要在selection
的所有来电中将selection.node()
替换为d3.zoomTransform
答案 2 :(得分: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);
}