Barrierefreie und interaktive Diagramme mit Angular und Highcharts

Säulen- und Liniendiagramme müssen nicht langweilig und statisch sein. Moderne JavaScript-Bibliotheken ermöglichen das Erstellen von animierten, interaktiven und barrierefreien Diagrammen.

Ich bin ein großer Fan von Highcharts, einer JavaScript-Bibliothek für SVG-basierte Diagramme. Es gibt mehrere Bibliotheken, welche Highcharts in die auf Komponenten basierte Architektur von React und Angular integrieren. In meiner Demo-App zeige ich dir, wie du auch das Event-Handling von Highcharts mit Angular-Komponenten verbinden kannst.

Ein Kugelschreiber zeigt auf ein Blatt Papier mit Säulen- und Liniendiagrammen. Foto: © Lukas / pexels.com

Demo App: Auswahl eines Tabs, wenn eine Säule im Diagramm geklickt wird

Meine Demo-App basiert auf Angular 13, Highcharts und highcharts-angular, einer minimalen Bibliothek, die Highcharts für Angular kapselt. Ein Säulendiagramm zeigt die Nutzung primärer Desktop-Screenreader. Mehrere Tabs bieten zusätzliche Informationen zu den Screenreadern. Wenn eine Säule im Diagramm geklickt wird, wird das zugehörige Tab ausgewählt. Probiere es aus:

Also, wie habe ich das geschafft?

Schritt 1: Diagramm-Optionen definieren und das Diagramm rendern

Die Highcharts-Bibliothek ist extrem praktisch. Du definierst einfach deine Diagramm-Optionen und Highcharts erledigt den Rest. In meiner Demo-App habe ich ein Diagramm mit zwei Säulenreihen definiert:

export const EXAMPLE_CHART: Highcharts.Options = { series: [ { data: [ [ScreenreaderName.Jaws, 53.7], [ScreenreaderName.Nvda, 30.7], [ScreenreaderName.VoiceOver, 6.5], [ScreenreaderName.ZoomTextFusion, 4.7], [ScreenreaderName.Other, 4.4], ], name: 'Worldwide', type: 'column', }, { data: [ [ScreenreaderName.Jaws, 40.2], [ScreenreaderName.Nvda, 41.6], ], name: 'Europe', type: 'column', } ], subtitle: { text: '', }, title: { text: 'Primary desktop/laptop screen reader (2021)', }, xAxis: { categories: [ ScreenreaderName.Jaws, ScreenreaderName.Nvda, ScreenreaderName.VoiceOver, ScreenreaderName.ZoomTextFusion, ScreenreaderName.Other, ], }, yAxis: { title: { text: 'Usage in percent', } } }

Dann stelle ich in der AppComponent die Diagramm-Optionen und die Highcharts-Bibliothek bereit:

import * as Highcharts from 'highcharts'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'] }) export class AppComponent { public chartOptions = EXAMPLE_CHART; public highchartsLib = Highcharts; }

Als letztes übergebe ich im HTML-Template die Bibliothek und die Diagramm-Optionen an die <highcharts-chart> Komponente:

<highcharts-chart [Highcharts]="highchartsLib" [options]="chartOptions" (chartInstance)="addCustomPropertiesToChart($event)" ></highcharts-chart>

Schritt 2: Benutzerdefinierte Eigenschaften der Diagramm-Instanz hinzufügen

Die <highcharts-chart> Komponente stellt die Ausgabe-Eigenschaft chartInstance bereit. Über diese erhalten wir die Instanz des Diagramms, nachdem dieses erstellt wurde. Dieser Instanz fügen wir eine Funktion als benutzerdefinierte Eigenschaft hinzu:

public addCustomPropertiesToChart( chartInstance: Highcharts.Chart ): void { (chartInstance as MyExampleChart) .onSeriesPointClick = (name) => this.selectScreenreaderTab(name); }

Das Chart Interface von Highcharts kennt keine Methode namens onSeriesPointClick. Deshalb definieren wir ein eigenes Interface, welches diese benutzerdefinierte Eigenschaft hinzufügt:

export interface MyExampleChart extends Highcharts.Chart { onSeriesPointClick: (name: ScreenreaderName) => void; }

Nun bietet unsere Diagramm-Instanz eine Methode an, die direkt mit der Eltern-Komponente des Diagramms verknüpft ist. Ein Event Handler des Diagramms kann diese Methode aufrufen, um zum Beispiel zu kommunizieren, dass ein konkreter Datenpunkt angeklickt worden ist.

Schritt 3: Die benutzerdefinierte Methode in einem Event Handler aufrufen

Mithilfe der Eigenschaft plotOptions in den Diagramm-Optionen definieren wir einen Click Event Handler für alle Datenpunkte:

click: function(this) { const chart = this.series.chart as MyExampleChart; chart.onSeriesPointClick(this.name as ScreenreaderName); }

Der Event Handler holt sich die Diagramm-Instanz, die unserem benutzerdefinierten Interface MyExampleChart entspricht. Nun können wir die benutzerdefinierte Methode onSeriesPointClick aufrufen und somit das zum Datenpunkt gehörige Screenreader-Tab in der Applikation auswählen.

Schritt 4: Mache dein Diagramm barrierefrei

Highcharts bietet großartige Features für mehr Barrierefreiheit an. Du kannst etwa Farben als Musterfüllungen definieren. Das hilft besonders Menschen mit eingeschränktem Farbsehen. Diese profitieren davon, wenn durch Farbe vermittelte Informationen auch auf andere visuelle Weise verfügbar sind.

color: { pattern: { backgroundColor: '#96dbe7', color: '#080e38', height: 10, path: 'M 0 0 L 10 10 M 9 - 1 L 11 1 M - 1 9 L 1 11', width: 10, } },

Mithilfe der Eigenschaft linkedDescription kannst du das Diagramm mit einem HTML-Element verknüpfen, das den Inhalt des Diagramms beschreibt:

accessibility: { enabled: true, linkedDescription: '#highcharts-description-1', },

Fazit

Kombiniere Angular und Highcharts, um wunderschöne, barrierefreie Diagramme mit minimalem Aufwand zu gestalten. Mithilfe von benutzerdefinierten Eigenschaften kannst du das Event Handling von Highcharts mit der auf Komponenten basierten Architektur von Angular verbinden, um noch interaktivere Nutzer:innen-Erlebnisse zu erschaffen.

Ressourcen

Erstellt am