Kapitel 4. Webdev 101
Diese Arbeit wurde mithilfe von KI übersetzt. Wir freuen uns über dein Feedback und deine Kommentare: translation-feedback@oreilly.com
In diesem Kapitel werden die grundlegenden Webentwicklungskenntnisse vorgestellt, die du brauchst, um die Webseiten zu verstehen, die du nach Daten durchsuchst, und um die Seiten zu strukturieren, die du als Grundgerüst für deine JavaScript-Visualisierungen verwenden willst. Du wirst sehen, dass ein wenig Wissen in der modernen Webentwicklung sehr hilfreich ist, vor allem, wenn du dich darauf konzentrierst, in sich geschlossene Visualisierungen und nicht ganze Websites zu erstellen (siehe "Single-Page Apps" für weitere Informationen).
Es gelten die üblichen Vorbehalte: Dieses Kapitel ist teils Referenz, teils Tutorial. Wahrscheinlich gibt es hier Dinge, die du bereits kennst, also kannst du sie ruhig überspringen und dich dem neuen Material widmen.
Das große Bild
Die einfache Webseite, der Grundbaustein des World Wide Web (WWW) - jenesTeils des Internets, der von Menschen genutzt wird - besteht aus verschiedenen Dateitypen. Abgesehen von den Multimediadateien (Bilder, Videos, Ton usw.) sind die wichtigsten Elemente Texte, bestehend aus Hypertext Markup Language (HTML), Cascading Style Sheets (CSS) und JavaScript. Diese drei Elemente werden zusammen mit den erforderlichen Datendateien über das Hypertext Transfer Protocol (HTTP) übertragen und zum Aufbau der Seite verwendet, die du in deinem Browserfenster siehst und mit der du interagieren kannst. Sie wird durch das Document Object Model (DOM) beschrieben, einen hierarchischen Baum, an dem dein Inhalt hängt. Ein grundlegendes Verständnis dafür, wie diese Elemente zusammenwirken, ist für die Erstellung moderner Webvisualisierungen unerlässlich.
Webentwicklung ist ein weites Feld, und das Ziel dieses Kurses ist es nicht, aus dir einen vollwertigen Webentwickler zu machen. Ich gehe davon aus, dass du den Umfang der Webentwicklung so weit wie möglich einschränken und dich nur auf den Teil konzentrieren willst, der für die Erstellung einer modernen Visualisierung notwendig ist. Um die Art von Visualisierungen zu erstellen, die auf d3js.org gezeigt, in der New York Times veröffentlicht oder in interaktive Daten-Dashboards eingebaut werden, brauchst du eigentlich erstaunlich wenig Webdev fu. Das Ergebnis deiner Arbeit sollte sich leicht in eine größere Website einbinden lassen, wenn jemand dafür zuständig ist. Bei kleinen, persönlichen Websites ist es einfach genug, die Visualisierung selbst einzubauen.
Single-Page Apps
Single-Page-Applikationen (SPAs) sind Webanwendungen (oder ganze Websites), die dynamisch mit JavaScript zusammengestellt werden und oft auf einem leichtgewichtigen HTML-Backbone und CSS-Styles aufbauen, die dynamisch mit Klassen- und ID-Attributen angewendet werden können. Viele moderne Datenvisualisierungen passen auf diese Beschreibung, darunter auch die Nobelpreisvisualisierung, auf die dieses Buch aufbaut.
Der SPA-Stammordner ist oft eigenständig und kann leicht in eine bestehende Website integriert werden oder für sich alleine stehen, da er nur einen HTTP-Server wie Apache oder NGINX benötigt.
Wenn wir unsere Datenvisualisierungen als SPAs betrachten, entfällt ein Großteil des kognitiven Aufwands für den Webentwicklungsaspekt von JavaScript-Visualisierungen, so dass wir uns auf die Programmierung konzentrieren können. Die Fähigkeiten, die erforderlich sind, um die Visualisierung ins Web zu stellen, sind immer noch recht einfach und amortisieren sich schnell. Oft wird es die Aufgabe von jemand anderem sein.
Aufrüsten
Wie du sehen wirst, braucht man für die Erstellung moderner Datenvisualisierungen nicht mehr als einen guten Texteditor, einen modernen Browser und ein Terminal(Abbildung 4-1). Ich beschreibe die Mindestanforderungen an einen webdev-fähigen Editor und die unwichtigen, aber nützlichen Funktionen.
Meine bevorzugten Browser-Entwicklungstools sind das Web-Developer-Kit von Chrome, das auf allen Plattformen frei verfügbar ist. It verfügt über eine Menge tabulatorgesteuerter Funktionen, die ich in diesem Kapitel behandeln werde:
-
Die Registerkarte Elemente, auf der du die Struktur einer Webseite, ihren HTML-Inhalt, ihre CSS-Stile und die DOM-Darstellung untersuchen kannst
-
Die Registerkarte " Quellen", auf der die meisten deiner JavaScript-Debugging-Funktionen stattfinden werden
Du brauchst ein Terminal für die Ausgabe, zum Starten deines lokalen Webservers und vielleicht zum Skizzieren von Ideen mit dem IPython-Interpreter. Heutzutage verwende ich in der Regel browserbasierte Jupyter-Notizbücher als Skizzenblock fürPython-Daten - einerder Hauptvorteile ist, dass die Sitzung in Form einer Notizbuchdatei (.ipynb) gespeichert wird, mit der du die Sitzung zu einem späteren Zeitpunkt erneut starten kannst. Außerdem kannst du deine Daten mit eingebetteten Diagrammen iterativ erkunden. Das werden wir in Teil III noch genauer unter die Lupe nehmen.
Bevor wir uns damit beschäftigen, was du brauchst, wollen wir uns mit ein paar Dingen beschäftigen, die du nicht brauchst, wenn du dich auf den Weg machst, und ein paar Mythen aus dem Weg räumen.
Der Mythos von IDEs, Frameworks und Tools
Viele angehende Javacripter gehen davon aus, dass für die Programmierung im Web ein komplexes Toolset erforderlich ist, vor allem eine intelligente Entwicklungsumgebung (IDE), wie sie von Unternehmen und anderen Programmierern überall verwendet wird. Das ist potenziell teuer und stellt eine weitere Lernkurve dar. Die gute Nachricht ist, dass du Web-Dataviz auf professionellem Niveau mit nichts anderem als einem guten Texteditor erstellen kannst. Solange du dich nicht mit modernen JavaScript-Frameworks beschäftigst (und damit würde ich warten, bis du dich mit Webdev auskennst), bietet eine IDE keine großen Vorteile und ist in der Regel auch weniger leistungsfähig. Eine weitere gute Nachricht ist, dass die kostenlose und leichtgewichtige Visual Studio Code IDE (VSCode) der De-facto-Standard für die Webentwicklung geworden ist. Wenn du VSCode bereits verwendest oder ein paar mehr Funktionen haben möchtest, ist es ein gutes Arbeitspferd, um diesem Buch zu folgen.
Es ist auch ein weit verbreiteter Mythos, dass man in JavaScript nicht produktiv sein kann, ohne ein Framework zu benutzen.1 Im Moment wetteifern eine Reihe von Frameworks um die Kontrolle über das JavaScript-Ökosystem, die meisten davon gesponsert von den verschiedenen großen Unternehmen, die sie entwickelt haben. Diese Frameworks kommen und gehen in einem schwindelerregenden Tempo, und mein Rat für alle, die mit JavaScript anfangen, ist, sie komplett zu ignorieren, während du deine Grundkenntnisse entwickelst. Nutze kleine, zielgerichtete Bibliotheken, wie die des jQuery-Ökosystems oder die funktionalen Programmerweiterungen von Underscore, und sieh zu, wie weit du kommst, bevor du ein "my way or the highway "-Framework brauchst. Binde dich nur dann an ein Framework, wenn du einen klaren und aktuellen Bedarf hast, und nicht, weil der aktuelle JS-Groupthink davon schwärmt, wie toll es ist.2 Eine weitere wichtige Überlegung ist, dass D3, die wichtigste Webdatenbibliothek, mit keinem der größeren Frameworks, die ich kenne, wirklich gut zusammenspielt, vor allem nicht mit denen, die Kontrolle über das DOM wollen. D3 mit dem Framework kompatibel zu machen, ist eine fortgeschrittene Fähigkeit.
Wenn du dich in Webdev-Foren, Reddit-Listen und Stack Overflow umschaust, wirst du feststellen, dass es eine Vielzahl von Tools gibt, die ständig um Aufmerksamkeit buhlen. Es gibt u. a. JS+CSS Minifier und Watcher, die automatisch Dateiänderungen erkennen und Webseiten während der Entwicklung neu laden. Auch wenn einige davon ihre Berechtigung haben, gibt es meiner Erfahrung nach eine Menge unzuverlässiger Tools, die wahrscheinlich mehr Zeit kosten, als sie an Produktivität gewinnen. Um es noch einmal zu sagen: Du kannst auch ohne diese Dinge sehr produktiv sein und solltest nur dann zu ihnen greifen, wenn es dich dringend juckt. Einige sind sehr nützlich, aber nur sehr wenige sind für die Arbeit mit Datenvisualisierung auch nur annähernd notwendig.
Ein Arbeitstier für die Textbearbeitung
An erster Stelle deiner Webentwicklungswerkzeuge steht ein Texteditor, mit dem du gut zurechtkommst und der zumindest die Syntaxhervorhebung für mehrere Sprachen beherrscht - in unserem Fall HTML, CSS, JavaScript und Python. Du kannst mit einem einfachen Editor ohne Syntaxhervorhebung auskommen, aber auf lange Sicht wird sich das als lästig erweisen. Dinge wie Syntaxhervorhebung, Code-Linting, intelligente Einrückung und Ähnliches nehmen dem Programmieren eine enorme kognitive Belastung, so dass ich ihr Fehlen als einschränkenden Faktor betrachte. Das sind meine Mindestanforderungen an einen Texteditor:
-
Syntaxhervorhebung für alle von dir verwendeten Sprachen
-
Konfigurierbare Einrückung Stufen und Typen für Sprachen (z. B. Python 4 weiche Tabs, JavaScript 2 weiche Tabs)
-
Mehrere Fenster/Panels/Registerkarten für eine einfache Navigation in deiner Codebasis
-
Ein anständiger Code-Linter (siehe Abbildung 4-2)
Wenn du einen relativ fortschrittlichen Texteditor verwendest, sollten alle oben genannten Funktionen standardmäßig vorhanden sein, mit Ausnahme von Code Linting, das ein wenig Konfiguration erfordern kann.
Browser mit Entwicklungswerkzeugen
Einer der Gründe, warum eine vollwertige IDE im modernen Webdev weniger wichtig ist, ist, dass der beste Ort zum Debuggen der Webbrowser selbst ist und sich dort so schnell verändert, dass jede IDE, die versucht, diesen Kontext zu emulieren, es schwer haben wird. Darüber hinaus haben moderne Webbrowser eine Reihe leistungsstarker Debugging- und Entwicklungstools entwickelt. Das beste unter ihnen ist Chrome DevTools, das eine riesige Menge an Funktionen bietet, vom ausgefeilten Debugging (vor allem für Pythonisten) (parametrische Breakpoints, Variablenüberwachung usw.) bis hin zu Speicher- und Prozessoroptimierungsprofilen, Geräteemulation (willst du wissen, wie deine Webseite auf einem Smartphone oder Tablet aussieht?) und vielem mehr. Chrome DevTools ist der Debugger meiner Wahl und wird in diesem Buch verwendet. Wie alles, was in diesem Buch behandelt wird, ist auch er kostenlos.
Terminal oder Eingabeaufforderung
Das Terminal oder die Kommandozeile ist der Ort, an dem du die verschiedenen Server startest und wahrscheinlich nützliche Logging-Informationen ausgibst. Hier probierst du auch Python-Module aus oder lässt einen Python-Interpreter laufen (IPython ist in vielerlei Hinsicht der beste).
Eine Webseite erstellen
Es gibt vier Elemente einer typischen Webvisualisierung:
-
Ein HTML-Skelett, mit Platzhaltern für unsere programmatische Visualisierung
-
Cascading Style Sheets (CSS), die das Erscheinungsbild definieren (z. B. Rahmenbreiten, Farben, Schriftgrößen, Platzierung von Inhaltsblöcken)
-
JavaScript zur Erstellung der Visualisierung
-
Zu transformierende Daten
Bei den ersten drei handelt es sich lediglich um Textdateien, die mit unserem Lieblingseditor erstellt und vom Webserver an den Browser übermittelt werden (siehe Kapitel 12). Schauen wir sie uns nacheinander an.
Seiten mit HTTP bereitstellen
Die Auslieferung der HTML-, CSS- und JS-Dateien, aus denen eine bestimmte Webseite besteht (sowie alle zugehörigen Datendateien, Multimedia usw.), wird zwischen einem Server und einem Browser über das Hypertext Transfer Protocol ausgehandelt. HTTP bietet eine Reihe von Methoden, von denen die am häufigsten verwendete GET ist, die eine Webressource anfordert und die Daten vom Server abruft, wenn alles gut geht, oder einen Fehler ausgibt, wenn das nicht der Fall ist. In Kapitel 6 werden wir GET zusammen mit dem Python-Modul "Requests" verwenden, um Inhalte von Webseiten zu scrapen.
Um die vom Browser erzeugten HTTP-Anfragen zu verarbeiten, brauchst du einen Server. In der Entwicklung kannst du mit dem in Python integrierten Webserver (einer der mitgelieferten Batterien), der Teil des Moduls http
ist, lokal einen kleinen Server betreiben. Du startest den Server in der Befehlszeile mit einer optionalen Portnummer (Standard 8000), etwa so:
$ python -m http.server 8080 Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...
Dieser Server stellt jetzt lokal Inhalte auf Port 8080 bereit. Du kannst auf die Seite zugreifen, indem du die URL http://localhost:8080 in deinem Browser aufrufst.
Das Modul http.server
ist eine nette Sache und für Demos und Ähnliches gut geeignet, aber es fehlt ihm eine Menge grundlegender Funktionen. Aus diesem Grund ist es, wie wir in Teil IV sehen werden, besser, einen richtigen Entwicklungs- (und Produktions-) Server wie Flask (der Server der Wahl in diesem Buch) zu beherrschen.
Das DOM
Die HTML-Dateien, die du über HTTP schickst, werden im Browser in ein Document Object Model (DOM) umgewandelt, das wiederum von JavaScript angepasst werden kann, denn dieses programmatische DOM ist die Grundlage von Dataviz-Bibliotheken wie D3. Das DOM ist eine Baumstruktur, die durch hierarchische Knoten dargestellt wird, wobei der oberste Knoten die Hauptwebseite oder das Dokument ist.
Im Wesentlichen wird das HTML, das du schreibst oder mit einer Vorlage erzeugst, vom Browser in eine Baumhierarchie von Knoten umgewandelt, von denen jeder ein HTML-Element darstellt. Der oberste Knoten wird als Document Object bezeichnet und alle anderen Knoten werden nach dem Eltern-Kind-Prinzip untergeordnet. Die programmatische Bearbeitung des DOM ist das Herzstück von Bibliotheken wie jQuery und dem mächtigen D3, daher ist es wichtig, ein gutes mentales Modell davon zu haben, was vor sich geht. Ein guter Weg, um ein Gefühl für das DOM zu bekommen, ist die Verwendung eines Webtools wie Chrome DevTools (mein empfohlenes Toolset), um die Zweige des Baums zu untersuchen.
Was auch immer du auf der Webseite siehst, der Zustand des Objekts (angezeigt oder versteckt, Matrix-Transformation usw.) wird mit dem DOM verwaltet. Die große Neuerung von D3 ist, dass Daten direkt an das DOM angehängt und für visuelle Veränderungen genutzt werden können (Data-Driven Documents).
Das HTML-Skelett
Eine typische Webvisualisierung verwendet ein HTML-Skelett und baut die Visualisierung mit JavaScript darauf auf.
HTML ist die Sprache, die verwendet wird, um den Inhalt einer Webseite zu beschreiben. Sie wurde erstmals 1980 von dem Physiker Tim Berners-Lee vorgeschlagen, als er am Teilchenbeschleuniger CERN in der Schweiz arbeitete. Sie verwendet Tags wie <div>
, <img>
und <h>
, um den Inhalt der Seite zu strukturieren, während CSS für das Aussehen und die Darstellung verwendet wird.3 Mit dem Aufkommen von HTML5 wurde der Textbaustein erheblich reduziert, aber das Wesentliche ist in diesen dreißig Jahren im Wesentlichen unverändert geblieben.
Vollständig spezifiziertes HTML beinhaltete früher eine Menge ziemlich verwirrender Header-Tags, aber mit HTML5 hat man sich Gedanken über einen benutzerfreundlicheren Minimalismus gemacht. Das ist so ziemlich die Minimalanforderung für ein Templating zu Beginn:4
<!DOCTYPE html>
<
meta
charset
=
"utf-8"
>
<
body
>
<!-- page content -->
</
body
>
Wir müssen also nur das Dokument als HTML deklarieren, unseren Zeichensatz 8-bit Unicode und ein <body>
Tag, unter dem wir unseren Seiteninhalt hinzufügen. Das ist eine große Verbesserung gegenüber der vorher erforderlichen Buchhaltung und bietet eine sehr niedrige Einstiegsschwelle für die Erstellung der Dokumente, die in Webseiten umgewandelt werden. Beachte die Form des Kommentar-Tags: <!-- comment -->
.
Realistischer ist, dass wir wahrscheinlich CSS und JavaScript hinzufügen wollen. Du kannst beides direkt in ein HTML-Dokument einfügen, indem du die Tags <style>
und <script>
wie folgt verwendest:
<!DOCTYPE html>
<
meta
charset
=
"utf-8"
>
<
style
>
/* CSS */
</style>
<
body
>
<!-- page content -->
<
script
>
// JavaScript...
</
script
>
</
body
>
Dieses einseitige HTML-Formular wird oft in Beispielen wie den Visualisierungen auf d3js.org verwendet. Es ist praktisch, eine einzige Seite zu haben, wenn du den Code demonstrieren oder den Überblick über die Dateien behalten willst, aber im Allgemeinen würde ich empfehlen, die HTML-, CSS- und JavaScript-Elemente in separate Dateien aufzuteilen. Abgesehen von der einfacheren Navigation, wenn die Codebasis größer wird, liegt der große Vorteil darin, dass du die sprachspezifischen Verbesserungen deines Editors, wie z. B. die solide Syntaxhervorhebung und das Code-Linting (im Grunde eine fliegende Syntaxprüfung), voll ausnutzen kannst. Einige Editoren und Bibliotheken behaupten zwar, dass sie mit eingebettetem CSS und JavaScript umgehen können, aber ich habe noch keinen geeigneten gefunden.
Um CSS- und JavaScript-Dateien zu verwenden, fügen wir sie einfach in den HTML-Code ein, indem wir die Tags <link>
und <script>
wie folgt verwenden:
<!DOCTYPE html>
<
meta
charset
=
"utf-8"
>
<
link
rel
=
"stylesheet"
href
=
"style.css"
/>
<
body
>
<!-- page content -->
<
script
type
=
"text/javascript"
src
=
"script.js"
></
script
>
</
body
>
Inhalte markieren
Visualisierungen verwenden oft nur eine kleine Teilmenge der verfügbaren HTML-Tags und bauen die Seite normalerweise programmatisch auf, indem sie Elemente an den DOM-Baum anhängen.
Das gebräuchlichste Tag ist das <div>
, das einen Inhaltsblock markiert. <div>
s können andere <div>
s enthalten, was eine Baumhierarchie ermöglicht, deren Zweige bei der Elementauswahl und bei der Weitergabe von Benutzeroberflächenereignissen (UI) wie Mausklicks verwendet werden. Hier ist eine einfache <div>
Hierarchie:
<
div
id
=
"my-chart-wrapper"
class
=
"chart-holder dev"
>
<
div
id
=
"my-chart"
class
=
"bar chart"
>
this is a placeholder, with parent #my-chart-wrapper</
div
>
</
div
>
Beachte die Verwendung der Attribute id
und class
. Diese werden verwendet, wenn du DOM-Elemente auswählst und um CSS-Stile anzuwenden. IDs sind eindeutige Bezeichner; jedes Element sollte nur einen haben und eine bestimmte ID sollte nur einmal auf einer Seite vorkommen. Die Klasse kann auf mehrere Elemente angewendet werden, was eine Massenauswahl ermöglicht, und jedes Element kann mehrere Klassen haben.
Für Textinhalte sind die wichtigsten Tags <p>
, <h*>
und <br>
. Du wirst sie häufig verwenden. Dieser Code ergibt Abbildung 4-3:
<
h2
>
A Level-2 Header</
h2
>
<
p
>
A paragraph of body text with a line break here..</
br
>
and a second paragraph...</
p
>
Die Header-Tags sind in umgekehrter Reihenfolge nach Größe sortiert, beginnend mit dem größten <h1>
.
<div>
, <h*>
und <p>
sind so genannte Blockelemente. Sie beginnen und enden normalerweise mit einer neuen Zeile. Die andere Klasse von Tags sind Inline-Elemente, die ohne Zeilenumbruch angezeigt werden. Dazu gehören Bilder <img>
, Hyperlinks <a>
und Tabellenzellen <td>
, die das Tag <span>
für Inline-Text enthalten:
<
div
id
=
"inline-examples"
>
<
img
src
=
"path/to/image.png"
id
=
"prettypic"
>
<
p
>
This is a
<
a
href
=
"link-url"
>
link
<
/
a
>
to
<
span
class
=
"url"
>
link-url
<
/
span
>
<
/
p
>
<
/
div
>
Beachte, dass wir für Bilder keinen schließenden Tag brauchen.
Die Spanne und der Link sind im Text fortlaufend.
Weitere nützliche Tags sind Listen, geordnete <ol>
und ungeordnete <ul>
:
<
div
style
=
"display: flex; gap: 50px"
>
<
div
>
<
h3
>
Ordered (ol) list
<
/
h3
>
<
ol
>
<
li
>
First Item
<
/
li
>
<
li
>
Second Item
<
/
li
>
<
/
ol
>
<
/
div
>
<
div
>
<
h3
>
Unordered (ul) list
<
/
h3
>
<
ul
>
<
li
>
First Item
<
/
li
>
<
li
>
Second Item
<
/
li
>
<
/
ul
>
<
/
div
>
<
/
div
>
Hier wenden wir einen CSS-Stil direkt (inline) auf das
div
Tag an. Unter "Positionierung und Größenanpassung von Containern mit Flex" findest du eine Einführung in die Eigenschaftflex
display.
Abbildung 4-4 zeigt die gerenderten Listen.
HTML hat auch einen eigenen <table>
Tag, der nützlich ist, wenn du Rohdaten in deiner Visualisierung darstellen willst. Dieses HTML erzeugt die Überschrift und die Zeile in Abbildung 4-5:
<
table
id
=
"chart-data"
>
<
tr
>
<
th
>
Name
<
/
th
>
<
th
>
Category
<
/
th
>
<
th
>
Country
<
/
th
>
<
/
tr
>
<
tr
>
<
td
>
Albert Einstein
<
/
td
>
<
td
>
Physics
<
/
td
>
<
td
>
Switzerland
<
/
td
>
<
/
tr
>
<
/
table
>
Bei der Erstellung von Web-Visualisierungen werden die Text-Tags, die Anweisungen, Infokästen und so weiter enthalten, am häufigsten verwendet. Der Hauptteil unserer JavaScript-Arbeit wird aber wahrscheinlich dem Aufbau von DOM-Zweigen gewidmet sein, die auf den Tags Scalable Vector Graphics (SVG) <svg>
und <canvas>
basieren. In den meisten modernen Browsern unterstützt das Tag <canvas>
auch einen 3D-WebGL-Kontext, mit dem OpenGL-Visualisierungen in die Seite eingebettet werden können.5
Mit SVG, dem Schwerpunkt dieses Buches und dem Format, das von der mächtigen D3-Bibliothek verwendet wird, befassen wir uns in "Skalierbare Vektorgrafiken". Schauen wir uns nun an, wie wir unseren Inhaltsblöcken einen Stil hinzufügen.
CSS
CSS, die Abkürzung für Cascading Style Sheets, ist eine Sprache, mit der das Aussehen einer Webseite beschrieben werden kann. Du kannst Stilattribute zwar fest in deinen HTML-Code einfügen, aber das wird allgemein als schlechte Praxis angesehen.6 Es ist viel besser, dein Tag mit einem id
oder class
zu kennzeichnen und dieses zu verwenden, um Stile im Stylesheet anzuwenden.
Das Schlüsselwort in CSS ist Kaskadierung. CSS folgt einer Vorrangregel, die besagt, dass im Falle eines Konflikts der neueste Stil den früheren außer Kraft setzt. Das bedeutet, dass die Reihenfolge der Einbindung der Blätter wichtig ist. In der Regel soll dein Stylesheet als letztes geladen werden, damit du sowohl die Standardeinstellungen des Browsers als auch die von den verwendeten Bibliotheken definierten Styles außer Kraft setzen kannst.
Abbildung 4-6 zeigt, wie CSS verwendet wird, um Stile auf die HTML-Elemente anzuwenden. Zunächst wählst du das Element mit Hilfe von Raute (#) aus, um eine eindeutige ID anzugeben, und mit Punkten (.), um Mitglieder einer Klasse auszuwählen. Dann definierst du ein oder mehrere Eigenschaft/Wert-Paare. Beachte, dass die Eigenschaft font-family
eine Liste von Fallbacks sein kann, die in der Reihenfolge der Präferenz angeordnet sind. Hier wollen wir, dass die Browser-Standardeinstellung font-family
von serif
(gekappte Striche) durch die modernere sans-serif
ersetzt wird, wobei Helvetica Neue
unsere erste Wahl ist.
Um Stile erfolgreich anwenden zu können, ist es wichtig, die CSS-Regeln für die Rangfolge zu kennen. Kurz gesagt, die Reihenfolge ist:
-
!important
nach CSS-Eigenschaft übertrumpft alles. -
Je spezifischer, desto besser (d.h. IDs überschreiben Klassen).
-
Die Reihenfolge der Anmeldung: Die letzte Anmeldung gewinnt, vorbehaltlich der Punkte 1 und 2.
Nehmen wir zum Beispiel an, wir haben eine <span>
der Klasse alert
:
<
span
class
=
"alert"
id
=
"special-alert"
>
something to be alerted to</
span
>
Wenn du die folgende Zeile in unsere style.css-Datei einfügst, wird der Alarmtext rot und fett:
.alert
{
font-weight
:
bold
;
color
:
red
}
Wenn wir dies zur style.css hinzufügen, wird die ID-Farbe Schwarz die Klassenfarbe Rot überschreiben, während die Klasse font-weight
fett bleibt:
#special-alert
{
background
:
yellow
;
color
:
black
}
Um die Farbe Rot für Warnungen zu erzwingen, können wir die Direktive !important
verwenden:7
.alert
{
font-weight
:
bold
;
color
:
red
!important
}
Wenn wir dann ein weiteres Stylesheet, style2.css, nach style.css hinzufügen:
<
link
rel
=
"stylesheet"
href
=
"style.css"
type
=
"text/css"
/>
<
link
rel
=
"stylesheet"
href
=
"style2.css"
type
=
"text/css"
/>
mit style2.css mit folgendem Inhalt:
.alert
{
font-weight
:
normal
}
dann wird die font-weight
der Meldung auf normal
zurückgesetzt, da der neue Klassenstil zuletzt deklariert wurde.
JavaScript
JavaScript ist die einzige browserbasierte Programmiersprache, deren Interpreter in allen modernen Browsern enthalten ist. Um irgendetwas auch nur annähernd Fortgeschrittenes zu machen (und dazu gehören alle modernen Web-Visualisierungen), solltest du JavaScript-Kenntnisse haben. TypeScript ist eine Obermenge von JavaScript, die eine starke Typisierung bietet und derzeit viel Zuspruch erfährt. TypeScript lässt sich mit JavaScript kompilieren und setzt entsprechende Kenntnisse voraus.
99% aller codierten Beispiele für Webvisualisierungen, von denen du lernen solltest, sind in JavaScript geschrieben, und schicke Alternativen verblassen mit der Zeit. Im Grunde genommen ist eine gute Beherrschung von JavaScript eine Voraussetzung für interessante Webvisualisierungen.
Die gute Nachricht für Pythonisten ist, dass JavaScript eigentlich eine ganz nette Sprache ist, wenn man erst einmal ein paar seiner unangenehmen Macken in den Griff bekommen hat.8 Wie ich in Kapitel 2 gezeigt habe, haben JavaScript und Python viele Gemeinsamkeiten und es ist normalerweise einfach, von der einen in die andere Sprache zu wechseln.
Daten
Die Daten, die du für deine Webvisualisierung benötigst, werden vom Webserver in Form von statischen Dateien (z. B. JSON- oder CSV-Dateien) oder dynamisch über eine Art Web-API (z. B. RESTful APIs) bereitgestellt, wobei die Daten in der Regel serverseitig aus einer Datenbank abgerufen werden. Wir werden alle diese Formen in Teil IV behandeln.
Obwohl früher viele Daten in XML-Form geliefert wurden, geht es bei der modernen Webvisualisierung hauptsächlich um JSON- und in geringerem Maße um CSV- oder TSV-Dateien.
JSON (kurz für JavaScript Object Notation) ist der De-facto-Standard für Web-Visualisierungsdaten und ich empfehle dir, ihn lieben zu lernen. JSON lässt sich natürlich sehr gut mit JavaScript kombinieren, aber auch Pythonisten werden mit seiner Struktur vertraut sein. Wie wir in "JSON" gesehen haben , ist das Lesen und Schreiben von JSON-Daten mit Python ein Kinderspiel. Hier ist ein kleines Beispiel für JSON-Daten:
{
"firstName"
:
"Groucho"
,
"lastName"
:
"Marx"
,
"siblings"
:
[
"Harpo"
,
"Chico"
,
"Gummo"
,
"Zeppo"
],
"nationality"
:
"American"
,
"yearOfBirth"
:
1890
}
Chrome DevTools
Das Wettrüsten bei den JavaScript-Engines in den letzten Jahren, das zu enormen Leistungssteigerungen geführt hat, wurde durch ein immer ausgefeilteres Angebot an Entwicklungstools in den verschiedenen Browsern ergänzt. Firebug von Firefox war eine Zeit lang führend, aber die DevTools von Chrome haben es überholt und erweitern die Funktionen ständig. Es gibt inzwischen eine ganze Menge, was du mit den Chrome Tabs machen kannst, aber hier stelle ich dir die beiden nützlichsten Tabs vor: die HTML+CSS-fokussierten Elements und die JavaScript-fokussierten Sources. Beide ergänzen die Entwicklerkonsole von Chrome, die in "JavaScript" vorgestellt wird .
Die Registerkarte Elemente
Um auf zuzugreifen, wähleauf der Registerkarte Elemente die Option Weitere Werkzeuge→Entwicklertools aus dem rechten Optionsmenü oder verwende die Tastenkombination Strg-Umschalt-I (Cmd-Option-I auf dem Mac).
Abbildung 4-7 zeigt die Registerkarte Elemente bei der Arbeit. Du kannst DOM-Elemente auf der Seite mit der linken Lupe auswählen und ihren HTML-Zweig im linken Bereich sehen. Im rechten Fenster kannst du die CSS-Stile sehen, die auf das Element angewendet wurden, und alle angehängten Event-Listener oder DOM-Eigenschaften einsehen.
Eine wirklich coole Funktion der Registerkarte Elemente ist, dass du das Elementstyling sowohl für CSS-Stile als auch für Attribute interaktiv ändern kannst.9 Das ist eine großartige Möglichkeit, das Aussehen und die Wirkung deiner Datenvisualisierungen zu verfeinern.
Die Registerkarte "Elemente" in Chrome bietet eine gute Möglichkeit, die Struktur einer Seite zu erkunden und herauszufinden, wie die verschiedenen Elemente positioniert sind. Dies ist eine gute Möglichkeit, sich mit der Positionierung von Inhaltsblöcken mit den Eigenschaften position
und float
vertraut zu machen. Wenn du dir ansiehst, wie die Profis CSS-Stile anwenden, kannst du deine Fähigkeiten verbessern und einige nützliche Tricks lernen.
Die Registerkarte Quellen
Auf der Registerkarte "Quellen" kannst du alle in der Seite enthaltenen JavaScript-Dateien sehen. Abbildung 4-8 zeigt die Registerkarte bei der Arbeit. Im linken Bereich kannst du ein Skript oder eine HTML-Datei mit eingebettetem <script>
tagged JavaScript auswählen. Wie in der Abbildung gezeigt, kannst du einen Haltepunkt im Code setzen, die Seite laden und bei einer Unterbrechung den Aufrufstapel und alle zugewiesenen oder globalen Variablen sehen. Diese Haltepunkte sind parametrisch, d.h. du kannst Bedingungen für ihre Auslösung festlegen, was praktisch ist, wenn du eine bestimmte Konfiguration abfangen und durchlaufen willst. Bei einer Unterbrechung kannst du standardmäßig in, aus und über Funktionen springen und so weiter.
Die Registerkarte Quellen ist eine fantastische Ressource und reduziert die Notwendigkeit von Konsolenprotokollen10 wenn du versuchst, JavaScript zu debuggen. Wo das Debuggen von JavaScript früher ein großes Problem war, ist es jetzt fast ein Vergnügen.
Andere Werkzeuge
Die Chrome DevTools-Tabs bieten eine riesige Menge an Funktionen und werden fast täglich aktualisiert. Du kannst Speicher- und CPU-Zeitleisten und Profile erstellen, deine Netzwerk-Downloads überwachen und deine Seiten für verschiedene Formfaktoren testen. Die meiste Zeit wirst du jedoch als Datenvisualisierer in den Registerkarten Elemente und Quellen verbringen.
Eine einfache Seite mit Platzhaltern
Nachdem wir nun die wichtigsten Elemente einer Webseite kennengelernt haben, wollen wir sie zusammensetzen. Die meisten Webvisualisierungen beginnen als HTML- und CSS-Skelette mit Platzhalterelementen, die mit ein wenig JavaScript und Daten ergänzt werden können (siehe "Single-Page Apps").
Zuerst brauchen wir unser HTML-Skelett, das wir mit dem Code in Beispiel 4-1 erstellen. Dieses besteht aus einem Baum von <div>
Inhaltsblöcken, die drei Diagrammelemente definieren: einen Kopf-, Haupt- und Seitenleistenabschnitt. Wir speichern diese Datei als index.html.
Beispiel 4-1. Die Datei index.html, unser HTML-Skelett
<!DOCTYPE html>
<
meta
charset
=
"utf-8"
>
<
link
rel
=
"stylesheet"
href
=
"style.css"
type
=
"text/css"
/>
<
body
>
<
div
id
=
"chart-holder"
class
=
"dev"
>
<
div
id
=
"header"
>
<
h2
>
A Catchy Title Coming Soon...</
h2
>
<
p
>
Some body text describing what this visualization is all about and why you should care.</
p
>
</
div
>
<
div
id
=
"chart-components"
>
<
div
id
=
"main"
>
A placeholder for the main chart.</
div
><
div
id
=
"sidebar"
>
<
p
>
Some useful information about the chart, probably changing with user interaction.</
p
>
</
div
>
</
div
>
</
div
>
<
script
src
=
"script.js"
></
script
>
</
body
>
Jetzt, wo wir unser HTML-Skelett haben, wollen wir es mit CSS gestalten. Dabei werden die Klassen und IDs unserer Inhaltsblöcke verwendet, um Größe, Position, Hintergrundfarbe usw. anzupassen. Um unser CSS anzuwenden, importieren wir in Beispiel 4-1 eine style.css-Datei, wie in Beispiel 4-2 gezeigt.
Beispiel 4-2. Die style.css-Datei, die unser CSS-Styling bereitstellt
body
{
background
:
#ccc
;
font-family
:
Sans
-
serif
;
}
div
.dev
{
border
:
solid
1px
red
;
}
div
.dev
div
{
border
:
dashed
1px
green
;
}
div
#chart-holder
{
width
:
600px
;
background
:
white
;
margin
:
auto
;
font-size
:
16px
;
}
div
#chart-components
{
height
:
400px
;
position
:
relative
;
}
div
#main
,
div
#sidebar
{
position
:
absolute
;
}
div
#main
{
width
:
75%
;
height
:
100%
;
background
:
#eee
;
}
div
#sidebar
{
right
:
0
;
width
:
25%
;
height
:
100%
;
}
Diese
dev
Klasse ist eine praktische Möglichkeit, den Rand von visuellen Blöcken zu sehen, was für die Visualisierungsarbeit nützlich ist.Macht
chart-components
zum relativen Elternteil.Setzt die Positionen
main
undsidebar
relativ zuchart-components
.Positioniert diesen Block bündig mit der rechten Wand von
chart-components
.
Wir verwenden die absolute Positionierung der Haupt- und Seitentabellenelemente(Beispiel 4-2). Es gibt verschiedene Möglichkeiten, die Inhaltsblöcke mit CSS zu positionieren, aber die absolute Positionierung gibt dir explizite Kontrolle über ihre Platzierung, was ein Muss ist, wenn du das Aussehen genau richtig hinbekommen willst.
Nachdem du die Größe des Containers chart-components
festgelegt hast, werden die untergeordneten Elemente main
und sidebar
anhand der prozentualen Anteile der übergeordneten Elemente dimensioniert und positioniert. Das bedeutet, dass jede Änderung der Größe von chart-components
sich auf die Kinderelemente auswirkt.
Nachdem wir unser HTML und CSS definiert haben, können wir das Skelett untersuchen, indem wir den einzeiligen HTTP-Server von Python in dem Projektverzeichnis starten, das die in den Beispielen 4-1 und 4-2 definierten Dateien index.html und style.css enthält, und zwar so:
$ python -m http.server8000
Serving HTTP on0
.0.0.0 port8000
...
Abbildung 4-9 zeigt die resultierende Seite mit der geöffneten Registerkarte Elemente, die den DOM-Baum der Seite anzeigt.
Die Inhaltsblöcke des Diagramms sind jetzt richtig positioniert und dimensioniert und bereit für JavaScript, um ansprechende Inhalte hinzuzufügen.
Positionierung und Größenbestimmung von Containern mit Flex
In der Vergangenheit war die Positionierung und Größenanpassung von Inhalten (in der Regel <div>
Container) mit CSS eher eine dunkle Kunst. Erschwerend kam hinzu, dass es viele browserübergreifende Inkompatibilitäten und Meinungsverschiedenheiten darüber gab, was als Polsterung oder Ränder gilt. Aber selbst wenn man das berücksichtigt, schienen die verwendeten CSS-Eigenschaften ziemlich ad-hoc zu sein. Oft stellte sich heraus, dass für eine scheinbar vernünftige Positionierung oder Größenanpassung geheimnisvolles CSS-Wissen erforderlich war, das in den Tiefen eines Stack Overflow-Threads versteckt war. Ein Beispiel ist die Zentrierung von div
in der Horizontalen und Vertikalen.11 Das hat sich mit dem Aufkommen der CSS-Flexbox geändert, die einige leistungsstarke neue CSS-Eigenschaften nutzt, um fast alle Größen- und Positionierungseinstellungen zu ermöglichen, die du jemals brauchen wirst.
Flexboxen sind nicht die einzige CSS-Eigenschaft, die alle anderen beherrscht - die im vorigen Abschnitt vorgestellte absolute Positionierung hat immer noch ihre Berechtigung, vor allem bei Datenvisualisierungen -, aber sie sind eine Sammlung sehr leistungsstarker Eigenschaften, die in den meisten Fällen die einfachste und manchmal auch die einzige Möglichkeit darstellen, eine bestimmte Platzierung/Größe zu erreichen. Effekte, für die früher CSS-Kenntnisse erforderlich waren, sind jetzt auch für relative Neulinge gut zu erreichen, und das Tüpfelchen auf dem i ist, dass Flexboxen wirklich gut mit variablen Bildschirmverhältnissen zusammenspielen - die Macht der Flex. Sehen wir uns also an, was mit den grundlegenden Flex-Eigenschaften alles möglich ist.
Zunächst erstellen wir mit ein wenig HTML einen Container div
mit drei untergeordneten div
s (Boxen). Die untergeordneten Boxen haben die Klasse box
und eine ID, damit ein bestimmtes CSS angewendet werden kann:
<
div
class
=
"container"
id
=
"top-container"
>
<
div
class
=
"box"
id
=
"box1"
>
box 1</
div
>
<
div
class
=
"box"
id
=
"box2"
>
box 2</
div
>
<
div
class
=
"box"
id
=
"box3"
>
box 3</
div
>
</
div
>
Das ursprüngliche CSS gibt dem Container einen roten Rahmen, eine Breite und eine Höhe (600x400). Die Boxen sind 100 Pixel breit und hoch (80 Pixel plus 10 Pixel Padding) und haben einen grünen Rand. Eine neue CSS-Eigenschaft ist die display: flex
des Containers, die einen flexiblen Anzeigekontext festlegt. Das Ergebnis ist in Abbildung 4-10 (display: flex
) zu sehen, in der die Kästchen in einer Reihe dargestellt werden und nicht in der Standardspalte, in der jedes Kästchen eine eigene Reihe einnimmt:
.container
{
display
:
flex
;
width
:
600px
;
height
:
400px
;
border
:
2px
solid
red
;
}
.box
{
border
:
2px
solid
green
;
font-size
:
28px
;
padding
:
10px
;
width
:
80px
;
height
:
80px
;
}
Flex-Anzeigen reagieren auf Kinder mit der Eigenschaft flex
, indem sie ihre Größe an den verfügbaren Platz anpassen. Wenn wir die Boxen flexibel machen, werden sie so erweitert, dass sie die Containerzeile ausfüllen. Abbildung 4-10 (flex-direction: row) zeigt das Ergebnis. Beachte, dass die Eigenschaft flex
die Eigenschaft width der Boxen außer Kraft setzt, so dass sie sich ausdehnen können:
.box
{
/* ... */
flex
:
1
;
}
Die Eigenschaft flex-direction
ist standardmäßig auf row
eingestellt. Wenn du sie auf column
setzt, werden die Kästchen in einer Spalte platziert und die Eigenschaft Höhe wird überschrieben, damit sie sich an die Höhe des Containers anpassen können. Abbildung 4-10 (Richtungsspalte) zeigt das Ergebnis:
.container
{
/* ... */
flex-direction
:
column
;
}
Wenn du die Eigenschaften Breite und Höhe aus den Boxen entfernst oder auskommentierst, werden sie vollständig flexibel und können sich horizontal und vertikal ausdehnen, was zu Abbildung 4-10 (volle Flexibilität) führt:
.box
{
/* ... */
/* width: 80px;
height: 80px; */
flex
:
1
;
}
Wenn du die Reihenfolge der Flexboxen umkehren möchtest, gibt es eine row-reverse
und column-reverse
flex-direction
. Abbildung 4-10 (Spalte umkehren) zeigt das Ergebnis, wenn du die Spalten umkehrst:
.container
{
/* ... */
flex-direction
:
column
-
reverse
;
}
Der Wert der Eigenschaft flex
der Kästchen stellt eine Größengewichtung dar. Zu Beginn haben alle Kästchen eine Gewichtung von eins, wodurch sie gleich groß sind. Wenn wir der ersten Box eine Gewichtung von zwei geben, nimmt sie die Hälfte (2 / (1 + 1 + 2)) des verfügbaren Platzes in der angegebenen Zeilen- oder Spaltenrichtung ein. Abbildung 4-10 (#box1 flex 2) zeigt das Ergebnis, wenn wir den Flex-Wert von box1
erhöhen:
#box1
{
flex
:
2
;
}
Wenn wir die 100-Pixel-Höhen- und -Breitenbeschränkungen (einschließlich Padding) an die Boxen zurückgeben und ihre flex
Eigenschaft entfernen, können wir die Leistungsfähigkeit der Flex-Display-Positionierung demonstrieren. Außerdem müssen wir die flex-Direktive aus box1
entfernen:
.box
{
width
:
80px
;
height
:
80px
;
/* flex: 1; */
}
#box1
{
/* flex: 2; */
}
Bei Inhalten mit fester Größe haben Flex-Displays eine Reihe von Eigenschaften, die eine präzise Platzierung des Inhalts ermöglichen. Diese Art der Manipulation erforderte früher alle möglichen kniffligen CSS-Hacks. Zunächst verteilen wir die Kästchen gleichmäßig in ihrem Container, indem wir zeilenbasierte Abstände verwenden. Die magische Eigenschaft ist justify-content
mit dem Wert space-between
; Abbildung 4-10 (Abstand zwischen) zeigt das Ergebnis:
.container
{
/* ... */
flex-direction
:
row
;
justify-content
:
space
-
between
;
}
Es gibt ein space-around
Komplement zu space-between
, das den Inhalt durch Hinzufügen von gleichem Abstand links und rechts auffüllt. Abbildung 4-10 (Leerzeichen drumherum) zeigt das Ergebnis:
.container
{
/* ... */
justify-content
:
space
-
around
;
}
Durch die Kombination der Eigenschaften justify-content
und align-items
können wir den heiligen Gral der CSS-Positionierung erreichen: die Zentrierung des Inhalts in der Vertikalen und Horizontalen. Mit der Eigenschaft gap
von flex display fügen wir einen Abstand von 20 Pixeln zwischen den Kästchen ein:
.container
{
/* ... */
gap
:
20px
;
justify-content
:
center
;
align-items
:
center
;
}
Abbildung 4-10 (zentriert mit gap
) zeigt, dass unser Inhalt genau in der Mitte seines Containers sitzt.
Eine weitere großartige Eigenschaft der Flex-Anzeige ist, dass sie vollständig rekursiv ist. div
kann sowohl eine Flex-Anzeige-Eigenschaft haben als auch Flex-Inhalt sein. Das macht komplexe Inhaltslayouts zu einem Kinderspiel. Sehen wir uns eine kleine Demonstration von verschachtelten Flex-Boxen an, um das zu verdeutlichen.
Zunächst verwenden wir etwas HTML, um einen verschachtelten Baum von Boxen zu erstellen (einschließlich der Hauptcontainerbox). Wir geben jeder Box und jedem Container eine ID und eine Klasse:
<
div
class
=
"main-container"
>
<
div
class
=
"container"
id
=
"top-container"
>
<
div
class
=
"box"
id
=
"box1"
>
box 1</
div
>
<
div
class
=
"box"
id
=
"box2"
>
box 2</
div
>
</
div
>
<
div
class
=
"container"
id
=
"middle-container"
>
<
div
class
=
"box"
id
=
"box3"
>
box 3</
div
>
</
div
>
<
div
class
=
"container"
id
=
"bottom-container"
>
<
div
class
=
"box"
id
=
"box4"
>
box 4</
div
>
<
div
class
=
"box"
id
=
"box5"
>
<
div
class
=
"box"
id
=
"box6"
>
box 6</
div
>
<
div
class
=
"box"
id
=
"box7"
>
box 7</
div
>
</
div
>
</
div
>
</
div
>
Das folgende CSS gibt dem Hauptcontainer eine Höhe von 800 Pixeln (er füllt standardmäßig die verfügbare Breite aus), eine Flex-Darstellung und eine Flex-Richtung von Spalte, sodass er seinen Flex-Inhalt stapelt.
Es gibt drei Container, die gestapelt werden sollen, die beide flexibel sind und eine flexible Anzeige für ihren Inhalt bieten. Die Boxen haben einen roten Rahmen und sind vollständig flexibel (keine Breite oder Höhe angegeben). Standardmäßig haben alle Boxen eine flexible Gewichtung von eins.
Der mittlere Container hat eine feste Breite (Breite 66%) und verwendet justify-content: center
, um ihn zu zentrieren.
Der unterste Container hat einen Flex-Wert von 2 und ist damit doppelt so hoch wie seine Geschwister. Er hat zwei gleichgewichtige Boxen, von denen eine (Box 5) zwei Boxen enthält, die gestapelt sind (flex-direction: column
). Das ziemlich komplexe Layout (siehe Abbildung 4-11) wird mit beeindruckend wenig CSS erreicht und lässt sich leicht anpassen, indem man ein paar Flex-Display-Eigenschaften ändert:
.main-container
{
height
:
800px
;
padding
:
10px
;
border
:
2px
solid
green
;
display
:
flex
;
flex-direction
:
column
;
}
.container
{
flex
:
1
;
display
:
flex
;
}
.box
{
flex
:
1
;
border
:
2px
solid
red
;
padding
:
10px
;
font-size
:
30px
;
}
#middle-container
{
justify-content
:
center
;
}
#box3
{
width
:
66%
;
flex
:
initial
;
}
#bottom-container
{
flex
:
2
;
}
#box5
{
display
:
flex
;
flex-direction
:
column
;
}
Flex-Boxen bieten einen sehr leistungsstarken Größen- und Positionierungskontext für deinen HTML-Inhalt, der auf die Größe des Containers reagiert und leicht angepasst werden kann. Wenn du deinen Inhalt in einer Spalte statt in einer Zeile haben möchtest, reicht eine einzige Eigenschaftsänderung aus, um dies zu erreichen. Für eine präzisere Steuerung der Positionierung und Größe gibt es das CSS-Grid-Layout, aber ich würde empfehlen, dass du dich zunächst auf das Flex-Display konzentrierst - es ist im Moment die beste Investition, die du in CSS machen kannst. Weitere Beispiele findest du im CSS-Tricks-Artikel über Flexboxen und in diesem praktischen Spickzettel.
Füllen der Platzhalter mit Inhalt
Nachdem unsere Inhaltsblöcke in HTML definiert und mit CSS positioniert wurden, verwendet eine moderne Datenvisualisierung JavaScript, um interaktive Diagramme, Menüs, Tabellen und Ähnliches zu erstellen. Es gibt viele Möglichkeiten, visuelle Inhalte (abgesehen von Bild- oder Multimedia-Tags) in deinem modernen Browser zu erstellen, die wichtigsten davon sind:
-
Skalierbare Vektorgrafiken (SVG) mit speziellen HTML-Tags
-
Zeichnen in einem 2D-Kontext
canvas
-
Zeichnen in einem 3D
canvas
WebGL-Kontext, der eine Teilmenge der OpenGL-Befehle erlaubt -
Mit modernem CSS Animationen, grafische Primitive und mehr erstellen
Da SVG die Sprache der Wahl für D3 ist, die in vielerlei Hinsicht die größte JavaScript-Datenbibliothek ist, wurden viele der coolen Webdatenvisualisierungen, die du gesehen hast, wie die der New York Times, mit SVG erstellt. Generell gilt: Wenn du nicht mit vielen (>1.000) beweglichen Elementen in deiner Visualisierung rechnest oder eine spezielle canvas
-basierte Bibliothek verwenden musst, ist SVG wahrscheinlich die beste Wahl.
Durch die Verwendung von Vektoren anstelle von Pixeln zur Darstellung von Primitiven erzeugt SVG in der Regel sauberere Grafiken, die reibungslos auf Skalierungsvorgänge reagieren. Außerdem kann es viel besser mit Text umgehen, was für viele Visualisierungen entscheidend ist. Ein weiterer entscheidender Vorteil von SVG ist, dass die Benutzerinteraktion (z. B. Mausbewegungen oder -klicks) direkt im Browser stattfindet, da sie Teil der Standard-DOM-Ereignisverarbeitung ist.12 Ein weiterer Pluspunkt ist, dass die grafischen Komponenten auf dem DOM aufgebaut sind und du sie mit den Entwicklungswerkzeugen deines Browsers überprüfen und anpassen kannst (siehe "Chrome DevTools"). Das kann die Fehlersuche und die Verbesserung deiner Visualisierungen viel einfacher machen, als wenn du versuchst, Fehler in der relativ schwarzen Box von canvas
zu finden.
canvas
Grafikkontexte kommen dann zum Tragen, wenn du über einfache grafische Primitive wie Kreise und Linien hinausgehen musst, z. B. wenn du Bilder wie PNGs und JPGs einbinden willst. canvas
ist in der Regel wesentlich leistungsfähiger als SVG, sodass alles mit vielen beweglichen Elementen13 besser auf einer Leinwand gerendert werden sollte. Wenn du wirklich ehrgeizig sein oder über 2D-Grafiken hinausgehen willst, kannst du sogar die unglaubliche Leistung moderner Grafikkarten nutzen, indem du eine besondere Form des canvas
Kontextes verwendest, den OpenGL-basierten WebGL-Kontext. Bedenke nur, dass die einfache Benutzerinteraktion mit SVG (z. B. das Klicken auf ein visuelles Element) oft manuell von den Mauskoordinaten abgeleitet werden muss, was die Sache noch komplizierter macht.
Die Datenvisualisierung für den Nobelpreis, die am Ende dieses Buches realisiert wird, wurde hauptsächlich mit D3 erstellt, daher stehen SVG-Grafiken im Mittelpunkt dieses Buches. Der sichere Umgang mit SVG ist eine Grundvoraussetzung für moderne webbasierte Datenvisualisierung, also lass uns eine kleine Einführung machen.
Skalierbare Vektorgrafiken
Alle SVG-Kreationen beginnen mit einem <svg>
Root-Tag. Alle grafischen Elemente wie Kreise und Linien sowie deren Gruppen werden in diesem Zweig des DOM-Baums definiert. Beispiel 4-3 zeigt einen kleinen SVG-Kontext, den wir in den kommenden Demonstrationen verwenden werden: ein hellgraues Rechteck mit der ID chart
. Wir fügen auch die D3-Bibliothek, die von d3js.org geladen wurde, und eine JavaScript-Datei script.js in den Projektordner ein.
Beispiel 4-3. Ein einfacher SVG-Kontext
<!DOCTYPE html>
<
meta
charset
=
"utf-8"
>
<!-- A few CSS style rules -->
<
style
>
svg
#chart
{
background
:
lightgray
;
}
</style>
<
svg
id
=
"chart"
width
=
"300"
height
=
"225"
>
</
svg
>
<!-- Third-party libraries and our JS script. -->
<
script
src
=
"http://d3js.org/d3.v7.min.js"
></
script
>
<
script
src
=
"script.js"
></
script
>
Jetzt, wo wir unsere kleine SVG-Leinwand haben, können wir anfangen, etwas zu zeichnen.
Das <g> Element
Wir können Formen innerhalb unseres <svg>
Elements gruppieren, indem wir das Element Gruppe <g>
verwenden. Wie wir in "Arbeiten mit Gruppen" sehen werden , können die Formen in einer Gruppe gemeinsam bearbeitet werden, z. B. durch Ändern ihrer Position, Skalierung oder Deckkraft.
Kreise
Bei der Erstellung von SVG-Visualisierungen - vom kleinen statischen Balkendiagramm bis hin zu interaktiven, geografischen Meisterwerken - werden Elemente aus einer relativ kleinen Gruppe von grafischen Primitiven wie Linien, Kreisen und den sehr mächtigen Pfaden zusammengesetzt. Jedes dieser Elemente hat sein eigenes DOM-Tag, das bei Änderungen aktualisiert wird.14 So ändern sich zum Beispiel die x- und y-Attribute, um alle Verschiebungen innerhalb des <svg>
oder des Gruppenkontextes (<g>
) widerzuspiegeln.
Fügen wir zur Veranschaulichung einen Kreis zu unserem <svg>
Kontext hinzu:
<
svg
id
=
"chart"
width
=
"300"
height
=
"225"
>
<
circle
r
=
"15"
cx
=
"100"
cy
=
"50"
></
circle
>
</
svg
>
Mit ein wenig CSS auf kannst du die Füllfarbe des Kreises bestimmen:
#chart
circle
{
fill
:
lightblue
}
So entsteht Abbildung 4-12. Beachte, dass die y-Koordinate von der Oberkante des Containers <svg>
'#chart'
aus gemessen wird, eine gängige grafische Konvention.
Sehen wir uns nun an, wie wir Stile auf SVG-Elemente anwenden können.
CSS-Stile anwenden
Der Kreis in Abbildung 4-12 ist mit Hilfe von CSS-Stylingregeln hellblau gefüllt :
#chart
circle
{
fill
:
lightblue
}
In modernen Browsern kannst du die meisten visuellen SVG-Stile mit CSS festlegen, darunter fill
, stroke
, stroke-width
und opacity
. Wenn wir also eine dicke, halbtransparente grüne Linie (mit der ID total
) haben wollen, können wir folgendes CSS verwenden:
#chart
line
#total
{
stroke
:
green
;
stroke-width
:
3px
;
opacity
:
0
.
5
;
}
Du kannst die Stile auch als Attribute der Tags festlegen, obwohl CSS im Allgemeinen vorzuziehen ist:
<
svg
>
<
circle
r
=
"15"
cx
=
"100"
cy
=
"50"
fill
=
"lightblue"
></
circle
>
</
svg
>
Tipp
Welche SVG-Eigenschaften mit CSS festgelegt werden können und welche nicht, ist eine Quelle für Verwirrung und eine Menge Probleme. In der SVG-Spezifikation wird zwischen Elementeigenschaften und Attributen unterschieden, wobei erstere eher unter den gültigen CSS-Stilen zu finden sind. Du kannst die gültigen CSS-Eigenschaften mit der Registerkarte Elemente und der Autovervollständigung von Chrome untersuchen. Sei außerdem auf einige Überraschungen vorbereitet. SVG-Text wird zum Beispiel durch die Eigenschaft fill
, nicht color
, eingefärbt.
Für fill
und stroke
gibt es verschiedene Farbkonventionen, die du verwenden kannst:
-
Benannte HTML-Farben, wie z. B. hellblau
-
Verwendung von HTML-Hex-Codes (#RRGGBB); zum Beispiel ist Weiß #FFFFFF
-
RGB-Werte; zum Beispiel: rot = rgb(255, 0, 0)
-
RGBA-Werte, wobei A ein Alphakanal (0-1) ist; zum Beispiel ist halbtransparentes Blau rgba(0, 0, 255, 0.5)
Du kannst nicht nur den Alphakanal der Farbe mit RGBA anpassen, sondern auch die SVG-Elemente mit ihrer Eigenschaft opacity
verblassen lassen. Die Deckkraft wird häufig in D3-Animationen verwendet.
Die Strichstärke wird standardmäßig in Pixeln gemessen, du kannst aber auch Punkte verwenden.
Linien, Rechtecke und Polygone
Wir fügen ein paar weitere Elemente zu unserem Diagramm hinzu, um Abbildung 4-13 zu erstellen.
Zunächst fügen wir mit dem Tag <line>
ein paar einfache Achsenlinien zu unserem Diagramm hinzu. Die Linienpositionen werden durch eine Startkoordinate (x1, y1) und eine Endkoordinate (x2, y2) definiert:
<
svg
>
<
line
x1
=
"20"
y1
=
"20"
x2
=
"20"
y2
=
"130"
></
line
>
<
line
x1
=
"20"
y1
=
"130"
x2
=
"280"
y2
=
"130"
></
line
>
</
svg
>
Außerdem fügen wir in der rechten oberen Ecke eine Dummy-Legende mit einem SVG-Rechteck ein. Rechtecke werden durch x- und y-Koordinaten relativ zu ihrem übergeordneten Container sowie durch eine Breite und Höhe definiert:
<
svg
>
<
rect
x
=
"240"
y
=
"5"
width
=
"55"
height
=
"30"
></
rect
>
</
svg
>
Du kannst unregelmäßige Polygone mit dem Tag <polygon>
erstellen, das eine Liste von Koordinatenpaaren benötigt. Lass uns eine Dreiecksmarkierung unten rechts in unserem Diagramm erstellen:
<
svg
>
<
polygon
points
=
"210,100, 230,100, 220,80"
></
polygon
>
</
svg
>
Wir werden die Elemente mit ein wenig CSS gestalten:
#chart
circle
{
fill
:
lightblue
}
#chart
line
{
stroke
:
#555555
;
stroke-width
:
2
}
#chart
rect
{
stroke
:
red
;
fill
:
white
}
#chart
polygon
{
fill
:
green
}
Nachdem wir nun ein paar grafische Primitive erstellt haben, wollen wir sehen, wie wir unserem Dummy-Diagramm Text hinzufügen können.
Text
Eine der größten Stärken von SVG gegenüber dem gerasterten canvas
Kontext ist der Umgang mit Text. Vektorbasierter Text sieht in der Regel viel klarer aus als seine verpixelten Gegenstücke und profitiert auch von einer sanften Skalierung. Außerdem kannst du wie bei jedem SVG-Element die Eigenschaften von Strich und Füllung anpassen.
Fügen wir unserem Dummy-Diagramm ein wenig Text hinzu: einen Titel und eine beschriftete y-Achse (siehe Abbildung 4-14).
Wir platzieren den Text mithilfe von x- und y-Koordinaten. Eine wichtige Eigenschaft ist die text-anchor
, die festlegt, wo der Text relativ zu seiner x-Position platziert wird. Die Optionen sind start
, middle
und end
; start
ist die Standardeinstellung.
Wir können die Eigenschaft text-anchor
verwenden, um unseren Diagrammtitel zu zentrieren. Wir setzen die x-Koordinaten auf die Hälfte der Diagrammbreite und setzen dann text-anchor
auf middle
:
<
svg
>
<
text
id
=
"title"
text-anchor
=
"middle"
x
=
"150"
y
=
"20"
>
A Dummy Chart</
text
>
</
svg
>
Wie bei allen SVG-Primitiven können wir Skalierungs- und Rotationstransformationen auf unseren Text anwenden. Um unsere y-Achse zu beschriften, müssen wir den Text in die Vertikale drehen(Beispiel 4-4). Standardmäßig erfolgt die Drehung im Uhrzeigersinn, also gegen den Uhrzeigersinn, um -90 Grad. Standardmäßig erfolgt die Drehung um den Punkt (0,0) des Element-Containers (<svg>
oder Gruppe <g>
). Wir wollen unseren Text um seine eigene Position drehen, also übersetzen wir zuerst den Drehpunkt mit den zusätzlichen Argumenten der Funktion rotate
. Außerdem müssen wir die Funktion text-anchor
auf das Ende der Zeichenfolge y axis label
setzen, um sie um ihren Endpunkt zu drehen.
Beispiel 4-4. Drehen von Text
<
svg
>
<
text
x
=
"20"
y
=
"20"
transform
=
"rotate(-90,20,20)"
text-anchor
=
"end"
dy
=
"0.71em"
>
y axis label</
text
>
</
svg
>
In Beispiel 4-4 verwenden wir das Attribut dy
, das zusammen mit dx
verwendet werden kann, um die Position des Textes fein einzustellen. In diesem Fall wollen wir den Text so verschieben, dass er sich bei einer Drehung gegen den Uhrzeigersinn rechts von der y-Achse befindet.
SVG-Textelemente können auch mit CSS gestylt werden. Hier setzen wir die font-family
des Diagramms auf sans-serif
und die font-size
auf 16px
und verwenden die title
ID, um sie etwas größer zu machen:
#chart
{
background
:
#eee
;
font-family
:
sans-serif
;
}
#chart
text
{
font-size
:
16px
}
#chart
text
#title
{
font-size
:
18px
}
Beachte, dass die text
Elemente font-family
und font-size
aus dem CSS des Diagramms erben; du musst kein text
Element angeben.
Pfade
Pfade sind das komplizierteste und leistungsstärkste SVG-Element. Sie ermöglichen die Erstellung von mehrzeiligen, mehrkurvigen Komponentenpfaden, die geschlossen und gefüllt werden können und so ziemlich jede gewünschte Form erzeugen. Ein einfaches Beispiel ist das Hinzufügen einer kleinen Diagrammlinie zu unserem Dummy-Diagramm, um Abbildung 4-15 zu erstellen.
Der rote Pfad in Abbildung 4-15 wird durch das folgende SVG erzeugt:
<
svg
>
<
path
d
=
"M20 130L60 70L110 100L160 45"
></
path
>
</
svg
>
Das d
Attribut von path
gibt die Reihe von Operationen an, die nötig sind, um die rote Linie zu erstellen. Lasst uns das aufschlüsseln:
-
"M20 130": Bewege dich zur Koordinate (20, 130)
-
"L60 70": Zeichne eine Linie nach (60, 70)
-
"L110 100": Zeichne eine Linie nach (110, 100)
-
"L160 45": Zeichne eine Linie nach (160, 45)
Du kannst dir d
als eine Reihe von Anweisungen an einen Stift vorstellen, sich zu einem Punkt zu bewegen, wobei M
den Stift von der Leinwand abhebt.
Es ist ein wenig CSS-Styling erforderlich. Beachte, dass fill
auf none
eingestellt ist; andernfalls würde der Pfad geschlossen, eine Linie von den End- zu den Anfangspunkten gezogen und alle eingeschlossenen Bereiche mit der Standardfarbe Schwarz gefüllt werden:
#chart
path
{
stroke
:
red
;
fill
:
none
}
Neben moveto 'M'
und lineto 'L'
verfügt der Pfad über eine Reihe weiterer Befehle zum Zeichnen von Bögen, Bézier-Kurven und Ähnlichem. SVG-Bögen und -Kurven werden häufig in der Dataviz-Arbeit verwendet, und viele der D3-Bibliotheken nutzen sie.15 Abbildung 4-16 zeigt einige elliptische SVG-Bögen, die mit dem folgenden Code erstellt wurden:
<
svg
id
=
"chart"
width
=
"300"
height
=
"150"
>
<
path
d
=
"M40 40 A30 40
0 0 1
80 80 A50 50 0 0 1 160 80 A30 30 0 0 1 190 80 "
>
<
/
svg
>
Nachdem du dich zur Position (40, 40) bewegt hast, zeichne einen elliptischen Bogen mit dem x-Radius 30, dem y-Radius 40 und dem Endpunkt (80, 80).
Das erste Flag (0) legt die Drehung der x-Achse fest, in diesem Fall die herkömmliche Null. Auf der Mozilla-Entwicklerseite findest du eine visuelle Demonstration. Die letzten beiden Flags (0, 1) sind
large-arc-flag
, das angibt, welcher Bogen der Ellipse verwendet werden soll, undsweep-flag
, das angibt, welche der beiden möglichen Ellipsen, die durch Start- und Endpunkt definiert sind, verwendet werden soll.
Die Schlüsselflags, die im elliptischen Bogen verwendet (large-arc-flag
und sweep-flag
), sind, wie die meisten geometrischen Dinge, besser zu demonstrieren als zu beschreiben. Abbildung 4-17 zeigt, wie es sich auswirkt, wenn du die Flags für dieselben relativen Anfangs- und Endpunkte änderst:
<
svg
id
=
"chart"
width
=
"300"
height
=
"150"
>
<
path
d
=
"M40 80
A30 40 0 0 1 80 80
A30 40 0 0 0 120 80
A30 40 0 1 0 160 80
A30 40 0 1 1 200 80
"
>
</
svg
>
Neben Linien und Bögen bietet das Element path
auch eine Reihe von Bézier-Kurven, darunter quadratische, kubische und Mischungen aus beiden. Mit ein bisschen Arbeit kannst du damit jeden beliebigen Linienverlauf erstellen. Auf SitePoint gibt es einen schönen Durchlauf mit guten Illustrationen.
Die endgültige Liste der path
Elemente und ihrer Argumente findest du in der Quelle des World Wide Web Consortium (W3C). Und eine schöne Zusammenfassung findest du in Jakob Jenkovs Einführung.
Skalieren und Drehen
Wie es sich für einen Vektor gehört, können alle SVG-Elemente durch geometrische Operationen transformiert werden. Die gebräuchlichsten sind rotate
, translate
und scale
, aber du kannst sie auch mit skewX
und skewY
schräg stellen oder die leistungsstarke, vielseitige Matrixtransformation verwenden.
Wir wollen die gängigsten Transformationen anhand einer Reihe identischer Rechtecke demonstrieren. Die umgewandelten Rechtecke in Abbildung 4-18 werden auf diese Weise erzeugt:
<
svg
id
=
"chart"
width
=
"300"
height
=
"150"
>
<
rect
width
=
"20"
height
=
"40"
transform
=
"translate(60, 55)"
fill
=
"blue"
/>
<
rect
width
=
"20"
height
=
"40"
transform
=
"translate(120, 55),
rotate(45)"
fill
=
"blue"
/>
<
rect
width
=
"20"
height
=
"40"
transform
=
"translate(180, 55),
scale(0.5)"
fill
=
"blue"
/>
<
rect
width
=
"20"
height
=
"40"
transform
=
"translate(240, 55),
rotate(45),scale(0.5)"
fill
=
"blue"
/>
</
svg
>
Hinweis
Die Reihenfolge, in der die Transformationen angewendet werden, ist wichtig. Bei einer Drehung um 45 Grad im Uhrzeigersinn und einer anschließenden Verschiebung entlang der x-Achse wird das Element nach Südosten verschoben, während es bei der umgekehrten Operation nach links verschoben und dann gedreht wird.
Arbeit mit Gruppen
Wenn du eine Visualisierung erstellst, ist es oft hilfreich, die visuellen Elemente zu gruppieren. Ein paar besondere Anwendungen sind:
-
Wenn du lokale Koordinatenschemata benötigst (z. B. wenn du eine Textbeschriftung für ein Symbol hast und seine Position relativ zum Symbol und nicht zum gesamten
<svg>
Canvas angeben möchtest). -
Wenn du eine Skalierungs- und/oder Rotationstransformation auf eine Teilmenge der visuellen Elemente anwenden willst.
SVG hat dafür das Tag group <g>
, das du dir wie eine Mini-Leinwand innerhalb der <svg>
Leinwand vorstellen kannst. Gruppen können Gruppen enthalten, wodurch sehr flexible geometrische Zuordnungen möglich sind.16
Beispiel 4-5 gruppiert Formen in der Mitte des Canvas, wodurch Abbildung 4-19 entsteht. Beachte, dass die Position der Elemente circle
, rect
und path
relativ zur übersetzten Gruppe ist.
Beispiel 4-5. SVG-Formen gruppieren
<
svg
id
=
"chart"
width
=
"300"
height
=
"150"
>
<
g
id
=
"shapes"
transform
=
"translate(150,75)"
>
<
circle
cx
=
"50"
cy
=
"0"
r
=
"25"
fill
=
"red"
/>
<
rect
x
=
"30"
y
=
"10"
width
=
"40"
height
=
"20"
fill
=
"blue"
/>
<
path
d
=
"M-20 -10L50 -10L10 60Z"
fill
=
"green"
/>
<
circle
r
=
"10"
fill
=
"yellow"
>
</
g
>
</
svg
>
Wenn wir nun eine Transformation auf die Gruppe anwenden, werden alle Formen innerhalb der Gruppe davon betroffen sein. Abbildung 4-20 zeigt das Ergebnis, wenn wir Abbildung 4-19 um den Faktor 0,75 skalieren und dann um 90 Grad drehen, indem wir das Attribut transformieren:
<
svg
id
=
"chart"
width
=
"300"
height
=
"150"
>
<
g
id
=
"shapes"
,
transform
=
"translate(150,75),scale(0.5),rotate(90)"
>
...</
svg
>
Schichtung und Transparenz
Die Reihenfolge, in der die SVG-Elemente in den DOM-Baum eingefügt werden, ist wichtig: Spätere Elemente haben Vorrang und überlagern andere. In Abbildung 4-19 zum Beispiel verdeckt der dreieckige Pfad den roten Kreis und das blaue Rechteck und wird wiederum vom gelben Kreis verdeckt.
Die Manipulation der DOM-Reihenfolge ist ein wichtiger Bestandteil von JavaScript-gestütztem Dataviz (z. B. kannst du mit der D3-Methode insert
ein SVG-Element vor ein bestehendes setzen).
Die Transparenz von Elementen kann mit dem Alphakanal der Farben von rgba(R,G,B,A)
oder mit der bequemeren Eigenschaft opacity
beeinflusst werden. Beide können mit CSS eingestellt werden. Bei überlagerten Elementen ist die Deckkraft kumulativ, wie das Farbdreieck in Abbildung 4-21 zeigt, das durch die folgende SVG erzeugt wird:
<
style
>
#chart
circle
{
opacity
:
0
.
33
}
</style>
<
svg
id
=
"chart"
width
=
"300"
height
=
"150"
>
<
g
transform
=
"translate(150, 75)"
>
<
circle
cx
=
"0"
cy
=
"-20"
r
=
"30"
fill
=
"red"
/>
<
circle
cx
=
"17.3"
cy
=
"10"
r
=
"30"
fill
=
"green"
/>
<
circle
cx
=
"-17.3"
cy
=
"10"
r
=
"30"
fill
=
"blue"
/>
</
g
>
</
svg
>
Die hier gezeigten SVG-Elemente wurden von Hand in HTML kodiert, aber bei Datenvisualisierungen werden sie fast immer programmatisch hinzugefügt. Der grundlegende D3-Arbeitsablauf besteht also darin, SVG-Elemente zu einer Visualisierung hinzuzufügen und ihre Attribute und Eigenschaften in Datendateien festzulegen.
SVG mit JavaScript
Die Tatsache, dass SVG-Grafiken durch DOM-Tags beschrieben werden, hat eine Reihe von Vorteilen gegenüber einer Blackbox wie dem <canvas>
Kontext. So können zum Beispiel auch Nicht-Programmierer Grafiken erstellen oder anpassen, und das ist ein Segen für die Fehlersuche.
Im Web-Dataviz werden so gut wie alle SVG-Elemente mit JavaScript erstellt, und zwar mit einer Bibliothek wie D3. Du kannst die Ergebnisse dieser Skripterstellung über die Registerkarte "Elemente" des Browsers überprüfen (siehe "Chrome DevTools"), was eine großartige Möglichkeit ist, um deine Arbeit zu verfeinern und zu debuggen (z. B. um einen ärgerlichen visuellen Fehler zu finden).
Als kleinen Vorgeschmack verwenden wir D3, um ein paar rote Kreise auf einer SVG-Leinwand zu verteilen. Die Abmessungen der Leinwand und der Kreise sind in einem data
Objekt enthalten, das an eine chartCircles
Funktion gesendet wird.
Wir verwenden einen kleinen HTML-Platzhalter für das Element <svg>
:
<!DOCTYPE html>
<
meta
charset
=
"utf-8"
>
<
style
>
#chart
{
background
:
lightgray
;
}
#chart
circle
{
fill
:
red
}
</style>
<
body
>
<
svg
id
=
"chart"
></
svg
>
<
script
src
=
"http://d3js.org/d3.v7.min.js"
></
script
>
<
script
src
=
"script.js"
></
script
>
</
body
>
Nachdem unser SVG-Element chart
platziert wurde, wird ein wenig D3 in der Datei script.js verwendet, um einige Daten in die verstreuten Kreise zu verwandeln (siehe Abbildung 4-22):
// script.js
var
chartCircles
=
function
(
data
)
{
var
chart
=
d3
.
select
(
'#chart'
)
;
// Set the chart height and width from data
chart
.
attr
(
'height'
,
data
.
height
)
.
attr
(
'width'
,
data
.
width
)
;
// Create some circles using the data
chart
.
selectAll
(
'circle'
)
.
data
(
data
.
circles
)
.
enter
(
)
.
append
(
'circle'
)
.
attr
(
'cx'
,
function
(
d
)
{
return
d
.
x
}
)
.
attr
(
'cy'
,
d
=>
d
.
y
)
.
attr
(
'r'
,
d
=>
d
.
r
)
;
}
;
var
data
=
{
width
:
300
,
height
:
150
,
circles
:
[
{
'x'
:
50
,
'y'
:
30
,
'r'
:
20
}
,
{
'x'
:
70
,
'y'
:
80
,
'r'
:
10
}
,
{
'x'
:
160
,
'y'
:
60
,
'r'
:
10
}
,
{
'x'
:
200
,
'y'
:
100
,
'r'
:
5
}
,
]
}
;
chartCircles
(
data
)
;
Dies ist die moderne pfeilbasierte anonyme Funktion, die der Langform in der vorherigen Zeile entspricht. D3 verwendet viele dieser Funktionen, um auf die Eigenschaften von gebundenen Datenobjekten zuzugreifen, daher ist diese neue Syntax ein großer Gewinn.
Wie D3 genau funktioniert, werden wir in Kapitel 17 sehen. Fassen wir erst einmal zusammen, was wir in diesem Kapitel gelernt haben.
Zusammenfassung
Dieses Kapitel vermittelte dem angehenden Datenvisualisierer die Grundkenntnisse der modernen Webentwicklung. Es wurde gezeigt, wie die verschiedenen Elemente einer Webseite (HTML, CSS-Stylesheets, JavaScript und Mediendateien) über HTTP übertragen und beim Empfang durch den Browser zu der Webseite zusammengesetzt werden, die der Nutzer sieht. Wir haben gesehen, wie Inhaltsblöcke mit HTML-Tags wie div
und p
beschrieben und dann mit CSS gestaltet und positioniert werden. Außerdem haben wir die Registerkarten "Elemente" und "Quellen" von Chrome kennengelernt, die die wichtigsten Entwicklungswerkzeuge des Browsers sind. Zum Schluss gab es noch eine kleine Einführung in SVG, die Sprache, in der die meisten modernen Webdatenvisualisierungen dargestellt werden. Diese Kenntnisse werden erweitert, wenn unsere Toolchain die D3-Visualisierung erreicht, und neue werden im Kontext eingeführt.
1 Es gibt einige interessante Alternativen zu vollwertigen Frameworks wie Alpine.js und htmx, die gut mit Python-Webservern wie Django und Flask zusammenarbeiten.
2 Ich trage die Narben, damit du es nicht musst.
3 Du kannst Stile in HTML-Tags mit dem style
-Attribut kodieren, aber das ist im Allgemeinen eine schlechte Praxis. Besser ist es, die in CSS definierten Klassen und IDs zu verwenden.
4 Wie von Mike Bostock demonstriert, mit einem Hut-Tipp an Paul Irish.
5 OpenGL (Open Graphics Language) und sein Web-Pendant WebGL sind plattformübergreifende APIs für das Rendern von 2D- und 3D-Vektorgrafiken (siehe die Wikipedia-Seite für Details).
6 Das ist nicht dasselbe wie das programmatische Festlegen von Stilen, das eine sehr mächtige Technik ist, mit der sich Stile an die Benutzerinteraktion anpassen lassen.
7 Dies gilt allgemein als schlechte Praxis und ist in der Regel ein Hinweis auf schlecht strukturiertes CSS. Verwende es mit äußerster Vorsicht, da es den Code-Entwicklern das Leben sehr schwer machen kann.
8 Diese werden in Douglas Crockfords berühmt-berüchtigtem JavaScript kurz und bündig erläutert : The Good Parts (O'Reilly).
9 Die Möglichkeit, mit Attributen zu spielen, ist besonders nützlich, wenn du versuchst, skalierbare Vektorgrafiken (SVG) zum Laufen zu bringen.
10 Logging ist eine gute Möglichkeit, den Datenfluss in deiner App zu verfolgen. Ich empfehle dir, hier einen konsequenten Ansatz zu verfolgen.
11 Hier ist ein Thread, der die vielen verschiedenen Lösungen für das Problem zeigt, von denen keine als elegant bezeichnet werden kann.
12 In einem canvas
Grafikkontext musst du dir in der Regel deine eigene Ereignisbehandlung ausdenken.
13 Diese Zahl ändert sich mit der Zeit und dem jeweiligen Browser, aber als grobe Faustregel gilt, dass SVG oft im niedrigen Tausenderbereich anfängt zu belasten.
14 Mit den Entwicklungswerkzeugen deines Browsers solltest du sehen können, wie die Tag-Attribute in Echtzeit aktualisiert werden.
15 Das Akkorddiagramm von Mike Bostock ist ein schönes Beispiel und verwendet die chord
Funktion von D3.
16 Eine Körpergruppe kann zum Beispiel eine Armgruppe enthalten, die eine Handgruppe enthalten kann, die wiederum Fingerelemente enthalten kann.
Get Datenvisualisierung mit Python und JavaScript, 2. now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.