这是我在这里的第一篇文章,所以如果看起来有点笨拙,我深表歉意。
我正在使用 D3.js 处理力导向图。我遇到了过滤功能的问题。这是我的情况: 我在我的图表中创建了具有很多功能的节点。我希望首先能够根据用户认为可能是相关功能的内容创建所有这些节点的子集并进行可视化分析。
例如,我正在处理玫瑰图像(这是我的节点),我想根据它们的圆度来过滤它们。圆度特征可以从 0 到 1000,所以我首先尝试制作 5 个子集。第一个节点的圆度从 0 到 200,第二个节点的圆度从 200 到 400,等等...直到最后一个子集从 800 到 1000。
为了获取子集,我使用了 d3.js 的过滤函数。这是我遇到问题的地方:
注意:- 变量“节点”是我的节点集,它们都存在。 - 变量“groups = []”将包含我的五个节点子集。 - 变量“thresholds = []”包含我所有的阈值。例如:阈值[0] == 0,阈值[1] == 200,阈值[2] == 400。
for(i = 0 ; i < 5 ; i++) //going through the creation of 5 subsets
{
groups[i] = nodes.filter(function(d, i)
{
return d.Shape_Roundness > thresholds[i] && d.Shape_Roundness <= thresholds[i + 1];
//Get the nodes "d" which have a roundness superior to a minimum threshold and inferior to a maximum threshold
});
}
当我检查我的子集的输出时,只有一个结果,好像函数在遇到“return”关键字时中断了。更重要的是,结果在每个子集中始终相同,并且是我整个集合的第一个节点。
但是当我输入硬输入时,将例如“thresholds[i]”和“thresholds[i + 1]”替换为数字 0 和 200,如下所示:
for(i = 0 ; i < 5 ; i++) //going through the creation of 5 subsets
{
groups[i] = nodes.filter(function(d, i)
{
return d.Shape_Roundness > 0 && d.Shape_Roundness <= 200;
});
}
现在,我不知道为什么但它有效,而且我当然有 5 个相同的子集。我认为也许我的变量“thresholds = []”不包含数字,但是当我对每个值使用 typeof 运算符时,输出都是“数字”。
我想使用变量而不是硬值,因为我希望用户可以更改阈值。当然,并不是我节点的所有特征都从 0 到 1000。
谁能告诉我我做错了什么?
非常感谢, 祝大家有个愉快的一天!
最佳答案
问题是,您将变量 i
用作 for 循环的循环变量,并用作过滤器部分匿名函数的参数。
在匿名函数内部,只能访问参数 i
并且您的循环变量是不可见的,因为它具有相同的名称。这叫做 variable shadowing .
正如 D3 的文档所解释的那样 here , filter
函数回调的第二个参数是节点的索引。因此,在您的回调中,您访问 thresholds[0]
用于 nodes
的第一个节点,thresholds[1]
用于第二个节点,依此类推。
由于您的过滤器不需要当前节点的索引,因此最简单的解决方法是省略 i
参数,如下所示:
for(i = 0 ; i < 5 ; i++) { //going through the creation of 5 subsets
groups[i] = nodes.filter(function(d) {
return d.Shape_Roundness > thresholds[i] && d.Shape_Roundness <= thresholds[i + 1];
//Get the nodes "d" which have a roundness superior to a minimum threshold and inferior to a maximum threshold
});
}
这样,回调中的 i
变量将引用您的循环变量。
关于javascript - 如何在循环中使用 selection.filter 方法将 D3 选择分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31250121/