Diagramm (erweitert)
Mehrere Datenpunkte in einem Diagramm — pro Serie eigener Typ (Linie, Fläche, Balken, Punkte), Farbe und Y-Achse. Auf ECharts basierend, mit zwei Y-Achsen, Legende, Vergleichs- und Gauge-Modus sowie einem JSON-Override für ECharts-Feineinstellungen.
Fertige Beispiele mit Bild und Widget-Export zum Importieren: Beispiel-Galerie
Datenpunkt
Das Widget hat keinen eigenen Haupt-Datenpunkt — jede Serie trägt ihren Datenpunkt selbst.
| Feld | Pflicht | Typ | |
|---|---|---|---|
echartSeries[].datapointId | ja | number · string | Datenpunkt der Serie (string im JSON-Modus) |
echartSeries[].historyInstance | nein | — | History-Adapter; leer = Live-Daten |
echartSeries[].source | nein | — | history (Standard) · json — je Serie |
Serien konfigurieren
Modus, Zahlenformat und Serien liegen im Dialog Datenpunkte verwalten (Button im Optionen-Panel). Seine Tabs stehen in der Reihenfolge der Entscheidungen: Modus → Zahlenformat → Serien → Werte; was für alle Serien gilt, steht vor ihnen. Im Tab „Serien“ links die Serienliste, rechts die komplette Konfiguration der ausgewählten Serie. Die übrigen globalen Einstellungen (Achsen, Legende, Zeitraum, Einheiten) bleiben im Optionen-Panel.
Der Modus ändert die Serien nicht: er entscheidet nur, wie gelesen wird. Im Modus json liest jede Serie ihren Datenpunktwert, unabhängig von ihrer eingestellten Datenquelle — ein Wechsel in einen anderen Modus und zurück lässt die Serien also unverändert.
| Im Dialog | Im Optionen-Panel |
|---|---|
| Modus | Darstellung, Achsen, Gitter |
| Zahlenformat (Dezimalstellen, 1000er) | Legende, aktueller Wert |
| Serien anlegen, sortieren, löschen | Zeitraum, Tages-Navigation |
| Datenpunkt je Serie | Einheiten, Achsengrenzen |
| Datenquelle, Typ, Y-Achse, Stapeln | JSON-Override |
| Farbe + Zahlenformat je Serie (eine Zeile) | |
| JSON-Quelle, Verlauf/Aggregation | |
| Werte-Vorgabe, Anteil am Stapel |
Der Tab Zahlenformat ist die Vorgabe für alle Serien (decimals, numberFormat); jede Serie überschreibt sie im Tab „Serien“ mit echartSeries[].decimals / echartSeries[].numberFormat. Der Knopf Diagramm in der Serie schaltet die Überschreibung wieder ab. Achsenbeschriftungen und die Stapelsumme folgen immer dem Diagramm-Format — sie gehören zu mehreren Serien gleichzeitig.
Der Tab Werte trägt die beiden Einstellungen, die nur neben den Serien Sinn ergeben: echartShowValues ist die Vorgabe, die jede Serie als „Auto (…)" anzeigt, und echartShowStackPercent erscheint erst, wenn eine Serie stapelt — was im selben Dialog eingestellt wird.
Layouts
Das Diagramm-Verhalten steuert die Option echartMode; das Widget-Layout gauge schaltet auf eine Tacho-Anzeige.
Timeseries
Zeitachsen-Diagramm mit allen Serien über die Zeit — Standard.
Je Serie ist die Datenquelle wählbar (echartSeries[].source), Verlauf und JSON-Datenpunkt lassen sich also mischen — z. B. Messwerte aus der InfluxDB plus Solarprognose aus einem JSON:
| Serie | source | |
|---|---|---|
| Messwerte | history | Zeitraum-Umschalter und Tages-Navigation wirken nur auf diese |
| Prognose, Fahrplan | json | ganzes Array aus dem Datenpunkt; die Beschriftung ist der Zeitpunkt |
Voraussetzung für die JSON-Serie: die Beschriftungen sind Zeitstempel (Epoch in ms oder s, ISO-Datum). Einträge ohne gültigen Zeitstempel entfallen — der Editor sagt es, sobald er den Datenpunkt gelesen hat. Für Kategorie-Beschriftungen (Mo, Di, 01) den Modus JSON („Kategorien (JSON)“ im Editor) wählen. Der Editor meldet das direkt beim Datenpunkt und nennt die Beschriftung; lesen alle Serien aus JSON, stellt ein Button dort auf „Kategorien (JSON)“ um. Im Dashboard nennt das leere Diagramm denselben Grund statt „Keine Daten“.
[
{ "ts": "1785362400000", "val": 0 },
{ "ts": "1785366000000", "val": 2.5 }
]Reicht die JSON-Serie in die Zukunft, dehnt sich die Zeitachse mit — die Verlaufsdaten enden bei „jetzt", die Prognose läuft weiter. Felder, Pfade und Achsengrenzen wie unter JSON-Quelle.
Comparison
Kategorisches Balkendiagramm — je Serie ein Balken mit ihrem aktuellen Wert.
Beschriftung aus Datenpunkt
Der Serienname versteht Bindings — z. B. eine 5-Tage-Prognose, bei der jeder Balken das Datum seines Tages trägt:
| Serie | Datenpunkt | Name |
|---|---|---|
| 1 | …forecast.day1.energy | {…forecast.day1.date;date(DD.MM.)} |
| 2 | …forecast.day2.energy | Di {…forecast.day2.date;date(DD.MM.)} |
Gilt in allen Modi (Legende, Tooltip, Zeitraum-Kennzahl). Der Knopf neben dem Namensfeld fügt einen Datenpunkt als {id} ein. Bis der Datenpunkt einen Wert hat, steht dort Serie N.
JSON
Im Editor Kategorien (JSON). Kategorisches Diagramm aus einem JSON-Datenpunkt statt aus einem History-Adapter — die Labels bilden die X-Achse, in der Reihenfolge des Arrays. Kein Zeitraum-Umschalter, keine Tages-Navigation. Sind die Labels Zeitstempel, gehört die Serie in die Timeseries mit source: json.
Erwartetes Format im Datenpunkt (String oder Objekt):
[
{ "label": "12:00", "value": "0.5" },
{ "label": "13:00", "value": "1.2" }
]Werte dürfen Strings sein und werden in Zahlen gewandelt; Einträge ohne gültige Zahl entfallen. Mehrere Serien werden über gleiche Labels ausgerichtet, fehlende Labels lassen die Linie brechen.
Feldnamen müssen nicht konfiguriert werden. Der Editor liest den Datenpunkt aus, erkennt Beschriftungs- und Wertfeld selbst und bietet die tatsächlich vorhandenen Schlüssel in zwei Auswahlfeldern an — inklusive Vorschau des ersten Eintrags. Bekannte Namen (label/value, ts/val, x/y, time/amount, name/count) werden bevorzugt, sonst gilt: erstes Feld = Beschriftung, erstes numerisches Feld = Wert. jsonLabelKey/jsonValueKey sind nur nötig, wenn die Erkennung danebenliegt.
Sind die Beschriftungen Zeitstempel, schaltet echartJsonTimeAxis auf eine echte Zeitachse mit korrekten Abständen:
[
{ "ts": "1785362400000", "val": 0 },
{ "ts": "1785366000000", "val": 2.5 }
]ts und val erkennt der Editor selbst; erkennt er zusätzlich, dass alle Beschriftungen Zeitstempel sind, schaltet er die Zeitachse einmalig von allein ein. Akzeptiert werden Epoch in Millisekunden, Epoch in Sekunden und ISO-Datumsstrings; Einträge ohne gültigen Zeitstempel entfallen. Reine Jahreszahlen wie 2024 gelten nicht als Zeitstempel — dafür die Option ausgeschaltet lassen.
Neben den Daten darf der Datenpunkt die Grenzen der Y-Achse tragen — dann skaliert die Achse nach dem Skript statt nach den Daten. Dazu echartJsonAxisBounds einschalten:
{
"axis": { "min": 0, "max": 100 },
"data": [
{ "label": "12:00", "value": 42 },
{ "label": "13:00", "value": 87 }
]
}Den Block sucht das Widget selbst: min/max direkt neben den Daten, in einem Block wie axis, yAxis, scale, range, limits oder in einem beliebigen anderen Unterobjekt. yMin/yMax, minValue/maxValue und axisMin/axisMax gelten ebenso, Zahlen als String auch. Eine der beiden Grenzen genügt — die andere bleibt automatisch. jsonAxisPath legt den Block fest, wenn mehrere in Frage kommen.
Ist das ganze JSON in ein Array gepackt — z. B. weil ein Skript seine bestehende Liste nur umhüllt hat —, findet das Widget Daten und Block trotzdem, mit oder ohne Pfad:
[
{
"yAxis": { "yMin": 0, "yMax": 20 },
"data": [{ "ts": 1786990830338, "value": 10 }]
}
]Stehen die beiden Grenzen verdreht im JSON (yMin größer als yMax), werden sie getauscht.
Dieselben Beispiele stehen im Serien-Editor: „Welche JSON-Formen funktionieren?" direkt unter dem Datenpunkt — bei einer neuen Serie aufgeklappt, bis der Datenpunkt gelesen ist —, „Wo dürfen die Grenzen stehen?" unter dem min/max-Pfad. Findet der eingetragene Pfad kein Array, nennt der Editor die Pfade, die eines enthalten.
Die Grenzen gelten für die Achse der jeweiligen Serie (yAxisIndex) und werden wie deren Werte umgerechnet (valueFactor/valueOffset). Ohne Block bleibt die Skalierung, wie sie konfiguriert ist.
Gauge
Tacho-Anzeige des aktuellen Werts der ersten Serie (Widget-Layout gauge). Skala: echartLeftMin/echartLeftMax.
Custom
Frei in einer Zellenmatrix platzieren — siehe Custom-Layout.
| Zelle | Inhalt |
|---|---|
Aktion / Icon → Diagramm (chart) | die Diagrammfläche samt Zeitraum-Chips und Blättern, ohne Titel |
Diagramm (widget, embedWidgetId) | ein anderes Diagramm-Widget aus einem Tab oder einer Popup-Ansicht |
Einstellungen
Alle Optionen werden im Editor unter Widget bearbeiten gesetzt.

