D3 Dynamic Hierarchical Edge Bundling - 2 Way Import
Solution 1:
There are a few ways to approach this, but this is the easiest one I can think of as of now.
Note that there are two paths between Assess
and Create QoS Degradation Report
in your bl.ock with equal but opposite values (as they are both a source and a target for each other). One of them is laid exactly on top the other, giving them the appearance of a single path. That's why the link between these two nodes is somewhat jagged, while the others are smooth. Perhaps we can take advantage of this.
If you adjust the definitions for link--source
and link--target
in your CSS to have an opacity value of less than 1, a partially transparent source link will overlap a partially transparent target link, giving the appearance of a "new", different color.
As for the node color, create a new CSS class node--both
with the "new" color, and apply it to the node if both n.source
and n.target
are true in the mousovered
function.
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; });
It's not perfect, but here's a fiddle demonstrating this: http://jsfiddle.net/w2rfwokx/
The key is to choose the source and target link colors and opacity values appropriately (which I didn't do) so that you get a new color different enough from the source and target links and also the same color regardless of whether the source or the target link is "on top". In the current fiddle version, you can see that the colors slightly differ depending on which node is active. This thread or something similar might help.
You could also try manipulating the links
array to merge the two identical paths into one and adding an attribute to indicate that this is a source-and-target link and use this attribute later while processing.
Update: You have the right idea in your comment. The color trick was more of a hack anyway.
The links
array contains two items for the one path between the two-way import nodes. Let's remove one of them and also set an attribute in the other to indicate that this is a two-way import.
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;
},[]);
Now unique_links
has only one element per edge and that one element has both=true
. Let's also pass the both
attribute along to the bundle layout.
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);
The final step is to change the mouseovered
function to set a new CSS class with a different color using both
:
functionmouseovered(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; });
}
And reset the classes in 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);
}
Remember to define the new classes in CSS:
.link--both {
stroke: orange;
}
.node--both {
fill: orange;
}
Here's an updated fiddle with the complete code: http://jsfiddle.net/w2rfwokx/1/
Post a Comment for "D3 Dynamic Hierarchical Edge Bundling - 2 Way Import"