Merge branch 'realTimeVisulization' of http://185.100.212.76:7776/Dwinzo-Beta/Dwinzo_dev into realTimeVisulization

This commit is contained in:
2025-04-01 14:27:19 +05:30
parent 6f483baf8d
commit 03e7c32bfb
15 changed files with 741 additions and 119 deletions

View File

@@ -379,14 +379,13 @@ const DroppedObjects: React.FC = () => {
</>
) : obj.className === "warehouseThroughput floating" ? (
<>
<WarehouseThroughputComponent />
<WarehouseThroughputComponent object={obj}/>
</>
) : obj.className === "fleetEfficiency floating" ? (
<>
<FleetEfficiencyComponent object={obj} />
</>
) : null}
{renderObjectContent(obj)}
<div
className="icon kebab"
onClick={(event) => handleKebabClick(obj.id, event)}

View File

@@ -1,8 +1,8 @@
const FleetEfficiency = () => {
const progress = 75; // Example progress value (0-100)
const progress = 50; // Example progress value (0-100)
// Calculate the rotation angle for the progress bar
const rotationAngle = -90 + progress * 3.6; // Progress starts from the left (-90°)
const rotationAngle = 45 + progress * 1.8;
const handleDragStart = (event: React.DragEvent<HTMLDivElement>) => {
const rect = event.currentTarget.getBoundingClientRect(); // Get position

View File

@@ -1,10 +1,11 @@
import React from 'react'
import React,{ useEffect, useState} from 'react'
type Props = {}
const FleetEfficiencyComponent = ({object}: any) => {
const [ progress, setProgress ] = useState<any>(0)
const FleetEfficiencyComponent = ({
object
}: any) => {
// Calculate the rotation angle for the progress bar
const rotationAngle = 45 + progress * 1.8;
return (
<>
<h2 className="header">Fleet Efficiency</h2>
@@ -13,7 +14,7 @@ const FleetEfficiencyComponent = ({
<div className="barOverflow">
<div
className="bar"
style={{ transform: `rotate(${object.value}deg)` }}
style={{ transform: `rotate(${rotationAngle}deg)` }}
></div>
</div>
</div>
@@ -21,7 +22,7 @@ const FleetEfficiencyComponent = ({
<div className="scaleLabels">
<span>0%</span>
<div className="centerText">
<div className="percentage">{object.per}%</div>
<div className="percentage">{progress}%</div>
<div className="status">Optimal</div>
</div>
<span>100%</span>

View File

@@ -1,6 +1,9 @@
import React, { useState } from 'react'
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
@@ -8,6 +11,17 @@ const WarehouseThroughputComponent = ({
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: [
@@ -95,35 +109,94 @@ const WarehouseThroughputComponent = ({
};
// const fetchSavedInputes = async() => {
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])
// 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>
<h2>{name}</h2>
{/* <p>
<span>(+5) more</span> in 2025
</p>
</p> */}
</div>
<div className="lineGraph" style={{ height: "100%" }}>
<Line data={lineGraphData} options={lineGraphOptions} />
<Line data={ Object.keys(measurements).length > 0 ? chartData : lineGraphData} options={lineGraphOptions} />
</div>
</>
)