Skip to content

Commit

Permalink
Zoom functionality added
Browse files Browse the repository at this point in the history
  • Loading branch information
NoraKri committed Dec 17, 2024
1 parent 8a59d3b commit 6737d82
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 42 deletions.
35 changes: 33 additions & 2 deletions www/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions www/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@
"dependencies": {
"@equinor/eds-core-react": "^0.42.5",
"@svgr/core": "^8.1.0",
"@types/react-svg-pan-zoom": "^3.3.9",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-svg-pan-zoom": "^3.13.1",
"styled-components": "^6.1.13",
"xml-to-react": "^1.2.2"
},
Expand Down
86 changes: 48 additions & 38 deletions www/src/components/diagram/Pandid.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { XMLParser } from "fast-xml-parser";
import Equipment from "./Equipment.tsx";
import { useEffect, useState } from "react";
import { useEffect, useRef, useState } from "react";
import ProcessInstrumentationFunction from "./ProcessInstrumentationFunction.tsx";
import { EquipmentProps, XMLProps } from "../../types/diagram/Diagram.ts";
import { PipingNetworkSystemProps } from "../../types/diagram/Piping.ts";
Expand All @@ -13,6 +13,7 @@ import { cleanTripleStore } from "../../utils/Triplestore.ts";
import { useCommissioningPackageContext } from "../../hooks/useCommissioningPackageContext.tsx";
import styled from "styled-components";
import { preloadSVGs } from "../../utils/SvgEdit.ts";
import ZoomableSVGWrapper from "../editor/ZoomableSVGWrapper.tsx";

const SVGContainer = styled.div`
width: 100%;
Expand All @@ -33,6 +34,7 @@ export default function Pandid() {
ActuatingSystemProps[]
>([]);
const [svgMap, setSvgMap] = useState<Map<string, Element | null>>(new Map());
const containerRef = useRef<HTMLDivElement>(null);

const parser = new XMLParser({
ignoreAttributes: false,
Expand Down Expand Up @@ -72,55 +74,63 @@ export default function Pandid() {
const preloadedMap = await preloadSVGs(xmlData);
setSvgMap(preloadedMap);
};

initializeSvgMap();
}, [xmlData]);

return (
<SVGContainer>
<SVGContainer ref={containerRef}>
{xmlData && (
<PandidContext.Provider
value={{
height: xmlData.PlantModel.Drawing.Extent.Max.Y,
height: parseInt(xmlData.PlantModel.Drawing.Extent.Max.Y),
svgMap,
setSvgMap,
}}
>
<svg
viewBox={`${xmlData.PlantModel.Drawing.Extent.Min.X} ${xmlData.PlantModel.Drawing.Extent.Min.Y} ${xmlData.PlantModel.Drawing.Extent.Max.X} ${xmlData.PlantModel.Drawing.Extent.Max.Y}`}
width={"100%"}
height={"100%"}
{" "}
<ZoomableSVGWrapper
containerRef={containerRef}
svgWidth={parseInt(String(xmlData.PlantModel.Drawing.Extent.Max.X))}
svgHeight={parseInt(
String(xmlData.PlantModel.Drawing.Extent.Max.Y),
)}
>
{equipments &&
equipments.map((equipment: EquipmentProps, index: number) => (
<Equipment key={index} {...equipment} />
))}
{pipingNetworkSystems &&
pipingNetworkSystems.map(
(
pipingNetworkSystem: PipingNetworkSystemProps,
index: number,
) => <PipeSystem key={index} {...pipingNetworkSystem} />,
)}
{processInstrumentationFunction &&
processInstrumentationFunction.map(
(
processInstrumentationFunction: ProcessInstrumentationFunctionProps,
index: number,
) => (
<ProcessInstrumentationFunction
key={index}
{...processInstrumentationFunction}
/>
),
)}
{actuatingSystem &&
actuatingSystem.map(
(actuatingSystem: ActuatingSystemProps, index: number) => (
<ActuatingSystem key={index} {...actuatingSystem} />
),
)}
</svg>
<svg
viewBox={`${xmlData.PlantModel.Drawing.Extent.Min.X} ${xmlData.PlantModel.Drawing.Extent.Min.Y} ${xmlData.PlantModel.Drawing.Extent.Max.X} ${xmlData.PlantModel.Drawing.Extent.Max.Y}`}
width={"100%"}
height={"100%"}
>
{equipments &&
equipments.map((equipment: EquipmentProps, index: number) => (
<Equipment key={index} {...equipment} />
))}
{pipingNetworkSystems &&
pipingNetworkSystems.map(
(
pipingNetworkSystem: PipingNetworkSystemProps,
index: number,
) => <PipeSystem key={index} {...pipingNetworkSystem} />,
)}
{processInstrumentationFunction &&
processInstrumentationFunction.map(
(
processInstrumentationFunction: ProcessInstrumentationFunctionProps,
index: number,
) => (
<ProcessInstrumentationFunction
key={index}
{...processInstrumentationFunction}
/>
),
)}
{actuatingSystem &&
actuatingSystem.map(
(actuatingSystem: ActuatingSystemProps, index: number) => (
<ActuatingSystem key={index} {...actuatingSystem} />
),
)}
</svg>
</ZoomableSVGWrapper>
</PandidContext.Provider>
)}
</SVGContainer>
Expand Down
65 changes: 65 additions & 0 deletions www/src/components/editor/ZoomableSVGWrapper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { TOOL_AUTO, UncontrolledReactSVGPanZoom } from "react-svg-pan-zoom";
import { ReactElement, RefObject, useEffect, useRef, useState } from "react";

interface ZoomableSVGWrapperProps {
containerRef: RefObject<HTMLDivElement>;
svgWidth: number;
svgHeight: number;
children: ReactElement;
}

export default function ZoomableSVGWrapper({
containerRef,
children,
}: ZoomableSVGWrapperProps) {
const Viewer = useRef<UncontrolledReactSVGPanZoom>(null);
const [dimensions, setDimensions] = useState({
width: 0,
height: 0,
});

// Dynamically update dimensions on mount and resize
useEffect(() => {
const updateDimensions = () => {
if (containerRef.current) {
setDimensions({
width: containerRef.current.offsetWidth,
height: containerRef.current.offsetHeight,
});
}
};

updateDimensions();
window.addEventListener("resize", updateDimensions);
return () => window.removeEventListener("resize", updateDimensions);
}, []);

// Fit SVG to screen on mount
useEffect(() => {
if (Viewer.current) {
Viewer.current.fitToViewer();
}
}, [dimensions]);

return (
<>
{dimensions.width > 0 && dimensions.height > 0 && (
<UncontrolledReactSVGPanZoom
width={dimensions.width}
height={dimensions.height}
background={"#FFFFFF"}
scaleFactorMin={2}
scaleFactorMax={10}
tool={TOOL_AUTO}
ref={Viewer}
detectAutoPan={false}
onChangeValue={() => {}}
onChangeTool={() => {}}
detectWheel={true}
>
{children}
</UncontrolledReactSVGPanZoom>
)}
</>
);
}
4 changes: 2 additions & 2 deletions www/src/types/diagram/Drawing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ export interface DrawingProps {
export type PresentationProps = object;

export interface XYProps {
X: number;
Y: number;
X: string;
Y: string;
}

export interface ExtentProps {
Expand Down

0 comments on commit 6737d82

Please sign in to comment.