Built with blockbuilder.org
xxxxxxxxxx
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://unpkg.com/d3-sankey"></script>
</head>
<body>
<svg id="diagram" height="150" width="600"></svg>
<button onclick="updateSankey()">Click Me!</button>
<style>
#diagram{
border: 1px solid black;
}
</style>
<script>
var target = 0;
var sankeyLinks;
var sankeyData = {nodes:[], links:[]};
calculateLinks();
initSankey();
updateSankey();
function initSankey() {
svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height");
formatNumber = d3.format(",.0f"),
format = function (d) { return formatNumber(d) + " %"; },
sankey = d3.sankey()
.nodeWidth(15)
.nodePadding(10)
.size([width - 1, height - 6])
t = d3.transition()
.duration(1500)
.ease(d3.easeLinear);
//set attributes for all links
titleGroup = svg.append("g")
.attr("class", "titles")
.attr("font-family", "sans-serif")
.attr("font-size", "150%");
diagram= svg.append("g")
.attr("class", "sankey")
svg.append("defs")
linkGroup = diagram.append("g")
.attr("class", "links")
.attr("fill", "none");
//set attributes for all nodes
nodeGroup = diagram.append("g")
.attr("class", "nodes")
.attr("font-family", "sans-serif")
.attr("font-size", 10);
}
function calculateLinks() {
if(target == 0)
{
target = 1;
sankeyLinks = [
{name: "firstsecond",source:0, target:1, value:5},
{name: "firstthird",source:0, target:2, value:10},
{name: "firstfourth",source:0, target:3, value:15}];
}
else
{
target = 0;
sankeyLinks = [
{name: "firstthird", source:0, target:2, value:15},
{name: "firstsecond", source:0, target:1, value:20},
{name: "firstfourth", source:0, target:3, value:10}
];
}
}
function updateSankey() {
calculateLinks();
sankeyData.links = sankeyLinks;
sankeyData.nodes = [{name: "first"}, {name:"second"}, {name:"third"}, {name: "fourth"}];
sankey(sankeyData);
var pathGradient = svg.select("defs").selectAll("linearGradient")
.data(sankeyData.links, function(d){ return d.name })
.enter()
.append("linearGradient")
.attr("id",function (d) {
return "grad" + d.name;
})
.attr("gradientUnit","userSpaceOnUse")
.attr("x1","0%")
.attr("x2","100%")
.attr("y1","0%")
.attr("y2","0%");
pathGradient.append("stop")
.attr("class","from")
.attr("offset","0%")
.attr("style", function (d) {
var color = setColor(d.source);
return "stop-color:" + color;
});
pathGradient.append("stop")
.attr("class","to")
.attr("offset","100%")
.attr("style",function (d) {
var color = setColor(d.target);
return "stop-color:" + color;
});
var links = linkGroup.selectAll('path')
.data(sankeyData.links, function(d){ return d.name });
//Set attributes for each link separately
var linksenter = links.enter()
.append("g")
.attr("id",function (d) {return "path" + d.name;})
.append("path")
.style("stroke", "#000")
.style("stroke-opacity", 0.15)
.attr("stroke-width", function (d) {return Math.max(1, d.width); })
.on("mouseover",function (d) {
var pathGroup = svg.select('#path' + d.name);
var path = pathGroup.select("path");
path.style("stroke","url(#grad" + d.name + ")")
.style("stroke-opacity","0.95");
})
.on("mouseout",function (d, id) {
pathGroup = svg.select('#path' + d.source.name + d.target.name);
var path = pathGroup.select("path");
path.style("stroke","#000")
.style("stroke-opacity","0.15");
})
linksenter.merge(links).attr("d", d3.sankeyLinkHorizontal())
links.transition(t)
.attr("d", d3.sankeyLinkHorizontal())
.attr("stroke-width", function (d) { return Math.max(1, d.width); })
.select('title')
.text(function (d) {
return d.source.name + " → " + d.target.name + "\n" + format(d.value); });
var nodes = nodeGroup.selectAll('.node')
.data(sankeyData.nodes, function(d){ return d.name });
var nodesEnter = nodes.enter()
.append("g")
.attr('class', 'node');
nodesEnter.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", function (d) {
var width = d.x1 - d.x0;
return width;
})
.attr("fill", setColor)
.attr("stroke", "#000")
.attr("fill-opacity", 0.5)
//specify Pop-Up when hovering over node
nodesEnter.append("title")
.text(function (d) { return d.name + "\n" + format(d.value); });
//Update selection
var nodesUpdate = nodes.transition(t);
//same as the links we have to state the methods again in the update
nodesUpdate.select("rect")
.attr("y", function (d) { return d.y0; })
.attr("x", function (d) { return d.x0; })
.attr("height", function (d) { return d.y1 - d.y0; });
nodesUpdate.select("title")
.text(function (d) { return d.name + "\n" + format(d.value); });
}
function setColor(d) {
switch (d.name) {
case "first":
return "#f00";
case "second":
return "#ff0";
case "third":
return "#f0f";
case "fourth":
return "#0ff";
default:
return "#0f0";
}
}
</script>
</body>
</html>
https://d3js.org/d3.v4.min.js
https://unpkg.com/d3-sankey