162 lines
3.6 KiB
TypeScript
162 lines
3.6 KiB
TypeScript
"use client";
|
|
import React, { useEffect } from "react";
|
|
import { Line } from "react-chartjs-2";
|
|
import { getColor } from "@/utils/colors";
|
|
import {
|
|
Chart as ChartJS,
|
|
LineElement,
|
|
PointElement,
|
|
CategoryScale,
|
|
LinearScale,
|
|
Tooltip,
|
|
Legend,
|
|
Filler,
|
|
TimeScale,
|
|
} from "chart.js";
|
|
import "chartjs-adapter-date-fns";
|
|
import { de } from "date-fns/locale";
|
|
import { useSelector, useDispatch } from "react-redux";
|
|
import type { RootState, AppDispatch } from "../../../redux/store";
|
|
import { getAnalogInputsHistoryThunk } from "@/redux/thunks/getAnalogInputsHistoryThunk";
|
|
|
|
// Basis-Registrierung (ohne Zoom-Plugin)
|
|
ChartJS.register(
|
|
LineElement,
|
|
PointElement,
|
|
CategoryScale,
|
|
LinearScale,
|
|
Tooltip,
|
|
Legend,
|
|
Filler,
|
|
TimeScale
|
|
);
|
|
|
|
export default function AnalogInputsChart({
|
|
selectedId,
|
|
}: {
|
|
selectedId: number | null;
|
|
}) {
|
|
const selectedInput = useSelector(
|
|
(state: RootState) => state.selectedAnalogInput
|
|
);
|
|
|
|
const dispatch = useDispatch<AppDispatch>();
|
|
const { data } = useSelector(
|
|
(state: RootState) => state.analogInputsHistory
|
|
) as {
|
|
data: { [key: string]: any[] };
|
|
};
|
|
|
|
useEffect(() => {
|
|
dispatch(getAnalogInputsHistoryThunk());
|
|
}, [dispatch]);
|
|
|
|
// ✅ Zoom-Plugin dynamisch importieren und registrieren
|
|
useEffect(() => {
|
|
const loadZoomPlugin = async () => {
|
|
if (typeof window !== "undefined") {
|
|
const zoomPlugin = (await import("chartjs-plugin-zoom")).default;
|
|
if (!ChartJS.registry.plugins.get("zoom")) {
|
|
ChartJS.register(zoomPlugin);
|
|
}
|
|
}
|
|
};
|
|
loadZoomPlugin();
|
|
}, []);
|
|
|
|
if (!selectedId) {
|
|
return (
|
|
<div className="text-gray-500">Bitte einen Messwerteingang auswählen</div>
|
|
);
|
|
}
|
|
|
|
const key = String(selectedId + 99);
|
|
const inputData = data[key];
|
|
|
|
if (!inputData) {
|
|
return (
|
|
<div className="text-red-500">
|
|
Keine Verlaufsdaten für Messwerteingang {selectedId} gefunden.
|
|
</div>
|
|
);
|
|
}
|
|
|
|
const chartData = {
|
|
datasets: [
|
|
{
|
|
label: `Messkurve ${selectedInput?.label ?? "Eingang"} [${
|
|
selectedInput?.unit ?? ""
|
|
}]`,
|
|
data: inputData.map((point: any) => ({
|
|
x: point.t,
|
|
y: point.m,
|
|
})),
|
|
fill: false,
|
|
borderColor: getColor("littwin-blue"),
|
|
backgroundColor: "rgba(59,130,246,0.5)",
|
|
borderWidth: 2,
|
|
pointRadius: 0,
|
|
pointHoverRadius: 10,
|
|
tension: 0.1,
|
|
},
|
|
],
|
|
};
|
|
|
|
const chartOptions = {
|
|
responsive: true,
|
|
plugins: {
|
|
legend: { position: "top" as const },
|
|
tooltip: { mode: "index" as const, intersect: false },
|
|
title: {
|
|
display: true,
|
|
text: `Verlauf der letzten 24 Stunden`,
|
|
},
|
|
zoom: {
|
|
pan: {
|
|
enabled: true,
|
|
mode: "x" as const,
|
|
},
|
|
zoom: {
|
|
wheel: { enabled: true },
|
|
pinch: { enabled: true },
|
|
mode: "x" as const,
|
|
},
|
|
},
|
|
},
|
|
scales: {
|
|
x: {
|
|
type: "time" as const,
|
|
time: {
|
|
unit: "hour" as const,
|
|
tooltipFormat: "HH:mm 'Uhr' dd.MM.",
|
|
displayFormats: {
|
|
hour: "HH:mm",
|
|
day: "dd.MM.",
|
|
},
|
|
},
|
|
adapters: {
|
|
date: {
|
|
locale: de,
|
|
},
|
|
},
|
|
title: {
|
|
display: true,
|
|
text: "Zeit",
|
|
},
|
|
},
|
|
y: {
|
|
title: {
|
|
display: true,
|
|
text: `Messwert [${selectedInput?.unit ?? ""}]`,
|
|
},
|
|
},
|
|
},
|
|
};
|
|
|
|
return (
|
|
<div className="w-full h-full">
|
|
<Line data={chartData} options={chartOptions} />
|
|
</div>
|
|
);
|
|
}
|