Datenvisualisierung/Balken- und Kreisdiagramme

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche

Im Selfhtml-aktuell-Bereich stellte Lutz Tautenhahn mit dem JavaScript Diagram Builder 2002 eine Bibliothek zur Verfügung, mit der man einfache Diagramme erstellen konnte.

SVG eignet sich für Diagramme, da die fertigen Grafiken im Gegensatz zu Rastergrafiken (jpg) oder canvas aus einzelnen Elementen bestehen, denen Sie zusätzliche, mit CSS formatierbare, Textinformationen hinzufügen können.

Dieses Kapitel zeigt, wie Diagramme mit wenigen Grundformen gezeichnet werden können. Am Ende des Kapitels entwerfen wir einen bequemen Diagramm-Generator, der aus Einzeldaten Balken- oder Kreisdiagramme erstellt, die Sie dann auf Ihren Webseiten verwenden können.

Balkendiagramm

Das Balkendiagramm ist einer der häufigsten Diagrammtypen, das durch nicht aneinandergrenzende Säulen (Rechtecke mit bedeutungsloser Breite) die Häufigkeitsverteilung einer Variablen veranschaulicht. Balkendiagramme mit horizontalen Balken eignen sich besonders für Rangfolgen.[1]

Diagramme aus auf der x-Achse senkrecht stehenden Rechtecken nennt man Säulendiagramm. Sie eignen sich besonders, um wenige Ausprägungen zu veranschaulichen. Bei mehr Kategorien leidet die Anschaulichkeit und es sind Liniendiagramme zu bevorzugen. Auch im Falle von metrisch stetigen Daten eignet sich das Balkendiagramm nicht, es ist ein Histogramm zu bevorzugen.


Balkendiagramm - SVG-Markup ansehen …
<svg class="chart" width="450" height="300" aria-labelledby="chartinfo" viewBox="0 0 450 300">
	<desc id="chartinfo">Ein Diagramm unserer Ernte</desc>

	<g class="bar purple" tabindex="0">
		<rect width="40" height="45" />
		<text x="55" y="40">4 Pflaumen</text>
	</g>
	<g class="bar green" tabindex="0">
		<rect width="80" height="45" y="50"/>
		<text x="95" y="90">8 Kiwis</text>
	</g>
	<g class="bar yellow" tabindex="0">
		<rect width="150" height="45" y="100" />
		<text x="160" y="140">15 Zitronen</text>
	</g>
	<g class="bar orange" tabindex="0">
		<rect width="160" height="45" y="150" />
		<text x="170" y="190">16 Orangen</text>
	</g>
	<g class="bar red" tabindex="0">
		<rect width="230" height="45" y="200" />
		<text x="245" y="240">23 Äpfel</text>
	</g>
</svg>

Für jeden Datensatz wird nun ein g-Element angelegt. Dies beinhaltet je ein …

  • rect-Element. (Wenn Sie ein title-Element als Tooltipp einbauen wollen, erhält das rect-Element Start-und End-Tag.)
  • text-Element, das eine Legende enthält, die auch vorgelesen wird. Der Text ist über das g-Element semantisch mit dem dem rechteckigen Grafik-Objekt verbunden.

Jedes rect und text-Element enthält mehrere XML-Attribute, die Breite und Höhe, aber auch die Position mithilfe der x- und y-Koordinaten festlegen. (In diesem Beispiel kann auf das x-Attribut verzichtet werden, da alle Balken links starten!)

Säulendiagramm

Ein Säulendiagramm ist eigentlich das Gleiche in grün - einziger Unterschied sind die vertauschten Werte für width und height des rect-Elements.

Zeit für einige grundsätzliche Gedanken:

  • das SVG-Markup für beide Diagramme ist eigentlich identisch.
  • das Aussehen kann über CSS und entsprechende Regelsätze für die Geometrieattribute gesetzt werden.
  • nur die Werte an sich, also die Breiten beim Balken-, bzw die Höhen beim Säulendiagramm unterscheiden sich.
Säulendiagramm - SVG-Markup ansehen …
  <g class="bar" tabindex="0" style="--value: 4; --color: var(--purple);">
    <rect />
    <text x="-25"  y="250">4 Pflaumen</text>
  </g>
  <g class="bar" tabindex="0" style="--value: 8;--color: var(--green);">
    <rect />
    <text x="50" y="200" >8 Kiwis</text>
  </g>
  <g class="bar" tabindex="0" style="--value: 15; --color: var(--yellow);">
    <rect />
    <text x="70"  y="140" >15 Zitronen</text>
  </g>

Gegenüber dem oberen Balkendiagramm fällt auf, dass unser Markup viel weniger XML-Attribute hat.

Wichtigste Neuerung ist ein style-Attribut, in dem nun je ein --value- und ein --color-Wert gesetzt wird. Diese custom properties (CSS-Variablen) finden sich im CSS wieder:

custom properties berechnen unser Diagramm ansehen …
.bar > rect {
	width: 45px;
	height: calc(var(--value) * 10px); 
	x: calc(var(--n) * 50px);
	y: calc((30 - var(--value)) * 10px);	
}

.bar {
	fill: var(--color);
	stroke: var(--black);
	stroke-width: 1;
	transition: fill .3s ease;
	cursor: pointer;
}

