Sankey diagram in javascript

前端 未结 7 862
灰色年华
灰色年华 2021-02-02 16:22

I want to draw a Sankey diagram using Javascript. Can anyone provide some direction regarding the algorithms or libraries that are available for this?

相关标签:
7条回答
  • 2021-02-02 16:51

    In case helpful to others: I've extracted my javascript sankey diagram drawing code here:

    http://tamc.github.com/Sankey/

    The original usage is on this UK government site:

    http://2050-calculator-tool.decc.gov.uk/pathways/2022222122222103332220023211022330220130233022012/sankey

    0 讨论(0)
  • 2021-02-02 16:55

    Here is a fairly detailed explanation of how Mike Bostock's D3-based Sankey DIagram code works: http://www.d3noob.org/2013/02/sankey-diagrams-description-of-d3js-code.html

    I have implemented this on a Grails-based app server and it works.

    0 讨论(0)
  • 2021-02-02 16:57

    Google Charts includes the Sankey Diagram: https://developers.google.com/chart/interactive/docs/gallery/sankey

    0 讨论(0)
  • 2021-02-02 17:04

    This is a basic Sankey diagram using raphaeljs

    function Sankey(x0, y0, height, losses) {
        var initialcolor = Raphael.getColor();
        var start = x0 + 200;
        var level = y0 + height;
        var heightunit = height / 100;
        var remaining = 100 * heightunit;
    
        function drawloss(start, level, loss) {
            var thecolor = Raphael.getColor();
            paper.path("M" + (start - 100) + "," + (level - loss) + "L" + start + "," + (level - loss)).attr({stroke: thecolor});
            paper.path("M" + (start - 100) + "," + level + "L" + start + "," + level).attr({stroke: thecolor});
            paper.path("M " + start + "," + level + " Q" + (start + 100) + "," + level + " " + (start + 100) + "," + (level + 100)).attr({stroke: thecolor});
            paper.path("M " + start + "," + (level - loss) + " Q" + (start + 100 + loss) + "," + (level - loss) + " " + (start + 100 + loss) + "," + (level + 100)).attr({stroke: thecolor});
            paper.path("M " + (start + 100) + "," + (level + 100) + " L " + (start - 10 + 100) + "," + (level + 100) + " L " + (start + loss / 2 + 100) + "," + (level + 110) + " L " + (start + loss + 10 + 100) + "," + (level + 100) + " L " + (start + loss + 100) + ", " + (level + 100)).attr({stroke: thecolor});
        }
    
        function drawremaining(start, level, loss) {
            paper.path("M 100," + y0 + "L" + (start + 100) + "," + y0).attr({stroke: initialcolor});
            paper.path("M" + (start - 100) + "," + level + "L" + (start + 100) + "," + level).attr({stroke: initialcolor});
            paper.path("M " + (start + 100) + " " + y0 + " L " + (start + 100) + " " + (y0 - 10) + " L " + (start + 110) + " " + (y0 + loss / 2) + " L " + (start + 100) + " " + (level + 10) + " L " + (start + 100) + " " + level).attr({stroke: initialcolor});
        }
    
        function drawstart(x0, y0, width, height) {
            paper.path("M " + x0 + "," + y0 + "L" + (x0 + width) + "," + y0).attr({stroke: initialcolor});
            paper.path("M " + x0 + "," + (y0 + height) + "L" + (x0 + width) + "," + y0 + height)).attr({stroke:  initialcolor});
            paper.path("M " + x0 + "," + y0 + "L" + x0 + "," + (y0 + height)).attr({stroke: initialcolor});
        }
    
        drawstart(x0, y0, 100, height);
    
        for (var i in losses) {
            drawloss(start, level, losses[i] * heightunit);
            remaining -= losses[i] * heightunit;
            level -= losses[i] * heightunit;
            start += 100;
        }
    }
    

    And I use it like this:

    <div id="notepad" style="height:1000px; width:1000px; background: #eee"></div>
    <script type="text/javascript">
        var paper = Raphael(document.getElementById("notepad"), 1020, 1000);
        var losses=[50, 30, 5];
        Sankey(10, 100, 200, losses);
    </script>
    
    0 讨论(0)
  • 2021-02-02 17:07

    Thanks to zenify for starting me on the path, I had to rejig some of the copied code above to get it to work but it definitely gives a good starting point. The code below can be copied into a .htm file and you just need to have raphael-min.js in the same directory for it to work.

    Regards / Colm

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" class="JS">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <title>Raphael makes Sankey</title>
    <script type="text/javascript" src="raphael-min.js"></script>
    <script type="text/javascript">
    function Sankey(x0,y0,height,losses){
        initialcolor= Raphael.getColor();
        var start=x0+200;
        var level=y0+height;    
        var heightunit=height/100;
        var remaining=100*heightunit;
    
    function drawloss(start,level,loss){
        var thecolor=Raphael.getColor();
        paper.path("M"+(start-100)+","+(level-loss)+"L"+start+","+(level-loss)).attr({stroke: thecolor});
        paper.path("M"+(start-100)+","+(level)+"L"+start+","+(level)).attr({stroke: thecolor});
        paper.path("M "+start+","+level+" Q"+(start+100)+","+level+" "+(start+100)+","+(level+100)).attr({stroke: thecolor});
        paper.path("M "+start+","+(level-loss)+" Q"+(start+100+loss)+","+(level-loss)+" "+(start+100+loss)+","+(level+100)).attr({stroke: thecolor});
        paper.path("M "+(start+100)+","+(level+100)+" L "+(start-10+100)+","+(level+100)+" L "+(start+(loss/2)+100)+","+(level+110)+" L "+(start+(loss)+10+100)+","+(level+100)+" L "+(start+(loss)+100)+", "+(level+100)).attr({stroke: thecolor});
    }
    
    function drawremaining(start,level,loss){
        paper.path("M 100,"+y0+"L"+(start+100)+","+y0).attr({stroke: initialcolor});
        paper.path("M"+(start-100)+","+(level)+"L"+(start+100)+","+(level)).attr({stroke: initialcolor});
        paper.path("M "+(start+100)+" "+y0+" L "+(start+100)+" "+(y0-10)+" L "+(start+110)+" "+(y0+(loss/2))+" L "+(start+100)+" "+(level+10)+" L "+(start+100)+" "+(level)).attr({stroke: initialcolor});
    }
    
    function drawstart(x0, y0, width, height){
        paper.path("M "+x0+","+y0+"L"+(x0+width)+","+y0+"").attr({stroke: initialcolor});
        paper.path("M "+x0+","+(y0+height)+"L"+(x0+width)+","+y0+height+"").attr({stroke:  initialcolor});
        paper.path("M "+x0+","+y0+"L"+x0+","+(y0+height)+"").attr({stroke: initialcolor});
    }
    
        drawstart(x0,y0,100,height);
        for (var i in losses){
          drawloss(start,level,losses[i]*heightunit);
          remaining-=losses[i]*heightunit;
          level-=losses[i]*heightunit;
          start+=100;
        }
        drawremaining(start, level, remaining);
    }
    </script>
    </head>
    <body id="blog">
        <div id="notepad" style="height:1000px; width:1000px; background: #eee"></div>
        <script type="text/javascript">
        var paper = Raphael(document.getElementById("notepad"), 1020, 1000);
        var losses=[50, 30, 5];
        Sankey(10, 100, 200, losses);
        </script>
    </body>
    </html>
    
    0 讨论(0)
  • 2021-02-02 17:08

    D3.js uses a plugin to create sankey diagrams pretty well.

    http://bost.ocks.org/mike/sankey/

    0 讨论(0)
提交回复
热议问题