- fetchAnalogInputsHistoryService angepasst: nutzt /api/cpl/fetchAnalogInputsHistory bei NODE_ENV=development - Produktionsdaten weiterhin direkt vom CPL-Webserver über CGI-Endpunkte geladen - Chart- und Redux-Datenstrom jetzt vollständig stabil in Entwicklung und Produktion - Fehler beim direkten Zugriff auf Mock-Dateien in Pages Router Next.js behoben
124 lines
2.7 KiB
TypeScript
124 lines
2.7 KiB
TypeScript
"use client"; // components/main/analogeEingaenge/AnalogInputsChart.tsx
|
||
import React, { useEffect } from "react";
|
||
import { Line } from "react-chartjs-2";
|
||
import {
|
||
Chart as ChartJS,
|
||
LineElement,
|
||
PointElement,
|
||
CategoryScale,
|
||
LinearScale,
|
||
Tooltip,
|
||
Legend,
|
||
Filler,
|
||
TimeScale,
|
||
} from "chart.js";
|
||
import "chartjs-adapter-date-fns";
|
||
import { useSelector, useDispatch } from "react-redux";
|
||
import type { RootState, AppDispatch } from "../../../redux/store";
|
||
import { fetchAnalogInputsHistoryThunk } from "../../../redux/thunks/fetchAnalogInputsHistoryThunk";
|
||
|
||
ChartJS.register(
|
||
LineElement,
|
||
PointElement,
|
||
CategoryScale,
|
||
LinearScale,
|
||
Tooltip,
|
||
Legend,
|
||
Filler,
|
||
TimeScale
|
||
);
|
||
|
||
const colors = [
|
||
"#007bff",
|
||
"#28a745",
|
||
"#dc3545",
|
||
"#ffc107",
|
||
"#17a2b8",
|
||
"#6f42c1",
|
||
"#fd7e14",
|
||
"#20c997",
|
||
];
|
||
|
||
export default function AnalogInputsChart() {
|
||
const dispatch = useDispatch<AppDispatch>();
|
||
const { data, isLoading, error } = useSelector(
|
||
(state: RootState) => state.analogInputsHistory
|
||
);
|
||
|
||
useEffect(() => {
|
||
dispatch(fetchAnalogInputsHistoryThunk());
|
||
}, [dispatch]);
|
||
|
||
const datasets = Object.entries(data).map(([key, inputData], index) => ({
|
||
label: `Eingang ${Number(key) - 99}`,
|
||
data: inputData.map((point: any) => ({
|
||
x: point.t,
|
||
y: point.m,
|
||
})),
|
||
fill: false,
|
||
borderColor: colors[index % colors.length],
|
||
backgroundColor: colors[index % colors.length],
|
||
tension: 0.3,
|
||
}));
|
||
|
||
const chartData = {
|
||
datasets,
|
||
};
|
||
|
||
const chartOptions = {
|
||
responsive: true,
|
||
plugins: {
|
||
legend: {
|
||
position: "top" as const,
|
||
labels: {
|
||
usePointStyle: true,
|
||
},
|
||
},
|
||
tooltip: {
|
||
mode: "index" as const,
|
||
intersect: false,
|
||
},
|
||
},
|
||
scales: {
|
||
x: {
|
||
type: "time" as const,
|
||
time: {
|
||
unit: "hour",
|
||
tooltipFormat: "HH:mm",
|
||
displayFormats: {
|
||
hour: "HH:mm",
|
||
},
|
||
},
|
||
title: {
|
||
display: true,
|
||
text: "Zeit",
|
||
},
|
||
},
|
||
y: {
|
||
title: {
|
||
display: true,
|
||
text: "Messwert",
|
||
},
|
||
},
|
||
},
|
||
};
|
||
|
||
return (
|
||
<div className="w-full bg-white shadow-md rounded-lg p-4 border border-gray-200">
|
||
<h2 className="text-lg font-bold mb-4">
|
||
Alle analogen Eingänge – Verlauf der letzten 24 Stunden
|
||
</h2>
|
||
|
||
{isLoading ? (
|
||
<div className="text-center text-gray-500">Lade Daten...</div>
|
||
) : error ? (
|
||
<div className="text-center text-red-500">Fehler: {error}</div>
|
||
) : (
|
||
<div className="w-full h-[400px]">
|
||
<Line data={chartData} options={chartOptions} />
|
||
</div>
|
||
)}
|
||
</div>
|
||
);
|
||
}
|