Schlagwort-Archive: Browser

Highcharts und PrinceXML

Hintergrund

Mein Arbeitgeber lebt zu 90% von unterschiedlichsten Berichten. Diese werden bis dato in Word geschrieben, ggf. mit Seriendruckfeldern aufgefüllt und separat Diagramme in Excel erstellt. Fast alle Kollegen sind tagelang damit beschäftigt, Berichte zu erstellen, zu formatieren und zu kontrollieren. Gerade bei größeren Berichten ist die Arbeit stupide, denn Werte werden kopiert, Diagramme erstellt, Diagramme im Bericht eingefügt, ggf. wird festgestellt, dass beim Kopieren ein Fehler unterlaufen ist und der Spaß beginnt von vorne.

Beim aktuellen Bericht sollten Standortprofile für die einzelnen Bezirke einer Stadt erstellt werden: pro Bezirk sollen zwei Seiten mit Tabellen, Kommentaren und 16 Diagrammen erstellt werden. Bei 81 Bezirken müssen also knapp 1.300 Diagramme erstellt werden. Das händische Erstellen der Diagramme per MS Office hätte bestimmt Wochen beansprucht. Die automatische Berichtsgenerierung mit PHP, MySQL, Highcharts, Javascript, Ajax und PrinceXML dauert jetzt 7 Minuten.

Technische Herausforderungen

PrinceXML nimmt ein HTML-Dokument und erstellt daraus ein druckbares PDF. Mit PrinceXML kann man über HTML und CSS Seitenumbrüche, Seitenzahlen, Seitenabstände, Fußnoten, Inhaltsverzeichnisse und andere druckrelevante Features steuern. So wird bspw. aus dieser HTML-Seite diese PDF-Datei.

Eine weitere Herausforderung ist die Verwendung von Highcharts mit PrinceXML. Warum? Highcharts wird per Javascript im Browser des Besuchers gerendert. PrinceXML kann zwar auch Javascript interpretieren, aber für Highcharts reicht die Unterstützung bislang nicht aus (erst in Version 8.2 soll Highcharts unterstützt werden). Es gibt verschiedene Ansätze dieses Problem zu lösen, denn HighCharts erzeugt eine SVG, welche durch PrinceXML problemlos dargestellt werden kann: Serverseitiges Ausführen von Highcharts mit Node.JS oder PhantomJS oder indem man CutyCapt als serverseitigen Browser verwendet, der das erzeugte SVG dann an das Skript zur weiteren Verarbeitung übergibt. Mich überzeugte keines der Ansätze, denn

  1. es ist zusätzliche Software notwendig, in dessen Abhängigkeit man sich begibt
  2. in meinem Anwendungsfall ist es problemlos möglich den Bericht im Browser anzeigen zu lassen, dort die Diagramme generieren zu lassen und die SVG-Daten in einer Datenbank zu speichern, um sie später im Bericht für PrinceXML zu verwenden.

Aufbau

Aufbau: Highcharts und PrinceXML

Die einzelnen Schritte sind:

  1. Rufe alle Daten zur Erstellung der Diagramme des Berichts ab
  2. Erstelle eine Berichtsversion, in der Highcharts über Javascript generiert wird
  3. Im Bericht werden nach Erstellung der Diagramme die SVG-Daten per Ajax abgesetzt
  4. und durch die svgsaver.php-Datei in der Datenbank gespeichert
  5. Zur Erstellung des Berichts mit den SVG-Daten, werden diese von der DB abgefragt
  6. Die SVG-Berichtsversion enthält kein Javascript und kein Highcharts-Code mehr, sondern nur noch die SVG-Daten
  7. Die SVG-Berichtsversion wird von PrinceXML zur…
  8. … Erstellung des PDFs verwendet

svgsaver.php

Der SVG-Saver sichert lediglich die per Ajax erhaltenen Daten mit folgenden Feldern: berichts_id, container (Name des Highchartscontainers), svg (die eigentlichen SVG-Daten) und eingefuegt.

