From b362c1185174fdb3fcecaca0c975464dadd9c3e5 Mon Sep 17 00:00:00 2001 From: moklick Date: Mon, 14 Mar 2022 16:01:00 +0100 Subject: [PATCH] refactor(edges): use new edge as default, add simplebezier --- example/src/EdgeTypes/utils.ts | 2 +- example/src/Edges/index.tsx | 28 ++- src/components/ConnectionLine/index.tsx | 2 +- src/components/Edges/BezierEdge.tsx | 211 ++++++++--------- ...ealBezierEdge.tsx => SimpleBezierEdge.tsx} | 212 +++++++++--------- src/components/Edges/index.ts | 4 +- src/container/EdgeRenderer/utils.ts | 4 +- src/container/ReactFlow/index.tsx | 16 +- src/index.ts | 2 +- 9 files changed, 248 insertions(+), 233 deletions(-) rename src/components/Edges/{UnrealBezierEdge.tsx => SimpleBezierEdge.tsx} (65%) diff --git a/example/src/EdgeTypes/utils.ts b/example/src/EdgeTypes/utils.ts index 3c679060..a6d898d7 100644 --- a/example/src/EdgeTypes/utils.ts +++ b/example/src/EdgeTypes/utils.ts @@ -12,7 +12,7 @@ const nodeColors = [ ['#1e9e99', '#4cb3ac', '#6ec9c0', '#8ddfd4', '#c4fff7'], ['#0f4c75', '#1b5d8b', '#276fa1', '#3282b8', '#4fa6e0'], ]; -const edgeTypes = ['default', 'step', 'smoothstep', 'straight', 'unreal']; +const edgeTypes = ['default', 'step', 'smoothstep', 'straight', 'simplebezier']; const offsets = [ { x: 0, diff --git a/example/src/Edges/index.tsx b/example/src/Edges/index.tsx index 6d7b9b08..d527ae45 100644 --- a/example/src/Edges/index.tsx +++ b/example/src/Edges/index.tsx @@ -1,12 +1,22 @@ import { MouseEvent } from 'react'; import ReactFlow, { - addEdge, Background, Connection, Controls, Edge, EdgeTypes, MarkerType, MiniMap, Node, ReactFlowInstance, useEdgesState, useNodesState + addEdge, + Background, + Connection, + Controls, + Edge, + EdgeTypes, + MarkerType, + MiniMap, + Node, + Position, + ReactFlowInstance, + useEdgesState, + useNodesState, } from 'react-flow-renderer'; import CustomEdge from './CustomEdge'; import CustomEdge2 from './CustomEdge2'; - - const onInit = (reactFlowInstance: ReactFlowInstance) => reactFlowInstance.fitView(); const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node); const onNodeClick = (_: MouseEvent, node: Node) => console.log('click', node); @@ -15,7 +25,7 @@ const initialNodes: Node[] = [ { id: '1', type: 'input', data: { label: 'Input 1' }, position: { x: 250, y: 0 } }, { id: '2', data: { label: 'Node 2' }, position: { x: 150, y: 100 } }, { id: '2a', data: { label: 'Node 2a' }, position: { x: 0, y: 180 } }, - { id: '2b', data: { label: 'Node 2b' }, position: { x: -80, y: 100 } }, + { id: '2b', data: { label: 'Node 2b' }, position: { x: -80, y: 100 }, targetPosition: Position.Left }, { id: '3', data: { label: 'Node 3' }, position: { x: 250, y: 200 } }, { id: '4', data: { label: 'Node 4' }, position: { x: 400, y: 300 } }, { id: '3a', data: { label: 'Node 3a' }, position: { x: 150, y: 300 } }, @@ -29,7 +39,13 @@ const initialNodes: Node[] = [ const initialEdges: Edge[] = [ { id: 'e1-2', source: '1', target: '2', label: 'bezier edge (default)', className: 'normal-edge' }, { id: 'e2-2a', source: '2', target: '2a', type: 'smoothstep', label: 'smoothstep edge' }, - { id: 'e2a-2b', source: '2a', target: '2b', type: 'unreal', label: 'unreal bezier edge', className: 'unreal-edge' }, + { + id: 'e2a-2b', + source: '2a', + target: '2b', + type: 'simplebezier', + label: 'simple bezier edge', + }, { id: 'e2-3', source: '2', target: '3', type: 'step', label: 'step edge' }, { id: 'e3-4', source: '3', target: '4', type: 'straight', label: 'straight edge' }, { id: 'e3-3a', source: '3', target: '3a', type: 'straight', label: 'label only edge', style: { stroke: 'none' } }, @@ -99,7 +115,7 @@ const edgeTypes: EdgeTypes = { }; const EdgesFlow = () => { - const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes); + const [nodes, , onNodesChange] = useNodesState(initialNodes); const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges); const onConnect = (params: Connection | Edge) => setEdges((eds) => addEdge(params, eds)); diff --git a/src/components/ConnectionLine/index.tsx b/src/components/ConnectionLine/index.tsx index f3839442..0654a4b4 100644 --- a/src/components/ConnectionLine/index.tsx +++ b/src/components/ConnectionLine/index.tsx @@ -2,7 +2,7 @@ import React, { useRef, CSSProperties } from 'react'; import shallow from 'zustand/shallow'; import { useStore } from '../../store'; -import { getBezierPath } from '../Edges/BezierEdge'; +import { getBezierPath } from '../Edges/SimpleBezierEdge'; import { getSmoothStepPath } from '../Edges/SmoothStepEdge'; import { HandleElement, diff --git a/src/components/Edges/BezierEdge.tsx b/src/components/Edges/BezierEdge.tsx index 7edb5a42..9daf07bb 100644 --- a/src/components/Edges/BezierEdge.tsx +++ b/src/components/Edges/BezierEdge.tsx @@ -1,101 +1,110 @@ -import React, { memo } from 'react'; - -import EdgeText from './EdgeText'; -import { getCenter } from './utils'; -import { EdgeProps, Position } from '../../types'; - -interface GetBezierPathParams { - sourceX: number; - sourceY: number; - sourcePosition?: Position; - targetX: number; - targetY: number; - targetPosition?: Position; - centerX?: number; - centerY?: number; -} - -export function getBezierPath({ - sourceX, - sourceY, - sourcePosition = Position.Bottom, - targetX, - targetY, - targetPosition = Position.Top, - centerX, - centerY, -}: GetBezierPathParams): string { - const [_centerX, _centerY] = getCenter({ sourceX, sourceY, targetX, targetY }); - const leftAndRight = [Position.Left, Position.Right]; - - const cX = typeof centerX !== 'undefined' ? centerX : _centerX; - const cY = typeof centerY !== 'undefined' ? centerY : _centerY; - - let path = `M${sourceX},${sourceY} C${sourceX},${cY} ${targetX},${cY} ${targetX},${targetY}`; - - if (leftAndRight.includes(sourcePosition) && leftAndRight.includes(targetPosition)) { - path = `M${sourceX},${sourceY} C${cX},${sourceY} ${cX},${targetY} ${targetX},${targetY}`; - } else if (leftAndRight.includes(targetPosition)) { - path = `M${sourceX},${sourceY} Q${sourceX},${targetY} ${targetX},${targetY}`; - } else if (leftAndRight.includes(sourcePosition)) { - path = `M${sourceX},${sourceY} Q${targetX},${sourceY} ${targetX},${targetY}`; - } - - return path; -} - -export default memo( - ({ - sourceX, - sourceY, - targetX, - targetY, - sourcePosition = Position.Bottom, - targetPosition = Position.Top, - label, - labelStyle, - labelShowBg, - labelBgStyle, - labelBgPadding, - labelBgBorderRadius, - style, - markerEnd, - markerStart, - }: EdgeProps) => { - const [centerX, centerY] = getCenter({ sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition }); - const path = getBezierPath({ - sourceX, - sourceY, - sourcePosition, - targetX, - targetY, - targetPosition, - }); - - const text = label ? ( - - ) : null; - - return ( - <> - - {text} - - ); - } -); +import React, { memo } from 'react'; +import { EdgeProps, Position } from '../../types'; +import EdgeText from './EdgeText'; +import { getCenter } from './utils'; + +interface GetBezierPathParams { + sourceX: number; + sourceY: number; + sourcePosition?: Position; + targetX: number; + targetY: number; + targetPosition?: Position; + curvature?: number; +} + +export function getBezierPath({ + sourceX, + sourceY, + sourcePosition = Position.Bottom, + targetX, + targetY, + targetPosition = Position.Top, + curvature = 0.5, +}: GetBezierPathParams): string { + const leftAndRight = [Position.Left, Position.Right]; + + // Distance between the source and target + const distanceX = sourceX - targetX; + const distanceY = sourceY - targetY; + + // // A scalar value to fix the curve size getting larger + const scalarX = Math.min(curvature, Math.max(0, distanceX / 10000)); + const scalarY = Math.min(curvature, Math.max(0, distanceY / 10000)); + + const hx1 = sourceX + Math.abs(targetX - sourceX) * (curvature - scalarX); + const hx2 = targetX - Math.abs(targetX - sourceX) * (curvature - scalarX); + + const hy1 = sourceY + Math.abs(targetY - sourceY) * (curvature - scalarY); + const hy2 = targetY - Math.abs(targetY - sourceY) * (curvature - scalarY); + + let path = `M${sourceX},${sourceY} C${sourceX},${hy1} ${targetX},${hy2} ${targetX},${targetY}`; + + if (leftAndRight.includes(sourcePosition) && leftAndRight.includes(targetPosition)) { + path = `M${sourceX},${sourceY} C${hx1},${sourceY} ${hx2},${targetY}, ${targetX},${targetY}`; + } else if (leftAndRight.includes(targetPosition)) { + path = `M${sourceX},${sourceY} Q${sourceX},${targetY} ${targetX},${targetY}`; + } else if (leftAndRight.includes(sourcePosition)) { + path = `M${sourceX},${sourceY} Q${targetX},${sourceY} ${targetX},${targetY}`; + } + + return path; +} + +export default memo( + ({ + sourceX, + sourceY, + targetX, + targetY, + sourcePosition = Position.Bottom, + targetPosition = Position.Top, + label, + labelStyle, + labelShowBg, + labelBgStyle, + labelBgPadding, + labelBgBorderRadius, + style, + markerEnd, + markerStart, + curvature, + }: EdgeProps) => { + const [centerX, centerY] = getCenter({ sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition }); + const path = getBezierPath({ + sourceX, + sourceY, + sourcePosition, + targetX, + targetY, + targetPosition, + curvature, + }); + + const text = label ? ( + + ) : null; + + return ( + <> + + {text} + + ); + } +); diff --git a/src/components/Edges/UnrealBezierEdge.tsx b/src/components/Edges/SimpleBezierEdge.tsx similarity index 65% rename from src/components/Edges/UnrealBezierEdge.tsx rename to src/components/Edges/SimpleBezierEdge.tsx index c4bc04fc..7edb5a42 100644 --- a/src/components/Edges/UnrealBezierEdge.tsx +++ b/src/components/Edges/SimpleBezierEdge.tsx @@ -1,111 +1,101 @@ -import React, { memo } from 'react'; -import { EdgeProps, Position } from '../../types'; -import EdgeText from './EdgeText'; -import { getCenter } from './utils'; - - -interface GetBezierPathParams { - sourceX: number; - sourceY: number; - sourcePosition?: Position; - targetX: number; - targetY: number; - targetPosition?: Position; - curvature?: number; -} - -export function getUnrealBezierPath({ - sourceX, - sourceY, - sourcePosition = Position.Bottom, - targetX, - targetY, - targetPosition = Position.Top, - curvature = 0.5 -}: GetBezierPathParams): string { - const leftAndRight = [Position.Left, Position.Right]; - - // Distance between the source and target - const distanceX = sourceX - targetX; - const distanceY = sourceY - targetY; - - // A scalar value to fix the curve size getting larger - const scalarX = Math.min(curvature, Math.max(0, distanceX / 10000)); - const scalarY = Math.min(curvature, Math.max(0, distanceY / 10000)); - - const hx1 = sourceX + Math.abs(targetX - sourceX) * (curvature - scalarX); - const hx2 = targetX - Math.abs(targetX - sourceX) * (curvature - scalarX); - - const hy1 = sourceY + Math.abs(targetY - sourceY) * (curvature - scalarY); - const hy2 = targetY - Math.abs(targetY - sourceY) * (curvature - scalarY); - - let path = `M${sourceX},${sourceY} C${sourceX},${hy1} ${targetX},${hy2} ${targetX},${targetY}`; - - if (leftAndRight.includes(sourcePosition) && leftAndRight.includes(targetPosition)) { - path = `M${sourceX},${sourceY} C${hx1},${sourceY} ${hx2},${targetY}, ${targetX},${targetY}`; - } else if (leftAndRight.includes(targetPosition)) { - path = `M${sourceX},${sourceY} Q${sourceX},${targetY} ${targetX},${targetY}`; - } else if (leftAndRight.includes(sourcePosition)) { - path = `M${sourceX},${sourceY} Q${targetX},${sourceY} ${targetX},${targetY}`; - } - - return path; -} - -export default memo( - ({ - sourceX, - sourceY, - targetX, - targetY, - sourcePosition = Position.Bottom, - targetPosition = Position.Top, - label, - labelStyle, - labelShowBg, - labelBgStyle, - labelBgPadding, - labelBgBorderRadius, - style, - markerEnd, - markerStart, - curvature, - }: EdgeProps) => { - const [centerX, centerY] = getCenter({ sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition }); - const path = getUnrealBezierPath({ - sourceX, - sourceY, - sourcePosition, - targetX, - targetY, - targetPosition, - curvature, - }); - - const text = label ? ( - - ) : null; - - return ( - <> - - {text} - - ); - } -); +import React, { memo } from 'react'; + +import EdgeText from './EdgeText'; +import { getCenter } from './utils'; +import { EdgeProps, Position } from '../../types'; + +interface GetBezierPathParams { + sourceX: number; + sourceY: number; + sourcePosition?: Position; + targetX: number; + targetY: number; + targetPosition?: Position; + centerX?: number; + centerY?: number; +} + +export function getBezierPath({ + sourceX, + sourceY, + sourcePosition = Position.Bottom, + targetX, + targetY, + targetPosition = Position.Top, + centerX, + centerY, +}: GetBezierPathParams): string { + const [_centerX, _centerY] = getCenter({ sourceX, sourceY, targetX, targetY }); + const leftAndRight = [Position.Left, Position.Right]; + + const cX = typeof centerX !== 'undefined' ? centerX : _centerX; + const cY = typeof centerY !== 'undefined' ? centerY : _centerY; + + let path = `M${sourceX},${sourceY} C${sourceX},${cY} ${targetX},${cY} ${targetX},${targetY}`; + + if (leftAndRight.includes(sourcePosition) && leftAndRight.includes(targetPosition)) { + path = `M${sourceX},${sourceY} C${cX},${sourceY} ${cX},${targetY} ${targetX},${targetY}`; + } else if (leftAndRight.includes(targetPosition)) { + path = `M${sourceX},${sourceY} Q${sourceX},${targetY} ${targetX},${targetY}`; + } else if (leftAndRight.includes(sourcePosition)) { + path = `M${sourceX},${sourceY} Q${targetX},${sourceY} ${targetX},${targetY}`; + } + + return path; +} + +export default memo( + ({ + sourceX, + sourceY, + targetX, + targetY, + sourcePosition = Position.Bottom, + targetPosition = Position.Top, + label, + labelStyle, + labelShowBg, + labelBgStyle, + labelBgPadding, + labelBgBorderRadius, + style, + markerEnd, + markerStart, + }: EdgeProps) => { + const [centerX, centerY] = getCenter({ sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition }); + const path = getBezierPath({ + sourceX, + sourceY, + sourcePosition, + targetX, + targetY, + targetPosition, + }); + + const text = label ? ( + + ) : null; + + return ( + <> + + {text} + + ); + } +); diff --git a/src/components/Edges/index.ts b/src/components/Edges/index.ts index 727f889b..e4d30109 100644 --- a/src/components/Edges/index.ts +++ b/src/components/Edges/index.ts @@ -1,5 +1,5 @@ -export { default as BezierEdge } from './BezierEdge'; +export { default as SimpleBezierEdge } from './SimpleBezierEdge'; export { default as SmoothStepEdge } from './SmoothStepEdge'; export { default as StepEdge } from './StepEdge'; export { default as StraightEdge } from './StraightEdge'; -export { default as UnrealBezierEdge } from './UnrealBezierEdge'; +export { default as BezierEdge } from './BezierEdge'; diff --git a/src/container/EdgeRenderer/utils.ts b/src/container/EdgeRenderer/utils.ts index c00dd6aa..450995e2 100644 --- a/src/container/EdgeRenderer/utils.ts +++ b/src/container/EdgeRenderer/utils.ts @@ -1,5 +1,5 @@ import { ComponentType } from 'react'; -import { BezierEdge, SmoothStepEdge, StepEdge, StraightEdge, UnrealBezierEdge } from '../../components/Edges'; +import { BezierEdge, SmoothStepEdge, StepEdge, StraightEdge, SimpleBezierEdge } from '../../components/Edges'; import wrapEdge from '../../components/Edges/wrapEdge'; import { EdgeProps, @@ -22,7 +22,7 @@ export function createEdgeTypes(edgeTypes: EdgeTypes): EdgeTypes { straight: wrapEdge((edgeTypes.bezier || StraightEdge) as ComponentType), step: wrapEdge((edgeTypes.step || StepEdge) as ComponentType), smoothstep: wrapEdge((edgeTypes.step || SmoothStepEdge) as ComponentType), - unreal: wrapEdge((edgeTypes.unreal || UnrealBezierEdge) as ComponentType), + simplebezier: wrapEdge((edgeTypes.simplebezier || SimpleBezierEdge) as ComponentType), }; const wrappedTypes = {} as EdgeTypes; diff --git a/src/container/ReactFlow/index.tsx b/src/container/ReactFlow/index.tsx index d5a6ea38..0a133393 100644 --- a/src/container/ReactFlow/index.tsx +++ b/src/container/ReactFlow/index.tsx @@ -1,7 +1,7 @@ import cc from 'classcat'; import React, { forwardRef } from 'react'; import Attribution from '../../components/Attribution'; -import { BezierEdge, SmoothStepEdge, StepEdge, StraightEdge, UnrealBezierEdge } from '../../components/Edges'; +import { BezierEdge, SmoothStepEdge, StepEdge, StraightEdge, SimpleBezierEdge } from '../../components/Edges'; import DefaultNode from '../../components/Nodes/DefaultNode'; import InputNode from '../../components/Nodes/InputNode'; import OutputNode from '../../components/Nodes/OutputNode'; @@ -10,9 +10,13 @@ import StoreUpdater from '../../components/StoreUpdater'; import css from '../../style.css'; import theme from '../../theme-default.css'; import { - ConnectionLineType, ConnectionMode, EdgeTypes, NodeTypes, PanOnScrollMode, + ConnectionLineType, + ConnectionMode, + EdgeTypes, + NodeTypes, + PanOnScrollMode, ReactFlowProps, - ReactFlowRefType + ReactFlowRefType, } from '../../types'; import { createEdgeTypes } from '../EdgeRenderer/utils'; import GraphView from '../GraphView'; @@ -20,10 +24,6 @@ import { createNodeTypes } from '../NodeRenderer/utils'; import injectStyle, { useNodeOrEdgeTypes } from './utils'; import Wrapper from './Wrapper'; - - - - if (__INJECT_STYLES__) { injectStyle(css as unknown as string); injectStyle(theme as unknown as string); @@ -40,7 +40,7 @@ const defaultEdgeTypes = { straight: StraightEdge, step: StepEdge, smoothstep: SmoothStepEdge, - unreal: UnrealBezierEdge, + simplebezier: SimpleBezierEdge, }; const initSnapGrid: [number, number] = [15, 15]; diff --git a/src/index.ts b/src/index.ts index 6f29e003..03a8a0ef 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,7 +6,7 @@ export { default as Handle } from './components/Handle'; export { default as EdgeText } from './components/Edges/EdgeText'; export { default as StraightEdge } from './components/Edges/StraightEdge'; export { default as StepEdge } from './components/Edges/StepEdge'; -export { default as BezierEdge, getBezierPath } from './components/Edges/BezierEdge'; +export { default as BezierEdge, getBezierPath } from './components/Edges/SimpleBezierEdge'; export { default as SmoothStepEdge, getSmoothStepPath } from './components/Edges/SmoothStepEdge'; export * from './additional-components';