在javascript中的Sankey图

时间:2010-12-28 10:09:38

标签: javascript drawing data-visualization diagram sankey-diagram

我想使用Javascript绘制Sankey diagram。任何人都可以就可用的算法或库提供一些指导吗?

7 个答案:

答案 0 :(得分:11)

这是使用raphaeljs

的基本Sankey图表
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;
    }
}

我这样使用它:

<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>

答案 1 :(得分:9)

如果对其他人有帮助:我在这里提取了我的javascript sankey图表绘图代码:

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

最初的用法是在英国政府网站上:

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

答案 2 :(得分:6)

D3.js使用插件很好地创建了sankey图。

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

答案 3 :(得分:2)

以下是Mike Bostock基于D3的Sankey DIagram代码如何工作的相当详细的解释:http://www.d3noob.org/2013/02/sankey-diagrams-description-of-d3js-code.html

我已经在基于Grails的应用服务器上实现了它,并且它可以工作。

答案 4 :(得分:2)

答案 5 :(得分:1)

感谢zenify在路径上启动我,我不得不重新调整上面的一些复制代码才能使它工作,但它确实提供了一个很好的起点。下面的代码可以复制到.htm文件中,您只需要在同一目录中安装raphael-min.js即可。

问候/ 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>

答案 6 :(得分:1)

更新2020:

对于那些努力使D3 Sankey示例栩栩如生的人,我找到了这个超级简单的视频教程。对我来说就像是一种魅力:)

https://reactviz.holiday/sankey/

另外,如果您也无法使它正常工作, react-google-charts 有一个非常漂亮的选择,使用起来再容易不过了(至少实现了该示例只是从这里https://react-google-charts.com/sankey-diagram复制粘贴整个组件:

import Chart from "react-google-charts";


<Chart
  width={600}
  height={'300px'}
  chartType="Sankey"
  loader={<div>Loading Chart</div>}
  data={[
    ['From', 'To', 'Weight'],
    ['A', 'X', 5],
    ['A', 'Y', 7],
    ['A', 'Z', 6],
    ['B', 'X', 2],
    ['B', 'Y', 9],
    ['B', 'Z', 4],
  ]}
  rootProps={{ 'data-testid': '1' }}
/>