diff --git a/package-lock.json b/package-lock.json index 9371ace8..01063812 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "react-flow-renderer", - "version": "10.0.0-next.10", + "version": "10.0.0-next.11", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "react-flow-renderer", - "version": "10.0.0-next.10", + "version": "10.0.0-next.11", "license": "MIT", "dependencies": { "@babel/runtime": "^7.15.4", diff --git a/package.json b/package.json index 45912eb1..dfb777aa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-flow-renderer", - "version": "10.0.0-next.10", + "version": "10.0.0-next.11", "engines": { "node": ">=12" }, diff --git a/src/additional-components/MiniMap/index.tsx b/src/additional-components/MiniMap/index.tsx index 1f13149f..7cc82df9 100644 --- a/src/additional-components/MiniMap/index.tsx +++ b/src/additional-components/MiniMap/index.tsx @@ -3,7 +3,8 @@ import cc from 'classcat'; import shallow from 'zustand/shallow'; import { useStore } from '../../store'; -import { getRectOfNodes, getBoundsofRects } from '../../utils/graph'; +import { getRectOfNodes } from '../../utils/graph'; +import { getBoundsofRects } from '../../utils'; import { Node, Rect, ReactFlowState } from '../../types'; import MiniMapNode from './MiniMapNode'; diff --git a/src/container/EdgeRenderer/utils.ts b/src/container/EdgeRenderer/utils.ts index 8a5826d1..1f94f616 100644 --- a/src/container/EdgeRenderer/utils.ts +++ b/src/container/EdgeRenderer/utils.ts @@ -2,7 +2,7 @@ import { ComponentType } from 'react'; import { BezierEdge, StepEdge, SmoothStepEdge, StraightEdge } from '../../components/Edges'; import wrapEdge from '../../components/Edges/wrapEdge'; -import { rectToBox } from '../../utils/graph'; +import { rectToBox } from '../../utils'; import { EdgeTypesType, EdgeProps, Position, XYPosition, ElementId, HandleElement, Transform, Rect } from '../../types'; diff --git a/src/hooks/useOnLoadHandler.ts b/src/hooks/useOnLoadHandler.ts index 714840e7..39c123eb 100644 --- a/src/hooks/useOnLoadHandler.ts +++ b/src/hooks/useOnLoadHandler.ts @@ -1,47 +1,9 @@ -import { GetState } from 'zustand'; import { useEffect, useRef } from 'react'; import { pointToRendererPoint } from '../utils/graph'; import { useStoreApi } from '../store'; import useZoomPanHelper from '../hooks/useZoomPanHelper'; -import { OnLoadFunc, ReactFlowState, XYPosition, Node, Edge, FlowExportObject } from '../types'; - -export const onLoadProject = (getState: GetState) => { - return (position: XYPosition): XYPosition => { - const { transform, snapToGrid, snapGrid } = getState(); - - return pointToRendererPoint(position, transform, snapToGrid, snapGrid); - }; -}; - -export const onLoadGetNodes = (getState: GetState) => { - return (): Node[] => { - const { nodes = [] } = getState(); - - return nodes.map((n) => ({ ...n })); - }; -}; - -export const onLoadGetEdges = (getState: GetState) => { - return (): Edge[] => { - const { edges = [] } = getState(); - - return edges.map((e) => ({ ...e })); - }; -}; - -export const onLoadToObject = (getState: GetState) => { - return (): FlowExportObject => { - const { nodes = [], edges = [], transform } = getState(); - - return { - nodes: nodes.map((n) => ({ ...n })), - edges: edges.map((e) => ({ ...e })), - position: [transform[0], transform[1]], - zoom: transform[2], - }; - }; -}; +import { OnLoadFunc, XYPosition, Node, Edge, FlowExportObject } from '../types'; function useOnLoadHandler(onLoad: OnLoadFunc | undefined) { const isInitialized = useRef(false); @@ -51,16 +13,42 @@ function useOnLoadHandler(onLoad: OnLoadFunc | undefined) { useEffect(() => { if (!isInitialized.current && initialized) { if (onLoad) { + const project = (position: XYPosition): XYPosition => { + const { transform, snapToGrid, snapGrid } = store.getState(); + return pointToRendererPoint(position, transform, snapToGrid, snapGrid); + }; + + const getNodes = (): Node[] => { + const { nodes = [] } = store.getState(); + return nodes.map((n) => ({ ...n })); + }; + + const getEdges = (): Edge[] => { + const { edges = [] } = store.getState(); + return edges.map((e) => ({ ...e })); + }; + + const toObject = (): FlowExportObject => { + const { nodes = [], edges = [], transform } = store.getState(); + + return { + nodes: nodes.map((n) => ({ ...n })), + edges: edges.map((e) => ({ ...e })), + position: [transform[0], transform[1]], + zoom: transform[2], + }; + }; + onLoad({ fitView: (params = { padding: 0.1 }) => fitView(params), zoomIn, zoomOut, zoomTo, setTransform, - project: onLoadProject(store.getState), - getNodes: onLoadGetNodes(store.getState), - getEdges: onLoadGetEdges(store.getState), - toObject: onLoadToObject(store.getState), + project, + getNodes, + getEdges, + toObject, }); } diff --git a/src/index.ts b/src/index.ts index 47989de5..6aa465d3 100644 --- a/src/index.ts +++ b/src/index.ts @@ -22,9 +22,8 @@ export { updateEdge, getTransformForBounds, getRectOfNodes, - applyNodeChanges, - applyEdgeChanges, } from './utils/graph'; +export { applyNodeChanges, applyEdgeChanges } from './utils/changes'; export { default as useZoomPanHelper } from './hooks/useZoomPanHelper'; export { default as useUpdateNodeInternals } from './hooks/useUpdateNodeInternals'; diff --git a/src/utils/changes.ts b/src/utils/changes.ts new file mode 100644 index 00000000..89ac2037 --- /dev/null +++ b/src/utils/changes.ts @@ -0,0 +1,51 @@ +import { Node, Edge, EdgeChange, NodeChange } from '../types'; + +function applyChanges(changes: NodeChange[] | EdgeChange[], elements: any[]): any[] { + const initElements: any[] = []; + + return elements.reduce((res: any[], item: any) => { + const currentChange = changes.find((c) => c.id === item.id); + + if (currentChange) { + switch (currentChange.type) { + case 'select': { + res.push({ ...item, isSelected: currentChange.isSelected }); + return res; + } + case 'dimensions': { + const updateItem = { ...item }; + + if (typeof currentChange.dimensions !== 'undefined') { + updateItem.width = currentChange.dimensions.width; + updateItem.height = currentChange.dimensions.height; + } + + if (typeof currentChange.position !== 'undefined') { + updateItem.position = currentChange.position; + } + + if (typeof currentChange.isDragging !== 'undefined') { + updateItem.isDragging = currentChange.isDragging; + } + + res.push(updateItem); + return res; + } + case 'remove': { + return res; + } + } + } + + res.push(item); + return res; + }, initElements); +} + +export function applyNodeChanges(changes: NodeChange[], nodes: Node[]): Node[] { + return applyChanges(changes, nodes) as Node[]; +} + +export function applyEdgeChanges(changes: EdgeChange[], edges: Edge[]): Edge[] { + return applyChanges(changes, edges) as Edge[]; +} diff --git a/src/utils/graph.ts b/src/utils/graph.ts index ddbabe40..d9055596 100644 --- a/src/utils/graph.ts +++ b/src/utils/graph.ts @@ -1,19 +1,6 @@ -import { clamp } from '../utils'; +import { boxToRect, clamp, getBoundsOfBoxes, rectToBox } from '../utils'; -import { - ElementId, - Node, - Edge, - Elements, - Transform, - XYPosition, - Rect, - Box, - Connection, - EdgeChange, - NodeChange, - EdgeMarkerType, -} from '../types'; +import { ElementId, Node, Edge, Elements, Transform, XYPosition, Rect, Connection, EdgeMarkerType } from '../types'; export const isEdge = (element: Node | Connection | Edge): element is Edge => 'id' in element && 'source' in element && 'target' in element; @@ -137,30 +124,6 @@ export const pointToRendererPoint = ( return position; }; -const getBoundsOfBoxes = (box1: Box, box2: Box): Box => ({ - x: Math.min(box1.x, box2.x), - y: Math.min(box1.y, box2.y), - x2: Math.max(box1.x2, box2.x2), - y2: Math.max(box1.y2, box2.y2), -}); - -export const rectToBox = ({ x, y, width, height }: Rect): Box => ({ - x, - y, - x2: x + width, - y2: y + height, -}); - -export const boxToRect = ({ x, y, x2, y2 }: Box): Rect => ({ - x, - y, - width: x2 - x, - height: y2 - y, -}); - -export const getBoundsofRects = (rect1: Rect, rect2: Rect): Rect => - boxToRect(getBoundsOfBoxes(rectToBox(rect1), rectToBox(rect2))); - export const getRectOfNodes = (nodes: Node[]): Rect => { const box = nodes.reduce( (currBox, { position, width, height }) => @@ -171,11 +134,6 @@ export const getRectOfNodes = (nodes: Node[]): Rect => { return boxToRect(box); }; -export const graphPosToZoomedPos = ({ x, y }: XYPosition, [tx, ty, tScale]: Transform): XYPosition => ({ - x: x * tScale + tx, - y: y * tScale + ty, -}); - export const getNodesInside = ( nodes: Node[], rect: Rect, @@ -247,53 +205,3 @@ export const getTransformForBounds = ( return [x, y, clampedZoom]; }; - -function applyChanges(changes: NodeChange[] | EdgeChange[], elements: any[]): any[] { - const initElements: any[] = []; - - return elements.reduce((res: any[], item: any) => { - const currentChange = changes.find((c) => c.id === item.id); - - if (currentChange) { - switch (currentChange.type) { - case 'select': { - res.push({ ...item, isSelected: currentChange.isSelected }); - return res; - } - case 'dimensions': { - const updateItem = { ...item }; - - if (typeof currentChange.dimensions !== 'undefined') { - updateItem.width = currentChange.dimensions.width; - updateItem.height = currentChange.dimensions.height; - } - - if (typeof currentChange.position !== 'undefined') { - updateItem.position = currentChange.position; - } - - if (typeof currentChange.isDragging !== 'undefined') { - updateItem.isDragging = currentChange.isDragging; - } - - res.push(updateItem); - return res; - } - case 'remove': { - return res; - } - } - } - - res.push(item); - return res; - }, initElements); -} - -export function applyNodeChanges(changes: NodeChange[], nodes: Node[]): Node[] { - return applyChanges(changes, nodes) as Node[]; -} - -export function applyEdgeChanges(changes: EdgeChange[], edges: Edge[]): Edge[] { - return applyChanges(changes, edges) as Edge[]; -} diff --git a/src/utils/index.ts b/src/utils/index.ts index 29c3149f..ec44298a 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,4 +1,4 @@ -import { Dimensions, XYPosition, NodeExtent } from '../types'; +import { Dimensions, XYPosition, NodeExtent, Box, Rect } from '../types'; export const getDimensions = (node: HTMLDivElement): Dimensions => ({ width: node.offsetWidth, @@ -14,3 +14,27 @@ export const clampPosition = (position: XYPosition, extent: NodeExtent) => ({ export const getHostForElement = (element: HTMLElement): Document | ShadowRoot => (element.getRootNode?.() as Document | ShadowRoot) || window?.document; + +export const getBoundsOfBoxes = (box1: Box, box2: Box): Box => ({ + x: Math.min(box1.x, box2.x), + y: Math.min(box1.y, box2.y), + x2: Math.max(box1.x2, box2.x2), + y2: Math.max(box1.y2, box2.y2), +}); + +export const rectToBox = ({ x, y, width, height }: Rect): Box => ({ + x, + y, + x2: x + width, + y2: y + height, +}); + +export const boxToRect = ({ x, y, x2, y2 }: Box): Rect => ({ + x, + y, + width: x2 - x, + height: y2 - y, +}); + +export const getBoundsofRects = (rect1: Rect, rect2: Rect): Rect => + boxToRect(getBoundsOfBoxes(rectToBox(rect1), rectToBox(rect2)));