Anzeige
| Option | Standard | |
|---|---|---|
showTitle | true | Titel anzeigen |
showIcon | true | Icon anzeigen |
icon | BarChart2 | Lucide-Icon |
iconSize | 20 | px |
titleAlign | left | left · center · right |
echartShowCurrent | true | aktuelle Werte in der Kopfzeile anzeigen |
echartCurrentFrom | last | welcher Punkt der „aktuelle“ ist: last (rechts) · first (links, für Reihen mit neuestem Wert vorn) |
echartCurrentAlign | right | Position der Anzeige in der Kopfzeile: right · left |
echartShowValues | im Vergleichs-Modus true, sonst false | Werte am Datenpunkt anzeigen (Format und Einheit wie im Tooltip; überlappende Beschriftungen entfallen) — Vorgabe für alle Serien, je Serie überschreibbar |
echartShowStackPercent | false | prozentualen Anteil an der Stapelsumme anzeigen (nur gestapelte Serien, siehe Stapeln) |
echartShowLegend | im Vergleichs-Modus false, sonst true | Legende anzeigen; Klick auf einen Eintrag blendet die Serie aus (im Vergleichs-Modus: den Balken) |
echartPeriodPlacement | legend | wo die Zeitraum-Kennzahl steht: legend (hinter dem Legendeneintrag) · row (eigene Zeile über dem Diagramm); ohne Legende immer row |
echartAnimation | true | Aufbau- und Übergangsanimation; aus, wenn Werte, Achsen oder Zeitraum ständig wechseln |
echartNowLine | false | senkrechte Linie bei der aktuellen Uhrzeit, wenn „jetzt“ im gezeigten Zeitraum liegt (Tagesansicht heute, Prognosen); Kategorie-Achse: echartNowLineMatch |
echartNowLineMatch | leer | JSON-Modus ohne Zeitachse: Linie bei der ersten Kategorie, deren Beschriftung diesen Text enthält (z. B. jetzt) |
echartNowLineColor | #ef4444 | Farbe der Jetzt-Linie |
echartNowLineLabel | leer | Beschriftung an der Jetzt-Linie, z. B. jetzt oder jetzt {HH:mm} ({…} = Datumsmuster der aktuellen Zeit); leer = keine |
echartNowLinePosition | top | Beschriftung oben (top) oder unten (bottom) an der Linie |
decimals | globale Einstellung | Nachkommastellen in Tooltip, Wert-Labels, aktuellem Wert und Achsenbeschriftung — Vorgabe für alle Serien, je Serie überschreibbar |
numberFormat | globale Einstellung | 1000er-Trennzeichen: plain · de · en · space · apostrophe — Vorgabe für alle Serien, je Serie überschreibbar |
Serien
| Option | Standard | |
|---|---|---|
echartMode | timeseries | timeseries · comparison · json |
echartSeries | [] | Liste der Serien (siehe unten) |
echartSeries[].name | Serie N | Name in Legende/Tooltip, im Vergleichs-Modus Balkenbeschriftung — Bindings erlaubt |
echartSeries[].chartType | line | line · area · bar · scatter |
echartSeries[].color | Palette | Linien-/Balkenfarbe: var(--accent-green) wie überall sonst (das Widget löst das Token auf, bevor es ans Canvas geht — das Diagramm folgt also dem Theme) oder ein fester Wert wie #eab308. Ohne Angabe die nächste Farbe der Palette. |
echartSeries[].yAxisIndex | 0 | 0 = links, 1 = rechte Y-Achse; ab 2 nur mit eigenen Achsen in echartJsonExtra (vollständiges yAxis-Array) |
echartSeries[].unit | — | Einheit der Serie in Tooltip, Werten und Aktuell-Anzeige — vor der Einheit ihrer Achse; "" = ohne Einheit |
echartSeries[].smooth | true | geglättete Linie (nur Linie/Fläche) |
echartSeries[].step | boolescher DP: true, sonst false | Treppenkurve — jeder Wert gilt bis zum nächsten (nur Linie/Fläche, ersetzt smooth) |
echartSeries[].valueLabels | common.states des DP | Texte statt Zahlen, z. B. 0=An; 1=Aus — im Tooltip, an den Werten und im aktuellen Wert; an der Achse, wenn alle Serien darauf dieselben Texte haben. Leer = Texte aus common.states (nicht bei ƒx-Umrechnung) |
echartSeries[].stack | false | Serie auf die anderen gestapelten Serien derselben Y-Achse addieren (siehe unten) |
echartSeries[].aggregate | average | average · minmax · max · min · total · delta · none — minmax erhält echte Extremwerte mit echten Zeitstempeln (empfohlen für änderungsbasiert geloggte Zähler wie Tagesregen), delta siehe unten |
echartSeries[].deltaBucket | hour | auto · hour · day · week · month · year — Zeiteinheit für aggregate: delta |
echartSeries[].timeShift | 0 | „Werte von früher zeigen“: die Serie zeigt die Werte von vor n Einheiten, eingezeichnet über dem aktuellen Zeitraum (siehe unten) |
echartSeries[].timeShiftUnit | year | hour · day · week · month · year — Einheit von timeShift |
echartSeries[].periodValue | leer | Zeitraum-Kennzahl: consumption · change · min · max · average — eine Zahl über den gezeigten Zeitraum |
echartSeries[].lineWidth | 2 | Linienstärke 0–4, 0 = keine Linie (nur Linie/Fläche) |
echartSeries[].stackOutline | false | Kontur eines gestapelten Bandes zeichnen (nur gestapelte Fläche) |
echartSeries[].areaOpacity | Auto | Deckkraft der Fläche in Prozent 10–100 (nur Fläche); Auto = gestapelt 100 %, einzeln 20 % |
echartSeries[].showValues | Auto | Werte am Datenpunkt dieser Serie: Auto folgt der Widget-Einstellung, An und Aus überschreiben sie |
echartSeries[].labelInterval | 1 | nur jeden n-ten Wert beschriften (1–10), vom neuesten Punkt aus gezählt — nicht im Vergleichs-Modus |
echartSeries[].decimals | Diagramm | Nachkommastellen dieser Serie; leer = Diagramm-Einstellung (decimals) |
echartSeries[].numberFormat | Diagramm | 1000er-Trennzeichen dieser Serie; leer = Diagramm-Einstellung (numberFormat) |
Stapeln
Stapeln je Serie: die Serie wird auf die anderen gestapelten Serien derselben Y-Achse addiert — z. B. Speicher-Entladung 150 W + Netzbezug 50 W als Bänder, die zusammen den Hausverbrauch von 200 W ergeben. Für Linie, Fläche und Balken.
- Linke und rechte Y-Achse stapeln getrennt — Werte zweier verschieden skalierter Achsen zu addieren ergäbe keine sinnvolle Zahl.
- Eine gestapelte Achse beginnt bei 0, damit die Bandhöhen den Werten entsprechen. Ein gesetztes
Minhat weiterhin Vorrang. - Der Tooltip zeigt weiter den Einzelwert jeder Serie und zusätzlich eine Zeile
Σ Summe. Prozentualen Anteil am Stapel anzeigen(Abschnitt „Anzeige“, erscheint sobald eine Serie stapelt) schreibt den Anteil an der Stapelsumme desselben Datenpunkts an den Balken bzw. Punkt und in den Tooltip. Zusammen mitWerte am Datenpunkt anzeigensteht er in Klammern hinter dem Wert, ohne diese Option allein. Anteil =|Wert| / Σ|Werte des Stapels|— mit Betrag, damit die Anteile auch bei einem negativen Mitglied 100 % ergeben. Kein Anteil bei Stapeln mit nur einer Serie je Achse, an Stellen ohne Wert und bei einer Stapelsumme von 0. Anzeige in ganzen Prozent, unter 10 % mit einer Nachkommastelle.- Gestapelte Flächen sind deckend gefüllt: das Band zeigt genau die gewählte Farbe, wie Legende und Farbwähler. Bänder liegen übereinander statt voreinander, Transparenz würde die Farbe nur mit dem Hintergrund mischen. Weicher per
Flächen-Deckkraftje Serie, unter der Linienstärke. - Gestapelte Flächen werden ohne Kontur gezeichnet: die Kontur läge auf der Oberkante des Bandes darunter, eine Serie mit Wert 0 sähe also aus wie eine Linie ohne Fläche. Bei Bedarf per
Bandkonturje Serie wieder einschalten — der Wert 0 bleibt in Tooltip undΣ Summeerhalten. - Serien mit eigenen Zeitstempeln werden vorher auf eine gemeinsame Zeitachse gebracht (jede Serie behält ihren letzten gemeldeten Wert bis zur nächsten Messung). Vor dem ersten Datensatz einer Serie bleibt das Band offen, statt eine 0 zu erfinden.
Werte-Transformation
ƒx-Button neben dem Datenpunkt-Feld der Serie. Reine Anzeige-Umrechnung Wert × Faktor + Offset, je Serie einzeln — der Datenpunkt und seine History bleiben unverändert. Gilt für Kurve, Tooltip, Legende und den aktuellen Wert; ein Preset (z. B. W → kW) setzt gleich die Einheit der Y-Achse, an der die Serie hängt.
| Option | Standard | |
|---|---|---|
echartSeries[].valueTransform | — | Preset-Id oder custom |
echartSeries[].valueFactor | 1 | Multiplikator |
echartSeries[].valueOffset | 0 | Summand |
Bei aggregate: delta wird vor der Differenzbildung umgerechnet: der Faktor wirkt auf den Verbrauch, der Offset fällt heraus (die Differenz zweier verschobener Zählerstände ist dieselbe).
Skala der Y-Achse
| Serien auf der Achse | Skala |
|---|---|
Balken, gestapelt oder delta | enthält immer die 0 — die Balkenlänge ist der Wert, die Nulllinie bleibt sichtbar |
| nur Linie / Fläche / Punkte | passt sich dem Wertebereich an (eine Kurve bei 200–250 klebt sonst am oberen Rand) |
| nur boolesche Datenpunkte | genau 0 und 1, ein Schritt; true/false werden als 1/0 gezeichnet, gebündelt mit max statt average (Aggregation leer lassen) |
echartLeftMin / echartLeftMax | gesetzte Grenzen gewinnen in beiden Fällen |
Beide Y-Achsen entscheiden das für sich: Balken links und eine Temperaturkurve rechts behalten jede ihre passende Skala.
Die horizontalen Hilfslinien zeichnet immer nur eine Achse — zwei verschieden skalierte Raster würden sich überkreuzen. Normalerweise die linke; hängen alle Serien an der rechten, übernimmt sie.
Negativ darstellen
Häkchen Negativ darstellen (× −1) im ƒx-Dialog. Zeichnet die Serie unter der Nulllinie — für Einspeisung und Batterie-Ladung, die als positive Werte geliefert werden.
| Gespeichert als | negatives valueFactor (× −1) |
| Mit Umrechnung kombiniert | ja — Wh → kWh negativ ist −0.001 |
Bei aggregate: delta | der Zählerstand wird unverändert differenziert, das Vorzeichen kommt auf die Balken |
| Gestapelt | positive Serien nach oben, negative nach unten |
| Wertelabels | wandern unter den Balken |
Verbrauch aus Zählerständen
aggregate: delta für Zähler. Statt des Zählerstands wird der Zuwachs je Zeiteinheit gezeichnet — also der Verbrauch bzw. Ertrag pro Stunde, Tag, Woche, Monat oder Jahr.
| Bauart | Beispiel |
|---|---|
| fortlaufend steigend | Strom-, Wasser-, Gaszähler, PV-Gesamtertrag |
täglicher Rücksprung auf 0 | PV-Tagesertrag, z. B. solaredge.0.*.lastDayData |
| Datenquelle | Verlaufs-Adapter (history, influxdb, sql) |
| Zeiteinheit | deltaBucket — Kalendergrenzen in lokaler Zeit |
| Chart-Typ | beim Umschalten automatisch bar |
| Y-Achse | beginnt automatisch bei 0 (Balken werden von der Nulllinie gelesen) |
| Rücksprung um Mitternacht | Reset eines Tageszählers; der Anstieg danach zählt voll |
| Rücksprung innerhalb des Tages | bei einem täglich zurückspringenden Zähler der Reset des Tages (der Anstieg danach zählt voll); jeder weitere Rücksprung am selben Tag gilt als Ausreißer — weder er noch der Sprung zurück auf den alten Stand werden gewertet |
| Buckets ohne Datensatz | übersprungen; ihr Verbrauch fällt in den nächsten Bucket mit Daten |
| Aktueller Wert oben rechts | Verbrauch des laufenden Buckets, nicht der Zählerstand |
| Zeitraum-Anfang | fällt auf die Kalendergrenze der Zeiteinheit zurück (7 Tage beginnen also um 00:00 Uhr); alle Serien des Diagramms starten dort, auch reine Kurven |
| Zeitraum-Ende | der jüngste Messwert; der Balken des laufenden Buckets sitzt auf dessen Anfang, eine Kurve läuft also bis zur aktuellen Uhrzeit rechts davon weiter |
Bilder dazu: Beispiele.
deltaBucket: auto leitet die Zeiteinheit aus dem aktiven Zeitraum ab und wechselt mit, wenn im Frontend umgeschaltet wird:
| Zeitraum | Zeiteinheit |
|---|---|
| bis 1 Tag | pro Stunde |
| bis 45 Tage | pro Tag |
| bis 180 Tage | pro Woche |
| bis 1 Jahr | pro Monat |
| darüber | pro Jahr |
Vorjahresvergleich
Eine Serie kann statt der aktuellen Werte die Werte von früher zeigen — eingezeichnet an der Stelle des heutigen Zeitraums. Bei „1 Jahr zurück“ steht neben dem Balken für Januar 2026 der Balken für Januar 2025.
Dafür eine zweite Serie auf denselben Datenpunkt mit timeShift: 1 · timeShiftUnit: year — im Editor per + Vorjahres-Serie anlegen unter „Werte von früher zeigen (Vergleich)“. Die erste Serie bleibt auf 0.

