// ==UserScript==
// @name Koalitionenrechner - wahlrecht.de
// @namespace Violentmonkey Scripts
// @match https://www.wahlrecht.de/umfragen/
// @grant none
// @version 1.2
// @author Sidem
// @description 8/22/2021, 6:38:16 PM
// ==/UserScript==
/* jshint esversion: 6 */
window.addEventListener('load', function () {
function generatePowerSet(array) {
var result = [];
result.push([]);
for (var i = 1; i < (1 << array.length); i++) {
var subset = [];
for (var j = 0; j < array.length; j++)
if (i & (1 << j))
subset.push(array[j]);
result.push(subset);
}
return result;
}
let data = [
{name:'CDU/CSU', votes:12000},
{name:'SPD', votes:15000},
{name:'GRÜNE', votes:5500},
{name:'FDP', votes:12800},
{name:'LINKE', votes:16000},
{name:'AfD', votes:8800},
{name:'Sonstige', votes:1800}
];
let names = ['CDU/CSU','SPD','GRÜNE','FDP','LINKE','AfD','Sonstige'];
let partyIcons = ['⚫️','🔴','🟣','🟡','🟢','🔵'];
let allPossibleCoalitions = generatePowerSet(partyIcons);
allPossibleCoalitions = allPossibleCoalitions.filter((el) => { return (el.length > 1 && el.length < 4)}); // filter to only 2-4 party coalitions
let coalitions = allPossibleCoalitions.filter((el) => { // filter exclusions, eg far right wont have a coalition with far left
if (el.includes('🔵') && el.includes('🟢')) return false;
if (el.includes('🔵') && el.includes('🔴')) return false;
if (el.includes('🔵') && el.includes('🟣')) return false;
if (el.includes('🟣') && el.includes('🟡')) return false;
if (el.includes('🟣') && el.includes('⚫️')) return false;
return true;
});
const getPartyColor = (name) => {
switch(name) {
case 'CDU/CSU':
return '#000000';
case 'SPD':
return '#FF0000';
case 'GRÜNE':
return '#00FF00';
case 'FDP':
return '#FFFF00';
case 'LINKE':
return '#FF0088';
case 'AfD':
return '#1199FF';
case 'Sonstige':
return '#888888';
default:
return '#888888';
}
};
const getColorIcon = (name) => {
switch(name) {
case 'CDU/CSU':
return '⚫️';
case 'SPD':
return '🔴';
case 'GRÜNE':
return '🟢';
case 'FDP':
return '🟡';
case 'LINKE':
return '🟣';
case 'AfD':
return '🔵';
case 'Sonstige':
return '⚪️';
default:
return '⚪️';
}
};
function setChart() {
let canvas = document.getElementById('c');
let ctx = canvas.getContext('2d');
canvas.width = 500;
canvas.height = 400;
let total = data.reduce( (ttl, party) => {
return ttl + party.votes
}, 0);
let startAngle = 0;
let radius = 100;
let cx = canvas.width/2;
let cy = canvas.height/2;
data.forEach( party => {
//set the styles before beginPath
ctx.fillStyle = getPartyColor(party.name);
ctx.lineWidth = 1;
ctx.strokeStyle = '#333';
ctx.beginPath();
//console.log(total, party.votes, party.votes/total);
// draw the pie wedges
let endAngle = ((party.votes / total) * Math.PI * 2) + startAngle;
ctx.moveTo(cx, cy);
ctx.arc(cx, cy, radius, startAngle, endAngle, false);
ctx.lineTo(cx, cy);
ctx.fill();
ctx.stroke();
ctx.closePath();
// add the labels
ctx.beginPath();
ctx.font = '20px Helvetica, Calibri';
ctx.textAlign = 'center';
ctx.fillStyle = 'rebeccapurple';
// midpoint between the two angles
// 1.5 * radius is the length of the Hypotenuse
let theta = (startAngle + endAngle) / 2;
let deltaY = Math.sin(theta) * 1.5 * radius;
let deltaX = Math.cos(theta) * 1.5 * radius;
/***
SOH - sin(angle) = opposite / hypotenuse
= opposite / 1px
CAH - cos(angle) = adjacent / hypotenuse
= adjacent / 1px
TOA
***/
ctx.fillText(party.name, deltaX+cx, deltaY+cy);
ctx.closePath();
startAngle = endAngle;
});
}
function isPermutation(a,b) {
return b.filter(x => !a.includes(x)).length === 0;
}
function coalitionSymbol(coalition) {
if (isPermutation(coalition, ['⚫️','🔴','🟢'])) return "<img src='https://flagcdn.com/w20/ke.png' alt='ke' title='Kenia'>";
if (isPermutation(coalition, ['⚫️','🔴','🟡'])) return "<img src='https://flagcdn.com/w20/de.png' alt='de' title='Deutschland'>";
if (isPermutation(coalition, ['⚫️','🟡','🟢'])) return "<img src='https://flagcdn.com/w20/jm.png' alt='jm' title='Jamaika'>";
if (isPermutation(coalition, ['⚫️','🔴','🟢'])) return "<img src='https://flagcdn.com/w20/af.png' alt='af' title='Afghanistan'>";
if (isPermutation(coalition, ['🟣','🔴','🟢'])) return "<img src='https://flagcdn.com/w20/by.png' alt='by' title='Weissrussland'>";
if (isPermutation(coalition, ['⚫️','🟡','🔵'])) return "<img src='https://flagcdn.com/w20/bs.png' alt='bs' title='Bahamas'>";
if (isPermutation(coalition, ['🟡','🔴','🟢'])) return "<img src='https://flagcdn.com/w20/gn.png' alt='gn' title='Guinea'>";
return "";
}
function getCoalitions() {
let str = "";
let currentCoalitionVotes = 0;
let results = [];
for (let coalition of coalitions) {
let currentCoalitionVotes = 0;
for (let p of coalition) {
currentCoalitionVotes += getPartyVotes(p);
}
coalition.sort((p1, p2) => {return getPartyVotes(p2) - getPartyVotes(p1)});
results.push({coalition:coalition.join(""), parties: coalition, votes: currentCoalitionVotes});
}
results.sort((a,b) => {return b.votes - a.votes;});
let line = false;
for (let c of results) {
if(!line && c.votes < 50) {
line = true;
str += "<p style='margin: 0px;'>〰️〰️〰️〰️〰️〰️</p>";
}
str += "<p style='margin: 0px;'><strong style='display: inline-block; width: 70px;'>"+c.coalition + "</strong>" + c.votes.toFixed(1) + "% "+coalitionSymbol(c.parties)+"</p>";
}
coalitionBox.innerHTML = str;
}
function clean(str) {
return parseFloat(str.replace(',', '.').replace(' %', ''));
}
function getPartyVotes(identifier) {
for (let p of data) {
if (p.name == identifier || p.color == identifier) {
return p.votes;
}
}
return 0;
}
let getChart = (e) => {
let colDataElements = document.getElementsByClassName(e.target.classList[e.target.classList.length-1]);
data = [];
let i = 0;
for (let el of colDataElements) {
data.push({name:names[i], votes:clean(el.innerText), color: getColorIcon(names[i])})
i++;
}
data.sort((a,b) => {return b.votes - a.votes;});
setChart();
getCoalitions();
};
let partyIds = ["cdu","spd","gru","fdp","lin","afd","son"];
let rows = document.getElementsByTagName('tr');
for (let row of rows) {
if (partyIds.includes(row.id)) {
let numbers = row.getElementsByTagName('td');
let n = 0;
for (let number of numbers) {
if (n != 0 && n != 9) {
number.classList.add('col-'+n);
number.onclick = getChart;
number.style.cursor = 'pointer';
number.addEventListener("mouseenter", function( e ) {
let columnClass = e.target.classList[e.target.classList.length-1];
let column = document.getElementsByClassName(columnClass);
for (let item of column) {
item.style.backgroundColor = 'aqua';
}
});
number.addEventListener("mouseleave", function( e ) {
let columnClass = e.target.classList[e.target.classList.length-1];
let column = document.getElementsByClassName(columnClass);
for (let item of column) {
item.style.backgroundColor = 'white';
}
});
}
n++;
}
}
}
let canvas = document.createElement('canvas');
canvas.setAttribute('id','c');
let info = document.getElementById('info');
info.parentNode.insertBefore(canvas, info);
let coalitionBox = document.createElement('div');
coalitionBox.setAttribute('id','coalitionBox');
coalitionBox.style.marginRight = '270px';
coalitionBox.style.marginTop = '40px';
coalitionBox.style.float = 'right';
info.parentNode.insertBefore(coalitionBox, info);
}, false);