feat: Zoom wird beim Wechsel des Zeitraums im Detail-Chart automatisch zurückgesetzt

This commit is contained in:
ISA
2025-07-10 14:08:09 +02:00
parent eae69d4392
commit 7cabbafad5
6 changed files with 158 additions and 57 deletions

View File

@@ -6,6 +6,6 @@ NEXT_PUBLIC_USE_MOCK_BACKEND_LOOP_START=false
NEXT_PUBLIC_EXPORT_STATIC=false
NEXT_PUBLIC_USE_CGI=false
# App-Versionsnummer
NEXT_PUBLIC_APP_VERSION=1.6.574
NEXT_PUBLIC_APP_VERSION=1.6.577
NEXT_PUBLIC_CPL_MODE=json # json (Entwicklungsumgebung) oder jsSimulatedProd (CPL ->CGI-Interface-Simulator) oder production (CPL-> CGI-Interface Platzhalter)

View File

@@ -5,5 +5,5 @@ NEXT_PUBLIC_CPL_API_PATH=/CPL
NEXT_PUBLIC_EXPORT_STATIC=true
NEXT_PUBLIC_USE_CGI=true
# App-Versionsnummer
NEXT_PUBLIC_APP_VERSION=1.6.574
NEXT_PUBLIC_APP_VERSION=1.6.577
NEXT_PUBLIC_CPL_MODE=production

View File

@@ -1,3 +1,18 @@
## [1.6.577] 2025-07-10
- fix(detail-chart): X-Achse zeigt jetzt Datum und Uhrzeit ohne Sekunden (z.B. 10.07.2025 14:32)
---
## [1.6.576] 2025-07-10
- fix(detail-chart): X-Achse zeigt jetzt Datum und Uhrzeit ohne Sekunden (z.B. 10.07.2025 14:32)
---
## [1.6.575] 2025-07-10
- fix(detail-chart): X-Achse zeigt jetzt Datum und Uhrzeit ohne Sekunden (z.B. 10.07.2025 14:32)
---
## [1.6.574] 2025-07-10
- fix(system-charts): Zeitachse angepasst aktuelle Daten jetzt rechts wie bei Kabelüberwachung

View File

@@ -1,11 +1,111 @@
// components/main/system/DetailModal.tsx
"use client";
import React from "react";
import React, { useEffect, useRef } from "react";
import { Line } from "react-chartjs-2";
import { useSelector } from "react-redux";
import { RootState } from "@/redux/store";
import { Listbox } from "@headlessui/react";
import {
Chart as ChartJS,
LineElement,
PointElement,
CategoryScale,
LinearScale,
Title,
Tooltip,
Legend,
Filler,
TimeScale,
} from "chart.js";
import "chartjs-adapter-date-fns";
import { de } from "date-fns/locale";
ChartJS.register(
LineElement,
PointElement,
CategoryScale,
LinearScale,
Title,
Tooltip,
Legend,
Filler,
TimeScale
);
const initialChartData = {
datasets: [
{
label: "Messdaten",
data: [],
borderColor: "rgba(61, 176, 242, 1)",
backgroundColor: "rgba(59,130,246,0.3)",
borderWidth: 2,
pointRadius: 0,
tension: 0.1,
fill: false,
},
],
};
const chartOptions = {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: { position: "top" as const },
title: {
display: true,
text: "Verlauf",
},
tooltip: {
mode: "index" as const,
intersect: false,
callbacks: {
label: function (ctx: any) {
return `Messwert: ${ctx.parsed.y}`;
},
title: function (items: any[]) {
const date = items[0].parsed.x;
return `Zeitpunkt: ${new Date(date).toLocaleString("de-DE")}`;
},
},
},
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: "day" as const,
tooltipFormat: "dd.MM.yyyy HH:mm",
displayFormats: {
day: "dd.MM.yyyy",
},
},
adapters: {
date: { locale: de },
},
title: {
display: true,
text: "Zeit",
},
},
y: {
title: {
display: true,
text: "Messwert",
},
},
},
};
type Props = {
isOpen: boolean;
selectedKey: string | null;
@@ -23,6 +123,8 @@ export const DetailModal = ({
zeitraum,
setZeitraum,
}: Props) => {
const chartRef = useRef<any>(null);
const reduxData: ReduxDataEntry[] = useSelector((state: RootState) => {
switch (selectedKey) {
case "+5V":
@@ -42,50 +144,50 @@ export const DetailModal = ({
}
});
const reversedData = [...reduxData].reverse();
const labels = reversedData.map((e) =>
new Date(e.t).toLocaleString("de-DE", {
day: "2-digit",
month: "2-digit",
year: "numeric",
hour: "2-digit",
minute: "2-digit",
second: undefined, // Sekunden ausschließen
})
);
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();
}, []);
const values = reversedData.map((e) => e.i);
useEffect(() => {
if (chartRef.current) {
const chart = chartRef.current;
chart.data.datasets[0].data = [...reduxData]
.reverse()
.map((p) => ({ x: new Date(p.t), y: p.i }));
chart.update("none");
}
}, [reduxData]);
const baseOptions = {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: false,
grid: { color: "rgba(200,200,200,0.2)" },
title: { display: true, text: "Wert" },
},
x: {
grid: { color: "rgba(200,200,200,0.2)" },
title: { display: true, text: "Zeit" },
},
},
plugins: {
legend: { position: "bottom" as const },
title: { display: true, text: `Verlauf ${selectedKey}` },
},
};
useEffect(() => {
if (chartRef.current && selectedKey) {
chartRef.current.options.plugins.title.text = `Verlauf ${selectedKey}`;
chartRef.current.update("none");
}
}, [selectedKey]);
useEffect(() => {
if (chartRef.current) {
chartRef.current.resetZoom();
}
}, [zeitraum]);
if (!isOpen || !selectedKey) return null;
return (
<div className="fixed inset-0 bg-black bg-opacity-40 flex items-center justify-center z-50">
<div className="bg-white p-6 rounded-xl w-[50%] h-[60%] overflow-auto shadow-2xl">
<div className="bg-white p-6 rounded-xl w-[50%] h-[60%] overflow-auto shadow-2xl">
<div className="flex justify-between items-center mb-4">
<h2 className="text-xl font-semibold">
Detailansicht: {selectedKey}
</h2>
<button onClick={onClose} className="text-2xl hover:text-gray-200">
<i className="bi bi-x-circle-fill"></i>
</button>
@@ -147,23 +249,7 @@ export const DetailModal = ({
</div>
<div className="h-[85%]">
<Line
data={{
labels,
datasets: [
{
label: selectedKey,
data: values,
// littwin-blue
// rgb(61, 176, 242),
borderColor: "rgba(61, 176, 242, 1)",
fill: false,
},
],
}}
options={baseOptions}
/>
<Line ref={chartRef} data={initialChartData} options={chartOptions} />
</div>
</div>
</div>

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "cpl-v4",
"version": "1.6.574",
"version": "1.6.577",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "cpl-v4",
"version": "1.6.574",
"version": "1.6.577",
"dependencies": {
"@fontsource/roboto": "^5.1.0",
"@headlessui/react": "^2.2.4",

View File

@@ -1,6 +1,6 @@
{
"name": "cpl-v4",
"version": "1.6.574",
"version": "1.6.577",
"private": true,
"scripts": {
"dev": "next dev",