diff --git a/example/src/Edges/index.tsx b/example/src/Edges/index.tsx
index d527ae45..35d6aaa4 100644
--- a/example/src/Edges/index.tsx
+++ b/example/src/Edges/index.tsx
@@ -25,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 }, targetPosition: Position.Left },
+ { id: '2b', data: { label: 'Node 2b' }, position: { x: -40, y: 300 } },
{ 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 } },
diff --git a/src/components/ConnectionLine/index.tsx b/src/components/ConnectionLine/index.tsx
index 0654a4b4..4a4db773 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/SimpleBezierEdge';
+import { getBezierPath } from '../Edges/BezierEdge';
import { getSmoothStepPath } from '../Edges/SmoothStepEdge';
import {
HandleElement,
@@ -13,6 +13,7 @@ import {
ReactFlowState,
Position,
} from '../../types';
+import { getSimpleBezierPath } from '../Edges/SimpleBezierEdge';
interface ConnectionLineProps {
connectionNodeId: string;
@@ -112,6 +113,8 @@ export default ({
});
} else if (connectionLineType === ConnectionLineType.SmoothStep) {
dAttr = getSmoothStepPath(pathParams);
+ } else if (connectionLineType === ConnectionLineType.SimpleBezier) {
+ dAttr = getSimpleBezierPath(pathParams);
} else {
dAttr = `M${sourceX},${sourceY} ${targetX},${targetY}`;
}
diff --git a/src/components/Edges/BaseEdge.tsx b/src/components/Edges/BaseEdge.tsx
new file mode 100644
index 00000000..19d0ab37
--- /dev/null
+++ b/src/components/Edges/BaseEdge.tsx
@@ -0,0 +1,39 @@
+import React from 'react';
+
+import EdgeText from './EdgeText';
+import { BaseEdgeProps } from '../../types';
+
+export default ({
+ path,
+ centerX,
+ centerY,
+ label,
+ labelStyle,
+ labelShowBg,
+ labelBgStyle,
+ labelBgPadding,
+ labelBgBorderRadius,
+ style,
+ markerEnd,
+ markerStart,
+}: BaseEdgeProps) => {
+ const text = label ? (
+
+ ) : null;
+
+ return (
+ <>
+
+ {text}
+ >
+ );
+};
diff --git a/src/components/Edges/BezierEdge.tsx b/src/components/Edges/BezierEdge.tsx
index 9daf07bb..b3ab9047 100644
--- a/src/components/Edges/BezierEdge.tsx
+++ b/src/components/Edges/BezierEdge.tsx
@@ -1,9 +1,10 @@
import React, { memo } from 'react';
-import { EdgeProps, Position } from '../../types';
-import EdgeText from './EdgeText';
-import { getCenter } from './utils';
-interface GetBezierPathParams {
+import BaseEdge from './BaseEdge';
+import { getCenter } from './utils';
+import { EdgeProps, Position } from '../../types';
+
+export interface GetBezierPathParams {
sourceX: number;
sourceY: number;
sourcePosition?: Position;
@@ -11,6 +12,8 @@ interface GetBezierPathParams {
targetY: number;
targetPosition?: Position;
curvature?: number;
+ centerX?: number;
+ centerY?: number;
}
export function getBezierPath({
@@ -21,14 +24,24 @@ export function getBezierPath({
targetY,
targetPosition = Position.Top,
curvature = 0.5,
+ centerX,
+ centerY,
}: GetBezierPathParams): string {
const leftAndRight = [Position.Left, Position.Right];
+ const hasCurvature = curvature > 0;
+ let cX,
+ cY = 0;
+
+ if (!hasCurvature) {
+ const [_centerX, _centerY] = getCenter({ sourceX, sourceY, targetX, targetY });
+ cX = typeof centerX !== 'undefined' ? centerX : _centerX;
+ cY = typeof centerY !== 'undefined' ? centerY : _centerY;
+ }
- // Distance between the source and target
const distanceX = sourceX - targetX;
const distanceY = sourceY - targetY;
- // // A scalar value to fix the curve size getting larger
+ // 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));
@@ -38,10 +51,14 @@ export function getBezierPath({
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}`;
+ let path = hasCurvature
+ ? `M${sourceX},${sourceY} C${sourceX},${hy1} ${targetX},${hy2} ${targetX},${targetY}`
+ : `M${sourceX},${sourceY} C${sourceX},${cY} ${targetX},${cY} ${targetX},${targetY}`;
if (leftAndRight.includes(sourcePosition) && leftAndRight.includes(targetPosition)) {
- path = `M${sourceX},${sourceY} C${hx1},${sourceY} ${hx2},${targetY}, ${targetX},${targetY}`;
+ path = hasCurvature
+ ? `M${sourceX},${sourceY} C${hx1},${sourceY} ${hx2},${targetY}, ${targetX},${targetY}`
+ : `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)) {
@@ -81,30 +98,21 @@ export default memo(
curvature,
});
- const text = label ? (
-
- ) : null;
-
- return (
- <>
-
- {text}
- >
);
}
);
diff --git a/src/components/Edges/SimpleBezierEdge.tsx b/src/components/Edges/SimpleBezierEdge.tsx
index 7edb5a42..1bc671c9 100644
--- a/src/components/Edges/SimpleBezierEdge.tsx
+++ b/src/components/Edges/SimpleBezierEdge.tsx
@@ -1,101 +1,12 @@
import React, { memo } from 'react';
-import EdgeText from './EdgeText';
-import { getCenter } from './utils';
-import { EdgeProps, Position } from '../../types';
+import BezierEdge, { getBezierPath, GetBezierPathParams } from './BezierEdge';
+import { EdgeProps } from '../../types';
-interface GetBezierPathParams {
- sourceX: number;
- sourceY: number;
- sourcePosition?: Position;
- targetX: number;
- targetY: number;
- targetPosition?: Position;
- centerX?: number;
- centerY?: number;
+export function getSimpleBezierPath(props: GetBezierPathParams): string {
+ return getBezierPath({ ...props, curvature: 0 });
}
-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}
- >
- );
- }
-);
+export default memo((props: EdgeProps) => {
+ return ;
+});
diff --git a/src/components/Edges/SmoothStepEdge.tsx b/src/components/Edges/SmoothStepEdge.tsx
index 0736683a..4eb1ba6b 100644
--- a/src/components/Edges/SmoothStepEdge.tsx
+++ b/src/components/Edges/SmoothStepEdge.tsx
@@ -1,8 +1,8 @@
import React, { memo } from 'react';
-import EdgeText from './EdgeText';
import { getCenter } from './utils';
import { EdgeSmoothStepProps, Position } from '../../types';
+import BaseEdge from './BaseEdge';
// These are some helper methods for drawing the round corners
// The name indicates the direction of the path. "bottomLeftCorner" goes
@@ -21,7 +21,7 @@ const topLeftCorner = (x: number, y: number, size: number): string => `L ${x},${
const topRightCorner = (x: number, y: number, size: number): string => `L ${x},${y + size}Q ${x},${y} ${x - size},${y}`;
const rightTopCorner = (x: number, y: number, size: number): string => `L ${x - size},${y}Q ${x},${y} ${x},${y + size}`;
-interface GetSmoothStepPathParams {
+export interface GetSmoothStepPathParams {
sourceX: number;
sourceY: number;
sourcePosition?: Position;
@@ -146,30 +146,21 @@ export default memo(
borderRadius,
});
- const text = label ? (
-
- ) : null;
-
- return (
- <>
-
- {text}
- >
);
}
);
diff --git a/src/components/Edges/StraightEdge.tsx b/src/components/Edges/StraightEdge.tsx
index b7f0fac1..45357615 100644
--- a/src/components/Edges/StraightEdge.tsx
+++ b/src/components/Edges/StraightEdge.tsx
@@ -1,6 +1,6 @@
import React, { memo } from 'react';
-import EdgeText from './EdgeText';
+import BaseEdge from './BaseEdge';
import { EdgeProps } from '../../types';
export default memo(
@@ -24,31 +24,23 @@ export default memo(
const xOffset = Math.abs(targetX - sourceX) / 2;
const centerX = targetX < sourceX ? targetX + xOffset : targetX - xOffset;
+ const path = `M ${sourceX},${sourceY}L ${targetX},${targetY}`;
- const text = label ? (
-
- ) : null;
-
- return (
- <>
-
- {text}
- >
);
}
);
diff --git a/src/index.ts b/src/index.ts
index 03a8a0ef..826673c7 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -6,7 +6,8 @@ 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/SimpleBezierEdge';
+export { default as BezierEdge, getBezierPath } from './components/Edges/BezierEdge';
+export { default as SimpleBezierEdge, getSimpleBezierPath } from './components/Edges/SimpleBezierEdge';
export { default as SmoothStepEdge, getSmoothStepPath } from './components/Edges/SmoothStepEdge';
export * from './additional-components';
diff --git a/src/types/edges.ts b/src/types/edges.ts
index 48757d7f..2f83eac7 100644
--- a/src/types/edges.ts
+++ b/src/types/edges.ts
@@ -4,7 +4,6 @@ import { HandleElement } from './handles';
import { Node } from './nodes';
import { Position } from './utils';
-
// interface for the user edge items
export interface Edge {
id: string;
@@ -65,6 +64,23 @@ export interface EdgeProps {
curvature?: number;
}
+export type BaseEdgeProps = Pick<
+ EdgeProps,
+ | 'label'
+ | 'labelStyle'
+ | 'labelShowBg'
+ | 'labelBgStyle'
+ | 'labelBgPadding'
+ | 'labelBgBorderRadius'
+ | 'style'
+ | 'markerStart'
+ | 'markerEnd'
+> & {
+ centerX: number;
+ centerY: number;
+ path: string;
+};
+
export type EdgeMouseHandler = (event: React.MouseEvent, edge: Edge) => void;
export interface WrapEdgeProps {
@@ -127,6 +143,7 @@ export enum ConnectionLineType {
Straight = 'straight',
Step = 'step',
SmoothStep = 'smoothstep',
+ SimpleBezier = 'simplebezier',
}
export type ConnectionLineComponentProps = {