繁体   English   中英

手动设置平移和缩放后,在d3 v4中更新缩放状态

[英]Update zoom state in d3 v4 after manually setting translation and scale

这可能已经被问过很多次了,但是作为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;
  }

我已经尝试了两天的不同解决方案,但是无法正常工作。

任何帮助都超过赞赏!

长时间后,我找到了解决方案。 在我的selectFeature函数中,我应该更新缓存的缩放状态,而不是直接设置transform属性。 该解决方案的好处在于,它将触发缩放事件,该事件将更新已经设置的缩放功能中的UI。

此处的工作示例: https : //codepen.io/brunofenzl/pen/zWmoWJ

为了更新缓存的转换,我使用了自述文件中所述的d3.zoomIdentity

var 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)
  );

这种技术的缺点是,范围约束无法再按预期工作,因此,例如,如果您的范围小于新的缩放比例,则下次拖动或缩放时,缩放比例将跳至您的范围允许的下一个可能的缩放值。 我已解决此问题,因为现在禁用了缩放范围。 我希望这对其他人有帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM