Wie Du mit D3.js und Node.js Charts erstellst und als PNG abspeicherst

Für mein aktuelles Projekt geofy.de, musste ich eine große Anzahl von Charts generieren, die ich als Marker auf Landkarten einsetzen wollte. Dieser Beitrag zeigt Euch wie.

Jan Krogmann
4 min readApr 22, 2021

geofy.de ist ein Service, der Informationen über Regionen in Deutschland sammelt und über Indikatoren leicht zugänglich macht. Es gibt unter anderem auch ein Tool, dass Euch beim Umzug nach Berlin, Hamburg oder München unterstützt. Ein zur Zeit in Arbeit befindlicher Teil des Service, versucht statistische Kennzahlen als sogenannte Marker auf einer Karte darzustellen.

Leaflet und/oder Google Maps bieten die Möglichkeit, Landkarten mit eigenen “Markern” zu versehen. Wie der Name vermuten lässt, werden Marker verwendet, um bestimmte Orte auf einer Karte zu “markieren”.
Ich hatte mich für geofy.de entschieden, die angezeigten Marker mit zusätzlicher visueller Information auszustatten. So konnte ich komplexe Sachverhalte in einer einfachen Grafik verpacken und im Kontext der jeweiligen Region anzeigen.

Die folgende Karte zeigt Euch ein Beispiel:

Ein Beispiel für Marker auf geofy.de
Ein Beispiel für Marker auf geofy.de

Jeder Marker zeigt drei Indikatoren an, die Auskunft über die Wohnqualität einer bestimmten Region geben. Je “geschlossener” ein Kreis im Marker ist, umso höher der Wert des Indikators.

Die in der Karte angezeigten Miniatur-Charts wurden mit den in diesem Beitrag vorgestellten Tools generiert. Ich werde Euch Schritt für Schritt zeigen, wie ich das bewerkstelligt habe.

tl;dr

Dieser Beitrag zeigt eine Lösung, die in einer Node.js Laufzeitumgebung mit Hilfe von D3.js and Radial Progress Chart SVG Charts generiert. Anschließend werden die SVG Grafiken in PNG Grafiken konvertiert.
Den Source Code dazu findet Ihr bei github.

Voraussetzungen

Dieser Beitrag geht davon aus, dass Ihr bereits über eine funktionierende Installation von Node.js verfügt. Die Installationsversion könnt ihr hier herunterladen. Ich würde empfehlen, zunächst die Installation von Node.js abzuschließen, um anschließend hier weiter zu machen.

Wir werden gemeinsam eine Lösung entwickeln, die in einer Node.js Laufzeitumgebung mit Hilfe von D3.js and Radial Progress Chart SVG Charts generiert. Anschließend verwenden wir sharp, um den SVG Code in PNG Grafiken zu konvertieren.

D3.js

Ich hatte mich während des Projektes aus verschiedenen Gründen sehr früh für die Verwendung von D3.js entschieden. D3.js ist ein sehr mächtiges Werkzeug für die Erstellung von interaktiven Charts. Es existieren zudem zahllose Tutorials, Anleitungen und How-Tos, die Dir helfen, D3.js zu meistern.

Node.js

Da ich die Marker serverseitig vorgenerieren musste, war es notwendig eine JavaScript Laufzeitumgebung auf dem Server zu installieren. Ich habe ich mich für Node.js entschieden.
Radial Progress Charts
Für die Generierung der eigentlichen Charts verwenden wir eine leicht angepasste Version von Pablo Molnars Radial Progress Chart, die wunderbare Radial Bar Charts erstellt. Hier ein Beispiel:

Ein Beispiel für eine Radial Progess Chart
Ein Beispiel für eine Radial Progess Chart

Der Code für das oben dargestellte Ergebnis ist erstaunlich simpel:

Sharp

Für die Konvertierung des generierten SVG Codes verwenden wir das Projekt sharp, eine “High performance Node.js image processing” Bibliothek. Und “high performance” ist sharp in der Tat: es ist wirklich extrem fix!

Los geht’s…

Jetzt aber “Butter bei die Fische”, wie man in meiner alten Heimat Hamburg sagt. Zunächst gilt es, mit Hilfe des Node.js Paketmanagers npm, die D3.js, JSDOM und sharp Bibliotheken zu installieren:

npm install — save d3 jsdom sharp

Anschließend legen wir uns eine neue JavaScript Datei an. Ich nenne sie `generate-markers.js`.

Als erstes werden wir die benötigten Bibliotheken laden und ein paar Initialisierungen vornehmen:

Als erstes werden wir die benötigten Bibliotheken laden und ein paar Initialisierungen vornehmen:

Die Bibliothek `fs` benötigen wir, um die Ergebnisse unserer Generierung in das Dateisystem schreiben zu können. Die Bibliothek `d3` ist das Node.js Paket, für D3.js und die Bibliothek `jsdom` wird benötigt, um für D3 ein Domain Object Model (DOM) zur Verfügung zu stellen. Ohne DOM hat D3.js keine Basis, um SVG Grafiken generieren zu können. Die Bibliothek `sharp` schließlich, hilft uns die SVG Dateien in PNG zu konvertieren.

Nachdem das Lager bereitet ist, kann die eigentliche Arbeit beginnen. Wir definieren die Farben, die für die einzelnen Ringe verwendet werden sollen (von innen nach außen) und initialisieren das Chart Objekt. Zunächst noch für jeden Ring mit dem Wert 0:

Zu guter Letzt iterieren wir für alle Ringe über die Werte 0 bis 10. Für jede Kombination der Werte generieren wir eine SVG Datei und konvertieren sie in ein PNG:

Als Ergebnis erhalten wir eine Verzeichnisstruktur mit den generierten SVG und PNG Dateien:

└───radial
└───0
├───0
│ 0.png
│ 0.svg
│ 1.png
│ 1.svg
│ 10.png
│ 10.svg
│ 2.png
│ 2.svg
│ 3.png
│ 3.svg
│ 4.png
│ 4.svg
│ 5.png
│ 5.svg
│ 6.png
│ 6.svg
│ 7.png
│ 7.svg
│ 8.png
│ 8.svg
│ 9.png
│ 9.svg

├───1
│ 0.png
│ 0.svg
│ 1.png
│ 1.svg
│ 10.png
│ 10.svg
│ 2.png
│ 2.svg
│ 3.png
│ 3.svg
│ 4.png
│ 4.svg
│ 5.png
[…]

Das fertige Skript hat von mir noch ein paar Tweaks bekommen, beispielsweise mehrere Farbthemen und die Möglichkeit, Farben als Argument zu übergeben. Die grundlegende Funktionalität bleibt davon aber unberührt.

--

--