| Thema | Verhalten |
|---|---|
| Lage der Balken | gleiche Zeiteinheit wie die aktuelle Serie → Balken je Monat/Tag nebeneinander |
| Stapeln | aus lassen, sonst werden die Jahre addiert |
| Laufender Bucket | wird beim Vorjahr vollständig gelesen (ganzer Oktober des Vorjahres, nicht nur bis heute) |
| Live-Werte | keine — die versetzte Serie zeigt nur History |
| Tooltip | nennt hinter dem Seriennamen den Zeitraum, aus dem der Wert stammt |
| Andere Vergleiche | day = gestern, week = Vorwoche, month = Vormonat |
Zeitraum Gesamt | Versatz wirkt nicht |
Zeitraum-Kennzahl
Eine Zahl je Serie über den gerade gezeigten Zeitraum, z. B. die Einspeisung der letzten 30 Tage. Geht mit Zeitraum-Knöpfen, Tagesnavigation und Zeitversatz mit. Im Editor unter „Verlauf“ der Serie, die Position im Tab „Werte“. Zum Importieren: Beispiel „Einspeisung und Bezug des Zeitraums“.


periodValue | Zählerstand / Messwert | Serie mit aggregate: delta (Balken) |
|---|---|---|
consumption | Summe aller Anstiege — bleibt bei Tageszähler und Zählertausch richtig | Summe der Balken |
change | Ende − Start | Summe der Balken |
min · max | kleinster / größter Wert im Zeitraum | kleinster / größter Balken |
average | Mittelwert | mittlerer Balken |
integral | Fläche über die Zeit: W → Wh, kW → kWh (Einheit bekommt ein „h“) | Summe der Balken |
| Thema | Verhalten |
|---|---|
| Datenquelle | eigene History-Abfrage (dieselbe wie Verteilung → gleiche Zahl); Balken: aus den Balken |
| Live-Werte | Verbrauch, Differenz, Min, Max laufen live mit; Mittelwert beim nächsten Nachladen |
| Format | Nachkommastellen und Einheit der Serie bzw. ihrer Achse |
| Nicht verfügbar | Modus comparison und json, Serien mit source: json |
Formel-Reihe
Eine Reihe aus mehreren Datenpunkten berechnen, ohne Skript und ohne eigenen Datenpunkt: Datenquelle → Formel.

