Skip to content

Commit

Permalink
added sankey diagrams
Browse files Browse the repository at this point in the history
  • Loading branch information
stefanomoret committed Aug 15, 2018
1 parent 7c25969 commit 715c4b3
Show file tree
Hide file tree
Showing 4 changed files with 876 additions and 9 deletions.
263 changes: 263 additions & 0 deletions output/sankey/SES_sankey.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,263 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>SANKEY</title>

<style>
<!-- ********************* CSS Styling **************************-->
html,body{min-height:100%;}

#chart { height: 500px;}

/* Change here the font style for the chart*/
body {
font-family:Utopia, serif;
font-size:62.5%;
}

/*------------------------------------------------------------*/
/*------------ Customization of Rectangle Nodes --------------*/
/*------------------------------------------------------------*/
.node rect {
cursor : move; /* Cursor changes its form */
fill-opacity : .6; /* Opacity of rectangle node color. Recall colors are defined in json-like graph */
shape-rendering : crispEdges;
}
.node text {
pointer-events : none;
text-shadow : none !important;
}
/*------------------------------------------------------------*/
/*----Changing style of node while hovering over it ----------*/
/*------------------------------------------------------------*/
/* define if when hovering the color is lighter or stronger */
.node rect:hover {
fill-opacity : 0.8;
}
/*------------------------------------------------------------*/
/*------------------ Customization of Links ------------------*/
/*------------------------------------------------------------*/
.link {
fill : none;
stroke : #336666;
stroke-opacity : .8;
}
/*------------------------------------------------------------*/
/*------ Changing style of link while hovering over it -------*/
/*------------------------------------------------------------*/
/* define if when hovering the color is lighter or stronger */
.link:hover {
stroke-opacity : 0.8 !important;
}
/*------------------------------------------------------------*/
</style>

<body onload = "resize()">
<!-- Removed title
<h1 style = "font-family:Sans-serif;font-size:200%"> Sankey diagram example</h1>
-->
<div id = "chart"></div>
<!-- ********************* Javascript Functionality **************************-->
<script src = "d3.min.js"></script>
<script src = "Sankey.js"></script>
<script>

// the start the script begins by defining a range of variables that will be used

var margin = {top: 10, right: 10, bottom: 10, left: 10},
width = 1220 - margin.left - margin.right,
height = 760 - margin.top - margin.bottom;


var formatNumber = d3.format(",.2f"),
format = function(d) { return formatNumber(d); },
//format is a function that returns a given number formatted with formatNumber
//as well as a space and our units of choice.
//This is used to display the values for the links and nodes later in the script.
color = d3.scale.category20();

// append the svg canvas to the page
var svg = d3.select("#chart") // select the chart element in the document
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g") // container element for grouping together related graphics elements.
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

// Set the Sankey diagram properties
var sankey = d3.sankey()
.nodeWidth(50) // sets the pixel width of all nodes (heights are variable, widths are fixed)
.nodePadding(10) // sets the minimum vertical pixel spacing between nodes
.size([width, height]); // sets the width and height of the diagram in pixels

var path = sankey.link();

