我有一个使用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>
与
<script type='text/javascript' src='http://d3js.org/d3.v2.min.js'></script>
为什么v3在v2没有时会破坏强制布局,更重要的是,我该怎么做才能解决它?
提前致谢!
答案 0 :(得分:81)
如果您仔细阅读release notes,您将看到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 */ });
如果使用强制布局,则代码为:
var drag = force.drag()
.on("dragstart", function() { d3.event.sourceEvent.stopPropagation(); });
工作示例:
注意:结合这两种行为意味着手势解释模糊且对位置高度敏感。单击圆圈将被解释为拖动该圆圈,而单击一个像素可以将其解释为平移背景。结合这些行为的更稳健的方法是采用模态。例如,如果用户按住SPACE键,则无论点击位置如何,单击和拖动都将被解释为平移,而不是拖动。这种方法通常用于商业软件,如Adobe Photoshop。