A refactored version of Sara Quigley's Issue Breakdown as a simple example of a Sankey diagram
forked from syntagmatic's block: Issue Breakdown
xxxxxxxxxx
<meta charset="utf-8">
<title>Issue Breakdown</title>
<style>
body {
background: #fcfcfa;
width: 944px;
margin: 10px;
}
svg {
font: 500 14px "arial", sans-serif;
fill: #023848;
}
.node {
transition: opacity 0.25s;
}
.node rect {
fill-opacity: .75;
shape-rendering: crispEdges;
}
.node text {
pointer-events: none;
font-size: 9px;
opacity: 0;
transition: opacity 0.25s;
}
.link {
fill: none;
stroke: #969696;
stroke-opacity: .1;
}
.link:hover {
stroke-opacity: .6;
}
</style>
<body>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script src="https://bost.ocks.org/mike/sankey/sankey.js"></script>
<script>
var margin = {top: 1, right: 30, bottom: 1, left: 1},
width = 940 - margin.left - margin.right,
height = 480 - margin.top - margin.bottom;
var category20b_sq = [
'#393b79', '#5254a3', '#6b6ecf', '#9c9ede',
'#8c6d31', '#bd9e39', '#e7ba52', '#e7cb94',
'#843c39', '#ad494a', '#d6616b', '#e7969c',
'#637939', '#8ca252', '#b5cf6b', '#cedb9c',
'#ce6dbd', '#a55194', '#de9ed6', '#7b4173'
];
var color = d3.scale.ordinal()
.range(category20b_sq);
var svg = d3.select("body").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 + ")");
var sankey = d3.sankey()
.nodeWidth(16)
.nodePadding(10)
.size([width, height]);
var path = sankey.link()
.curvature(0.3);
d3.json("sankey.json", function(energy) {
sankey
.nodes(energy.nodes)
.links(energy.links)
.layout(20);
var link = svg.append("g").selectAll(".link")
.data(energy.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; })
.on("mouseover", function(d) {
d3.selectAll(".node")
.style("opacity", 0.3)
.filter(function(p) {
return d.source.name == p.name ||
d.target.name == p.name;
})
.style("opacity", 1)
.selectAll("text")
.style("opacity", 1);
})
.on("mouseout", function(d) {
d3.selectAll(".node")
.style("opacity", null)
.selectAll("text")
.style("opacity", 0);
});
var node = svg.append("g").selectAll(".node")
.data(energy.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", function(d) { return color(d.category); })
.append("title")
.text(function(d) { return d.name; });
node.append("text")
.attr("x", 6 + sankey.nodeWidth())
.attr("y", function(d) { return d.dy / 2; })
.attr("dy", ".35em")
.attr("text-anchor", "start")
.attr("transform", null)
.text(function(d) { return d.name; })
.filter(function(d) { return d.x > width * .9; })
.attr("class", function(d) { return d.category ; })
.attr("text-anchor", "end")
.attr("transform", function(d) { return "translate (" + ((d.dy / 2) + 30) + "," + (d.dy / 2) + ") rotate(90)"; });
});
</script>
Modified http://d3js.org/d3.v3.min.js to a secure url
Modified http://bost.ocks.org/mike/sankey/sankey.js to a secure url
https://d3js.org/d3.v3.min.js
https://bost.ocks.org/mike/sankey/sankey.js