refactor: Change Position into enum (#48)

This commit is contained in:
AndyLnd
2019-10-22 16:37:47 +02:00
committed by Moritz
parent 59caff6505
commit 8ca5c0f84b
7 changed files with 84 additions and 125 deletions
+6 -11
View File
@@ -1,6 +1,6 @@
import React, { memo } from 'react'; import React, { memo } from 'react';
import { EdgeBezierProps } from '../../types'; import { EdgeBezierProps, Position } from '../../types';
export default memo( export default memo(
({ ({
@@ -8,8 +8,8 @@ export default memo(
sourceY, sourceY,
targetX, targetX,
targetY, targetY,
sourcePosition = 'bottom', sourcePosition = Position.Bottom,
targetPosition = 'top', targetPosition = Position.Top,
style = {}, style = {},
}: EdgeBezierProps) => { }: EdgeBezierProps) => {
const yOffset = Math.abs(targetY - sourceY) / 2; const yOffset = Math.abs(targetY - sourceY) / 2;
@@ -17,18 +17,13 @@ export default memo(
let dAttr = `M${sourceX},${sourceY} C${sourceX},${centerY} ${targetX},${centerY} ${targetX},${targetY}`; let dAttr = `M${sourceX},${sourceY} C${sourceX},${centerY} ${targetX},${centerY} ${targetX},${targetY}`;
if ( const leftAndRight = [Position.Left, Position.Right];
['left', 'right'].includes(sourcePosition) && if (leftAndRight.includes(sourcePosition) && leftAndRight.includes(targetPosition)) {
['left', 'right'].includes(targetPosition)
) {
const xOffset = Math.abs(targetX - sourceX) / 2; const xOffset = Math.abs(targetX - sourceX) / 2;
const centerX = targetX < sourceX ? targetX + xOffset : targetX - xOffset; const centerX = targetX < sourceX ? targetX + xOffset : targetX - xOffset;
dAttr = `M${sourceX},${sourceY} C${centerX},${sourceY} ${centerX},${targetY} ${targetX},${targetY}`; dAttr = `M${sourceX},${sourceY} C${centerX},${sourceY} ${centerX},${targetY} ${targetX},${targetY}`;
} else if ( } else if (leftAndRight.includes(sourcePosition) || leftAndRight.includes(targetPosition)) {
['left', 'right'].includes(sourcePosition) ||
['left', 'right'].includes(targetPosition)
) {
dAttr = `M${sourceX},${sourceY} C${sourceX},${targetY} ${sourceX},${targetY} ${targetX},${targetY}`; dAttr = `M${sourceX},${sourceY} C${sourceX},${targetY} ${sourceX},${targetY} ${targetX},${targetY}`;
} }
+1 -1
View File
@@ -23,7 +23,7 @@ const Handle = memo(
({ ({
onConnect = _ => {}, onConnect = _ => {},
type = 'source', type = 'source',
position = 'top', position = Position.Top,
isValidConnection = () => true, isValidConnection = () => true,
...rest ...rest
}: HandleProps) => { }: HandleProps) => {
+3 -3
View File
@@ -1,7 +1,7 @@
import React, { CSSProperties } from 'react'; import React, { CSSProperties } from 'react';
import Handle from '../../components/Handle'; import Handle from '../../components/Handle';
import { NodeProps } from '../../types'; import { NodeProps, Position } from '../../types';
const nodeStyles: CSSProperties = { const nodeStyles: CSSProperties = {
background: '#ff6060', background: '#ff6060',
@@ -12,8 +12,8 @@ const nodeStyles: CSSProperties = {
export default ({ data, style }: NodeProps) => ( export default ({ data, style }: NodeProps) => (
<div style={{ ...nodeStyles, ...style }}> <div style={{ ...nodeStyles, ...style }}>
<Handle type="target" position="top" /> <Handle type="target" position={Position.Top} />
{data.label} {data.label}
<Handle type="source" position="bottom" /> <Handle type="source" position={Position.Bottom} />
</div> </div>
); );
+2 -2
View File
@@ -1,7 +1,7 @@
import React, { CSSProperties } from 'react'; import React, { CSSProperties } from 'react';
import Handle from '../../components/Handle'; import Handle from '../../components/Handle';
import { NodeProps } from '../../types'; import { NodeProps, Position } from '../../types';
const nodeStyles: CSSProperties = { const nodeStyles: CSSProperties = {
background: '#9999ff', background: '#9999ff',
@@ -13,6 +13,6 @@ const nodeStyles: CSSProperties = {
export default ({ data, style }: NodeProps) => ( export default ({ data, style }: NodeProps) => (
<div style={{ ...nodeStyles, ...style }}> <div style={{ ...nodeStyles, ...style }}>
{data.label} {data.label}
<Handle type="source" position="bottom" /> <Handle type="source" position={Position.Bottom} />
</div> </div>
); );
+2 -2
View File
@@ -1,7 +1,7 @@
import React, { CSSProperties } from 'react'; import React, { CSSProperties } from 'react';
import Handle from '../../components/Handle'; import Handle from '../../components/Handle';
import { NodeProps } from '../../types'; import { NodeProps, Position } from '../../types';
const nodeStyles: CSSProperties = { const nodeStyles: CSSProperties = {
background: '#55dd99', background: '#55dd99',
@@ -12,7 +12,7 @@ const nodeStyles: CSSProperties = {
export default ({ data, style }: NodeProps) => ( export default ({ data, style }: NodeProps) => (
<div style={{ ...nodeStyles, ...style }}> <div style={{ ...nodeStyles, ...style }}>
<Handle type="target" position="top" /> <Handle type="target" position={Position.Top} />
{data.label} {data.label}
</div> </div>
); );
+64 -105
View File
@@ -3,15 +3,7 @@ import React, { memo, SVGAttributes } from 'react';
import { useStoreState } from '../../store/hooks'; import { useStoreState } from '../../store/hooks';
import ConnectionLine from '../../components/ConnectionLine/index'; import ConnectionLine from '../../components/ConnectionLine/index';
import { isEdge } from '../../utils/graph'; import { isEdge } from '../../utils/graph';
import { import { XYPosition, Position, Edge, Node, ElementId, Transform, HandleElement } from '../../types';
XYPosition,
Position,
Edge,
Node,
ElementId,
Transform,
HandleElement,
} from '../../types';
interface EdgeRendererProps { interface EdgeRendererProps {
width: number; width: number;
@@ -38,29 +30,25 @@ interface EdgePositions {
targetY: number; targetY: number;
} }
function getHandlePosition( function getHandlePosition(position: Position, node: Node, handle: any | null = null): XYPosition {
position: Position,
node: Node,
handle: any | null = null
): XYPosition {
if (!handle) { if (!handle) {
switch (position) { switch (position) {
case 'top': case Position.Top:
return { return {
x: node.__rg.width / 2, x: node.__rg.width / 2,
y: 0, y: 0,
}; };
case 'right': case Position.Right:
return { return {
x: node.__rg.width, x: node.__rg.width,
y: node.__rg.height / 2, y: node.__rg.height / 2,
}; };
case 'bottom': case Position.Bottom:
return { return {
x: node.__rg.width / 2, x: node.__rg.width / 2,
y: node.__rg.height, y: node.__rg.height,
}; };
case 'left': case Position.Left:
return { return {
x: 0, x: 0,
y: node.__rg.height / 2, y: node.__rg.height / 2,
@@ -69,22 +57,22 @@ function getHandlePosition(
} }
switch (position) { switch (position) {
case 'top': case Position.Top:
return { return {
x: handle.x + handle.width / 2, x: handle.x + handle.width / 2,
y: handle.y, y: handle.y,
}; };
case 'right': case Position.Right:
return { return {
x: handle.x + handle.width, x: handle.x + handle.width,
y: handle.y + handle.height / 2, y: handle.y + handle.height / 2,
}; };
case 'bottom': case Position.Bottom:
return { return {
x: handle.x + handle.width / 2, x: handle.x + handle.width / 2,
y: handle.y + handle.height, y: handle.y + handle.height,
}; };
case 'left': case Position.Left:
return { return {
x: handle.x, x: handle.x,
y: handle.y + handle.height / 2, y: handle.y + handle.height / 2,
@@ -92,10 +80,7 @@ function getHandlePosition(
} }
} }
function getHandle( function getHandle(bounds: HandleElement[], handleId: ElementId | null): HandleElement | null | undefined {
bounds: HandleElement[],
handleId: ElementId | null
): HandleElement | null | undefined {
let handle = null; let handle = null;
if (!bounds) { if (!bounds) {
@@ -121,19 +106,11 @@ function getEdgePositions(
targetHandle: HandleElement | unknown, targetHandle: HandleElement | unknown,
targetPosition: Position targetPosition: Position
): EdgePositions { ): EdgePositions {
const sourceHandlePos = getHandlePosition( const sourceHandlePos = getHandlePosition(sourcePosition, sourceNode, sourceHandle);
sourcePosition,
sourceNode,
sourceHandle
);
const sourceX = sourceNode.__rg.position.x + sourceHandlePos.x; const sourceX = sourceNode.__rg.position.x + sourceHandlePos.x;
const sourceY = sourceNode.__rg.position.y + sourceHandlePos.y; const sourceY = sourceNode.__rg.position.y + sourceHandlePos.y;
const targetHandlePos = getHandlePosition( const targetHandlePos = getHandlePosition(targetPosition, targetNode, targetHandle);
targetPosition,
targetNode,
targetHandle
);
const targetX = targetNode.__rg.position.x + targetHandlePos.x; const targetX = targetNode.__rg.position.x + targetHandlePos.x;
const targetY = targetNode.__rg.position.y + targetHandlePos.y; const targetY = targetNode.__rg.position.y + targetHandlePos.y;
@@ -145,11 +122,7 @@ function getEdgePositions(
}; };
} }
function renderEdge( function renderEdge(edge: Edge, props: EdgeRendererProps, state: EdgeRendererState) {
edge: Edge,
props: EdgeRendererProps,
state: EdgeRendererState
) {
const edgeType = edge.type || 'default'; const edgeType = edge.type || 'default';
const hasSourceHandleId = edge.source.includes('__'); const hasSourceHandleId = edge.source.includes('__');
@@ -173,16 +146,10 @@ function renderEdge(
} }
const EdgeComponent = props.edgeTypes[edgeType] || props.edgeTypes.default; const EdgeComponent = props.edgeTypes[edgeType] || props.edgeTypes.default;
const sourceHandle = getHandle( const sourceHandle = getHandle(sourceNode.__rg.handleBounds.source, sourceHandleId);
sourceNode.__rg.handleBounds.source, const targetHandle = getHandle(targetNode.__rg.handleBounds.target, targetHandleId);
sourceHandleId const sourcePosition = sourceHandle ? sourceHandle.position : Position.Bottom;
); const targetPosition = targetHandle ? targetHandle.position : Position.Top;
const targetHandle = getHandle(
targetNode.__rg.handleBounds.target,
targetHandleId
);
const sourcePosition = sourceHandle ? sourceHandle.position : 'bottom';
const targetPosition = targetHandle ? targetHandle.position : 'top';
const { sourceX, sourceY, targetX, targetY } = getEdgePositions( const { sourceX, sourceY, targetX, targetY } = getEdgePositions(
sourceNode, sourceNode,
@@ -219,61 +186,53 @@ function renderEdge(
); );
} }
const EdgeRenderer = memo( const EdgeRenderer = memo(({ width, height, connectionLineStyle, connectionLineType, ...rest }: EdgeRendererProps) => {
({ const state: EdgeRendererState = useStoreState(s => ({
width, nodes: s.nodes,
height, edges: s.edges,
connectionLineStyle, transform: s.transform,
connectionLineType, selectedElements: s.selectedElements,
...rest connectionSourceId: s.connectionSourceId,
}: EdgeRendererProps) => { position: s.connectionPosition,
const state: EdgeRendererState = useStoreState(s => ({ }));
nodes: s.nodes, if (!width) {
edges: s.edges, return null;
transform: s.transform,
selectedElements: s.selectedElements,
connectionSourceId: s.connectionSourceId,
position: s.connectionPosition,
}));
if (!width) {
return null;
}
const { transform, edges, nodes, connectionSourceId, position } = state;
const transformStyle = `translate(${transform[0]},${transform[1]}) scale(${transform[2]})`;
return (
<svg width={width} height={height} className="react-flow__edges">
<g transform={transformStyle}>
{edges.map((e: Edge) =>
renderEdge(
e,
{
width,
height,
connectionLineStyle,
connectionLineType,
...rest,
},
state
)
)}
{connectionSourceId && (
<ConnectionLine
nodes={nodes}
connectionSourceId={connectionSourceId}
connectionPositionX={position.x}
connectionPositionY={position.y}
transform={transform}
connectionLineStyle={connectionLineStyle}
connectionLineType={connectionLineType}
/>
)}
</g>
</svg>
);
} }
);
const { transform, edges, nodes, connectionSourceId, position } = state;
const transformStyle = `translate(${transform[0]},${transform[1]}) scale(${transform[2]})`;
return (
<svg width={width} height={height} className="react-flow__edges">
<g transform={transformStyle}>
{edges.map((e: Edge) =>
renderEdge(
e,
{
width,
height,
connectionLineStyle,
connectionLineType,
...rest,
},
state
)
)}
{connectionSourceId && (
<ConnectionLine
nodes={nodes}
connectionSourceId={connectionSourceId}
connectionPositionX={position.x}
connectionPositionY={position.y}
transform={transform}
connectionLineStyle={connectionLineStyle}
connectionLineType={connectionLineType}
/>
)}
</g>
</svg>
);
});
EdgeRenderer.displayName = 'EdgeRenderer'; EdgeRenderer.displayName = 'EdgeRenderer';
+6 -1
View File
@@ -6,7 +6,12 @@ export type Elements = Array<Node | Edge>;
export type Transform = [number, number, number]; export type Transform = [number, number, number];
export type Position = 'left' | 'top' | 'right' | 'bottom'; export enum Position {
Left = 'left',
Top = 'top',
Right = 'right',
Bottom = 'bottom',
}
export type XYPosition = { export type XYPosition = {
x: number; x: number;