Merge branch 'v10' into refactor/nodes-edges-state
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import React, { memo } from 'react';
|
||||
|
||||
import EdgeText from './EdgeText';
|
||||
import { getMarkerEnd, getCenter } from './utils';
|
||||
import { getCenter } from './utils';
|
||||
import { EdgeProps, Position } from '../../types';
|
||||
|
||||
interface GetBezierPathParams {
|
||||
@@ -36,9 +36,9 @@ export function getBezierPath({
|
||||
if (leftAndRight.includes(sourcePosition) && leftAndRight.includes(targetPosition)) {
|
||||
path = `M${sourceX},${sourceY} C${cX},${sourceY} ${cX},${targetY} ${targetX},${targetY}`;
|
||||
} else if (leftAndRight.includes(targetPosition)) {
|
||||
path = `M${sourceX},${sourceY} C${sourceX},${targetY} ${sourceX},${targetY} ${targetX},${targetY}`;
|
||||
path = `M${sourceX},${sourceY} Q${sourceX},${targetY} ${targetX},${targetY}`;
|
||||
} else if (leftAndRight.includes(sourcePosition)) {
|
||||
path = `M${sourceX},${sourceY} C${targetX},${sourceY} ${targetX},${sourceY} ${targetX},${targetY}`;
|
||||
path = `M${sourceX},${sourceY} Q${targetX},${sourceY} ${targetX},${targetY}`;
|
||||
}
|
||||
|
||||
return path;
|
||||
@@ -59,8 +59,8 @@ export default memo(
|
||||
labelBgPadding,
|
||||
labelBgBorderRadius,
|
||||
style,
|
||||
arrowHeadType,
|
||||
markerEndId,
|
||||
markerEnd,
|
||||
markerStart,
|
||||
}: EdgeProps) => {
|
||||
const [centerX, centerY] = getCenter({ sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition });
|
||||
const path = getBezierPath({
|
||||
@@ -85,11 +85,15 @@ export default memo(
|
||||
/>
|
||||
) : null;
|
||||
|
||||
const markerEnd = getMarkerEnd(arrowHeadType, markerEndId);
|
||||
|
||||
return (
|
||||
<>
|
||||
<path style={style} d={path} className="react-flow__edge-path" markerEnd={markerEnd} />
|
||||
<path
|
||||
style={style}
|
||||
d={path}
|
||||
className="react-flow__edge-path"
|
||||
markerEnd={markerEnd}
|
||||
markerStart={markerStart}
|
||||
/>
|
||||
{text}
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { memo } from 'react';
|
||||
|
||||
import EdgeText from './EdgeText';
|
||||
import { getMarkerEnd, getCenter } from './utils';
|
||||
import { getCenter } from './utils';
|
||||
import { EdgeSmoothStepProps, Position } from '../../types';
|
||||
|
||||
// These are some helper methods for drawing the round corners
|
||||
@@ -73,8 +73,8 @@ export function getSmoothStepPath({
|
||||
sourceY <= targetY ? rightTopCorner(cX, sourceY, cornerSize) : rightBottomCorner(cX, sourceY, cornerSize);
|
||||
secondCornerPath =
|
||||
sourceY <= targetY ? bottomLeftCorner(cX, targetY, cornerSize) : topLeftCorner(cX, targetY, cornerSize);
|
||||
} else if (sourcePosition === Position.Right && targetPosition === Position.Left){
|
||||
// and sourceX > targetX
|
||||
} else if (sourcePosition === Position.Right && targetPosition === Position.Left) {
|
||||
// and sourceX > targetX
|
||||
firstCornerPath =
|
||||
sourceY <= targetY ? leftTopCorner(cX, sourceY, cornerSize) : leftBottomCorner(cX, sourceY, cornerSize);
|
||||
secondCornerPath =
|
||||
@@ -126,8 +126,8 @@ export default memo(
|
||||
style,
|
||||
sourcePosition = Position.Bottom,
|
||||
targetPosition = Position.Top,
|
||||
arrowHeadType,
|
||||
markerEndId,
|
||||
markerEnd,
|
||||
markerStart,
|
||||
borderRadius = 5,
|
||||
}: EdgeSmoothStepProps) => {
|
||||
const [centerX, centerY] = getCenter({ sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition });
|
||||
@@ -142,8 +142,6 @@ export default memo(
|
||||
borderRadius,
|
||||
});
|
||||
|
||||
const markerEnd = getMarkerEnd(arrowHeadType, markerEndId);
|
||||
|
||||
const text = label ? (
|
||||
<EdgeText
|
||||
x={centerX}
|
||||
@@ -159,7 +157,13 @@ export default memo(
|
||||
|
||||
return (
|
||||
<>
|
||||
<path style={style} className="react-flow__edge-path" d={path} markerEnd={markerEnd} />
|
||||
<path
|
||||
style={style}
|
||||
className="react-flow__edge-path"
|
||||
d={path}
|
||||
markerEnd={markerEnd}
|
||||
markerStart={markerStart}
|
||||
/>
|
||||
{text}
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import React, { memo } from 'react';
|
||||
|
||||
import EdgeText from './EdgeText';
|
||||
import { getMarkerEnd } from './utils';
|
||||
import { EdgeProps } from '../../types';
|
||||
|
||||
export default memo(
|
||||
@@ -17,15 +16,14 @@ export default memo(
|
||||
labelBgPadding,
|
||||
labelBgBorderRadius,
|
||||
style,
|
||||
arrowHeadType,
|
||||
markerEndId,
|
||||
markerEnd,
|
||||
markerStart,
|
||||
}: EdgeProps) => {
|
||||
const yOffset = Math.abs(targetY - sourceY) / 2;
|
||||
const centerY = targetY < sourceY ? targetY + yOffset : targetY - yOffset;
|
||||
|
||||
const xOffset = Math.abs(targetX - sourceX) / 2;
|
||||
const centerX = targetX < sourceX ? targetX + xOffset : targetX - xOffset;
|
||||
const markerEnd = getMarkerEnd(arrowHeadType, markerEndId);
|
||||
|
||||
const text = label ? (
|
||||
<EdgeText
|
||||
@@ -47,6 +45,7 @@ export default memo(
|
||||
className="react-flow__edge-path"
|
||||
d={`M ${sourceX},${sourceY}L ${targetX},${targetY}`}
|
||||
markerEnd={markerEnd}
|
||||
markerStart={markerStart}
|
||||
/>
|
||||
{text}
|
||||
</>
|
||||
|
||||
@@ -6,6 +6,7 @@ import { useStore, useStoreApi } from '../../store';
|
||||
import { Edge, EdgeProps, WrapEdgeProps, ReactFlowState } from '../../types';
|
||||
import { onMouseDown } from '../../components/Handle/handler';
|
||||
import { EdgeAnchor } from './EdgeAnchor';
|
||||
import { getMarkerId } from '../../utils/graph';
|
||||
|
||||
const selector = (s: ReactFlowState) => ({
|
||||
addSelectedElements: s.addSelectedElements,
|
||||
@@ -32,7 +33,6 @@ export default (EdgeComponent: ComponentType<EdgeProps>) => {
|
||||
labelBgPadding,
|
||||
labelBgBorderRadius,
|
||||
style,
|
||||
arrowHeadType,
|
||||
source,
|
||||
target,
|
||||
sourceX,
|
||||
@@ -42,7 +42,6 @@ export default (EdgeComponent: ComponentType<EdgeProps>) => {
|
||||
sourcePosition,
|
||||
targetPosition,
|
||||
elementsSelectable,
|
||||
markerEndId,
|
||||
isHidden,
|
||||
sourceHandleId,
|
||||
targetHandleId,
|
||||
@@ -55,6 +54,8 @@ export default (EdgeComponent: ComponentType<EdgeProps>) => {
|
||||
edgeUpdaterRadius,
|
||||
onEdgeUpdateStart,
|
||||
onEdgeUpdateEnd,
|
||||
markerEnd,
|
||||
markerStart,
|
||||
}: WrapEdgeProps): JSX.Element | null => {
|
||||
const store = useStoreApi();
|
||||
const { addSelectedElements, setConnectionNodeId, unsetNodesSelection, setPosition, connectionMode } = useStore(
|
||||
@@ -200,6 +201,8 @@ export default (EdgeComponent: ComponentType<EdgeProps>) => {
|
||||
|
||||
const onEdgeUpdaterMouseEnter = useCallback(() => setUpdating(true), [setUpdating]);
|
||||
const onEdgeUpdaterMouseOut = useCallback(() => setUpdating(false), [setUpdating]);
|
||||
const markerStartUrl = useMemo(() => `url(#${getMarkerId(markerStart)})`, [markerStart]);
|
||||
const markerEndUrl = useMemo(() => `url(#${getMarkerId(markerEnd)})`, [markerEnd]);
|
||||
|
||||
if (isHidden) {
|
||||
return null;
|
||||
@@ -229,16 +232,16 @@ export default (EdgeComponent: ComponentType<EdgeProps>) => {
|
||||
labelBgBorderRadius={labelBgBorderRadius}
|
||||
data={data}
|
||||
style={style}
|
||||
arrowHeadType={arrowHeadType}
|
||||
sourceX={sourceX}
|
||||
sourceY={sourceY}
|
||||
targetX={targetX}
|
||||
targetY={targetY}
|
||||
sourcePosition={sourcePosition}
|
||||
targetPosition={targetPosition}
|
||||
markerEndId={markerEndId}
|
||||
sourceHandleId={sourceHandleId}
|
||||
targetHandleId={targetHandleId}
|
||||
markerStart={markerStartUrl}
|
||||
markerEnd={markerEndUrl}
|
||||
/>
|
||||
{handleEdgeUpdate && (
|
||||
<g
|
||||
|
||||
@@ -1,52 +1,113 @@
|
||||
import React, { ReactNode } from 'react';
|
||||
import React, { useMemo } from 'react';
|
||||
|
||||
interface MarkerProps {
|
||||
import { useStore } from '../../store';
|
||||
import { EdgeMarker, ArrowHeadType, ReactFlowState } from '../../types';
|
||||
import { getMarkerId } from '../../utils/graph';
|
||||
interface MarkerProps extends EdgeMarker {
|
||||
id: string;
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
const Marker = ({ id, children }: MarkerProps) => (
|
||||
<marker
|
||||
className="react-flow__arrowhead"
|
||||
id={id}
|
||||
markerWidth="12.5"
|
||||
markerHeight="12.5"
|
||||
viewBox="-10 -10 20 20"
|
||||
orient="auto"
|
||||
refX="0"
|
||||
refY="0"
|
||||
>
|
||||
{children}
|
||||
</marker>
|
||||
);
|
||||
|
||||
interface MarkerDefinitionsProps {
|
||||
color: string;
|
||||
defaultColor: string;
|
||||
}
|
||||
|
||||
const MarkerDefinitions = ({ color }: MarkerDefinitionsProps) => {
|
||||
type SymbolProps = Omit<MarkerProps, 'id' | 'type'>;
|
||||
|
||||
const ArrowSymbol = ({ color = 'none', strokeWidth = 1 }: SymbolProps) => {
|
||||
return (
|
||||
<polyline
|
||||
stroke={color}
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={strokeWidth}
|
||||
fill="none"
|
||||
points="-5,-4 0,0 -5,4"
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const ArrowClosedSymbol = ({ color = 'none', strokeWidth = 1 }: SymbolProps) => {
|
||||
return (
|
||||
<polyline
|
||||
stroke={color}
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={strokeWidth}
|
||||
fill={color}
|
||||
points="-5,-4 0,0 -5,4 -5,-4"
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const markerSymbols = {
|
||||
[ArrowHeadType.Arrow]: ArrowSymbol,
|
||||
[ArrowHeadType.ArrowClosed]: ArrowClosedSymbol,
|
||||
};
|
||||
|
||||
const Marker = ({
|
||||
id,
|
||||
type,
|
||||
color,
|
||||
width = 12.5,
|
||||
height = 12.5,
|
||||
units = 'strokeWidth',
|
||||
strokeWidth,
|
||||
orient = 'auto',
|
||||
}: MarkerProps) => {
|
||||
const Symbol = markerSymbols[type];
|
||||
|
||||
return (
|
||||
<marker
|
||||
className="react-flow__arrowhead"
|
||||
id={id}
|
||||
markerUnits={units}
|
||||
markerWidth={`${width}`}
|
||||
markerHeight={`${height}`}
|
||||
viewBox="-10 -10 20 20"
|
||||
orient={orient}
|
||||
refX="0"
|
||||
refY="0"
|
||||
>
|
||||
<Symbol color={color} strokeWidth={strokeWidth} />
|
||||
</marker>
|
||||
);
|
||||
};
|
||||
|
||||
const edgesSelector = (s: ReactFlowState) => s.edges;
|
||||
|
||||
const MarkerDefinitions = ({ defaultColor }: MarkerDefinitionsProps) => {
|
||||
const edges = useStore(edgesSelector);
|
||||
const markers = useMemo(() => {
|
||||
const ids: string[] = [];
|
||||
|
||||
return edges.reduce<MarkerProps[]>((markers, edge) => {
|
||||
[edge.markerStart, edge.markerEnd].forEach((marker) => {
|
||||
if (marker && typeof marker === 'object') {
|
||||
const markerId = getMarkerId(marker);
|
||||
if (!ids.includes(markerId)) {
|
||||
markers.push({ id: markerId, color: marker.color || defaultColor, ...marker });
|
||||
ids.push(markerId);
|
||||
}
|
||||
}
|
||||
});
|
||||
return markers.sort((a, b) => a.id.localeCompare(b.id));
|
||||
}, []);
|
||||
}, [edges, defaultColor]);
|
||||
|
||||
return (
|
||||
<defs>
|
||||
<Marker id="react-flow__arrowclosed">
|
||||
<polyline
|
||||
stroke={color}
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="1"
|
||||
fill={color}
|
||||
points="-5,-4 0,0 -5,4 -5,-4"
|
||||
{markers.map((marker: MarkerProps) => (
|
||||
<Marker
|
||||
id={marker.id}
|
||||
key={marker.id}
|
||||
type={marker.type}
|
||||
color={marker.color}
|
||||
width={marker.width}
|
||||
height={marker.height}
|
||||
units={marker.units}
|
||||
strokeWidth={marker.strokeWidth}
|
||||
orient={marker.orient}
|
||||
/>
|
||||
</Marker>
|
||||
<Marker id="react-flow__arrow">
|
||||
<polyline
|
||||
stroke={color}
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="1.5"
|
||||
fill="none"
|
||||
points="-5,-4 0,0 -5,4"
|
||||
/>
|
||||
</Marker>
|
||||
))}
|
||||
</defs>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -24,8 +24,7 @@ interface EdgeRendererProps {
|
||||
connectionLineComponent?: ConnectionLineComponent;
|
||||
onEdgeClick?: (event: React.MouseEvent, node: Edge) => void;
|
||||
onEdgeDoubleClick?: (event: React.MouseEvent, edge: Edge) => void;
|
||||
arrowHeadColor: string;
|
||||
markerEndId?: string;
|
||||
defaultMarkerColor: string;
|
||||
onlyRenderVisibleElements: boolean;
|
||||
onEdgeUpdate?: OnEdgeUpdateFunc;
|
||||
onEdgeContextMenu?: (event: React.MouseEvent, edge: Edge) => void;
|
||||
@@ -176,11 +175,12 @@ const Edge = memo(
|
||||
labelBgPadding={edge.labelBgPadding}
|
||||
labelBgBorderRadius={edge.labelBgBorderRadius}
|
||||
style={edge.style}
|
||||
arrowHeadType={edge.arrowHeadType}
|
||||
source={edge.source}
|
||||
target={edge.target}
|
||||
sourceHandleId={sourceHandleId}
|
||||
targetHandleId={targetHandleId}
|
||||
markerEnd={edge.markerEnd}
|
||||
markerStart={edge.markerStart}
|
||||
sourceX={sourceX}
|
||||
sourceY={sourceY}
|
||||
targetX={targetX}
|
||||
@@ -271,12 +271,12 @@ const EdgeRenderer = (props: EdgeRendererProps) => {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { connectionLineType, arrowHeadColor, connectionLineStyle, connectionLineComponent } = props;
|
||||
const { connectionLineType, defaultMarkerColor, connectionLineStyle, connectionLineComponent } = props;
|
||||
const renderConnectionLine = connectionNodeId && connectionHandleType;
|
||||
|
||||
return (
|
||||
<svg width={width} height={height} className="react-flow__edges">
|
||||
<MarkerDefinitions color={arrowHeadColor} />
|
||||
<MarkerDefinitions defaultColor={defaultMarkerColor} />
|
||||
<g transform={`translate(${transform[0]},${transform[1]}) scale(${transform[2]})`}>
|
||||
{edges.map((edge: Edge) => {
|
||||
const { sourceNode, targetNode } = getSourceTargetNodes(edge, nodes);
|
||||
@@ -295,7 +295,6 @@ const EdgeRenderer = (props: EdgeRendererProps) => {
|
||||
targetNodeY={targetNode?.position.y}
|
||||
targetNodeHandleBounds={targetNode?.handleBounds}
|
||||
elementsSelectable={elementsSelectable}
|
||||
markerEndId={props.markerEndId}
|
||||
onEdgeContextMenu={props.onEdgeContextMenu}
|
||||
onEdgeMouseEnter={props.onEdgeMouseEnter}
|
||||
onEdgeMouseMove={props.onEdgeMouseMove}
|
||||
|
||||
@@ -21,6 +21,7 @@ interface FlowRendererProps
|
||||
| 'arrowHeadColor'
|
||||
| 'onlyRenderVisibleElements'
|
||||
| 'selectNodesOnDrag'
|
||||
| 'defaultMarkerColor'
|
||||
> {
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ export interface GraphViewProps extends Omit<ReactFlowProps, 'onSelectionChange'
|
||||
onlyRenderVisibleElements: boolean;
|
||||
defaultZoom: number;
|
||||
defaultPosition: [number, number];
|
||||
arrowHeadColor: string;
|
||||
defaultMarkerColor: string;
|
||||
selectNodesOnDrag: boolean;
|
||||
}
|
||||
|
||||
@@ -60,8 +60,7 @@ const GraphView = ({
|
||||
defaultZoom,
|
||||
defaultPosition,
|
||||
preventScrolling,
|
||||
arrowHeadColor,
|
||||
markerEndId,
|
||||
defaultMarkerColor,
|
||||
zoomOnScroll,
|
||||
zoomOnPinch,
|
||||
panOnScroll,
|
||||
@@ -154,8 +153,6 @@ const GraphView = ({
|
||||
connectionLineType={connectionLineType}
|
||||
connectionLineStyle={connectionLineStyle}
|
||||
connectionLineComponent={connectionLineComponent}
|
||||
arrowHeadColor={arrowHeadColor}
|
||||
markerEndId={markerEndId}
|
||||
onEdgeUpdate={onEdgeUpdate}
|
||||
onlyRenderVisibleElements={onlyRenderVisibleElements}
|
||||
onEdgeContextMenu={onEdgeContextMenu}
|
||||
@@ -165,6 +162,7 @@ const GraphView = ({
|
||||
onEdgeUpdateStart={onEdgeUpdateStart}
|
||||
onEdgeUpdateEnd={onEdgeUpdateEnd}
|
||||
edgeUpdaterRadius={edgeUpdaterRadius}
|
||||
defaultMarkerColor={defaultMarkerColor}
|
||||
/>
|
||||
</FlowRenderer>
|
||||
);
|
||||
|
||||
@@ -114,8 +114,7 @@ export interface ReactFlowProps extends Omit<HTMLAttributes<HTMLDivElement>, 'on
|
||||
translateExtent?: TranslateExtent;
|
||||
preventScrolling?: boolean;
|
||||
nodeExtent?: NodeExtent;
|
||||
arrowHeadColor?: string;
|
||||
markerEndId?: string;
|
||||
defaultMarkerColor?: string;
|
||||
zoomOnScroll?: boolean;
|
||||
zoomOnPinch?: boolean;
|
||||
panOnScroll?: boolean;
|
||||
@@ -191,8 +190,7 @@ const ReactFlow = forwardRef<ReactFlowRefType, ReactFlowProps>(
|
||||
translateExtent,
|
||||
preventScrolling = true,
|
||||
nodeExtent,
|
||||
arrowHeadColor = '#b1b1b7',
|
||||
markerEndId,
|
||||
defaultMarkerColor = '#b1b1b7',
|
||||
zoomOnScroll = true,
|
||||
zoomOnPinch = true,
|
||||
panOnScroll = false,
|
||||
@@ -255,8 +253,6 @@ const ReactFlow = forwardRef<ReactFlowRefType, ReactFlowProps>(
|
||||
defaultZoom={defaultZoom}
|
||||
defaultPosition={defaultPosition}
|
||||
preventScrolling={preventScrolling}
|
||||
arrowHeadColor={arrowHeadColor}
|
||||
markerEndId={markerEndId}
|
||||
zoomOnScroll={zoomOnScroll}
|
||||
zoomOnPinch={zoomOnPinch}
|
||||
zoomOnDoubleClick={zoomOnDoubleClick}
|
||||
@@ -280,6 +276,7 @@ const ReactFlow = forwardRef<ReactFlowRefType, ReactFlowProps>(
|
||||
onEdgeUpdateStart={onEdgeUpdateStart}
|
||||
onEdgeUpdateEnd={onEdgeUpdateEnd}
|
||||
edgeUpdaterRadius={edgeUpdaterRadius}
|
||||
defaultMarkerColor={defaultMarkerColor}
|
||||
/>
|
||||
<StoreUpdater
|
||||
nodes={nodes}
|
||||
|
||||
+18
-5
@@ -93,6 +93,18 @@ export enum ArrowHeadType {
|
||||
ArrowClosed = 'arrowclosed',
|
||||
}
|
||||
|
||||
export interface EdgeMarker {
|
||||
type: ArrowHeadType;
|
||||
color?: string;
|
||||
width?: number;
|
||||
height?: number;
|
||||
units?: string;
|
||||
orient?: string;
|
||||
strokeWidth?: number;
|
||||
}
|
||||
|
||||
export type EdgeMarkerType = string | EdgeMarker;
|
||||
|
||||
export interface Edge<T = any> {
|
||||
id: ElementId;
|
||||
type?: string;
|
||||
@@ -108,13 +120,14 @@ export interface Edge<T = any> {
|
||||
labelBgBorderRadius?: number;
|
||||
style?: CSSProperties;
|
||||
animated?: boolean;
|
||||
arrowHeadType?: ArrowHeadType;
|
||||
isHidden?: boolean;
|
||||
data?: T;
|
||||
className?: string;
|
||||
sourceNode?: Node;
|
||||
targetNode?: Node;
|
||||
isSelected?: boolean;
|
||||
markerStart?: EdgeMarkerType;
|
||||
markerEnd?: EdgeMarkerType;
|
||||
}
|
||||
|
||||
export enum BackgroundVariant {
|
||||
@@ -150,7 +163,6 @@ export interface WrapEdgeProps<T = any> {
|
||||
labelBgPadding?: [number, number];
|
||||
labelBgBorderRadius?: number;
|
||||
style?: CSSProperties;
|
||||
arrowHeadType?: ArrowHeadType;
|
||||
source: ElementId;
|
||||
target: ElementId;
|
||||
sourceHandleId: ElementId | null;
|
||||
@@ -162,7 +174,6 @@ export interface WrapEdgeProps<T = any> {
|
||||
sourcePosition: Position;
|
||||
targetPosition: Position;
|
||||
elementsSelectable?: boolean;
|
||||
markerEndId?: string;
|
||||
isHidden?: boolean;
|
||||
handleEdgeUpdate: boolean;
|
||||
onConnectEdge: OnConnectFunc;
|
||||
@@ -173,6 +184,8 @@ export interface WrapEdgeProps<T = any> {
|
||||
edgeUpdaterRadius?: number;
|
||||
onEdgeUpdateStart?: (event: React.MouseEvent, edge: Edge) => void;
|
||||
onEdgeUpdateEnd?: (event: MouseEvent, edge: Edge) => void;
|
||||
markerStart?: EdgeMarkerType;
|
||||
markerEnd?: EdgeMarkerType;
|
||||
}
|
||||
|
||||
export interface EdgeProps<T = any> {
|
||||
@@ -194,11 +207,11 @@ export interface EdgeProps<T = any> {
|
||||
labelBgPadding?: [number, number];
|
||||
labelBgBorderRadius?: number;
|
||||
style?: CSSProperties;
|
||||
arrowHeadType?: ArrowHeadType;
|
||||
markerEndId?: string;
|
||||
data?: T;
|
||||
sourceHandleId?: ElementId | null;
|
||||
targetHandleId?: ElementId | null;
|
||||
markerStart?: string;
|
||||
markerEnd?: string;
|
||||
}
|
||||
export interface EdgeSmoothStepProps<T = any> extends EdgeProps<T> {
|
||||
borderRadius?: number;
|
||||
|
||||
+24
-7
@@ -16,6 +16,7 @@ import {
|
||||
EdgeChange,
|
||||
NodeChange,
|
||||
ReactFlowState,
|
||||
EdgeMarkerType,
|
||||
} from '../types';
|
||||
|
||||
export const isEdge = (element: Node | Connection | Edge): element is Edge =>
|
||||
@@ -45,13 +46,29 @@ export const getIncomers = (node: Node, nodes: Node[], edges: Edge[]): Node[] =>
|
||||
const getEdgeId = ({ source, sourceHandle, target, targetHandle }: Connection): ElementId =>
|
||||
`reactflow__edge-${source}${sourceHandle}-${target}${targetHandle}`;
|
||||
|
||||
const connectionExists = (edge: Edge, edges: Edge[]) => {
|
||||
return edges.some(
|
||||
(e) =>
|
||||
edge.source === e.source &&
|
||||
edge.target === e.target &&
|
||||
(edge.sourceHandle === e.sourceHandle || (!edge.sourceHandle && !e.sourceHandle)) &&
|
||||
(edge.targetHandle === e.targetHandle || (!edge.targetHandle && !e.targetHandle))
|
||||
export const getMarkerId = (marker: EdgeMarkerType | undefined): string => {
|
||||
if (typeof marker === 'undefined') {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (typeof marker === 'string') {
|
||||
return marker;
|
||||
}
|
||||
|
||||
return Object.keys(marker)
|
||||
.sort()
|
||||
.map((key: string) => `${key}=${(marker as any)[key]}`)
|
||||
.join('&');
|
||||
};
|
||||
|
||||
const connectionExists = (edge: Edge, elements: Elements) => {
|
||||
return elements.some(
|
||||
(el) =>
|
||||
isEdge(el) &&
|
||||
el.source === edge.source &&
|
||||
el.target === edge.target &&
|
||||
(el.sourceHandle === edge.sourceHandle || (!el.sourceHandle && !edge.sourceHandle)) &&
|
||||
(el.targetHandle === edge.targetHandle || (!el.targetHandle && !edge.targetHandle))
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user