d3.js 重写 version4 中的缩放示例

2024-02-19

拖放示例 http://bl.ocks.org/robschmuecker/7880033

我正在尝试重写上面示例的一部分以在我的代码中使用,特别是这一部分:

function centerNode(source) {
        scale = zoomListener.scale();
        x = -source.y0;
        y = -source.x0;
        x = x * scale + viewerWidth / 2;
        y = y * scale + viewerHeight / 2;
        d3.select('g').transition()
            .duration(duration)
            .attr("transform", "translate(" + x + "," + y + ")scale(" + scale + ")");
        zoomListener.scale(scale);
        zoomListener.translate([x, y]);
    }

然而,由于 v4 包发生了很大的变化,我陷入了困境。我将 ZoomListener 函数编写为

    var zoomListener = d3.zoom()
                 .scaleExtent([0.3,2])
                 .on("zoom", zoomed);

    function zoomed() {
       transform = d3.event.transform;
       console.log(d3.event);
         svg.attr("transform", transform);
    } 

function centerNode(source){
  t = transform;
  console.log(t);
  x = t.x*t.k; //I only want things to be centered vertically
  y = (t.y + -source.x0)*t.k + (viewerHeight)/2 ;
  svg.transition()
     .duration(duration)
     .attr("transform","translate(" + x + "," + y +")scale(" + t.k + ")");

  transform.scale(t.k); //DOES NOT WORK
  transform.translate([x, y]); //DOES NOT WORK

}

我知道根据文档,事情已经发生了变化,信息不再存储在我的 ZoomListener 上D3 V4 关于变焦的发行说明 https://github.com/d3/d3/blob/master/CHANGES.md#zooming-d3-zoom我想我只是对新版本应该如何做感到困惑。我的 centerNode 函数的最后几行不起作用,当我将节点居中时,缩放和平移会重置......

有什么建议吗?


因此,经过多次挖掘和反复试验,我得出了一个非常适合我的目的的答案。请注意,下面的代码只是我的代码的相关部分,而不是整个代码,某些变量是不言自明的,因此没有包含它们。这也是 d3.js 的第 4 版。

var zoom = d3.zoom()
             .scaleExtent([0.3,2])
             .on("zoom", zoomed);


var svg = d3.select("body")
            .append("svg")
              .attr("width", viewerWidth)
              .attr("height", viewerHeight);

var zoomer = svg.append("rect")
                .attr("width", viewerWidth)
                .attr("height", viewerHeight)
                .style("fill", "none")
                .style("pointer-events", "all")
                .call(zoom);

var g = svg.append("g");

zoomer.call(zoom.transform, d3.zoomIdentity.translate(150,0)); //This is to pad my svg by a 150px on the left hand side

function zoomed() {
  g.attr("transform", d3.event.transform);//The zoom and panning is affecting my G element which is a child of SVG
}

function centerNode(source){

  t = d3.zoomTransform(zoomer.node());
  console.log(t);

  x =  t.x;
  y = source.x0;

  y = -y *t.k + viewerHeight / 2;

  g.transition()
   .duration(duration)
   .attr("transform", "translate(" + x + "," + y + ")scale(" + t.k + ")")
   .on("end", function(){ zoomer.call(zoom.transform, d3.zoomIdentity.translate(x,y).scale(t.k))});


}

根据 d3.js 页面上 v4 的示例,我使用了一个矩形来应用缩放

缩放行为应用于覆盖 SVG 的不可见矩形 元素;这确保它接收输入,并且指针 坐标不受缩放行为变换的影响。平移和缩放示例 http://bl.ocks.org/mbostock/4e3925cdc804db257a86fdef3a032a45

在我正在使用的中心节点功能中d3.zoomTransform(zoomer.node());获取应用于页面的当前变换。 这个函数的目的只是使可折叠树垂直居中而不是水平居中,所以我保留当前的transform.x(这里t.x) 相同。 我的 svg 中的坐标是翻转的,所以为什么y= source.x0,源是我的可折叠树中单击的节点。 (“查看本线程顶部引用的示例,了解我试图转换为版本 4 的内容)

我将转换应用于我的 G 元素,然后我想将这些更改提交到缩放转换,为此我使用.on("end", function(){})否则它会在转换中做出奇怪的行为,通过这样做它所做的只是设置转换的当前状态。

zoomer.call(zoom.transform, d3.zoomIdentity.translate(x,y).scale(t.k))

上面这一行将 x 和 y 的平移以及比例(等于当前状态)应用于单位矩阵,以获得 G 的新变换,然后将其应用于zoomer这是我称之为的元素zoom早些时候。

这对我来说就像一个魅力!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

d3.js 重写 version4 中的缩放示例 的相关文章

随机推荐