Merge remote-tracking branch 'origin/realTimeVisulization' into simulation
This commit is contained in:
commit
a5cdd53568
2
app/.env
2
app/.env
|
@ -7,6 +7,8 @@ REACT_APP_SERVER_SOCKET_API_BASE_URL=185.100.212.76:8000
|
|||
# Base URL for the server REST API, used for HTTP requests to the backend server.
|
||||
REACT_APP_SERVER_REST_API_BASE_URL=185.100.212.76:5000
|
||||
|
||||
REACT_APP_SERVER_REST_API_LOCAL_BASE_URL=192.168.0.102:5000
|
||||
|
||||
# Base URL for the server marketplace API.
|
||||
# REACT_APP_SERVER_MARKETPLACE_URL=185.100.212.76:50011
|
||||
REACT_APP_SERVER_MARKETPLACE_URL=192.168.0.111:3501
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
"@types/react-dom": "^18.3.0",
|
||||
"@use-gesture/react": "^10.3.1",
|
||||
"chart.js": "^4.4.8",
|
||||
"chartjs-plugin-annotation": "^3.1.0",
|
||||
"glob": "^11.0.0",
|
||||
"gsap": "^3.12.5",
|
||||
"leva": "^0.10.0",
|
||||
|
@ -8499,6 +8500,15 @@
|
|||
"pnpm": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/chartjs-plugin-annotation": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/chartjs-plugin-annotation/-/chartjs-plugin-annotation-3.1.0.tgz",
|
||||
"integrity": "sha512-EkAed6/ycXD/7n0ShrlT1T2Hm3acnbFhgkIEJLa0X+M6S16x0zwj1Fv4suv/2bwayCT3jGPdAtI9uLcAMToaQQ==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"chart.js": ">=4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/check-more-types": {
|
||||
"version": "2.24.0",
|
||||
"resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz",
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
"@types/react-dom": "^18.3.0",
|
||||
"@use-gesture/react": "^10.3.1",
|
||||
"chart.js": "^4.4.8",
|
||||
"chartjs-plugin-annotation": "^3.1.0",
|
||||
"glob": "^11.0.0",
|
||||
"gsap": "^3.12.5",
|
||||
"leva": "^0.10.0",
|
||||
|
|
|
@ -0,0 +1,177 @@
|
|||
import React, { useEffect, useState } from "react";
|
||||
import MultiLevelDropdown from "../../../../ui/inputs/MultiLevelDropDown";
|
||||
import { AddIcon } from "../../../../icons/ExportCommonIcons";
|
||||
import RegularDropDown from "../../../../ui/inputs/RegularDropDown";
|
||||
import useChartStore from "../../../../../store/useChartStore";
|
||||
import { useSelectedZoneStore } from "../../../../../store/useZoneStore";
|
||||
import { useWidgetStore } from "../../../../../store/useWidgetStore";
|
||||
import axios from "axios";
|
||||
import RenameInput from "../../../../ui/inputs/RenameInput";
|
||||
|
||||
type Props = {};
|
||||
|
||||
const FlotingWidgetInput = (props: Props) => {
|
||||
const [widgetName, setWidgetName] = useState('Widget');
|
||||
const { setMeasurements, updateDuration, updateName } = useChartStore();
|
||||
const [duration, setDuration] = useState('1h')
|
||||
const [dropDowndata, setDropDownData] = useState({});
|
||||
const [selections, setSelections] = useState<Record<string, { name: string; fields: string }>>({});
|
||||
const { selectedZone } = useSelectedZoneStore();
|
||||
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]
|
||||
|
||||
useEffect(() => {
|
||||
const fetchZoneData = async () => {
|
||||
try {
|
||||
const response = await axios.get(`http://${iotApiUrl}/getinput`);
|
||||
if (response.status === 200) {
|
||||
// console.log("dropdown data:", response.data);
|
||||
setDropDownData(response.data);
|
||||
} else {
|
||||
console.log("Unexpected response:", response);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("There was an error!", error);
|
||||
}
|
||||
};
|
||||
fetchZoneData();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchSavedInputes = async () => {
|
||||
if (selectedChartId.id !== "") {
|
||||
try {
|
||||
const response = await axios.get(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/WidgetData/${selectedChartId.id}/${organization}`);
|
||||
if (response.status === 200) {
|
||||
setSelections(response.data.Data.measurements)
|
||||
setDuration(response.data.Data.duration)
|
||||
setWidgetName(response.data.widgetName)
|
||||
} else {
|
||||
console.log("Unexpected response:", response);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("There was an error!", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fetchSavedInputes();
|
||||
|
||||
}, [selectedChartId.id]);
|
||||
|
||||
// Sync Zustand state when component mounts
|
||||
useEffect(() => {
|
||||
setMeasurements(selections);
|
||||
updateDuration(duration);
|
||||
updateName(widgetName);
|
||||
}, [selections, duration, widgetName]);
|
||||
|
||||
|
||||
const sendInputes = async (inputMeasurement: any, inputDuration: any, inputName: any) => {
|
||||
try {
|
||||
const response = await axios.post(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/floatwidget/save`, {
|
||||
organization: organization,
|
||||
zoneId: selectedZone.zoneId,
|
||||
widget: {
|
||||
id: selectedChartId.id,
|
||||
panel: selectedChartId.panel,
|
||||
widgetName: inputName,
|
||||
Data: {
|
||||
measurements: inputMeasurement,
|
||||
duration: inputDuration
|
||||
}
|
||||
}
|
||||
} as any);
|
||||
if (response.status === 200) {
|
||||
return true
|
||||
} else {
|
||||
console.log("Unexpected response:", response);
|
||||
return false
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("There was an error!", error);
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
const handleSelect = async (inputKey: string, selectedData: { name: string; fields: string } | null) => {
|
||||
|
||||
// async() => {
|
||||
const newSelections = { ...selections };
|
||||
if (selectedData === null) {
|
||||
delete newSelections[inputKey];
|
||||
} else {
|
||||
newSelections[inputKey] = selectedData;
|
||||
}
|
||||
// setMeasurements(newSelections); // Update Zustand store
|
||||
console.log(newSelections);
|
||||
if (await sendInputes(newSelections, duration, widgetName)) {
|
||||
setSelections(newSelections);
|
||||
}
|
||||
// sendInputes(newSelections, duration); // Send data to server
|
||||
// return newSelections;
|
||||
// };
|
||||
};
|
||||
|
||||
const handleSelectDuration = async (option: string) => {
|
||||
if (await sendInputes(selections, option, widgetName)) {
|
||||
setDuration(option);
|
||||
}
|
||||
// setDuration(option);
|
||||
};
|
||||
|
||||
const handleNameChange = async (name:any) => {
|
||||
console.log('name change requested',name);
|
||||
|
||||
if (await sendInputes(selections, duration, name)) {
|
||||
setWidgetName(name);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="inputs-wrapper">
|
||||
<div className="datas">
|
||||
<div className="datas__label">Title</div>
|
||||
<RenameInput value={selectedChartId?.title || "untited"} onRename={handleNameChange}/>
|
||||
</div>
|
||||
{[...Array(6)].map((_, index) => {
|
||||
const inputKey = `input${index + 1}`;
|
||||
return (
|
||||
<div key={index} className="datas">
|
||||
<div className="datas__label">Input {index + 1}</div>
|
||||
<div className="datas__class">
|
||||
<MultiLevelDropdown
|
||||
data={dropDowndata}
|
||||
onSelect={(selectedData) => handleSelect(inputKey, selectedData)}
|
||||
onUnselect={() => handleSelect(inputKey, null)}
|
||||
selectedValue={selections[inputKey]} // Load from Zustand
|
||||
/>
|
||||
<div className="icon">
|
||||
<AddIcon />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<div>
|
||||
<div className="datas">
|
||||
<div className="datas__label">Duration</div>
|
||||
<div className="datas__class">
|
||||
<RegularDropDown
|
||||
header={duration}
|
||||
options={["1h", "2h", "12h"]}
|
||||
onSelect={handleSelectDuration}
|
||||
search={false}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default FlotingWidgetInput;
|
|
@ -125,11 +125,13 @@ import useChartStore from "../../../../../store/useChartStore";
|
|||
import { useSelectedZoneStore } from "../../../../../store/useZoneStore";
|
||||
import { useWidgetStore } from "../../../../../store/useWidgetStore";
|
||||
import axios from "axios";
|
||||
import RenameInput from "../../../../ui/inputs/RenameInput";
|
||||
|
||||
type Props = {};
|
||||
|
||||
const LineGrapInput = (props: Props) => {
|
||||
const { setMeasurements, updateDuration } = useChartStore();
|
||||
const [widgetName, setWidgetName] = useState('Widget');
|
||||
const { setMeasurements, updateDuration, updateName } = useChartStore();
|
||||
const [duration, setDuration] = useState('1h')
|
||||
const [dropDowndata, setDropDownData] = useState({});
|
||||
const [selections, setSelections] = useState<Record<string, { name: string; fields: string }>>({});
|
||||
|
@ -157,13 +159,14 @@ const LineGrapInput = (props: Props) => {
|
|||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchSavedInputes = async() => {
|
||||
const fetchSavedInputes = async () => {
|
||||
if (selectedChartId.id !== "") {
|
||||
try {
|
||||
const response = await axios.get(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/WidgetData/${selectedChartId.id}/${organization}`);
|
||||
if (response.status === 200) {
|
||||
setSelections(response.data.Data.measurements)
|
||||
setDuration(response.data.Data.duration)
|
||||
setWidgetName(response.data.widgetName)
|
||||
} else {
|
||||
console.log("Unexpected response:", response);
|
||||
}
|
||||
|
@ -181,17 +184,19 @@ const LineGrapInput = (props: Props) => {
|
|||
useEffect(() => {
|
||||
setMeasurements(selections);
|
||||
updateDuration(duration);
|
||||
}, [selections, duration]);
|
||||
updateName(widgetName);
|
||||
}, [selections, duration, widgetName]);
|
||||
|
||||
|
||||
const sendInputes = async(inputMeasurement: any, inputDuration: any) => {
|
||||
const sendInputes = async (inputMeasurement: any, inputDuration: any, inputName: any) => {
|
||||
try {
|
||||
const response = await axios.post(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/widget/save`,{
|
||||
const response = await axios.post(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/widget/save`, {
|
||||
organization: organization,
|
||||
zoneId: selectedZone.zoneId,
|
||||
widget:{
|
||||
widget: {
|
||||
id: selectedChartId.id,
|
||||
panel: selectedChartId.panel,
|
||||
widgetName: inputName,
|
||||
Data: {
|
||||
measurements: inputMeasurement,
|
||||
duration: inputDuration
|
||||
|
@ -210,35 +215,47 @@ const LineGrapInput = (props: Props) => {
|
|||
}
|
||||
}
|
||||
|
||||
const handleSelect = async(inputKey: string, selectedData: { name: string; fields: string } | null) => {
|
||||
const handleSelect = async (inputKey: string, selectedData: { name: string; fields: string } | null) => {
|
||||
|
||||
// async() => {
|
||||
const newSelections = { ...selections };
|
||||
if (selectedData === null) {
|
||||
delete newSelections[inputKey];
|
||||
} else {
|
||||
newSelections[inputKey] = selectedData;
|
||||
}
|
||||
// setMeasurements(newSelections); // Update Zustand store
|
||||
console.log(newSelections);
|
||||
if ( await sendInputes(newSelections, duration)) {
|
||||
setSelections(newSelections);
|
||||
}
|
||||
// sendInputes(newSelections, duration); // Send data to server
|
||||
// return newSelections;
|
||||
// async() => {
|
||||
const newSelections = { ...selections };
|
||||
if (selectedData === null) {
|
||||
delete newSelections[inputKey];
|
||||
} else {
|
||||
newSelections[inputKey] = selectedData;
|
||||
}
|
||||
// setMeasurements(newSelections); // Update Zustand store
|
||||
console.log(newSelections);
|
||||
if (await sendInputes(newSelections, duration, widgetName)) {
|
||||
setSelections(newSelections);
|
||||
}
|
||||
// sendInputes(newSelections, duration); // Send data to server
|
||||
// return newSelections;
|
||||
// };
|
||||
};
|
||||
|
||||
const handleSelectDuration = async(option: string) => {
|
||||
if ( await sendInputes(selections, option)) {
|
||||
const handleSelectDuration = async (option: string) => {
|
||||
if (await sendInputes(selections, option, widgetName)) {
|
||||
setDuration(option);
|
||||
}
|
||||
// setDuration(option);
|
||||
};
|
||||
|
||||
const handleNameChange = async (name:any) => {
|
||||
console.log('name change requested',name);
|
||||
|
||||
if (await sendInputes(selections, duration, name)) {
|
||||
setWidgetName(name);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="inputs-wrapper">
|
||||
<div className="datas">
|
||||
<div className="datas__label">Title</div>
|
||||
<RenameInput value={selectedChartId?.title || "untited"} onRename={handleNameChange}/>
|
||||
</div>
|
||||
{[...Array(6)].map((_, index) => {
|
||||
const inputKey = `input${index + 1}`;
|
||||
return (
|
||||
|
|
|
@ -3,6 +3,7 @@ import { useWidgetStore } from "../../../../../store/useWidgetStore";
|
|||
import { AddIcon, RemoveIcon } from "../../../../icons/ExportCommonIcons";
|
||||
import MultiLevelDropDown from "../../../../ui/inputs/MultiLevelDropDown";
|
||||
import LineGrapInput from "../IotInputCards/LineGrapInput";
|
||||
import RenameInput from "../../../../ui/inputs/RenameInput";
|
||||
|
||||
// Define the data structure for demonstration purposes
|
||||
const DATA_STRUCTURE = {
|
||||
|
@ -107,25 +108,34 @@ const Data = () => {
|
|||
[selectedChartId.id]: currentChartData.map((group) =>
|
||||
group.id === groupId
|
||||
? {
|
||||
...group,
|
||||
children: group.children.filter(
|
||||
(child) => child.id !== childId
|
||||
),
|
||||
}
|
||||
...group,
|
||||
children: group.children.filter(
|
||||
(child) => child.id !== childId
|
||||
),
|
||||
}
|
||||
: group
|
||||
),
|
||||
};
|
||||
});
|
||||
};
|
||||
console.log("selectedChartId", selectedChartId);
|
||||
|
||||
return (
|
||||
<div className="dataSideBar">
|
||||
{selectedChartId?.title && (
|
||||
{/* {selectedChartId?.title && (
|
||||
<div className="sideBarHeader">{selectedChartId?.title}</div>
|
||||
)}
|
||||
)} */}
|
||||
|
||||
|
||||
{/* <RenameInput value={selectedChartId?.title || "untited"} /> */}
|
||||
|
||||
{/* Render groups dynamically */}
|
||||
{
|
||||
chartDataGroups[selectedChartId?.id] && <LineGrapInput />
|
||||
chartDataGroups[selectedChartId?.id] &&
|
||||
<>
|
||||
<div className="sideBarHeader">2D Widget Input</div>
|
||||
<LineGrapInput />
|
||||
</>
|
||||
}
|
||||
|
||||
{/* Info Box */}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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} />;
|
||||
};
|
||||
|
|
|
@ -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;
|
|
@ -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} />;
|
||||
};
|
||||
|
|
|
@ -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} />;
|
||||
};
|
||||
|
|
|
@ -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;
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -1,4 +1,5 @@
|
|||
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
|
||||
console.log("url_Backend_dwinzo: ", url_Backend_dwinzo);
|
||||
|
||||
export const getSelect2dZoneData = async (
|
||||
ZoneId?: string,
|
||||
|
|
|
@ -14,7 +14,6 @@ export const getZoneData = async (zoneId: string, organization: string) => {
|
|||
}
|
||||
);
|
||||
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to fetch zoneData");
|
||||
}
|
||||
|
|
|
@ -9,20 +9,26 @@ interface MeasurementStore {
|
|||
measurements: Record<string, Measurement>; // Change array to Record<string, Measurement>
|
||||
interval: number;
|
||||
duration: string;
|
||||
name: string;
|
||||
setMeasurements: (newMeasurements: Record<string, Measurement>) => void;
|
||||
updateDuration: (newDuration: string) => void;
|
||||
updateName: (newName: string) => void;
|
||||
}
|
||||
|
||||
const useChartStore = create<MeasurementStore>((set) => ({
|
||||
measurements: {}, // Initialize as an empty object
|
||||
interval: 1000,
|
||||
duration: "1h",
|
||||
name:'',
|
||||
|
||||
setMeasurements: (newMeasurements) =>
|
||||
set(() => ({ measurements: newMeasurements })),
|
||||
|
||||
updateDuration: (newDuration) =>
|
||||
set(() => ({ duration: newDuration })),
|
||||
|
||||
updateName: (newName) =>
|
||||
set(() => ({ duration: newName })),
|
||||
}));
|
||||
|
||||
export default useChartStore;
|
||||
|
|
|
@ -33,7 +33,7 @@ interface WidgetStore {
|
|||
setDraggedAsset: (asset: Widget | null) => void; // Setter for draggedAsset
|
||||
addWidget: (widget: Widget) => void; // Add a new widget
|
||||
setWidgets: (widgets: Widget[]) => void; // Replace the entire widgets array
|
||||
setSelectedChartId: (widget: Widget | null) => void; // Set the selected chart/widget
|
||||
setSelectedChartId: (widget: any | null) => void; // Set the selected chart/widget
|
||||
}
|
||||
|
||||
// Create the store with Zustand
|
||||
|
|
|
@ -318,6 +318,25 @@
|
|||
|
||||
.sidebar-right-content-container {
|
||||
.dataSideBar {
|
||||
.inputs-wrapper {
|
||||
.datas {
|
||||
|
||||
.input-value {
|
||||
|
||||
padding: 5px 10px;
|
||||
}
|
||||
|
||||
.input-value,
|
||||
.rename-input {
|
||||
margin-right: 24px;
|
||||
width: 170px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
|
@ -991,11 +1010,9 @@
|
|||
top: 50%;
|
||||
right: -10px;
|
||||
transform: translate(0, -50%);
|
||||
background: linear-gradient(
|
||||
144.19deg,
|
||||
#f1e7cd 16.62%,
|
||||
#fffaef 85.81%
|
||||
);
|
||||
background: linear-gradient(144.19deg,
|
||||
#f1e7cd 16.62%,
|
||||
#fffaef 85.81%);
|
||||
}
|
||||
|
||||
.category-image {
|
||||
|
|
Loading…
Reference in New Issue