205 lines
6.6 KiB
TypeScript
205 lines
6.6 KiB
TypeScript
import React, { useState, useEffect } from 'react'
|
|
import { Line } from 'react-chartjs-2'
|
|
import useChartStore from '../../../../store/useChartStore';
|
|
import { useWidgetStore } from '../../../../store/useWidgetStore';
|
|
import axios from 'axios';
|
|
import io from "socket.io-client";
|
|
|
|
const WarehouseThroughputComponent = ({
|
|
object
|
|
}: any) => {
|
|
|
|
const [measurements, setmeasurements] = useState<any>({});
|
|
const [duration, setDuration] = useState("1h")
|
|
const [name, setName] = useState(object.header ? object.header : '')
|
|
const [chartData, setChartData] = useState<{ labels: string[]; datasets: any[] }>({
|
|
labels: [],
|
|
datasets: [],
|
|
});
|
|
const email = localStorage.getItem("email") || "";
|
|
const organization = email?.split("@")[1]?.split(".")[0]
|
|
const { header, flotingDuration, flotingMeasurements } = useChartStore();
|
|
const { selectedChartId } = useWidgetStore();
|
|
|
|
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
|
|
|
|
const lineGraphData = {
|
|
labels: [
|
|
"Jan",
|
|
"Feb",
|
|
"Mar",
|
|
"Apr",
|
|
"May",
|
|
"Jun",
|
|
"Jul",
|
|
"Aug",
|
|
"Sep",
|
|
"Oct",
|
|
"Nov",
|
|
"Dec",
|
|
], // Months of the year
|
|
datasets: [
|
|
{
|
|
label: "Throughput (units/month)",
|
|
data: [500, 400, 300, 450, 350, 250, 200, 300, 250, 150, 100, 150], // Example monthly data
|
|
borderColor: "#6f42c1", // Use the desired color for the line (purple)
|
|
backgroundColor: "rgba(111, 66, 193, 0.2)", // Use a semi-transparent purple for the fill
|
|
borderWidth: 2, // Line thickness
|
|
fill: true, // Enable fill for this dataset
|
|
pointRadius: 0, // Remove dots at each data point
|
|
tension: 0.5, // Smooth interpolation for the line
|
|
},
|
|
],
|
|
};
|
|
|
|
// Line graph options
|
|
const lineGraphOptions = {
|
|
responsive: true,
|
|
maintainAspectRatio: false, // Allow custom height/width adjustments
|
|
plugins: {
|
|
legend: {
|
|
display: false, // Hide legend
|
|
},
|
|
title: {
|
|
display: false, // No chart title needed
|
|
},
|
|
tooltip: {
|
|
callbacks: {
|
|
label: (context: any) => {
|
|
const value = context.parsed.y;
|
|
return `${value} units`; // Customize tooltip to display "units"
|
|
},
|
|
},
|
|
},
|
|
},
|
|
scales: {
|
|
x: {
|
|
grid: {
|
|
display: false, // Hide x-axis grid lines
|
|
},
|
|
ticks: {
|
|
maxRotation: 0, // Prevent label rotation
|
|
autoSkip: false, // Display all months
|
|
font: {
|
|
size: 8, // Adjust font size for readability
|
|
color: "#ffffff", // Light text color for labels
|
|
},
|
|
},
|
|
},
|
|
y: {
|
|
display: true, // Show y-axis
|
|
grid: {
|
|
drawBorder: false, // Remove border line
|
|
color: "rgba(255, 255, 255, 0.2)", // Light gray color for grid lines
|
|
borderDash: [5, 5], // Dotted line style (array defines dash and gap lengths)
|
|
},
|
|
ticks: {
|
|
font: {
|
|
size: 8, // Adjust font size for readability
|
|
color: "#ffffff", // Light text color for ticks
|
|
},
|
|
},
|
|
},
|
|
},
|
|
elements: {
|
|
line: {
|
|
tension: 0.5, // Smooth interpolation for the line
|
|
},
|
|
},
|
|
};
|
|
|
|
|
|
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 ?? [],
|
|
borderColor: "#6f42c1", // Use the desired color for the line (purple)
|
|
backgroundColor: "rgba(111, 66, 193, 0.2)", // Use a semi-transparent purple for the fill
|
|
borderWidth: 2, // Line thickness
|
|
fill: true, // Enable fill for this dataset
|
|
pointRadius: 0, // Remove dots at each data point
|
|
tension: 0.5, // Smooth interpolation for the line
|
|
};
|
|
});
|
|
|
|
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 (object?.id !== "") {
|
|
try {
|
|
const response = await axios.get(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/A_floatWidget/${object?.id}/${organization}`);
|
|
if (response.status === 200) {
|
|
setmeasurements(response.data.Data.measurements)
|
|
setDuration(response.data.Data.duration)
|
|
setName(response.data.header)
|
|
} else {
|
|
console.log("Unexpected response:", response);
|
|
}
|
|
} catch (error) {
|
|
console.error("There was an error!", error);
|
|
}
|
|
}
|
|
}
|
|
|
|
useEffect(() => {
|
|
fetchSavedInputes();
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
if (selectedChartId?.id === object?.id) {
|
|
fetchSavedInputes();
|
|
}
|
|
}
|
|
,[header, flotingDuration, flotingMeasurements])
|
|
|
|
|
|
return (
|
|
<>
|
|
<div className="header">
|
|
<h2>{name}</h2>
|
|
{/* <p>
|
|
<span>(+5) more</span> in 2025
|
|
</p> */}
|
|
</div>
|
|
<div className="lineGraph" style={{ height: "100%" }}>
|
|
<Line data={ Object.keys(measurements).length > 0 ? chartData : lineGraphData} options={lineGraphOptions} />
|
|
</div>
|
|
</>
|
|
)
|
|
}
|
|
|
|
export default WarehouseThroughputComponent |