Ziel der Übung: Eine automatisch erzeugte Karte der Schweiz, die in Echtzeit die Ergebnisse von Abstimmungen zeigt, wobei die Kantone ihrem Entscheid entsprechend eingefärbt werden. Die Abstimmungsresultate werden auf admin.ch publiziert, das von mir verwendete Beispiel hier. Diese Daten habe ich mit Scraperwiki eingelesen. Der Python-Quellcode lautet:
#!/usr/bin/env python
import scraperwiki import requests import lxml.html
html = requests.get("http://www.admin.ch/ch/d/pore/va/20130922/det572.html").content
dom = lxml.html.fromstring(html)
i = 1 for entry in dom.cssselect('table tr'): if i > 1: if i < 28: post = { 'kanton': entry.cssselect('td')[0].text_content(), 'ja': entry.cssselect('td')[1].text_content().replace("`",""), } print post scraperwiki.sqlite.save(unique_keys=['kanton'], data=post) i = i+1
Seit einem Relaunch bietet Scraperwiki einen automatisierten Export der Daten im JSON-Format an. Die Funktion versteckt sich unter dem Menupunkt „Query with SQL“ . Die von mir erzeugte Datendatei enthält zwei Felder: Kanton und Ja-Stimmen-Anteil und ist hier zu finden. Die SQL-Abfrage dazu lautet:
select ja, kanton from swdata order by kanton limit 30
Für die Schweizerkarte im SVG-Format habe ich mich bei Wikimedia bedient. In einem Text-Editor habe ich die Farben entfernt und die IDs der einzelnen Kantone angepasst sowie die einzelnen Text- und Pathelemente in die gleiche Reihenfolge wie beim obengenannten JSON-File gebracht. Die so bearbeitete Version gibt’s hier.
Die Script habe ich mit der Java-Script Library D3 geschrieben. Ein sehr gutes, 20-teiliges Videotutorial zu D3 bietet youtube-user d3Vienno.
Der D3-Code ist extrem dicht und kurz:
d3.json('https://premium.scraperwiki.com/dexzd4i/5f6e1b937dbd42e/sql/?q=select%20%0A%09ja%2C%0A%09kanton%0Afrom%20swdata%0Aorder%20by%20kanton%0Alimit%2030%0A', function(data){ var color = d3.scale.linear() .domain([20, 49.99, 50, 80]) .range(["#143d00", "#cde6c1", "#ffcece", "#660000"]); d3.selectAll("path") .data(data) .attr("fill", function(d){ return color(d.ja)});
d3.selectAll("text") .data(data) .text(function(d){ return d.ja}); });
Zunächst wird das JSON-File importiert und als data-Array an eine Funktion weitergegeben. Dann wird eine Variabel „color“ definiert. Die Domain-Werte sind prozentuale Stimmanteile, es sind vier Werte, damit zwischen 49% und 51% auf der Karte klar zwischen hellrot und hellgrün unterscheidet werden kann. Die Range-Angaben sind die entsprechenden Farbcodes, wobei D3 den genauen Farbverlauf mittels der scale-Funktion automatisch regelt.
Dann folgen zwei Befehle, zunächst für die Kantonsflächen / Farbgebung, dann für die Angabe der Ja-Stimmen in Prozent. Der Quellcode des Scripts ist zu finden unter: http://jsfiddle.net/shufschmid/z28SL/3/