- // ==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);