.bar:hover,
.bar:focus {
  fill: var(--bgcolor);
}

Das rect-Element <rect /> verzichtet auf alle XML-Attribute. Mit CSS werden nun Werte berechnet für:

  • width - hier wird mit 45px (die px-Angaben sind im Firefox nötig!) noch eine Magic Number verwendet.
  • height: hier wird der --value-Wert verzehnfacht. Durch die Multiplikation mit einem Pixelwert entsteht ein für CSS gültiger Wert.
  • x: Jede Säule soll neben der anderen platziert werden. Dies ist leider noch nicht automagisch möglich, weshalb diese Werte im CSS mit .bar:nth-of-type(1) { --n: 1; } usw. von Hand gesetzt werden.
  • y: Anders als beim Balkendiagramm, bei dem alle Balken bei x=0 beginnen; müssen die Säulen, die ja alle am Ende des SVG bei y=300 enden, einen unterschiedlichen y-Wert für den oberen Rand haben. Dieser wird mit calc((30 - var(--value)) * 10px); berechnet - die Höhe des Rechtecks wird vom unteren Rand des SVG abgezogen. (Da das gesamte SVG die --value-Werte um das Zehnfache skaliert, wird hier die Magic Number 30 verwendet; besser wäre eine weitere CSS-Variable.)

Was (noch) nicht funktioniert: Das X-Attribut des text-Elements ist in SVG2 noch kein Präsentationsattribut und kann daher nicht über custom properties gesetzt werden.[2]


Warum sollte man die Werte nicht in einem Datenteil vorhalten und per JavaScript in die vorhandene Struktur dynamisch einfügen? Die Art des Diagramms könnte dann über eine Klasse gesetzt werden.

Bevor wir einen solchen Diagramm-Generator bauen, sollten wir uns noch den Aufbau eines Tortendiagramms anschauen:

Kreisdiagramm

Etwas anders zeigen sich Kreis- oder Tortendiagramme. Kreissektoren kann man gemeinhin mit einem Pfad-Element mit einem Kreisbogen in drei Zügen zeichnen.

Kreis-Sektor.svg

Zuerst wird der Zeichenstift mit M x,y auf den Startpunkt gelegt. Dann wird der Kreisbogen mit A für Arc gezogen und mit L 0,0 zum Mittelpunkt gezogen. Mit Z wird der Pfad geschlossen. Diese Pfadkommandos werden im d-Attribut notiert.

Kreisdiagramm - SVG-Markup ansehen …
<svg class="chart" width="420" height="150" aria-labelledby="chartinfo" >
  <desc id="chartinfo">Ein Diagramm unserer Ernte</desc>
  <defs>
  </defs>

<svg class="pie" width="200" height="200" viewBox="-100 -100 200 200" style="transform: rotate(-0.25turn)">     

  <circle id="background" r="50" />

  <g class="slice" tabindex="0">
    <path d="M 1 0 A 1 1 0 0 1 0.8 0.59 L 0 0 Z" />
    <text x="45" y="9.5">4 apples</text>
  </g>
</svg>
</svg>

Wie schon bei der SVG-Uhr und dem Pie Timer wird die viewBox am Mittelpunkt des Kreises ausgerichtet; enthält rechts aber noch Platz für eine Legende.

Als Hintergrund für unser Diagramm wird ein grauer Kreis gezeichnet.

Jeder Kreissektor enthält ein path- und ein text-Element. Hier verbietet sich ein symbol, da die Werte für das d-Attribut zu unterschiedlich sind.

Hervorhebung: Explodierte Darstellung

Bei :focus und :hover soll die Grundform optisch hervorgehoben werden. Eine Vergrößerung des Rands oder ein Schattenwurf wirkt besser, wenn der entsprechende Kreissektor etwas vom Mittelpunkt weg nach außen geschoben wird.

Diagramm-Generator

Unser Diagramm-Generator soll folgende Features haben:

  • manuelle Eingabe von Datensätzen
  • Importfunktion von CSV-Dateien aus Excel und Calc (dem OpenOffice-Pendant)
  • wahlweise Darstellung als Balken-, Säulen oder Kreisdiagramm
  • Exportfunktion des SVG-Markups (in Planung)

HTML-Markup

Die Eingaben und Einstellungen sollen über ein HTML-Formular realisiert werden. Als Inhalte der Menü-Elemente könnte man Unicode-Zeichen oder Emojis verwenden. Abgesehen von der mangelnden Zugänglichkeit besteht aber die Gefahr, dass die Zeichensätze nicht vorhanden sind. ◔ 📈 📊 [4]

Deshalb greifen wir auf die bewährten SVG-Grafiken als background-image zurück.


Beispiel Thomas Meinike, 2002


Fazit

Der Verzicht auf Bibliotheken erfordert einige Vorarbeit; mit einigen Tricks lassen sich so schnell barrierefreie und interaktive Diagramme erstellen.


Weblinks

  1. css-tricks: How to Make Charts with SVG 05.10.2015
  2. W3C: In SVG 2, the ‘text’ and ‘tspan’ ‘x’ and ‘y’ attributes are not presentation attributes and cannot be set via CSS. This may change in a future version of SVG.
  3. Simple pie charts with fallback, today (Lea Verou, 12.11.2020)
  4. https://emojiterra.com/de/buero/

Video-Tutorial: