Dynamische Balkengrafiken aus XML
Auto-Grafik
Einleitung
Dynamische Balkengrafiken aus XML
Designer und Entwickler profitieren gleichermaßen von XML, sofern sie gemeinsam zur Erkenntnis gelangen, dass sich strukturierte Datenhaltung und ansprechende Präsentation nicht ausschließen müssen. XML ist dabei das konzeptionelle Bindeglied. In einer XML-Teilstruktur könnte der Gewinn einer Firma bezogen auf einen konkreten Monat etwa so formuliert werden:
Der Inhalt des Elements gewinn ist der Zahlenwert 10000. Über die Attribute monat und waehrung erhält dieser Wert eine bestimmte Bedeutung. Mit etwas Übung kann ein Mensch durchaus auch eine Folge solcher Auszeichnungen verstehen. Zur Erfassung und Beurteilung der Gewinnverteilung über ein Jahr hinweg würde sich aber eine grafische Ansicht weitaus besser eignen. Für die Publikation im Web kommen prinzipiell Rasterformate wie GIF, JPEG und PNG in Betracht, während sich das SVG-Format (Scalable Vector Graphics) für die Ausgabe von Vektorgrafiken anbietet.
Von XML zum Bild
Dynamische Balkengrafiken aus XML
Das Ziel des Workshops ist die Visualisierung von in XML-Dokumenten abgelegten Daten. Bezogen auf das eingangs verwendete Beispiel wäre die Umsetzung der monatlichen Gewinne in ein Balkendiagramm sinnvoll. Balken sind Rechtecke, also beschreibt dies am einfachsten ein SVG-Konstrukt der folgenden Art
Der Wert 10000 EUR wird in die Rechteckbreite von 100 Pixeln übersetzt. Vor beziehungsweise nach dem Rechteck ist die Angabe des Monatsnamens und des Gewinns hilfreich.
Die konkreten x- und y-Koordinaten werden bei dieser Überlegung zunächst vernachlässigt.
Genauer betrachtet, findet eine Transformation aus einem XML-Dokumentenbaum (Element gewinn) in einen anderen (Element rect) statt. Für die technische Ausführung ist im XML-Portfolio XSLT vorgesehen. Es wird ein XSL-Stylesheet benötigt, das das Ausgangsdokument mit Hilfe eines XSLT-Prozessors in eine SVG-Repräsentation überführt.
Von SVG zur Rastergrafik
Dynamische Balkengrafiken aus XML
Würden alle Browser das erhaltene SVG-Dokument klaglos anzeigen, wären Sie an dieser Stelle bereits fertig. Mit Rastergrafiken kommen heutige Browser besser klar. Diese ließen sich aus dem Datenmaterial auch mit Server-seitiger Programmierung erzeugen – zum Beispiel über PHP mit der GD-Bibliothek.
Hier soll jedoch ein anderes Verfahren zur Anwendung kommen: Die bereits vorhandenen Vektorgrafiken werden mit einem so genannten Rasterizer in Pixelbilder konvertiert. Diese Vorgehensweise mag zwar umständlich erscheinen, bietet aber die Chance zur bedarfsorientierten Produktion von Vektor- und Rastergrafiken.
Von der Theorie zur Praxis
Dynamische Balkengrafiken aus XML
Ein Beispielprojekt soll den geschilderten Weg Schritt für Schritt nachvollziehbar machen. Für den XML-Datensatz kommt Material vom Statistischen Bundesamt Deutschland zu Fläche und Bevölkerung der 16 Bundesländer zum Einsatz, siehe www.destatis.de/jahrbuch/ jahrtab1.htm. Die Struktur des XML-Dokuments einwohner.xml basiert auf der Document-Type-Definition einwohner.dtd (siehe Kasten). Das Wurzelelement daten besitzt drei beschreibende Attribute, während die eigentlichen Informationen innerhalb der datensatz-Elemente mit den Kindelementen bundesland, einwohner und flaeche untergebracht sind:
Zum Erstellen solcher Dokumente bieten sich neben einfachen Text-Editoren spezialisierte Entwicklungsumgebungen wie Bonfire Studio an. Praktisch ist dabei die direkte Möglichkeit zur Validierung gegen die DTD. Ein neues Sternchen am XML-Himmel ist XML Starlet, das nur aus der Programmdatei xml.exe besteht und sich über Parameter gesteuert in einer DOS-Box ausführen lässt. Die Gültigkeit des XML-Codes kann durch den Aufruf
xml val -?d einwohner.dtd einwohner.xml
geprüft werden. Als Ergebnis sollte valid erscheinen.
XML+XSL=SVG
Dynamische Balkengrafiken aus XML
XML-Daten lassen sich nach HTML, XML oder in unformatierten Text transformieren. Einige relevante Codeausschnitte aus einwohner.xsl sollen das Prinzip einer Transformation nach SVG verdeutlichen. Zunächst das Grundgerüst:
Nach dem Wurzelelement xsl:stylesheet werden über xsl:output Angaben zum gewünschten Zielformat gemacht. Da SVG ein XML-Derivat ist, wird method=”xml” verwendet. Im fertigen Code sind weitere Optionen zu finden. Innerhalb der folgenden xsl:template-Vorlage wird der eigentliche SVG-Code, ausgehend vom Wurzelelement svg, erzeugt:
Der Titel wird bereits dynamisch aus dem XML-Dokument mittels xsl:value-of eingesetzt. Weitere statische Vorgaben im defs-Element beziehen sich auf die spätere Formatierung der Grafikobjekte.
Nun folgen die Überschrift und eine Legende:
Legende: [Einwohner gesamt | Einwohner pro km²]
Innerhalb eines xsl:for-each-Konstruktes werden die Balken als Rechtecke formuliert. Ihre Anordnung erfolgt horizontal an einer festen x-Position, während der vertikale y-Versatz über die aktuelle Positionsnummer der Datensätze berechnet wird:
[
Die Namen der Bundesländer erscheinen vor dem jeweiligen Balken. Danach werden die Einwohnerzahlen insgesamt beziehungsweise pro Quadratkilometer angeordnet. Letztere Zahl kommt durch eine im XSL-Code definierte Berechnung zu Stande:
round(einwohner div flaeche)
Dabei ersetzt der Operator div in XPath-Ausdrücken den sonst bei Divisionen üblichen Schrägstrich. Nach dem letzten Balken wird zusätzlich die Summe der Einwohnerzahlen als
sum(daten/datensatz/einwohner)
und deren Beziehung zur Gesamtfläche aller Bundesländer als
round(sum(daten/datensatz/einwohner) div sum(daten/datensatz/flaeche))
ermittelt und ausgegeben. Schließlich folgt noch der verlinkte Verweis auf die Datenquelle. Zur Transformation leistet wiederum XML-Starlet mit dem folgenden Einzeiler ganze Arbeit:
xml tr einwohner.xsl einwohner.xml > einwohner.svg
Grafikausgabe
Dynamische Balkengrafiken aus XML
Einem SVG-fähigen Browser kann man das erhaltene Ergebnis in dieser Form anbieten:
Dabei sollte als Ersatzinhalt ein Text-Link auf die Download-Seite eines Plug-ins angegeben werden. Alternativ kann auch eine Rastergrafik eingebunden werden. Das Batik-SVG-Toolkit enthält unter anderem einen Rasterizer, der aus SVG-Dokumenten wahlweise die Formate JPEG, PNG und TIFF sowie auch PDF erzeugen kann. Die Batik-Anwendungen wurden mit Java entwickelt und stehen als JAR-Module plattformübergreifend zur Verfügung. Ist eine Java-2-Laufzeitumgebung (JRE ab 1.3) vorhanden, lässt sich der Rasterizer direkt aufrufen und mit Parametern steuern. Die wichtigsten sind:
– m MIME-Type (image/jpeg, image/png, image/tif, application/pdf)
– dpi (Auflösung, zum Beispiel 72)
– q (Qualität für JPEG-Ausgabe, 0 bis 1)
– width und -height (Breite und Höhe).
Der Aufruf
java -jar batik-rasterizer.jar -m image/png einwohner.svg
erzeugt einwohner.png, während
java -jar batik-rasterizer.jar -m image/jpeg -q 0.9 einwohner.svg
die Ausgabe eines moderat komprimierten JPEG-Bildes bewirkt. Eine PDF-Datei wird durch
java -jar batik-rasterizer.jar -m application/pdf -dpi 72 -w 800 -h 600 einwohner.svg
erzeugt. Ohne Angaben zu Breite und Höhe werden die Dimensionen der Ausgangsgrafik verwendet. Die Dateiendung wird automatisch angepasst. Beim wiederholten Aufruf erweisen sich Batch-Dateien als praktisch. Beispiele finden Sie auf der Heft-CD.
Hinweis: Alle interaktiven Inhalte der Vektorgrafik wie Animationen und Skriptaufrufe gehen bei der ablaufenden Prozedur natürlich verloren.
Alles zusammen
Dynamische Balkengrafiken aus XML
Das bisher beschriebene Vorgehen erscheint eher für die gelegentliche Arbeit mit XML-Daten geeignet. Interessanter und praktikabler ist ein kompletter Workflow, der vorzugsweise auf dem Server stattfindet. Auf der Heft-CD befindet sich dazu die PHP-Anwendung xml2grafik.php, die sowohl die Transformation der Ausgangsdaten nach SVG als auch die Umwandlung in JPEG oder PNG demonstriert.
Zur Steuerung der Ausgabe lassen sich die beiden Parameter modus (Werte: raster/vektor) und format (Werte: jpg/png) an das Skript übergeben:
$modus=$_GET["modus"];
$format=$_GET["format"];
Die Ressourcen für Ein- und Ausgaben werden ebenfalls in Variablen abgelegt:
$xmlres="einwohner.xml";
$xslres="einwohner.xsl";
$svgres="einwohner.svg";
$imgres="einwohner.$format";
Der Kern der Anwendung ist die XSL-Transformation mittels Sablotron-Prozessor, der mittlerweile zur PHP-Standardinstallation gehören sollte:
$xsltref=xslt_create();
$xslt_result=xslt_process($xsltref,$xmlres,$xslres,$svgres);
xslt_free($xsltref);
Die Variable $xslt_result besitzt nach erfolgreicher Verarbeitung den Wert 1 (true). Anschließend wird die oben praktizierte Umwandlung von einwohner.svg in eine Rastergrafik über einen externen Funktionsaufruf angestoßen. Voraussetzung ist wiederum eine (auf dem Server) installierte Java-Umgebung:
$cmd="$java $para $svgres";
$out=exec($cmd);
if(strstr($out,"success"))
$batik_result=true;
Über die Variable $cmd und weitere Hilfsvariablen wird der Aufruf des Rasterizers mit den entsprechenden Parametern initialisiert. Die von der Kommandozeile bekannte success-Meldung wird über $out ausgewertet.
Liegen schließlich Vektor- und Rastergrafik vor, erfolgt je nach Wahl der Startparameter die – gegebenenfalls verschachtelte – Ausgabe der Bilder in HTML über object- und img-Elemente. Im PHP-Code selbst und in der Datei readme.txt sind weitere Kommentare enthalten. Unter der Adresse ktd.et.fh-merseburg.de/ ~tm/xml2grafik steht die Anwendung zum Testen zur Verfügung.
Fazit
Dynamische Balkengrafiken aus XML
XML-Daten können direkt in SVG umgesetzt werden. Das Problem der noch unzureichenden Browser-Unterstützung lässt sich zumindest ansatzweise durch die Umwandlung in Rastergrafiken kompensieren. SVG kann somit auch als Zwischenformat nützlich sein.
DTD zum Beispiel
Dynamische Balkengrafiken aus XML
In der Document Type Definition einwohner.dtd werden die zum Aufbau der Datensätze verwendeten Elemente und Attribute definiert.
Außerdem wird der Inhalt der Datensätze bestimmt sowie Reihenfolge und Verschachtelung der Elemente festgelegt.
Gegen diese DTD kann ein entsprechendes XML-Dokument auf Gültigkeit überprüft werden (im Beispiel einwohner.xml).