// ==UserScript==
// @name Koalitionenrechner - wahlrecht.de
// @namespace Violentmonkey Scripts
// @match https://www.wahlrecht.de/umfragen/
// @grant none
// @version 1.0
// @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 getCoalitions() {
let str = "";
let currentCoalitionVotes = 0;
let results = [];
for (let coalition of coalitions) {
let currentCoalitionVotes = 0;
for (let p of coalition) {
currentCoalitionVotes += getPartyVotes(p);
}
results.push({coalition:coalition.join(""), votes: currentCoalitionVotes});
}
results.sort((a,b) => {return b.votes - a.votes;});
for (let c of results) str += c.coalition + ": \t\t" + c.votes.toFixed(1) + "%\n";
coalitionBox.innerText = 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);