37

我有一个使用 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 没有打破强制布局的情况下,更重要的是,我能做些什么来修复它?

提前致谢!

4

1 回答 1

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 中,这不再自动发生,您可以选择哪种行为优先,何时优先。

如果要在拖动节点时赋予拖动行为优先级,则需要在拖动时停止输入事件的传播,以便这些事件不会同时被缩放行为解释为平移。在 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 键,则单击和拖动将被解释为平移,而不是拖动,无论单击位置如何。这种方法通常用于商业软件,例如 Adob​​e Photoshop。

于 2013-07-31T16:44:53.767 回答