refactor(graphView): add useOnLoadHandler
This commit is contained in:
@@ -4,18 +4,7 @@ import { BezierEdge, StepEdge, SmoothStepEdge, StraightEdge } from '../../compon
|
|||||||
import wrapEdge from '../../components/Edges/wrapEdge';
|
import wrapEdge from '../../components/Edges/wrapEdge';
|
||||||
import { rectToBox } from '../../utils/graph';
|
import { rectToBox } from '../../utils/graph';
|
||||||
|
|
||||||
import {
|
import { EdgeTypesType, EdgeProps, Position, XYPosition, ElementId, HandleElement, Transform, Rect } from '../../types';
|
||||||
EdgeTypesType,
|
|
||||||
EdgeProps,
|
|
||||||
Position,
|
|
||||||
Node,
|
|
||||||
XYPosition,
|
|
||||||
ElementId,
|
|
||||||
HandleElement,
|
|
||||||
Transform,
|
|
||||||
Edge,
|
|
||||||
Rect,
|
|
||||||
} from '../../types';
|
|
||||||
|
|
||||||
export function createEdgeTypes(edgeTypes: EdgeTypesType): EdgeTypesType {
|
export function createEdgeTypes(edgeTypes: EdgeTypesType): EdgeTypesType {
|
||||||
const standardTypes: EdgeTypesType = {
|
const standardTypes: EdgeTypesType = {
|
||||||
@@ -164,23 +153,3 @@ export function isEdgeVisible({
|
|||||||
|
|
||||||
return overlappingArea > 0;
|
return overlappingArea > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
type SourceTargetNode = {
|
|
||||||
sourceNode: Node | null;
|
|
||||||
targetNode: Node | null;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getSourceTargetNodes = (edge: Edge, nodes: Node[]): SourceTargetNode => {
|
|
||||||
return nodes.reduce(
|
|
||||||
(res, node) => {
|
|
||||||
if (node.id === edge.source) {
|
|
||||||
res.sourceNode = node;
|
|
||||||
}
|
|
||||||
if (node.id === edge.target) {
|
|
||||||
res.targetNode = node;
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
},
|
|
||||||
{ sourceNode: null, targetNode: null } as SourceTargetNode
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -1,15 +1,11 @@
|
|||||||
import React, { useEffect, useRef, memo } from 'react';
|
import React, { memo } from 'react';
|
||||||
|
|
||||||
import { useStoreApi } from '../../store';
|
|
||||||
import FlowRenderer from '../FlowRenderer';
|
import FlowRenderer from '../FlowRenderer';
|
||||||
import NodeRenderer from '../NodeRenderer';
|
import NodeRenderer from '../NodeRenderer';
|
||||||
import EdgeRenderer from '../EdgeRenderer';
|
import EdgeRenderer from '../EdgeRenderer';
|
||||||
import Viewport from '../Viewport';
|
import Viewport from '../Viewport';
|
||||||
import { onLoadProject, onLoadGetNodes, onLoadGetEdges, onLoadToObject } from '../../utils/graph';
|
|
||||||
import useZoomPanHelper from '../../hooks/useZoomPanHelper';
|
|
||||||
|
|
||||||
import { ReactFlowProps } from '../ReactFlow';
|
import { ReactFlowProps } from '../ReactFlow';
|
||||||
|
import useOnLoadHandler from '../../hooks/useOnLoadHandler';
|
||||||
import { NodeTypesType, EdgeTypesType, ConnectionLineType, KeyCode } from '../../types';
|
import { NodeTypesType, EdgeTypesType, ConnectionLineType, KeyCode } from '../../types';
|
||||||
|
|
||||||
export interface GraphViewProps extends Omit<ReactFlowProps, 'onSelectionChange' | 'nodes' | 'edges'> {
|
export interface GraphViewProps extends Omit<ReactFlowProps, 'onSelectionChange' | 'nodes' | 'edges'> {
|
||||||
@@ -81,29 +77,7 @@ const GraphView = ({
|
|||||||
onEdgeUpdateStart,
|
onEdgeUpdateStart,
|
||||||
onEdgeUpdateEnd,
|
onEdgeUpdateEnd,
|
||||||
}: GraphViewProps) => {
|
}: GraphViewProps) => {
|
||||||
const isInitialized = useRef<boolean>(false);
|
useOnLoadHandler(onLoad);
|
||||||
const store = useStoreApi();
|
|
||||||
const { zoomIn, zoomOut, zoomTo, transform: setTransform, fitView, initialized } = useZoomPanHelper();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!isInitialized.current && initialized) {
|
|
||||||
if (onLoad) {
|
|
||||||
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),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
isInitialized.current = true;
|
|
||||||
}
|
|
||||||
}, [onLoad, zoomIn, zoomOut, zoomTo, setTransform, fitView, initialized]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FlowRenderer
|
<FlowRenderer
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
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<ReactFlowState>) => {
|
||||||
|
return (position: XYPosition): XYPosition => {
|
||||||
|
const { transform, snapToGrid, snapGrid } = getState();
|
||||||
|
|
||||||
|
return pointToRendererPoint(position, transform, snapToGrid, snapGrid);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const onLoadGetNodes = (getState: GetState<ReactFlowState>) => {
|
||||||
|
return (): Node[] => {
|
||||||
|
const { nodes = [] } = getState();
|
||||||
|
|
||||||
|
return nodes.map((n) => ({ ...n }));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const onLoadGetEdges = (getState: GetState<ReactFlowState>) => {
|
||||||
|
return (): Edge[] => {
|
||||||
|
const { edges = [] } = getState();
|
||||||
|
|
||||||
|
return edges.map((e) => ({ ...e }));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const onLoadToObject = (getState: GetState<ReactFlowState>) => {
|
||||||
|
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],
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
function useOnLoadHandler(onLoad: OnLoadFunc<any> | undefined) {
|
||||||
|
const isInitialized = useRef<boolean>(false);
|
||||||
|
const store = useStoreApi();
|
||||||
|
const { zoomIn, zoomOut, zoomTo, transform: setTransform, fitView, initialized } = useZoomPanHelper();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isInitialized.current && initialized) {
|
||||||
|
if (onLoad) {
|
||||||
|
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),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
isInitialized.current = true;
|
||||||
|
}
|
||||||
|
}, [onLoad, zoomIn, zoomOut, zoomTo, setTransform, fitView, initialized]);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default useOnLoadHandler;
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
import { GetState } from 'zustand';
|
|
||||||
|
|
||||||
import { clamp } from '../utils';
|
import { clamp } from '../utils';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -12,10 +10,8 @@ import {
|
|||||||
Rect,
|
Rect,
|
||||||
Box,
|
Box,
|
||||||
Connection,
|
Connection,
|
||||||
FlowExportObject,
|
|
||||||
EdgeChange,
|
EdgeChange,
|
||||||
NodeChange,
|
NodeChange,
|
||||||
ReactFlowState,
|
|
||||||
EdgeMarkerType,
|
EdgeMarkerType,
|
||||||
} from '../types';
|
} from '../types';
|
||||||
|
|
||||||
@@ -141,14 +137,6 @@ export const pointToRendererPoint = (
|
|||||||
return position;
|
return position;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const onLoadProject = (getState: GetState<ReactFlowState>) => {
|
|
||||||
return (position: XYPosition): XYPosition => {
|
|
||||||
const { transform, snapToGrid, snapGrid } = getState();
|
|
||||||
|
|
||||||
return pointToRendererPoint(position, transform, snapToGrid, snapGrid);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const getBoundsOfBoxes = (box1: Box, box2: Box): Box => ({
|
const getBoundsOfBoxes = (box1: Box, box2: Box): Box => ({
|
||||||
x: Math.min(box1.x, box2.x),
|
x: Math.min(box1.x, box2.x),
|
||||||
y: Math.min(box1.y, box2.y),
|
y: Math.min(box1.y, box2.y),
|
||||||
@@ -240,35 +228,6 @@ export const getConnectedEdges = (nodes: Node[], edges: Edge[]): Edge[] => {
|
|||||||
return edges.filter((edge) => nodeIds.includes(edge.source) || nodeIds.includes(edge.target));
|
return edges.filter((edge) => nodeIds.includes(edge.source) || nodeIds.includes(edge.target));
|
||||||
};
|
};
|
||||||
|
|
||||||
export const onLoadGetNodes = (getState: GetState<ReactFlowState>) => {
|
|
||||||
return (): Node[] => {
|
|
||||||
const { nodes = [] } = getState();
|
|
||||||
|
|
||||||
return nodes.map((n) => ({ ...n }));
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const onLoadGetEdges = (getState: GetState<ReactFlowState>) => {
|
|
||||||
return (): Edge[] => {
|
|
||||||
const { edges = [] } = getState();
|
|
||||||
|
|
||||||
return edges.map((e) => ({ ...e }));
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const onLoadToObject = (getState: GetState<ReactFlowState>) => {
|
|
||||||
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],
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getTransformForBounds = (
|
export const getTransformForBounds = (
|
||||||
bounds: Rect,
|
bounds: Rect,
|
||||||
width: number,
|
width: number,
|
||||||
|
|||||||
Reference in New Issue
Block a user