kopia lustrzana https://github.com/drastus/sejm-calculator
Updates
rodzic
28744a4487
commit
d9c8582037
6
.babelrc
6
.babelrc
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"presets": [
|
||||
"@babel/env",
|
||||
"@babel/typescript"
|
||||
]
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
# editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[package*.json]
|
||||
indent_style = space
|
||||
indent_size = 2
|
|
@ -1,21 +0,0 @@
|
|||
{
|
||||
"env": {
|
||||
"browser": true,
|
||||
"node": true,
|
||||
"es6": true
|
||||
},
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2018,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"plugins": ["@typescript-eslint"],
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/recommended"
|
||||
],
|
||||
"rules": {
|
||||
"@typescript-eslint/explicit-function-return-type": "off",
|
||||
"@typescript-eslint/no-non-null-assertion": "off"
|
||||
}
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
dist
|
||||
node_modules
|
|
@ -1,17 +0,0 @@
|
|||
{
|
||||
"extends": "stylelint-config-standard",
|
||||
"rules": {
|
||||
"indentation": "tab",
|
||||
"font-family-name-quotes": "always-where-recommended",
|
||||
"function-url-quotes": ["always", {
|
||||
"except": "empty"
|
||||
}],
|
||||
"selector-attribute-quotes": "always",
|
||||
"string-quotes": "single",
|
||||
"at-rule-no-vendor-prefix": true,
|
||||
"media-feature-name-no-vendor-prefix": true,
|
||||
"property-no-vendor-prefix": true,
|
||||
"selector-no-vendor-prefix": true,
|
||||
"value-no-vendor-prefix": true
|
||||
}
|
||||
}
|
Plik diff jest za duży
Load Diff
50
package.json
50
package.json
|
@ -1,50 +0,0 @@
|
|||
{
|
||||
"name": "sejm-mandates-simulator",
|
||||
"version": "1.0.0",
|
||||
"description": "Simulator for the Polish Sejm 2019 election",
|
||||
"scripts": {
|
||||
"build": "webpack",
|
||||
"start": "webpack-dev-server --inline --watch --hot",
|
||||
"deploy": "gh-pages -d build -e kalkulator"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "Michał Górny",
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.5.5",
|
||||
"@babel/preset-env": "^7.5.5",
|
||||
"@babel/preset-typescript": "^7.3.3",
|
||||
"@babel/register": "^7.5.5",
|
||||
"@types/chartist": "^0.9.46",
|
||||
"@types/pug": "^2.0.4",
|
||||
"@typescript-eslint/eslint-plugin": "^2.0.0",
|
||||
"@typescript-eslint/parser": "^2.0.0",
|
||||
"babel-loader": "^8.0.6",
|
||||
"css-loader": "^3.2.0",
|
||||
"cssnano": "^4.1.10",
|
||||
"eslint": "^6.1.0",
|
||||
"eslint-loader": "^3.0.0",
|
||||
"eslint-utils": "^1.4.1",
|
||||
"file-loader": "^4.2.0",
|
||||
"gh-pages": "^2.1.1",
|
||||
"html-webpack-plugin": "^3.2.0",
|
||||
"mini-css-extract-plugin": "^0.8.0",
|
||||
"postcss": "^7.0.17",
|
||||
"postcss-import": "^12.0.1",
|
||||
"postcss-loader": "^3.0.0",
|
||||
"postcss-preset-env": "^6.7.0",
|
||||
"pug": "^2.0.4",
|
||||
"pug-loader": "^2.4.0",
|
||||
"stylelint": "^10.1.0",
|
||||
"stylelint-config-standard": "^18.3.0",
|
||||
"stylelint-webpack-plugin": "^0.10.5",
|
||||
"typescript": "^3.5.3",
|
||||
"webpack": "^4.39.1",
|
||||
"webpack-cli": "^3.3.6",
|
||||
"webpack-dev-server": "^3.8.0",
|
||||
"webpack-livereload-plugin": "^2.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"chartist": "^0.11.3",
|
||||
"modern-normalize": "^0.5.0"
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
module.exports = {
|
||||
plugins: {
|
||||
'postcss-import': {},
|
||||
'postcss-preset-env': {
|
||||
browsers: 'last 2 versions',
|
||||
},
|
||||
'cssnano': {},
|
||||
},
|
||||
};
|
638
src/data.ts
638
src/data.ts
|
@ -1,638 +0,0 @@
|
|||
import {
|
||||
PastSupport,
|
||||
Committee,
|
||||
Constituency,
|
||||
} from './types';
|
||||
|
||||
export const pastSupport: PastSupport = {
|
||||
pis: 37.58,
|
||||
po: 24.09,
|
||||
razem: 3.62,
|
||||
korwin: 4.76,
|
||||
psl: 5.13,
|
||||
zl: 7.55,
|
||||
k15: 8.81,
|
||||
nowoczesna: 7.6,
|
||||
};
|
||||
|
||||
export const committees: Committee[] = [
|
||||
{
|
||||
id: 'pis',
|
||||
name: 'Prawo i Sprawiedliwość',
|
||||
shortName: 'PiS',
|
||||
threshold: 5,
|
||||
pastSupportEquivalence: [['pis', 1]],
|
||||
},
|
||||
{
|
||||
id: 'ko',
|
||||
name: 'Koalicja Obywatelska',
|
||||
shortName: 'KO',
|
||||
threshold: 8,
|
||||
pastSupportEquivalence: [['po', 1], ['nowoczesna', 1]],
|
||||
},
|
||||
{
|
||||
id: 'lewica',
|
||||
name: 'SLD – Lewica',
|
||||
shortName: 'Lew.',
|
||||
threshold: 5,
|
||||
pastSupportEquivalence: [['zl', 1], ['razem', 1]],
|
||||
},
|
||||
{
|
||||
id: 'psl',
|
||||
name: 'PSL – Koalicja Polska',
|
||||
shortName: 'PSL',
|
||||
threshold: 5,
|
||||
pastSupportEquivalence: [['psl', 1], ['k15', 0.5]],
|
||||
},
|
||||
{
|
||||
id: 'konfederacja',
|
||||
name: 'Konfederacja',
|
||||
shortName: 'Konf.',
|
||||
threshold: 5,
|
||||
pastSupportEquivalence: [['korwin', 1], ['k15', 0.5]],
|
||||
},
|
||||
{
|
||||
id: 'mn',
|
||||
name: 'Mniejszość Niemiecka',
|
||||
shortName: 'MN',
|
||||
threshold: 0,
|
||||
pastSupportEquivalence: [],
|
||||
},
|
||||
];
|
||||
|
||||
export const constituencies: Constituency[] = [
|
||||
{
|
||||
name: 'Legnica',
|
||||
size: 12,
|
||||
pastSupport: {
|
||||
pis: 35.70,
|
||||
po: 25.24,
|
||||
razem: 3.64,
|
||||
korwin: 4.32,
|
||||
psl: 3.89,
|
||||
zl: 10.45,
|
||||
k15: 9.59,
|
||||
nowoczesna: 7.15,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Wałbrzych',
|
||||
size: 8,
|
||||
pastSupport: {
|
||||
pis: 31.15,
|
||||
po: 32.65,
|
||||
razem: 3.41,
|
||||
korwin: 4.30,
|
||||
psl: 3.18,
|
||||
zl: 8.76,
|
||||
k15: 8.81,
|
||||
nowoczesna: 6.64,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Wrocław',
|
||||
size: 14,
|
||||
pastSupport: {
|
||||
pis: 31.21,
|
||||
po: 30.49,
|
||||
razem: 4.21,
|
||||
korwin: 5.22,
|
||||
psl: 2.60,
|
||||
zl: 6.10,
|
||||
k15: 8.74,
|
||||
nowoczesna: 10.65,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Bydgoszcz',
|
||||
size: 12,
|
||||
pastSupport: {
|
||||
pis: 30.20,
|
||||
po: 29.64,
|
||||
razem: 3.76,
|
||||
korwin: 4.54,
|
||||
psl: 6.07,
|
||||
zl: 10.04,
|
||||
k15: 7.77,
|
||||
nowoczesna: 7.30,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Toruń',
|
||||
size: 13,
|
||||
pastSupport: {
|
||||
pis: 33.57,
|
||||
po: 25.77,
|
||||
razem: 3.65,
|
||||
korwin: 3.90,
|
||||
psl: 6.75,
|
||||
zl: 10.76,
|
||||
k15: 8.32,
|
||||
nowoczesna: 6.50,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Lublin',
|
||||
size: 15,
|
||||
pastSupport: {
|
||||
pis: 47.57,
|
||||
po: 16.59,
|
||||
razem: 2.75,
|
||||
korwin: 5.00,
|
||||
psl: 7.74,
|
||||
zl: 5.98,
|
||||
k15: 9.32,
|
||||
nowoczesna: 4.54,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Chełm',
|
||||
size: 12,
|
||||
pastSupport: {
|
||||
pis: 48.02,
|
||||
po: 12.31,
|
||||
razem: 2.39,
|
||||
korwin: 4.37,
|
||||
psl: 11.39,
|
||||
zl: 7.11,
|
||||
k15: 10.47,
|
||||
nowoczesna: 3.75,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Zielona Góra',
|
||||
size: 12,
|
||||
pastSupport: {
|
||||
pis: 28.27,
|
||||
po: 28.21,
|
||||
razem: 3.99,
|
||||
korwin: 4.99,
|
||||
psl: 5.12,
|
||||
zl: 10.02,
|
||||
k15: 8.75,
|
||||
nowoczesna: 9.99,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Łódź',
|
||||
size: 10,
|
||||
pastSupport: {
|
||||
pis: 29.90,
|
||||
po: 31.28,
|
||||
razem: 4.63,
|
||||
korwin: 4.78,
|
||||
psl: 2.70,
|
||||
zl: 10.48,
|
||||
k15: 7.24,
|
||||
nowoczesna: 8.99,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Piotrków Trybunalski',
|
||||
size: 9,
|
||||
pastSupport: {
|
||||
pis: 46.95,
|
||||
po: 15.46,
|
||||
razem: 3.06,
|
||||
korwin: 3.91,
|
||||
psl: 7.48,
|
||||
zl: 7.47,
|
||||
k15: 10.08,
|
||||
nowoczesna: 5.59,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Sieradz',
|
||||
size: 12,
|
||||
pastSupport: {
|
||||
pis: 39.93,
|
||||
po: 21.18,
|
||||
razem: 3.54,
|
||||
korwin: 4.10,
|
||||
psl: 7.86,
|
||||
zl: 8.18,
|
||||
k15: 8.92,
|
||||
nowoczesna: 5.32,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Chrzanów',
|
||||
size: 8,
|
||||
pastSupport: {
|
||||
pis: 49.05,
|
||||
po: 20.42,
|
||||
razem: 3.26,
|
||||
korwin: 4.45,
|
||||
psl: 3.03,
|
||||
zl: 5.33,
|
||||
k15: 8.67,
|
||||
nowoczesna: 5.79,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Kraków',
|
||||
size: 14,
|
||||
pastSupport: {
|
||||
pis: 38.62,
|
||||
po: 24.61,
|
||||
razem: 3.88,
|
||||
korwin: 6.35,
|
||||
psl: 2.70,
|
||||
zl: 6.38,
|
||||
k15: 7.26,
|
||||
nowoczesna: 9.73,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Nowy Sącz',
|
||||
size: 10,
|
||||
pastSupport: {
|
||||
pis: 60.56,
|
||||
po: 13.95,
|
||||
razem: 2.13,
|
||||
korwin: 4.31,
|
||||
psl: 4.16,
|
||||
zl: 2.55,
|
||||
k15: 7.83,
|
||||
nowoczesna: 3.69,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Tarnów',
|
||||
size: 9,
|
||||
pastSupport: {
|
||||
pis: 51.99,
|
||||
po: 14.71,
|
||||
razem: 2.43,
|
||||
korwin: 4.72,
|
||||
psl: 8.08,
|
||||
zl: 3.41,
|
||||
k15: 9.60,
|
||||
nowoczesna: 4.54,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Płock',
|
||||
size: 10,
|
||||
pastSupport: {
|
||||
pis: 43.78,
|
||||
po: 16.44,
|
||||
razem: 3.35,
|
||||
korwin: 4.07,
|
||||
psl: 10.66,
|
||||
zl: 8.14,
|
||||
k15: 8.41,
|
||||
nowoczesna: 5.15,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Radom',
|
||||
size: 9,
|
||||
pastSupport: {
|
||||
pis: 47.49,
|
||||
po: 17.55,
|
||||
razem: 2.62,
|
||||
korwin: 3.91,
|
||||
psl: 9.42,
|
||||
zl: 4.82,
|
||||
k15: 8.41,
|
||||
nowoczesna: 4.81,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Siedlce',
|
||||
size: 12,
|
||||
pastSupport: {
|
||||
pis: 51.10,
|
||||
po: 13.55,
|
||||
razem: 2.66,
|
||||
korwin: 4.35,
|
||||
psl: 10.23,
|
||||
zl: 4.35,
|
||||
k15: 8.36,
|
||||
nowoczesna: 4.63,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Warszawa I',
|
||||
size: 20,
|
||||
pastSupport: {
|
||||
pis: 29.89,
|
||||
po: 27.54,
|
||||
razem: 5.54,
|
||||
korwin: 6.18,
|
||||
psl: 0.72,
|
||||
zl: 8.55,
|
||||
k15: 7.76,
|
||||
nowoczesna: 13.39,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Warszawa II',
|
||||
size: 12,
|
||||
pastSupport: {
|
||||
pis: 38.80,
|
||||
po: 25.12,
|
||||
razem: 3.85,
|
||||
korwin: 4.81,
|
||||
psl: 3.80,
|
||||
zl: 5.66,
|
||||
k15: 7.22,
|
||||
nowoczesna: 10.01,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Opole',
|
||||
size: 12,
|
||||
pastSupport: {
|
||||
pis: 27.77,
|
||||
po: 26.23,
|
||||
razem: 3.02,
|
||||
korwin: 3.95,
|
||||
psl: 3.68,
|
||||
zl: 6.75,
|
||||
k15: 12.57,
|
||||
nowoczesna: 7.14,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Krosno',
|
||||
size: 11,
|
||||
pastSupport: {
|
||||
pis: 53.51,
|
||||
po: 13.76,
|
||||
razem: 2.32,
|
||||
korwin: 4.28,
|
||||
psl: 7.28,
|
||||
zl: 4.56,
|
||||
k15: 9.15,
|
||||
nowoczesna: 3.97,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Rzeszów',
|
||||
size: 15,
|
||||
pastSupport: {
|
||||
pis: 56.11,
|
||||
po: 13.11,
|
||||
razem: 2.29,
|
||||
korwin: 4.96,
|
||||
psl: 4.67,
|
||||
zl: 4.42,
|
||||
k15: 9.28,
|
||||
nowoczesna: 4.16,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Białystok',
|
||||
size: 14,
|
||||
pastSupport: {
|
||||
pis: 45.38,
|
||||
po: 16.74,
|
||||
razem: 2.59,
|
||||
korwin: 4.66,
|
||||
psl: 8.07,
|
||||
zl: 7.35,
|
||||
k15: 9.07,
|
||||
nowoczesna: 5.37,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Gdańsk',
|
||||
size: 12,
|
||||
pastSupport: {
|
||||
pis: 29.61,
|
||||
po: 34.72,
|
||||
razem: 3.98,
|
||||
korwin: 5.00,
|
||||
psl: 3.02,
|
||||
zl: 6.59,
|
||||
k15: 7.15,
|
||||
nowoczesna: 9.17,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Gdynia',
|
||||
size: 14,
|
||||
pastSupport: {
|
||||
pis: 31.22,
|
||||
po: 33.46,
|
||||
razem: 4.05,
|
||||
korwin: 4.43,
|
||||
psl: 3.23,
|
||||
zl: 6.64,
|
||||
k15: 8.02,
|
||||
nowoczesna: 8.22,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Bielsko-Biała',
|
||||
size: 9,
|
||||
pastSupport: {
|
||||
pis: 40.42,
|
||||
po: 23.57,
|
||||
razem: 3.72,
|
||||
korwin: 4.68,
|
||||
psl: 3.42,
|
||||
zl: 6.56,
|
||||
k15: 9.36,
|
||||
nowoczesna: 8.27,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Częstochowa',
|
||||
size: 7,
|
||||
pastSupport: {
|
||||
pis: 35.82,
|
||||
po: 20.95,
|
||||
razem: 3.64,
|
||||
korwin: 4.27,
|
||||
psl: 4.99,
|
||||
zl: 11.12,
|
||||
k15: 11.63,
|
||||
nowoczesna: 6.74,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Gliwice',
|
||||
size: 9,
|
||||
pastSupport: {
|
||||
pis: 30.51,
|
||||
po: 28.99,
|
||||
razem: 4.15,
|
||||
korwin: 5.09,
|
||||
psl: 2.50,
|
||||
zl: 7.21,
|
||||
k15: 12.19,
|
||||
nowoczesna: 8.90,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Rybnik',
|
||||
size: 9,
|
||||
pastSupport: {
|
||||
pis: 39.59,
|
||||
po: 24.21,
|
||||
razem: 3.33,
|
||||
korwin: 4.53,
|
||||
psl: 1.79,
|
||||
zl: 5.93,
|
||||
k15: 11.31,
|
||||
nowoczesna: 6.33,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Katowice',
|
||||
size: 12,
|
||||
pastSupport: {
|
||||
pis: 32.92,
|
||||
po: 28.37,
|
||||
razem: 4.08,
|
||||
korwin: 5.55,
|
||||
psl: 0.99,
|
||||
zl: 6.77,
|
||||
k15: 10.05,
|
||||
nowoczesna: 8.66,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Sosnowiec',
|
||||
size: 9,
|
||||
pastSupport: {
|
||||
pis: 29.65,
|
||||
po: 25.56,
|
||||
razem: 4.44,
|
||||
korwin: 4.81,
|
||||
psl: 2.35,
|
||||
zl: 13.97,
|
||||
k15: 10.24,
|
||||
nowoczesna: 8.97,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Kielce',
|
||||
size: 16,
|
||||
pastSupport: {
|
||||
pis: 42.81,
|
||||
po: 17.25,
|
||||
razem: 2.80,
|
||||
korwin: 4.14,
|
||||
psl: 9.51,
|
||||
zl: 7.87,
|
||||
k15: 9.41,
|
||||
nowoczesna: 4.98,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Elbląg',
|
||||
size: 8,
|
||||
pastSupport: {
|
||||
pis: 31.56,
|
||||
po: 30.12,
|
||||
razem: 3.80,
|
||||
korwin: 4.73,
|
||||
psl: 6.69,
|
||||
zl: 7.69,
|
||||
k15: 8.24,
|
||||
nowoczesna: 5.82,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Olsztyn',
|
||||
size: 10,
|
||||
pastSupport: {
|
||||
pis: 30.42,
|
||||
po: 27.07,
|
||||
razem: 3.74,
|
||||
korwin: 5.10,
|
||||
psl: 8.44,
|
||||
zl: 8.76,
|
||||
k15: 8.97,
|
||||
nowoczesna: 6.82,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Kalisz',
|
||||
size: 12,
|
||||
pastSupport: {
|
||||
pis: 31.85,
|
||||
po: 24.69,
|
||||
razem: 3.17,
|
||||
korwin: 4.25,
|
||||
psl: 10.98,
|
||||
zl: 8.82,
|
||||
k15: 7.98,
|
||||
nowoczesna: 7.04,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Konin',
|
||||
size: 9,
|
||||
pastSupport: {
|
||||
pis: 37.41,
|
||||
po: 20.23,
|
||||
razem: 3.98,
|
||||
korwin: 3.99,
|
||||
psl: 6.86,
|
||||
zl: 11.77,
|
||||
k15: 8.83,
|
||||
nowoczesna: 6.94,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Piła',
|
||||
size: 9,
|
||||
pastSupport: {
|
||||
pis: 27.26,
|
||||
po: 31.02,
|
||||
razem: 3.92,
|
||||
korwin: 4.07,
|
||||
psl: 7.66,
|
||||
zl: 9.15,
|
||||
k15: 9.01,
|
||||
nowoczesna: 6.98,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Poznań',
|
||||
size: 10,
|
||||
pastSupport: {
|
||||
pis: 23.90,
|
||||
po: 35.65,
|
||||
razem: 4.60,
|
||||
korwin: 4.77,
|
||||
psl: 1.91,
|
||||
zl: 8.07,
|
||||
k15: 6.06,
|
||||
nowoczesna: 14.49,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Koszalin',
|
||||
size: 8,
|
||||
pastSupport: {
|
||||
pis: 28.58,
|
||||
po: 30.07,
|
||||
razem: 3.90,
|
||||
korwin: 4.46,
|
||||
psl: 4.13,
|
||||
zl: 11.38,
|
||||
k15: 9.41,
|
||||
nowoczesna: 8.06,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Szczecin',
|
||||
size: 12,
|
||||
pastSupport: {
|
||||
pis: 29.09,
|
||||
po: 31.93,
|
||||
razem: 4.12,
|
||||
korwin: 5.33,
|
||||
psl: 3.88,
|
||||
zl: 8.56,
|
||||
k15: 8.42,
|
||||
nowoczesna: 8.66,
|
||||
},
|
||||
},
|
||||
];
|
99
src/index.ts
99
src/index.ts
|
@ -1,99 +0,0 @@
|
|||
import Chartist, {ChartistStatic} from 'chartist';
|
||||
import {committees, constituencies} from './data';
|
||||
import {calculateMandates} from './mandates';
|
||||
import template from './templates/constituency.pug';
|
||||
import './styles.css';
|
||||
|
||||
const clearResults = (bar: ChartistStatic['Bar'], pie: ChartistStatic['Pie']) => {
|
||||
document.querySelectorAll<HTMLTableDataCellElement>(`tr td:last-child`).forEach(td => {
|
||||
td.innerHTML = '';
|
||||
});
|
||||
bar.detach();
|
||||
pie.detach();
|
||||
document.getElementById('support-bar-chart')!.innerHTML = '';
|
||||
document.getElementById('division-pie-chart')!.innerHTML = '';
|
||||
document.getElementById('constituency-results')!.innerHTML = '';
|
||||
}
|
||||
|
||||
const displayConstituencyResults = () => {
|
||||
const container = document.getElementById('constituency-results');
|
||||
constituencies.forEach((constituency, index) => {
|
||||
const data = (constituency.mandates && constituency.support)
|
||||
? constituency.mandates.map((mandates, index) => ({
|
||||
committee: committees[index].name,
|
||||
support: (constituency.support as number[])[index],
|
||||
mandates,
|
||||
}))
|
||||
: [];
|
||||
data.sort((a, b) => b.support - a.support)
|
||||
container!.insertAdjacentHTML('beforeend', template({
|
||||
number: index + 1,
|
||||
name: constituency.name,
|
||||
size: constituency.size,
|
||||
data,
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
const handleCalculateButtonClick = (event: Event) => {
|
||||
event.preventDefault();
|
||||
|
||||
const inputs = document.querySelectorAll<HTMLInputElement>('#support-form input');
|
||||
const support = Array
|
||||
.from(inputs)
|
||||
.map(input => parseFloat(input.value));
|
||||
if (!document.querySelector<HTMLFormElement>('#support-form')!.checkValidity()) return;
|
||||
const mandates = calculateMandates(support);
|
||||
|
||||
mandates.forEach((value, index) => {
|
||||
const committeeId = committees[index].id;
|
||||
const td = document.querySelector<HTMLTableDataCellElement>(`tr.${committeeId} td:last-child`);
|
||||
if (td) td.textContent = value.toString();
|
||||
});
|
||||
|
||||
const barChartData = {
|
||||
labels: committees.map(committee => committee.shortName).slice(0, -1),
|
||||
series: support,
|
||||
};
|
||||
const barChartOptions = {
|
||||
distributeSeries: true,
|
||||
};
|
||||
const bar = new Chartist.Bar('#support-bar-chart', barChartData, barChartOptions);
|
||||
bar.on('draw', (data: {type: string; element: {attr(a: object): object}}) => {
|
||||
if (data.type === 'bar') {
|
||||
data.element.attr({
|
||||
style: 'stroke-width: 30px',
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const pieChartData = {
|
||||
series: mandates,
|
||||
};
|
||||
const pieChartOptions = {
|
||||
donut: true,
|
||||
donutWidth: 60,
|
||||
startAngle: 270,
|
||||
total: 460 * 2,
|
||||
labelInterpolationFnc: (value: number) => {
|
||||
return value < 15 ? '' : String(value);
|
||||
},
|
||||
};
|
||||
const pie = new Chartist.Pie('#division-pie-chart', pieChartData, pieChartOptions);
|
||||
|
||||
displayConstituencyResults();
|
||||
|
||||
inputs.forEach(input => input.addEventListener('input', () => {
|
||||
clearResults(bar, pie);
|
||||
}));
|
||||
}
|
||||
|
||||
const bindActions = () => {
|
||||
document
|
||||
.querySelector('#calculate-button')!
|
||||
.addEventListener('click', handleCalculateButtonClick);
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
bindActions();
|
||||
});
|
|
@ -1,62 +0,0 @@
|
|||
import {committees, constituencies, pastSupport} from './data';
|
||||
import {Constituency} from './types';
|
||||
|
||||
const calculateLocalSupport = (
|
||||
support: number[],
|
||||
pastSupportProjection: number[],
|
||||
constituency: Constituency,
|
||||
): number[] => {
|
||||
const localPastSupport = constituency.pastSupport;
|
||||
const localPastSupportProjection = support.map((committeeSupport, index) => (
|
||||
committees[index].pastSupportEquivalence
|
||||
.map(pastCommittee => localPastSupport[pastCommittee[0]] * pastCommittee[1])
|
||||
.reduce((a, b) => a + b, 0)
|
||||
));
|
||||
const localSupportDeviation = pastSupportProjection
|
||||
.map((pastCommitteSupportProjection, index) => (
|
||||
localPastSupportProjection[index] / pastCommitteSupportProjection
|
||||
)
|
||||
);
|
||||
const localSupport = support.map((committeeSupport, index) => (
|
||||
committeeSupport * localSupportDeviation[index]
|
||||
));
|
||||
if (constituency.name === 'Opole') {
|
||||
localSupport.push(8.14);
|
||||
}
|
||||
return localSupport;
|
||||
}
|
||||
|
||||
export const calculateMandates = (support: number[]): number[] => {
|
||||
const pastSupportProjection = support.map((committeeSupport, index) => (
|
||||
committees[index].pastSupportEquivalence
|
||||
.map(pastCommittee => pastSupport[pastCommittee[0]] * pastCommittee[1])
|
||||
.reduce((a, b) => a + b, 0)
|
||||
));
|
||||
const mandates: number[] = new Array(support.length + 1).fill(0);
|
||||
constituencies.forEach(constituency => {
|
||||
const localSupport = calculateLocalSupport(support, pastSupportProjection, constituency);
|
||||
constituency.support = localSupport;
|
||||
constituency.mandates = new Array(localSupport.length).fill(0);
|
||||
const filteredLocalSupport = localSupport.map((localCommitteeSupport, index) => {
|
||||
if (support[index] < committees[index].threshold) return 0;
|
||||
return localCommitteeSupport;
|
||||
});
|
||||
const quotients: {quotient: number; committeeIndex: number}[] = [];
|
||||
for (let divisor = 1; divisor <= constituency.size; divisor++) {
|
||||
for (let committeeIndex = 0; committeeIndex < localSupport.length; committeeIndex++) {
|
||||
quotients.push({
|
||||
quotient: filteredLocalSupport[committeeIndex] / divisor,
|
||||
committeeIndex,
|
||||
});
|
||||
}
|
||||
}
|
||||
quotients.sort((a, b) => b.quotient - a.quotient);
|
||||
quotients.slice(0, constituency.size).forEach(quotient => {
|
||||
if (quotient.quotient > 0) {
|
||||
mandates[quotient.committeeIndex]++;
|
||||
constituency.mandates![quotient.committeeIndex]++;
|
||||
}
|
||||
});
|
||||
});
|
||||
return mandates;
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
declare module '*.pug' {
|
||||
import pug = require('pug');
|
||||
const content: pug.compileTemplate;
|
||||
export = content;
|
||||
}
|
163
src/styles.css
163
src/styles.css
|
@ -1,163 +0,0 @@
|
|||
@import 'modern-normalize/modern-normalize.css';
|
||||
@import 'chartist/dist/chartist.min.css';
|
||||
|
||||
body {
|
||||
color: #333;
|
||||
background-color: lightgoldenrodyellow;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 100%;
|
||||
max-width: 58rem;
|
||||
margin: 1rem auto;
|
||||
padding: 0.25rem 1.5rem 1rem;
|
||||
border: 1px solid lightgray;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
|
||||
p {
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
.charts-row {
|
||||
display: flex;
|
||||
height: auto;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.ct-chart:empty {
|
||||
height: 0;
|
||||
}
|
||||
|
||||
#division-pie-chart svg {
|
||||
transform-origin: (0, 100%);
|
||||
transform: translate(-6%, 34%) scale(1.1);
|
||||
}
|
||||
|
||||
#division-pie-chart .ct-label {
|
||||
fill: white;
|
||||
}
|
||||
|
||||
@media (max-width: 500px) {
|
||||
.charts-row {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
}
|
||||
|
||||
input[type='number'] {
|
||||
appearance: textfield;
|
||||
}
|
||||
|
||||
input[type='number']::-webkit-inner-spin-button,
|
||||
input[type='number']::-webkit-outer-spin-button {
|
||||
appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1rem;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
#constituency-results {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
#constituency-results::after {
|
||||
content: '';
|
||||
flex: auto;
|
||||
max-width: 26rem;
|
||||
margin: 0.5rem 0;
|
||||
padding: 0.5rem 1rem;
|
||||
border: 1px solid white;
|
||||
}
|
||||
|
||||
.constituency {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
max-width: 26rem;
|
||||
margin: 0.5rem 0;
|
||||
padding: 0.5rem 1rem;
|
||||
border: 1px solid grey;
|
||||
}
|
||||
|
||||
.constituency-data {
|
||||
width: 11rem;
|
||||
}
|
||||
|
||||
.constituency table {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
.constituency p,
|
||||
.constituency td {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.constituency td:last-child {
|
||||
width: 2rem;
|
||||
padding-left: 1rem;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
#support-form table {
|
||||
margin: 1rem auto 0;
|
||||
}
|
||||
|
||||
#support-form button {
|
||||
display: block;
|
||||
margin: 1rem auto 2.5rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#support-form input {
|
||||
width: 3.5rem;
|
||||
padding: 0.25rem;
|
||||
margin: 0 0.25rem 0 0.5rem;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
#support-form table td,
|
||||
#support-form table th {
|
||||
height: 2rem;
|
||||
}
|
||||
|
||||
#support-form table td:nth-child(2) {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#support-form table td:last-child {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.ct-series-a .ct-bar,
|
||||
.ct-series-a .ct-slice-donut {
|
||||
stroke: #56e;
|
||||
}
|
||||
|
||||
.ct-series-b .ct-bar,
|
||||
.ct-series-b .ct-slice-donut {
|
||||
stroke: #eb4;
|
||||
}
|
||||
|
||||
.ct-series-c .ct-bar,
|
||||
.ct-series-c .ct-slice-donut {
|
||||
stroke: #d44;
|
||||
}
|
||||
|
||||
.ct-series-d .ct-bar,
|
||||
.ct-series-d .ct-slice-donut {
|
||||
stroke: #1c6;
|
||||
}
|
||||
|
||||
.ct-series-e .ct-bar,
|
||||
.ct-series-e .ct-slice-donut {
|
||||
stroke: #655;
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
.constituency
|
||||
.constituency-data
|
||||
h2 Okręg #{number} #{name}
|
||||
p Łącznie #{size} mandatów
|
||||
table
|
||||
each datum in data
|
||||
tr
|
||||
td #{datum.committee}
|
||||
td #{datum.mandates}
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
p.
|
||||
Przeliczanie sondażowych wyników poparcia dla partii na uzyskane mandaty w Sejmie nie jest
|
||||
łatwe. Zgodnie z obecnie obowiązującą w Polsce ordynacją wyborczą głosy na poszczególne
|
||||
komitety są przeliczane na mandaty metodą D’Hondta osobno w każdym z 41 okręgów. Symulacja
|
||||
podziału mandatów przy założeniu takiego samego wyniku we wszystkich okręgach jest bardzo
|
||||
niedokładna, bowiem różnice w rozkładzie poparcia w poszczególnych okręgach mają istotne
|
||||
przełożenie na uzyskiwane mandaty.
|
||||
p.
|
||||
Poniższy kalkulator próbuje rozwiązać ten problem poprzez symulację zróżnicowanego poparcia
|
||||
partii w okręgach na podstawie szczegółowych wyników wyborów do Sejmu w 2015 roku.
|
||||
Ugrupowanie, które w danym okręgu miało wtedy poparcie wyższe/niższe niż w całym kraju,
|
||||
również w tej symulacji będzie miało w tym okręgu odpowiednio wyższe/niższe poparcie. Pozwala
|
||||
to na sporządzenie szczegółowej prognozy podziału mandatów na poziomie poszczególnych okręgów.
|
||||
p.
|
||||
Oczywiście problemem pozostaje ustalenie przepływów elektoratu między ugrupowaniami
|
||||
startującymi w 2015 roku a obecnymi. Można to zrobić jedynie w mocno przybliżony sposób.
|
||||
W przypadku PiS-u odpowiednikiem z poprzednich wyborów jest ten sam komitet. Dla pozostałych
|
||||
komitetów zastosowano następujące odpowiedniki: KO ≈ PO + Nowoczesna; Lewica ≈ Zjednoczona
|
||||
Lewica + Razem; PSL ≈ PSL + ½ Kukiz’15; Konfederacja ≈ KORWiN + ½ Kukiz’15.
|
||||
form#support-form
|
||||
table
|
||||
tr
|
||||
th Komitet
|
||||
th Poparcie
|
||||
th Mandaty
|
||||
tr(class='pis')
|
||||
td
|
||||
label(for='pis') Prawo i Sprawiedliwość
|
||||
td
|
||||
input(type='number' step='any' id='pis' name='pis')
|
||||
| %
|
||||
td
|
||||
tr(class='ko')
|
||||
td
|
||||
label(for='ko') Koalicja Obywatelska
|
||||
td
|
||||
input(type='number' step='any' id='ko' name='ko')
|
||||
| %
|
||||
td
|
||||
tr(class='lewica')
|
||||
td
|
||||
label(for='lewica') SLD – Lewica
|
||||
td
|
||||
input(type='number' step='any' id='lewica' name='lewica')
|
||||
| %
|
||||
td
|
||||
tr(class='psl')
|
||||
td
|
||||
label(for='psl') PSL – Koalicja Polska
|
||||
td
|
||||
input(type='number' step='any' id='psl' name='psl')
|
||||
| %
|
||||
td
|
||||
tr(class='konfederacja')
|
||||
td
|
||||
label(for='konfederacja') Konfederacja
|
||||
td
|
||||
input(type='number' step='any' id='konfederacja' name='konfederacja')
|
||||
| %
|
||||
td
|
||||
tr(class='mn')
|
||||
td Mniejszość Niemiecka
|
||||
td
|
||||
td
|
||||
button#calculate-button Oblicz
|
||||
|
||||
.charts-row
|
||||
#support-bar-chart.ct-chart.ct-perfect-fourth
|
||||
#division-pie-chart.ct-chart.ct-perfect-fourth
|
||||
|
||||
#constituency-results
|
|
@ -1,10 +0,0 @@
|
|||
doctype html
|
||||
html(lang='pl')
|
||||
head
|
||||
title Kalkulator mandatów w wyborach do Sejmu
|
||||
meta(charset="UTF-8")
|
||||
body
|
||||
div.container
|
||||
h1.main-heading Kalkulator mandatów w wyborach do Sejmu 2019
|
||||
|
||||
include content.pug
|
21
src/types.ts
21
src/types.ts
|
@ -1,21 +0,0 @@
|
|||
type PastCommiteeId = 'pis' | 'po' | 'razem' | 'korwin' | 'psl' | 'zl' | 'k15' | 'nowoczesna'
|
||||
|
||||
export type PastSupport = {
|
||||
[pastCommitteeId in PastCommiteeId]: number;
|
||||
}
|
||||
|
||||
export type Committee = {
|
||||
id: string;
|
||||
name: string;
|
||||
shortName: string;
|
||||
threshold: number;
|
||||
pastSupportEquivalence: [PastCommiteeId, number][];
|
||||
}
|
||||
|
||||
export type Constituency = {
|
||||
name: string;
|
||||
size: number;
|
||||
pastSupport: PastSupport;
|
||||
support?: number[];
|
||||
mandates?: number[];
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist/",
|
||||
"strict": true,
|
||||
"module": "es6",
|
||||
"target": "es5",
|
||||
"allowJs": true,
|
||||
"sourceMap": true,
|
||||
"allowSyntheticDefaultImports": true
|
||||
}
|
||||
}
|
|
@ -1,81 +0,0 @@
|
|||
import path from 'path';
|
||||
import HtmlWebpackPlugin from 'html-webpack-plugin';
|
||||
import LiveReloadPlugin from 'webpack-livereload-plugin';
|
||||
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
|
||||
import StyleLintPlugin from 'stylelint-webpack-plugin';
|
||||
|
||||
export default {
|
||||
entry: './src/index.ts',
|
||||
output: {
|
||||
filename: 'bundle.js',
|
||||
path: path.resolve(__dirname, 'dist'),
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.ts', '.js', '.json'],
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.ts$/,
|
||||
exclude: /node_modules/,
|
||||
use: 'babel-loader',
|
||||
},
|
||||
{
|
||||
test: /\.ts$/,
|
||||
exclude: /node_modules/,
|
||||
enforce: 'pre',
|
||||
use: {
|
||||
loader: 'eslint-loader',
|
||||
options: {
|
||||
configFile: __dirname + '/.eslintrc.json',
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.pug$/,
|
||||
exclude: /node_modules/,
|
||||
use: 'pug-loader',
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
exclude: /node_modules/,
|
||||
use: [
|
||||
{
|
||||
loader: MiniCssExtractPlugin.loader,
|
||||
},
|
||||
{
|
||||
loader: 'css-loader',
|
||||
options: {importLoaders: 1},
|
||||
},
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
config: {
|
||||
path: __dirname + '/postcss.config.js',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
new HtmlWebpackPlugin({
|
||||
template: './src/templates/index.pug',
|
||||
}),
|
||||
new MiniCssExtractPlugin({
|
||||
filename: "[name].css",
|
||||
chunkFilename: "[id].css"
|
||||
}),
|
||||
new StyleLintPlugin({
|
||||
configFile: path.resolve(__dirname, '.stylelintrc.json'),
|
||||
context: path.resolve(__dirname, './src'),
|
||||
files: '**/*.css',
|
||||
failOnError: false,
|
||||
quiet: false,
|
||||
}),
|
||||
new LiveReloadPlugin({
|
||||
appendScriptTag: true
|
||||
}),
|
||||
],
|
||||
};
|
Ładowanie…
Reference in New Issue