[code lang=’php‘]
$stmt = $mysqli->prepare(„INSERT INTO highcharts_svg SET berichts_id=?, container=?, svg=?, eingefuegt=NOW()“);
if (isset($_POST[„berichts_id“]) AND isset($_POST[„container“]) AND isset($_POST[„svg“])){
$berichts_id = intval($_POST[„berichts_id“]);
$svg = $_POST[„svg“];

$stmt->bind_param(‚iss‘, $berichts_id, $_POST[„container“], $svg);
$stmt->execute();
}

$stmt->close();[/code]

bericht.php

Die bericht.php muss je nachdem welche Berichtsversion angezeigt werden soll, einen Platzhalter (div-Container) für das Highcharts-Diagramm anzeigen oder die SVG-Daten aus der Datenbank. Das übernimmt die Funktion container, die dies abhängig von der Variable $show_svg realisiert:
[code lang=’php‘]function container($name, $height=270, $width=470){
global $show_svg, $berichts_id, $mysqli;
if ($show_svg){
$stmt = $mysqli->prepare(„SELECT svg FROM highcharts_svg WHERE berichts_id=? AND container=? ORDER BY eingefuegt DESC LIMIT 1“);
$stmt->bind_param(‚is‘, $berichts_id, $name);
$stmt->execute();
$stmt->bind_result($svg);
$stmt->fetch();
echo $svg;

} else {
echo ‚

‚;
}
}[/code]

