Dan*_*Dan 8 javascript recursion dictionary filtering d3.js
更新:我在这里创建了一个JSFiddle.请发布一个更新的小提琴你的答案.
我有动态过滤器,用户可以应用于数据,但是它们会改变节点的不透明度以指示过滤进出的内容(过滤后的"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;
}
});
Run Code Online (Sandbox Code Playgroud)
我基本上需要做的是:
递归地选择当前"已滤除"节点的所有子节点,并且也"过滤"那些节点(即将它们的不透明度改变为0.1并设置n.isFilteredOut = true;).
将所有边的不透明度更改为0.1,其中源节点或目标节点被"过滤掉"(即n.isFilteredOut = true;在边缘的任一端)
我不知道如何访问源节点和目标节点的数据,只给出每个边缘的索引(记住我没有this从点击事件开始的节点).我尝试传递从边缘获得的节点索引来获取节点数据:
var node_data = d3.select(current_edge.source.index).datum();
Run Code Online (Sandbox Code Playgroud)
但是,这导致d3库中的错误与this.node()null 相关(因此在此处传递索引不起作用).
我也尝试通过嵌套函数来处理边缘,处理传递给node.style()函数的函数内部的链接,然后它尝试处理每个节点上的所有边缘,我无法得到它来提供所需的结果.
link.style("opacity", function (e) {
return ( (n.isFilteredOut)
&& (n.index==e.source.index | n.index==e.target.index) ) ? 0.1 : 1;
});
Run Code Online (Sandbox Code Playgroud)
这是我试图"过滤掉""滤出"节点两侧的边缘,但是当我出于某种原因使用它时,没有任何边缘被过滤掉(似乎根本没有发生任何事情).
关于小提琴的注释:
node.isFilteredOut = true;dataSet自身进行任何过滤的解决方案将无法正常工作,因为我的大部分数据都是从各种JSON源动态填充的.随时与工作nodes,edges,links,node,和/或link.eval()陈述并不好.但这不是关于如何最好地应用无限联合滤波器的问题,而是基于应用的滤波器递归地改变节点和边缘的不透明度这是一种可能的方法,它实现了递归过滤(如果设备被过滤,则其部分被过滤)和基于节点过滤的链接过滤:http ://jsfiddle.net/Lsr9c8nL/4/
我改变了你实现过滤器的方式。使用字符串来构建过滤器,然后eval()被认为是非常糟糕的,因为工具不能用 做太多事情eval(),例如检测错误或优化浏览器上的 JS 代码。
我直接在 上进行过滤dataSet,而不是在节点上(您必须查询节点type并比较字符串,这很慢)。直接在数据集上执行此操作还可以轻松查找给定部件的设备是什么。
诀窍基本上是每次都重新绘制整个图表,并仔细使用 d3 的exit,enter和update选择。如果需要,这还允许您添加动画
| 归档时间: |
|
| 查看次数: |
615 次 |
| 最近记录: |