| Feld | Inhalt |
|---|---|
| Eingänge | je Zeile ein kurzer Name (u, a) und ein Datenpunkt; 🗄 schlägt den Namen vor |
| Formel | Rechnung mit den Namen: (is - ib) * u, a + b + c, Math.max(a - b, 0) |
| Jetzt | Ergebnis mit den aktuellen Werten bzw. Fehler („Unbekannte Variable …“) |
| Verlauf | History-Instanz, Aggregation, Kennzahl, Zeitversatz wie bei jeder Reihe |
| Thema | Verhalten |
|---|---|
| Fehlende Werte | jeder Eingang hält seinen letzten Wert (auch von vor dem Zeitraum) — keine Lücken |
| Start | erst, wenn alle Eingänge einen Wert haben |
| Division durch 0, Text | an der Stelle eine Lücke |
| bis 7 Tage | Rohdaten, exakt für jede Formel |
| länger | Mittelwerte der Eingänge: Summe/Differenz exakt, Produkt/Quotient Näherung |
aggregate: delta | jeder Zähler für sich je Zeitraum differenziert, dann gerechnet — für Summen/Differenzen |
| Kennzahl | aus der berechneten Kurve; integral = Verbrauch in Wh aus W |
| Mischen | Formel-Reihen und normale Reihen im selben Diagramm |
| Formel-Syntax | wie Bindings: + - * / %, Klammern, Vergleiche, ?:, Math.* — kein JavaScript |
{
"id": "last",
"name": "Hausverbrauch",
"source": "formula",
"datapointId": "",
"formulaInputs": [
{ "name": "u", "datapointId": "alias.0.battery.raVoltage" },
{ "name": "is", "datapointId": "alias.0.solar.raCurrent" },
{ "name": "ib", "datapointId": "alias.0.battery.raCurrent" }
],
"formula": "(is - ib) * u",
"unit": "W",
"periodValue": "integral"
}historyInstance kann je Eingang abweichen; sonst gilt die der Reihe.
JSON-Quelle
Für Serien mit source: json — im Modus json alle, im Modus timeseries die einzeln umgestellten.
echartJsonTimeAxis gilt nur im Modus json; in der Zeitreihe ist die Zeitachse gesetzt.
| Option | Standard | |
|---|---|---|
echartSeries[].jsonPath | — | Punkt-Pfad bis zum Array, z. B. data.hours; leer = Wurzel |
echartSeries[].jsonLabelKey | automatisch | Objekt-Feld für die X-Beschriftung; leer = erkennen |
echartSeries[].jsonValueKey | automatisch | Objekt-Feld für den Y-Wert; leer = erkennen |
echartJsonTimeAxis | false | Beschriftungen als Zeitstempel lesen → Zeitachse statt Kategorien |
echartJsonAxisBounds | false | min/max-Block aus dem Datenpunkt für die Y-Achse übernehmen |
echartSeries[].jsonAxisPath | automatisch | Punkt-Pfad zum min/max-Block, z. B. axis; leer = suchen |
echartSeries[].jsonMultiSeries | false | das Array enthält ganze Serien — je Eintrag eine Linie (s. u.) |
Statt Objekten nimmt data auch [x, y]-Paare: [[1759312800000, 98], [1759399200000, 101]].
Mehrere Serien aus einem Datenpunkt
Im Editor Mehrere Serien aus dem JSON, direkt unter der Datenquelle. Name und Farbe der Serie sind dann ausgegraut — beides kommt je Linie aus dem JSON. Eine Serie liefert so viele Linien, wie der Datenpunkt Einträge hat — kommt einer dazu, erscheint eine Linie mehr, ohne das Widget anzufassen. Die Einstellungen der Serie (Typ, Glättung, Einheit, Achse, Stapeln, Umrechnung) gelten für alle Linien.
{
"series": [
{ "name": "script-restore", "data": [[1759312800000, 98], [1759399200000, 101]] },
{ "name": "agent-dvr", "data": [[1759312800000, 14]], "color": "var(--accent-green)" },
{ "name": "Gesamt", "data": [[1759312800000, 190]], "lineStyle": "dashed" }
]
}| Feld je Eintrag | Pflicht | |
|---|---|---|
name | ja | Legende und Tooltip; doppelte Namen bekommen (2) |
data | ja | Punkte wie bei einer einfachen JSON-Serie oder [x, y]-Paare |
color | nein | Farbe oder Theme-Token; ohne Angabe feste Palettenfarbe je Name |
lineStyle | nein | dashed / dotted |
yAxisIndex | nein | 0 links, 1 rechts; sonst die Achse der Serie |
type | nein | line / bar / area / scatter; sonst der Typ der Serie |
jsonPath zeigt auf die Liste (series); leer findet sie auch in {"series": [...]}. Mit Zeitstempeln in data: Modus timeseries oder echartJsonTimeAxis.
Achsen
| Option | Standard | |
|---|---|---|
echartShowYAxis | true | Y-Achsen anzeigen |
echartShowYAxisRight | true | rechte Y-Achse beschriften; aus = nur die linke Skala, die rechte Achse skaliert weiter |
echartShowXAxis | true | X-Achse anzeigen |
echartXLabelCount | auto | nur mit Zeitachse: ungefähre Zahl der Beschriftungen (1–24) |
echartShowGridLines | true | horizontale Hilfslinien (von der Achse, an der die Serien hängen) |
echartLeftUnit | — | Einheit der linken Y-Achse |
echartRightUnit | — | Einheit der rechten Y-Achse |
echartLeftMin / echartLeftMax | auto | Skala links; Zahl oder dataMin/dataMax |
echartRightMin / echartRightMax | auto | Skala rechts; Zahl oder dataMin/dataMax |
echartLeftMinDp / echartLeftMaxDp | — | Datenpunkt liefert die Grenze links — ändert sich die Zahl, skaliert die Achse mit |
echartRightMinDp / echartRightMaxDp | — | Datenpunkt liefert die Grenze rechts |
Reihenfolge, wenn mehrere Quellen gesetzt sind: Datenpunkt → min/max-Block im JSON → feste Eingabe. Ein leerer oder nicht-numerischer Datenpunkt zählt nicht mit, dann gilt die nächste Quelle. Die Datenpunkt-Grenzen wirken in jedem Modus, auch im Gauge.
Verlauf
Ein gemeinsamer Zeitraum für alle Serien.
| Option | Standard | |
|---|---|---|
echartRange | 24h | 1h · 6h · 24h · 7d · 30d · 1y · total · custom |
echartRangeCustomValue | 24 | nur bei custom |
echartRangeCustomUnit | h | m · h · d · w · M · y, nur bei custom |
lockRange | false | Zeitraum-Umschalter im Frontend ausblenden |
echartVisibleRanges | alle | Welche Presets der Frontend-Umschalter anbietet, z. B. ["6h","24h","7d","30d"] |
rangeChips | — | Eigene Zeitraum-Chips, ersetzt echartVisibleRanges, z. B. ["1M","3M","12M","total"] |
echartDayNav | false | Blättern im Frontend (‹ › ⇥ 📅) — Schritt = aktiver Zeitraum-Chip |
echartDayNavDefault | false | Beim Laden auf den aktuellen Zeitraum stellen (24 Std: heute 00:00–24:00) |
echartNavAnchor | end | Gewähltes Datum ist end = letzter Tag des Fensters · start = erster Tag |
rangeChipSize | sm | Größe der Zeitraum-Chips: sm · md · lg (Touch) |
rangeChipPosition | top | Zeitraum-Chips über (top) oder unter (bottom) dem Diagramm |
navSize | sm | Größe der Blätter-Leiste: sm · md · lg (Touch) |
navPosition | top | Blätter-Leiste über (top) oder unter (bottom) dem Diagramm |
echartNavGroup | — | Kopplungsgruppe: gleiche Namen blättern gemeinsam (im selben Browser) |
echartNavGroupMode | all | all = Datum und Zeitraum-Chip gemeinsam · date = nur das Datum, jedes Diagramm behält seinen Zeitraum |
echartNavRangeDp | — | Zeitraum-Datenpunkt, lesen + schreiben: 6h · 24h · 7d · 1M · total |
echartNavDateDp | — | Datum-Datenpunkt, lesen + schreiben: YYYY-MM-DD, ms, leer = bis jetzt |
echartNavEndDp | — | Ende-Datenpunkt (von–bis): gesetzt = echartNavDateDp ist der erste, dieser der letzte Tag |
echartNavFreeRange | false | Freier Zeitraum: 📅 wählt Von und Bis statt eines Tags |
echartNavIdleReset | — | Minuten ohne Bedienung → zurück auf Standard-Zeitraum und Startdatum; Gruppe folgt, DPs bleiben |
echartNavCommandDp | — | Befehls-Datenpunkt, nur lesen: prev · next · today · now |
echartRangeLead | — | Prognose: rollender Zeitraum reicht so weit über jetzt hinaus, z. B. 36h |
echartNavFuture | none | Prognose: Blättern in die Zukunft — none · data (bis zum letzten Wert) · 16d |
echartNavCurrent | contains-now | ⇥ = Fenster, das heute endet · starts-today = Fenster, das heute beginnt |
autoHistoryInstance | false | History-Instanz je Serie automatisch erkennen |
Live-Wert am rechten Rand:
| Serie | Kurve | aktueller Wert oben |
|---|---|---|
Rohdaten, Mittelwert bis 7d, minmax, boolesche Datenpunkte | endet am Live-Wert (fällt z. B. auf 0) | Live-Wert |
max, min, total; Mittelwert ab 30d (Bündel über 1 h) | endet am letzten Bündel | Live-Wert |
Ein einzelner Messwert ist kein Tagesminimum und keine Tagessumme — angehängt würde er die Linie am Rand auf den aktuellen Wert ziehen.
Blättern (echartDayNav):

