Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/components/canvas/use-canvas.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ describe('use-canvas', () => {
{
id: 'employees-to-orders',
markerEnd: 'one',
markerStart: 'one',
markerStart: 'many',
source: 'employees',
target: 'orders',
type: 'floatingEdge',
Expand All @@ -73,7 +73,7 @@ describe('use-canvas', () => {
source: 'employees',
target: 'employees',
markerEnd: 'one',
markerStart: 'oneOrMany',
markerStart: 'many',
type: 'selfReferencingEdge',
},
]);
Expand Down
2 changes: 1 addition & 1 deletion src/components/edge/floating-edge.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ describe('floating-edge', () => {
expect(path).toHaveAttribute('id', 'orders-to-employees');
expect(path).toHaveAttribute(
'd',
'M240 136L240 156L 240,213Q 240,218 245,218L 381,218Q 386,218 386,223L386 280L386 300',
'M240 143.5L240 163.5L 240,213Q 240,218 245,218L 381,218Q 386,218 386,223L386 272.5L386 292.5',
);
});

Expand Down
14 changes: 11 additions & 3 deletions src/components/edge/floating-edge.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import { EdgeProps, getSmoothStepPath, useNodes } from '@xyflow/react';
import { EdgeProps, getSmoothStepPath, useNodes, BaseEdge } from '@xyflow/react';
import { useMemo } from 'react';
import styled from '@emotion/styled';
import { palette } from '@leafygreen-ui/palette';

import { getEdgeParams } from '@/utilities/get-edge-params';
import { InternalNode } from '@/types/internal';

export const FloatingEdge = ({ id, source, target }: EdgeProps) => {
const Edge = styled(BaseEdge)`
stroke: ${palette.gray.base};
`;

export const FloatingEdge = ({ id, source, target, markerEnd, markerStart }: EdgeProps) => {
const nodes = useNodes<InternalNode>();

const { sourceNode, targetNode } = useMemo(() => {
Expand All @@ -26,5 +32,7 @@ export const FloatingEdge = ({ id, source, target }: EdgeProps) => {
targetY: ty,
});

return <path data-testid={`floating-edge-${id}`} className="react-flow__edge-path" d={path} id={id} />;
return (
<Edge data-testid={`floating-edge-${id}`} markerEnd={markerEnd} markerStart={markerStart} path={path} id={id} />
);
};
2 changes: 1 addition & 1 deletion src/components/edge/self-referencing-edge.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ describe('self-referencing-edge', () => {
renderComponent();
const path = screen.getByTestId('self-referencing-edge-employees-to-employees');
expect(path).toHaveAttribute('id', 'employees-to-employees');
expect(path).toHaveAttribute('d', 'M422,300L422,270L584,270L584,336L544,336');
expect(path).toHaveAttribute('d', 'M422,292.5L422,262.5L584,262.5L584,328.5L551.5,328.5');
});

it('Should not render edge if source does not exist', () => {
Expand Down
22 changes: 15 additions & 7 deletions src/components/edge/self-referencing-edge.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
import { EdgeProps, useNodes } from '@xyflow/react';
import { BaseEdge, EdgeProps, useNodes } from '@xyflow/react';
import { useMemo } from 'react';
import { path } from 'd3-path';
import styled from '@emotion/styled';
import { palette } from '@leafygreen-ui/palette';

import { InternalNode } from '@/types/internal';
import { DEFAULT_MARKER_SIZE } from '@/utilities/constants';

export const SelfReferencingEdge = ({ id, source }: EdgeProps) => {
const Edge = styled(BaseEdge)`
stroke: ${palette.gray.base};
`;

export const SelfReferencingEdge = ({ id, source, markerEnd, markerStart }: EdgeProps) => {
const nodes = useNodes<InternalNode>();

const { sourceNode } = useMemo(() => {
Expand All @@ -24,7 +31,7 @@ export const SelfReferencingEdge = ({ id, source }: EdgeProps) => {
const rightHeight = centerY + leftHeight;

const startX = sourceNode.position.x + centerX;
const startY = sourceNode.position.y;
const startY = sourceNode.position.y - DEFAULT_MARKER_SIZE / 2;

const topLeftCornerX = startX;
const topLeftCornerY = startY - leftHeight;
Expand All @@ -35,7 +42,7 @@ export const SelfReferencingEdge = ({ id, source }: EdgeProps) => {
const bottomRightCornerX = topRightCornerX;
const bottomRightCornerY = topRightCornerY + rightHeight;

const bottomLeftCornerX = topRightCornerX - width + centerX;
const bottomLeftCornerX = topRightCornerX - width + centerX + DEFAULT_MARKER_SIZE / 2;
const bottomLeftCornerY = bottomRightCornerY;

const context = path();
Expand All @@ -46,10 +53,11 @@ export const SelfReferencingEdge = ({ id, source }: EdgeProps) => {
context.lineTo(bottomLeftCornerX, bottomLeftCornerY);

return (
<path
<Edge
data-testid={`self-referencing-edge-${id}`}
className="react-flow__edge-path"
d={context.toString()}
markerEnd={markerEnd}
markerStart={markerStart}
path={context.toString()}
id={id}
/>
);
Expand Down
4 changes: 2 additions & 2 deletions src/mocks/datasets/edges.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ export const ORDERS_TO_EMPLOYEES_EDGE: Edge = {
source: 'employees',
target: 'orders',
markerEnd: 'one',
markerStart: 'one',
markerStart: 'many',
};

export const EMPLOYEES_TO_EMPLOYEES_EDGE: Edge = {
id: 'employees-to-employees',
source: 'employees',
target: 'employees',
markerEnd: 'one',
markerStart: 'oneOrMany',
markerStart: 'many',
};
1 change: 1 addition & 0 deletions src/utilities/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ export const DEFAULT_NODE_HEADER_HEIGHT = 28;
export const DEFAULT_FIELD_HEIGHT = 18;
export const DEFAULT_FIELD_PADDING = 8;
export const DEFAULT_DEPTH_SPACING = 8;
export const DEFAULT_MARKER_SIZE = 15;
4 changes: 2 additions & 2 deletions src/utilities/get-edge-params.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ describe('get-edge-params', () => {
expect(result).toEqual({
sourcePos: 'bottom',
sx: 240,
sy: 136,
sy: 143.5,
targetPos: 'top',
tx: 386,
ty: 300,
ty: 292.5,
});
});
});
35 changes: 31 additions & 4 deletions src/utilities/get-edge-params.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Position, XYPosition } from '@xyflow/react';

import { InternalNode } from '@/types/internal';
import { DEFAULT_MARKER_SIZE } from '@/utilities/constants';

/**
* Returns the coordinates where a line connecting the centers of the source and target nodes intersects
Expand Down Expand Up @@ -66,6 +67,29 @@ const getEdgePosition = (node: InternalNode, intersectionPoint: XYPosition) => {
return Position.Top;
};

/**
* Offsets the edge position based on the size of the marker
*
* @param position Direction of the edge
* @param x Co-ordinates of the edge
* @param y Co-ordinates of the edge
*/
const offsetPosition = (position: Position, { x, y }: { x: number; y: number }) => {
const offset = DEFAULT_MARKER_SIZE / 2;
switch (position) {
case Position.Left:
return { x: x - offset, y };
case Position.Top:
return { x, y: y - offset };
case Position.Right:
return { x: x + offset, y };
case Position.Bottom:
return { x, y: y + offset };
default:
return { x, y };
}
};

/**
* Returns the coordinates where a line connecting the centers of the source and target nodes intersects
* the edges of those nodes. This implementation is copied from:
Expand All @@ -81,11 +105,14 @@ export const getEdgeParams = (source: InternalNode, target: InternalNode) => {
const sourcePos = getEdgePosition(source, sourceIntersectionPoint);
const targetPos = getEdgePosition(target, targetIntersectionPoint);

const sourceOffsetPosition = offsetPosition(sourcePos, sourceIntersectionPoint);
const targetOffsetPosition = offsetPosition(targetPos, targetIntersectionPoint);

return {
sx: sourceIntersectionPoint.x,
sy: sourceIntersectionPoint.y,
tx: targetIntersectionPoint.x,
ty: targetIntersectionPoint.y,
sx: sourceOffsetPosition.x,
sy: sourceOffsetPosition.y,
tx: targetOffsetPosition.x,
ty: targetOffsetPosition.y,
sourcePos,
targetPos,
};
Expand Down
3 changes: 2 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@
},
"include": [
"src",
".storybook"
".storybook",
"vite-env.d.ts"
],
"exclude": [
"node_modules",
Expand Down