Skip to content

Instantly share code, notes, and snippets.

@d3noob
Last active March 31, 2021 09:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save d3noob/9acbd342a173e46e6b0a190a382308d7 to your computer and use it in GitHub Desktop.
Save d3noob/9acbd342a173e46e6b0a190a382308d7 to your computer and use it in GitHub Desktop.
Sankey diagram using a csv file with v6
license: mit
<!DOCTYPE html>
<meta charset="utf-8">
<title>SANKEY Experiment</title>
<style>
.node rect {
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;
}
.link:hover {
stroke-opacity: .5;
}
</style>
<body>
<script src="https://d3js.org/d3.v6.min.js"></script>
<script
src="https://unpkg.com/d3-sankey@0.12.3/dist/d3-sankey.min.js">
</script>
<script>
// set the dimensions and margins of the graph
var margin = {top: 10, right: 10, bottom: 10, left: 10},
width = 900 - margin.left - margin.right,
height = 300 - margin.top - margin.bottom;
// format variables
var formatNumber = d3.format(",.0f"), // zero decimal places
format = function(d) { return formatNumber(d); },
color = d3.scaleOrdinal(d3.schemeCategory10);
// append the svg object to the body of the page
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 + ")");
// Set the sankey diagram properties
var sankey = d3.sankey()
.nodeWidth(36)
.nodePadding(40)
.size([width, height]);
var path = sankey.links();
// load the data
d3.csv("sankey.csv").then(function(data) {
//set up graph in same style as original example but empty
sankeydata = {"nodes" : [], "links" : []};
data.forEach(function (d) {
sankeydata.nodes.push({ "name": d.source });
sankeydata.nodes.push({ "name": d.target });
sankeydata.links.push({ "source": d.source,
"target": d.target,
"value": +d.value });
});
// return only the distinct / unique nodes
sankeydata.nodes = Array.from(
d3.group(sankeydata.nodes, d => d.name),
([value]) => (value)
);
// loop through each link replacing the text with its index from node
sankeydata.links.forEach(function (d, i) {
sankeydata.links[i].source = sankeydata.nodes
.indexOf(sankeydata.links[i].source);
sankeydata.links[i].target = sankeydata.nodes
.indexOf(sankeydata.links[i].target);
});
// now loop through each nodes to make nodes an array of objects
// rather than an array of strings
sankeydata.nodes.forEach(function (d, i) {
sankeydata.nodes[i] = { "name": d };
});
graph = sankey(sankeydata);
// add in the links
var link = svg.append("g").selectAll(".link")
.data(graph.links)
.enter().append("path")
.attr("class", "link")
.attr("d", d3.sankeyLinkHorizontal())
.attr("stroke-width", function(d) { return d.width; });
// add the link titles
link.append("title")
.text(function(d) {
return d.source.name + " → " +
d.target.name + "\n" + format(d.value); });
// add in the nodes
var node = svg.append("g").selectAll(".node")
.data(graph.nodes)
.enter().append("g")
.attr("class", "node");
// add the rectangles for the nodes
node.append("rect")
.attr("x", function(d) { return d.x0; })
.attr("y", function(d) { return d.y0; })
.attr("height", function(d) { return d.y1 - d.y0; })
.attr("width", sankey.nodeWidth())
.style("fill", function(d) {
return d.color = color(d.name.replace(/ .*/, "")); })
.style("stroke", function(d) {
return d3.rgb(d.color).darker(2); })
.append("title")
.text(function(d) {
return d.name + "\n" + format(d.value); });
// add in the title for the nodes
node.append("text")
.attr("x", function(d) { return d.x0 - 6; })
.attr("y", function(d) { return (d.y1 + d.y0) / 2; })
.attr("dy", "0.35em")
.attr("text-anchor", "end")
.text(function(d) { return d.name; })
.filter(function(d) { return d.x0 < width / 2; })
.attr("x", function(d) { return d.x1 + 6; })
.attr("text-anchor", "start");
});
</script>
</body>
source target value
Barry Elvis 2
Frodo Elvis 2
Frodo Sarah 2
Barry Alice 2
Elvis Sarah 2
Elvis Alice 2
Sarah Alice 4
@juniord3
Copy link

Hi, thank you for your sharing. I wanted to add time slider which updates the date. I looked this code
http://www.d3noob.org/2013/02/sankey-diagrams-description-of-d3js-code.html.
How can i combine it with time slider?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment