Sankey diagram in javascript
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>
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