diff --git a/app/src/components/layout/3D-cards/cards/ProductionCapacity.tsx b/app/src/components/layout/3D-cards/cards/ProductionCapacity.tsx index aff7867..d6980b3 100644 --- a/app/src/components/layout/3D-cards/cards/ProductionCapacity.tsx +++ b/app/src/components/layout/3D-cards/cards/ProductionCapacity.tsx @@ -31,6 +31,7 @@ interface ProductionCapacityProps { type: string; position: [number, number, number]; rotation: [number, number, number]; + Data?: any, onContextMenu?: (event: React.MouseEvent) => void; // onPointerDown:any } @@ -38,6 +39,7 @@ interface ProductionCapacityProps { const ProductionCapacity: React.FC = ({ id, type, + Data, position, rotation, onContextMenu, @@ -48,8 +50,8 @@ const ProductionCapacity: React.FC = ({ duration: chartDuration, name: widgetName, } = useChartStore(); - const [measurements, setmeasurements] = useState({}); - const [duration, setDuration] = useState("1h"); + const [measurements, setmeasurements] = useState(Data?.measurements ? Data.measurements : {}); + const [duration, setDuration] = useState(Data?.duration ? Data.duration : "1h"); const [name, setName] = useState("Widget"); const [chartData, setChartData] = useState<{ labels: string[]; diff --git a/app/src/components/layout/3D-cards/cards/ReturnOfInvestment.tsx b/app/src/components/layout/3D-cards/cards/ReturnOfInvestment.tsx index 0dfe967..16bb8dd 100644 --- a/app/src/components/layout/3D-cards/cards/ReturnOfInvestment.tsx +++ b/app/src/components/layout/3D-cards/cards/ReturnOfInvestment.tsx @@ -44,11 +44,13 @@ interface ReturnOfInvestmentProps { type: string; position: [number, number, number]; rotation: [number, number, number]; + Data?: any; onContextMenu?: (event: React.MouseEvent) => void; } const ReturnOfInvestment: React.FC = ({ id, type, + Data, position, rotation, onContextMenu, @@ -59,8 +61,8 @@ const ReturnOfInvestment: React.FC = ({ duration: chartDuration, name: widgetName, } = useChartStore(); - const [measurements, setmeasurements] = useState({}); - const [duration, setDuration] = useState("1h"); + const [measurements, setmeasurements] = useState(Data?.measurements ? Data.measurements : {}); + const [duration, setDuration] = useState(Data?.duration ? Data.duration : "1h"); const [name, setName] = useState("Widget"); const [chartData, setChartData] = useState<{ labels: string[]; diff --git a/app/src/components/layout/3D-cards/cards/StateWorking.tsx b/app/src/components/layout/3D-cards/cards/StateWorking.tsx index 2e5623d..9df9642 100644 --- a/app/src/components/layout/3D-cards/cards/StateWorking.tsx +++ b/app/src/components/layout/3D-cards/cards/StateWorking.tsx @@ -11,11 +11,13 @@ interface StateWorkingProps { type: string; position: [number, number, number]; rotation: [number, number, number]; + Data?:any; onContextMenu?: (event: React.MouseEvent) => void; } const StateWorking: React.FC = ({ id, type, + Data, position, rotation, onContextMenu, @@ -26,8 +28,8 @@ const StateWorking: React.FC = ({ duration: chartDuration, name: widgetName, } = useChartStore(); - const [measurements, setmeasurements] = useState({}); - const [duration, setDuration] = useState("1h"); + const [measurements, setmeasurements] = useState(Data?.measurements ? Data.measurements : {}); + const [duration, setDuration] = useState(Data?.duration ? Data.duration : "1h"); const [name, setName] = useState("Widget"); const [datas, setDatas] = useState({}); const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL; diff --git a/app/src/components/layout/3D-cards/cards/Throughput.tsx b/app/src/components/layout/3D-cards/cards/Throughput.tsx index 65e1bee..a433692 100644 --- a/app/src/components/layout/3D-cards/cards/Throughput.tsx +++ b/app/src/components/layout/3D-cards/cards/Throughput.tsx @@ -46,12 +46,14 @@ interface ThroughputProps { type: string; position: [number, number, number]; rotation: [number, number, number]; + Data?:any; onContextMenu?: (event: React.MouseEvent) => void; } const Throughput: React.FC = ({ id, type, + Data, position, rotation, onContextMenu, @@ -62,8 +64,8 @@ const Throughput: React.FC = ({ duration: chartDuration, name: widgetName, } = useChartStore(); - const [measurements, setmeasurements] = useState({}); - const [duration, setDuration] = useState("1h"); + const [measurements, setmeasurements] = useState(Data?.measurements ? Data.measurements : {}); + const [duration, setDuration] = useState(Data?.duration ? Data.duration : "1h"); const [name, setName] = useState("Widget"); const [chartData, setChartData] = useState<{ labels: string[]; diff --git a/app/src/components/layout/sidebarLeft/visualization/widgets/Widgets2D.tsx b/app/src/components/layout/sidebarLeft/visualization/widgets/Widgets2D.tsx index d0873c5..7b532b8 100644 --- a/app/src/components/layout/sidebarLeft/visualization/widgets/Widgets2D.tsx +++ b/app/src/components/layout/sidebarLeft/visualization/widgets/Widgets2D.tsx @@ -45,7 +45,10 @@ const ChartWidget: React.FC = ({ type, index, title }) => { ), title, panel: "top", - data: sampleData, + Data: { + measurements:{}, + duration:'1h' + }, }); }} onDragEnd={() => setDraggedAsset(null)} diff --git a/app/src/components/ui/componets/DraggableWidget.tsx b/app/src/components/ui/componets/DraggableWidget.tsx index e0c8773..3c726c3 100644 --- a/app/src/components/ui/componets/DraggableWidget.tsx +++ b/app/src/components/ui/componets/DraggableWidget.tsx @@ -1,5 +1,6 @@ import { useWidgetStore } from "../../../store/useWidgetStore"; import ProgressCard from "../realTimeVis/charts/ProgressCard"; +import useChartStore from "../../../store/useChartStore"; import PieGraphComponent from "../realTimeVis/charts/PieGraphComponent"; import BarGraphComponent from "../realTimeVis/charts/BarGraphComponent"; import LineGraphComponent from "../realTimeVis/charts/LineGraphComponent"; @@ -81,6 +82,16 @@ export const DraggableWidget = ({ const [panelDimensions, setPanelDimensions] = useState<{ [side in Side]?: { width: number; height: number }; }>({}); + const { measurements, duration, name } = useChartStore(); + const { isPlaying } = usePlayButtonStore(); + + const [canvasDimensions, setCanvasDimensions] = useState({ + width: 0, + height: 0, + }); + useEffect(() => { + console.log("changes loggggg", measurements, duration, name); + }, [measurements, duration, name]) const handlePointerDown = () => { if (selectedChartId?.id !== widget.id) { setSelectedChartId(widget); @@ -96,6 +107,8 @@ export const DraggableWidget = ({ "sidebar-right-wrapper", "card", "dropdown-menu", + "sidebar-right-content-container", + "dropdown-options" ], setMenuVisible: () => setSelectedChartId(null), }); @@ -139,40 +152,50 @@ export const DraggableWidget = ({ } }; + // Calculate panel size + const panelSize = Math.max( + Math.min(canvasDimensions.width * 0.25, canvasDimensions.height * 0.25), + 170 // Min 170px + ); + const getCurrentWidgetCount = (panel: Side) => selectedZone.widgets.filter((w) => w.panel === panel).length; - + // Calculate panel capacity + const calculatePanelCapacity = (panel: Side) => { - const CHART_WIDTH = 150; - const CHART_HEIGHT = 150; - const FALLBACK_HORIZONTAL_CAPACITY = 5; - const FALLBACK_VERTICAL_CAPACITY = 3; + const CHART_WIDTH = panelSize; + const CHART_HEIGHT = panelSize; const dimensions = panelDimensions[panel]; if (!dimensions) { - return panel === "top" || panel === "bottom" - ? FALLBACK_HORIZONTAL_CAPACITY - : FALLBACK_VERTICAL_CAPACITY; + return panel === "top" || panel === "bottom" ? 5 : 3; // Fallback capacities } return panel === "top" || panel === "bottom" - ? Math.floor(dimensions.width / CHART_WIDTH) - : Math.floor(dimensions.height / CHART_HEIGHT); + ? Math.max(1, Math.floor(dimensions.width / CHART_WIDTH)) + : Math.max(1, Math.floor(dimensions.height / CHART_HEIGHT)); }; const isPanelFull = (panel: Side) => { const currentWidgetCount = getCurrentWidgetCount(panel); const panelCapacity = calculatePanelCapacity(panel); - return currentWidgetCount >= panelCapacity; + + return currentWidgetCount > panelCapacity; }; const duplicateWidget = async () => { try { const email = localStorage.getItem("email") || ""; const organization = email?.split("@")[1]?.split(".")[0]; + console.log("widget data sent", widget); + const duplicatedWidget: Widget = { ...widget, + Data: { + duration: duration, + measurements: { ...measurements } + }, id: `${widget.id}-copy-${Date.now()}`, }; console.log('duplicatedWidget: ', duplicatedWidget); @@ -183,6 +206,8 @@ export const DraggableWidget = ({ widget: duplicatedWidget, }; if (visualizationSocket) { + console.log("duplecate widget", duplicateWidget); + visualizationSocket.emit("v2:viz-widget:add", duplicateWidget); } setSelectedZone((prevZone: any) => ({ @@ -255,12 +280,7 @@ export const DraggableWidget = ({ // useClickOutside(chartWidget, () => { // setSelectedChartId(null); // }); - const { isPlaying } = usePlayButtonStore(); - const [canvasDimensions, setCanvasDimensions] = useState({ - width: 0, - height: 0, - }); // Track canvas dimensions // Current: Two identical useEffect hooks for canvas dimensions @@ -298,9 +318,8 @@ export const DraggableWidget = ({
diff --git a/app/src/components/ui/componets/Dropped3dWidget.tsx b/app/src/components/ui/componets/Dropped3dWidget.tsx index 4403e68..18f7602 100644 --- a/app/src/components/ui/componets/Dropped3dWidget.tsx +++ b/app/src/components/ui/componets/Dropped3dWidget.tsx @@ -5,6 +5,7 @@ import { useSocketStore, useWidgetSubOption, } from "../../../store/store"; +import useChartStore from "../../../store/useChartStore"; import useModuleStore from "../../../store/useModuleStore"; import { ThreeState } from "../../../types/world/worldTypes"; import * as THREE from "three"; @@ -30,6 +31,7 @@ import { update3dWidget, update3dWidgetRotation, } from "../../../services/realTimeVisulization/zoneData/update3dWidget"; +import { useWidgetStore } from "../../../store/useWidgetStore"; type WidgetData = { id: string; type: string; @@ -57,6 +59,8 @@ export default function Dropped3dWidgets() { const planeIntersect = useRef(new THREE.Vector3()); const rotationStartRef = useRef<[number, number, number]>([0, 0, 0]); const mouseStartRef = useRef<{ x: number; y: number }>({ x: 0, y: 0 }); + const { setSelectedChartId } = useWidgetStore(); + const { measurements, duration} = useChartStore(); let [floorPlanesVertical, setFloorPlanesVertical] = useState( new THREE.Plane(new THREE.Vector3(0, 1, 0)) ); @@ -258,8 +262,10 @@ export default function Dropped3dWidgets() { const widgetToDuplicate = activeZoneWidgets.find( (w: WidgetData) => w.id === rightClickSelected ); + console.log("3d widget to duplecate", widgetToDuplicate); + if (!widgetToDuplicate) return; - const newWidget: WidgetData = { + const newWidget: any = { id: generateUniqueId(), type: widgetToDuplicate.type, position: [ @@ -268,6 +274,10 @@ export default function Dropped3dWidgets() { widgetToDuplicate.position[2] + 0.5, ], rotation: widgetToDuplicate.rotation || [0, 0, 0], + Data:{ + measurements: measurements, + duration: duration + }, }; const adding3dWidget = { organization: organization, @@ -657,8 +667,21 @@ export default function Dropped3dWidgets() { return ( <> {activeZoneWidgets.map( - ({ id, type, position, rotation = [0, 0, 0] }: WidgetData) => { + ({ id, type, position, Data, rotation = [0, 0, 0] }: any) => { const handleRightClick = (event: React.MouseEvent, id: string) => { + setSelectedChartId({ id: id, type: type }) + event.preventDefault(); + const canvasElement = document.getElementById( + "real-time-vis-canvas" + ); + if (!canvasElement) throw new Error("Canvas element not found"); + const canvasRect = canvasElement.getBoundingClientRect(); + const relativeX = event.clientX - canvasRect.left; + const relativeY = event.clientY - canvasRect.top; + setEditWidgetOptions(true); + setRightClickSelected(id); + setTop(relativeY); + setLeft(relativeX); handleRightClick3d(event, id) }; @@ -671,6 +694,7 @@ export default function Dropped3dWidgets() { type={type} position={position} rotation={rotation} + Data={Data} onContextMenu={(e) => handleRightClick(e, id)} /> ); @@ -682,6 +706,7 @@ export default function Dropped3dWidgets() { type={type} position={position} rotation={rotation} + Data={Data} onContextMenu={(e) => handleRightClick(e, id)} /> ); @@ -693,6 +718,7 @@ export default function Dropped3dWidgets() { type={type} position={position} rotation={rotation} + Data={Data} onContextMenu={(e) => handleRightClick(e, id)} /> ); @@ -704,6 +730,7 @@ export default function Dropped3dWidgets() { type={type} position={position} rotation={rotation} + Data={Data} onContextMenu={(e) => handleRightClick(e, id)} /> ); diff --git a/app/src/components/ui/componets/Panel.tsx b/app/src/components/ui/componets/Panel.tsx index 0f72dfc..82764d1 100644 --- a/app/src/components/ui/componets/Panel.tsx +++ b/app/src/components/ui/componets/Panel.tsx @@ -108,9 +108,8 @@ const Panel: React.FC = ({ case "bottom": return { minWidth: "170px", - width: `calc(100% - ${ - (leftActive ? panelSize : 0) + (rightActive ? panelSize : 0) - }px)`, + width: `calc(100% - ${(leftActive ? panelSize : 0) + (rightActive ? panelSize : 0) + }px)`, minHeight: "170px", height: `${panelSize}px`, left: leftActive ? `${panelSize}px` : "0", @@ -123,9 +122,8 @@ const Panel: React.FC = ({ minWidth: "170px", width: `${panelSize}px`, minHeight: "170px", - height: `calc(100% - ${ - (topActive ? panelSize : 0) + (bottomActive ? panelSize : 0) - }px)`, + height: `calc(100% - ${(topActive ? panelSize : 0) + (bottomActive ? panelSize : 0) + }px)`, top: topActive ? `${panelSize}px` : "0", bottom: bottomActive ? `${panelSize}px` : "0", [side]: "0", @@ -151,6 +149,7 @@ const Panel: React.FC = ({ const currentWidgetsCount = getCurrentWidgetCount(panel); const maxCapacity = calculatePanelCapacity(panel); + if (currentWidgetsCount < maxCapacity) { addWidgetToPanel(draggedAsset, panel); } @@ -284,9 +283,8 @@ const Panel: React.FC = ({
handleDrop(e, side)} onDragOver={(e) => e.preventDefault()} @@ -303,7 +301,7 @@ const Panel: React.FC = ({ style={{ pointerEvents: selectedZone.lockedPanels.includes(side) || - hiddenPanels[selectedZone.zoneId]?.includes(side) + hiddenPanels[selectedZone.zoneId]?.includes(side) ? "none" : "auto", opacity: selectedZone.lockedPanels.includes(side) ? "0.8" : "1", diff --git a/app/src/components/ui/realTimeVis/charts/LineGraphComponent.tsx b/app/src/components/ui/realTimeVis/charts/LineGraphComponent.tsx index c7f7252..8d4d4e9 100644 --- a/app/src/components/ui/realTimeVis/charts/LineGraphComponent.tsx +++ b/app/src/components/ui/realTimeVis/charts/LineGraphComponent.tsx @@ -160,6 +160,8 @@ const LineGraphComponent = ({ 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) { + console.log('line chart res',response); + setmeasurements(response.data.Data.measurements) setDuration(response.data.Data.duration) setName(response.data.widgetName) diff --git a/app/src/services/realTimeVisulization/zoneData/addFloatingWidgets.ts b/app/src/services/realTimeVisulization/zoneData/addFloatingWidgets.ts index 9b03dbe..beaa1b3 100644 --- a/app/src/services/realTimeVisulization/zoneData/addFloatingWidgets.ts +++ b/app/src/services/realTimeVisulization/zoneData/addFloatingWidgets.ts @@ -8,7 +8,7 @@ export const addingFloatingWidgets = async ( ) => { - + try { const response = await fetch( `${url_Backend_dwinzo}/api/v2/floatwidget/save`, diff --git a/app/src/store/useDroppedObjectsStore.ts b/app/src/store/useDroppedObjectsStore.ts index 8f0067e..ca39d9f 100644 --- a/app/src/store/useDroppedObjectsStore.ts +++ b/app/src/store/useDroppedObjectsStore.ts @@ -1,6 +1,7 @@ import { create } from "zustand"; import { addingFloatingWidgets } from "../services/realTimeVisulization/zoneData/addFloatingWidgets"; import { useSocketStore } from "./store"; +import useChartStore from "./useChartStore"; type DroppedObject = { className: string; @@ -96,7 +97,10 @@ export const useDroppedObjectsStore = create((set) => ({ const state = useDroppedObjectsStore.getState(); // Get the current state const zone = state.zones[zoneName]; let socketState = useSocketStore.getState(); + let iotData = useChartStore.getState(); let visualizationSocket = socketState.visualizationSocket; + let iotMeasurements = iotData.flotingMeasurements; + let iotDuration = iotData.flotingDuration; if (!zone) return; @@ -109,6 +113,10 @@ export const useDroppedObjectsStore = create((set) => ({ // Create a shallow copy of the object with a unique ID and slightly adjusted position const duplicatedObject: DroppedObject = { ...originalObject, + Data:{ + measurements: iotMeasurements, + duration: iotDuration, + }, id: `${originalObject.id}-copy-${Date.now()}`, // Unique ID position: { ...originalObject.position, @@ -122,7 +130,8 @@ export const useDroppedObjectsStore = create((set) => ({ : originalObject.position.left, }, }; - + console.log("duplicated object",duplicatedObject); + let duplicateFloatingWidget = { organization: organization, widget: duplicatedObject, diff --git a/app/src/store/useWidgetStore.ts b/app/src/store/useWidgetStore.ts index 047b57b..2d73c77 100644 --- a/app/src/store/useWidgetStore.ts +++ b/app/src/store/useWidgetStore.ts @@ -8,22 +8,8 @@ export interface Widget { fontFamily?: string; fontSize?: string; fontWeight?: string; - data: { - // Chart data - labels?: string[]; - datasets?: Array<{ - data: number[]; - backgroundColor: string; - borderColor: string; - borderWidth: number; - }>; - // Progress card data - stocks?: Array<{ - key: string; - value: number; - description: string; - }>; - }; + data?: any; + Data?:any; } interface WidgetStore { diff --git a/app/src/styles/pages/realTimeViz.scss b/app/src/styles/pages/realTimeViz.scss index c6f980a..0d4f98d 100644 --- a/app/src/styles/pages/realTimeViz.scss +++ b/app/src/styles/pages/realTimeViz.scss @@ -285,9 +285,6 @@ } } - .chart-container.notLinked { - border-color: red; - } .close-btn { position: absolute; @@ -755,6 +752,13 @@ z-index: 2 !important; } +.chart-container.notLinked { + + outline: 1px solid red; + + +} + .connectionSuccess { outline-color: #43c06d; }