Kapitel 3: Schwellenwerte, Zonen und Marker
Eine Messreihe allein sagt, was passiert ist. Erst ein Schwellenwert sagt, ob es akzeptabel war. Das ist der Unterschied zwischen einem Diagramm, das du nur ansiehst, und einem, nach dem du handelst.
Die Linie
Der einfachste Fall: ein benannter Schwellenwert als gestrichelte Linie.
thresholds: [{ name: 'crit', value: 22, color: '#e11d48' }]
// wohin die Beschriftung kommt: above, below, outside-left, outside-right
thresholds: [{ name: 'crit', value: 22, label: { text: 'KRITISCH', position: 'above' } }]Grenzen im Blick
Der automatische Wertebereich folgt den Messwerten. Bei Werten von 2–7 °C und Grenzen bei 0 und 10 °C liegen beide Grenzlinien außerhalb des Bildes — genau die Linien, die es zeigen sollte. Ein Schalter an der Achse weitet den Bereich auf die Schwellenwerte, die auf ihr gezeichnet werden:
axes: { left: { includeThresholds: true } }Ein Schwellenwert mit line: 'none' ist nur Bezug und zählt nicht; ein
ausdrücklicher domain gewinnt.
Die Fläche
Eine Linie sagt, wo der Schwellenwert liegt. Eine Fläche sagt, wie lange er überschritten war — und das ist meist die eigentliche Frage.
Farbe nach Wert
Statt eines Schwellenwerts mehrere: Die Kurve nimmt die Farbe der Zone an, in der sie sich gerade befindet. Nützlich für abgestufte Bewertungen — grün, gelb, rot — und gefährlich, wenn die Stufen willkürlich gewählt sind, weil die Farbe dann eine Gewissheit suggeriert, die die Daten nicht hergeben.
Zeiträume markieren
Manchmal liegt die Aussage nicht im Wert, sondern im Zeitraum: ein Wartungsfenster, ein Ausfall, eine Schicht. Annotationsbänder liegen hinter der Kurve.
Zwei Fühler, die übereinstimmen sollten
Zwei Fühler in einem Kühlschrank sind in Ordnung, solange sie dasselbe sehen. Mehr als 2 °C auseinander, und etwas stimmt nicht: einer vereist, einer sitzt im Luftzug, einer ist abgedriftet. Eine Füllfläche zwischen den beiden Linien, mit Bedingung, markiert genau diese Strecke:
series: [
{ ...oben, style: { fill: { regions: [{
from: 'series', to: { series: 'Unten' },
where: { exceeds: 2 }, // nur wo |Unten − Oben| > 2 °C
fill: { color: '#dc262640' },
}] } } },
unten,
]Entschieden wird an den Messwerten — linear dazwischen, bei einer Treppe
gehalten —, nicht an der gezeichneten Kurve, deren Glättung überschwingen kann.
Für einen Nachweis ist das die richtige Grundlage. side: 'above' oder
'below' fragt nur nach einer Richtung; maxAgeMs zeichnet nichts, wo der
letzte Wert eines Fühlers zu alt für eine Aussage ist. divergenceExcursions()
aus ml-time-graph/analyze sagt dazu, welcher Fühler weggelaufen ist — die
Hälfte, nach der man handeln kann.
Wie lange draußen
Die Frage eines GxP-Berichts ist nicht, ob die Grenze überschritten wurde,
sondern wie lange insgesamt. computeLimitExcursions beantwortet sie:
import { computeLimitExcursions } from 'ml-time-graph/analyze';
const { msAboveHigh, msBelowLow, excursions } =
computeLimitExcursions(daten, { low: 2, high: 8 });
// excursions: [{ startTime, endTime, side, extremum, durationMs }]Streng draußen — genau 8 °C ist drinnen. Eine Lücke beendet eine Episode, und
die Zeit zwischen zwei Messwerten zählt zu der Seite, auf der der zweite liegt.
Die Go-Fassung (analyze.ComputeLimitExcursions) rechnet dasselbe, Bildschirm
und PDF nennen also dieselbe Dauer.
Und interaktiv
Die Demo zeigt dieselben Bausteine im Browser: sechs Karten, von denen jede die vorherige um genau eine Idee erweitert. Code und Werte stehen neben jedem Schritt auf eigenen Tabs. Aus technischen Gründen ist die interaktive Demo nicht direkt in der Buchversion enthalten, aber du kannst sie im Browser öffnen und dort die Werte ändern, um zu sehen, wie sich das Diagramm verhält.