Big commit

parent b33f8dfd
......@@ -280,3 +280,4 @@ modules.xml
!index.html
!webpack.*.js
!postcss.config.js
<html>
<head>
<link rel="stylesheet" type="text/css" href="./styles.css"/>
<title>Votemanager Results</title>
</head>
<body>
......@@ -24,9 +25,27 @@
<h2>Bezirke</h2>
<section id="districtsSection">
<section id="districtsSection" class="container">
</section>
<!--
<h2>Karte</h2>
<div id="mapid" style="height: 50em;"></div>
-->
<h2>Ranglisten</h2>
<label for="partyDropdown">Partei auswählen:</label>
<br/>
<select id="partyDropdown">
<option value="" disabled selected>Bitte auswählen</option>
</select>
<!-- Parties in Squares -->
<!-- Rank per District -->
<!-- Rank by Votes in Percent -->
<!-- Rank per Municipality -->
<!-- Rank by Votes in Percent -->
</section>
</body>
......
This diff is collapsed.
......@@ -76,7 +76,7 @@
},
"D16": {
"title": "Bayernpartei",
"short": "Bayernpartei",
"short": "BP",
"color": "#4d76aa"
},
"D17": {
......
.container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
.item {
width: 15rem;
}
}
@import "main/flexbox";
import L = require("leaflet/dist/leaflet.js");
import {Map, Polygon, Polyline} from "leaflet";
export class DistrictsMap {
private streetGeoCords: any[] = [];
private globalMap: L.Map;
constructor() {
const achimStreets: streetObject[] = require("../json/streets/europeanParliament/2019/achim.json");
const mymap: Map = new Map('mapid').setView([51.505, -0.09], 13);
L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=sk.eyJ1Ijoid2luc2NodSIsImEiOiJjanlxOGM5OHAwcWQzM2ZtbWFtYnRwd2lhIn0.xlezMvNoYTIEe7_qkrpbzA',
{
attribution: 'DistrictsMap data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
maxZoom: 18,
id: 'mapbox.light',
accessToken: 'sk.eyJ1Ijoid2luc2NodSIsImEiOiJjanlxOGM5OHAwcWQzM2ZtbWFtYnRwd2lhIn0.xlezMvNoYTIEe7_qkrpbzA'
}
).addTo(mymap);
this.globalMap = mymap;
console.log("Achim => ", achimStreets);
console.time("Streets");
this.drawStreets(this, achimStreets);
console.timeEnd("Streets");
}
public drawStreets(self, streets) {
this.getGeoCoordsForStreet(self, streets).then((streetCoords: NominatimPlaceType[]): void => {
const coords = [];
console.log("Result => ", streetCoords);
console.log("Length => ", streetCoords.length);
for (let i = 0; i < streetCoords.length; i++) {
let street = streetCoords[i];
if (street[0].address.town === "Achim") {
coords.push([street[0].lat, street[0].lon]);
}
else {
console.log("Other Street => ", street);
for(let i = 0; i < (street as unknown as NominatimPlaceType[]).length; i++) {
const halfStreet = street[i];
console.log("Half Street => ", halfStreet);
if(halfStreet.address.town === "Achim") {
coords.push([halfStreet.lat, halfStreet.lon]);
}
}
}
}
console.log("Final Coords => ", coords);
coords.push(coords[0]);
drawPolygon(coords);
function drawPolygon(coords) {
var polygon = L.polygon(coords, {color: 'red'});
polygon.addTo(self.globalMap);
self.globalMap.fitBounds(polygon.getBounds());
}
});
}
public async getGeoCoordsForStreet(self: DistrictsMap, streets: streetObject[]): Promise<any[]> {
console.log("Start searching!");
return await getGeoCordsForStreetAsync();
async function getGeoCordsForStreetAsync(): Promise<any[]> {
const streetGeoCords = [];
for (let i = 0; i < streets.length; i++) {
if (streets[i].Bezirk === 4) {
streetGeoCords.push(await getStreetCoords(streets[i]));
}
}
console.log("Found Coords => ", streetGeoCords);
return streetGeoCords;
}
async function getStreetCoords(street: streetObject) {
return new Promise((resolve, reject) => {
const req: XMLHttpRequest = new XMLHttpRequest();
req.open("GET", `https://nominatim.openstreetmap.org/search?q=${street.Name},achim&format=json&polygon=1&addressdetails=1`, true);
req.onload = function (): void {
if (this.readyState == 4 && this.status == 200) {
const coords = JSON.parse(this.responseText);
return resolve(coords);
}
// Handle network errors
req.onerror = (): void => console.error(Error("Network Error"));
};
req.send();
});
}
}
}
......@@ -3,7 +3,6 @@ import {Chart} from "chart.js";
import {DistrictResultsPie} from "./objects";
import {cleanUpDistricts, combineMailResults} from "./initHelpers";
export class init {
private infosObject: infoObject;
......@@ -95,7 +94,7 @@ export class init {
//combineMailDistricts
const combinedMailTuple = combineMailResults(csvResults);
for(let i = 0; i < combinedMailTuple[0]; i++) {
for (let i = 0; i < combinedMailTuple[0]; i++) {
csvResults.pop();
}
......@@ -108,11 +107,10 @@ export class init {
csvResults.forEach((entry: string[]): void => {
const entryObject = entry;
const districtHeading = document.createElement("h3");
districtHeading.innerText = entryObject["name"];
const container: HTMLDivElement = document.createElement("div");
container.classList.add("item");
document.getElementById("districtsSection").appendChild(districtHeading);
container.appendChild(createHeading(entryObject["name"]));
const validVotes = document.createElement("p");
const invalidVotes = document.createElement("p");
......@@ -127,26 +125,49 @@ export class init {
invalidVotes.innerText = `Ungültige Stimmen: ${invalidVotesCount} (${invalidVotesPercent}%)`;
const voterPercentageText = document.createElement("p");
const partiesList: any = JSON.parse(self.partiesObject as unknown as string);
container.appendChild(validVotes);
container.appendChild(invalidVotes);
//Voter Percentage
if (entryObject["A"] !== undefined) {
const voterPercentageText = document.createElement("p");
const totalVoters: number = parseInt(entryObject["A"]);
const totalVoters: number = parseInt(entryObject["A"]);
const voterPercentage: number = (totalVotesCount / totalVoters) * 100;
const voterPercentage: number = (totalVotesCount / totalVoters) * 100;
voterPercentageText.innerHTML = `
voterPercentageText.innerHTML = `
Wahlbeteiligung: ${voterPercentage}%
<br/> (Wahlberechtigte: ${totalVoters})
`;
const partiesList: any = JSON.parse(self.partiesObject as unknown as string);
document.getElementById("districtsSection").appendChild(validVotes);
document.getElementById("districtsSection").appendChild(invalidVotes);
document.getElementById("districtsSection").appendChild(voterPercentageText);
container.appendChild(voterPercentageText);
}
const fwVoters = document.createElement("p");
new DistrictResultsPie(entryObject, partiesList);
fwVoters.innerText = "FREIE WÄHLER Stimmen: " + entryObject["D12"];
container.appendChild(fwVoters);
const pie: DistrictResultsPie = new DistrictResultsPie(entryObject, partiesList);
container.appendChild(pie.Canvas);
pie.setOptions(pie.Canvas.getContext("2d"));
document.getElementById("districtsSection").appendChild(container);
entryList.push(entryObject);
});
function createHeading(title: string): HTMLHeadingElement {
const districtHeading = document.createElement("h3");
districtHeading.innerText = title;
return districtHeading;
}
}
});
......
......@@ -2,19 +2,28 @@ import chartjs = require('chart.js');
export class DistrictResultsPie {
private pieLables: string[] = [];
private pieLabels: string[] = [];
private pieColors: string[] = [];
private pieValues: number[] = [];
private entryObject: object = {};
private canvas: HTMLCanvasElement;
constructor(entryObject: object, parties: partyObject[]) {
this.initLabelsAndColors(parties);
this.initValues(entryObject);
this.createChart(entryObject["nr"]);
this.entryObject = entryObject;
}
public get Canvas(): HTMLCanvasElement {
return this.canvas;
}
public initLabelsAndColors(list: partyObject[]): void {
Object.values(list).forEach((value: partyObject): void => {
this.pieLables.push(value.short);
this.pieLabels.push(value.short);
if(value.color !== undefined) {
this.pieColors.push(value.color);
}
......@@ -25,31 +34,42 @@ export class DistrictResultsPie {
}
public initValues(entryObject: object): void {
Object.keys(entryObject).forEach((key: string, index: number): void => {
if(index !== 0 && key.includes("D")) {
Object.keys(entryObject).forEach((key: string): void => {
if( key.match(/^D*[0-9]*[0-9]$/g)) {
console.log("Key => ", key);
this.pieValues.push(parseInt(entryObject[key]));
}
});
}
public createChart(nr: number) {
public createChart(nr: number): void {
const voterPercentageChart: HTMLCanvasElement = document.createElement("canvas") as HTMLCanvasElement;
voterPercentageChart.id = `voterPercentageChart${nr}`;
document.getElementById("districtsSection").appendChild(voterPercentageChart);
this.canvas = voterPercentageChart;
}
new chartjs.Chart(voterPercentageChart.getContext('2d'), {
public setOptions(chartCtx: CanvasRenderingContext2D) {
new chartjs.Chart(chartCtx, {
type: 'pie',
data: {
labels: this.pieLables,
labels: this.pieLabels,
datasets: [{
label: '# of Votes',
data: this.pieValues,
backgroundColor: this.pieColors,
borderColor: "white",
borderWidth: 1
}]
}],
},
options: {
responsiveAnimationDuration: 5,
legend: {
display: false,
labels: {
usePointStyle: true
}
}
}
});
}
......
type infoObject = {A1: string, A2: string, A3: string, A: string, B: string, B1: string, C: string, D: string};
type partyObject = {title: string, short: string, color: string};
type streetObject = {Name: string, Nummer: string, PLZ: string, Ortsteil: string, Bezirk: number};
interface NominatimPlaceType {
address: {
country: string,
country_code: string,
county: string,
postcode: string,
road: string,
state: string,
town: string
}
boundingBox: string[],
class: string,
display_name: string,
importance: number,
lat: string,
licence: string,
lon: string,
osm_id: string,
osm_type: string,
place_id: number,
polygonpoints: string[][2],
type: string
}
......@@ -3,7 +3,13 @@
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"sourceMap": true
"sourceMap": true,
"lib": [
"dom",
"es5",
"scripthost",
"es2015.promise"
]
},
"exclude": [
"node_modules"
......
......@@ -5,7 +5,7 @@ const HtmlWebpackPlugin = require("html-webpack-plugin");
const CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = {
entry: ["./ts/index.ts"],
entry: ["./ts/index.ts", "./sass/styles.scss"],
module: {
rules: [
{
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment