Koalitionenrechner - wahlrecht.de

8/22/2021, 6:38:16 PM

Mint 2021.08.22.. Lásd a legutóbbi verzió

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