Greasy Fork is available in English.

Koalitionenrechner - wahlrecht.de

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

Verze ze dne 22. 08. 2021. Zobrazit nejnovější verzi.

  1. // ==UserScript==
  2. // @name Koalitionenrechner - wahlrecht.de
  3. // @namespace Violentmonkey Scripts
  4. // @match https://www.wahlrecht.de/umfragen/
  5. // @grant none
  6. // @version 1.0
  7. // @author Sidem
  8. // @description 8/22/2021, 6:38:16 PM
  9. // ==/UserScript==
  10. /* jshint esversion: 6 */
  11.  
  12.  
  13. window.addEventListener('load', function () {
  14. function generatePowerSet(array) {
  15. var result = [];
  16. result.push([]);
  17.  
  18. for (var i = 1; i < (1 << array.length); i++) {
  19. var subset = [];
  20. for (var j = 0; j < array.length; j++)
  21. if (i & (1 << j))
  22. subset.push(array[j]);
  23.  
  24. result.push(subset);
  25. }
  26.  
  27. return result;
  28. }
  29. let data = [
  30. {name:'CDU/CSU', votes:12000},
  31. {name:'SPD', votes:15000},
  32. {name:'GRÜNE', votes:5500},
  33. {name:'FDP', votes:12800},
  34. {name:'LINKE', votes:16000},
  35. {name:'AfD', votes:8800},
  36. {name:'Sonstige', votes:1800}
  37. ];
  38. let names = ['CDU/CSU','SPD','GRÜNE','FDP','LINKE','AfD','Sonstige'];
  39. let partyIcons = ['⚫️','🔴','🟢','🟡','🟣','🔵'];
  40. let allPossibleCoalitions = generatePowerSet(partyIcons);
  41. allPossibleCoalitions = allPossibleCoalitions.filter((el) => { return (el.length > 1 && el.length < 4)}); // filter to only 2-4 party coalitions
  42. let coalitions = allPossibleCoalitions.filter((el) => { // filter exclusions, eg far right wont have a coalition with far left
  43. if (el.includes('🔵') && el.includes('🟢')) return false;
  44. if (el.includes('🔵') && el.includes('🔴')) return false;
  45. if (el.includes('🔵') && el.includes('🟣')) return false;
  46. if (el.includes('🟣') && el.includes('🟡')) return false;
  47. if (el.includes('🟣') && el.includes('⚫️')) return false;
  48. return true;
  49. });
  50.  
  51. const getPartyColor = (name) => {
  52. switch(name) {
  53. case 'CDU/CSU':
  54. return '#000000';
  55. case 'SPD':
  56. return '#FF0000';
  57. case 'GRÜNE':
  58. return '#00FF00';
  59. case 'FDP':
  60. return '#FFFF00';
  61. case 'LINKE':
  62. return '#FF0088';
  63. case 'AfD':
  64. return '#1199FF';
  65. case 'Sonstige':
  66. return '#888888';
  67. default:
  68. return '#888888';
  69. }
  70. };
  71. const getColorIcon = (name) => {
  72. switch(name) {
  73. case 'CDU/CSU':
  74. return '⚫️';
  75. case 'SPD':
  76. return '🔴';
  77. case 'GRÜNE':
  78. return '🟢';
  79. case 'FDP':
  80. return '🟡';
  81. case 'LINKE':
  82. return '🟣';
  83. case 'AfD':
  84. return '🔵';
  85. case 'Sonstige':
  86. return '⚪️';
  87. default:
  88. return '⚪️';
  89. }
  90. };
  91. function setChart() {
  92. let canvas = document.getElementById('c');
  93. let ctx = canvas.getContext('2d');
  94. canvas.width = 500;
  95. canvas.height = 400;
  96. let total = data.reduce( (ttl, party) => {
  97. return ttl + party.votes
  98. }, 0);
  99. let startAngle = 0;
  100. let radius = 100;
  101. let cx = canvas.width/2;
  102. let cy = canvas.height/2;
  103.  
  104. data.forEach( party => {
  105. //set the styles before beginPath
  106. ctx.fillStyle = getPartyColor(party.name);
  107. ctx.lineWidth = 1;
  108. ctx.strokeStyle = '#333';
  109. ctx.beginPath();
  110. //console.log(total, party.votes, party.votes/total);
  111. // draw the pie wedges
  112. let endAngle = ((party.votes / total) * Math.PI * 2) + startAngle;
  113. ctx.moveTo(cx, cy);
  114. ctx.arc(cx, cy, radius, startAngle, endAngle, false);
  115. ctx.lineTo(cx, cy);
  116. ctx.fill();
  117. ctx.stroke();
  118. ctx.closePath();
  119.  
  120. // add the labels
  121. ctx.beginPath();
  122. ctx.font = '20px Helvetica, Calibri';
  123. ctx.textAlign = 'center';
  124. ctx.fillStyle = 'rebeccapurple';
  125. // midpoint between the two angles
  126. // 1.5 * radius is the length of the Hypotenuse
  127. let theta = (startAngle + endAngle) / 2;
  128. let deltaY = Math.sin(theta) * 1.5 * radius;
  129. let deltaX = Math.cos(theta) * 1.5 * radius;
  130. /***
  131. SOH - sin(angle) = opposite / hypotenuse
  132. = opposite / 1px
  133. CAH - cos(angle) = adjacent / hypotenuse
  134. = adjacent / 1px
  135. TOA
  136.  
  137. ***/
  138. ctx.fillText(party.name, deltaX+cx, deltaY+cy);
  139. ctx.closePath();
  140.  
  141. startAngle = endAngle;
  142. });
  143. }
  144. function getCoalitions() {
  145. let str = "";
  146. let currentCoalitionVotes = 0;
  147. let results = [];
  148. for (let coalition of coalitions) {
  149. let currentCoalitionVotes = 0;
  150. for (let p of coalition) {
  151. currentCoalitionVotes += getPartyVotes(p);
  152. }
  153. results.push({coalition:coalition.join(""), votes: currentCoalitionVotes});
  154. }
  155. results.sort((a,b) => {return b.votes - a.votes;});
  156. for (let c of results) str += c.coalition + ": \t\t" + c.votes.toFixed(1) + "%\n";
  157. coalitionBox.innerText = str;
  158. }
  159. function clean(str) {
  160. return parseFloat(str.replace(',', '.').replace(' %', ''));
  161. }
  162. function getPartyVotes(identifier) {
  163. for (let p of data) {
  164. if (p.name == identifier || p.color == identifier) {
  165. return p.votes;
  166. }
  167. }
  168. return 0;
  169. }
  170. let getChart = (e) => {
  171. let colDataElements = document.getElementsByClassName(e.target.classList[e.target.classList.length-1]);
  172. data = [];
  173. let i = 0;
  174. for (let el of colDataElements) {
  175. data.push({name:names[i], votes:clean(el.innerText), color: getColorIcon(names[i])})
  176. i++;
  177. }
  178. data.sort((a,b) => {return b.votes - a.votes;});
  179. setChart();
  180. getCoalitions();
  181. };
  182. let partyIds = ["cdu","spd","gru","fdp","lin","afd","son"];
  183. let rows = document.getElementsByTagName('tr');
  184. for (let row of rows) {
  185. if (partyIds.includes(row.id)) {
  186. let numbers = row.getElementsByTagName('td');
  187. let n = 0;
  188. for (let number of numbers) {
  189. if (n != 0 && n != 9) {
  190. number.classList.add('col-'+n);
  191. number.onclick = getChart;
  192. number.style.cursor = 'pointer';
  193. number.addEventListener("mouseenter", function( e ) {
  194. let columnClass = e.target.classList[e.target.classList.length-1];
  195. let column = document.getElementsByClassName(columnClass);
  196. for (let item of column) {
  197. item.style.backgroundColor = 'aqua';
  198. }
  199. });
  200. number.addEventListener("mouseleave", function( e ) {
  201. let columnClass = e.target.classList[e.target.classList.length-1];
  202. let column = document.getElementsByClassName(columnClass);
  203. for (let item of column) {
  204. item.style.backgroundColor = 'white';
  205. }
  206. });
  207. }
  208. n++;
  209. }
  210. }
  211. }
  212. let canvas = document.createElement('canvas');
  213. canvas.setAttribute('id','c');
  214. let info = document.getElementById('info');
  215. info.parentNode.insertBefore(canvas, info);
  216. let coalitionBox = document.createElement('div');
  217. coalitionBox.setAttribute('id','coalitionBox');
  218. coalitionBox.style.marginRight = '270px';
  219. coalitionBox.style.marginTop = '40px';
  220. coalitionBox.style.float = 'right';
  221. info.parentNode.insertBefore(coalitionBox, info);
  222. }, false);