Skip to content

Instantly share code, notes, and snippets.

@froh
Last active July 6, 2018 19:17
Show Gist options
  • Save froh/6352367 to your computer and use it in GitHub Desktop.
Save froh/6352367 to your computer and use it in GitHub Desktop.
Wahl-o-Mat
These CSU SPD FW Grüne FDP Linke ÖDP REP NPD BP BüSo Freiheit Frauen Franken Piraten
1. In Bayern sollen Geschäfte an Werktagen länger geöffnet haben dürfen. x x x x # x x x x - x y x x y
2. In die Bayerische Verfassung soll eine Schuldenbremse aufgenommen werden. # # # x # x # # # # x y y y x
3. Autofahrer aus dem Ausland sollen für die Nutzung deutscher Autobahnen bezahlen. # x x x x x x # # # x y y y x
4. Bei Neuvermietungen sollen sich Vermieter an regionale Mietobergrenzen halten müssen. # # # # x # # # # # y y y x y
5. Das Land soll die ökologische Landwirtschaft stärker finanziell fördern. - # x # x # # x # - - x y y y
6. Mehr Videoüberwachung auf öffentlichen Plätzen! # - x x x x - - x x x y y y x
7. Alle Kinder sollen ungeachtet ihres kulturellen Hintergrundes gemeinsam unterrichtet werden. # # # # # # # x x # y y y y y
8. Auch der Besitz von nur geringen Mengen Cannabis soll strafrechtlich verfolgt werden. # x # x x x # # # # y y x - x
9. Die wirtschaftlich stärkeren Länder sollen weniger an die wirtschaftlich schwächeren Länder zahlen müssen. # # # x # x - # # # x y - y x
10. Der Bau von Minaretten soll verboten werden. x x x x x x x # # - x y x y x
11. Bayern soll sich dafür einsetzen, dass alle Studierenden BAföG unabhängig vom Einkommen ihrer Eltern erhalten können. x # x # # # x x x # x x y x y
12. Auch in Bayern soll nach Endlagerstätten für Atommüll gesucht werden. x x # # x # x - # - x y - x y
13. Der Freistaat Bayern soll die Bewerbung Münchens für die olympischen Winterspiele 2022 finanziell unterstützen. # # # x # x x - x x - y y x -
14. Einführung einer Frauenquote für Führungspositionen im öffentlichen Dienst! x # x # x # x x x x - x y x x
15. Das Land soll weiterhin Projekte gegen politischen Extremismus fördern. # # # - # - # x x # - y y y -
16. Das dreigliedrige Schulsystem (Mittelschule, Realschule, Gymnasium) soll erhalten bleiben. # # # x # x # # # # y y x y x
17. Das Land soll sich dafür einsetzen, dass die Vermögensteuer wieder erhoben wird. x # x - x # # x # x x x y x -
18. Keine Solaranlagen auf landwirtschaftlichen Flächen! x x # x # # - # # x y y y x -
19. Mehr Menschen mit Migrationshintergrund sollen im Polizeidienst arbeiten. # # # # # # # x x x y x y x y
20. Keine Privatisierung von Krankenhäusern! - # - x x # # # # # y - y - -
21. Vollständige Gleichstellung von Ehe und gleichgeschlechtlicher Lebenspartnerschaft. x # # # # # x x x x x x y y y
22. Abgabe von Entscheidungsbefugnissen an die Europäische Union nur durch Volksentscheid! # # # x x - # # # # y y - y x
23. Deutsche sollen bei der Vergabe von Sozialwohnungen bevorzugt werden. x x x x x x x # # - x y x - x
24. Bei Landtagswahlen: Wählen ab 16! x # x # x # # x x x x x y x y
25. Steuerhinterziehung soll weiterhin bei Selbstanzeige straffrei bleiben. - x x - # x x x x # y x x x -
26. Das Bayerische Landesamt für Verfassungsschutz soll aufgelöst werden. x - x # x # x # # x x x - x y
27. Jeder Schulabsolvent soll einen gesetzlichen Anspruch auf einen Ausbildungsplatz haben. - # x x x # # # x - y x y y x
28. Die finanzielle Unterstützung für einkommensschwache Familien (Landeserziehungsgeld) soll beibehalten werden. # x # x # x # # # # y y y y x
29. Polizisten und Polizistinnen sollen bei Großeinsätzen eine gut lesbare, individuelle Kennung tragen müssen. x # - # # # x x x # y - y y y
30. Die Stromsteuer soll gesenkt werden. - # # x # # x # # # y y y y x
31. Das letzte Kindergartenjahr vor der Einschulung soll verpflichtend sein. x x # x x # x x x x y y y y -
32. Das Land soll weiterhin Kulturprojekte von Migrantinnen und Migranten fördern. # # # # # # # x x - y - y - y
33. Die Erhöhung des gesetzlichen Renteneintrittsalters auf 67 Jahre soll beibehalten werden. # x x # # x x x x x x y x - -
34. Asylbewerber und Asylbewerberinnen sollen eine uneingeschränkte Arbeitserlaubnis erhalten. x # x # # # x x x - x x x x y
35. Der Schutz der "stillen Tage" soll beibehalten werden (Tanzverbot). # # # # x x # # - # y x y y x
36. Die dritte Startbahn am Münchener Flughafen soll gebaut werden. - x x x # x x - x x y y x x x
37. Abbau der Verflechtung von Kirche und Staat in Bayern! x - x # # # x # # x y y y y y
38. Der Einsatz von Schneekanonen soll in den bayerischen Skigebieten verboten werden. x - x - x # # - # x x x - x y
The code in this gist is
copyright (C) 2013 Susanne Oberhauser-Hirschoff
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the <organization> nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{"description":"Wahl-o-Mat","endpoint":"","display":"svg","public":true,"require":[],"fileconfigs":{"inlet.js":{"default":true,"vim":false,"emacs":false,"fontSize":12},"_.md":{"default":true,"vim":false,"emacs":false,"fontSize":12},"Bayern-2013.tsv":{"default":true,"vim":false,"emacs":false,"fontSize":12},"BSD-3-License.txt":{"default":true,"vim":false,"emacs":false,"fontSize":12},"config.json":{"default":true,"vim":false,"emacs":false,"fontSize":12},"bayern2013.tsv":{"default":true,"vim":false,"emacs":false,"fontSize":12},"index.html":{"default":true,"vim":false,"emacs":false,"fontSize":12}},"fullscreen":false,"play":false,"loop":false,"restart":false,"autoinit":true,"pause":true,"loop_type":"period","bv":false,"nclones":15,"clone_opacity":0.4,"duration":3000,"ease":"linear","dt":0.01,"thumbnail":"http://i.imgur.com/iFHq4Tu.png","ajax-caching":true}
<?xml version="1.0" encoding="utf-8"?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script src="http://mbostock.github.com/d3/d3.js"></script>
<script src="http://jashkenas.github.io/underscore/underscore.js"></script>
<script src="inlet.js"></script>
<title>Political Landscape</title>
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg"></svg>
</body>
</html>
/* visualization of the political landscape as induced by Wahl-O-Mat data
Copyright (C) 2013 Susanne Oberhauser-Hirschoff
This whole gist is under a BSD-3 clause License (see file BSD-3-License.txt)
A force based interactive layout of a Wahl-O-Mat http://www.wahl-o-mat.de
political landscape.
Each thesis ("These") is represented as a node.
Each political party is represented as a node.
The stance of the party to the thesis is represented as a link from the party to the thesis.
The 'agreement' is reflected as the default distance of the party to the thesis.
To get the theses reasonably arranged by default, they get a distance to the center,
and to each other, so they will create a random circle.
The Neutral stance is represented as a separate node.
TODO: rename from 'Ich' to 'neutral'
The user will also be represented as a node.
The user can strengthen or release her distance to the individual theses:
click on the link from user to thesis.
The user can increase or decrease the relevance of the individual theses:
click on the thesis.
The user can increase or decrease the relevance of each political party:
click on the party.
*/
/* load the theses, then display them */
/* TODO: allow for multiple files for different elections */
if (typeof tributary === 'undefined') {
d3.tsv("bayern2013.tsv", fromDataToDisplay);
} else {
fromDataToDisplay(tributary.bayern2013, tributary.sh, tributary.sw);
}
var DEBUGME_GLOBAL = {}
function fromDataToDisplay(Bayern_2013_json, w, h) {
var parties_Theses_Stances = parseRows(Bayern_2013_json);
var graph = makeGraph(parties_Theses_Stances);
DEBUGME_GLOBAL.graph = graph;
visualizeGraph(graph, w, h);
}
var W = {
disagree: 2,
neutral: 1,
agree: 0
}
function parseRows(rows) {
/* 'rows' is an array with the input columns:
[ {Thesis: thesis1, Party_x: stance }, ... ]
desired structure:
theses = [ thesis_1..m ]
parties = [ party_i..n ]
stances = [ [thesis_1..m]_1..n ]
*/
var theses = [],
parties = null,
stancesByThesis = [];
var stance2distance = {
'x': W.disagree,
'-': W.neutral,
'#': W.agree,
'y': W.agree
}
rows.forEach(function (_row) {
row = _row;
var thesis = row.These; // 'These' = german for 'thesis', that's hwo the data is.
// TODO: chop off thesis number?
theses.push(thesis);
// Set the parties fromt the first row keys.
if (!parties) {
parties = d3.keys(row).filter(function (x) {
return x !== 'These';
});
}
var stancesThisRow = [];
parties.forEach(function (party) {
stancesThisRow.push(row[party]);
});
stancesThisRow = stancesThisRow.map(function (item) {
return stance2distance[item];
});
stancesByThesis.push(stancesThisRow);
});
var stances = d3.transpose(stancesByThesis);
return {
theses: theses,
parties: parties,
stances: stances
};
}
// nodes
function Node(label) {
this.label = label;
return this;
}
function Thesis() {
Node.apply(this, arguments);
}
Thesis.prototype = new Node();
function Party() {
Node.apply(this, arguments);
}
Party.prototype = new Node();
function Neutral() {
Node.apply(this, arguments);
}
Neutral.prototype = new Node();
// edges
function Link(s, t) {
this.source = s;
this.target = t;
return this;
}
function Stance(s, t, a) {
Link.call(this, s, t);
this.agreement = a;
return this;
}
Stance.prototype = new Link();
function makeGraph(data) {
/* the graph proper */
var graph = {
nodes: [],
edges: []
}
/* create node for each thesis */
data.theses.forEach(function (thesis, i) {
var node = new Thesis(thesis);
graph.nodes.push(node);
})
var nTheses = graph.nodes.length;
var neutralStanceId = nTheses;
/* create node for user and for The Neutral Stance */
graph.neutralStance = new Neutral('Neutral');
graph.nodes.push(graph.neutralStance);
for (var i in d3.range(nTheses)) {
var edge = new Stance(neutralStanceId, +i, W.neutral);
graph.edges.push(edge)
}
var partyOffset = graph.nodes.length;
/* create node for each party */
data.parties.forEach(function (party, id) {
var p = new Party(party);
graph.nodes.push(p);
})
/* create link from each party to each thesis with appropriate weight */
data.stances.forEach(function (partysTheses, partyId) {
partysTheses.forEach(function (thesisWeight, thesisId) {
s = new Stance(partyOffset + partyId, thesisId, thesisWeight);
graph.edges.push(s);
})
})
return graph;
}
// svg visualization.
// enrich the nodes and edges of the graph with visualization
Stance.prototype.linkDistance = function () {
// transform stance.agreement into distance in graph
return Math.pow(this.agreement, 2.4) * 120 + 10;
}
Stance.prototype.linkStrength = function() {
var linkStrength = _.object([
[W.disagree, 1],
[W.neutral, 0.1],
[W.agree, 1]
]);
return linkStrength[this.agreement];
}
Stance.prototype.pimpLine = function(selection, i) {
var strokeWidth = _.object([
[W.disagree, 2],
[W.neutral, 1],
[W.agree, 2]
]);
var strokeDasharray = _.object([
[W.disagree, " 4, 4"],
[W.neutral, "2, 2"],
[W.agree, "10, 0"]
]);
d3.select(selection)
.style("stroke", this.source.color())
.style("stroke-width", strokeWidth[this.agreement])
.style("stroke-dasharray", strokeDasharray[this.agreement])
.style("opacity", 0.6)
}
Node.prototype.pimpCircle = function(selection, i) {
d3.select(selection)
.attr("r", this.radius())
.style("fill", this.color())
.style('opacity', 0.9)
.attr('stroke-width', 1)
.attr('stroke', 'black');
}
Node.prototype.radius = function() { return this._radius; }
Node.prototype._radius = 7;
Node.prototype.color = function() { return 'grey'; }
Neutral.prototype._radius = 4;
Neutral.prototype.color = function() { return 'white'; }
Party.prototype._radius = 12;
Party.prototype.color = (function() {
var _partyColors = {
NEUTRAL : "#ffffff",
SPD : "#e2001a",
Linke : "#FF0000",
CSU : d3.rgb(0, 153, 255),
CDU : "#000",
Piraten : "#FF8800",
"Grüne" : d3.rgb(100, 161, 45),
Frauen : "#7F1E48",
FW : "#007E84",
FDP : "#ffd600",
REP : "#964B00",
NPD : "#964B00",
"ÖDP" : "#EA7c13"
}
var colorGenerator = d3.scale.category20();
var _generatedColors = {};
var nColors = 0;
return function partyColor() {
party = this.label;
if (party in _partyColors) return _partyColors[party];
if (party in _generatedColors) return _generatedColors[party];
return _generatedColors[party] = colorGenerator(nColors++);
}
}())
function visualizeGraph(graph, w, h) {
w = w || 1200;
h = h || 1000;
graph.neutralStance.x = w/2;
graph.neutralStance.y = h/2;
graph.neutralStance.fixed = true;
var force = d3.layout.force()
.nodes(graph.nodes)
.links(graph.edges)
.size([w, h])
.linkDistance( function(s, i) { return s.linkDistance(); } )
.linkStrength( function(s, i) { return s.linkStrength(); })
.charge(10)
.friction(0.9)
.start();
var svg = d3.select('svg');
var edges = svg.selectAll("line")
.data(graph.edges)
.enter()
.append("line")
.each(function (d, i) { d.pimpLine(this, i) });
//Create nodes as circles
var nodes = svg.selectAll("circle")
.data(graph.nodes)
.enter()
.append("circle")
.each(function(d, i) { d.pimpCircle(this, i) })
.call(force.drag)
.on('mouseover', function (d) {
var x = d3.select(this).attr("cx"),
y = d3.select(this).attr("cy");
svg.append("text")
.attr("id", "tooltip")
.attr("x", x)
.attr("y", y)
.attr('pointer-events', 'none')
.attr("text-anchor", "middle")
.attr("font-family", "sans-serif")
.attr("font-size", "14px")
.attr("font-weight", "bold")
.attr("fill", "black")
.text(d.label);
})
.on('mouseout', function () {
d3.select("#tooltip").remove();
});
force.on("tick", function () {
edges
.attr("x1", function (d) {
return d.source.x;
})
.attr("y1", function (d) {
return d.source.y;
})
.attr("x2", function (d) {
return d.target.x;
})
.attr("y2", function (d) {
return d.target.y;
});
nodes.attr("cx", function (d) {
return d.x;
})
.attr("cy", function (d) {
return d.y;
});
});
}
//function display_graphics(data) {
// //console.log(data);
//
// /* Create a grpah from the data. Annotate it as you go. */
//
// /* The node and edge types in the graph */
//
// var Node = {
// svg: function svg(selection) {
// selection.append("circle");
// this.d3GraceStyle(selection);
// }
// }
//
// function Citizen(name) {
// this.label = name;
// this.d3GraceStyle(selection) { selection.attr("r":7).style('fill','#FFFFFF'); }
// }
// Citizen.prototype = new Node;
//
// function Thesis(thesis) {
// Node.call(this,thesis);
// this.d3GraceStyle(selection) { selection.attr("r":12).style('fill','#EEEEEE'); }
// }
// Thesis.prototype = new Node;
//
// function Party(name) {
// this.label = name;
// this.d3GraceStyle(selection) {
// selection
// .attr("r":12)
// .style('fill', partyColor);
// var _partyColors = {
// NEUTRAL : "#ffffff",
// SPD : "#e2001a",
// Linke : "#FF0000",
// CSU : d3.rgb(0, 153, 255),
// CDU : "#000",
// Piraten : "#FF8800",
// "Grüne" : d3.rgb(100, 161, 45),
// Frauen : "#7F1E48",
// FW : "#007E84",
// FDP : "#ffd600",
// REP : "#964B00",
// NPD : "#964B00",
// "ÖDP" : "#EA7c13"
// }
// var colorGenerator = d3.scale.category20();
// var _generatedColors = {};
// var nColors = 0;
// function partyColor(party) {
// console.log(party);
// if (party in _partyColors) return _partyColors[party];
// if (party in _generatedColors) return _generatedColors[party];
// return _generatedColors[party] = colorGenerator(nColors++);
// }
// }
// }
// Party.prototype = new Node;
//
// function Link(source, target) {
// this.source = source;
// this.target = target;
// this.d3svg(selection) {
// selection.append("line");
// this.d3GraceStyle(selection);
// }
// }
//
// function PartyOpinion(party, ) {
// this.d3GraceStyle(selection) {
// selection.style('stroke-width': );
// }
// }
// PartyOpinion.prototype = new Link;
//
// function PersonalOpinion() {
// this.d3GraceStyle(selection) {
// selection.attr();
// }
// }
// PersonalOpinion.prototype = new Link;
//
// var graceAndStyle = {
// ,
// "persönliche Meinung": {
// elem: 'line',
// attr: {},
// style: {
// 'stroke-width': 2,
// stroke: "#5EC3D6"
// }
// },
// "Partei Meinung": {
// elem: '',
// attr: {},
// style: {
// 'stroke-width': function (d) {
// return 5 - d.weight * d.weight
// },
// stroke: partyColor
// }
// }
// }
//
//
// /* create a visualization of the graph */
//
// h = tributary.sh;
// w = tributary.sw;
//
// var force = d3.layout.force()
// .nodes(graph.nodes)
// .links(graph.edges)
// .size([w, h])
// .linkDistance(function (link) {
// return Math.pow(link.weight, 2.4) * 100 + 30;
// })
// .linkStrength(0.8316)
// .charge(0)
// .friction(0.8)
// .start();
//
// //console.log(graph);
// //console.log(force);
//
//
// //Create SVG element
// svg = d3.select('svg');
//
//
// //Create edges as lines
// var edges = svg.selectAll("line")
// .data(graph.edges)
// .enter()
// .append("line")
// .style("stroke", function (d) {
// var f = graceAndStyle[d.type].style.stroke;
// return typeof (f) == 'function' ? f(d.party) : f;
// })
// .style("stroke-width", function (d) {
// f = graceAndStyle[d.type].style['stroke-width'];
// return typeof (f) == 'function' ? f(d) : f
// }).style('opacity', 0.576);
//
// //Create nodes as circles
// var nodes = svg.selectAll("circle")
// .data(graph.nodes)
// .enter()
// .append("circle")
// .attr("r", function (d) {
// return graceAndStyle[d.type].attr.r;
// })
// .style("fill", function (d) {
// var f = graceAndStyle[d.type].style.fill;
// var c;
// if (typeof (f) == 'function') {
// c = f(d.party);
// } else {
// c = f;
// return c;
// }
// }).style('opacity', 0.9).attr('stroke-width', 1).attr('stroke', 'black').call(force.drag)
// .on('mouseover', function (d) {
// var x = d3.select(this).attr("cx"),
// y = d3.select(this).attr("cy");
// svg.append("text")
// .attr("id", "tooltip")
// .attr("x", x)
// .attr("y", y)
// //.attr('pointer-events',none)
// .attr("text-anchor", "middle")
// .attr("font-family", "sans-serif")
// .attr("font-size", "14px")
// .attr("font-weight", "bold")
// .attr("fill", "black")
// .text(d.label);
//
// })
// .on('mouseout', function () {
// d3.select("#tooltip").remove();
//
// });
//
// //Every time the simulation "ticks", this will be called
// force.on("tick", function () {
//
// edges.attr("x1", function (d) {
// return d.source.x;
// })
// .attr("y1", function (d) {
// return d.source.y;
// })
// .attr("x2", function (d) {
// return d.target.x;
// })
// .attr("y2", function (d) {
// return d.target.y;
// });
//
// nodes.attr("cx", function (d) {
// return d.x;
// })
// .attr("cy", function (d) {
// return d.y;
// });
//
// });
//}
//
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment