refactor: EdgeRenderer (#53)

This commit is contained in:
AndyLnd
2019-10-22 22:37:33 +02:00
committed by Moritz
parent 02005917f8
commit 66711f19fa

View File

@@ -3,7 +3,7 @@ import React, { memo, SVGAttributes } from 'react';
import { useStoreState } from '../../store/hooks';
import ConnectionLine from '../../components/ConnectionLine/index';
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 {
width: number;
@@ -14,15 +14,6 @@ interface EdgeRendererProps {
onElementClick?: () => void;
}
interface EdgeRendererState {
nodes: Node[];
edges: Edge[];
transform: Transform;
selectedElements: any;
connectionSourceId: ElementId | null;
position: XYPosition;
}
interface EdgePositions {
sourceX: number;
sourceY: number;
@@ -122,20 +113,12 @@ function getEdgePositions(
};
}
function renderEdge(edge: Edge, props: EdgeRendererProps, state: EdgeRendererState) {
const edgeType = edge.type || 'default';
function renderEdge(edge: Edge, props: EdgeRendererProps, nodes: Node[], selectedElements: Elements) {
const [sourceId, sourceHandleId] = edge.source.split('__');
const [targetId, targetHandleId] = edge.target.split('__');
const hasSourceHandleId = edge.source.includes('__');
const hasTargetHandleId = edge.target.includes('__');
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);
const sourceNode = nodes.find(n => n.id === sourceId);
const targetNode = nodes.find(n => n.id === targetId);
if (!sourceNode) {
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) {
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 sourceHandle = getHandle(sourceNode.__rg.handleBounds.source, sourceHandleId);
const targetHandle = getHandle(targetNode.__rg.handleBounds.target, targetHandleId);
@@ -159,9 +142,10 @@ function renderEdge(edge: Edge, props: EdgeRendererProps, state: EdgeRendererSta
targetHandle,
targetPosition
);
const selected = state.selectedElements
.filter(isEdge)
.find((elm: Edge) => elm.source === sourceId && elm.target === targetId);
const isSelected = (selectedElements as Edge[]).some(
elm => isEdge(elm) && elm.source === sourceId && elm.target === targetId
);
return (
<EdgeComponent
@@ -169,7 +153,7 @@ function renderEdge(edge: Edge, props: EdgeRendererProps, state: EdgeRendererSta
id={edge.id}
type={edge.type}
onClick={props.onElementClick}
selected={selected}
selected={isSelected}
animated={edge.animated}
style={edge.style}
source={sourceId}
@@ -186,44 +170,35 @@ function renderEdge(edge: Edge, props: EdgeRendererProps, state: EdgeRendererSta
);
}
const EdgeRenderer = memo(({ width, height, connectionLineStyle, connectionLineType, ...rest }: EdgeRendererProps) => {
const state: EdgeRendererState = useStoreState(s => ({
nodes: s.nodes,
edges: s.edges,
transform: s.transform,
selectedElements: s.selectedElements,
connectionSourceId: s.connectionSourceId,
position: s.connectionPosition,
}));
const EdgeRenderer = memo((props: EdgeRendererProps) => {
const {
transform,
edges,
nodes,
connectionSourceId,
connectionPosition: { x, y },
selectedElements,
} = useStoreState(s => s);
const { width, height, connectionLineStyle, connectionLineType } = props;
if (!width) {
return null;
}
const { transform, edges, nodes, connectionSourceId, position } = state;
const transformStyle = `translate(${transform[0]},${transform[1]}) scale(${transform[2]})`;
const [tx, ty, tScale] = transform;
const transformStyle = `translate(${tx},${ty}) scale(${tScale})`;
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
)
)}
{edges.map((e: Edge) => renderEdge(e, props, nodes, selectedElements))}
{connectionSourceId && (
<ConnectionLine
nodes={nodes}
connectionSourceId={connectionSourceId}
connectionPositionX={position.x}
connectionPositionY={position.y}
connectionPositionX={x}
connectionPositionY={y}
transform={transform}
connectionLineStyle={connectionLineStyle}
connectionLineType={connectionLineType}