JSON-Schnittstelle zu Infogr.am

Seit wir regelmässig das Basler Kantonsparlament mit einem Live-Ticker begleiten, stellte ich mir die Frage: Wie lassen sich Abstimmungsresultate schnell, detailliert, schön und kompatibel für alle bz-Plattformen darstellen. Die Lösung: Die in Echtzeit als PDF (!) publizierten Resultate werden durch meinen bereits geschriebenen Scraper eingelesen, ausgewertet und als speziell formatiertes JSON ausgegeben, exakt so, wie es vom Drittanbieter infogr.am vorgegeben wird. Die infogram-Grafik wiederum kann dann mittels embed in alle bz-Angebote eingebunden werden.

Was einfach klingt (und nun auch funtioniert), war ein Weg mit vielen Stolpersteinen. Das Einlesen und Auswerten der PDFs habe ich ja bereits an anderer Stelle beschrieben. Die Vorgabe für den JSON-Import bei infogr.am entspricht a) eigentlich diesem Beispiel:

[[["Index of Happiness","09:00","10:00","11:00","12:00","13:00"],["Eden",762,240,929,963,596],["Shambhala",550,118,976,762,738],["Avalon",952,886,234,794,227],["Camelot",197,452,687,876,952],["El Dorado",156,267,294,354,560],["Atlantis",500,924,954,138,585]]]

und b) eben nicht, zumindest dann nicht, wenn eine Tabelle über mehrere Blätter verfügen soll. Dann muss das ganze folgendermassen formatiert werden (die Logik erschliesst sich mir nicht, aber es funktioniert):

[[["Fraktionen","SP","LDP","SVP","GB","FDP","CVP/EVP","fraktionslos"],["Ja","15","6","11","4","4","3","2"],["Nein","13","1","1","7","2","",""],["Total","35","15","15","13","11","8","3"]],[["Politiker","Fraktion","Stimme"],["Semseddin Yilmaz","SP","J"],["Franziska Roth","SP","N"],["Sasha Mazzotti","SP","N"],["Andreas Zappalà","FDP","J"],["Annemarie Pfeifer","CVP/EVP","A"],["Thomas Grossenbacher","GB","N"],["Christian Griss","CVP/EVP","A"],["Katja Christ","fraktionslos","J"],["Olivier Battaglia","LDP","E"]]]

Entscheidend sind die zweifachen eckigen Klammern (rot), um die beiden Tabellen-Blätter voneinander zu trennen.

Weil es sich nicht um echtes JSON handelt, musste ich die Ausgabe manuell erstellen. Der Quellcode (gekürzt) dazu:

$geschaeft = auswerten($eintrag);
 if($_GET["ausgabe"] == "json"){
 //$geschaeftdetails["parteien"][$partei][$resultat]++;
 echo "[[[\"Fraktionen\"";
 foreach($geschaeft["parteien"] as $partei=>$resultat){
 echo ",\"".$partei."\"";
 }
 echo "],";
 
 echo "[\"Ja\"";
 foreach($geschaeft["parteien"] as $partei=>$resultat){
 echo ",\"".$resultat["J"]."\"";
 }
 echo "],";
 
 echo "[\"Total\"";
 foreach($geschaeft["parteien"] as $partei=>$resultat){
 echo ",\"";echo $resultat["N"]+$resultat["J"]+$resultat["E"]+$resultat["P"]+$resultat["A"];
 echo "\"";
 }
 echo "]],";
 //$geschaeftdetails["parteien"][$partei][$resultat]++;
 echo "[[\"Politiker\",\"Fraktion\",\"Stimme\"]";
 foreach($geschaeft["politiker"] as $name=>$detail){
 echo ",[\"".$name."\",\"".$detail["partei"]."\",\"".$detail["resultat"]."\"]";
 }
 echo "]]";
}

Aufgerufen wird der gewünschte JSON-Feed via URL-Parameter:

http://samuelhufschmid.ch/grossratssitzung/?action=einzeln&source=web&ausgabe=json&url=http://abstimmungen.grosserrat-basel.ch/aktuell/Abst_0614_20180919_223358_0025_0000_ab.pdf

Der zuständige Online-Redaktor am Grossrats-Ticker muss also künftig „nur“ noch die PDF-URL der gewünschten Abstimmung von der Grossrats-Seite (hier) kopieren und damit den roten Teil der obenstehenden URL ersetzen. Diese neue URL ergibt dann die von Infogram verlangte JSON-Formatierung und kann in ein vorgefertigtes Diagramm importiert werden. Das Ergebnis lässt sich, so finde ich, sehen und verfügt über alle interessanten Details, etwa das (sortierbare) Stimmverhalten aller Ratsmitglieder oder die Abwesenden.

Autor: Samuel Hufschmid

Jounalist bei bz Basel, Papi, Organisator Swiss Kubb Open, mit Interesse an Datenjournalismus.

Kommentar verfassen