且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

D3.js缩放和平移可折叠树图

更新时间:2022-12-24 12:38:38

可以在这里查看(大部分)工作实施: http://jsfiddle.net/nrabinowitz/fF4L4/2/

You can see (most of) a working implementation here: http://jsfiddle.net/nrabinowitz/fF4L4/2/

这里的关键部分:


  • 致电 d3.behavior.zoom()。这需要 svg 元素具有 pointer-events:all 设置。你也可以在子元素上调用它,但是如果你想让整个事物进行平移和缩放,我看不到一个原因,因为你基本上希望整个SVG区域响应平移/缩放事件。

  • Call d3.behavior.zoom() on the svg element. This requires the svg element to have pointer-events: all set. You can also call this on a subelement, but I don't see a reason if you want the whole thing to pan and zoom, since you basically want the whole SVG area to respond to pan/zoom events.

d3.select("svg")
    .call(d3.behavior.zoom()
      .scaleExtent([0.5, 5])
      .on("zoom", zoom));


  • 设置 scaleExtent 限制缩放比例的能力。您可以将其设置为 [1,1] 完全禁用缩放,或者将其设置为内容的最大大小(如果这是您想要的)

  • Setting scaleExtent here gives you the ability to limit the zoom scale. You can set it to [1, 1] to disable zooming entirely, or set it programmatically to the max size of your content, if that's what you want (I wasn't sure exactly what was desired here).

    缩放函数与您的 dragmove 函数,但包括缩放因子并设置对平移偏移的限制(据我所知,d3没有任何内置的 panExtent support):

    The zoom function is similar to your dragmove function, but includes the scale factor and sets limits on the pan offset (as far as I can tell, d3 doesn't have any built-in panExtent support):

    function zoom() {
        var scale = d3.event.scale,
            translation = d3.event.translate,
            tbound = -h * scale,
            bbound = h * scale,
            lbound = (-w + m[1]) * scale,
            rbound = (w - m[3]) * scale;
        // limit translation to thresholds
        translation = [
            Math.max(Math.min(translation[0], rbound), lbound),
            Math.max(Math.min(translation[1], bbound), tbound)
        ];
        d3.select(".drawarea")
            .attr("transform", "translate(" + translation + ")" +
                  " scale(" + scale + ")");
    }
    

    (说实话,我不认为我的逻辑非常正确在这里为正确的左和右阈值 - 这似乎并不限制拖动正确放大时。作为练习为读者:)。)

    (To be honest, I don't think I have the logic quite right here for the correct left and right thresholds - this doesn't seem to limit dragging properly when zoomed in. Left as an exercise for the reader :).)

    为了使这里的操作更简单,它有助于使 g.drawarea 元素没有初始转换 - 所以我添加了另一个 g 元素到外部包装器设置边距补偿:

    To make things simpler here, it helps to have the g.drawarea element not have an initial transform - so I added another g element to the outer wrappers to set the margin offset:

    vis // snip
      .append("svg:g")
        .attr("class","drawarea")
      .append("svg:g")
        .attr("transform", "translate(" + m[3] + "," + m[0] + ")");
    


  • 使你的代码在JSFiddle中更好的工作。这里有一些缺失的细节,但希望这足以让你开始。

    The rest of the changes here are just to make your code work better in JSFiddle. There are a few missing details here, but hopefully this is enough to get you started.