| Aktion | Wirkung |
|---|---|
| ‹ / › | ein Fenster des aktiven Chips zurück/vor: 24 Std = Tag, 7 Tage = Woche, 1M = Monat |
| Zeitraum-Chip | wechselt den Zeitraum, das gewählte Datum bleibt |
| 📅 Datum | springt auf den Tag; Anzeige Mo 27.10. bzw. 21.10.–27.10. |
| ⇥ | aktuelles Fenster; zweiter Klick auf das leuchtende ⇥ = rollend bis jetzt |
| ▶ grau | das nächste Fenster begänne in der Zukunft |
Gesamt | nichts zu blättern, Knöpfe ausgegraut |
Freier Zeitraum (echartNavFreeRange):

| Aktion | Wirkung |
|---|---|
| 📅 → Von / Bis | Zeitraum aus ganzen Tagen, z. B. 14.08.–02.09. = 20d (max. 999 Tage) |
| ‹ / › | springen um die Länge des Zeitraums |
echartNavGroup | gekoppelte Diagramme übernehmen den Zeitraum wie einen Chip |
echartNavDateDp + echartNavEndDp | 2025-08-14 + 2025-09-02; beide leer = rollend |
echartNavAnchor | Datum 03.10., 7 Tage | Datum 03.10., 24 Std |
|---|---|---|
end | 27.09. 00:00 – 04.10. 00:00 | 03.10. 00:00–24:00 |
start | 03.10. 00:00 – 10.10. 00:00 | 03.10. 00:00–24:00 |
Koppeln:
| Weg | Reichweite |
|---|---|
gleiches echartNavGroup | alle Diagramme im Browser-Tab |
gleiche echartNavDateDp + echartNavRangeDp | alle Geräte |
echartNavCommandDp (Taster, Skript) | jedes Diagramm, das ihn liest |
Datenpunkte: Das Widget schreibt nur bei Bedienung (Zahl-DP: ms, sonst YYYY-MM-DD). Der Befehls-DP reagiert auf jede Aktualisierung, auch auf denselben Wert; der Wert beim Laden zählt nicht, zurückgesetzt wird nichts.
Mit lockRange bleibt nur das Blättern übrig — ein reines Tagesdiagramm.
Prognosen (nur Modus Zeitreihe; Werte per storeState mit eigenem Zeitstempel im History-Adapter):
| Einstellung | Wirkung |
|---|---|
Chip 2d+36h oder echartRangeLead: "36h" | rollend jetzt − 12 h bis jetzt + 36 h; Jetzt-Linie (echartNowLine) bei ¼ |
+0h am Chip | dieser Chip ohne Vorlauf |
echartNavFuture: "data" | › aktiv, solange eine Reihe Punkte hinter dem Fensterende hat (Abfrage alle 15 min) |
echartNavFuture: "16d" | › bis 16 Tage ab jetzt |
echartNavCurrent: "starts-today" | ⇥ bei 2d = heute + morgen, bei 7d = heute + 6 Tage |
| eine der drei gesetzt | Abfrage und Achse enden nicht bei jetzt; Kalender und echartNavDateDp nehmen Zukunftsdaten an |
rangeChips nimmt Kürzel aus Zahl + Einheit: m (Minute) · h · d · w · M (Kalendermonat) · y (Kalenderjahr) oder total, eigene Beschriftung nach = (3M=Quartal). Liegt echartRange nicht in der Liste, startet das Diagramm mit dem ersten Chip. Im Editor: Eigene Liste anlegen.
total (Umschalter: Gesamt) zeichnet alles, was der Verlaufs-Adapter hergibt.
| Fensterstart | wird je Serie beim Adapter ermittelt, nicht konfiguriert |
| Auflösung | ergibt sich aus der gefundenen Länge — je länger die Historie, desto grober der Schritt |
| Obergrenze der Suche | 20 Jahre; älter ist ioBroker selbst nicht |
deltaBucket: auto | ab 400 Tagen Historie year, darunter entsprechend feiner |
| Adapter ohne Daten | leeres Diagramm, wie jeder andere Zeitraum ohne Datensätze |
Der Fensterstart kostet eine zusätzliche, grobe Abfrage je Serie. Bei sehr langen Historien auf dem dateibasierten history-Adapter ist der erste Aufbau daher merklich langsamer als bei influxdb oder sql.
JSON-Override
| Option | Standard | |
|---|---|---|
echartJsonExtra | — | JSON, das tief in die ECharts-Optionen gemischt wird |
Beispiele
Vier Datenpunkte, alle per history.0 geloggt: PV-Ertragszähler demo.0.PV.Ertrag_Gesamt (kWh, fortlaufend steigend), Hausleistung demo.0.Haus.Leistung (W), Außentemperatur demo.0.Wetter.Aussentemperatur (°C) und Regenmenge demo.0.Regen.Menge (mm je Messintervall).
Zählerstand → Tagesertrag
aggregate: average · chartType: line · echartRange: 30d — der Zähler steigt, der Tagesertrag ist daraus nicht ablesbar:

