Built with blockbuilder.org
xxxxxxxxxx
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
<link rel="stylesheet" type="text/css" href="style.css">
<body>
<div id="sankey"></div>
</body>
<!--<script src='../../../../../_common/js/jquery/jquery-1.11.0.min.js'></script>-->
<!--<script src='../../../../../_common/js/d3/d3.v3.5.13.min.js'></script>-->
<!--<script type="text/javascript" src="./lib/sankey.js"></script>-->
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/gh/d3/d3-plugins/sankey/sankey.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/gh/caged/d3-tip/index.js"></script>
<script>
// create empty tooltip (div) that we later append html to for links and nodes
var tooltip = d3.select("body")
.append("div")
.style("position", "absolute")
.style("z-index", "10")
.style("visibility", "hidden") // to blend tooltip in and out
.style("background", "#fff")
.attr("class", "tooltip") //style in css
var tooltipnode = d3.select("body")
.append("div")
.style("position", "absolute")
.style("z-index", "10")
.style("visibility", "hidden")
.style("background", "#fff")
.attr('class', 'tooltipnode tooltipnode-nodes')
// .append('div', 'close_button')
//-----------------------------------------
// configuration desktop / mobile, calculate and/or set height depending on screen size
var mobile = /(preview\.)?(a|m)\.spiegel\.de/.test(location.hostname);
// mobile = true;
var initial_height;
if (mobile) { initial_height = 550; } // if mobile calculate height and width
else { initial_height = 750; }
var margin = {top: 10, right: 0, bottom: 10, left: 0}, //margins important for numbers on top and tooltip, see css file
width = window.innerWidth - margin.left - margin.right,
height = initial_height - margin.top - margin.bottom;
var window_width = parseInt(d3.select("body").style("width"),10);
var window_height = parseInt(d3.select("body").style("height"),10);
// format numbers in D3 so that they have a . as a thousand seperator. In case the numbers are money you could add in Euro or Dollar signs here and use a different D3 format and substitute the dollar sign, see https://bl.ocks.org/zanarmstrong/05c1e95bf7aa16c4768e, einmal für link auflistung in tooltips für nodes und einmal für tooltips links
function formatAmount(val) {
return d3.format(",d")(val).replace(',', '.').replace(',', '.');
}
function formatAmountLinks(d) {
return d3.format(",d")(d.value).replace(',', '.').replace(',', '.');
}
// calculate percentages for links, return <1% for anything rounded to 0
function roundPercentages(d) {
if ((Math.round(d.value / d.source.value * 100)) < 1)
{return "<1"}
else {return Math.round(d.value / d.source.value * 100)}
}
// append the svg canvas to the page
var svg = d3.select("#sankey").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.attr("class", "sankey")
.append("g");
// .attr("transform",
// "translate(" + margin.left + "," + margin.top + ")");
// Set the sankey diagram properties
var sankey = d3.sankey()
.nodeWidth(36)
.nodePadding(14)
.size([width, height]);
var path = sankey.link();
// get data from external csv file (need to change filename here), must be in same folder, otherwise have to change pathname
d3.csv("data1.csv", function(error, data) {
var currentData = data;
function processData(data) {
var graph = {"nodes" : [], "links" : []}; //this creates empty nodes and links
data.forEach(function (d) {
graph.nodes.push({ "name": d.source,
"shortname": d.shortname });
graph.nodes.push({ "name": d.target,
"shortname": d.shortname });
graph.links.push({ "source": d.source,
"target": d.target,
"value": +d.value });
}); // this fills empty nodes and links with data
graph.nodesNew = d3.nest()
.key(function (d) { return d.name; })
.rollup(function (d) { return d[0].shortname; }) // returns the shortname of the first element of that key
.map(graph.nodes);
// return only the distinct / unique nodes = meaning all links will be added up to one node on each side of the diagram which is super handy as we don't need sums for the nodes, as it basically sums up the links right here whey! This is also a great way of checking whether all the entered data is correct: check the sums with the sums you've got (in case you've got any that is)
graph.nodes = d3.keys(d3.nest()
.key(function (d) { return d.name; })
.map(graph.nodes));
// loop through each link replacing the text with its index from node - I think this is for the colours ?!
graph.links.forEach(function (d, i) {
graph.links[i].source = graph.nodes.indexOf(graph.links[i].source);
graph.links[i].target = graph.nodes.indexOf(graph.links[i].target);
});
//now loop through all 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,
"shortname": d };
});
return graph;
}
// All tooltip functions
// tooltip for links
function mousetooltiplink(d) {
d3.select(".tooltip") // selects empty div we created beforehand
.style("left", function(){
var tt_margin_right = window_width - d3.event.pageX;
if (tt_margin_right < 250){ return d3.event.pageX - 210 + "px"; }
else { return d3.event.pageX + 10 + "px"; }
}) //checks how much space there is and decides where to place the tooltip - left or right of the mouse. You have to adapt this code depending on the size of your tooltip (i.e. change settings for tt_margin_right etc)!
.style("top", function(){
var tt_margin_top = window_height - d3.event.pageY;
if (tt_margin_top < -350){ return d3.event.pageY - 90 + "px"; }
else { return d3.event.pageY + 10 + "px"; }
}) //calculates margin, checks how much space there is and decides where to place the tooltip - top or bottom of mouse. You have to adapt this code depending on the size of your tooltip!
}
// tooltip for nodes
function mousetooltip(d) {
d3.select(".tooltipnode")
.style("left", function(){
var tt_margin_right = window_width - d3.event.pageX;
if (tt_margin_right < 170){ return d3.event.pageX - 220 + "px"; }
else { return d3.event.pageX + 20 + "px"; }
}) //checks how much space there is and decides where to place the tooltip - left or right of the mouse. You have to adapt this code depending on the size of your tooltip (i.e. change settings for tt_margin_right etc)!
.style("top", function(){
var tt_margin_top = window_height - d3.event.pageY;
if (tt_margin_top < -350){ return d3.event.pageY - 280 + "px"; }
else { return d3.event.pageY + 40 + "px"; }
}) //calculates margin, checks how much space there is and decides where to place the tooltip - top or bottom of mouse. You have to adapt this code depending on the size of your tooltip!
}
// shows tooltip for links, aka sets visibility to visible and inserts html in div
function showtooltip(d) {
d3.select(".tooltip")
.style("visibility", "visible")
// Here comes...if loops for all the special cases etc, checks which source and/or target node are there and fills text for link tooltip accordingly
.html(function() {
if (d.source.name == "Nichtwaehler_2013" && d.target.name == "Nichtwaehler_2017") {
return "<b>" + formatAmountLinks(d) + "</b> ehemalige <b>Nichtwähler</b> (" + roundPercentages(d) + " %) gingen diesmal ebenfalls nicht zur Wahl";
} // returns format for number that uses d.value as a variable and adds text and calculates percentage
if (d.source.name == "Nichtwaehler_2013" && d.target.name == "Verstorbene_2017") {
return "<b>" + formatAmountLinks(d) + "</b> ehemalige <b>Nichtwähler</b> (" + roundPercentages(d) + " %) sind seit der letzten Wahl verstorben";
}
if (d.source.name == "Nichtwaehler_2013" && d.target.name == "Weggezogene_2017") {
return "<b>" + formatAmountLinks(d) + "</b> ehemalige <b>Nichtwähler</b> (" + roundPercentages(d) + " %) sind weggezogen";
}
if (d.source.name == "Nichtwaehler_2013" && d.target.name == "Andere_2017") {
return "<b>" + formatAmountLinks(d) + "</b> ehemalige <b>Nichtwähler</b> (" + roundPercentages(d) + " %) wählten diesmal <b>eine andere Partei</b>";
}
if (d.source.name == "Erstwaehler_2013" && d.target.name == "Andere_2017") {
return "<b>" + formatAmountLinks(d) + "</b> Erstwähler</b> (" + roundPercentages(d) + " %) wählten diesmal <b>eine andere Partei</b>";
}
if (d.source.name == "Erstwaehler_2013" && d.target.name == "Nichtwaehler_2017") {
return "<b>" + formatAmountLinks(d) + "</b> Erstwähler</b> (" + roundPercentages(d) + " %) gingen diesmal nicht zur Wahl";
}
if (d.source.name == "Erstwaehler_2013" && d.target.name == "Verstorbene_2017") {
return "<b>" + formatAmountLinks(d) + "</b> Erstwähler</b> (" + roundPercentages(d) + " %) sind seit der letzten Wahl verstorben";
}
if (d.source.name == "Erstwaehler_2013" && d.target.name == "Weggezogene_2017") {
return "<b>" + formatAmountLinks(d) + "</b> Erstwähler</b> (" + roundPercentages(d) + " %) sind weggezogen";
}
if (d.source.name == "Zugezogene_2013" && d.target.name == "Andere_2017") {
return "<b>" + formatAmountLinks(d) + "</b> Zugezogene</b> (" + roundPercentages(d) + " %) wählten diesmal <b>eine andere Partei</b>";
}
if (d.source.name == "Zugezogene_2013" && d.target.name == "Verstorbene_2017") {
return "<b>" + formatAmountLinks(d) + "</b> Zugezogene</b> (" + roundPercentages(d) + " %) sind seit der letzten Wahl verstorben";
}
if (d.source.name == "Zugezogene_2013" && d.target.name == "Weggezogene_2017") {
return "<b>" + formatAmountLinks(d) + "</b> Zugezogene</b> (" + roundPercentages(d) + " %) sind weggezogen";
}
if (d.source.name == "Zugezogene_2013" && d.target.name == "Nichtwaehler_2017") {
return "<b>" + formatAmountLinks(d) + "</b> Zugezogene</b> (" + roundPercentages(d) + " %) gingen diesmal nicht zur Wahl";
}
if (d.source.name == "Andere_2013" && d.target.name == "Nichtwaehler_2017") {
return "<b>" + formatAmountLinks(d) + "</b> ehemalige <b>Wähler anderer Parteien</b> (" + roundPercentages(d) + " %) gingen diesmal nicht zur Wahl";
}
if (d.source.name == "Nichtwaehler_2013") {
return "<b>" + formatAmountLinks(d) + "</b> ehemalige <b>Nichtwähler</b> (" + roundPercentages(d) + " %) wählten diesmal die <b>" + d.target.name.slice(0, -5).replace("ae","ä").replace("ue","ü") + "</b>";
}
if (d.target.name == "Nichtwaehler_2017") {
return "<b>" + formatAmountLinks(d) + "</b> ehemalige <b>" + d.source.name.slice(0, -5).replace("ae","ä").replace("ue","ü") + "</b>-Wähler (" + roundPercentages(d) + " %) gingen diesmal nicht wählen";
}
if (d.source.name == "Andere_2013" && d.target.name == "Andere_2017") {
return "<b>" + formatAmountLinks(d) + "</b> ehemalige <b>Wähler anderer Parteien</b> (" + roundPercentages(d) + " %) wählten diesmal <b>eine andere Partei</b>";
}
if (d.source.name == "Andere_2013" && d.target.name == "Weggezogene_2017") {
return "<b>" + formatAmountLinks(d) + "</b> ehemalige <b>Wähler anderer Parteien</b> (" + roundPercentages(d) + " %) sind weggezogen";
}
if (d.source.name == "Andere_2013" && d.target.name == "Verstorbene_2017") {
return "<b>" + formatAmountLinks(d) + "</b> ehemalige <b>Wähler anderer Parteien</b> (" + roundPercentages(d) + " %) sind seit der letzten Wahl verstorben";
}
if (d.target.name == "Andere_2017") {
return "<b>" + formatAmountLinks(d) + "</b> ehemalige <b>" + d.source.name.slice(0, -5).replace("ae","ä").replace("ue","ü") + "</b>-Wähler (" + roundPercentages(d) + " %) wählten diesmal eine andere Partei";
}
if (d.source.name == "Andere_2013") {
return "<b>" + formatAmountLinks(d) + "</b> ehemalige <b>Wähler anderer Parteien</b> (" + roundPercentages(d) + " %) wählten diesmal die <b>" + d.target.name.slice(0, -5).replace("ae","ä").replace("ue","ü") + "</b>";
}
if (d.source.name == "Zugezogene_2013") {
return "<b>" + formatAmountLinks(d) + "</b> Zugezogene</b> (" + roundPercentages(d) + "%) wählten diesmal die <b>" + d.target.name.slice(0, -5).replace("ae","ä").replace("ue","ü") + "</b>";
}
if (d.source.name == "Erstwaehler_2013") {
return "<b>" + formatAmountLinks(d) + "</b> Erstwähler</b> (" + roundPercentages(d) + " %) wählten diesmal die <b>" + d.target.name.slice(0, -5).replace("ae","ä").replace("ue","ü") + "</b>";
}
if (d.target.name == "Verstorbene_2017") {
return "<b>" + formatAmountLinks(d) + "</b> ehemalige <b>" + d.source.name.slice(0, -5).replace("ae","ä").replace("ue","ü") + "</b>-Wähler (" + roundPercentages(d) + " %) sind seit der letzten Wahl verstorben";
}
if (d.target.name == "Weggezogene_2017") {
return "<b>" + formatAmountLinks(d) + "</b> ehemalige <b>" + d.source.name.slice(0, -5).replace("ae","ä").replace("ue","ü") + "</b>-Wähler (" + roundPercentages(d) + " %) sind weggezogen";
}
if (d.source.name.slice(0, -5).replace("ae","ä").replace("ue","ü") == d.target.name.slice(0, -5).replace("ae","ä").replace("ue","ü")) {
return "<b>" + formatAmountLinks(d) + "</b> ehemalige <b>" + d.source.name.slice(0, -5).replace("ae","ä").replace("ue","ü") + "</b>-Wähler (" + roundPercentages(d) + " %) wählten wieder die <b>" + d.target.name.slice(0, -5).replace("ae","ä").replace("ue","ü") + "</b>";
}
else {
return "<b>" + formatAmountLinks(d) + "</b> ehemalige <b>" + d.source.name.slice(0, -5).replace("ae","ä").replace("ue","ü") + "</b>-Wähler (" + roundPercentages(d) + " %) wählten diesmal die <b>" + d.target.name.slice(0, -5).replace("ae","ä").replace("ue","ü") + "</b>";
}
})
}
// Hide tooltip for links (function gets called on mouseover)
function hidetooltip(d) {
d3.select(".tooltip").style("visibility", "hidden")
}
// opacity Funktionen
function highlight(d) {
d3.select(d)
.style("stroke-opacity", 1)
}
function opacity(d) {
d3.select(d)
.style("stroke-opacity", 0.2)
}
function opacitynodes(d, mouseover_node) {
var is_source = d3.select(mouseover_node).classed("source");
if (is_source) {
var selector = d.name.replace("_2013","");
d3.selectAll('path.' + 'coming_from_' + selector).style("stroke-opacity", 1);
}
else{
var selector = d.name.replace("_2017","");
d3.selectAll('path.' + 'going_to_' + selector).style("stroke-opacity", 1);
}
//d3.selectAll('path.' + 'coming_from_' + selector + 'going_to_' + selector).style("stroke-opacity", 1);
}
function opacitynodeshide(d, mouseover_node) {
var is_source = d3.select(mouseover_node).classed("source");
if (is_source) {
var selector = d.name.replace("_2013","");
d3.selectAll('path.' + 'coming_from_' + selector).style("stroke-opacity", 0.2);
}
else{
var selector = d.name.replace("_2017","");
d3.selectAll('path.' + 'going_to_' + selector).style("stroke-opacity", 0.2);
}
}
// Tooltip für die Nodes (Tabelle)
function showtooltipnodes(d) {
d3.select(".tooltipnode")
.style("visibility", "visible")
.html(function() {
var object = d3.entries(d),
nodeName = object[0].value,
linksTo = object[2].value,
linksFrom = object[3].value,
html;
if (nodeName == "Andere_2017") {
html = '<div class="table-wrapper">'+
'<div id="tooltip_header" ><table><tr><th>' + '<h1>Andere Parteien</h1></th><th><h3>' +formatAmountLinks(d)+'</h3></th></tr></table>So verhielten sich diese Wähler 2013:</b></div>'+
'<table>';
for (i in linksFrom) {
html += '<tr>'+
'<td class="col-left">'+linksFrom[i].source.name.slice(0, -5).replace("ae","ä").replace("ue","ü")+'</td>'+
'<td align="right">'+formatAmount(linksFrom[i].value)+'</td>'+
'</tr>';
};
}
else if (nodeName == "Nichtwaehler_2017") {
html = '<div class="table-wrapper">'+
'<div id="tooltip_header" ><table><tr><th>' + '<h1>'+nodeName.slice(0, -5).replace("ae","ä").replace("ue","ü")+ ' </h1></th><th><h3>' +formatAmountLinks(d)+'</h3></th></tr></table>So verhielt sich diese Gruppe 2013:</b></div>'+
'<table>';
for (i in linksFrom) {
html += '<tr>'+
'<td class="col-left">'+linksFrom[i].source.name.slice(0, -5).replace("ae","ä").replace("ue","ü")+'</td>'+
'<td align="right">'+formatAmount(linksFrom[i].value)+'</td>'+
'</tr>';
};
}
else if (nodeName == "Verstorbene_2017") {
html = '<div class="table-wrapper">'+
'<div id="tooltip_header" ><table><tr><th>' + '<h1>Verstorbene</h1></th><th><h3>' +formatAmountLinks(d)+'</h3></th></tr></table>Wähler dieser Parteien sind seit 2013 verstorben:</b></div>'+
'<table>';
for (i in linksFrom) {
html += '<tr>'+
'<td class="col-left">'+linksFrom[i].source.name.slice(0, -5).replace("ae","ä").replace("ue","ü")+'</td>'+
'<td align="right">'+formatAmount(linksFrom[i].value)+'</td>'+
'</tr>';
};
}
else if (nodeName == "Weggezogene_2017") {
html = '<div class="table-wrapper">'+
'<div id="tooltip_header" ><table><tr><th>' + '<h1>'+nodeName.slice(0, -5).replace("ae","ä").replace("ue","ü")+ ' </h1></th><th><h3>' +formatAmountLinks(d)+'</h3></th></tr></table>Wähler dieser Parteien sind seit 2013 weggezogen:</b></div>'+
'<table>';
for (i in linksFrom) {
html += '<tr>'+
'<td class="col-left">'+linksFrom[i].source.name.slice(0, -5).replace("ae","ä").replace("ue","ü")+'</td>'+
'<td align="right">'+formatAmount(linksFrom[i].value)+'</td>'+
'</tr>';
};
}
else if (nodeName == "SPD_2013" || nodeName == "Union_2013" || nodeName == "FDP_2013" || nodeName == "AfD_2013" || nodeName == "Gruene_2013" || nodeName == "Linke_2013") {
html = '<div class="table-wrapper">'+
'<div id="tooltip_header" ><table><tr><th>' + '<h1>'+nodeName.slice(0, -5).replace("ae","ä").replace("ue","ü")+ ' </h1></th><th><h3>' +formatAmountLinks(d)+'</h3></th></tr></table>So verhielten sich diese Wähler 2017:</b></div>'+
'<table>';
for (i in linksTo) {
html += '<tr>'+
'<td class="col-left">'+linksTo[i].target.name.slice(0, -5).replace("ae","ä").replace("ue","ü")+'</td>'+
'<td align="right">'+formatAmount(linksTo[i].value)+'</td>'+
'</tr>';
};
}
else if (nodeName == "Andere_2013") {
html = '<div class="table-wrapper">'+
'<div id="tooltip_header" ><table><tr><th>' + '<h1>Andere Parteien</h1></th><th><h3>' +formatAmountLinks(d)+'</h3></th></tr></table>So verhielten sich diese Wähler 2017:</b></div>'+
'<table>';
for (i in linksTo) {
html += '<tr>'+
'<td class="col-left">'+linksTo[i].target.name.slice(0, -5).replace("ae","ä").replace("ue","ü")+'</td>'+
'<td align="right">'+formatAmount(linksTo[i].value)+'</td>'+
'</tr>';
};
}
else if (nodeName == "Erstwaehler_2013") {
html = '<div class="table-wrapper">'+
'<div id="tooltip_header" ><table><tr><th>' + '<h1>'+nodeName.slice(0, -5).replace("ae","ä").replace("ue","ü")+ ' </h1></th><th><h3>' +formatAmountLinks(d)+'</h3></th></tr></table>So verhielten sich diese Wähler 2017:</b></div>'+
'<table>';
for (i in linksTo) {
html += '<tr>'+
'<td class="col-left">'+linksTo[i].target.name.slice(0, -5).replace("ae","ä").replace("ue","ü")+'</td>'+
'<td align="right">'+formatAmount(linksTo[i].value)+'</td>'+
'</tr>';
};
}
else if (nodeName == "Nichtwaehler_2013") {
html = '<div class="table-wrapper">'+
'<div id="tooltip_header" ><table><tr><th>' + '<h1>'+nodeName.slice(0, -5).replace("ae","ä").replace("ue","ü")+ ' </h1></th><th><h3>' +formatAmountLinks(d)+'</h3></th></tr></table>So verhielt sich diese Gruppe 2017:</b></div>'+
'<table>';
for (i in linksTo) {
html += '<tr>'+
'<td class="col-left">'+linksTo[i].target.name.slice(0, -5).replace("ae","ä").replace("ue","ü")+'</td>'+
'<td align="right">'+formatAmount(linksTo[i].value)+'</td>'+
'</tr>';
};
}
else if (nodeName == "Zugezogene_2013") {
html = '<div class="table-wrapper">'+
'<div id="tooltip_header" ><table><tr><th>' + '<h1>'+nodeName.slice(0, -5).replace("ae","ä").replace("ue","ü")+ ' </h1></th><th><h3>' +formatAmountLinks(d)+'</h3></th></tr></table>So verhielten sich diese Wähler 2017:</b></div>'+
'<table>';
for (i in linksTo) {
html += '<tr>'+
'<td class="col-left">'+linksTo[i].target.name.slice(0, -5).replace("ae","ä").replace("ue","ü")+'</td>'+
'<td align="right">'+formatAmount(linksTo[i].value)+'</td>'+
'</tr>';
};
}
else {
html = '<div class="table-wrapper">'+
'<div id="tooltip_header" ><table><tr><th>' + '<h1>'+nodeName.slice(0, -5).replace("ae","ä").replace("ue","ü")+ ' </h1></th><th><h3>' +formatAmountLinks(d)+'</h3></th></tr></table>So verhielten sich diese Wähler 2013:</b></div>'+
'<table>';
for (i in linksFrom) {
html += '<tr>'+
'<td class="col-left">'+linksFrom[i].source.name.slice(0, -5).replace("ae","ä").replace("ue","ü")+'</td>'+
'<td align="right">'+formatAmount(linksFrom[i].value)+'</td>'+
'</tr>';
};
}
html += '</table></div>';
return html;
});
}
renderSankey();
function hidetooltipnodes() {
d3.select(".tooltipnode").style("visibility", "hidden");
d3.select(".tooltip").style("visibility", "hidden");
}
function renderSankey() {
// get width from current window width - funciton is triggered initially and on resize
width = window.innerWidth - margin.left - margin.right;
d3.select('body').selectAll('g').remove();
graph = processData(currentData);
myLinks = graph.links;
myNodes = graph.nodes;
svg = d3.select('.sankey')
.attr("width", width)
.attr("height", height)
.append("g");
sankey = d3.sankey()
.size([width, height])
.nodes(myNodes)
.links(myLinks)
.layout(0); //automatically the nodes are ordered according to their order of appearance in the csv, if you insert a number here the code will iterate the order, the higher the number, the more variations
path = sankey.link();
// Links hinzufügen, Links Klasse für Farbe und opacity zuweisen, hover Funktionen (Tooltip und opacity)
link = svg.append("g").selectAll(".link")
.data(myLinks)
.enter().append("path")
.attr("class", "link")
.attr("class", function(d){
var selector_coming = d.source.name.replace("_2013","");
var selector_going = d.target.name.replace("_2017","");
return(selector_coming + " " + "coming_from_" + selector_coming + " " + "going_to_" + selector_going);
})
.attr("d", path)
.style("stroke-width", function(d) { return Math.max(1, d.dy); })
.sort(function(a, b) { return b.dy - a.dy; })
.on("click", function(){
hidetooltipnodes();
});
// deactivating tooltips for links on mobile. not enough screen space
if (!mobile){
link.on("mouseover", function(d){
//if (d.source.name === "Union_2013") { d3.selectAll("#Union_2013,#Union_2017").style("fill", "white"); }
showtooltip(d);
highlight(this, d);
})
.on("mousemove", function(d){
mousetooltiplink(d);})
.on("mouseout", function(d){
//d3.selectAll("text").style("fill", "black");
hidetooltip(d);
opacity(this, d);
});
}
// insert axis labels as title (left and right)
// first number (to the left)
svg.append("text")
.attr("x", 0)
.attr("y", - (margin.top / 2))
.attr("class", "number1")
.text("2013");
// second number (to the right)
svg.append("text")
// .attr("x", (width / 1.05))
.attr("x", width)
.attr("y", 0- (margin.top / 2))
.attr("class", "number2")
.text("2017");
// insert nodes
node = svg.append("g").selectAll(".node")
.data(myNodes)
.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")"; });
// insert rectangles for nodes, assign colours according to class
node.append("rect")
.attr("height", function(d) { return d.dy; })
.attr("width", sankey.nodeWidth())
.attr("class", function(d) {
if (d.sourceLinks.length > 0) {
var type = "source";
var party = d.name.replace("_2013","");
}
else {
var type = "target";
var party = d.name.replace("_2017","");
}
return(type + " " + party)
})
.on('mouseover', function(d){
//if (d.name === "Union_2017" || d.name === "Union_2013") { d3.selectAll("#Union_2013,#Union_2017").style("fill", "white"); }
opacitynodes(d, this);
showtooltipnodes(d);
})
.on("mousemove", function(d){
mousetooltip(d);
})
.on('mouseout', function(d){
//d3.selectAll("text").style("fill", "black");
opacitynodeshide(d, this);
hidetooltipnodes();
});
if (true) {
node.append("text")
.attr("x", -6)
.attr("y", function(d) { return d.dy / 2; })
.attr("dy", ".35em")
.attr("text-anchor", "end")
.attr("transform", null)
.attr("id", function(d){ return d.name; })
.text(function(d) { return d.name.slice(0, -5).replace("ae","ä").replace("ue","ü"); })
.style("fill", "white")
.style("text-shadow", "1px 1px 3px black")
.filter(function(d) { return d.x < width / 2; })
.attr("x", 6 + sankey.nodeWidth())
.attr("text-anchor", "start");
} else {
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.slice(0, -5).replace("ae","ä").replace("ue","ü"); })
.filter(function(d) { return d.x < width / 2; })
.attr("x", -6)
.attr("text-anchor", "end");
}
}
d3.select(window).on('resize', function(){
window_width = parseInt(d3.select("body").style("width"),10);
window_height = parseInt(d3.select("body").style("height"),10);
renderSankey();
});
});
</script>
Updated missing url https://cdn.rawgit.com/d3/d3-plugins/master/sankey/sankey.js to https://cdn.jsdelivr.net/gh/d3/d3-plugins/sankey/sankey.js
Updated missing url https://cdn.rawgit.com/Caged/d3-tip/master/index.js to https://cdn.jsdelivr.net/gh/caged/d3-tip/index.js
https://d3js.org/d3.v3.min.js
https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js
https://cdn.rawgit.com/d3/d3-plugins/master/sankey/sankey.js
https://cdn.rawgit.com/Caged/d3-tip/master/index.js