It seems that if there exist multiple links between two nodes in D3 force layout, D3 just picks up one and ignores others. Is it possible to visualize multigraph?
So, it turns out that d3 does render multiple links between nodes, it's just that it draws them on top of one another. My approach to addressing this is to draw the links as paths (instead of lines) and to add a different curve to each path. This means that each link object needs something to differentiate it from others that the same source and target nodes. My links look like this:
links: [
{"source": 0,"target": 1,"count": 1},
{"source": 1,"target": 2,"count": 1},
{"source": 1,"target": 3,"count": 1},
{"source": 1,"target": 4,"count": 1},
// same source and target with greater count
{"source": 1,"target": 4,"count": 2},
{"source": 1,"target": 4,"count": 3},
{"source": 1,"target": 4,"count": 4}
]
And then the path rendering code looks like
function tick() {
link.attr("d", function(d) {
var x1 = d.source.x,
y1 = d.source.y,
x2 = d.target.x,
y2 = d.target.y,
dx = x2 - x1,
dy = y2 - y1,
// Set dr to 0 for straight edges.
// Set dr to Math.sqrt(dx * dx + dy * dy) for a simple curve.
// Assuming a simple curve, decrease dr to space curves.
// There's probably a better decay function that spaces things nice and evenly.
dr = Math.sqrt(dx * dx + dy * dy) - Math.sqrt(300*(d.count-1));
return "M" + x1 + "," + y1 + "A" + dr + "," + dr + " 0 0,1 " + x2 + "," + y2;
});
node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
}
Here is a jsfiddle that demonstrates the approach.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With