【问题标题】:Understanding "call" in D3.js with force-directed layouts使用强制导向布局理解 D3.js 中的“调用”
【发布时间】:2014-05-17 06:23:39
【问题描述】:

我是 D3.js 的新手,我想使用图形布局。我用一个非常简单的图表设置了这个演示,它遵循 D3 中内置的力导向布局。

http://jsfiddle.net/ewG95/

我想要做的是能够关闭图形布局算法(例如,当用户按空格键时)然后仍然能够拖动节点,并转向力导向稍后重新布局。

现在我已经将它设置为在击中空间时停止强制导向布局:

d3.select("body")
   .on("keydown", function() { 
     if (d3.event.keyCode == 32) { 
        if (forceActive) {force.stop();} else {force.resume();} 
     } 
   });

问题是每次拖动节点时都会重新启动强制布局。我已经将其范围缩小到(基本上)节点上的调用方法被绑定到强制布局的拖动方法。

即这段链接代码:

var node = svg.selectAll(".node")
     .data(graph.nodes)
   .enter().append("circle")
     ...
     .call(force.drag);

我想我可能需要做两件事:

  1. 编写一个自定义的“拖动”方法来移动一个节点以及与单个节点关联的边。
  2. 根据需要将节点的调用方法重新绑定到它(这是否有意义?这会取代绑定的方法吗?而 force.drag 的真正作用是什么?)。

我想知道这是否以前做过,以及如何去做(完全可能没有用我的猜测来做这件事)。

【问题讨论】:

    标签: javascript d3.js drag force-layout


    【解决方案1】:

    首先,关于您的明确问题:call() 方法有什么作用?

    在 d3 中,call 只是一个方便的函数,可以将其他函数从里到外。正在做

    node.call( force.drag );
    

    其实和做的一样

    force.drag( node );
    

    唯一的区别是选择上的call 方法总是返回选择,因此您可以将其他方法链接到它。

    所以现在你的问题是,force.drag( selection ) 是做什么的?它创建事件侦听器来处理拖动行为的鼠标和触摸事件。这些事件监听器会更新节点数据对象的位置,但它们也会重新启动强制布局。

    如果您不想要默认的强制布局拖动行为,请不要在您的选择上调用 force.drag 方法。

    就能够自定义拖动行为以使其不会重新启动强制布局而言,您似乎无法使用force.drag 来做到这一点(无论如何都不能不更改源代码)。 但是,您可以通过创建自己的 drag behaviour object 并将其绑定到节点来访问大多数与拖动相关的功能。

    然后,在您的拖动事件处理程序中,您将更新节点数据对象的 x 和 y 位置,并重新绘制节点和附加到它的任何链接。如果您的图表不是太大,您可以通过重新调用tick 函数来重新绘制所有元素以匹配它们的数据;如果您的图表 很大,您可能希望在数据对象中存储对实际元素的引用,以便您可以快速找到正确的链接。

    一些关于使用拖动行为(无强制布局)来帮助您入门的示例:

    【讨论】:

    • 看起来不错。我很高兴能开始。
    猜你喜欢
    • 2012-10-21
    • 1970-01-01
    • 2013-06-25
    • 1970-01-01
    • 2016-06-05
    • 2017-03-02
    • 2013-07-15
    • 2013-02-12
    • 1970-01-01
    相关资源
    最近更新 更多