xxxxxxxxxx
<html xmlns="https://www.w3.org/1999/xhtml">
<head>
<title>Mutli-Part Sankey</title>
<meta charset="utf-8" />
</head>
<style>
#chart {
height: 500px;
}
.node rect {
cursor: move;
fill-opacity: .9;
shape-rendering: crispEdges;
}
.node text {
pointer-events: none;
text-shadow: 0 1px 0 #fff;
}
.link {
fill: none;
stroke: #000;
stroke-opacity: .2;
fill-opacity: .2;
}
.link:hover {
fill-opacity: .5;
}
</style>
<script>
var margin = {
top: 1,
right: 1,
bottom: 6,
left: 1
},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
expData = "";
nodes = [];
edges = [];
nodeHash = {};
edgeHash = {};
function makeVizSankey() {
d3.select(".chart")
.append("svg")
.attr("height", height)
.attr("width", width)
d3.csv("energy.csv", createData);
}
function createData(data) {
//Build the network
data.forEach(function (datum) {
if (!nodeHash[datum.source]) {
nodeHash[datum.source] = {id: datum.source};
nodes.push(nodeHash[datum.source]);
}
if (!nodeHash[datum.target]) {
nodeHash[datum.target] = {id: datum.target};
nodes.push(nodeHash[datum.target]);
}
// Each link will have a segments array made up of the 5-year values
var newEdge = {source: nodeHash[datum.source], target: nodeHash[datum.target]};
edgeHash[datum.source+datum.target] = newEdge;
newEdge.value = parseFloat(datum.total);
edges.push((newEdge));
})
buildSankey();
}
function buildSankey() {
var formatNumber = d3.format(",.0f"),
format = function(d) {
return formatNumber(d) + " kr";
};
var sankey = d3.sankey()
.nodeWidth(15)
.nodePadding(10)
.size([width, height]);
var path = sankey.link();
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 + ")");
sankey
.nodes(nodes)
.links(edges)
.layout(32);
var link = svg.append("g").selectAll(".link")
.data(edges)
.enter().append("path")
.attr("class", "link")
.attr("d", path)
.style("fill", "lightgrey")
.sort(function(a, b) {
return b.dy - a.dy;
});
link.append("title")
.text(function(d) {
return d.source.id + " → " + d.target.id + "\n" + format(d.value);
});
var node = svg.append("g").selectAll(".node")
.data(nodes)
.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
node.append("rect")
.attr("height", function(d) { return d.dy; })
.attr("width", sankey.nodeWidth())
.style("fill", "green")
.style("stroke", function(d) {
return d3.rgb(d.color).darker(2);
})
.append("title")
.text(function(d) {
return d.id + "\n" + format(d.value);
});
node.append("text")
.attr("x", -6)
.attr("y", function(d) {
return d.dy / 2;
})
.attr("dy", ".35em")
.attr("text-anchor", "end")
.attr("transform", null)
.text(function(d) {
return d.id;
})
.filter(function(d) {
return d.x < width / 2;
})
.attr("x", 6 + sankey.nodeWidth())
.attr("text-anchor", "start");
}
</script>
<body onload="makeVizSankey()">
<div id="chart"></div>
<footer>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script src="sankey.js" charset="utf-8" type="text/javascript"></script>
</footer>
</body>
</html>
https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js