我正在尝试基于M Bostock(http://bl.ocks.org/mbostock/7607999)实现创建动态分层边缘捆绑:
我的数据集的bl.ocks版本在这里:http://bl.ocks.org/ratnakarv/91ace0b5f77fff5ef0ab
与原始节点不同,节点1和节点2之间的关系是一种方式(即节点1可以导入节点2或其他方式),在我的数据集中,节点1和节点2可以有双向导入关系。这在业务流程中经常发生,这是我的应用程序所在的位置。
在此示例中 - '评估'导入'创建QOS降级报告'和'创建QOS ...'导入'评估'。但是当鼠标结束时,'评估',节点 - '创建..'显示为红色,但该行为绿色。当鼠标在节点上时 - 'Create ...',导入行和'Assess'显示为红色。
我的要求是,如果存在双向导入,则要么--1。该行以及其他节点以第三种颜色(红色或绿色除外)或2.该行以及其他节点显示为显示为红色。
任何对此的指示都会有所帮助。我对D3有基本的了解,但我不是数据可视化专家,只是尝试在我的工作领域使用可视化来更好地进行沟通。
答案 0 :(得分:2)
有几种方法可以解决这个问题,但这是我现在能想到的最简单的方法。
请注意,bl.ock中Assess
和Create QoS Degradation Report
之间的 两个 路径具有相同但相反的值(因为它们都是源和彼此的目标)。其中一个恰好放在另一个上面,给它们一个单一路径的外观。这就是为什么这两个节点之间的链接有点锯齿状,而其他节点之间的连接是平滑的。也许我们可以利用这一点。
如果您调整CSS中link--source
和link--target
的定义以使不透明度值小于1,则部分透明的源链接将与部分透明的目标链接重叠,从而呈现一种“新”,不同的颜色。
对于节点颜色,使用“新”颜色创建一个新的CSS类node--both
,如果n.source
和n.target
中的mousovered
和node
.classed("node--both", function(n) { return n.source && n.target; })
.classed("node--target", function(n) { return n.target; })
.classed("node--source", function(n) { return n.source; });
都为真,则将其应用于节点{1}}功能。
links
这并不完美,但这是一个小提琴,展示了这一点:http://jsfiddle.net/w2rfwokx/
关键是要适当地选择源和目标链接颜色和不透明度值(我没有这样做),这样你就可以获得与源链接和目标链接不同的新颜色,也可以使用相同的颜色,无论是否源或目标链接“在顶部”。在当前的小提琴版本中,您可以看到颜色略有不同,具体取决于哪个节点处于活动状态。 This thread或类似的东西可能有所帮助。
您还可以尝试操作links
数组,将两个相同的路径合并为一个,并添加一个属性以指示这是一个源 - 目标链接,并在以后处理时使用此属性。
更新:您的评论中有正确的想法。无论如何,颜色技巧更像是黑客攻击。
var unique_links = links.reduce(function(p,c) {
var index=p.map(function(d,i) { if(d.source===c.target && d.target===c.source) return i;}).shift();
if(!isNaN(index)) p[index].both=true; else p.push(c);
return p;
},[]);
数组包含两个项目,用于双向导入节点之间的一条路径。让我们删除其中一个,并在另一个中设置一个属性,以表明这是一个双向导入。
unique_links
现在both=true
每个边只有一个元素,而且一个元素有both
。我们还将link = link
.data(bundle(unique_links))
.enter().append("path")
.each(function(d) {
d.source = d[0],
d.target = d[d.length - 1],
d.both = unique_links.filter(function(v) { if (v.source===d.source && v.target===d.target) return v.both; }).shift();
})
.attr("class", "link")
.attr("d", line);
属性传递给包布局。
mouseovered
最后一步是更改both
函数,使用function mouseovered(d) {
node
.each(function(n) { n.target = n.source = false; });
link
.classed("link--both", function(l) { if((l.target===d || l.source===d) && l.both) return l.source.source = l.source.target = l.target.source = l.target.target = true;})
.classed("link--target", function(l) { if (l.target === d && !l.both) return l.source.source = true; })
.classed("link--source", function(l) { if (l.source === d && !l.both) return l.target.target = true; })
.filter(function(l) { return l.target === d || l.source === d; })
.each(function() { this.parentNode.appendChild(this); });
node
.classed("node--both", function(n) { return n.target && n.source; })
.classed("node--target", function(n) { return n.target; })
.classed("node--source", function(n) { return n.source; });
}
设置不同颜色的新CSS类:
mouseouted
并重置function mouseouted(d) {
link
.classed("link--both", false)
.classed("link--target", false)
.classed("link--source", false);
node
.classed("node--both", false)
.classed("node--target", false)
.classed("node--source", false);
}
中的课程:
.link--both {
stroke: orange;
}
.node--both {
fill: orange;
}
请记住在CSS中定义新类:
{{1}}
以下是完整代码的更新小提琴:http://jsfiddle.net/w2rfwokx/1/