Skip to content

Instantly share code, notes, and snippets.

@Marie-Ella
Created September 25, 2017 06:00
Show Gist options
  • Save Marie-Ella/2d09b3575b2cd058108224eb47995145 to your computer and use it in GitHub Desktop.
Save Marie-Ella/2d09b3575b2cd058108224eb47995145 to your computer and use it in GitHub Desktop.
diagramm
license: mit
source target value shortname
SPD_2015 SPD_2017 1680000 SPD
SPD_2015 CDU_2017 380000 CDU
SPD_2015 Gruene_2017 70000 Gruene
SPD_2015 FDP_2017 180000 FDP
SPD_2015 Linke_2017 80000 Linke
SPD_2015 AfD_2017 60000 AfD
SPD_2015 Andere_2017 40000 Andere
SPD_2015 Nichtwaehler_2017 190000 Nichtwaehler
SPD_2015 Verstorbene_2017 270000 Verstorbene
SPD_2015 Weggezogene_2017 100000 Weggezogene
CDU_2015 SPD_2017 70000 SPD
CDU_2015 CDU_2017 1380000 CDU
CDU_2015 Gruene_2017 10000 Gruene
CDU_2015 FDP_2017 190000 FDP
CDU_2015 Linke_2017 10000 Linke
CDU_2015 AfD_2017 50000 AfD
CDU_2015 Andere_2017 10000 Andere
CDU_2015 Nichtwaehler_2017 70000 Nichtwaehler
CDU_2015 Verstorbene_2017 200000 Verstorbene
CDU_2015 Weggezogene_2017 60000 Weggezogene
Gruene_2015 SPD_2017 180000 SPD
Gruene_2015 CDU_2017 100000 CDU
Gruene_2015 Gruene_2017 260000 Gruene
Gruene_2015 FDP_2017 40000 FDP
Gruene_2015 Linke_2017 60000 Linke
Gruene_2015 AfD_2017 10000 AfD
Gruene_2015 Andere_2017 30000 Andere
Gruene_2015 Nichtwaehler_2017 110000 Nichtwaehler
Gruene_2015 Verstorbene_2017 40000 Verstorbene
Gruene_2015 Weggezogene_2017 40000 Weggezogene
FDP_2015 SPD_2017 20000 SPD
FDP_2015 CDU_2017 140000 CDU
FDP_2015 Gruene_2017 10000 Gruene
FDP_2015 FDP_2017 350000 FDP
FDP_2015 Linke_2017 10000 Linke
FDP_2015 AfD_2017 30000 AfD
FDP_2015 Nichtwaehler_2017 30000 Nichtwaehler
FDP_2015 Verstorbene_2017 60000 Verstorbene
FDP_2015 Weggezogene_2017 20000 Weggezogene
Linke_2015 SPD_2017 20000 SPD
Linke_2015 CDU_2017 10000 CDU
Linke_2015 Linke_2017 100000 Linke
Linke_2015 AfD_2017 10000 AfD
Linke_2015 Andere_2017 10000 Andere
Linke_2015 Nichtwaehler_2017 10000 Nichtwaehler
Linke_2015 Verstorbene_2017 10000 Verstorbene
Linke_2015 Weggezogene_2017 10000 Weggezogene
Andere_2015 SPD_2017 90000 SPD
Andere_2015 CDU_2017 80000 CDU
Andere_2015 Gruene_2017 30000 Gruene
Andere_2015 FDP_2017 70000 FDP
Andere_2015 Linke_2017 50000 Linke
Andere_2015 AfD_2017 300000 AfD
Andere_2015 Andere_2017 180000 Andere
Andere_2015 Nichtwaehler_2017 70000 Nichtwaehler
Andere_2015 Verstorbene_2017 30000 Verstorbene
Andere_2015 Weggezogene_2017 60000 Weggezogene
Erstwaehler_2015 SPD_2017 130000 SPD
Erstwaehler_2015 CDU_2017 110000 CDU
Erstwaehler_2015 Gruene_2017 50000 Gruene
Erstwaehler_2015 FDP_2017 70000 FDP
Erstwaehler_2015 Linke_2017 40000 Linke
Erstwaehler_2015 AfD_2017 20000 AfD
Erstwaehler_2015 Andere_2017 50000 Andere
Erstwaehler_2015 Nichtwaehler_2017 380000 Nichtwaehler
Zugezogene_2015 SPD_2017 100000 SPD
Zugezogene_2015 CDU_2017 110000 CDU
Zugezogene_2015 Gruene_2017 30000 Gruene
Zugezogene_2015 FDP_2017 30000 FDP
Zugezogene_2015 Linke_2017 20000 Linke
Zugezogene_2015 AfD_2017 30000 AfD
Zugezogene_2015 Andere_2017 20000 Andere
Zugezogene_2015 Nichtwaehler_2017 270000 Nichtwaehler
Nichtwaehler_2015 SPD_2017 360000 SPD
Nichtwaehler_2015 CDU_2017 500000 CDU
Nichtwaehler_2015 Gruene_2017 80000 Gruene
Nichtwaehler_2015 FDP_2017 120000 FDP
Nichtwaehler_2015 Linke_2017 50000 Linke
Nichtwaehler_2015 AfD_2017 120000 AfD
Nichtwaehler_2015 Andere_2017 60000 Andere
Nichtwaehler_2015 Nichtwaehler_2017 9540000 Nichtwaehler
Nichtwaehler_2015 Verstorbene_2017 340000 Verstorbene
Nichtwaehler_2015 Weggezogene_2017 280000 Weggezogene
<!DOCTYPE html>
<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.rawgit.com/d3/d3-plugins/master/sankey/sankey.js"></script>-->
<!--<script type="text/javascript" src="https://cdn.rawgit.com/Caged/d3-tip/master/index.js"></script>-->
<script>
var tooltip = d3.select("body")
.append("div")
.style("position", "absolute")
.style("z-index", "10")
.style("visibility", "hidden")
.style("background", "#fff")
.attr("class", "tooltip")
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');
//-----------------------------------------
// configuration desktop / mobile
var mobile = /(preview\.)?(a|m)\.spiegel\.de/.test(location.hostname);
// mobile = true;
var initial_height;
if (mobile) { initial_height = 550; }
else { initial_height = 750; }
var margin = {top: 10, right: 0, bottom: 10, left: 0},
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);
function formatAmount(val) {
return d3.format(",d")(val).replace(',', '.').replace(',', '.');
}
// 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();
d3.csv("data1.csv", function(error, data) {
var currentData = data;
function processData(data) {
var graph = {"nodes" : [], "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 });
});
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
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
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 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,
"shortname": d };
});
return graph;
}
// tooltip Funktionen
function mousetooltiplink(d) {
d3.select(".tooltip")
.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"; }
})
.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"; }
})
}
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"; }
})
.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"; }
})
}
function showtooltip(d) {
d3.select(".tooltip")
.style("visibility", "visible")
.html(function() {
if (d.source.name == "Nichtwaehler_2015" && d.target.name == "Nichtwaehler_2017") {
return "<b>" + d3.format(",d")(d.value).replace(',', '.').replace(',', '.') + "</b> ehemalige <b>Nichtwähler</b> (" + Math.round(d.value / d.source.value * 100) + " %) gingen diesmal ebenfalls nicht zur Wahl";
}
if (d.source.name == "Nichtwaehler_2015" && d.target.name == "Verstorbene_2017") {
return "<b>" + d3.format(",d")(d.value).replace(',', '.').replace(',', '.') + "</b> ehemalige <b>Nichtwähler</b> (" + Math.round(d.value / d.source.value * 100) + " %) sind seit der letzten Wahl verstorben";
}
if (d.source.name == "Nichtwaehler_2015" && d.target.name == "Weggezogene_2017") {
return "<b>" + d3.format(",d")(d.value).replace(',', '.').replace(',', '.') + "</b> ehemalige <b>Nichtwähler</b> (" + Math.round(d.value / d.source.value * 100) + " %) sind weggezogen";
}
if (d.source.name == "Nichtwaehler_2015" && d.target.name == "Andere_2017") {
return "<b>" + d3.format(",d")(d.value).replace(',', '.').replace(',', '.') + "</b> ehemalige <b>Nichtwähler</b> (" + Math.round(d.value / d.source.value * 100) + " %) wählten diesmal <b>eine andere Partei</b>";
}
if (d.source.name == "Erstwaehler_2015" && d.target.name == "Andere_2017") {
return "<b>" + d3.format(",d")(d.value).replace(',', '.').replace(',', '.') + "</b> Erstwähler</b> (" + Math.round(d.value / d.source.value * 100) + " %) wählten diesmal <b>eine andere Partei</b>";
}
if (d.source.name == "Erstwaehler_2015" && d.target.name == "Nichtwaehler_2017") {
return "<b>" + d3.format(",d")(d.value).replace(',', '.').replace(',', '.') + "</b> Erstwähler</b> (" + Math.round(d.value / d.source.value * 100) + " %) gingen diesmal nicht zur Wahl";
}
if (d.source.name == "Erstwaehler_2015" && d.target.name == "Verstorbene_2017") {
return "<b>" + d3.format(",d")(d.value).replace(',', '.').replace(',', '.') + "</b> Erstwähler</b> (" + Math.round(d.value / d.source.value * 100) + " %) sind seit der letzten Wahl verstorben";
}
if (d.source.name == "Erstwaehler_2015" && d.target.name == "Weggezogene_2017") {
return "<b>" + d3.format(",d")(d.value).replace(',', '.').replace(',', '.') + "</b> Erstwähler</b> (" + Math.round(d.value / d.source.value * 100) + " %) sind weggezogen";
}
if (d.source.name == "Zugezogene_2015" && d.target.name == "Andere_2017") {
return "<b>" + d3.format(",d")(d.value).replace(',', '.').replace(',', '.') + "</b> Zugezogene</b> (" + Math.round(d.value / d.source.value * 100) + " %) wählten diesmal <b>eine andere Partei</b>";
}
if (d.source.name == "Zugezogene_2015" && d.target.name == "Verstorbene_2017") {
return "<b>" + d3.format(",d")(d.value).replace(',', '.').replace(',', '.') + "</b> Zugezogene</b> (" + Math.round(d.value / d.source.value * 100) + " %) sind seit der letzten Wahl verstorben";
}
if (d.source.name == "Zugezogene_2015" && d.target.name == "Weggezogene_2017") {
return "<b>" + d3.format(",d")(d.value).replace(',', '.').replace(',', '.') + "</b> Zugezogene</b> (" + Math.round(d.value / d.source.value * 100) + " %) sind weggezogen";
}
if (d.source.name == "Zugezogene_2015" && d.target.name == "Nichtwaehler_2017") {
return "<b>" + d3.format(",d")(d.value).replace(',', '.').replace(',', '.') + "</b> Zugezogene</b> (" + Math.round(d.value / d.source.value * 100) + " %) gingen diesmal nicht zur Wahl";
}
if (d.source.name == "Andere_2015" && d.target.name == "Nichtwaehler_2017") {
return "<b>" + d3.format(",d")(d.value).replace(',', '.').replace(',', '.') + "</b> ehemalige <b>Wähler anderer Parteien</b> (" + Math.round(d.value / d.source.value * 100) + " %) gingen diesmal nicht zur Wahl";
}
if (d.source.name == "Nichtwaehler_2015") {
return "<b>" + d3.format(",d")(d.value).replace(',', '.').replace(',', '.') + "</b> ehemalige <b>Nichtwähler</b> (" + Math.round(d.value / d.source.value * 100) + " %) wählten diesmal die <b>" + d.target.name.slice(0, -5).replace("ae","ä").replace("ue","ü") + "</b>";
}
if (d.target.name == "Nichtwaehler_2017") {
return "<b>" + d3.format(",d")(d.value).replace(',', '.').replace(',', '.') + "</b> ehemalige <b>" + d.source.name.slice(0, -5).replace("ae","ä").replace("ue","ü") + "</b>-Wähler (" + Math.round(d.value / d.source.value * 100) + " %) gingen diesmal nicht wählen";
}
if (d.source.name == "Andere_2015" && d.target.name == "Andere_2017") {
return "<b>" + d3.format(",d")(d.value).replace(',', '.').replace(',', '.') + "</b> ehemalige <b>Wähler anderer Parteien</b> (" + Math.round(d.value / d.source.value * 100) + " %) wählten diesmal <b>eine andere Partei</b>";
}
if (d.source.name == "Andere_2015" && d.target.name == "Weggezogene_2017") {
return "<b>" + d3.format(",d")(d.value).replace(',', '.').replace(',', '.') + "</b> ehemalige <b>Wähler anderer Parteien</b> (" + Math.round(d.value / d.source.value * 100) + " %) sind weggezogen";
}
if (d.source.name == "Andere_2015" && d.target.name == "Verstorbene_2017") {
return "<b>" + d3.format(",d")(d.value).replace(',', '.').replace(',', '.') + "</b> ehemalige <b>Wähler anderer Parteien</b> (" + Math.round(d.value / d.source.value * 100) + " %) sind seit der letzten Wahl verstorben";
}
if (d.target.name == "Andere_2017") {
return "<b>" + d3.format(",d")(d.value).replace(',', '.').replace(',', '.') + "</b> ehemalige <b>" + d.source.name.slice(0, -5).replace("ae","ä").replace("ue","ü") + "</b>-Wähler (" + Math.round(d.value / d.source.value * 100) + " %) wählten diesmal eine andere Partei";
}
if (d.source.name == "Andere_2015") {
return "<b>" + d3.format(",d")(d.value).replace(',', '.').replace(',', '.') + "</b> ehemalige <b>Wähler anderer Parteien</b> (" + Math.round(d.value / d.source.value * 100) + " %) wählten diesmal die <b>" + d.target.name.slice(0, -5).replace("ae","ä").replace("ue","ü") + "</b>";
}
if (d.source.name == "Zugezogene_2015") {
return "<b>" + d3.format(",d")(d.value).replace(',', '.').replace(',', '.') + "</b> Zugezogene</b> (" + Math.round(d.value / d.source.value * 100) + "%) wählten diesmal die <b>" + d.target.name.slice(0, -5).replace("ae","ä").replace("ue","ü") + "</b>";
}
if (d.source.name == "Erstwaehler_2015") {
return "<b>" + d3.format(",d")(d.value).replace(',', '.').replace(',', '.') + "</b> Erstwähler</b> (" + Math.round(d.value / d.source.value * 100) + " %) wählten diesmal die <b>" + d.target.name.slice(0, -5).replace("ae","ä").replace("ue","ü") + "</b>";
}
if (d.target.name == "Verstorbene_2017") {
return "<b>" + d3.format(",d")(d.value).replace(',', '.').replace(',', '.') + "</b> ehemalige <b>" + d.source.name.slice(0, -5).replace("ae","ä").replace("ue","ü") + "</b>-Wähler (" + Math.round(d.value / d.source.value * 100) + " %) sind seit der letzten Wahl verstorben";
}
if (d.target.name == "Weggezogene_2017") {
return "<b>" + d3.format(",d")(d.value).replace(',', '.').replace(',', '.') + "</b> ehemalige <b>" + d.source.name.slice(0, -5).replace("ae","ä").replace("ue","ü") + "</b>-Wähler (" + Math.round(d.value / d.source.value * 100) + " %) 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>" + d3.format(",d")(d.value).replace(',', '.').replace(',', '.') + "</b> ehemalige <b>" + d.source.name.slice(0, -5).replace("ae","ä").replace("ue","ü") + "</b>-Wähler (" + Math.round(d.value / d.source.value * 100) + " %) wählten wieder die <b>" + d.target.name.slice(0, -5).replace("ae","ä").replace("ue","ü") + "</b>";
}
else {
return "<b>" + d3.format(",d")(d.value).replace(',', '.').replace(',', '.') + "</b> ehemalige <b>" + d.source.name.slice(0, -5).replace("ae","ä").replace("ue","ü") + "</b>-Wähler (" + Math.round(d.value / d.source.value * 100) + " %) wählten diesmal die <b>" + d.target.name.slice(0, -5).replace("ae","ä").replace("ue","ü") + "</b>";
}
})
}
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("_2015","");
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("_2015","");
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>' +d3.format(",d")(d.value).replace(',', '.').replace(',', '.')+'</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>' +d3.format(",d")(d.value).replace(',', '.').replace(',', '.')+'</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>' +d3.format(",d")(d.value).replace(',', '.').replace(',', '.')+'</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>' +d3.format(",d")(d.value).replace(',', '.').replace(',', '.')+'</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_2015" || nodeName == "CDU_2015" || nodeName == "FDP_2015" || nodeName == "AfD_2015" || nodeName == "Gruene_2015" || nodeName == "Linke_2015") {
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>' +d3.format(",d")(d.value).replace(',', '.').replace(',', '.')+'</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_2015") {
html = '<div class="table-wrapper">'+
'<div id="tooltip_header" ><table><tr><th>' + '<h1>Andere Parteien</h1></th><th><h3>' +d3.format(",d")(d.value).replace(',', '.').replace(',', '.')+'</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_2015") {
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>' +d3.format(",d")(d.value).replace(',', '.').replace(',', '.')+'</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_2015") {
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>' +d3.format(",d")(d.value).replace(',', '.').replace(',', '.')+'</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_2015") {
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>' +d3.format(",d")(d.value).replace(',', '.').replace(',', '.')+'</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>' +d3.format(",d")(d.value).replace(',', '.').replace(',', '.')+'</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);
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("_2015","");
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 === "CDU_2015") { d3.selectAll("#CDU_2015,#CDU_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);
});
}
// Achsen Labels als Titel eingefügt
// erste Zahl
svg.append("text")
.attr("x", 0)
.attr("y", - (margin.top / 2))
.attr("class", "number1")
.text("2013");
// zweite Zahl
svg.append("text")
// .attr("x", (width / 1.05))
.attr("x", width)
.attr("y", 0- (margin.top / 2))
.attr("class", "number2")
.text("2017");
// Nodes hinzufügen
node = svg.append("g").selectAll(".node")
.data(myNodes)
.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")"; });
// Rechtecke für Nodes einfügen, Farbzuweisung nach Klasse
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("_2015","");
}
else {
var type = "target";
var party = d.name.replace("_2017","");
}
return(type + " " + party)
})
.on('mouseover', function(d){
if (d.name === "CDU_2017" || d.name === "CDU_2015") { d3.selectAll("#CDU_2015,#CDU_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","ü"); })
.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>
@font-face {
font-family: "SpiegelSansWeb";
src: url("http://www.spiegel.de/font/spiegelsans-regular/spiegelsans-regular-web-V1.0.1.eot") format("eot");
src: url("http://www.spiegel.de/font/spiegelsans-regular/spiegelsans-regular-web-V1.0.1.eot?#iefix") format("embedded-opentype"), url("http://www.spiegel.de/font/spiegelsans-regular/spiegelsans-regular-web-V1.0.1.woff2") format("woff2"), url("http://www.spiegel.de/font/spiegelsans-regular/spiegelsans-regular-web-V1.0.1.woff") format("woff"), url("http://www.spiegel.de/font/spiegelsans-regular/spiegelsans-regular-web-V1.0.1.ttf") format("truetype"), url("http://www.spiegel.de/font/spiegelsans-regular/spiegelsans-regular-web-V1.0.1.svg#SpiegelSansWeb") format("svg");
font-weight: 400;
font-style: normal;
font-display: swap; }
@font-face {
font-family: "SpiegelSansWeb";
src: url("http://www.spiegel.de/font/spiegelsans-bold/spiegelsans-bold-web-V1.0.1.eot") format("eot");
src: url("http://www.spiegel.de/font/spiegelsans-bold/spiegelsans-bold-web-V1.0.1.eot?#iefix") format("embedded-opentype"), url("http://www.spiegel.de/font/spiegelsans-bold/spiegelsans-bold-web-V1.0.1.woff2") format("woff2"), url("http://www.spiegel.de/font/spiegelsans-bold/spiegelsans-bold-web-V1.0.1.woff") format("woff"), url("http://www.spiegel.de/font/spiegelsans-bold/spiegelsans-bold-web-V1.0.1.ttf") format("truetype"), url("http://www.spiegel.de/font/spiegelsans-bold/spiegelsans-bold-web-V1.0.1.svg#SpiegelSansWeb") format("svg");
font-weight: 700;
font-style: normal;
font-display: swap; }
@font-face {
font-family: "SpiegelSansWeb";
src: url("http://www.spiegel.de/font/spiegelsans-semibold/spiegelsans-semibold-web-V1.0.1.eot") format("eot");
src: url("http://www.spiegel.de/font/spiegelsans-semibold/spiegelsans-semibold-web-V1.0.1.eot?#iefix") format("embedded-opentype"), url("http://www.spiegel.de/font/spiegelsans-semibold/spiegelsans-semibold-web-V1.0.1.woff2") format("woff2"), url("http://www.spiegel.de/font/spiegelsans-semibold/spiegelsans-semibold-web-V1.0.1.woff") format("woff"), url("http://www.spiegel.de/font/spiegelsans-semibold/spiegelsans-semibold-web-V1.0.1.ttf") format("truetype"), url("http://www.spiegel.de/font/spiegelsans-semibold/spiegelsans-semibold-web-V1.0.1.svg#SpiegelSansWeb") format("svg");
font-weight: 600;
font-style: normal;
font-display: swap; }
body,html{
font-family: SpiegelSansWeb, Calibri, Candara, Arial, Helvetica, sans-serif;
margin: 0;
/*display: flex;*/
/*justify-content: center;*/
/*align-items: center;*/
font-size: 12px;
/*margin: 5px;*/
/*margin-bottom: 20px;*/
/*margin-top: 50px;*/
}
.number1 {
font-size: 22px;
font-weight: bold;
line-height: 1.5em;
padding: 5px 5px 5px 10px;
}
.number2 {
font-weight: bold;
font-size: 22px;
line-height: 1.5em;
padding: 5px 5px 5px 10px;
text-anchor: end;
}
.tooltip {
font-size: 14px;
line-height: 1.5em;
padding: 10px;
border-radius: 2px;
box-shadow: 1px 1px 4px grey;
font-weight: normal;
background: white;
color: black;
pointer-events: none;
max-width: 180px;
}
.tooltipnode {
line-height: 1.2em;
border-radius: 2px;
box-shadow: 1px 1px 4px grey;
font-weight: normal;
padding: 6px;
background: white;
color: black;
pointer-events: none;
max-width: 190px;
}
.tooltipnode h1 {
font-weight: bold;
font-size: 16px;
padding: 0;
margin-bottom: 6px;
margin-top: 2px;
width: 100%;
text-align: left;
}
.tooltipnode h2 {
font-weight: bold;
font-size: 14px;
padding-right: inherit;
padding-left: inherit;
padding-top: 2px;
padding-bottom: 2px;
margin: 0px;
}
.tooltipnode h3 {
font-weight: normal;
font-size: 16px;
text-align: right;
margin-bottom: 6px;
margin-top: 2px;
}
.tooltipnode table {
font-weight: normal;
font-size: 14px;
padding: none;
margin: 0;
width: 100%;
border: none;
border-collapse: collapse;
}
.tooltipnode td {
padding-top: 2px;
padding-bottom: 2px;
}
.tooltipnode .col-left {
padding-right: 8px;
}
.tooltipnode .table-wrapper {
margin: 0;
padding: inherit;
border: none;
font-size: 14px;
}
#tooltip_header{
margin-bottom: 5px;
}
svg text {
font-size: 14px;
stroke-width: 0;
fill: black;
}
.sankey {
margin-top: 25px;
overflow: visible;
}
.sankey .node text {
pointer-events: none;
}
path.SPD {
fill: none;
stroke: #E2001A;
stroke-opacity: .2;
}
path.CDU {
fill: none;
stroke: #000000;
stroke-opacity: .2;
}
path.FDP {
fill: none;
stroke: #FEC803;
stroke-opacity: .2;
}
path.Gruene {
fill: none;
stroke: #329A07;
stroke-opacity: .2;
}
path.Linke {
fill: none;
stroke: #8837C1;
stroke-opacity: .2;
}
path.AfD {
fill: none;
stroke: #1295FF;
stroke-opacity: .2;
}
path.Andere {
fill: none;
stroke: #787C80;
stroke-opacity: .2;
}
path.Weggezogene {
fill: none;
stroke: #787C80;
stroke-opacity: .2;
}
path.Nichtwaehler {
fill: none;
stroke: #665370;
stroke-opacity: .2;
}
path.Erstwaehler {
fill: none;
stroke: #787C80;
stroke-opacity: .2;
}
path.Verstorbene {
fill: none;
stroke: #787C80;
stroke-opacity: .2;
}
path.Zugezogene {
fill: none;
stroke: #787C80;
stroke-opacity: .2;
}
rect.SPD {
fill: #E2001A;
stroke: #E2001A;
}
rect.CDU {
fill: #000000;
stroke: #000000;
}
rect.FDP {
fill: #FEC803;
stroke: #FEC803;
}
rect.Gruene {
fill: #329A07;
stroke: #329A07;
}
rect.Linke {
fill: #8837C1;
stroke: #8837C1;
}
rect.AfD {
fill: #1295FF;
stroke: #1295FF;
}
rect.Andere {
fill: #787C80;
stroke: #787C80;
}
rect.Weggezogene {
fill: #787C80;
stroke: #787C80;
}
rect.Nichtwaehler {
fill: #665370;
stroke: #665370;
}
rect.Erstwaehler {
fill: #787C80;
stroke: #787C80;
}
rect.Verstorbene {
fill: #787C80;
stroke: #787C80;
}
rect.Zugezogene {
fill: #787C80;
stroke: #787C80;
}
rect.none {
fill: #787C80;
stroke: #787C80;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment