【发布时间】:2017-01-30 11:00:37
【问题描述】:
更新:I have created a JSFiddle here。请发布更新的小提琴与您的答案。
我有动态过滤器,用户可以将其应用于数据,但它们会更改节点的不透明度以指示过滤入和出的内容(过滤后的“out”元素仍然部分可见,实际的 d3 filter() 函数是不使用(故意))。我还在每个被过滤掉的节点上设置了一个属性(例如node = {"name": "test", "isFilteredOut": true};)。 所以对于这个问题,即使我使用“过滤器”这个词,它实际上只是一个有条件的样式更改(我会尝试把这个词在这篇文章中的引号中“过滤”以提醒这一点)。
这一切都很好,但现在我想递归地“过滤”掉所有子节点和“过滤掉”节点的边,以及将初始“过滤掉”节点连接到其未过滤的边 -出父节点。
我能找到的所有示例都以单击事件开头,因此可以使用this 来获取所选初始节点的数据。我没有这种奢侈,因为过滤器是使用图形本身之外的 UI 元素应用的。
我目前像这样“过滤”节点:
node.style("opacity", function(n) {
if (my_filter_conditions) {
return 1;
} else {
n.isFilteredOut = true;
return 0.1;
}
});
我基本上需要做的是:
递归地选择当前“过滤掉”节点的所有子节点并“过滤”掉这些节点(即将它们的不透明度更改为 0.1 并设置
n.isFilteredOut = true;)。-
将所有边缘的不透明度更改为 0.1,其中源节点或目标节点被“过滤掉”(即边缘任一端的
n.isFilteredOut = true;)
我尝试了什么
我不知道如何访问源节点和目标节点的数据,只给定每个边缘的索引(请记住,我没有从点击事件开始的 this 节点)。我尝试通过从边缘获得的节点索引来获取节点数据:
var node_data = d3.select(current_edge.source.index).datum();
但是,这导致 d3 库中与 this.node() 为空相关的错误(因此在此处传递索引不起作用)。
我还尝试通过将用于处理链接的函数嵌套在传递给 node.style() 函数的函数内来处理边缘,但随后它尝试处理 every 上的 所有 边缘节点,我无法让它提供所需的结果。
link.style("opacity", function (e) {
return ( (n.isFilteredOut)
&& (n.index==e.source.index | n.index==e.target.index) ) ? 0.1 : 1;
});
这是我尝试在“过滤掉”节点的两侧“过滤掉”边缘,但是当我出于某种原因使用它时,没有任何边缘被过滤掉(看起来好像什么也没发生) .
更新:I have created a JSFiddle here。
小提琴注意事项:
- 我知道它很简单(它应该是一个最低限度的工作示例)
- 实际应用程序包含适用于类型的过滤器(即使只是搜索特定设备/部件/等),因此逻辑能够有条件地遵循“链”仅适用于那些具有
node.isFilteredOut = true; - 在此示例中,正确答案将导致创建过滤掉设备也会过滤掉所有部分的情况
- 使用
dataSet本身进行任何过滤的解决方案将不起作用,因为我的大部分数据都是从各种 JSON 源动态填充的。随时与nodes、edges、links、node和/或link合作。 - 请不要重写我的过滤方法。是的,我知道
eval()声明不是很好。但这不是关于如何最好地应用无限联合过滤器的问题,而是关于基于应用的过滤器递归地改变节点和边的不透明度的问题
【问题讨论】:
-
不费吹灰之力,很难。可以加个小提琴吗?
-
我添加了一个小提琴:更新:I have created a JSFiddle here。
-
@Dragon_Slayer 仅供参考:JSFiddle here
-
澄清一下,在我最简单的小提琴中,过滤掉设备也应该导致所有部分(和链接/边缘)也被过滤掉。
-
棘手的情况。这两个答案实际上都没有被证明可以工作(发布小提琴的那个实际上破坏了现有的功能并且没有做需要做的事情,并且作者承认新发布的一个不能与 D3 一起使用)。然而,不奖励任何人意味着积分被浪费了。精...
标签: javascript dictionary recursion d3.js filtering