added iot data and input card for 3D widget

This commit is contained in:
2025-04-02 18:06:51 +05:30
parent 721d3a3657
commit f0f7064b0a
9 changed files with 982 additions and 31 deletions

View File

@@ -1,5 +1,5 @@
import { Html } from "@react-three/drei";
import React from "react";
import React, { useEffect, useMemo, useState } from "react";
import { Bar } from "react-chartjs-2";
import {
Chart as ChartJS,
@@ -11,6 +11,11 @@ import {
Legend,
TooltipItem, // Import TooltipItem for typing
} from "chart.js";
import { ThroughputIcon } from "../../../icons/3dChartIcons";
import { useWidgetStore } from "../../../../store/useWidgetStore";
import useChartStore from "../../../../store/useChartStore";
import axios from "axios";
import io from "socket.io-client";
// Register ChartJS components
ChartJS.register(
@@ -22,12 +27,28 @@ ChartJS.register(
Legend
);
interface ProductionCapacityProps {
id: string;
type: string;
position: [number, number, number];
}
const ProductionCapacity : React.FC<ProductionCapacityProps> = ({ position }) => {
const ProductionCapacity : React.FC<ProductionCapacityProps> = ({ id, type, position }) => {
const { selectedChartId,setSelectedChartId } = useWidgetStore();
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 iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0]
// Chart data for a week
const chartData = {
const defaultChartData = {
labels: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"], // Days of the week
datasets: [
{
@@ -78,12 +99,94 @@ const ProductionCapacity : React.FC<ProductionCapacityProps> = ({ position }) =>
},
};
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", // Theme color
borderColor: "#6f42c1",
borderWidth: 1,
borderRadius: 8, // Rounded corners for the bars
borderSkipped: false, // Ensure all corners are rounded
};
});
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/widget3D/${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 (
<Html position={[position[0], position[1], position[2]]}
scale={[0.5, 0.5, 0.5]}
transform
sprite>
<div className="productionCapacity-wrapper card">
<div className="productionCapacity-wrapper card"
onClick={
() => setSelectedChartId({
id: id,
type: type
})
}>
<div className="headeproductionCapacityr-wrapper">
<div className="header">Production Capacity</div>
<div className="production-capacity">
@@ -104,7 +207,7 @@ const ProductionCapacity : React.FC<ProductionCapacityProps> = ({ position }) =>
</div>{" "}
<div className="bar-chart charts">
{/* Bar Chart */}
<Bar data={chartData} options={chartOptions} />
<Bar data={Object.keys(measurements).length > 0 ? chartData : defaultChartData } options={chartOptions} />
</div>
</div>
</Html>

View File

@@ -1,5 +1,5 @@
import { Html } from "@react-three/drei";
import React from "react";
import React, { useEffect, useMemo, useState } from "react";
import { Line } from "react-chartjs-2";
import {
Chart as ChartJS,
@@ -12,6 +12,10 @@ import {
ChartOptions,
} from "chart.js";
import { WavyIcon } from "../../../icons/3dChartIcons";
import { useWidgetStore } from "../../../../store/useWidgetStore";
import useChartStore from "../../../../store/useChartStore";
import axios from "axios";
import io from "socket.io-client";
// Register Chart.js components
ChartJS.register(
@@ -36,9 +40,24 @@ const SmoothLineGraphComponent: React.FC<SmoothLineGraphProps> = ({
return <Line data={data} options={options} />;
};
interface ReturnOfInvestmentProps {
id: string;
type: string;
position: [number, number, number];
}
const ReturnOfInvestment: React.FC<ReturnOfInvestmentProps> = ({ position }) => {
const ReturnOfInvestment: React.FC<ReturnOfInvestmentProps> = ({ id, type, position }) => {
const { selectedChartId,setSelectedChartId } = useWidgetStore();
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 iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0]
// Improved sample data for the smooth curve graph (single day)
const graphData: ChartData<"line"> = {
labels: [
@@ -107,16 +126,99 @@ const ReturnOfInvestment: React.FC<ReturnOfInvestmentProps> = ({ position }) =>
},
};
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, index) => {
const measurement = measurements[key];
const datasetKey = `${measurement.name}.${measurement.fields}`;
return {
label: datasetKey,
data: responseData[datasetKey]?.values ?? [],
borderColor: index === 0 ? "rgba(75, 192, 192, 1)": "rgba(255, 99, 132, 1)", // Light blue color
backgroundColor: index === 0 ? "rgba(75, 192, 192, 0.2)": "rgba(255, 99, 132, 0.2)",
fill: true,
tension: 0.4, // Smooth curve effect
pointRadius: 0, // Hide dots
pointHoverRadius: 0, // Hide hover dots
};
});
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/widget3D/${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 (
<Html position={[position[0], position[1], position[2]]}
scale={[0.5, 0.5, 0.5]}
transform
sprite>
<div className="returnOfInvestment card">
<div className="returnOfInvestment card"
onClick={
() => setSelectedChartId({
id: id,
type: type
})
}>
<div className="header">Return of Investment</div>
<div className="lineGraph charts">
{/* Smooth curve graph with two datasets */}
<SmoothLineGraphComponent data={graphData} options={graphOptions} />
<SmoothLineGraphComponent data={Object.keys(measurements).length > 0 ? chartData : graphData} options={graphOptions} />
</div>
<div className="returns-wrapper">
<div className="icon">

View File

@@ -1,28 +1,111 @@
import { Html } from "@react-three/drei";
import React, { useEffect, useMemo, useState } from "react";
import { useWidgetStore } from "../../../../store/useWidgetStore";
import useChartStore from "../../../../store/useChartStore";
import axios from "axios";
import io from "socket.io-client";
// import image from "../../../../assets/image/temp/image.png";
interface StateWorkingProps {
id:string;
type: string;
position: [number, number, number];
}
const StateWorking: React.FC<StateWorkingProps> = ({ position }) => {
const datas = [
{ key: "Oil Tank:", value: "24/341" },
{ key: "Oil Refin:", value: 36.023 },
{ key: "Transmission:", value: 36.023 },
{ key: "Fuel:", value: 36732 },
{ key: "Power:", value: 1300 },
{ key: "Time:", value: 13 - 9 - 2023 },
];
const StateWorking: React.FC<StateWorkingProps> = ({ id, type, position }) => {
const { selectedChartId, setSelectedChartId } = useWidgetStore();
const { measurements: chartMeasurements, duration: chartDuration, name: widgetName } = useChartStore();
const [measurements, setmeasurements] = useState<any>({});
const [duration, setDuration] = useState("1h")
const [name, setName] = useState("Widget")
const [datas, setDatas] = useState<any>({});
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0]
// const datas = [
// { key: "Oil Tank:", value: "24/341" },
// { key: "Oil Refin:", value: 36.023 },
// { key: "Transmission:", value: 36.023 },
// { key: "Fuel:", value: 36732 },
// { key: "Power:", value: 1300 },
// { key: "Time:", value: 13 - 9 - 2023 },
// ];
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("lastInput", inputData);
};
socket.on("connect", startStream);
socket.on("lastOutput", (response) => {
const responseData = response;
console.log("responceeeeeeeeeee",response);
setDatas(responseData);
});
return () => {
socket.off("lastOutput");
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/widget3D/${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);
}
}
}
console.log("dataaaaa",datas);
useEffect(() => {
fetchSavedInputes();
}, []);
useEffect(() => {
if (selectedChartId?.id === id) {
fetchSavedInputes();
}
}
,[chartMeasurements, chartDuration, widgetName])
return (
<Html position={[position[0], position[1], position[2]]}
scale={[0.5, 0.5, 0.5]}
transform
sprite>
<div className="stateWorking-wrapper card">
<div className="stateWorking-wrapper card"
onClick={
() => setSelectedChartId({
id: id,
type: type
})
}>
<div className="header-wrapper">
<div className="header">
<span>State</span>
<span>
Working <span>.</span>
{datas?.input1 ? datas.input1 : 'input1'} <span>.</span>
</span>
</div>
<div className="img">
@@ -31,12 +114,36 @@ const StateWorking: React.FC<StateWorkingProps> = ({ position }) => {
</div>
{/* Data */}
<div className="data-wrapper">
{datas.map((data, index) => (
{/* {datas.map((data, index) => (
<div className="data-table" key={index}>
<div className="data">{data.key}</div>
<div className="key">{data.value}</div>
</div>
))}
))} */}
<div className="data-table">
<div className="data">{measurements?.input2?.fields ? measurements.input2.fields : 'input2'}</div>
<div className="key">{datas?.input2 ? datas.input2 : 'data'}</div>
</div>
<div className="data-table">
<div className="data">{measurements?.input3?.fields ? measurements.input3.fields : 'input3'}</div>
<div className="key">{datas?.input3 ? datas.input3 : 'data'}</div>
</div>
<div className="data-table">
<div className="data">{measurements?.input4?.fields ? measurements.input4.fields : 'input4'}</div>
<div className="key">{datas?.input4 ? datas.input4 : 'data'}</div>
</div>
<div className="data-table">
<div className="data">{measurements?.input5?.fields ? measurements.input5.fields : 'input5'}</div>
<div className="key">{datas?.input5 ? datas.input5 : 'data'}</div>
</div>
<div className="data-table">
<div className="data">{measurements?.input6?.fields ? measurements.input6.fields : 'input6'}</div>
<div className="key">{datas?.input6 ? datas.input6 : 'data'}</div>
</div>
<div className="data-table">
<div className="data">{measurements?.input7?.fields ? measurements.input7.fields : 'input7'}</div>
<div className="key">{datas?.input7 ? datas.input7 : 'data'}</div>
</div>
</div>
</div>
</Html>

View File

@@ -1,5 +1,5 @@
import { Html } from "@react-three/drei";
import React from "react";
import React, { useEffect, useMemo, useState } from "react";
import { Line } from "react-chartjs-2";
import {
Chart as ChartJS,
@@ -14,6 +14,10 @@ import {
ChartOptions,
} from "chart.js";
import { ThroughputIcon } from "../../../icons/3dChartIcons";
import { useWidgetStore } from "../../../../store/useWidgetStore";
import useChartStore from "../../../../store/useChartStore";
import axios from "axios";
import io from "socket.io-client";
// Register Chart.js components
ChartJS.register(
@@ -38,10 +42,25 @@ const LineGraphComponent: React.FC<LineGraphProps> = ({ data, options }) => {
};
interface ThroughputProps {
id: string;
type: string;
position: [number, number, number];
}
const Throughput: React.FC<ThroughputProps> = ({ position }) => {
const Throughput: React.FC<ThroughputProps> = ({ id, type, position }) => {
const { selectedChartId,setSelectedChartId } = useWidgetStore();
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 iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0]
// Sample data for the line graph
const graphData: ChartData<"line"> = {
@@ -90,13 +109,93 @@ const Throughput: React.FC<ThroughputProps> = ({ position }) => {
},
};
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: "rgba(75, 192, 192, 1)",
backgroundColor: "rgba(75, 192, 192, 0.2)",
fill: true,
};
});
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/widget3D/${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 (
<Html position={[position[0], position[1], position[2]]}
scale={[0.5, 0.5, 0.5]}
transform
sprite>
<div className="throughput-wrapper">
<div className="header">Throughput</div>
<div className="throughput-wrapper"
onClick={
() => setSelectedChartId({
id: id,
type: type
})
}>
<div className="header">{name}</div>
<div className="display-value">
<div className="left">
<div className="icon">
@@ -119,7 +218,7 @@ const Throughput: React.FC<ThroughputProps> = ({ position }) => {
</div>
<div className="line-graph">
{/* Line graph using react-chartjs-2 */}
<LineGraphComponent data={graphData} options={graphOptions} />
<LineGraphComponent data={Object.keys(measurements).length > 0 ? chartData : graphData} options={graphOptions} />
</div>
<div className="footer">
You made an extra <span className="value">$1256.13</span> this month