refactor: EdgeRenderer (#53)

This commit is contained in:
AndyLnd
2019-10-22 22:37:33 +02:00
committed by Moritz
parent 02005917f8
commit 66711f19fa
+29 -54
View File
@@ -3,7 +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 { XYPosition, Position, Edge, Node, ElementId, Transform, HandleElement } from '../../types'; import { XYPosition, Position, Edge, Node, ElementId, HandleElement, Elements } from '../../types';
interface EdgeRendererProps { interface EdgeRendererProps {
width: number; width: number;
@@ -14,15 +14,6 @@ interface EdgeRendererProps {
onElementClick?: () => void; onElementClick?: () => void;
} }
interface EdgeRendererState {
nodes: Node[];
edges: Edge[];
transform: Transform;
selectedElements: any;
connectionSourceId: ElementId | null;
position: XYPosition;
}
interface EdgePositions { interface EdgePositions {
sourceX: number; sourceX: number;
sourceY: number; sourceY: number;
@@ -122,20 +113,12 @@ function getEdgePositions(
}; };
} }
function renderEdge(edge: Edge, props: EdgeRendererProps, state: EdgeRendererState) { function renderEdge(edge: Edge, props: EdgeRendererProps, nodes: Node[], selectedElements: Elements) {
const edgeType = edge.type || 'default'; const [sourceId, sourceHandleId] = edge.source.split('__');
const [targetId, targetHandleId] = edge.target.split('__');
const hasSourceHandleId = edge.source.includes('__'); const sourceNode = nodes.find(n => n.id === sourceId);
const hasTargetHandleId = edge.target.includes('__'); const targetNode = nodes.find(n => n.id === targetId);
const sourceId = hasSourceHandleId ? edge.source.split('__')[0] : edge.source;
const targetId = hasTargetHandleId ? edge.target.split('__')[0] : edge.target;
const sourceHandleId = hasSourceHandleId ? edge.source.split('__')[1] : null;
const targetHandleId = hasTargetHandleId ? edge.target.split('__')[1] : null;
const sourceNode = state.nodes.find(n => n.id === sourceId);
const targetNode = state.nodes.find(n => n.id === targetId);
if (!sourceNode) { if (!sourceNode) {
throw new Error(`couldn't create edge for source id: ${sourceId}`); throw new Error(`couldn't create edge for source id: ${sourceId}`);
@@ -144,7 +127,7 @@ function renderEdge(edge: Edge, props: EdgeRendererProps, state: EdgeRendererSta
if (!targetNode) { if (!targetNode) {
throw new Error(`couldn't create edge for target id: ${targetId}`); throw new Error(`couldn't create edge for target id: ${targetId}`);
} }
const edgeType = edge.type || 'default';
const EdgeComponent = props.edgeTypes[edgeType] || props.edgeTypes.default; const EdgeComponent = props.edgeTypes[edgeType] || props.edgeTypes.default;
const sourceHandle = getHandle(sourceNode.__rg.handleBounds.source, sourceHandleId); const sourceHandle = getHandle(sourceNode.__rg.handleBounds.source, sourceHandleId);
const targetHandle = getHandle(targetNode.__rg.handleBounds.target, targetHandleId); const targetHandle = getHandle(targetNode.__rg.handleBounds.target, targetHandleId);
@@ -159,9 +142,10 @@ function renderEdge(edge: Edge, props: EdgeRendererProps, state: EdgeRendererSta
targetHandle, targetHandle,
targetPosition targetPosition
); );
const selected = state.selectedElements
.filter(isEdge) const isSelected = (selectedElements as Edge[]).some(
.find((elm: Edge) => elm.source === sourceId && elm.target === targetId); elm => isEdge(elm) && elm.source === sourceId && elm.target === targetId
);
return ( return (
<EdgeComponent <EdgeComponent
@@ -169,7 +153,7 @@ function renderEdge(edge: Edge, props: EdgeRendererProps, state: EdgeRendererSta
id={edge.id} id={edge.id}
type={edge.type} type={edge.type}
onClick={props.onElementClick} onClick={props.onElementClick}
selected={selected} selected={isSelected}
animated={edge.animated} animated={edge.animated}
style={edge.style} style={edge.style}
source={sourceId} source={sourceId}
@@ -186,44 +170,35 @@ function renderEdge(edge: Edge, props: EdgeRendererProps, state: EdgeRendererSta
); );
} }
const EdgeRenderer = memo(({ width, height, connectionLineStyle, connectionLineType, ...rest }: EdgeRendererProps) => { const EdgeRenderer = memo((props: EdgeRendererProps) => {
const state: EdgeRendererState = useStoreState(s => ({ const {
nodes: s.nodes, transform,
edges: s.edges, edges,
transform: s.transform, nodes,
selectedElements: s.selectedElements, connectionSourceId,
connectionSourceId: s.connectionSourceId, connectionPosition: { x, y },
position: s.connectionPosition, selectedElements,
})); } = useStoreState(s => s);
const { width, height, connectionLineStyle, connectionLineType } = props;
if (!width) { if (!width) {
return null; return null;
} }
const { transform, edges, nodes, connectionSourceId, position } = state; const [tx, ty, tScale] = transform;
const transformStyle = `translate(${transform[0]},${transform[1]}) scale(${transform[2]})`; const transformStyle = `translate(${tx},${ty}) scale(${tScale})`;
return ( return (
<svg width={width} height={height} className="react-flow__edges"> <svg width={width} height={height} className="react-flow__edges">
<g transform={transformStyle}> <g transform={transformStyle}>
{edges.map((e: Edge) => {edges.map((e: Edge) => renderEdge(e, props, nodes, selectedElements))}
renderEdge(
e,
{
width,
height,
connectionLineStyle,
connectionLineType,
...rest,
},
state
)
)}
{connectionSourceId && ( {connectionSourceId && (
<ConnectionLine <ConnectionLine
nodes={nodes} nodes={nodes}
connectionSourceId={connectionSourceId} connectionSourceId={connectionSourceId}
connectionPositionX={position.x} connectionPositionX={x}
connectionPositionY={position.y} connectionPositionY={y}
transform={transform} transform={transform}
connectionLineStyle={connectionLineStyle} connectionLineStyle={connectionLineStyle}
connectionLineType={connectionLineType} connectionLineType={connectionLineType}