@@ -91,10 +91,12 @@ const BasicFlow = () => <ReactFlow elements={elements} />;
|
|||||||
- `nodesDraggable`: default: `true`
|
- `nodesDraggable`: default: `true`
|
||||||
- `nodesConnectable`: default: `true`
|
- `nodesConnectable`: default: `true`
|
||||||
- `elementsSelectable`: default: `true`
|
- `elementsSelectable`: default: `true`
|
||||||
|
- `zoomOnScroll`: default: `true`
|
||||||
- `selectNodesOnDrag`: default: `true`
|
- `selectNodesOnDrag`: default: `true`
|
||||||
- `minZoom`: default: `0.5`
|
- `minZoom`: default: `0.5`
|
||||||
- `maxZoom`: default: `2`
|
- `maxZoom`: default: `2`
|
||||||
- `defaultZoom`: default: `1`
|
- `defaultZoom`: default: `1`
|
||||||
|
- `arrowHeadColor`: default: `#bbb`
|
||||||
|
|
||||||
## React Flow Instance
|
## React Flow Instance
|
||||||
|
|
||||||
@@ -247,6 +249,8 @@ If you wanted to display this edge, you would need a node with id = 1 (source no
|
|||||||
- `labelStyle`: css properties for the text
|
- `labelStyle`: css properties for the text
|
||||||
- `labelShowBg`: boolean - default: `true`
|
- `labelShowBg`: boolean - default: `true`
|
||||||
- `labelBgStyle`: css properties for the text background
|
- `labelBgStyle`: css properties for the text background
|
||||||
|
- `arrowHeadType`: 'arrow' or 'arrowclosed' - defines the arrowhead of the edge
|
||||||
|
- `markerEndId`: custom marker end url - if this is used `arrowHeadType` gets ignored
|
||||||
|
|
||||||
You can find an example with lots of different edges in the [edges example](https://react-flow.netlify.app/edges).
|
You can find an example with lots of different edges in the [edges example](https://react-flow.netlify.app/edges).
|
||||||
|
|
||||||
|
|||||||
@@ -25,13 +25,21 @@ const initialElements = [
|
|||||||
{ id: 'e3-4', source: '3', target: '4', type: 'straight', label: 'straight edge' },
|
{ id: 'e3-4', source: '3', target: '4', type: 'straight', label: 'straight edge' },
|
||||||
{ id: 'e3-3a', source: '3', target: '3a', type: 'straight', label: 'label only edge', style: { stroke: 'none' } },
|
{ id: 'e3-3a', source: '3', target: '3a', type: 'straight', label: 'label only edge', style: { stroke: 'none' } },
|
||||||
{ id: 'e3-5', source: '4', target: '5', animated: true, label: 'animated styled edge', style: { stroke: 'red' } },
|
{ id: 'e3-5', source: '4', target: '5', animated: true, label: 'animated styled edge', style: { stroke: 'red' } },
|
||||||
{ id: 'e5-6', source: '5', target: '6', label: 'styled label', labelStyle: { fill: 'red', fontWeight: 700 } },
|
{
|
||||||
|
id: 'e5-6',
|
||||||
|
source: '5',
|
||||||
|
target: '6',
|
||||||
|
label: 'styled label',
|
||||||
|
labelStyle: { fill: 'red', fontWeight: 700 },
|
||||||
|
arrowHeadType: 'arrow',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: 'e5-7',
|
id: 'e5-7',
|
||||||
source: '5',
|
source: '5',
|
||||||
target: '7',
|
target: '7',
|
||||||
label: 'label with styled bg',
|
label: 'label with styled bg',
|
||||||
labelBgStyle: { fill: '#eee', fillOpacity: 0.7 },
|
labelBgStyle: { fill: '#eee', fillOpacity: 0.7 },
|
||||||
|
arrowHeadType: 'arrowclosed',
|
||||||
},
|
},
|
||||||
{ id: 'e5-8', source: '5', target: '8', type: 'custom', label: 'custom edge' },
|
{ id: 'e5-8', source: '5', target: '8', type: 'custom', label: 'custom edge' },
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ const InteractionFlow = () => {
|
|||||||
const [isSelectable, setIsSelectable] = useState(false);
|
const [isSelectable, setIsSelectable] = useState(false);
|
||||||
const [isDraggable, setIsDraggable] = useState(false);
|
const [isDraggable, setIsDraggable] = useState(false);
|
||||||
const [isConnectable, setIsConnectable] = useState(false);
|
const [isConnectable, setIsConnectable] = useState(false);
|
||||||
|
const [zoomOnScroll, setZoomOnScroll] = useState(true);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ReactFlow
|
<ReactFlow
|
||||||
@@ -25,6 +26,7 @@ const InteractionFlow = () => {
|
|||||||
elementsSelectable={isSelectable}
|
elementsSelectable={isSelectable}
|
||||||
nodesConnectable={isConnectable}
|
nodesConnectable={isConnectable}
|
||||||
nodesDraggable={isDraggable}
|
nodesDraggable={isDraggable}
|
||||||
|
zoomOnScroll={zoomOnScroll}
|
||||||
onConnect={onConnect}
|
onConnect={onConnect}
|
||||||
>
|
>
|
||||||
<MiniMap />
|
<MiniMap />
|
||||||
@@ -67,6 +69,18 @@ const InteractionFlow = () => {
|
|||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<label htmlFor="zoomonscroll">
|
||||||
|
zoom on scroll
|
||||||
|
<input
|
||||||
|
id="zoomonscroll"
|
||||||
|
type="checkbox"
|
||||||
|
checked={zoomOnScroll}
|
||||||
|
onChange={(evt) => setZoomOnScroll(evt.target.checked)}
|
||||||
|
className="react-flow__zoomonscroll"
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ReactFlow>
|
</ReactFlow>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ const initialElements = [
|
|||||||
</>
|
</>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
position: { x: 250, y: 300 },
|
position: { x: 250, y: 325 },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: '6',
|
id: '6',
|
||||||
@@ -88,7 +88,7 @@ const initialElements = [
|
|||||||
{ id: 'e1-2', source: '1', target: '2', label: 'this is an edge label' },
|
{ id: 'e1-2', source: '1', target: '2', label: 'this is an edge label' },
|
||||||
{ id: 'e1-3', source: '1', target: '3' },
|
{ id: 'e1-3', source: '1', target: '3' },
|
||||||
{ id: 'e3-4', source: '3', target: '4', animated: true, label: 'animated edge' },
|
{ id: 'e3-4', source: '3', target: '4', animated: true, label: 'animated edge' },
|
||||||
{ id: 'e4-5', source: '4', target: '5' },
|
{ id: 'e4-5', source: '4', target: '5', arrowHeadType: 'arrowclosed', label: 'edge with arrow head' },
|
||||||
{ id: 'e5-6', source: '5', target: '6', type: 'smoothstep', label: 'smooth step edge' },
|
{ id: 'e5-6', source: '5', target: '6', type: 'smoothstep', label: 'smooth step edge' },
|
||||||
{
|
{
|
||||||
id: 'e5-7',
|
id: 'e5-7',
|
||||||
|
|||||||
Generated
+5
@@ -6177,6 +6177,11 @@
|
|||||||
"integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
|
"integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"classcat": {
|
||||||
|
"version": "4.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/classcat/-/classcat-4.1.0.tgz",
|
||||||
|
"integrity": "sha512-RA8O5oCi1I1CF6rR4cRBROh8MtZzM4w7xKLm0jd+S6UN2G4FIto+9DVOeFc46JEZFN5PVe/EZWLQO1VU/AUH4A=="
|
||||||
|
},
|
||||||
"classnames": {
|
"classnames": {
|
||||||
"version": "2.2.6",
|
"version": "2.2.6",
|
||||||
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz",
|
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz",
|
||||||
|
|||||||
+1
-1
@@ -24,7 +24,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@welldone-software/why-did-you-render": "^4.2.5",
|
"@welldone-software/why-did-you-render": "^4.2.5",
|
||||||
"classnames": "^2.2.6",
|
"classcat": "^4.1.0",
|
||||||
"d3-selection": "^1.4.1",
|
"d3-selection": "^1.4.1",
|
||||||
"d3-zoom": "^1.8.3",
|
"d3-zoom": "^1.8.3",
|
||||||
"easy-peasy": "^3.3.1",
|
"easy-peasy": "^3.3.1",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React, { memo, HTMLAttributes } from 'react';
|
import React, { memo, HTMLAttributes } from 'react';
|
||||||
import classnames from 'classnames';
|
import cc from 'classcat';
|
||||||
|
|
||||||
import { useStoreState } from '../../store/hooks';
|
import { useStoreState } from '../../store/hooks';
|
||||||
import { BackgroundVariant } from '../../types';
|
import { BackgroundVariant } from '../../types';
|
||||||
@@ -25,7 +25,7 @@ const Background = memo(
|
|||||||
const height = useStoreState((s) => s.height);
|
const height = useStoreState((s) => s.height);
|
||||||
const [x, y, scale] = useStoreState((s) => s.transform);
|
const [x, y, scale] = useStoreState((s) => s.transform);
|
||||||
|
|
||||||
const bgClasses = classnames('react-flow__background', className);
|
const bgClasses = cc(['react-flow__background', className]);
|
||||||
const bgColor = color ? color : defaultColors[variant];
|
const bgColor = color ? color : defaultColors[variant];
|
||||||
const scaledGap = gap * scale;
|
const scaledGap = gap * scale;
|
||||||
const xOffset = x % scaledGap;
|
const xOffset = x % scaledGap;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import classnames from 'classnames';
|
import cc from 'classcat';
|
||||||
|
|
||||||
import { useStoreState, useStoreActions } from '../../store/hooks';
|
import { useStoreState, useStoreActions } from '../../store/hooks';
|
||||||
|
|
||||||
@@ -24,7 +24,7 @@ const Controls = ({ style, showZoom = true, showFitView = true, showInteractive
|
|||||||
const zoomOut = useStoreActions((actions) => actions.zoomOut);
|
const zoomOut = useStoreActions((actions) => actions.zoomOut);
|
||||||
|
|
||||||
const isInteractive = useStoreState((s) => s.nodesDraggable && s.nodesConnectable && s.elementsSelectable);
|
const isInteractive = useStoreState((s) => s.nodesDraggable && s.nodesConnectable && s.elementsSelectable);
|
||||||
const mapClasses = classnames('react-flow__controls', className);
|
const mapClasses = cc(['react-flow__controls', className]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={mapClasses} style={style}>
|
<div className={mapClasses} style={style}>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import classnames from 'classnames';
|
import cc from 'classcat';
|
||||||
|
|
||||||
import { useStoreState } from '../../store/hooks';
|
import { useStoreState } from '../../store/hooks';
|
||||||
import { getRectOfNodes, getBoundsofRects } from '../../utils/graph';
|
import { getRectOfNodes, getBoundsofRects } from '../../utils/graph';
|
||||||
@@ -31,7 +31,7 @@ const MiniMap = ({
|
|||||||
const [tX, tY, tScale] = useStoreState((s) => s.transform);
|
const [tX, tY, tScale] = useStoreState((s) => s.transform);
|
||||||
const nodes = useStoreState((s) => s.nodes);
|
const nodes = useStoreState((s) => s.nodes);
|
||||||
|
|
||||||
const mapClasses = classnames('react-flow__minimap', className);
|
const mapClasses = cc(['react-flow__minimap', className]);
|
||||||
const elementWidth = (style.width || defaultWidth)! as number;
|
const elementWidth = (style.width || defaultWidth)! as number;
|
||||||
const elementHeight = (style.height || defaultHeight)! as number;
|
const elementHeight = (style.height || defaultHeight)! as number;
|
||||||
const nodeColorFunc = (nodeColor instanceof Function ? nodeColor : () => nodeColor) as StringFunc;
|
const nodeColorFunc = (nodeColor instanceof Function ? nodeColor : () => nodeColor) as StringFunc;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React, { useEffect, useState, CSSProperties } from 'react';
|
import React, { useEffect, useState, CSSProperties } from 'react';
|
||||||
import cx from 'classnames';
|
import cc from 'classcat';
|
||||||
|
|
||||||
import { getBezierPath } from '../Edges/BezierEdge';
|
import { getBezierPath } from '../Edges/BezierEdge';
|
||||||
import { getStepPath } from '../Edges/StepEdge';
|
import { getStepPath } from '../Edges/StepEdge';
|
||||||
@@ -46,7 +46,7 @@ export default ({
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const connectionLineClasses: string = cx('react-flow__connection', className);
|
const connectionLineClasses: string = cc(['react-flow__connection', className]);
|
||||||
|
|
||||||
const sourceHandle = handleId
|
const sourceHandle = handleId
|
||||||
? sourceNode.__rf.handleBounds[connectionHandleType].find((d: HandleElement) => d.id === handleId)
|
? sourceNode.__rf.handleBounds[connectionHandleType].find((d: HandleElement) => d.id === handleId)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import React, { memo } from 'react';
|
import React, { memo } from 'react';
|
||||||
|
|
||||||
import EdgeText from './EdgeText';
|
import EdgeText from './EdgeText';
|
||||||
|
import { getMarkerEnd } from './utils';
|
||||||
import { EdgeBezierProps, Position } from '../../types';
|
import { EdgeBezierProps, Position } from '../../types';
|
||||||
|
|
||||||
interface GetBezierPathParams {
|
interface GetBezierPathParams {
|
||||||
@@ -52,6 +53,8 @@ export default memo(
|
|||||||
labelShowBg,
|
labelShowBg,
|
||||||
labelBgStyle,
|
labelBgStyle,
|
||||||
style,
|
style,
|
||||||
|
arrowHeadType,
|
||||||
|
markerEndId,
|
||||||
}: EdgeBezierProps) => {
|
}: EdgeBezierProps) => {
|
||||||
const yOffset = Math.abs(targetY - sourceY) / 2;
|
const yOffset = Math.abs(targetY - sourceY) / 2;
|
||||||
const centerY = targetY < sourceY ? targetY + yOffset : targetY - yOffset;
|
const centerY = targetY < sourceY ? targetY + yOffset : targetY - yOffset;
|
||||||
@@ -81,9 +84,11 @@ export default memo(
|
|||||||
/>
|
/>
|
||||||
) : null;
|
) : null;
|
||||||
|
|
||||||
|
const markerEnd = getMarkerEnd(arrowHeadType, markerEndId);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<path style={style} d={path} className="react-flow__edge-path" />
|
<path style={style} d={path} className="react-flow__edge-path" markerEnd={markerEnd} />
|
||||||
{text}
|
{text}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import React, { memo } from 'react';
|
import React, { memo } from 'react';
|
||||||
|
|
||||||
import EdgeText from './EdgeText';
|
import EdgeText from './EdgeText';
|
||||||
|
import { getMarkerEnd } from './utils';
|
||||||
import { EdgeBezierProps, Position } from '../../types';
|
import { EdgeBezierProps, Position } from '../../types';
|
||||||
|
|
||||||
// These are some helper methods for drawing the round corners
|
// These are some helper methods for drawing the round corners
|
||||||
@@ -138,6 +139,8 @@ export default memo(
|
|||||||
style,
|
style,
|
||||||
sourcePosition = Position.Bottom,
|
sourcePosition = Position.Bottom,
|
||||||
targetPosition = Position.Top,
|
targetPosition = Position.Top,
|
||||||
|
arrowHeadType,
|
||||||
|
markerEndId,
|
||||||
}: EdgeBezierProps) => {
|
}: EdgeBezierProps) => {
|
||||||
const yOffset = Math.abs(targetY - sourceY) / 2;
|
const yOffset = Math.abs(targetY - sourceY) / 2;
|
||||||
const centerY = targetY < sourceY ? targetY + yOffset : targetY - yOffset;
|
const centerY = targetY < sourceY ? targetY + yOffset : targetY - yOffset;
|
||||||
@@ -158,6 +161,8 @@ export default memo(
|
|||||||
targetPosition,
|
targetPosition,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const markerEnd = getMarkerEnd(arrowHeadType, markerEndId);
|
||||||
|
|
||||||
const text = label ? (
|
const text = label ? (
|
||||||
<EdgeText
|
<EdgeText
|
||||||
x={centerX}
|
x={centerX}
|
||||||
@@ -171,7 +176,7 @@ export default memo(
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<path style={style} className="react-flow__edge-path" d={path} />
|
<path style={style} className="react-flow__edge-path" d={path} markerEnd={markerEnd} />
|
||||||
{text}
|
{text}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import React, { memo } from 'react';
|
import React, { memo } from 'react';
|
||||||
|
|
||||||
import EdgeText from './EdgeText';
|
import EdgeText from './EdgeText';
|
||||||
|
import { getMarkerEnd } from './utils';
|
||||||
import { EdgeProps } from '../../types';
|
import { EdgeProps } from '../../types';
|
||||||
|
|
||||||
interface GetStepPathParams {
|
interface GetStepPathParams {
|
||||||
@@ -16,7 +17,19 @@ export function getStepPath({ centerY, sourceX, sourceY, targetX, targetY }: Get
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default memo(
|
export default memo(
|
||||||
({ sourceX, sourceY, targetX, targetY, label, labelStyle, labelShowBg, labelBgStyle, style }: EdgeProps) => {
|
({
|
||||||
|
sourceX,
|
||||||
|
sourceY,
|
||||||
|
targetX,
|
||||||
|
targetY,
|
||||||
|
label,
|
||||||
|
labelStyle,
|
||||||
|
labelShowBg,
|
||||||
|
labelBgStyle,
|
||||||
|
style,
|
||||||
|
arrowHeadType,
|
||||||
|
markerEndId,
|
||||||
|
}: EdgeProps) => {
|
||||||
const yOffset = Math.abs(targetY - sourceY) / 2;
|
const yOffset = Math.abs(targetY - sourceY) / 2;
|
||||||
const centerY = targetY < sourceY ? targetY + yOffset : targetY - yOffset;
|
const centerY = targetY < sourceY ? targetY + yOffset : targetY - yOffset;
|
||||||
|
|
||||||
@@ -25,6 +38,8 @@ export default memo(
|
|||||||
|
|
||||||
const path = getStepPath({ centerY, sourceX, sourceY, targetX, targetY });
|
const path = getStepPath({ centerY, sourceX, sourceY, targetX, targetY });
|
||||||
|
|
||||||
|
const markerEnd = getMarkerEnd(arrowHeadType, markerEndId);
|
||||||
|
|
||||||
const text = label ? (
|
const text = label ? (
|
||||||
<EdgeText
|
<EdgeText
|
||||||
x={centerX}
|
x={centerX}
|
||||||
@@ -38,7 +53,7 @@ export default memo(
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<path style={style} className="react-flow__edge-path" d={path} />
|
<path style={style} className="react-flow__edge-path" d={path} markerEnd={markerEnd} />
|
||||||
{text}
|
{text}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,15 +1,29 @@
|
|||||||
import React, { memo } from 'react';
|
import React, { memo } from 'react';
|
||||||
|
|
||||||
import EdgeText from './EdgeText';
|
import EdgeText from './EdgeText';
|
||||||
|
import { getMarkerEnd } from './utils';
|
||||||
import { EdgeProps } from '../../types';
|
import { EdgeProps } from '../../types';
|
||||||
|
|
||||||
export default memo(
|
export default memo(
|
||||||
({ sourceX, sourceY, targetX, targetY, label, labelStyle, labelShowBg, labelBgStyle, style }: EdgeProps) => {
|
({
|
||||||
|
sourceX,
|
||||||
|
sourceY,
|
||||||
|
targetX,
|
||||||
|
targetY,
|
||||||
|
label,
|
||||||
|
labelStyle,
|
||||||
|
labelShowBg,
|
||||||
|
labelBgStyle,
|
||||||
|
style,
|
||||||
|
arrowHeadType,
|
||||||
|
markerEndId,
|
||||||
|
}: EdgeProps) => {
|
||||||
const yOffset = Math.abs(targetY - sourceY) / 2;
|
const yOffset = Math.abs(targetY - sourceY) / 2;
|
||||||
const centerY = targetY < sourceY ? targetY + yOffset : targetY - yOffset;
|
const centerY = targetY < sourceY ? targetY + yOffset : targetY - yOffset;
|
||||||
|
|
||||||
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;
|
||||||
|
const markerEnd = getMarkerEnd(arrowHeadType, markerEndId);
|
||||||
|
|
||||||
const text = label ? (
|
const text = label ? (
|
||||||
<EdgeText
|
<EdgeText
|
||||||
@@ -24,7 +38,12 @@ export default memo(
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<path style={style} className="react-flow__edge-path" d={`M ${sourceX},${sourceY}L ${targetX},${targetY}`} />
|
<path
|
||||||
|
style={style}
|
||||||
|
className="react-flow__edge-path"
|
||||||
|
d={`M ${sourceX},${sourceY}L ${targetX},${targetY}`}
|
||||||
|
markerEnd={markerEnd}
|
||||||
|
/>
|
||||||
{text}
|
{text}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
export { default as BezierEdge } from './BezierEdge';
|
||||||
|
export { default as StepEdge } from './StepEdge';
|
||||||
|
export { default as SmoothStepEdge } from './SmoothStepEdge';
|
||||||
|
export { default as StraightEdge } from './StraightEdge';
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import { ArrowHeadType } from '../../types';
|
||||||
|
|
||||||
|
export const getMarkerEnd = (arrowHeadType?: ArrowHeadType, markerEndId?: string): string => {
|
||||||
|
if (typeof markerEndId !== 'undefined' && markerEndId) {
|
||||||
|
return `url(#${markerEndId})`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return typeof arrowHeadType !== 'undefined' ? `url(#react-flow__${arrowHeadType})` : 'none';
|
||||||
|
};
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import React, { memo, ComponentType, CSSProperties } from 'react';
|
import React, { memo, ComponentType, CSSProperties } from 'react';
|
||||||
import cx from 'classnames';
|
import cc from 'classcat';
|
||||||
|
|
||||||
import { useStoreActions } from '../../store/hooks';
|
import { useStoreActions } from '../../store/hooks';
|
||||||
import { ElementId, Edge, EdgeCompProps } from '../../types';
|
import { ElementId, Edge, EdgeCompProps } from '../../types';
|
||||||
@@ -39,7 +39,7 @@ export default (EdgeComponent: ComponentType<EdgeCompProps>) => {
|
|||||||
...rest
|
...rest
|
||||||
}: EdgeWrapperProps) => {
|
}: EdgeWrapperProps) => {
|
||||||
const setSelectedElements = useStoreActions((a) => a.setSelectedElements);
|
const setSelectedElements = useStoreActions((a) => a.setSelectedElements);
|
||||||
const edgeClasses = cx('react-flow__edge', `react-flow__edge-${type}`, className, { selected, animated });
|
const edgeClasses = cc(['react-flow__edge', `react-flow__edge-${type}`, className, { selected, animated }]);
|
||||||
const edgeGroupStyle: CSSProperties = {
|
const edgeGroupStyle: CSSProperties = {
|
||||||
pointerEvents: elementsSelectable ? 'all' : 'none',
|
pointerEvents: elementsSelectable ? 'all' : 'none',
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React, { memo, MouseEvent as ReactMouseEvent, CSSProperties } from 'react';
|
import React, { memo, MouseEvent as ReactMouseEvent, CSSProperties } from 'react';
|
||||||
import cx from 'classnames';
|
import cc from 'classcat';
|
||||||
|
|
||||||
import { HandleType, ElementId, Position, XYPosition, OnConnectFunc, Connection, SetConnectionId } from '../../types';
|
import { HandleType, ElementId, Position, XYPosition, OnConnectFunc, Connection, SetConnectionId } from '../../types';
|
||||||
|
|
||||||
@@ -144,10 +144,16 @@ const BaseHandle = memo(
|
|||||||
...rest
|
...rest
|
||||||
}: BaseHandleProps) => {
|
}: BaseHandleProps) => {
|
||||||
const isTarget = type === 'target';
|
const isTarget = type === 'target';
|
||||||
const handleClasses = cx('react-flow__handle', `react-flow__handle-${position}`, 'nodrag', className, {
|
const handleClasses = cc([
|
||||||
source: !isTarget,
|
'react-flow__handle',
|
||||||
target: isTarget,
|
`react-flow__handle-${position}`,
|
||||||
});
|
'nodrag',
|
||||||
|
className,
|
||||||
|
{
|
||||||
|
source: !isTarget,
|
||||||
|
target: isTarget,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
const nodeIdWithHandleId = id ? `${nodeId}__${id}` : nodeId;
|
const nodeIdWithHandleId = id ? `${nodeId}__${id}` : nodeId;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React, { memo, useContext } from 'react';
|
import React, { memo, useContext } from 'react';
|
||||||
import classnames from 'classnames';
|
import cc from 'classcat';
|
||||||
|
|
||||||
import { useStoreActions, useStoreState } from '../../store/hooks';
|
import { useStoreActions, useStoreState } from '../../store/hooks';
|
||||||
import BaseHandle from './BaseHandle';
|
import BaseHandle from './BaseHandle';
|
||||||
@@ -26,7 +26,7 @@ const Handle = memo(
|
|||||||
onConnectAction(params);
|
onConnectAction(params);
|
||||||
onConnect(params);
|
onConnect(params);
|
||||||
};
|
};
|
||||||
const handleClasses = classnames(className, { connectable: isConnectable });
|
const handleClasses = cc([className, { connectable: isConnectable }]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BaseHandle
|
<BaseHandle
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ import React, {
|
|||||||
useCallback,
|
useCallback,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import { DraggableCore } from 'react-draggable';
|
import { DraggableCore } from 'react-draggable';
|
||||||
import cx from 'classnames';
|
import cc from 'classcat';
|
||||||
|
|
||||||
import { ResizeObserver } from 'resize-observer';
|
import { ResizeObserver } from 'resize-observer';
|
||||||
import { useStoreActions } from '../../store/hooks';
|
import { useStoreActions } from '../../store/hooks';
|
||||||
|
|
||||||
@@ -192,10 +193,15 @@ export default (NodeComponent: ComponentType<NodeComponentProps>) => {
|
|||||||
const [offset, setOffset] = useState({ x: 0, y: 0 });
|
const [offset, setOffset] = useState({ x: 0, y: 0 });
|
||||||
const [isDragging, setDragging] = useState(false);
|
const [isDragging, setDragging] = useState(false);
|
||||||
const position = { x: xPos, y: yPos };
|
const position = { x: xPos, y: yPos };
|
||||||
const nodeClasses = cx('react-flow__node', `react-flow__node-${type}`, className, {
|
const nodeClasses = cc([
|
||||||
selected,
|
'react-flow__node',
|
||||||
selectable: isSelectable,
|
`react-flow__node-${type}`,
|
||||||
});
|
className,
|
||||||
|
{
|
||||||
|
selected,
|
||||||
|
selectable: isSelectable,
|
||||||
|
},
|
||||||
|
]);
|
||||||
const node = { id, type, position, data };
|
const node = { id, type, position, data };
|
||||||
const onMouseEnterHandler = useMemo(() => {
|
const onMouseEnterHandler = useMemo(() => {
|
||||||
if (!onMouseEnter || isDragging) {
|
if (!onMouseEnter || isDragging) {
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
import React, { ReactNode } from 'react';
|
||||||
|
|
||||||
|
interface MarkerProps {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
const MarkerDefinitions = ({ color }: MarkerDefinitionsProps) => {
|
||||||
|
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"
|
||||||
|
/>
|
||||||
|
</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>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
MarkerDefinitions.displayName = 'MarkerDefinitions';
|
||||||
|
|
||||||
|
export default MarkerDefinitions;
|
||||||
@@ -3,6 +3,7 @@ import React, { memo, CSSProperties } 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 MarkerDefinitions from './MarkerDefinitions';
|
||||||
import { XYPosition, Position, Edge, Node, ElementId, HandleElement, Elements, ConnectionLineType } from '../../types';
|
import { XYPosition, Position, Edge, Node, ElementId, HandleElement, Elements, ConnectionLineType } from '../../types';
|
||||||
|
|
||||||
interface EdgeRendererProps {
|
interface EdgeRendererProps {
|
||||||
@@ -12,6 +13,8 @@ interface EdgeRendererProps {
|
|||||||
connectionLineType: ConnectionLineType;
|
connectionLineType: ConnectionLineType;
|
||||||
connectionLineStyle?: CSSProperties;
|
connectionLineStyle?: CSSProperties;
|
||||||
onElementClick?: (element: Node | Edge) => void;
|
onElementClick?: (element: Node | Edge) => void;
|
||||||
|
arrowHeadColor: string;
|
||||||
|
markerEndId?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface EdgePositions {
|
interface EdgePositions {
|
||||||
@@ -171,6 +174,7 @@ function renderEdge(
|
|||||||
labelShowBg={edge.labelShowBg}
|
labelShowBg={edge.labelShowBg}
|
||||||
labelBgStyle={edge.labelBgStyle}
|
labelBgStyle={edge.labelBgStyle}
|
||||||
style={edge.style}
|
style={edge.style}
|
||||||
|
arrowHeadType={edge.arrowHeadType}
|
||||||
source={sourceId}
|
source={sourceId}
|
||||||
target={targetId}
|
target={targetId}
|
||||||
sourceHandleId={sourceHandleId}
|
sourceHandleId={sourceHandleId}
|
||||||
@@ -182,6 +186,7 @@ function renderEdge(
|
|||||||
sourcePosition={sourcePosition}
|
sourcePosition={sourcePosition}
|
||||||
targetPosition={targetPosition}
|
targetPosition={targetPosition}
|
||||||
elementsSelectable={elementsSelectable}
|
elementsSelectable={elementsSelectable}
|
||||||
|
markerEndId={props.markerEndId}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -197,7 +202,7 @@ const EdgeRenderer = memo((props: EdgeRendererProps) => {
|
|||||||
const nodesConnectable = useStoreState((s) => s.nodesConnectable);
|
const nodesConnectable = useStoreState((s) => s.nodesConnectable);
|
||||||
const elementsSelectable = useStoreState((s) => s.elementsSelectable);
|
const elementsSelectable = useStoreState((s) => s.elementsSelectable);
|
||||||
|
|
||||||
const { width, height, connectionLineStyle, connectionLineType } = props;
|
const { width, height, connectionLineStyle, connectionLineType, arrowHeadColor } = props;
|
||||||
|
|
||||||
if (!width) {
|
if (!width) {
|
||||||
return null;
|
return null;
|
||||||
@@ -208,6 +213,7 @@ const EdgeRenderer = memo((props: EdgeRendererProps) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<svg width={width} height={height} className="react-flow__edges">
|
<svg width={width} height={height} className="react-flow__edges">
|
||||||
|
<MarkerDefinitions color={arrowHeadColor} />
|
||||||
<g transform={transformStyle}>
|
<g transform={transformStyle}>
|
||||||
{edges.map((e: Edge) => renderEdge(e, props, nodes, selectedElements, elementsSelectable))}
|
{edges.map((e: Edge) => renderEdge(e, props, nodes, selectedElements, elementsSelectable))}
|
||||||
{renderConnectionLine && (
|
{renderConnectionLine && (
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
import { ComponentType } from 'react';
|
import { ComponentType } from 'react';
|
||||||
|
|
||||||
import StraightEdge from '../../components/Edges/StraightEdge';
|
import { BezierEdge, StepEdge, SmoothStepEdge, StraightEdge } from '../../components/Edges';
|
||||||
import BezierEdge from '../../components/Edges/BezierEdge';
|
|
||||||
import StepEdge from '../../components/Edges/StepEdge';
|
|
||||||
import SmoothStepEdge from '../../components/Edges/SmoothStepEdge';
|
|
||||||
import wrapEdge from '../../components/Edges/wrapEdge';
|
import wrapEdge from '../../components/Edges/wrapEdge';
|
||||||
|
|
||||||
import { EdgeTypesType, EdgeCompProps } from '../../types';
|
import { EdgeTypesType, EdgeCompProps } from '../../types';
|
||||||
|
|||||||
@@ -52,6 +52,9 @@ export interface GraphViewProps {
|
|||||||
minZoom: number;
|
minZoom: number;
|
||||||
maxZoom: number;
|
maxZoom: number;
|
||||||
defaultZoom: number;
|
defaultZoom: number;
|
||||||
|
arrowHeadColor: string;
|
||||||
|
markerEndId?: string;
|
||||||
|
zoomOnScroll: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const GraphView = memo(
|
const GraphView = memo(
|
||||||
@@ -84,6 +87,9 @@ const GraphView = memo(
|
|||||||
minZoom,
|
minZoom,
|
||||||
maxZoom,
|
maxZoom,
|
||||||
defaultZoom,
|
defaultZoom,
|
||||||
|
arrowHeadColor,
|
||||||
|
markerEndId,
|
||||||
|
zoomOnScroll,
|
||||||
}: GraphViewProps) => {
|
}: GraphViewProps) => {
|
||||||
const zoomPane = useRef<HTMLDivElement>(null);
|
const zoomPane = useRef<HTMLDivElement>(null);
|
||||||
const rendererNode = useRef<HTMLDivElement>(null);
|
const rendererNode = useRef<HTMLDivElement>(null);
|
||||||
@@ -154,7 +160,7 @@ const GraphView = memo(
|
|||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useD3Zoom({ zoomPane, onMove, selectionKeyPressed });
|
useD3Zoom({ zoomPane, onMove, selectionKeyPressed, zoomOnScroll });
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (d3Initialised && onLoad) {
|
if (d3Initialised && onLoad) {
|
||||||
@@ -212,6 +218,8 @@ const GraphView = memo(
|
|||||||
onElementClick={onElementClick}
|
onElementClick={onElementClick}
|
||||||
connectionLineType={connectionLineType}
|
connectionLineType={connectionLineType}
|
||||||
connectionLineStyle={connectionLineStyle}
|
connectionLineStyle={connectionLineStyle}
|
||||||
|
arrowHeadColor={arrowHeadColor}
|
||||||
|
markerEndId={markerEndId}
|
||||||
/>
|
/>
|
||||||
<UserSelection selectionKeyPressed={selectionKeyPressed} />
|
<UserSelection selectionKeyPressed={selectionKeyPressed} />
|
||||||
{nodesSelectionActive && <NodesSelection />}
|
{nodesSelectionActive && <NodesSelection />}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React, { useMemo, CSSProperties, HTMLAttributes, MouseEvent } from 'react';
|
import React, { useMemo, CSSProperties, HTMLAttributes, MouseEvent } from 'react';
|
||||||
import cx from 'classnames';
|
import cc from 'classcat';
|
||||||
|
|
||||||
const nodeEnv: string = process.env.NODE_ENV as string;
|
const nodeEnv: string = process.env.NODE_ENV as string;
|
||||||
|
|
||||||
@@ -14,10 +14,7 @@ import InputNode from '../../components/Nodes/InputNode';
|
|||||||
import OutputNode from '../../components/Nodes/OutputNode';
|
import OutputNode from '../../components/Nodes/OutputNode';
|
||||||
import { createNodeTypes } from '../NodeRenderer/utils';
|
import { createNodeTypes } from '../NodeRenderer/utils';
|
||||||
import SelectionListener from '../../components/SelectionListener';
|
import SelectionListener from '../../components/SelectionListener';
|
||||||
import BezierEdge from '../../components/Edges/BezierEdge';
|
import { BezierEdge, StepEdge, SmoothStepEdge, StraightEdge } from '../../components/Edges';
|
||||||
import StraightEdge from '../../components/Edges/StraightEdge';
|
|
||||||
import StepEdge from '../../components/Edges/StepEdge';
|
|
||||||
import SmoothStepEdge from '../../components/Edges/SmoothStepEdge';
|
|
||||||
import { createEdgeTypes } from '../EdgeRenderer/utils';
|
import { createEdgeTypes } from '../EdgeRenderer/utils';
|
||||||
import Wrapper from './Wrapper';
|
import Wrapper from './Wrapper';
|
||||||
import {
|
import {
|
||||||
@@ -63,6 +60,9 @@ export interface ReactFlowProps extends Omit<HTMLAttributes<HTMLDivElement>, 'on
|
|||||||
minZoom: number;
|
minZoom: number;
|
||||||
maxZoom: number;
|
maxZoom: number;
|
||||||
defaultZoom: number;
|
defaultZoom: number;
|
||||||
|
arrowHeadColor: string;
|
||||||
|
markerEndId?: string;
|
||||||
|
zoomOnScroll: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const ReactFlow = ({
|
const ReactFlow = ({
|
||||||
@@ -98,12 +98,16 @@ const ReactFlow = ({
|
|||||||
minZoom,
|
minZoom,
|
||||||
maxZoom,
|
maxZoom,
|
||||||
defaultZoom,
|
defaultZoom,
|
||||||
|
arrowHeadColor,
|
||||||
|
markerEndId,
|
||||||
|
zoomOnScroll
|
||||||
}: ReactFlowProps) => {
|
}: ReactFlowProps) => {
|
||||||
const nodeTypesParsed = useMemo(() => createNodeTypes(nodeTypes), []);
|
const nodeTypesParsed = useMemo(() => createNodeTypes(nodeTypes), []);
|
||||||
const edgeTypesParsed = useMemo(() => createEdgeTypes(edgeTypes), []);
|
const edgeTypesParsed = useMemo(() => createEdgeTypes(edgeTypes), []);
|
||||||
|
const reactFlowClasses = cc(['react-flow', className]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={style} className={cx('react-flow', className)}>
|
<div style={style} className={reactFlowClasses}>
|
||||||
<Wrapper>
|
<Wrapper>
|
||||||
<GraphView
|
<GraphView
|
||||||
onLoad={onLoad}
|
onLoad={onLoad}
|
||||||
@@ -134,6 +138,9 @@ const ReactFlow = ({
|
|||||||
minZoom={minZoom}
|
minZoom={minZoom}
|
||||||
maxZoom={maxZoom}
|
maxZoom={maxZoom}
|
||||||
defaultZoom={defaultZoom}
|
defaultZoom={defaultZoom}
|
||||||
|
arrowHeadColor={arrowHeadColor}
|
||||||
|
markerEndId={markerEndId}
|
||||||
|
zoomOnScroll={zoomOnScroll}
|
||||||
/>
|
/>
|
||||||
{onSelectionChange && <SelectionListener onSelectionChange={onSelectionChange} />}
|
{onSelectionChange && <SelectionListener onSelectionChange={onSelectionChange} />}
|
||||||
{children}
|
{children}
|
||||||
@@ -169,6 +176,8 @@ ReactFlow.defaultProps = {
|
|||||||
minZoom: 0.5,
|
minZoom: 0.5,
|
||||||
maxZoom: 2,
|
maxZoom: 2,
|
||||||
defaultZoom: 1,
|
defaultZoom: 1,
|
||||||
|
arrowHeadColor: '#bbb',
|
||||||
|
zoomOnScroll: true
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ReactFlow;
|
export default ReactFlow;
|
||||||
|
|||||||
@@ -6,10 +6,11 @@ import { useStoreState, useStoreActions } from '../store/hooks';
|
|||||||
interface UseD3ZoomParams {
|
interface UseD3ZoomParams {
|
||||||
zoomPane: MutableRefObject<Element | null>;
|
zoomPane: MutableRefObject<Element | null>;
|
||||||
selectionKeyPressed: boolean;
|
selectionKeyPressed: boolean;
|
||||||
|
zoomOnScroll: boolean;
|
||||||
onMove?: () => void;
|
onMove?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ({ zoomPane, onMove, selectionKeyPressed }: UseD3ZoomParams): void => {
|
export default ({ zoomPane, onMove, zoomOnScroll, selectionKeyPressed }: UseD3ZoomParams): void => {
|
||||||
const d3Zoom = useStoreState((s) => s.d3Zoom);
|
const d3Zoom = useStoreState((s) => s.d3Zoom);
|
||||||
|
|
||||||
const initD3 = useStoreActions((actions) => actions.initD3);
|
const initD3 = useStoreActions((actions) => actions.initD3);
|
||||||
@@ -31,6 +32,10 @@ export default ({ zoomPane, onMove, selectionKeyPressed }: UseD3ZoomParams): voi
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!zoomOnScroll && event.sourceEvent.type === 'wheel') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
updateTransform(event.transform);
|
updateTransform(event.transform);
|
||||||
|
|
||||||
if (onMove) {
|
if (onMove) {
|
||||||
@@ -39,5 +44,5 @@ export default ({ zoomPane, onMove, selectionKeyPressed }: UseD3ZoomParams): voi
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [selectionKeyPressed, d3Zoom]);
|
}, [selectionKeyPressed, zoomOnScroll, d3Zoom]);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -42,6 +42,11 @@ export interface Node {
|
|||||||
sourcePosition?: Position;
|
sourcePosition?: Position;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum ArrowHeadType {
|
||||||
|
Arrow = 'arrow',
|
||||||
|
ArrowClosed = 'arrowclosed',
|
||||||
|
}
|
||||||
|
|
||||||
export interface Edge {
|
export interface Edge {
|
||||||
id: ElementId;
|
id: ElementId;
|
||||||
type?: string;
|
type?: string;
|
||||||
@@ -53,6 +58,7 @@ export interface Edge {
|
|||||||
labelBgStyle?: CSSProperties;
|
labelBgStyle?: CSSProperties;
|
||||||
style?: CSSProperties;
|
style?: CSSProperties;
|
||||||
animated?: boolean;
|
animated?: boolean;
|
||||||
|
arrowHeadType?: ArrowHeadType;
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum BackgroundVariant {
|
export enum BackgroundVariant {
|
||||||
@@ -82,6 +88,8 @@ export interface EdgeProps {
|
|||||||
labelShowBg?: boolean;
|
labelShowBg?: boolean;
|
||||||
labelBgStyle?: CSSProperties;
|
labelBgStyle?: CSSProperties;
|
||||||
style?: CSSProperties;
|
style?: CSSProperties;
|
||||||
|
arrowHeadType?: ArrowHeadType;
|
||||||
|
markerEndId?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface EdgeBezierProps extends EdgeProps {
|
export interface EdgeBezierProps extends EdgeProps {
|
||||||
|
|||||||
Reference in New Issue
Block a user