refactor(edges): use new edge as default, add simplebezier

This commit is contained in:
moklick
2022-03-14 16:01:00 +01:00
parent 3c96b07c9c
commit b362c11851
9 changed files with 248 additions and 233 deletions
+1 -1
View File
@@ -12,7 +12,7 @@ const nodeColors = [
['#1e9e99', '#4cb3ac', '#6ec9c0', '#8ddfd4', '#c4fff7'], ['#1e9e99', '#4cb3ac', '#6ec9c0', '#8ddfd4', '#c4fff7'],
['#0f4c75', '#1b5d8b', '#276fa1', '#3282b8', '#4fa6e0'], ['#0f4c75', '#1b5d8b', '#276fa1', '#3282b8', '#4fa6e0'],
]; ];
const edgeTypes = ['default', 'step', 'smoothstep', 'straight', 'unreal']; const edgeTypes = ['default', 'step', 'smoothstep', 'straight', 'simplebezier'];
const offsets = [ const offsets = [
{ {
x: 0, x: 0,
+22 -6
View File
@@ -1,12 +1,22 @@
import { MouseEvent } from 'react'; import { MouseEvent } from 'react';
import ReactFlow, { 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'; } from 'react-flow-renderer';
import CustomEdge from './CustomEdge'; import CustomEdge from './CustomEdge';
import CustomEdge2 from './CustomEdge2'; import CustomEdge2 from './CustomEdge2';
const onInit = (reactFlowInstance: ReactFlowInstance) => reactFlowInstance.fitView(); const onInit = (reactFlowInstance: ReactFlowInstance) => reactFlowInstance.fitView();
const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node); const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node);
const onNodeClick = (_: MouseEvent, node: Node) => console.log('click', 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: '1', type: 'input', data: { label: 'Input 1' }, position: { x: 250, y: 0 } },
{ id: '2', data: { label: 'Node 2' }, position: { x: 150, y: 100 } }, { id: '2', data: { label: 'Node 2' }, position: { x: 150, y: 100 } },
{ id: '2a', data: { label: 'Node 2a' }, position: { x: 0, y: 180 } }, { 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: '3', data: { label: 'Node 3' }, position: { x: 250, y: 200 } },
{ id: '4', data: { label: 'Node 4' }, position: { x: 400, y: 300 } }, { id: '4', data: { label: 'Node 4' }, position: { x: 400, y: 300 } },
{ id: '3a', data: { label: 'Node 3a' }, position: { x: 150, y: 300 } }, { id: '3a', data: { label: 'Node 3a' }, position: { x: 150, y: 300 } },
@@ -29,7 +39,13 @@ const initialNodes: Node[] = [
const initialEdges: Edge[] = [ const initialEdges: Edge[] = [
{ id: 'e1-2', source: '1', target: '2', label: 'bezier edge (default)', className: 'normal-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: '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: '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-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' } }, { 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 EdgesFlow = () => {
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes); const [nodes, , onNodesChange] = useNodesState(initialNodes);
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges); const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
const onConnect = (params: Connection | Edge) => setEdges((eds) => addEdge(params, eds)); const onConnect = (params: Connection | Edge) => setEdges((eds) => addEdge(params, eds));
+1 -1
View File
@@ -2,7 +2,7 @@ import React, { useRef, CSSProperties } from 'react';
import shallow from 'zustand/shallow'; import shallow from 'zustand/shallow';
import { useStore } from '../../store'; import { useStore } from '../../store';
import { getBezierPath } from '../Edges/BezierEdge'; import { getBezierPath } from '../Edges/SimpleBezierEdge';
import { getSmoothStepPath } from '../Edges/SmoothStepEdge'; import { getSmoothStepPath } from '../Edges/SmoothStepEdge';
import { import {
HandleElement, HandleElement,
+20 -11
View File
@@ -1,8 +1,7 @@
import React, { memo } from 'react'; import React, { memo } from 'react';
import { EdgeProps, Position } from '../../types';
import EdgeText from './EdgeText'; import EdgeText from './EdgeText';
import { getCenter } from './utils'; import { getCenter } from './utils';
import { EdgeProps, Position } from '../../types';
interface GetBezierPathParams { interface GetBezierPathParams {
sourceX: number; sourceX: number;
@@ -11,8 +10,7 @@ interface GetBezierPathParams {
targetX: number; targetX: number;
targetY: number; targetY: number;
targetPosition?: Position; targetPosition?: Position;
centerX?: number; curvature?: number;
centerY?: number;
} }
export function getBezierPath({ export function getBezierPath({
@@ -22,19 +20,28 @@ export function getBezierPath({
targetX, targetX,
targetY, targetY,
targetPosition = Position.Top, targetPosition = Position.Top,
centerX, curvature = 0.5,
centerY,
}: GetBezierPathParams): string { }: GetBezierPathParams): string {
const [_centerX, _centerY] = getCenter({ sourceX, sourceY, targetX, targetY });
const leftAndRight = [Position.Left, Position.Right]; const leftAndRight = [Position.Left, Position.Right];
const cX = typeof centerX !== 'undefined' ? centerX : _centerX; // Distance between the source and target
const cY = typeof centerY !== 'undefined' ? centerY : _centerY; const distanceX = sourceX - targetX;
const distanceY = sourceY - targetY;
let path = `M${sourceX},${sourceY} C${sourceX},${cY} ${targetX},${cY} ${targetX},${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)) { if (leftAndRight.includes(sourcePosition) && leftAndRight.includes(targetPosition)) {
path = `M${sourceX},${sourceY} C${cX},${sourceY} ${cX},${targetY} ${targetX},${targetY}`; path = `M${sourceX},${sourceY} C${hx1},${sourceY} ${hx2},${targetY}, ${targetX},${targetY}`;
} else if (leftAndRight.includes(targetPosition)) { } else if (leftAndRight.includes(targetPosition)) {
path = `M${sourceX},${sourceY} Q${sourceX},${targetY} ${targetX},${targetY}`; path = `M${sourceX},${sourceY} Q${sourceX},${targetY} ${targetX},${targetY}`;
} else if (leftAndRight.includes(sourcePosition)) { } else if (leftAndRight.includes(sourcePosition)) {
@@ -61,6 +68,7 @@ export default memo(
style, style,
markerEnd, markerEnd,
markerStart, markerStart,
curvature,
}: EdgeProps) => { }: EdgeProps) => {
const [centerX, centerY] = getCenter({ sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition }); const [centerX, centerY] = getCenter({ sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition });
const path = getBezierPath({ const path = getBezierPath({
@@ -70,6 +78,7 @@ export default memo(
targetX, targetX,
targetY, targetY,
targetPosition, targetPosition,
curvature,
}); });
const text = label ? ( const text = label ? (
@@ -1,8 +1,8 @@
import React, { memo } from 'react'; import React, { memo } from 'react';
import { EdgeProps, Position } from '../../types';
import EdgeText from './EdgeText'; import EdgeText from './EdgeText';
import { getCenter } from './utils'; import { getCenter } from './utils';
import { EdgeProps, Position } from '../../types';
interface GetBezierPathParams { interface GetBezierPathParams {
sourceX: number; sourceX: number;
@@ -11,38 +11,30 @@ interface GetBezierPathParams {
targetX: number; targetX: number;
targetY: number; targetY: number;
targetPosition?: Position; targetPosition?: Position;
curvature?: number; centerX?: number;
centerY?: number;
} }
export function getUnrealBezierPath({ export function getBezierPath({
sourceX, sourceX,
sourceY, sourceY,
sourcePosition = Position.Bottom, sourcePosition = Position.Bottom,
targetX, targetX,
targetY, targetY,
targetPosition = Position.Top, targetPosition = Position.Top,
curvature = 0.5 centerX,
centerY,
}: GetBezierPathParams): string { }: GetBezierPathParams): string {
const [_centerX, _centerY] = getCenter({ sourceX, sourceY, targetX, targetY });
const leftAndRight = [Position.Left, Position.Right]; const leftAndRight = [Position.Left, Position.Right];
// Distance between the source and target const cX = typeof centerX !== 'undefined' ? centerX : _centerX;
const distanceX = sourceX - targetX; const cY = typeof centerY !== 'undefined' ? centerY : _centerY;
const distanceY = sourceY - targetY;
// A scalar value to fix the curve size getting larger let path = `M${sourceX},${sourceY} C${sourceX},${cY} ${targetX},${cY} ${targetX},${targetY}`;
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)) { if (leftAndRight.includes(sourcePosition) && leftAndRight.includes(targetPosition)) {
path = `M${sourceX},${sourceY} C${hx1},${sourceY} ${hx2},${targetY}, ${targetX},${targetY}`; path = `M${sourceX},${sourceY} C${cX},${sourceY} ${cX},${targetY} ${targetX},${targetY}`;
} else if (leftAndRight.includes(targetPosition)) { } else if (leftAndRight.includes(targetPosition)) {
path = `M${sourceX},${sourceY} Q${sourceX},${targetY} ${targetX},${targetY}`; path = `M${sourceX},${sourceY} Q${sourceX},${targetY} ${targetX},${targetY}`;
} else if (leftAndRight.includes(sourcePosition)) { } else if (leftAndRight.includes(sourcePosition)) {
@@ -69,17 +61,15 @@ export default memo(
style, style,
markerEnd, markerEnd,
markerStart, markerStart,
curvature,
}: EdgeProps) => { }: EdgeProps) => {
const [centerX, centerY] = getCenter({ sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition }); const [centerX, centerY] = getCenter({ sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition });
const path = getUnrealBezierPath({ const path = getBezierPath({
sourceX, sourceX,
sourceY, sourceY,
sourcePosition, sourcePosition,
targetX, targetX,
targetY, targetY,
targetPosition, targetPosition,
curvature,
}); });
const text = label ? ( const text = label ? (
+2 -2
View File
@@ -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 SmoothStepEdge } from './SmoothStepEdge';
export { default as StepEdge } from './StepEdge'; export { default as StepEdge } from './StepEdge';
export { default as StraightEdge } from './StraightEdge'; export { default as StraightEdge } from './StraightEdge';
export { default as UnrealBezierEdge } from './UnrealBezierEdge'; export { default as BezierEdge } from './BezierEdge';
+2 -2
View File
@@ -1,5 +1,5 @@
import { ComponentType } from 'react'; 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 wrapEdge from '../../components/Edges/wrapEdge';
import { import {
EdgeProps, EdgeProps,
@@ -22,7 +22,7 @@ export function createEdgeTypes(edgeTypes: EdgeTypes): EdgeTypes {
straight: wrapEdge((edgeTypes.bezier || StraightEdge) as ComponentType<EdgeProps>), straight: wrapEdge((edgeTypes.bezier || StraightEdge) as ComponentType<EdgeProps>),
step: wrapEdge((edgeTypes.step || StepEdge) as ComponentType<EdgeProps>), step: wrapEdge((edgeTypes.step || StepEdge) as ComponentType<EdgeProps>),
smoothstep: wrapEdge((edgeTypes.step || SmoothStepEdge) as ComponentType<EdgeProps>), smoothstep: wrapEdge((edgeTypes.step || SmoothStepEdge) as ComponentType<EdgeProps>),
unreal: wrapEdge((edgeTypes.unreal || UnrealBezierEdge) as ComponentType<EdgeProps>), simplebezier: wrapEdge((edgeTypes.simplebezier || SimpleBezierEdge) as ComponentType<EdgeProps>),
}; };
const wrappedTypes = {} as EdgeTypes; const wrappedTypes = {} as EdgeTypes;
+8 -8
View File
@@ -1,7 +1,7 @@
import cc from 'classcat'; import cc from 'classcat';
import React, { forwardRef } from 'react'; import React, { forwardRef } from 'react';
import Attribution from '../../components/Attribution'; 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 DefaultNode from '../../components/Nodes/DefaultNode';
import InputNode from '../../components/Nodes/InputNode'; import InputNode from '../../components/Nodes/InputNode';
import OutputNode from '../../components/Nodes/OutputNode'; import OutputNode from '../../components/Nodes/OutputNode';
@@ -10,9 +10,13 @@ import StoreUpdater from '../../components/StoreUpdater';
import css from '../../style.css'; import css from '../../style.css';
import theme from '../../theme-default.css'; import theme from '../../theme-default.css';
import { import {
ConnectionLineType, ConnectionMode, EdgeTypes, NodeTypes, PanOnScrollMode, ConnectionLineType,
ConnectionMode,
EdgeTypes,
NodeTypes,
PanOnScrollMode,
ReactFlowProps, ReactFlowProps,
ReactFlowRefType ReactFlowRefType,
} from '../../types'; } from '../../types';
import { createEdgeTypes } from '../EdgeRenderer/utils'; import { createEdgeTypes } from '../EdgeRenderer/utils';
import GraphView from '../GraphView'; import GraphView from '../GraphView';
@@ -20,10 +24,6 @@ import { createNodeTypes } from '../NodeRenderer/utils';
import injectStyle, { useNodeOrEdgeTypes } from './utils'; import injectStyle, { useNodeOrEdgeTypes } from './utils';
import Wrapper from './Wrapper'; import Wrapper from './Wrapper';
if (__INJECT_STYLES__) { if (__INJECT_STYLES__) {
injectStyle(css as unknown as string); injectStyle(css as unknown as string);
injectStyle(theme as unknown as string); injectStyle(theme as unknown as string);
@@ -40,7 +40,7 @@ const defaultEdgeTypes = {
straight: StraightEdge, straight: StraightEdge,
step: StepEdge, step: StepEdge,
smoothstep: SmoothStepEdge, smoothstep: SmoothStepEdge,
unreal: UnrealBezierEdge, simplebezier: SimpleBezierEdge,
}; };
const initSnapGrid: [number, number] = [15, 15]; const initSnapGrid: [number, number] = [15, 15];
+1 -1
View File
@@ -6,7 +6,7 @@ export { default as Handle } from './components/Handle';
export { default as EdgeText } from './components/Edges/EdgeText'; export { default as EdgeText } from './components/Edges/EdgeText';
export { default as StraightEdge } from './components/Edges/StraightEdge'; export { default as StraightEdge } from './components/Edges/StraightEdge';
export { default as StepEdge } from './components/Edges/StepEdge'; 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 { default as SmoothStepEdge, getSmoothStepPath } from './components/Edges/SmoothStepEdge';
export * from './additional-components'; export * from './additional-components';