import React, { useEffect, useMemo, useState } from "react"; import { Line } from "react-chartjs-2"; import io from "socket.io-client"; import axios from "axios"; import { useThemeStore } from "../../../../../store/useThemeStore"; import useChartStore from "../../../../../store/useChartStore"; import { useWidgetStore } from "../../../../../store/useWidgetStore"; interface ChartComponentProps { id: string; type: any; title: string; fontFamily?: string; fontSize?: string; fontWeight?: "Light" | "Regular" | "Bold"; } const LineGraphComponent = ({ id, type, title, fontFamily, fontSize, fontWeight = "Regular", }: ChartComponentProps) => { const { themeColor } = useThemeStore(); const { measurements: chartMeasurements, duration: chartDuration, name: widgetName, } = useChartStore(); const [measurements, setmeasurements] = useState({}); const [duration, setDuration] = useState("1h"); const [name, setName] = useState("Widget"); const [chartData, setChartData] = useState<{ labels: string[]; datasets: any[]; }>({ labels: [], datasets: [], }); const { selectedChartId } = useWidgetStore(); const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL; const email = localStorage.getItem("email") || ""; const organization = email?.split("@")[1]?.split(".")[0]; const defaultData = { labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"], datasets: [ { label: "Dataset", data: [12, 19, 3, 5, 2, 3], backgroundColor: ["#6f42c1"], borderColor: "#b392f0", borderWidth: 1, }, ], }; useEffect(() => {}, []); // Memoize Theme Colors const buttonActionColor = useMemo( () => themeColor[0] || "#5c87df", [themeColor] ); const buttonAbortColor = useMemo( () => themeColor[1] || "#ffffff", [themeColor] ); // Memoize Font Styling const chartFontWeightMap = useMemo( () => ({ Light: "lighter" as const, Regular: "normal" as const, Bold: "bold" as const, }), [] ); const fontSizeValue = useMemo( () => (fontSize ? parseInt(fontSize) : 12), [fontSize] ); const fontWeightValue = useMemo( () => chartFontWeightMap[fontWeight], [fontWeight, chartFontWeightMap] ); const chartFontStyle = useMemo( () => ({ family: fontFamily || "Arial", size: fontSizeValue, weight: fontWeightValue, }), [fontFamily, fontSizeValue, fontWeightValue] ); // Memoize Chart Options const options = useMemo( () => ({ responsive: true, maintainAspectRatio: false, plugins: { title: { display: true, text: name, font: chartFontStyle, }, legend: { display: false, }, }, scales: { x: { ticks: { display: true, // This hides the x-axis labels }, }, }, }), [title, chartFontStyle, name] ); // useEffect(() => {console.log(measurements); // },[measurements]) useEffect(() => { if (!iotApiUrl || !measurements || Object.keys(measurements).length === 0) return; const socket = io(`http://${iotApiUrl}`); const inputData = { measurements, duration, interval: 1000, }; const startStream = () => { socket.emit("lineInput", inputData); }; socket.on("connect", startStream); socket.on("lineOutput", (response) => { const responseData = response.data; // Extract timestamps and values const labels = responseData.time; const datasets = Object.keys(measurements).map((key) => { const measurement = measurements[key]; const datasetKey = `${measurement.name}.${measurement.fields}`; return { label: datasetKey, data: responseData[datasetKey]?.values ?? [], backgroundColor: "#6f42c1", borderColor: "#b392f0", borderWidth: 1, }; }); setChartData({ labels, datasets }); }); return () => { socket.off("lineOutput"); socket.emit("stop_stream"); // Stop streaming when component unmounts socket.disconnect(); }; }, [measurements, duration, iotApiUrl]); const fetchSavedInputes = async () => { if (id !== "") { try { const response = await axios.get( `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/WidgetData/${id}/${organization}` ); if (response.status === 200) { setmeasurements(response.data.Data.measurements); setDuration(response.data.Data.duration); setName(response.data.widgetName); } else { console.log("Unexpected response:", response); } } catch (error) { console.error("There was an error!", error); } } }; useEffect(() => { fetchSavedInputes(); }, []); useEffect(() => { if (selectedChartId?.id === id) { fetchSavedInputes(); } }, [chartMeasurements, chartDuration, widgetName]); return ( 0 ? chartData : defaultData} options={options} /> ); }; export default LineGraphComponent;