d3-plugins icon indicating copy to clipboard operation
d3-plugins copied to clipboard

Add support for self-loops and cycles in sankeys

Open kunalb opened this issue 12 years ago • 20 comments

  • Changes the logic of assigning breadths to first break the graph down into strongly connected components, layer out the resulting DAG the same way the current algo lays out nodes; then do a bfs from the obtained root of each SCC and lay out cycle members.
  • There are very weird artefacts at the endpoints of splines for wide splines, so I ended up replacing links with 2 splines to define the structure explicitly. Fill isn't as good as I want it to be, but I'm not sure about the best way to proceed.

Sample using existing data, and with a loop: http://bl.ocks.org/d/4658510/

The code is a bit rough -- I was mainly iterating to get something that looked decent first, can/will clean up as required.

kunalb avatar Jan 28 '13 20:01 kunalb

Nice work! I like the visual technique you've used for the loop back.

d3noob avatar Feb 20 '13 17:02 d3noob

^ Just cleaned up the code a bit, and reverted the link behaviour to the original for people who prefer to keep the same width nodes, while adding a reversibleLink function as an alternative for people creating cyclic sankey diagrams.

The reversible link function creates three parts that get filled correctly: basically so that reversed links are filled in correctly (see the attached screenshot: the bottom image is what was, with a single path filled in, and the top svg element is the new version, with 3 paths filled in making a ribbon) Screen Shot 2013-03-11 at 9 22 29 PM

New example (slightly more complex than the previous one) with cycles: http://bl.ocks.org/kunalb/raw/5140332/

kunalb avatar Mar 12 '13 04:03 kunalb

@mbostock: was this ever checked into the main repo? If not, is there an ETA?

We have a case where we are dynamically getting data for Sankey, and having it work with loops would be nice, otherwise it causes a hang.

itay avatar Jul 22 '13 17:07 itay

Thought I'd check in again - we've tried the suggested code ourselves, and it works pretty well. I'd love to see this integrated into the official sankey code.

itay avatar Sep 20 '13 02:09 itay

@itay I guess the fact that chord widths aren't constant is probably a problem because that's pretty crucial for most sankey diagrams? I couldn't figure out a way to fit everything in cleanly enough with constant width diagrams... @mbostock any suggestions? I can try and iterate on this.

kunalb avatar Sep 20 '13 03:09 kunalb

@kunalb: that's fair, thank you for pointing it out. I guess my main concern is that the current behavior with cycles is to cause the entire tab to crash essentially, since it is in an infinite loop. If it even just errored, that would be a start. Do you think it would be possible to modify your pull request to detect cycles and then throw an event?

itay avatar Sep 20 '13 19:09 itay

That's fairly trivial: sent out a separate pull request: #78

kunalb avatar Sep 22 '13 06:09 kunalb

@kunalb first of, thank you for adding that separate pull request. A quick question for you: with this pull request (adding cyclic link support), are there cases where some data without cycles is rendered worse than the old version (the one in d3-plugins)? Basically, is your PR regressing anything?

If not, it seems this is a net improvement, and one that we could iterate on.

The reason I'm pushing on this particular item is that we'd really like to include sankey visualization support in something that we're doing, but it's kind of a bummer that it either hangs/errors if your data has cycles. This is especially problematic for us because our data is dynamic and we can't control whether it is cyclic or not.

@mbostock: what can we do to help get this issue solved?

itay avatar Sep 24 '13 00:09 itay

Running into the same problem. Any best practice when dealing with circular reference or standard code to follow?

pkpp1233 avatar Feb 13 '14 18:02 pkpp1233

@pkpp1233 You could patch this diff and use reversibleLink instead of Link. See the example in the documentation for reversibleLink.

kunalb avatar Feb 14 '14 00:02 kunalb

@kunalb I know this is kind of old, but I tried using your sankey.js but my simple cycle sankey isn't rendering. Is there an update to D3 which breaks this?

josephsiu avatar Jun 20 '14 08:06 josephsiu

@josephsiu not that I know of. Put up a gist somewhere so that I can take a look?

kunalb avatar Jun 22 '14 01:06 kunalb

@kunalb Sorry for the false alarm. It was a separate issue. Your edits worked great for cycles! Thanks!

josephsiu avatar Jun 22 '14 01:06 josephsiu

@kunalb, both of the examples (http://bl.ocks.org/kunalb/4658510 and http://bl.ocks.org/kunalb/5140332) fail to run in Chrome, the console complains about wrong MIME type for sankey.js, not sure if this is something happened with the last changes, or just the Gists are acting up…

NPC avatar Jun 24 '14 05:06 NPC

@NPC Hm, looks like github doesn't allow hotlinking js files directly any more :). I set up one of the gists as an example at http://explog.in/notes/sankey/

kunalb avatar Jun 29 '14 08:06 kunalb

@kunalb, wow, these look neat. Thanks for the updated example!

NPC avatar Jun 29 '14 20:06 NPC

@kunalb , Thank you for your great work. Just one Question: Is there any possibility to change the color of the cycle-links, without changing the color of the "normal" links?

Erfabes avatar Dec 10 '14 12:12 Erfabes

@Erfabes you choose the link color when you draw the links for both the normal and reversible links -- see the example at https://github.com/d3/d3-plugins/pull/39/files#diff-3aa14326cff02f35c6674920e9334c9fR79 ; that's completely controlled by you.

kunalb avatar Dec 12 '14 03:12 kunalb

(FYI: as maintenance of d3-plugins stalled, I started a friendly (subtree) fork (see #133) of the sankey plugin at https://github.com/soxofaan/d3-plugin-captain-sankey)

I'm also working on rendering cycles at soxofaan/d3-plugin-captain-sankey#6

soxofaan avatar Jun 22 '15 12:06 soxofaan

@kunalb for your sankey cycle code, if I were to include a marker-end on the path, where would I put it or what kind of modifications would be required to include it? I have tried to put it in the path objects but it doesn't show up...

Hope you can help! Thanks for a great addition to the D3 library!

//marker-end of path svg.append('marker') .attr('id', "end-arrow") .attr('markerHeight', 2.5) .attr('markerWidth', 2, 5) .attr('orient', 'auto') .attr('refX', -5) .attr('refY', 0) .attr('viewBox', '-5 -5 20 10') .append('path') .attr('d', 'M 0,0 m -5,-5 L 0,0 L -5,5 Z') //.attr("fill", "#2ca25f") .style("fill", "#969696") .style("stroke", "2")

var path1 = linkEnter.append("path") .attr("class", "link1") .attr("opacity", .5) .style("marker-end", "url(#end-arrow)") .attr("fill", null) .style("fill", function (d) { return d.target.color = color(d.target.name.replace(/ .*/, "")); }) .attr("d", path(1)) .attr("class", "linkish"); ;

eformx avatar Oct 22 '15 04:10 eformx