feat(analogInputsChart): zeige Minimum (i) und Maximum (a) als zusätzliche Linien im Chart

- Chart zeigt jetzt Messwert (m), Minimum (i, grün) und Maximum (a, rot) für ausgewählten Zeitraum
- Tooltip und Legende angepasst
- Typdefinitionen für Chart
This commit is contained in:
ISA
2025-07-21 10:21:45 +02:00
parent 528773128d
commit 23a3c173dd
7 changed files with 61 additions and 18 deletions

View File

@@ -1,4 +1,5 @@
"use client";
// components/main/analogInputs/AnalogInputsChart.tsx
import React, { useEffect, useRef } from "react";
import { useDispatch, useSelector } from "react-redux";
import { RootState, AppDispatch } from "@/redux/store";
@@ -13,8 +14,8 @@ import {
Legend,
Filler,
TimeScale,
TooltipItem,
} from "chart.js";
import type { ChartOptions } from "chart.js";
import "chartjs-adapter-date-fns";
import { de } from "date-fns/locale";
import { getAnalogInputsHistoryThunk } from "@/redux/thunks/getAnalogInputsHistoryThunk";
@@ -42,6 +43,8 @@ ChartJS.register(
type AnalogInputHistoryPoint = {
t: string;
m: number;
i?: number;
a?: number;
};
export default function AnalogInputsChart() {
@@ -56,7 +59,7 @@ export default function AnalogInputsChart() {
}, []);
const dispatch = useDispatch<AppDispatch>();
const chartRef = useRef<any>(null);
const chartRef = useRef<ChartJS | null>(null);
const { zeitraum, vonDatum, bisDatum, data, autoLoad, selectedId } =
useSelector((state: RootState) => state.analogInputsHistory);
@@ -88,7 +91,9 @@ export default function AnalogInputsChart() {
chart.options.scales.x.max = new Date(latestBisDatum).getTime();
// Aktualisiere die Daten des Diagramms
const chartKey = selectedAnalogInput?.id ? String(selectedAnalogInput.id + 99) : null;
const chartKey = selectedAnalogInput?.id
? String(selectedAnalogInput.id + 99)
: null;
const inputData = chartKey ? data[chartKey] ?? [] : [];
const filteredData = inputData.filter((point) => {
const date = new Date(point.t);
@@ -170,12 +175,9 @@ export default function AnalogInputsChart() {
? [
{
label: selectedAnalogInput?.label
? `Messwerteingang ${selectedAnalogInput.label}`
: "Messwerte",
data: filteredData.map((point) => ({
x: point.t,
y: point.m,
})),
? `Messwert (m) ${selectedAnalogInput.label}`
: "Messwert (m)",
data: filteredData.map((point) => ({ x: point.t, y: point.m })),
fill: false,
borderColor: getColor("littwin-blue"),
backgroundColor: "rgba(59,130,246,0.3)",
@@ -183,6 +185,30 @@ export default function AnalogInputsChart() {
pointRadius: 0,
tension: 0.1,
},
{
label: "Minimum (i)",
data: filteredData
.filter((point) => typeof point.i === "number")
.map((point) => ({ x: point.t, y: point.i })),
fill: false,
borderColor: "#22c55e", // grün
borderWidth: 1,
pointRadius: 0,
borderDash: [4, 2],
tension: 0.1,
},
{
label: "Maximum (a)",
data: filteredData
.filter((point) => typeof point.a === "number")
.map((point) => ({ x: point.t, y: point.a })),
fill: false,
borderColor: "#ef4444", // rot
borderWidth: 1,
pointRadius: 0,
borderDash: [4, 2],
tension: 0.1,
},
]
: [],
};
@@ -195,10 +221,11 @@ export default function AnalogInputsChart() {
mode: "index" as const,
intersect: false,
callbacks: {
label: function (context: any) {
return `Messwert: ${context.parsed.y}`;
label: function (context: TooltipItem<"line">) {
const label = context.dataset.label || "";
return `${label}: ${context.parsed.y}`;
},
title: function (tooltipItems: any[]) {
title: function (tooltipItems: TooltipItem<"line">[]) {
const date = tooltipItems[0].parsed.x;
return `Zeitpunkt: ${new Date(date).toLocaleString("de-DE")}`;
},
@@ -212,7 +239,11 @@ export default function AnalogInputsChart() {
},
zoom: {
pan: { enabled: true, mode: "x" as const },
zoom: { wheel: { enabled: true }, pinch: { enabled: true }, mode: "x" as const },
zoom: {
wheel: { enabled: true },
pinch: { enabled: true },
mode: "x" as const,
},
},
},
scales: {