Derselbe Datenpunkt mit aggregate: delta · deltaBucket: day · chartType: bar · echartLeftMin: 0:

Die Einstellungen dazu im Editor:

Zeiteinheit
deltaBucket: hour · echartRange: 24h — Tagesverlauf, ein Balken je Stunde:

deltaBucket: month · echartRange: 1y — Monatserträge über ein Jahr:

deltaBucket: year · echartRange: custom / 1825 d — Jahreserträge, der letzte Balken ist das laufende Jahr:

Zeiteinheit automatisch
deltaBucket: auto · echartVisibleRanges: ["24h","30d","1y"] — die Zeiteinheit wechselt mit dem Umschalter im Frontend. 30 Tage ergibt Tagesbalken:

1 Jahr ergibt Monatsbalken — ohne Änderung an der Konfiguration:

Spitzen: Mittelwert oder Min/Max
Hausleistung über 24 h. aggregate: average glättet jedes 15-Minuten-Fenster — der Backofen wird zu einem Plateau, der Wasserkocher verschwindet fast:

aggregate: minmax behält die echten Extremwerte samt Zeitstempel — die Spitzen und das Takten der Geräte bleiben sichtbar:

Maximum, Mittelwert, Minimum
Derselbe Datenpunkt dreimal als eigene Serie, echartRange: 1y (Tages-Fenster): max zeichnet die Nachmittage, min die Nächte, average den Tagesmittelwert. Die Aggregation gilt je Serie, nicht je Widget.

