Source: Department of Energy & Climate Change, Tom Counsell.
A demonstration of d3-sankey.
forked from mbostock's block: Sankey Diagram
xxxxxxxxxx
<meta charset="utf-8">
<title>eRum 2018 participants</title>
<style>
html {
min-width: 1040px;
}
body {
background: #fcfcfa;
color: #333;
font-family: "Maven Pro";
margin: 1em auto 4em auto;
position: relative;
width: 960px;
}
body > p, li > p {
line-height: 1.5em;
}
body > p {
width: 900px;
}
aside {
font-size: small;
right: 0;
position: absolute;
width: 180px;
}
.attribution {
font-size: small;
margin-bottom: 2em;
}
footer {
display: block;
font-size: small;
text-align:center;
}
.node rect {
cursor: move;
fill-opacity: 2.0988;
shape-rendering: crispEdges;
}
.node text {
pointer-events: none;
text-shadow: 0 1px 0 #fff;
font-family: "Maven Pro";
}
text {
font-family: "Maven Pro";
font-size: 13px;
}
.link {
fill: none;
stroke: #000;
stroke-opacity: 0.09;
}
.link:hover {
stroke-opacity: 0.42;
}
</style>
<body>
<h1>Who is coming to eRum 2018?</h1>
<p id="chart">
<aside>Drag to rearrange nodes.</aside>
<p class="attribution">Author: <a href="https://twitter.com/olga_mie">Olga Mierzwa-Sulima</a>,<br> Source: <a href="https://2018.erum.io/">eRum 2018 @Budapest</a>, <a href="https://twitter.com/daroczig?lang=en">Gergely Daróczi</a>.
<p>Sankey diagram shows early bird registrations for <a href="https://2018.erum.io/">eRum 2018 conference in Budapest</a>.
<p>Other countries label includes countries with 9 or less registrations (Argentina, Brazil, Croatia, Cyprus, Egypt, Estonia, Georgia, Iceland, India, Ireland, Israel, Latvia, Lebanon, Luxembourg, Malta, New Zealand, Norway, Romania, Russian Federation, Serbia, Slovakia, Slovenia, South Africa, Spain, Sweden, Turkey).
<p><b>Many thanks</b> to eRum organizers, especially Gergely Daróczi for providing anonymized export on the early-bird registration data and recoding sex using babynames R package.
<footer>
<p>Created and hosted by:</p>
<a href="https://appsilondatascience.com">
<img class="footer-image" src="assets_sankey/logo.png" class="center" height="42"></a>
</footer>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script src="sankey.js"></script>
<link rel="stylesheet" type="text/css" href="//fonts.googleapis.com/css?family=Maven+Pro" />
<script>
var margin = {top: 10, right: 10, bottom: 10, left: 10},
width = 940 - margin.left - margin.right,
height = 450- margin.top - margin.bottom;
var formatNumber = d3.format(",.0f"), // zero decimal places
format = function(d) { return formatNumber(d); },
color = d3.scale.category20();
// append the svg canvas to the page
var svg = d3.select("#chart").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
// Set the sankey diagram properties
var sankey = d3.sankey()
.nodeWidth(20)
.nodePadding(20)
.size([width, height]);
var path = sankey.link();
// load the data
d3.json("energy.json", function(error, graph) {
var nodeMap = {};
graph.nodes.forEach(function(x) { nodeMap[x.name] = x; });
graph.links = graph.links.map(function(x) {
return {
source: nodeMap[x.source],
target: nodeMap[x.target],
value: x.value
};
});
sankey
.nodes(graph.nodes)
.links(graph.links)
.layout(30);
// add in the links
var link = svg.append("g").selectAll(".link")
.data(graph.links)
.enter().append("path")
.attr("class", "link")
.attr("d", path)
.style("stroke-width", function(d) { return Math.max(1, d.dy); })
.sort(function(a, b) { return b.dy - a.dy; });
// add the link titles
link.append("title")
.text(function(d) {
return d.value + " coming from " + d.source.name + " with " +
d.target.name + "(s)\n"; })
.filter(function(d) { return ['Female','Male', 'Unknown'].indexOf(d.target.name) > -1; })
.text(function(d) {
return d.value + " " + d.source.name + '(s) ' + 'purchased by ' +
d.target.name + "(s)\n"; })
// add in the nodes
var node = svg.append("g").selectAll(".node")
.data(graph.nodes)
.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")"; })
.call(d3.behavior.drag()
.origin(function(d) { return d; })
.on("dragstart", function() {
this.parentNode.appendChild(this); })
.on("drag", dragmove));
// add the rectangles for the nodes
node.append("rect")
.attr("height", function(d) { return d.dy; })
.attr("width", sankey.nodeWidth())
.style("fill", function(d) {
return d.color })
.style("stroke", function(d) {
return d3.rgb(d.color).darker(1); })
.append("title")
.text(function(d) {
return d.name + "\n" + format(d.value); });
// add in the title for the nodes
node.append("text")
.attr("x", -4)
.attr("y", function(d) { return d.dy / 2; })
.attr("dy", "0.3em")
.attr("text-anchor", "end")
.attr("transform", null)
.text(function(d) { return d.name + " (" + d.perc + ")"; })
.filter(function(d) { return d.x < width / 4; })
.attr("x", 4 + sankey.nodeWidth())
.attr("text-anchor", "start");
// the function for moving the nodes
function dragmove(d) {
d3.select(this).attr("transform",
"translate(" + d.x + "," + (
d.y = Math.max(0, Math.min(height - d.dy, d3.event.y))
) + ")");
sankey.relayout();
link.attr("d", path);
}
});
</script>
</body>
</html>
Modified http://d3js.org/d3.v3.min.js to a secure url
https://d3js.org/d3.v3.min.js