Merge remote-tracking branch 'origin/realTimeVisulization' into simulation

This commit is contained in:
2025-03-31 19:39:58 +05:30
31 changed files with 1575 additions and 971 deletions

View File

@@ -306,34 +306,20 @@ export const DraggableWidget = ({
)}
{widget.type === "doughnut" && (
<DoughnutGraphComponent
id={widget.id}
type={widget.type}
title={widget.title}
fontSize={widget.fontSize}
fontWeight={widget.fontWeight}
data={{
measurements: [
{ name: "testDevice", fields: "powerConsumption" },
{ name: "furnace", fields: "powerConsumption" },
],
interval: 1000,
duration: "1h",
}}
/>
)}
{widget.type === "polarArea" && (
<PolarAreaGraphComponent
id={widget.id}
type={widget.type}
title={widget.title}
fontSize={widget.fontSize}
fontWeight={widget.fontWeight}
data={{
measurements: [
{ name: "testDevice", fields: "powerConsumption" },
{ name: "furnace", fields: "powerConsumption" },
],
interval: 1000,
duration: "1h",
}}
/>
)}
</div>

View File

@@ -10,6 +10,10 @@ import { determinePosition } from "./functions/determinePosition";
import { getActiveProperties } from "./functions/getActiveProperties";
import { addingFloatingWidgets } from "../../../services/realTimeVisulization/zoneData/addFloatingWidgets";
import TotalCardComponent from "../realTimeVis/floating/TotalCardComponent";
import WarehouseThroughputComponent from "../realTimeVis/floating/WarehouseThroughputComponent";
import FleetEfficiencyComponent from "../realTimeVis/floating/FleetEfficiencyComponent";
import { useWidgetStore } from "../../../store/useWidgetStore";
const DroppedObjects: React.FC = () => {
const zones = useDroppedObjectsStore((state) => state.zones);
@@ -21,6 +25,7 @@ const DroppedObjects: React.FC = () => {
index: number;
} | null>(null);
const [offset, setOffset] = useState<[number, number] | null>(null);
const { setSelectedChartId } = useWidgetStore();
const positionRef = useRef<[number, number] | null>(null);
const animationRef = useRef<number | null>(null);
const { activeModule } = useModuleStore();
@@ -29,9 +34,13 @@ const DroppedObjects: React.FC = () => {
const zoneEntries = Object.entries(zones);
if (zoneEntries.length === 0) return null; // No zone, nothing to render
const [zoneName, zone] = zoneEntries[0]; // Only render the first zone
console.log("zone", zone);
// Handle pointer down event
function handlePointerDown(event: React.PointerEvent, index: number) {
const obj = zone.objects[index];
const container = document.getElementById("real-time-vis-canvas");
if (!container) return;
@@ -194,53 +203,21 @@ const DroppedObjects: React.FC = () => {
// transition: draggingIndex?.index === index ? "none" : "transform 0.1s ease-out",
}}
onPointerDown={(event) => handlePointerDown(event, index)}
onClick={() => {
setSelectedChartId(obj)
}}
>
{obj.className === "floating total-card" ? (
<>
<div className="header-wrapper">
<div className="header">{obj.header}</div>
<div className="data-values">
<div className="value">{obj.value}</div>
<div className="per">{obj.per}</div>
</div>
</div>
<div className="icon">
<WalletIcon />
</div>
<TotalCardComponent object={obj} />
</>
) : obj.className === "warehouseThroughput floating" ? (
<>
<div className="header">
<h2>Warehouse Throughput</h2>
<p>
<span>(+5) more</span> in 2025
</p>
</div>
<div className="lineGraph" style={{ height: "100%" }}>
{/* <Line data={lineGraphData} options={lineGraphOptions} /> */}
</div>
<WarehouseThroughputComponent />
</>
) : obj.className === "fleetEfficiency floating" ? (
<>
<h2 className="header">Fleet Efficiency</h2>
<div className="progressContainer">
<div className="progress">
<div className="barOverflow">
<div
className="bar"
style={{ transform: `rotate(${obj.value}deg)` }}
></div>
</div>
</div>
</div>
<div className="scaleLabels">
<span>0%</span>
<div className="centerText">
<div className="percentage">{obj.per}%</div>
<div className="status">Optimal</div>
</div>
<span>100%</span>
</div>
<FleetEfficiencyComponent object={obj} />
</>
) : null}
</div>

View File

@@ -211,9 +211,10 @@ const BarGraphComponent = ({
fontWeight = "Regular",
}: ChartComponentProps) => {
const { themeColor } = useThemeStore();
const { measurements: chartMeasurements, duration: chartDuration } = useChartStore();
const { measurements: chartMeasurements, duration: chartDuration, name: widgetName } = useChartStore();
const [measurements, setmeasurements] = useState<any>({});
const [duration, setDuration] = useState("1h")
const [name, setName] = useState("Widget")
const [chartData, setChartData] = useState<{ labels: string[]; datasets: any[] }>({
labels: [],
datasets: [],
@@ -236,6 +237,10 @@ const BarGraphComponent = ({
],
};
useEffect(() => {
console.log("titleeeeeeeeeeeeeeeeeee",title);
},[])
// Memoize Theme Colors
const buttonActionColor = useMemo(() => themeColor[0] || "#5c87df", [themeColor]);
const buttonAbortColor = useMemo(() => themeColor[1] || "#ffffff", [themeColor]);
@@ -270,7 +275,7 @@ const BarGraphComponent = ({
plugins: {
title: {
display: true,
text: title,
text: name,
font: chartFontStyle,
},
legend: {
@@ -285,7 +290,7 @@ const BarGraphComponent = ({
},
},
}),
[title, chartFontStyle]
[title, chartFontStyle, name]
);
// useEffect(() => {console.log(measurements);
@@ -304,15 +309,12 @@ const BarGraphComponent = ({
const startStream = () => {
console.log("inputtttttttttt",inputData);
socket.emit("lineInput", inputData);
};
socket.on("connect", startStream);
socket.on("lineOutput", (response) => {
console.log("responce dataaaaaaaaa",response.data);
const responseData = response.data;
// Extract timestamps and values
@@ -347,6 +349,7 @@ const BarGraphComponent = ({
if (response.status === 200) {
setmeasurements(response.data.Data.measurements)
setDuration(response.data.Data.duration)
setName(response.data.widgetName)
} else {
console.log("Unexpected response:", response);
}
@@ -365,7 +368,7 @@ const BarGraphComponent = ({
fetchSavedInputes();
}
}
,[chartMeasurements, chartDuration])
,[chartMeasurements, chartDuration, widgetName])
return <Bar data={Object.keys(measurements).length > 0 ? chartData : defaultData} options={options} />;
};

View File

@@ -1,22 +1,64 @@
import { useMemo } from "react";
import { Doughnut, Line } from "react-chartjs-2";
import React, { useEffect, useMemo, useState } from "react";
import { Doughnut } from "react-chartjs-2";
import io from "socket.io-client";
import { useThemeStore } from "../../../../store/useThemeStore";
import useChartStore from "../../../../store/useChartStore";
import { useWidgetStore } from "../../../../store/useWidgetStore";
import axios from "axios";
interface ChartComponentProps {
id: string;
type: any;
title: string;
fontFamily?: string;
fontSize?: string;
fontWeight?: "Light" | "Regular" | "Bold";
data: any;
}
const DoughnutGraphComponent = ({
id,
type,
title,
fontFamily,
fontSize,
fontWeight = "Regular",
}: ChartComponentProps) => {
// Memoize Font Weight Mapping
const { themeColor } = useThemeStore();
const { measurements: chartMeasurements, duration: chartDuration, name: widgetName } = useChartStore();
const [measurements, setmeasurements] = useState<any>({});
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(() => {
console.log("titleeeeeeeeeeeeeeeeeee",title);
},[])
// 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,
@@ -26,19 +68,9 @@ const DoughnutGraphComponent = ({
[]
);
// Parse and Memoize Font Size
const fontSizeValue = useMemo(
() => (fontSize ? parseInt(fontSize) : 12),
[fontSize]
);
const fontSizeValue = useMemo(() => (fontSize ? parseInt(fontSize) : 12), [fontSize]);
const fontWeightValue = useMemo(() => chartFontWeightMap[fontWeight], [fontWeight, chartFontWeightMap]);
// Determine and Memoize Font Weight
const fontWeightValue = useMemo(
() => chartFontWeightMap[fontWeight],
[fontWeight, chartFontWeightMap]
);
// Memoize Chart Font Style
const chartFontStyle = useMemo(
() => ({
family: fontFamily || "Arial",
@@ -48,46 +80,110 @@ const DoughnutGraphComponent = ({
[fontFamily, fontSizeValue, fontWeightValue]
);
const options = useMemo(
() => ({
responsive: true,
maintainAspectRatio: false,
plugins: {
title: {
display: true,
text: title,
font: chartFontStyle,
},
legend: {
display: false,
},
},
scales: {
x: {
ticks: {
display: false, // This hides the x-axis labels
// Memoize Chart Options
const options = useMemo(
() => ({
responsive: true,
maintainAspectRatio: false,
plugins: {
title: {
display: true,
text: name,
font: chartFontStyle,
},
legend: {
display: false,
},
},
},
}),
[title, chartFontStyle]
);
scales: {
// x: {
// ticks: {
// display: true, // This hides the x-axis labels
// },
// },
},
}),
[title, chartFontStyle, name]
);
const chartData = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [
{
label: "My First Dataset",
data: [65, 59, 80, 81, 56, 55, 40],
backgroundColor: "#6f42c1", // Updated to #6f42c1 (Purple)
borderColor: "#ffffff", // Keeping border color white
borderWidth: 2,
fill: false,
},
],
};
// useEffect(() => {console.log(measurements);
// },[measurements])
return <Doughnut data={chartData} options={options} />;
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 <Doughnut data={Object.keys(measurements).length > 0 ? chartData : defaultData} options={options} />;
};
export default DoughnutGraphComponent;
export default DoughnutGraphComponent;

View File

@@ -24,9 +24,10 @@ const LineGraphComponent = ({
fontWeight = "Regular",
}: ChartComponentProps) => {
const { themeColor } = useThemeStore();
const { measurements: chartMeasurements, duration: chartDuration } = useChartStore();
const { measurements: chartMeasurements, duration: chartDuration, name: widgetName } = useChartStore();
const [measurements, setmeasurements] = useState<any>({});
const [duration, setDuration] = useState("1h")
const [name, setName] = useState("Widget")
const [chartData, setChartData] = useState<{ labels: string[]; datasets: any[] }>({
labels: [],
datasets: [],
@@ -49,6 +50,10 @@ const LineGraphComponent = ({
],
};
useEffect(() => {
console.log("titleeeeeeeeeeeeeeeeeee",title);
},[])
// Memoize Theme Colors
const buttonActionColor = useMemo(() => themeColor[0] || "#5c87df", [themeColor]);
const buttonAbortColor = useMemo(() => themeColor[1] || "#ffffff", [themeColor]);
@@ -83,7 +88,7 @@ const LineGraphComponent = ({
plugins: {
title: {
display: true,
text: title,
text: name,
font: chartFontStyle,
},
legend: {
@@ -98,7 +103,7 @@ const LineGraphComponent = ({
},
},
}),
[title, chartFontStyle]
[title, chartFontStyle, name]
);
// useEffect(() => {console.log(measurements);
@@ -157,6 +162,7 @@ const LineGraphComponent = ({
if (response.status === 200) {
setmeasurements(response.data.Data.measurements)
setDuration(response.data.Data.duration)
setName(response.data.widgetName)
} else {
console.log("Unexpected response:", response);
}
@@ -175,7 +181,7 @@ const LineGraphComponent = ({
fetchSavedInputes();
}
}
,[chartMeasurements, chartDuration])
,[chartMeasurements, chartDuration, widgetName])
return <Line data={Object.keys(measurements).length > 0 ? chartData : defaultData} options={options} />;
};

View File

@@ -210,9 +210,10 @@ const PieChartComponent = ({
fontWeight = "Regular",
}: ChartComponentProps) => {
const { themeColor } = useThemeStore();
const { measurements: chartMeasurements, duration: chartDuration } = useChartStore();
const { measurements: chartMeasurements, duration: chartDuration, name: widgetName } = useChartStore();
const [measurements, setmeasurements] = useState<any>({});
const [duration, setDuration] = useState("1h")
const [name, setName] = useState("Widget")
const [chartData, setChartData] = useState<{ labels: string[]; datasets: any[] }>({
labels: [],
datasets: [],
@@ -235,6 +236,10 @@ const PieChartComponent = ({
],
};
useEffect(() => {
console.log("titleeeeeeeeeeeeeeeeeee",title);
},[])
// Memoize Theme Colors
const buttonActionColor = useMemo(() => themeColor[0] || "#5c87df", [themeColor]);
const buttonAbortColor = useMemo(() => themeColor[1] || "#ffffff", [themeColor]);
@@ -269,7 +274,7 @@ const PieChartComponent = ({
plugins: {
title: {
display: true,
text: title,
text: name,
font: chartFontStyle,
},
legend: {
@@ -284,7 +289,7 @@ const PieChartComponent = ({
// },
},
}),
[title, chartFontStyle]
[title, chartFontStyle, name]
);
// useEffect(() => {console.log(measurements);
@@ -343,6 +348,7 @@ const PieChartComponent = ({
if (response.status === 200) {
setmeasurements(response.data.Data.measurements)
setDuration(response.data.Data.duration)
setName(response.data.widgetName)
} else {
console.log("Unexpected response:", response);
}
@@ -361,7 +367,7 @@ const PieChartComponent = ({
fetchSavedInputes();
}
}
,[chartMeasurements, chartDuration])
,[chartMeasurements, chartDuration, widgetName])
return <Pie data={Object.keys(measurements).length > 0 ? chartData : defaultData} options={options} />;
};

View File

@@ -1,22 +1,64 @@
import { useMemo } from "react";
import { Line, PolarArea } from "react-chartjs-2";
import React, { useEffect, useMemo, useState } from "react";
import { PolarArea } from "react-chartjs-2";
import io from "socket.io-client";
import { useThemeStore } from "../../../../store/useThemeStore";
import useChartStore from "../../../../store/useChartStore";
import { useWidgetStore } from "../../../../store/useWidgetStore";
import axios from "axios";
interface ChartComponentProps {
id: string;
type: any;
title: string;
fontFamily?: string;
fontSize?: string;
fontWeight?: "Light" | "Regular" | "Bold";
data: any;
}
const PolarAreaGraphComponent = ({
id,
type,
title,
fontFamily,
fontSize,
fontWeight = "Regular",
}: ChartComponentProps) => {
// Memoize Font Weight Mapping
const { themeColor } = useThemeStore();
const { measurements: chartMeasurements, duration: chartDuration, name: widgetName } = useChartStore();
const [measurements, setmeasurements] = useState<any>({});
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(() => {
console.log("titleeeeeeeeeeeeeeeeeee",title);
},[])
// 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,
@@ -26,19 +68,9 @@ const PolarAreaGraphComponent = ({
[]
);
// Parse and Memoize Font Size
const fontSizeValue = useMemo(
() => (fontSize ? parseInt(fontSize) : 12),
[fontSize]
);
const fontSizeValue = useMemo(() => (fontSize ? parseInt(fontSize) : 12), [fontSize]);
const fontWeightValue = useMemo(() => chartFontWeightMap[fontWeight], [fontWeight, chartFontWeightMap]);
// Determine and Memoize Font Weight
const fontWeightValue = useMemo(
() => chartFontWeightMap[fontWeight],
[fontWeight, chartFontWeightMap]
);
// Memoize Chart Font Style
const chartFontStyle = useMemo(
() => ({
family: fontFamily || "Arial",
@@ -48,46 +80,110 @@ const PolarAreaGraphComponent = ({
[fontFamily, fontSizeValue, fontWeightValue]
);
const options = useMemo(
() => ({
responsive: true,
maintainAspectRatio: false,
plugins: {
title: {
display: true,
text: title,
font: chartFontStyle,
},
legend: {
display: false,
},
},
scales: {
x: {
ticks: {
display: false, // This hides the x-axis labels
// Memoize Chart Options
const options = useMemo(
() => ({
responsive: true,
maintainAspectRatio: false,
plugins: {
title: {
display: true,
text: name,
font: chartFontStyle,
},
legend: {
display: false,
},
},
},
}),
[title, chartFontStyle]
);
scales: {
// x: {
// ticks: {
// display: true, // This hides the x-axis labels
// },
// },
},
}),
[title, chartFontStyle, name]
);
const chartData = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [
{
label: "My First Dataset",
data: [65, 59, 80, 81, 56, 55, 40],
backgroundColor: "#6f42c1", // Updated to #6f42c1 (Purple)
borderColor: "#ffffff", // Keeping border color white
borderWidth: 2,
fill: false,
},
],
};
// useEffect(() => {console.log(measurements);
// },[measurements])
return <PolarArea data={chartData} options={options} />;
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 <PolarArea data={Object.keys(measurements).length > 0 ? chartData : defaultData} options={options} />;
};
export default PolarAreaGraphComponent;
export default PolarAreaGraphComponent;

View File

@@ -0,0 +1,33 @@
import React from 'react'
type Props = {}
const FleetEfficiencyComponent = ({
object
}: any) => {
return (
<>
<h2 className="header">Fleet Efficiency</h2>
<div className="progressContainer">
<div className="progress">
<div className="barOverflow">
<div
className="bar"
style={{ transform: `rotate(${object.value}deg)` }}
></div>
</div>
</div>
</div>
<div className="scaleLabels">
<span>0%</span>
<div className="centerText">
<div className="percentage">{object.per}%</div>
<div className="status">Optimal</div>
</div>
<span>100%</span>
</div>
</>
)
}
export default FleetEfficiencyComponent

View File

@@ -0,0 +1,29 @@
import React from 'react'
import { WalletIcon } from '../../../icons/3dChartIcons'
import { useWidgetStore } from '../../../../store/useWidgetStore';
const TotalCardComponent = ({
object
}: any) => {
const { setSelectedChartId } =
useWidgetStore();
return (
<>
<div className="header-wrapper" onClick={() => {
setSelectedChartId(object.id)
}}>
<div className="header">{object.header}</div>
<div className="data-values">
<div className="value">{object.value}</div>
<div className="per">{object.per}</div>
</div>
</div>
<div className="icon">
<WalletIcon />
</div>
</>
)
}
export default TotalCardComponent

View File

@@ -0,0 +1,132 @@
import React, { useState } from 'react'
import { Line } from 'react-chartjs-2'
import axios from 'axios';
const WarehouseThroughputComponent = ({
object
}: any) => {
const [measurements, setmeasurements] = useState<any>({});
const [duration, setDuration] = useState("1h")
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
},
},
};
// const fetchSavedInputes = async() => {
// if (object.id !== "") {
// try {
// const response = await axios.get(`http://${process.env.REACT_APP_SERVER_REST_API_LOCAL_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);
// }
// }
// }
return (
<>
<div className="header">
<h2>Warehouse Throughput</h2>
<p>
<span>(+5) more</span> in 2025
</p>
</div>
<div className="lineGraph" style={{ height: "100%" }}>
<Line data={lineGraphData} options={lineGraphOptions} />
</div>
</>
)
}
export default WarehouseThroughputComponent