javascript - d3 强制 : Making sense of data binding

标签 javascript d3.js

我可以重新创建以下 1000 次,并且有足够的理解力来这样做。但我正在努力了解我只是“做”而不是理解的一些特定部分:

var w = 900,
    h = 500;

var svg = d3.select("body").append("svg")
    .attr("width", w)
    .attr("height", h)
    .attr("style", "border: 1px solid grey;")
    .on("mousemove", fn)

var force = d3.layout.force()
    .size([w, h])
    .on("tick", tick)
    .gravity(0)
    .charge(0)
    .start()

function fn() {

    var m = d3.mouse(this); 
    var point = {x: m[0], y: m[1]};
    d3.select("#output").text(force.nodes().length)     

    var node = svg
        .append("circle")
            .data([point])
            .attr("cx", function(d) {return d.x})
            .attr("cy", function(d) {return d.y})
            .attr("r", 0.1)
            .transition().ease(Math.sqrt)
            .attr("r", 5)
            .transition().delay(1000)
            .each("end", function() {
                force.nodes().shift()
            })
            .remove()   

    force.nodes().push(point)   
    force.start()
}

function tick() {
    svg.selectAll("circle")
        .attr("cx", function(d) {return d.x})
        .attr("cy", function(d) {return d.y})
}

特别是我不确定的数据绑定(bind)部分。

在函数 fn() 中(在 svg 空间的 mousemove 上)我们定义了一个新点,我们需要用它做两件事;将其插入 force.nodes() 以便可以通过力布局中配置的力来操纵点的 x 和 y 坐标,我们需要使用点的坐标来创建和操纵可视化。

所以我们首先创建点。然后我们建立一个圆圈来表示这个点。我们将点插入 force.nodes() 并在短暂延迟后,从 force.nodes() 数组中删除可视化和点。

我不明白的一点是可视化和数组中的点如何保持“连接”?

猜想:数据点是力布局不断更新其x和y属性的对象。这个对象有一个“链接”绑定(bind)到 circle 元素。因此,该对象很容易被 circle 对象访问和使用,但并非没有我们控制该过程。圆被定义为在其创建时具有 cx 和 cy,但我们需要不断访问底层数据以更新其 cx 和 cy?

如果是这样,对象是如何被 force.nodes() 和 circle 元素“共享”的?

还是我离题太远了?

此外,我已经阅读了很多关于此的文档,但我觉得这是 javascript 而不是 d3 所必需的更固有的东西,因此在我迄今为止阅读的任何文献中都没有详细说明。

最佳答案

强制布局更新的数据结构与可视化(即 DOM 元素)之间的链接是 tick 事件处理函数。 tick 事件由力布局生成,表示力模拟已经进行了另一步(即 tick)并且其内部状态已更改。这表明可视化需要更新。

实现此链接有两个部分。首先,强制布局操作的数据(即链接和节点)需要绑定(bind)到 DOM 元素。这是使用通常的 .selectAll().data().enter().append() 模式完成的,通常在初始化代码中,有时在 tick 事件处理程序中功能。这在数据和 DOM 元素之间建立了联系。

第二部分是在强制布局更改其位置时更新 DOM 元素的代码。这就是 tick 事件处理函数中发生的事情。如果您不添加或删除元素,通常不需要重新绑定(bind)数据,并且通常您不会看到 .selectAll().data() 模式,而只会看到实际更新的代码基于已经绑定(bind)到元素的数据的位置(在您的情况下,即使您正在更改元素,这仍然有效,因为数据绑定(bind)发生在更新强制布局数据的函数中)。

作为实验,以任意力布局为例,删除 tick 事件处理函数——您会发现即使力布局正在运行,也没有任何反应。

关于javascript - d3 强制 : Making sense of data binding,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30153383/

相关文章:

javascript - JavaScript 中的简单 3D 粒子重力?

jquery - d3 相当于 jQuery Parent()

javascript - D3 自定义曲线 : bundle interpolation for areas

javascript - ES15 导入一个库作为另一个库的插件

javascript - 从 csv 数据创建哈希表/字典

JavaScript getElementById(...) 为 null 或不是对象 IE

javascript - 未定义不是对象(评估 '_this.props.navigation' )

javascript - React-native & d3 选择库

javascript - 如何检查函数是否已执行?

javascript - 可丢弃重新启用 - Jquery