// load the csv file from the data directory.
d3.csv("input2sankey.csv", function(error, data) {
// declare `graph` to consist of two empty arrays called `nodes` and `links`.
graph = {"nodes" : [], "links" : []};
// Take the `data` loaded with the csv file and for each row loads variables
// for the `source` and `target` into the `nodes` array then for each row loads
// variables for the `source` `target` and `value` into the `links` array.

data.forEach(function (d) {
graph.nodes.push({ "name": d.source });
graph.nodes.push({ "name": d.target });
graph.links.push({ "source": d.source,
"target": d.target,
"realValue": d.realValue,
"layerId": d.layerId,
"layerColor": d.layerColor,
"layerUnit": d.layerUnit});
});

// routine which retursn only the distinct / unique nodes
graph.nodes = d3.keys(d3.nest()
.key(function (d) { return d.name; })
.map(graph.nodes));

// now loop through each nodes to make nodes an array of objects
// rather than an array of strings
graph.nodes.forEach(function (d, i) {
graph.nodes[i] = { "name": d };
});


// for each link define "value" as equal to "realValue" this is needed in case of scaling the links thickness
graph.links.forEach(function(link,index) {link.value = link.realValue;})

// initializes links source and target. A lookupf node name must be performed for each links node
graph.links.forEach(function (l,i) {
// bounds the links source with the node object having the same name
l.source = graph.nodes.filter(function(n) { //filter nodes with the same name
return n.name === l.source;
})[0]; //get the first filtered element since the name is sensed to be unique
// bounds the links target with the node object having the same name
l.target = graph.nodes.filter(function(n) { // filter nodes with the same name
return n.name === l.target;
})[0]; // get the first foltered element since the name is sensed to be unique
});

sankey
.nodes(graph.nodes)
.links(graph.links)
.layout(32);

// ----------------------------------------------------------------------------
// Add the links
// ----------------------------------------------------------------------------

var link = svg.append("g").selectAll(".link")
.data(graph.links)
.enter()
.append("path")
.attr("class", "link")
.attr("id",function(d,i) { return "linkLabel" + i; })
.attr("d", path)
.style("stroke",function(d) {return d.layerColor; }) //setting color of link based on its layer color
.style("stroke-width", function (d) {
return Math.max(1, d.dy);
})
.sort(function (a, b) {
return b.dy - a.dy;
})

// Adding values in links. Taken from:
// http://stackoverflow.com/questions/33492736/show-text-on-google-chart-sankey-diagram

var labelText = svg.selectAll(".labelText")
.data(graph.links)
.enter()
.append("text")
.attr("class","labelText")
.attr("dx",40)
.attr("dy",2)
.append("textPath")
.attr("xlink:href",function(d,i) { return "#linkLabel" + i;})
.text(function(d,i) {
return format(d.value);});

// ----------------------------------------------------------------------------
// add the link titles showing the real flow Value + unit + layer
// ----------------------------------------------------------------------------
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")
.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)); // the dragmove function is laid out at the end of the code

// ----------------------------------------------------------------------------
// 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 "#D3D3D3" }) // define node color (same for all)
//.style("stroke", function(d) { return d3.rgb(d.color).darker(2); }) // rectangle border color
.append("title")
.text(function(d) { return d.name+ "\n" + format(d.value); });



// ----------------------------------------------------------------------------
// add in the title for the nodes
// ----------------------------------------------------------------------------
node.append("text")
// Case 1: normally text is aligned left at the start of the node
.attr("x", 0)
//.attr("y", function(d) { return 10; }) // put node name 10px below the top of the node
.attr("y", function(d) { return d.dy / 2; }) // put node name in the middle of its height
.attr("dy", ".35em") // What is it needed for?
.attr("text-anchor", "left")
.attr("transform", null)
.style("font-size","0.9rem")
.text(function(d) { return d.name; })
// Case 2: if in the center of the diagram, align center
.filter(function(d) { return d.x > width * .05})
.attr("x", 0 + sankey.nodeWidth() / 2)
//.text(function(d) { return d.name; }) // prints the name of the node
.attr("text-anchor", "middle")
// Case 3: if at the right end of the diagram, anchor and align right
.filter(function(d) { return d.x > width * .95; })
.attr("x", 0 + sankey.nodeWidth())
//.text(function(d) { return d.name; }) // prints the name of the node
.attr("text-anchor", "end");

// if you want the total value displayed for each node --> uncomment
/*node.append("text")
.attr("x", 0)
.attr("y", function(d) { return (d.dy / 2)+20; }) // put node name in the middle of its height
.attr("dy", ".35em")
.attr("text-anchor", "start")
.attr("transform", null)
.style("font-size","0.9rem")
.text(function(d) { return format(d.value); }) */


// ----------------------------------------------------------------------------
// the function for moving the nodes vertically and horizontally
// ----------------------------------------------------------------------------
function dragmove(d) {
d3.select(this).attr("transform",
"translate(" + ( d.x = Math.max(0, Math.min(width - d.dx, d3.event.x))) + ","
+ ( d.y = Math.max(0, Math.min(height - d.dy, d3.event.y))) + ")");
sankey.relayout();
link.attr("d", path);
};

});
</script>
</body>
</html>
5 changes: 5 additions & 0 deletions output/sankey/d3.min.js

Large diffs are not rendered by default.

Loading

0 comments on commit 715c4b3

Please sign in to comment.