Quiq::ChartJs::TimeSeries - Erzeuge Zeitreihen-Plot auf Basis von Chart.js
Quiq::Hash
use Quiq::ChartJs::TimeSeries;
my $ch = Quiq::ChartJs::TimeSeries->new( parameter => 'Windspeed', unit => 'm/s', points => \@rows, pointCallback => sub { my ($point,$i) = @_; my ($iso,$val) = split /\t/,$point,2; return [Quiq::Epoch->new($iso)->epoch*1000,$val]; }, );
my $h = Quiq::Html::Producer->new; my $html = Quiq::Html::Page->html($h, title => 'Chart.js testpage', load => [ js => $ch->cdnUrl('2.8.0'), ], body => $ch->html($h), );
(Folgendes Diagramm erscheint nur in HTML - außer auf meta::cpan, da der HTML-Code dort gestrippt wird. Es zeigt 720 Messwerte einer Windgeschwindigkeits-Messung)
Diese Klasse ist ein Perl-Wrapper für die Erzeugung für Zeitreihen-Plots auf Basis von Chart.js. Chart.js ist eine JavaScript-Bibliothek, die Diagramme auf einem HTML5 <canvas> darstellt. Chart.js bietet viele Möglichkeiten der Diagramm-Generierung. Die Einstellungen werden per Datenstruktur an den Chart-Konstruktor übergeben. Die Perl-Klasse ist darauf optimiert, einen speziellen Typ von Diagramm zu erzeugen: einen Zeitreihen-Plot. In einem Zeitreihen-Plot werden die Werte eines Parameters einer bestimmten Einheit (unit) gegen die Zeit geplottet. Die X-Achse ist die Zeitachse und die Y-Achse die Werteachse.
Zeitreihendaten werden als Array von Punkten übergeben:
data: { datasets: [{ type: 'line', data: [__POINTS__], }], }
Jeder Punkt in __POINTS__ ist ein JS-Objekt mit der Struktur:
{ t: __JAVASCRIPT_EPOCH__, y: __VALUE__, }
Hierbei ist __JAVASCRIPT_EPOCH__ der Zeitpunkt in Unix Epoch mal 1000 (also in Millisekunden-Auflösung).
Das <canvas>-Element wird in ein Parent-Element eingebettet, welches die Höhe __HEIGHT__ zugewiesen bekommt:
<div style="height: __HEIGHT__px"> <canvas id="__NAME__"></canvas> </div>
In den Chart-Optionen wird definiert:
options: { maintainAspectRatio: false, }
Damit ist das Diagramm fest auf __HEIGHT__ Pixel Höhe eingestellt, passt sich in der Breite aber dem zur Verfügung stehenden Raum an, auch nach einem Resize.
Eine Zeitachse bedarf einiger Konfigurationsarbeit, da die Defaults von Chart.js nicht besonders sinnvoll sind.
options: { scales: { xAxes: [{ type: 'time', ticks: { minRotation: 30, maxRotation: 60, }, time: { min: __T_MIN__, max: __T_MAX__, minUnit: 'second', displayFormats: { second: 'YYYY-MM-DD HH:mm:ss', minute: 'YYYY-MM-DD HH:mm', hour: 'YYYY-MM-DD HH', day: 'YYYY-MM-DD', week: 'YYYY-MM-DD', month: 'YYYY-MM', quarter: 'YYYY [Q]Q', year: 'YYYY', }, tooltipFormat: 'YYYY-MM-DD HH:mm:ss', }, }], }, }
Die X-Achse wird zu einer Zeitachse, wenn type: 'time' gesetzt ist.
type: 'time'
Eine Zeitachse wird speziell über die Unterstruktur time: ... konfiguriert.
time: ...
Anders als bei numerischen Achsen werden Minimum und Maximum dort und nicht in der Unterstruktur ticks: ... festgelegt.
ticks: ...
Werden min: und max: nicht oder auf undefined gesetzt, werden die Grenzen aus den Daten ermittelt.
min:
max:
undefined
Die Skalierung ergibt sich aus dem zur Verfügung stehenden Raum. Chart.js entscheidet sich für eine Auflösung aus den 9 Kategorien millisecond .. year.
millisecond
year
Die Tick-Beschriftung für die einzelnen Kategorien wird durch die Substuktur displayFormats: ... definiert. Diese sollte komplett durchdefiniert werden, da Defaults von Chart.js nicht besonders sinnvoll sind.
displayFormats: ...
Wie die Zeit im Tooltip dargestellt wird, definiert tooltipFormat:.
tooltipFormat:
Bei längeren Tick-Beschriftungen kann Chart.js diese gekippt darstellen. Da Zeitangaben länger sind, sollte die gekippte Darstellung forciert werden. Die gekippte Darstellung wird forciert, wenn minRotation: und maxRotation definiert werden. Dann unterbleibt eine gerade Beschriftung, denn ein Wechsel zwischen gerader und gekippter Beschriftung wirkt uneinheitlich.
minRotation:
maxRotation
data: { datasets: [{ fill: true; }], }
Die Perl-Klasse übergibt folgende Datenstruktur an den Konstruktor der JavaScript-Klasse Chart, wobei die Platzhalter __XXXX__ ersetzt werden, meist durch den Wert des betreffenden Klassen-Attributs xxxx. Die Liste aller Attribute siehe Abschnitt Attributes.
type: 'line', data: { datasets: [{ type: 'line', lineTension: __LINE_TENSION__, fill: true, borderColor: '__LINE_COLOR__', borderWidth: 1, pointRadius: __POINT_RADIUS__, data: [__POINTS__], }], }, options: { maintainAspectRatio: false, title: { display: true, text: '__TITLE__', fontSize: 16, fontStyle: 'normal', }, tooltips: { intersect: false, displayColors: false, backgroundColor: 'rgb(0,0,0,0.6)', titleMarginBottom: 2, callbacks: { label: function(tooltipItem,data) { return '__PARAMETER__: ' + tooltipItem.value + ' __UNIT__'; }, }, }, legend: { display: false, }, scales: { xAxes: [{ type: 'time', ticks: { minRotation: 30, maxRotation: 60, }, time: { min: __T_MIN__, max: __T_MAX__, minUnit: 'second', displayFormats: { second: 'YYYY-MM-DD HH:mm:ss', minute: 'YYYY-MM-DD HH:mm', hour: 'YYYY-MM-DD HH', day: 'YYYY-MM-DD', week: 'YYYY-MM-DD', month: 'YYYY-MM', quarter: 'YYYY [Q]Q', year: 'YYYY', }, tooltipFormat: 'YYYY-MM-DD HH:mm:ss', }, }], yAxes: [{ ticks: { min: __Y_MIN__, max: __Y_MAX__, }, scaleLabel: { display: true, labelString: '__UNIT__', }, }], }, }
https://www.chartjs.org
https://github.com/chartjs/Chart.js
Everything you need to know to create great looking charts using Chart.js
$ch = $class->new(@attVal);
Referenz auf Array der Zeit-Werte (in JavaScript-Epoch).
Referenz auf Array der Y-Werte (Weltkoordinaten).
Kleinster Wert auf der Zeitachse. Der Default 'undefined' bedeutet, dass der Wert aus den Daten ermittelt wird.
Größter Wert auf der Zeitachse. Der Default 'undefined' bedeutet, dass der Wert aus den Daten ermittelt wird.
Kleinster Wert auf der Y-Achse. Der Default 'undefined' bedeutet, dass der Wert aus den Daten ermittelt wird.
Größter Wert auf der Y-Achse. Der Default 'undefined' bedeutet, dass der Wert aus den Daten ermittelt wird.
Die Höhe des Diagramms. Eine Breite wird nicht angegeben, diese passt sich dem zur Verfügung stehenden Raum an.
Die Linienfarbe.
"Bezier curve tension of the line." Wenn 0, werden die Punkte gerade verbunden. Der Default 'undefined' bedeutet, dass der von Chart.js voreingestellte Wert 0.4 verwendet wird.
Name des Plot. Der Name wird als CSS-Id für die Zeichenfläche (Canvas) und als Variablenname für die Instanz verwendet.
Der Name des dargestellten Parameters.
Liste der Datenpunkte oder - alternativ - der Elemente, aus denen die Datenpunkte mittels der Methode pointCallback (s.u.) gewonnen werden. Ein Datenpunkt ist ein Array mit zwei numerischen Werten [$x, $y], wobei $x ein JavaScript Epoch-Wert (Unix Epoch in Millisekunden) ist und $y ein beliebiger Y-Wert.
Referenz auf eine Subroutine, die fr jedes Element der Liste @points einen Datenpunkt liefert, wie ihn die Klasse erwartet (s.o.). Ist kein rowCallback definiert, werden die Elemente aus @points unverändert verwendet.
Kennzeichne die Datenpunkte mit einem Kreis des Radius $n. 0 bedeutet, dass die Datenpunkte nicht gekennzeichnet werden.
Zeige das arithmetische Mittel an.
Zeige den Median an.
Titel, der über das Diagramm geschrieben wird.
Einheit des Parameters. Mit der Einheit wird die Y-Achse beschriftet und sie erscheint im Tooltip.
Objekt
Instantiiere ein Objekt der Klasse und liefere eine Referenz auf dieses Objekt zurück.
$url = $ch->cdnUrl($version);
URL (String)
Liefere einen CDN URL für Chart.js in der Version $version.
$html = $ch->html($h);
HTML-Code (String)
Liefere den HTML-Code der Chart-Instanz.
$js = $ch->js;
JavaScript-Code (String)
Liefere den JavaScript-Code der Chart-Instanz.
minRotation, maxRotation auf einen festen Wert einstellen, z.B. 45, damit alle Diagramme gleich aussehen (?)
Höhe des Diagramms per JS setzen statt im HTML?
JS-Code in Ready-Handler setzen
Daten per Ajax laden
Tick-Label der Zeitachse berechnen, so dass wiederholende Teile ausgeblendet sind
Zoomen in die Daten. Wie? Plugin?
1.204
Frank Seitz, http://fseitz.de/
Copyright (C) 2022 Frank Seitz
This code is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
To install Quiq, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Quiq
CPAN shell
perl -MCPAN -e shell install Quiq
For more information on module installation, please visit the detailed CPAN module installation guide.