这可能已被多次询问,但作为d3中的血腥菜鸟,我无法得到明确的解决方案。
我有一张点在其上传播的地图。当我点击一个点我想要缩放并平移到它。到目前为止一切都那么好,但是当我尝试再次拖动或缩放时,它会重置为zoomIdentity而不保留我手动设置的值。
编辑:这是一个有效的演示:https://codepen.io/brunofenzl/pen/pLxbjZ
我的代码的相关部分:
// zoom initialization
this.zoom = d3.zoom()
.scaleExtent([1, 2])
.translateExtent([[0, 0], [width, height]])
.on('zoom', this.zoomed);
// zoom listener
Map.prototype.zoomed = function zoomed() {
if (d3.event) {
this.view.attr('transform', d3.event.transform);
}
}
// the function that zooms in
Map.prototype.selectFeature = function selectFeature(el) {
this.active = d3.select(el);
const bounds = this.active.node().getBBox();
const dx = bounds.width;
const dy = bounds.height;
const x = bounds.x + (bounds.width / 2);
const y = bounds.y + (bounds.height / 2);
const scale = Math.max(1, Math.min(8, 0.9 / Math.max(dx / this.width, dy / this.height)));
const translate = [(this.width / 2) - (scale * x), (this.height / 2) - (scale * y)];
this.view.transition()
.duration(750)
.attr("transform", "translate(" + translate + ")scale(" + scale + ")");
return null;
}
我已经尝试了两天不同的解决方案,但无法使其正常工作。
任何帮助超过赞赏!
答案 0 :(得分:0)
经过很长一段时间我找到了解决方案。 在我的selectFeature函数中,我应该更新缓存的缩放状态,而不是直接设置transform属性。此解决方案的优点是,这将触发缩放事件,该事件将更新已设置的缩放功能中的UI。
这里的工作示例:https://codepen.io/brunofenzl/pen/zWmoWJ
要更新缓存的转换,我使用了readme
中所述的d3.zoomIdentityvar t = d3.zoomIdentity.translate(x, y).scale(k);
因此,我的修改后的代码是:
this.view.transition()
.duration(750)
.call(
this.zoom.transform,
d3.zoomIdentity.translate(translate[0], translate[1]).scale(scale)
);
此技术的缺点是范围约束不再按预期工作,因此如果您的范围小于新的缩放比例,则下次拖动或缩放时,缩放将跳转到下一个可能的缩放值你的程度。我解决了这个现在禁用缩放范围。 我希望这有助于其他人。