有几种方法可以解决这个问题,但这是我目前能想到的最简单的方法。
请注意,在您的 bl.ock 中,Assess 和 Create QoS Degradation Report 之间有 两条 路径,它们的值相等但相反(因为它们都是源 和彼此的目标)。其中一个恰好放在另一个之上,使它们看起来像是一条路径。这就是为什么这两个节点之间的链接有些参差不齐,而其他节点却是平滑的。也许我们可以利用这一点。
如果您在 CSS 中调整 link--source 和 link--target 的定义以使其不透明度值小于 1,则部分透明的源链接将与部分透明的目标链接重叠,从而呈现“新”的外观,不同的颜色。
对于节点颜色,使用“新”颜色创建一个新的 CSS 类 node--both,如果 mousovered 函数中的 n.source 和 n.target 都为 true,则将其应用于节点。
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; });
这并不完美,但这里有一个小提琴证明了这一点:http://jsfiddle.net/w2rfwokx/
关键是要适当地选择源链接和目标链接的颜色和不透明度值(我没有这样做),以便获得与源链接和目标链接足够不同的新颜色,并且无论是否源或目标链接在“顶部”。在当前的 fiddle 版本中,您可以看到颜色略有不同,具体取决于哪个节点处于活动状态。 This thread 或类似的东西可能会有所帮助。
您还可以尝试操作links 数组以将两个相同的路径合并为一个,并添加一个属性以指示这是一个源和目标链接,并在稍后处理时使用此属性。
更新:您在评论中的想法是正确的。无论如何,颜色技巧更像是一种技巧。
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 设置具有不同颜色的新 CSS 类:
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; });
}
并重置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);
}
记得在 CSS 中定义新的类:
.link--both {
stroke: orange;
}
.node--both {
fill: orange;
}
这是完整代码的更新小提琴:http://jsfiddle.net/w2rfwokx/1/