一段时间以来,我在根据用户输入添加和删除节点时遇到了一些困难,每次用户从复选框列表中选择他们想要查看的对象时,我都会通过更新插入 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/