javascript - d3 : Adding and removing force. 基于 slider 值的节点

标签 javascript d3.js

一段时间以来,我在根据用户输入添加和删除节点时遇到了一些困难,每次用户从复选框列表中选择他们想要查看的对象时,我都会通过更新插入 force.nodes() 的整个对象集来解决这个问题.

从 slider 更新,但我认为需要更精细的操作 - 我不想每次移动 slider 时都更新整个集合。我想将节点插入和弹出 force.nodes()。

使用我当前的代码,节点运行良好 - 它们只是不会返回。这里是 jsfiddle - https://jsfiddle.net/hiwilson1/ancmtxux/3/

这是导致问题的部分;

function brushed() {
    var exists;

    //var newd = new Date(2013, 05, 01)

    data.forEach(function(d, i) {
        //if data point in range (between extent 0 and 1)
        if (d.date >= brush.extent()[0] && d.date <= brush.extent()[1]) {
            exists = force.nodes().some(function(node, i) {
                //check if data point already exists in force.nodes()
                return (node.mIndex == d.mIndex)                
                })
            console.log(exists)
            if (!exists) {
                force.nodes().push(d)
            }
        }
        else {
            force.nodes().splice(i, 1)
        }   
    })



    d3.select("#nodeCount").text(force.nodes().length)
}

对于每个数据点,我正在检查该点是否位于 extent()[0] 和 [1] 之间。如果是,则检查 force.nodes() 以查看它当前是否是那里的成员。如果不是,则将其插入 force.nodes()。

如果数据点不在范围之间,则从 force.nodes() 拼接它。最后一点工作得很好。

更新:已修复。我实际上也研究了如何过滤附加到节点的链接。 jsfiddle 在这里 - https://jsfiddle.net/hiwilson1/7oumeat5/2/ .永远不要尝试使用索引/硬编码索引来执行此操作,将节点/链接作为对象进行比较。

顺便说一下,我在节点顶部看到了链接。如果有什么方法可以解决这个问题,我很乐意听到。

进一步更新:为了确保节点后面的链接使用 .insert("line", ":first-child") 代替 .append("line")

最佳答案

您当前的代码存在一些问题。根本问题是您将 data 赋予 force.nodes(),这意味着这两个数据结构实际上是相同的。也就是说,当您从 force.nodes() 中删除元素时,您也在修改底层的 data。因此,您无法将它们添加回来——它们已经消失了。

这很容易通过将 data 的副本传递给 force.nodes() 来解决:

var force = d3.layout.force()
    .nodes(JSON.parse(JSON.stringify(data)))

然后您从 force.nodes() 中删除了错误的节点——您使用的索引是用于 data,而不是 force.nodes ()。您可以在 force.nodes() 中计算 data 元素的索引并像这样使用它:

data.forEach(function(d, i) {
        var idx = -1;
        force.nodes().forEach(function(node, j) {
            if(node.mIndex == d.mIndex) {
                idx = j;
            }
        });
        //if data point in range (between extent 0 and 1)
        if (d.date >= brush.extent()[0] && d.date <= brush.extent()[1]) {
            if (idx == -1) {
                force.nodes().push(d)
            }
        }
        else if(idx > -1) {
            force.nodes().splice(idx, 1)
        }

最后,您需要在 brushed 结束时调用 force.start() 以使更改在布局稳定后变得可见。

完整示例 here .

关于javascript - d3 : Adding and removing force. 基于 slider 值的节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30063354/

相关文章:

javascript - javascript 函数表达式是否类似于或基于 s 表达式?

javascript - css 选择器在浏览器中有效,但在 Selenium 中无效

javascript - 给定值创建菱形的函数

javascript - 将闪烁边框应用于 appcelerator 中的 View

javascript - 在 d3 Dragstart 上附加元素

d3.js - D3 比例与图表不匹配

javascript - Chartjs 如何将垂直线保持在水平标尺线下方?

javascript - d3.js - 带 slider 的圆形动画

javascript - d3.js - 从图案填充 `image` 缩小图像尺寸

javascript - D3 更改选择/附加 svgs 的顺序