当v2没有实现缩放时,为什么d3.js v3会破坏我的力图?

Mat*_*bst 37 javascript svg d3.js force-layout

我有一个使用d3.js创建的强制布局

我想同时拥有可拖动力布局的正常功能以及缩放功能.

我基本上复制/粘贴了这个(http://jsfiddle.net/nrabinowitz/QMKm3/)代码的缩放代码.这与Mike Bostock在此(http://bl.ocks.org/mbostock/3680957)示例中使用的缩放方式相同.

这是我的代码:http://jsfiddle.net/kM4Hs/6/

从我的中可以清楚地看到,缩放工作正常,但我无法在力布局中选择单个节点并拖动它们.

我发现其他作者使用d3.v2.js而不是我正在使用的较新的d3.v3.js这个事实.当我将导入更改为v2时,它可以完美运行.但是,为了进步和一般良好的代码,我想尽可能使用v3.

<script type='text/javascript' src='http://d3js.org/d3.v3.min.js'></script>
Run Code Online (Sandbox Code Playgroud)

两个问题:为什么v3在v2没有时打破了力布局,更重要的是,我能做些什么,如果有的话,修复它?

提前致谢!

mbo*_*ock 81

如果您仔细阅读发行说明,您将看到2.x(2.10.3)的最终版本与最新版本3.2.7之间所有内容发生变化的完整说明.特别是从版本3.2.2开始:

通过不阻止默认行为或停止传播,更好地处理d3.behavior.drag,d3.behavior.zoom和d3.svg.brush中的拖动手势.例如,mousedown现在更改焦点,iframe外部的mouseup正常工作,touchstart不会断断续续.

因此,在V2​​中,通过停止缩放事件的传播,拖动行为可以优先于缩放行为.在V3中,这不再自动发生,让您可以选择哪种行为优先,何时.

如果要在拖动节点时赋予拖动行为优先级,则需要在拖动时对输入事件执行stopPropagation,以便这些事件不会被缩放行为同时解释为平移.停止在dragstart上传播就足够了:

var drag = d3.behavior.drag()
    .on("dragstart", function() { d3.event.sourceEvent.stopPropagation(); })
    .on("drag", function() { /* handle drag event here */ });
Run Code Online (Sandbox Code Playgroud)

如果使用强制布局,则代码为:

var drag = force.drag()
    .on("dragstart", function() { d3.event.sourceEvent.stopPropagation(); });
Run Code Online (Sandbox Code Playgroud)

工作范例:

拖动和缩放

注意:组合这两种行为意味着手势解释模糊不清并且对位置高度敏感.单击圆圈将被解释为拖动该圆圈,而单击一个像素可以将其解释为平移背景.结合这些行为的更稳健的方法是采用模态.例如,如果用户按住SPACE键,则无论点击位置如何,单击和拖动都将被解释为平移,而不是拖动.这种方法通常用于商业软件,如Adobe Photoshop.

  • 看一下[粘力布局示例](http://bl.ocks.org/mbostock/3750558/5093e88c0462173a3d7b5859d7db75fbf5a7d8b8)和[force.drag]的文档(https://github.com/mbostock/d3/维基/强制布局#维基拖动).我刚刚更新了它们. (6认同)
  • 我也遇到了力布局的问题.从阅读@mbostock发布的链接,我的答案是从`force.drag`而不是`d3.behavior.drag创建`var drag`. (4认同)