Summe
aggregate: total addiert die Werte im Zeitfenster — für Datenpunkte, die bereits Zuwächse loggen (Regenmenge je Messintervall, Wh je Impuls), nicht für Zählerstände (dafür delta). Hier Regenmenge je 10 Minuten, summiert auf Stundenwerte:

Derselbe Datenpunkt mit average: gleiche Form, aber der Durchschnitt der Einzelzuwächse — 0,6 mm statt 3,6 mm:

Rohdaten
aggregate: none liefert jeden geloggten Datensatz, ohne Zeitfenster. Das Takten der Waschmaschine (2 300 W an/aus) ist damit sichtbar:

average fasst dasselbe in 5-Minuten-Fenster zusammen — aus dem Takten wird ein Plateau bei ~1 100 W:

Viele Datensätze kosten Ladezeit; none ist für kurze Zeiträume gedacht, nicht für 30 Tage.
Stapeln
Zwei Serien mit stack: true und chartType: area auf derselben Y-Achse: Netzbezug und Speicher-Entladung ergeben zusammen den Hausverbrauch. Der Tooltip zeigt die Einzelwerte plus Σ Summe.

Bilder neu erzeugen
node tools/screenshots/echart-examples.mjs gegen einen laufenden npm run dev. Die Daten sind im Skript erzeugt (fester Zeitpunkt, fester Zufallsgenerator), es wird keine Instanz gelesen oder geschrieben.