kopia lustrzana https://github.com/drastus/sejm-calculator
Add constituency map
rodzic
8f91e48048
commit
d74f6d567e
|
@ -17,5 +17,6 @@ module.exports = {
|
||||||
'^.+\\.[jt]s$': 'ts-jest',
|
'^.+\\.[jt]s$': 'ts-jest',
|
||||||
'\\.(pug)$': 'jest-transform-pug',
|
'\\.(pug)$': 'jest-transform-pug',
|
||||||
'.+\\.(css)$': 'jest-transform-stub',
|
'.+\\.(css)$': 'jest-transform-stub',
|
||||||
|
'^.+\\.svg$': 'jest-transform-stub',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
import {BarChart, PieChart, Svg} from 'chartist';
|
import {BarChart, PieChart, Svg} from 'chartist';
|
||||||
import {benchSort, committees, constituencies} from './data';
|
import {benchSort, committees, constituencies} from './data';
|
||||||
import calculateMandates from './mandates';
|
import calculateMandates from './mandates';
|
||||||
|
import constituencyResultsTemplate from './templates/cresults.pug';
|
||||||
import constituencyTemplate from './templates/constituency.pug';
|
import constituencyTemplate from './templates/constituency.pug';
|
||||||
import tableTemplate from './templates/table.pug';
|
import tableTemplate from './templates/table.pug';
|
||||||
|
import constituenciesMap from './images/c41.svg';
|
||||||
import './styles/styles.css';
|
import './styles/styles.css';
|
||||||
|
|
||||||
const {location} = window;
|
const {location} = window;
|
||||||
|
@ -33,7 +35,7 @@ export const clearResults = (): void => {
|
||||||
document.getElementById('support-bar-chart')!.innerHTML = '';
|
document.getElementById('support-bar-chart')!.innerHTML = '';
|
||||||
document.getElementById('division-pie-chart')!.innerHTML = '';
|
document.getElementById('division-pie-chart')!.innerHTML = '';
|
||||||
const constituencyResultContainer = document.getElementById('constituency-results');
|
const constituencyResultContainer = document.getElementById('constituency-results');
|
||||||
if (constituencyResultContainer) constituencyResultContainer.innerHTML = '';
|
if (constituencyResultContainer) constituencyResultContainer.innerHTML = constituencyResultsTemplate();
|
||||||
if (location.search) {
|
if (location.search) {
|
||||||
const urlWithoutSearchString = location.href.split('?')[0];
|
const urlWithoutSearchString = location.href.split('?')[0];
|
||||||
window.history.pushState('', '', urlWithoutSearchString);
|
window.history.pushState('', '', urlWithoutSearchString);
|
||||||
|
@ -126,21 +128,57 @@ const displayPieChart = (mandates: number[]) => {
|
||||||
const displayConstituencyResults = () => {
|
const displayConstituencyResults = () => {
|
||||||
const container = document.getElementById('constituency-results');
|
const container = document.getElementById('constituency-results');
|
||||||
if (container) {
|
if (container) {
|
||||||
constituencies.forEach((constituency, constituenyIndex) => {
|
container.innerHTML = constituencyResultsTemplate();
|
||||||
const data = (constituency.mandates && constituency.support)
|
const constituencyResult = document.getElementById('constituency-result')!;
|
||||||
? constituency.mandates.map((mandates, committeeIndex) => ({
|
|
||||||
committee: committees[committeeIndex].name,
|
const mapObject = document.getElementById('constituencies-map')! as HTMLObjectElement;
|
||||||
support: (constituency.support as number[])[committeeIndex],
|
mapObject.setAttribute('data', constituenciesMap);
|
||||||
mandates,
|
mapObject.addEventListener('load', () => {
|
||||||
}))
|
const svgDocument = mapObject.contentDocument!;
|
||||||
: [];
|
const constituencyNumber = svgDocument.getElementById('constituency-number')!;
|
||||||
data.sort((a, b) => b.support - a.support);
|
const constituencyName = svgDocument.getElementById('constituency-name')!;
|
||||||
container.insertAdjacentHTML('beforeend', constituencyTemplate({
|
const paths = svgDocument.querySelectorAll<SVGPathElement>('svg path');
|
||||||
number: constituenyIndex + 1,
|
paths.forEach((path) => {
|
||||||
name: constituency.name,
|
const cid = parseInt(path.dataset.cid!, 10);
|
||||||
size: constituency.size,
|
const constituency = constituencies[cid - 1];
|
||||||
data,
|
const data = (constituency.mandates && constituency.support)
|
||||||
}));
|
? constituency.mandates.map((mandates, committeeIndex) => ({
|
||||||
|
committee: committees[committeeIndex],
|
||||||
|
support: (constituency.support as number[])[committeeIndex],
|
||||||
|
mandates,
|
||||||
|
}))
|
||||||
|
: [];
|
||||||
|
data.sort((a, b) => b.support - a.support);
|
||||||
|
if (data[0].support === data[1].support) {
|
||||||
|
path.style.fill = 'lightgray';
|
||||||
|
} else {
|
||||||
|
path.classList.add(data[0].committee.id);
|
||||||
|
if (data[0].support >= 50) path.classList.add('bright50');
|
||||||
|
else if (data[0].support < 40) path.classList.add('bright30');
|
||||||
|
}
|
||||||
|
|
||||||
|
path.addEventListener('mouseover', (event) => {
|
||||||
|
const pathElement = event.target as SVGPathElement;
|
||||||
|
pathElement.style.stroke = '#444';
|
||||||
|
constituencyNumber.innerHTML = `Okręg nr ${pathElement.dataset.cid}`;
|
||||||
|
constituencyName.innerHTML = pathElement.dataset.cname as string;
|
||||||
|
});
|
||||||
|
path.addEventListener('mouseout', (event) => {
|
||||||
|
const pathElement = event.target as SVGPathElement;
|
||||||
|
pathElement.style.stroke = '#fff';
|
||||||
|
constituencyNumber.innerHTML = '';
|
||||||
|
constituencyName.innerHTML = '';
|
||||||
|
});
|
||||||
|
path.addEventListener('click', (event) => {
|
||||||
|
(event.target as SVGPathElement).style.stroke = '#ccc';
|
||||||
|
constituencyResult.innerHTML = constituencyTemplate({
|
||||||
|
number: cid,
|
||||||
|
name: constituency.name,
|
||||||
|
size: constituency.size,
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
File diff suppressed because one or more lines are too long
Po Szerokość: | Wysokość: | Rozmiar: 225 KiB |
|
@ -7,7 +7,8 @@ body {
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
main,
|
||||||
|
footer {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 58rem;
|
max-width: 58rem;
|
||||||
margin: 1rem auto;
|
margin: 1rem auto;
|
||||||
|
@ -21,6 +22,10 @@ body {
|
||||||
padding: 0.25rem auto 1rem;
|
padding: 0.25rem auto 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.updates-texts {
|
||||||
|
font-size: 13.5px;
|
||||||
|
}
|
||||||
|
|
||||||
.updates {
|
.updates {
|
||||||
margin-top: -10px;
|
margin-top: -10px;
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
|
@ -44,6 +49,8 @@ li {
|
||||||
display: flex;
|
display: flex;
|
||||||
height: auto;
|
height: auto;
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
|
z-index: -1;
|
||||||
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ct-chart:empty {
|
.ct-chart:empty {
|
||||||
|
@ -90,40 +97,48 @@ h2 {
|
||||||
justify-content: space-around;
|
justify-content: space-around;
|
||||||
}
|
}
|
||||||
|
|
||||||
#constituency-results::after {
|
#constituency-result {
|
||||||
content: '';
|
flex: 1;
|
||||||
flex: auto;
|
}
|
||||||
max-width: 26rem;
|
|
||||||
margin: 0.5rem 0;
|
#constituency-result .info {
|
||||||
padding: 0.5rem 1rem;
|
margin-top: 32px;
|
||||||
border: 1px solid white;
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#constituencies-map {
|
||||||
|
flex: 1;
|
||||||
|
max-width: min(438px, 90vw);
|
||||||
}
|
}
|
||||||
|
|
||||||
.constituency {
|
.constituency {
|
||||||
display: flex;
|
max-width: 25rem;
|
||||||
flex-wrap: wrap;
|
margin: 0.5rem auto;
|
||||||
max-width: 26rem;
|
|
||||||
margin: 0.5rem 0;
|
|
||||||
padding: 0.5rem 1rem;
|
padding: 0.5rem 1rem;
|
||||||
border: 1px solid grey;
|
|
||||||
}
|
|
||||||
|
|
||||||
.constituency-data {
|
|
||||||
width: 11rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.constituency table {
|
.constituency table {
|
||||||
margin-left: 1rem;
|
border-collapse: collapse;
|
||||||
}
|
}
|
||||||
|
|
||||||
.constituency p,
|
.constituency p,
|
||||||
|
.constituency th,
|
||||||
.constituency td {
|
.constituency td {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.constituency th,
|
||||||
|
.constituency td {
|
||||||
|
padding: 4px 12px;
|
||||||
|
border: 1px solid #888;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.constituency th:nth-child(2),
|
||||||
|
.constituency th:last-child,
|
||||||
|
.constituency td:nth-child(2),
|
||||||
.constituency td:last-child {
|
.constituency td:last-child {
|
||||||
width: 2rem;
|
width: 2rem;
|
||||||
padding-left: 1rem;
|
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,36 +164,55 @@ h2 {
|
||||||
height: 2rem;
|
height: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
#support-form table td:nth-child(2) {
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
#support-form table td:last-child {
|
#support-form table td:last-child {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--pis: #31469b;
|
||||||
|
--ko: #fca43f;
|
||||||
|
--lewica: #d44;
|
||||||
|
--td: #8bd32e;
|
||||||
|
--konfederacja: #655;
|
||||||
|
--mn: #aaa;
|
||||||
|
}
|
||||||
|
|
||||||
.pis {
|
.pis {
|
||||||
stroke: #263778;
|
stroke: var(--pis);
|
||||||
|
fill: var(--pis);
|
||||||
}
|
}
|
||||||
|
|
||||||
.ko {
|
.ko {
|
||||||
stroke: #fca43f;
|
stroke: var(--ko);
|
||||||
|
fill: var(--ko);
|
||||||
}
|
}
|
||||||
|
|
||||||
.lewica {
|
.lewica {
|
||||||
stroke: #d44;
|
stroke: var(--lewica);
|
||||||
|
fill: var(--lewica);
|
||||||
}
|
}
|
||||||
|
|
||||||
.td {
|
.td {
|
||||||
stroke: #8bd32e;
|
stroke: var(--td);
|
||||||
|
fill: var(--td);
|
||||||
}
|
}
|
||||||
|
|
||||||
.konfederacja {
|
.konfederacja {
|
||||||
stroke: #655;
|
stroke: var(--konfederacja);
|
||||||
|
fill: var(--konfederacja);
|
||||||
}
|
}
|
||||||
|
|
||||||
.mn {
|
.mn {
|
||||||
stroke: #aaa;
|
stroke: var(--mn);
|
||||||
|
fill: var(--mn);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bright30 {
|
||||||
|
filter: brightness(125%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bright50 {
|
||||||
|
filter: brightness(75%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.bar-value {
|
.bar-value {
|
||||||
|
@ -189,7 +223,7 @@ footer {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
margin: 0.5rem 1rem;
|
padding: 1rem 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
address {
|
address {
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
declare module '*.svg' {
|
||||||
|
const content: string;
|
||||||
|
export default content;
|
||||||
|
}
|
|
@ -1,10 +1,14 @@
|
||||||
.constituency
|
.constituency
|
||||||
.constituency-data
|
h2 Okręg #{number} #{name}
|
||||||
h2 Okręg #{number} #{name}
|
|
||||||
p Łącznie #{size} mandatów
|
|
||||||
table
|
table
|
||||||
|
tr
|
||||||
|
th Komitet
|
||||||
|
th Poparcie
|
||||||
|
th Mandaty
|
||||||
each datum in data
|
each datum in data
|
||||||
tr
|
tr
|
||||||
td #{datum.committee}
|
td #{datum.committee.name}
|
||||||
|
td #{datum.support.toLocaleString('pl', {minimumFractionDigits: 1, maximumFractionDigits: 1})}%
|
||||||
td #{datum.mandates}
|
td #{datum.mandates}
|
||||||
|
p Łącznie #{size} mandatów
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
div(class=(embed ? 'container embed' : 'container'))
|
main(class=(embed ? 'embed' : ''))
|
||||||
unless embed
|
unless embed
|
||||||
h1 Kalkulator mandatów w wyborach do Sejmu
|
h1 Kalkulator mandatów w wyborach do Sejmu
|
||||||
|
|
||||||
|
@ -12,8 +12,8 @@ div(class=(embed ? 'container embed' : 'container'))
|
||||||
wtedy poparcie wyższe/niższe niż w całym kraju, również w tej symulacji będzie miało w tym
|
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
|
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.
|
podziału mandatów na poziomie poszczególnych okręgów.
|
||||||
p Aktualizacje:
|
p.updates-texts Aktualizacje:
|
||||||
ol.updates
|
ol.updates.updates-texts
|
||||||
li.
|
li.
|
||||||
2019-11-15: od teraz w prognozie brane są pod uwagę wyniki wyborów do Sejmu z 2019 roku.
|
2019-11-15: od teraz w prognozie brane są pod uwagę wyniki wyborów do Sejmu z 2019 roku.
|
||||||
li.
|
li.
|
||||||
|
@ -37,6 +37,7 @@ div(class=(embed ? 'container embed' : 'container'))
|
||||||
unless embed
|
unless embed
|
||||||
#constituency-results
|
#constituency-results
|
||||||
|
|
||||||
footer
|
unless embed
|
||||||
a.github(href='https://github.com/drastus/sejm-calculator') Kod źródłowy
|
footer
|
||||||
address Kontakt: zrchos na serwerze gmail.com
|
a.github(href='https://github.com/drastus/sejm-calculator') Kod źródłowy
|
||||||
|
address Kontakt: zrchos na serwerze gmail.com
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
object(id="constituencies-map")
|
||||||
|
#constituency-result
|
||||||
|
p.info
|
||||||
|
em Kliknij okręg, by zobaczyć szczegółowe wyniki.
|
|
@ -27,6 +27,16 @@ export default {
|
||||||
exclude: /node_modules/,
|
exclude: /node_modules/,
|
||||||
use: '@webdiscus/pug-loader',
|
use: '@webdiscus/pug-loader',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
test: /\.svg$/,
|
||||||
|
type: 'asset/resource',
|
||||||
|
generator: {
|
||||||
|
filename: (name: {filename: string}) => {
|
||||||
|
const filePath = name.filename.split('/').slice(1, -1).join('/');
|
||||||
|
return `${filePath}/[name][ext]`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
test: /\.css$/,
|
test: /\.css$/,
|
||||||
exclude: /node_modules/,
|
exclude: /node_modules/,
|
||||||
|
@ -65,11 +75,7 @@ export default {
|
||||||
devServer: {
|
devServer: {
|
||||||
watchFiles: ['src/**/*'],
|
watchFiles: ['src/**/*'],
|
||||||
client: {
|
client: {
|
||||||
overlay: {
|
overlay: false,
|
||||||
warnings: false,
|
|
||||||
errors: true,
|
|
||||||
runtimeErrors: true,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
Ładowanie…
Reference in New Issue