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',
|
||||
'\\.(pug)$': 'jest-transform-pug',
|
||||
'.+\\.(css)$': 'jest-transform-stub',
|
||||
'^.+\\.svg$': 'jest-transform-stub',
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import {BarChart, PieChart, Svg} from 'chartist';
|
||||
import {benchSort, committees, constituencies} from './data';
|
||||
import calculateMandates from './mandates';
|
||||
import constituencyResultsTemplate from './templates/cresults.pug';
|
||||
import constituencyTemplate from './templates/constituency.pug';
|
||||
import tableTemplate from './templates/table.pug';
|
||||
import constituenciesMap from './images/c41.svg';
|
||||
import './styles/styles.css';
|
||||
|
||||
const {location} = window;
|
||||
|
@ -33,7 +35,7 @@ export const clearResults = (): void => {
|
|||
document.getElementById('support-bar-chart')!.innerHTML = '';
|
||||
document.getElementById('division-pie-chart')!.innerHTML = '';
|
||||
const constituencyResultContainer = document.getElementById('constituency-results');
|
||||
if (constituencyResultContainer) constituencyResultContainer.innerHTML = '';
|
||||
if (constituencyResultContainer) constituencyResultContainer.innerHTML = constituencyResultsTemplate();
|
||||
if (location.search) {
|
||||
const urlWithoutSearchString = location.href.split('?')[0];
|
||||
window.history.pushState('', '', urlWithoutSearchString);
|
||||
|
@ -126,21 +128,57 @@ const displayPieChart = (mandates: number[]) => {
|
|||
const displayConstituencyResults = () => {
|
||||
const container = document.getElementById('constituency-results');
|
||||
if (container) {
|
||||
constituencies.forEach((constituency, constituenyIndex) => {
|
||||
const data = (constituency.mandates && constituency.support)
|
||||
? constituency.mandates.map((mandates, committeeIndex) => ({
|
||||
committee: committees[committeeIndex].name,
|
||||
support: (constituency.support as number[])[committeeIndex],
|
||||
mandates,
|
||||
}))
|
||||
: [];
|
||||
data.sort((a, b) => b.support - a.support);
|
||||
container.insertAdjacentHTML('beforeend', constituencyTemplate({
|
||||
number: constituenyIndex + 1,
|
||||
name: constituency.name,
|
||||
size: constituency.size,
|
||||
data,
|
||||
}));
|
||||
container.innerHTML = constituencyResultsTemplate();
|
||||
const constituencyResult = document.getElementById('constituency-result')!;
|
||||
|
||||
const mapObject = document.getElementById('constituencies-map')! as HTMLObjectElement;
|
||||
mapObject.setAttribute('data', constituenciesMap);
|
||||
mapObject.addEventListener('load', () => {
|
||||
const svgDocument = mapObject.contentDocument!;
|
||||
const constituencyNumber = svgDocument.getElementById('constituency-number')!;
|
||||
const constituencyName = svgDocument.getElementById('constituency-name')!;
|
||||
const paths = svgDocument.querySelectorAll<SVGPathElement>('svg path');
|
||||
paths.forEach((path) => {
|
||||
const cid = parseInt(path.dataset.cid!, 10);
|
||||
const constituency = constituencies[cid - 1];
|
||||
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;
|
||||
}
|
||||
|
||||
.container {
|
||||
main,
|
||||
footer {
|
||||
width: 100%;
|
||||
max-width: 58rem;
|
||||
margin: 1rem auto;
|
||||
|
@ -21,6 +22,10 @@ body {
|
|||
padding: 0.25rem auto 1rem;
|
||||
}
|
||||
|
||||
.updates-texts {
|
||||
font-size: 13.5px;
|
||||
}
|
||||
|
||||
.updates {
|
||||
margin-top: -10px;
|
||||
list-style-type: none;
|
||||
|
@ -44,6 +49,8 @@ li {
|
|||
display: flex;
|
||||
height: auto;
|
||||
margin-bottom: 1rem;
|
||||
z-index: -1;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.ct-chart:empty {
|
||||
|
@ -90,40 +97,48 @@ h2 {
|
|||
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-result {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
#constituency-result .info {
|
||||
margin-top: 32px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#constituencies-map {
|
||||
flex: 1;
|
||||
max-width: min(438px, 90vw);
|
||||
}
|
||||
|
||||
.constituency {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
max-width: 26rem;
|
||||
margin: 0.5rem 0;
|
||||
max-width: 25rem;
|
||||
margin: 0.5rem auto;
|
||||
padding: 0.5rem 1rem;
|
||||
border: 1px solid grey;
|
||||
}
|
||||
|
||||
.constituency-data {
|
||||
width: 11rem;
|
||||
}
|
||||
|
||||
.constituency table {
|
||||
margin-left: 1rem;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.constituency p,
|
||||
.constituency th,
|
||||
.constituency td {
|
||||
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 {
|
||||
width: 2rem;
|
||||
padding-left: 1rem;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
|
@ -149,36 +164,55 @@ h2 {
|
|||
height: 2rem;
|
||||
}
|
||||
|
||||
#support-form table td:nth-child(2) {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#support-form table td:last-child {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
:root {
|
||||
--pis: #31469b;
|
||||
--ko: #fca43f;
|
||||
--lewica: #d44;
|
||||
--td: #8bd32e;
|
||||
--konfederacja: #655;
|
||||
--mn: #aaa;
|
||||
}
|
||||
|
||||
.pis {
|
||||
stroke: #263778;
|
||||
stroke: var(--pis);
|
||||
fill: var(--pis);
|
||||
}
|
||||
|
||||
.ko {
|
||||
stroke: #fca43f;
|
||||
stroke: var(--ko);
|
||||
fill: var(--ko);
|
||||
}
|
||||
|
||||
.lewica {
|
||||
stroke: #d44;
|
||||
stroke: var(--lewica);
|
||||
fill: var(--lewica);
|
||||
}
|
||||
|
||||
.td {
|
||||
stroke: #8bd32e;
|
||||
stroke: var(--td);
|
||||
fill: var(--td);
|
||||
}
|
||||
|
||||
.konfederacja {
|
||||
stroke: #655;
|
||||
stroke: var(--konfederacja);
|
||||
fill: var(--konfederacja);
|
||||
}
|
||||
|
||||
.mn {
|
||||
stroke: #aaa;
|
||||
stroke: var(--mn);
|
||||
fill: var(--mn);
|
||||
}
|
||||
|
||||
.bright30 {
|
||||
filter: brightness(125%);
|
||||
}
|
||||
|
||||
.bright50 {
|
||||
filter: brightness(75%);
|
||||
}
|
||||
|
||||
.bar-value {
|
||||
|
@ -189,7 +223,7 @@ footer {
|
|||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
margin: 0.5rem 1rem;
|
||||
padding: 1rem 1.5rem;
|
||||
}
|
||||
|
||||
address {
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
declare module '*.svg' {
|
||||
const content: string;
|
||||
export default content;
|
||||
}
|
|
@ -1,10 +1,14 @@
|
|||
.constituency
|
||||
.constituency-data
|
||||
h2 Okręg #{number} #{name}
|
||||
p Łącznie #{size} mandatów
|
||||
h2 Okręg #{number} #{name}
|
||||
table
|
||||
tr
|
||||
th Komitet
|
||||
th Poparcie
|
||||
th Mandaty
|
||||
each datum in data
|
||||
tr
|
||||
td #{datum.committee}
|
||||
td #{datum.committee.name}
|
||||
td #{datum.support.toLocaleString('pl', {minimumFractionDigits: 1, maximumFractionDigits: 1})}%
|
||||
td #{datum.mandates}
|
||||
p Łącznie #{size} mandatów
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
div(class=(embed ? 'container embed' : 'container'))
|
||||
main(class=(embed ? 'embed' : ''))
|
||||
unless embed
|
||||
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
|
||||
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 Aktualizacje:
|
||||
ol.updates
|
||||
p.updates-texts Aktualizacje:
|
||||
ol.updates.updates-texts
|
||||
li.
|
||||
2019-11-15: od teraz w prognozie brane są pod uwagę wyniki wyborów do Sejmu z 2019 roku.
|
||||
li.
|
||||
|
@ -37,6 +37,7 @@ div(class=(embed ? 'container embed' : 'container'))
|
|||
unless embed
|
||||
#constituency-results
|
||||
|
||||
footer
|
||||
a.github(href='https://github.com/drastus/sejm-calculator') Kod źródłowy
|
||||
address Kontakt: zrchos na serwerze gmail.com
|
||||
unless embed
|
||||
footer
|
||||
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/,
|
||||
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$/,
|
||||
exclude: /node_modules/,
|
||||
|
@ -65,11 +75,7 @@ export default {
|
|||
devServer: {
|
||||
watchFiles: ['src/**/*'],
|
||||
client: {
|
||||
overlay: {
|
||||
warnings: false,
|
||||
errors: true,
|
||||
runtimeErrors: true,
|
||||
},
|
||||
overlay: false,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
Ładowanie…
Reference in New Issue