Im Headbereich der HTML-Seite wird über folgenden JS-Code das SVG der generierten Diagramme per Ajax an die vorher beschriebene svgsaver.php gesendet:
[code lang=’js‘]$(window).load(function() {
for (var i = 0; i < charts.length; ++i){ $.ajax({ type: 'POST', url: 'http://yourdomain.com/svgsaver.php', data: { berichts_id: 1, container: charts[i].options.chart.renderTo, svg: charts[i].getSVG() }, statusCode: { 404: function() { alert("Highcharts-Diagramme konnten in der Datenbank nicht gespeichert werden."); } } }); } });[/code] Alle Highcharts-Diagramme müssen folglich in dem Array charts enthalten sein, weswegen das Highcharts.Chart-Objekt in dem charts-Array gespeichert wird:
[code lang=’js‘]var charts = Array();
$(function () {
$(document).ready(function() {
var i = 0;
charts[i++] = new Highcharts.Chart({
chart: {
renderTo: ‚container_1‘,
type: ‚line‘,
…[/code]

Das sollte bei der Lösung der größten Hürden helfen, denn noch detaillierter möchte ich hier nicht werden.

Nachteile

Dieser Lösungsansatz zur Verwendung von Highcharts mit PrinceXML ist sicherlich nicht der Weisheit letzter Schluss:

  1. Es sind immer zwei Schritte nötig, um das PDF zu erzeugen: 1. Aufrufen der Highcharts-Berichtsversion, um die SVG zu erzeugen und 2. PrinceXML mit der SVG-Version aufrufen.
  2. Die Diagramme werden im Browser und nicht auf dem Server generiert. Bei sehr vielen Diagrammen wird der Client daher stark belastet. (Für die Generierung der 1.300 Diagramme braucht der Browser auf unseren Workstations ~ 7 Minuten).

aber es funktioniert! Und wie sagte George S. Patton?

Ein guter Plan heute ist besser als ein perfekter Plan morgen.

Neues (Responsive) Design

Liebe Leser,

es ist mal wieder Zeit: Das Design habe ich umgestellt!

Das alte Design entsprang wahrscheinlich eher einem LSD-Rausch des Designers, was mir aber nichts ausmachte, denn es sah mit seinen sphärischen Regenbogenfarben doch ganz ansehnlich aus.

Dass ich das Design umgestellt habe, liegt vor allem daran, dass ich mittlerweile viel mit meinem Smartphone surfe und es hasse (ja.. HASSE), wenn Webseiten nicht für kleinere Displays konzipiert sind. Klar, ich kann die Seite auf Lesegröße zoomen, aber dieses waagerechte Scrollen möchte ich meinen Lesern nicht zumuten! Und deswegen ist das jetzige Design etwas schlichter, dafür aber „responsive“ (wie es im Fachjargon heißt) und somit mit beliebigen Displaygrößen genießbar. Du kannst ja mal die Breite dieses Browserfenster verkleinern.. Cool, was?

Es sind hier und da noch Anpassungen nötig und das Design könnte ruhig noch etwas persönlicher sein, aber das bekommen wir mit der Zeit bestimmt noch alles hin.

Firefox Erweiterungen – Meine Top 5

5. Echofon

EchofonMit Echofon kannst du Twitter direkt in deinem Browser benutzen. Neue Tweets werden in einer kleinen Box angezeigt. Du kannst eigene Tweets und Direktnachrichten schreiben und siehst, in welchen Tweets, du erwähnt wurdest.

Außerdem werden neue Tweets farblich hervorgehoben, man kann auf Tweets antworten und Tweets favorisieren.

Auch mehrere Twitter Konten werden von Echofon unterstützt.

Download von Echofon

4. Deutsches Wörterbuch

Ein Wörterbuch macht dann Sinn, wenn man viel im Internet schreibt, aber auf eine Rechtschreibprüfung nicht verzichten will:

Firefox Wörterbuch

Einziges Manko dieser Erweiterung ist, dass das Wörterbuch leider nicht alle Wörter kennt und hin und wieder verschlimmbessert, weil sich auch einige Fehler in das Wörterbuch geschlichen haben. Aber da man selbst die Microsoft Office Rechtschreibprüfung nicht blindlings verwenden sollte, weiß man, dass man Rechtschreibprüfungen eh nur mit Vorsicht genießen sollte.

Download des Deutschen Wörterbuchs

3. Copy Plain Text

Diese Erweiterung fügt, wenn man mit der rechten Maustaste auf einen markierten Text klickt, den Punkt „Copy as Plain Text“ unter dem normalen Kopieren hinzu. Wozu das gut ist? Nun, wenn man z.B. etwas von einer Webseite in Word kopieren möchte, werden Formatierungen beim normalen Kopieren auch übernommen. Beim „Copy as Plain Text“ wird nur der Text kopiert.

Download von Copy Plain Text

2. Adblock Plus

Mit Adblock Plus war Werbung gestern, dann die Werbung wird mit dieser Erweiterung einfach ausgeblendet.

Auch wenn perun die Logik hinter Werbeblockern nicht versteht, so setze ich Adblock Plus seit Jahren ohne schlechtes Gewissen ein. Klar, wenn man Geld im Internet verdienen will oder zumindest seine Kosten decken will, sind Werbebanner eine Möglichkeit. Ich habe mich vor dem Einsatz dieser Erweiterung aber schon so oft von Werbung im Internet erschlagen gefühlt, dass mir Werbebanner äußerst suspekt sind und ich ihnen keine Träne nachweine. Wer Werbebanner einsetzt, verschreckt seine Besucher.

Wenn etwas so gut ist, dass ich dadurch einen echten Mehrwert habe, bezahle ich auch gerne dafür. Aber auf zweitklassigen Webseiten mit Werbebannern voll gepflastert zu werden, sehe ich nicht ein.

Download von Adblock Plus

1. Textarea Cache

Diese Erweiterung ist für all diejenigen gedacht, die – während sie lange Texte auf Webseiten schreiben – schon mal

  • auf den falschen Link klicken
  • vergessen den Text auch abzuschicken
  • fälschlicherweise auf den Zurück-Button klicken
  • denen hin und wieder der Computer abstürzt
  • oder per WLAN im Netz sind und beim Abschicken die Verbindung flöten geht

In all diesen Fällen wäre der Text (lange eMail, Forenbeitrag, Kommentar, Blog-Eintrag etc.) unwiderruflich weg – irgendwo im Datennirwana.

Mit dieser Erweiterung wird der Inhalt von Textfeldern allerdings zwischengespeichert, so dass man ihn wiederherstellen kann:

Textarea Cache

Download von Textarea Cache