From 9a7ccbf82903f353c796e7c34684728e78013b25 Mon Sep 17 00:00:00 2001 From: moklick Date: Sun, 28 Mar 2021 17:01:50 +0200 Subject: [PATCH] refactor(edges): handle mixed edges #961 --- src/components/Edges/BezierEdge.tsx | 2 +- src/components/Edges/SmoothStepEdge.tsx | 2 +- src/components/Edges/utils.ts | 25 ++++++++++++++++++++++++- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/components/Edges/BezierEdge.tsx b/src/components/Edges/BezierEdge.tsx index 18c62e40..368fdcc6 100644 --- a/src/components/Edges/BezierEdge.tsx +++ b/src/components/Edges/BezierEdge.tsx @@ -63,7 +63,7 @@ export default memo( arrowHeadType, markerEndId, }: EdgeProps) => { - const [centerX, centerY] = getCenter({ sourceX, sourceY, targetX, targetY }); + const [centerX, centerY] = getCenter({ sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition }); const path = getBezierPath({ sourceX, sourceY, diff --git a/src/components/Edges/SmoothStepEdge.tsx b/src/components/Edges/SmoothStepEdge.tsx index 3b6b5e5c..9062cb00 100644 --- a/src/components/Edges/SmoothStepEdge.tsx +++ b/src/components/Edges/SmoothStepEdge.tsx @@ -124,7 +124,7 @@ export default memo( markerEndId, borderRadius = 5, }: EdgeSmoothStepProps) => { - const [centerX, centerY] = getCenter({ sourceX, sourceY, targetX, targetY }); + const [centerX, centerY] = getCenter({ sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition }); const path = getSmoothStepPath({ sourceX, diff --git a/src/components/Edges/utils.ts b/src/components/Edges/utils.ts index cc217446..912fd58f 100644 --- a/src/components/Edges/utils.ts +++ b/src/components/Edges/utils.ts @@ -1,4 +1,4 @@ -import { ArrowHeadType } from '../../types'; +import { ArrowHeadType, Position } from '../../types'; export const getMarkerEnd = (arrowHeadType?: ArrowHeadType, markerEndId?: string): string => { if (typeof markerEndId !== 'undefined' && markerEndId) { @@ -13,14 +13,37 @@ export interface GetCenterParams { sourceY: number; targetX: number; targetY: number; + sourcePosition?: Position; + targetPosition?: Position; } +const LeftOrRight = [Position.Left, Position.Right]; + export const getCenter = ({ sourceX, sourceY, targetX, targetY, + sourcePosition = Position.Bottom, + targetPosition = Position.Top, }: GetCenterParams): [number, number, number, number] => { + const sourceIsLeftOrRight = LeftOrRight.includes(sourcePosition); + const targetIsLeftOrRight = LeftOrRight.includes(targetPosition); + + // we expect flows to be horizontal or vertical (all handles left or right respectively top or bottom) + // a mixed edge is when one the source is on the left and the target is on the top for example. + const mixedEdge = (sourceIsLeftOrRight && !targetIsLeftOrRight) || (targetIsLeftOrRight && !sourceIsLeftOrRight); + + if (mixedEdge) { + const xOffset = sourceIsLeftOrRight ? Math.abs(targetX - sourceX) : 0; + const centerX = sourceX > targetX ? sourceX - xOffset : sourceX + xOffset; + + const yOffset = sourceIsLeftOrRight ? 0 : Math.abs(targetY - sourceY); + const centerY = sourceY < targetY ? sourceY + yOffset : sourceY - yOffset; + + return [centerX, centerY, xOffset, yOffset]; + } + const xOffset = Math.abs(targetX - sourceX) / 2; const centerX = targetX < sourceX ? targetX + xOffset : targetX - xOffset;