Merge pull request #207 from wbkd/feat-edgetext
feat(edges): add label and labelBg options
This commit is contained in:
@@ -31,7 +31,7 @@ React Flow is a library for building node-based graphs. You can easily implement
|
|||||||
* **Plugin system:** [Mini map and graph controls](#plugins)
|
* **Plugin system:** [Mini map and graph controls](#plugins)
|
||||||
* **Reliable**: Written in [Typescript](https://www.typescriptlang.org/) and tested with [cypress](https://www.cypress.io/)
|
* **Reliable**: Written in [Typescript](https://www.typescriptlang.org/) and tested with [cypress](https://www.cypress.io/)
|
||||||
|
|
||||||
In order to make this library as flexible as possible we don’t do any state updates besides the positions. This means that you need to pass all functions that change the displayed nodes and edges by yourself. You can implement your own ones or use the helper functions that come with the library.
|
In order to make this library as flexible as possible we don’t do any state updates besides the positions. This means that you need to pass all functions that change the displayed nodes and edges by yourself. You can implement your own ones or use the helper functions that come with the library.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
@@ -130,7 +130,7 @@ You can find an example of how to implement a custom node in the [custom node ex
|
|||||||
|
|
||||||
There are three [edge types](#edge-types--custom-edges) (`straight`, `default`, `step`) you can use. The default type is `default`. You can also create [custom edges](#edge-types--custom-edges).
|
There are three [edge types](#edge-types--custom-edges) (`straight`, `default`, `step`) you can use. The default type is `default`. You can also create [custom edges](#edge-types--custom-edges).
|
||||||
|
|
||||||
Edge example: `{ id: 'e1-2', type: 'straight', source: '1', target: '2', animated: true }`
|
Edge example: `{ id: 'e1-2', type: 'straight', source: '1', target: '2', animated: true, label: 'edge label' }`
|
||||||
|
|
||||||
### Props
|
### Props
|
||||||
|
|
||||||
@@ -139,7 +139,13 @@ Edge example: `{ id: 'e1-2', type: 'straight', source: '1', target: '2', animate
|
|||||||
- `target`: string (an id of a node) *(required)*
|
- `target`: string (an id of a node) *(required)*
|
||||||
- `type`: 'input' | 'output' | 'default' or a custom one you implemented
|
- `type`: 'input' | 'output' | 'default' or a custom one you implemented
|
||||||
- `animated`: boolean
|
- `animated`: boolean
|
||||||
- `style`: css properties
|
- `style`: css properties for the edge line path
|
||||||
|
- `label`: string
|
||||||
|
- `labelStyle`: css properties for the text
|
||||||
|
- `labelShowBg`: boolean - default: `true`
|
||||||
|
- `labelBgStyle`: css properties for the text background
|
||||||
|
|
||||||
|
You can find an example with lots of different edges in the [edges example](https://react-flow.netlify.app/edges).
|
||||||
|
|
||||||
### Edge Types / Custom Edges
|
### Edge Types / Custom Edges
|
||||||
|
|
||||||
|
|||||||
Vendored
+51
-12
@@ -6896,7 +6896,7 @@ function renderEdge(edge, props, nodes, selectedElements, isInteractive) {
|
|||||||
var targetPosition = targetHandle ? targetHandle.position : Position.Top;
|
var targetPosition = targetHandle ? targetHandle.position : Position.Top;
|
||||||
var _c = getEdgePositions(sourceNode, sourceHandle, sourcePosition, targetNode, targetHandle, targetPosition), sourceX = _c.sourceX, sourceY = _c.sourceY, targetX = _c.targetX, targetY = _c.targetY;
|
var _c = getEdgePositions(sourceNode, sourceHandle, sourcePosition, targetNode, targetHandle, targetPosition), sourceX = _c.sourceX, sourceY = _c.sourceY, targetX = _c.targetX, targetY = _c.targetY;
|
||||||
var isSelected = selectedElements.some(function (elm) { return isEdge(elm) && elm.source === sourceId && elm.target === targetId; });
|
var isSelected = selectedElements.some(function (elm) { return isEdge(elm) && elm.source === sourceId && elm.target === targetId; });
|
||||||
return (React__default.createElement(EdgeComponent, { key: edge.id, id: edge.id, type: edge.type, onClick: props.onElementClick, selected: isSelected, animated: edge.animated, style: edge.style, source: sourceId, target: targetId, sourceHandleId: sourceHandleId, targetHandleId: targetHandleId, sourceX: sourceX, sourceY: sourceY, targetX: targetX, targetY: targetY, sourcePosition: sourcePosition, targetPosition: targetPosition, isInteractive: isInteractive }));
|
return (React__default.createElement(EdgeComponent, { key: edge.id, id: edge.id, type: edge.type, onClick: props.onElementClick, selected: isSelected, animated: edge.animated, label: edge.label, labelStyle: edge.labelStyle, labelShowBg: edge.labelShowBg, labelBgStyle: edge.labelBgStyle, style: edge.style, source: sourceId, target: targetId, sourceHandleId: sourceHandleId, targetHandleId: targetHandleId, sourceX: sourceX, sourceY: sourceY, targetX: targetX, targetY: targetY, sourcePosition: sourcePosition, targetPosition: targetPosition, isInteractive: isInteractive }));
|
||||||
}
|
}
|
||||||
var EdgeRenderer = memo(function (props) {
|
var EdgeRenderer = memo(function (props) {
|
||||||
var _a = useStoreState$1(function (s) { return ({
|
var _a = useStoreState$1(function (s) { return ({
|
||||||
@@ -9270,38 +9270,77 @@ function createNodeTypes(nodeTypes) {
|
|||||||
return __assign(__assign({}, standardTypes), specialTypes);
|
return __assign(__assign({}, standardTypes), specialTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var textBgPadding = 2;
|
||||||
|
var EdgeText = memo(function (_a) {
|
||||||
|
var x = _a.x, y = _a.y, label = _a.label, _b = _a.labelStyle, labelStyle = _b === void 0 ? {} : _b, _c = _a.labelShowBg, labelShowBg = _c === void 0 ? true : _c, _d = _a.labelBgStyle, labelBgStyle = _d === void 0 ? {} : _d;
|
||||||
|
var edgeRef = useRef(null);
|
||||||
|
var _e = useState({ x: 0, y: 0, width: 0, height: 0 }), edgeTextBbox = _e[0], setEdgeTextBbox = _e[1];
|
||||||
|
useEffect(function () {
|
||||||
|
if (edgeRef.current) {
|
||||||
|
var textBbox = edgeRef.current.getBBox();
|
||||||
|
setEdgeTextBbox({
|
||||||
|
x: textBbox.x,
|
||||||
|
y: textBbox.y,
|
||||||
|
width: textBbox.width,
|
||||||
|
height: textBbox.height,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
if (typeof label === 'undefined' || !label) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return (React__default.createElement("g", { transform: "translate(" + (x - edgeTextBbox.width / 2) + " " + (y - edgeTextBbox.height / 2) + ")" },
|
||||||
|
labelShowBg && (React__default.createElement("rect", { width: edgeTextBbox.width + 2 * textBgPadding, x: -textBgPadding, y: -textBgPadding, height: edgeTextBbox.height + 2 * textBgPadding, className: "react-flow__edge-textbg", style: labelBgStyle })),
|
||||||
|
React__default.createElement("text", { className: "react-flow__edge-text", y: edgeTextBbox.height / 2, dy: "0.3em", ref: edgeRef, style: labelStyle }, label)));
|
||||||
|
});
|
||||||
|
|
||||||
var BezierEdge = memo(function (_a) {
|
var BezierEdge = memo(function (_a) {
|
||||||
var sourceX = _a.sourceX, sourceY = _a.sourceY, targetX = _a.targetX, targetY = _a.targetY, _b = _a.sourcePosition, sourcePosition = _b === void 0 ? Position.Bottom : _b, _c = _a.targetPosition, targetPosition = _c === void 0 ? Position.Top : _c, _d = _a.style, style = _d === void 0 ? {} : _d;
|
var sourceX = _a.sourceX, sourceY = _a.sourceY, targetX = _a.targetX, targetY = _a.targetY, _b = _a.sourcePosition, sourcePosition = _b === void 0 ? Position.Bottom : _b, _c = _a.targetPosition, targetPosition = _c === void 0 ? Position.Top : _c, label = _a.label, labelStyle = _a.labelStyle, labelShowBg = _a.labelShowBg, labelBgStyle = _a.labelBgStyle, _d = _a.style, style = _d === void 0 ? {} : _d;
|
||||||
var yOffset = Math.abs(targetY - sourceY) / 2;
|
var yOffset = Math.abs(targetY - sourceY) / 2;
|
||||||
var centerY = targetY < sourceY ? targetY + yOffset : targetY - yOffset;
|
var centerY = targetY < sourceY ? targetY + yOffset : targetY - yOffset;
|
||||||
|
var xOffset = Math.abs(targetX - sourceX) / 2;
|
||||||
|
var centerX = targetX < sourceX ? targetX + xOffset : targetX - xOffset;
|
||||||
var dAttr = "M" + sourceX + "," + sourceY + " C" + sourceX + "," + centerY + " " + targetX + "," + centerY + " " + targetX + "," + targetY;
|
var dAttr = "M" + sourceX + "," + sourceY + " C" + sourceX + "," + centerY + " " + targetX + "," + centerY + " " + targetX + "," + targetY;
|
||||||
var leftAndRight = [Position.Left, Position.Right];
|
var leftAndRight = [Position.Left, Position.Right];
|
||||||
if (leftAndRight.includes(sourcePosition) && leftAndRight.includes(targetPosition)) {
|
if (leftAndRight.includes(sourcePosition) && leftAndRight.includes(targetPosition)) {
|
||||||
var xOffset = Math.abs(targetX - sourceX) / 2;
|
|
||||||
var 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 (leftAndRight.includes(sourcePosition) || leftAndRight.includes(targetPosition)) {
|
else if (leftAndRight.includes(sourcePosition) || leftAndRight.includes(targetPosition)) {
|
||||||
dAttr = "M" + sourceX + "," + sourceY + " C" + sourceX + "," + targetY + " " + sourceX + "," + targetY + " " + targetX + "," + targetY;
|
dAttr = "M" + sourceX + "," + sourceY + " C" + sourceX + "," + targetY + " " + sourceX + "," + targetY + " " + targetX + "," + targetY;
|
||||||
}
|
}
|
||||||
return React__default.createElement("path", __assign({}, style, { d: dAttr }));
|
var text = label ? (React__default.createElement(EdgeText, { x: centerX, y: centerY, label: label, labelStyle: labelStyle, labelShowBg: labelShowBg, labelBgStyle: labelBgStyle })) : null;
|
||||||
|
return (React__default.createElement("g", null,
|
||||||
|
React__default.createElement("path", { style: style, d: dAttr, className: "react-flow__edge-path" }),
|
||||||
|
text));
|
||||||
});
|
});
|
||||||
|
|
||||||
var StraightEdge = memo(function (_a) {
|
var StraightEdge = memo(function (_a) {
|
||||||
var sourceX = _a.sourceX, sourceY = _a.sourceY, targetX = _a.targetX, targetY = _a.targetY, _b = _a.style, style = _b === void 0 ? {} : _b;
|
var sourceX = _a.sourceX, sourceY = _a.sourceY, targetX = _a.targetX, targetY = _a.targetY, label = _a.label, labelStyle = _a.labelStyle, labelShowBg = _a.labelShowBg, labelBgStyle = _a.labelBgStyle, _b = _a.style, style = _b === void 0 ? {} : _b;
|
||||||
return (React__default.createElement("path", __assign({}, style, { d: "M " + sourceX + "," + sourceY + "L " + targetX + "," + targetY })));
|
var yOffset = Math.abs(targetY - sourceY) / 2;
|
||||||
|
var centerY = targetY < sourceY ? targetY + yOffset : targetY - yOffset;
|
||||||
|
var xOffset = Math.abs(targetX - sourceX) / 2;
|
||||||
|
var centerX = targetX < sourceX ? targetX + xOffset : targetX - xOffset;
|
||||||
|
var text = label ? (React__default.createElement(EdgeText, { x: centerX, y: centerY, label: label, labelStyle: labelStyle, labelShowBg: labelShowBg, labelBgStyle: labelBgStyle })) : null;
|
||||||
|
return (React__default.createElement("g", null,
|
||||||
|
React__default.createElement("path", { style: style, className: "react-flow__edge-path", d: "M " + sourceX + "," + sourceY + "L " + targetX + "," + targetY }),
|
||||||
|
text));
|
||||||
});
|
});
|
||||||
|
|
||||||
var StepEdge = memo(function (_a) {
|
var StepEdge = memo(function (_a) {
|
||||||
var sourceX = _a.sourceX, sourceY = _a.sourceY, targetX = _a.targetX, targetY = _a.targetY, _b = _a.style, style = _b === void 0 ? {} : _b;
|
var sourceX = _a.sourceX, sourceY = _a.sourceY, targetX = _a.targetX, targetY = _a.targetY, label = _a.label, labelStyle = _a.labelStyle, labelShowBg = _a.labelShowBg, labelBgStyle = _a.labelBgStyle, _b = _a.style, style = _b === void 0 ? {} : _b;
|
||||||
var yOffset = Math.abs(targetY - sourceY) / 2;
|
var yOffset = Math.abs(targetY - sourceY) / 2;
|
||||||
var centerY = targetY < sourceY ? targetY + yOffset : targetY - yOffset;
|
var centerY = targetY < sourceY ? targetY + yOffset : targetY - yOffset;
|
||||||
return (React__default.createElement("path", __assign({}, style, { d: "M " + sourceX + "," + sourceY + "L " + sourceX + "," + centerY + "L " + targetX + "," + centerY + "L " + targetX + "," + targetY })));
|
var xOffset = Math.abs(targetX - sourceX) / 2;
|
||||||
|
var centerX = targetX < sourceX ? targetX + xOffset : targetX - xOffset;
|
||||||
|
var text = label ? (React__default.createElement(EdgeText, { x: centerX, y: centerY, label: label, labelStyle: labelStyle, labelShowBg: labelShowBg, labelBgStyle: labelBgStyle })) : null;
|
||||||
|
return (React__default.createElement("g", null,
|
||||||
|
React__default.createElement("path", { style: style, className: "react-flow__edge-path", d: "M " + sourceX + "," + sourceY + "L " + sourceX + "," + centerY + "L " + targetX + "," + centerY + "L " + targetX + "," + targetY }),
|
||||||
|
text));
|
||||||
});
|
});
|
||||||
|
|
||||||
var wrapEdge = (function (EdgeComponent) {
|
var wrapEdge = (function (EdgeComponent) {
|
||||||
var EdgeWrapper = memo(function (_a) {
|
var EdgeWrapper = memo(function (_a) {
|
||||||
var id = _a.id, source = _a.source, target = _a.target, type = _a.type, animated = _a.animated, selected = _a.selected, onClick = _a.onClick, isInteractive = _a.isInteractive, rest = __rest(_a, ["id", "source", "target", "type", "animated", "selected", "onClick", "isInteractive"]);
|
var id = _a.id, source = _a.source, target = _a.target, type = _a.type, animated = _a.animated, selected = _a.selected, onClick = _a.onClick, isInteractive = _a.isInteractive, label = _a.label, labelStyle = _a.labelStyle, labelShowBg = _a.labelShowBg, labelBgStyle = _a.labelBgStyle, rest = __rest(_a, ["id", "source", "target", "type", "animated", "selected", "onClick", "isInteractive", "label", "labelStyle", "labelShowBg", "labelBgStyle"]);
|
||||||
var edgeClasses = classnames('react-flow__edge', { selected: selected, animated: animated });
|
var edgeClasses = classnames('react-flow__edge', { selected: selected, animated: animated });
|
||||||
var onEdgeClick = function () {
|
var onEdgeClick = function () {
|
||||||
if (!isInteractive) {
|
if (!isInteractive) {
|
||||||
@@ -9311,7 +9350,7 @@ var wrapEdge = (function (EdgeComponent) {
|
|||||||
onClick({ id: id, source: source, target: target, type: type });
|
onClick({ id: id, source: source, target: target, type: type });
|
||||||
};
|
};
|
||||||
return (React__default.createElement("g", { className: edgeClasses, onClick: onEdgeClick },
|
return (React__default.createElement("g", { className: edgeClasses, onClick: onEdgeClick },
|
||||||
React__default.createElement(EdgeComponent, __assign({ id: id, source: source, target: target, type: type, animated: animated, selected: selected, onClick: onClick }, rest))));
|
React__default.createElement(EdgeComponent, __assign({ id: id, source: source, target: target, type: type, animated: animated, selected: selected, onClick: onClick, label: label, labelStyle: labelStyle, labelShowBg: labelShowBg, labelBgStyle: labelBgStyle }, rest))));
|
||||||
});
|
});
|
||||||
EdgeWrapper.displayName = 'EdgeWrapper';
|
EdgeWrapper.displayName = 'EdgeWrapper';
|
||||||
return EdgeWrapper;
|
return EdgeWrapper;
|
||||||
@@ -9359,7 +9398,7 @@ function styleInject(css, ref) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var css_248z = ".react-flow {\n width: 100%;\n height: 100%;\n position: relative;\n overflow: hidden;\n}\n\n.react-flow__renderer {\n width: 100%;\n height: 100%;\n position: absolute;\n}\n\n.react-flow__zoompane {\n width: 100%;\n height: 100%;\n position: absolute;\n top: 0;\n left: 0;\n z-index: 1;\n}\n\n.react-flow__selectionpane {\n width: 100%;\n height: 100%;\n position: absolute;\n top: 0;\n left: 0;\n z-index: 2;\n}\n\n.react-flow__selection {\n position: absolute;\n top: 0;\n left: 0;\n background: rgba(0, 89, 220, 0.08);\n border: 1px dotted rgba(0, 89, 220, 0.8);\n}\n\n.react-flow__edges {\n position: absolute;\n top: 0;\n left: 0;\n pointer-events: none;\n z-index: 2;\n}\n\n.react-flow__edge {\n fill: none;\n stroke: #bbb;\n stroke-width: 2;\n pointer-events: all;\n}\n\n.react-flow__edge.selected {\n stroke: #555;\n }\n\n.react-flow__edge.animated {\n stroke-dasharray: 5;\n -webkit-animation: dashdraw 0.5s linear infinite;\n animation: dashdraw 0.5s linear infinite;\n }\n\n.react-flow__edge.connection {\n stroke: '#ddd';\n pointer-events: none;\n }\n\n@-webkit-keyframes dashdraw {\n from {\n stroke-dashoffset: 10;\n }\n}\n\n@keyframes dashdraw {\n from {\n stroke-dashoffset: 10;\n }\n}\n\n.react-flow__nodes {\n width: 100%;\n height: 100%;\n position: absolute;\n z-index: 3;\n pointer-events: none;\n transform-origin: 0 0;\n}\n\n.is-interactive .react-flow__node {\n cursor: -webkit-grab;\n cursor: grab;\n }\n\n.is-interactive .react-flow__node:hover > * {\n box-shadow: 0 1px 5px 2px rgba(0, 0, 0, 0.08);\n }\n\n.is-interactive .react-flow__handle {\n cursor: crosshair;\n }\n\n.react-flow__node {\n position: absolute;\n color: #222;\n font-family: sans-serif;\n font-size: 12px;\n text-align: center;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n pointer-events: all;\n transform-origin: 0 0;\n}\n\n.react-flow__node.selected > * {\n box-shadow: 0 0 0 2px #555;\n }\n\n.react-flow__handle {\n position: absolute;\n width: 10px;\n height: 8px;\n background: rgba(255, 255, 255, 0.4);\n}\n\n.react-flow__handle.bottom {\n top: auto;\n left: 50%;\n bottom: 0;\n transform: translate(-50%, 0);\n }\n\n.react-flow__handle.top {\n left: 50%;\n top: 0;\n transform: translate(-50%, 0);\n }\n\n.react-flow__handle.left {\n top: 50%;\n left: 0;\n transform: translate(0, -50%);\n }\n\n.react-flow__handle.right {\n right: 0;\n top: 50%;\n transform: translate(0, -50%);\n }\n\n.react-flow__nodesselection {\n z-index: 3;\n position: absolute;\n width: 100%;\n height: 100%;\n top: 0;\n left: 0;\n transform-origin: left top;\n pointer-events: none;\n}\n\n.react-flow__nodesselection-rect {\n position: absolute;\n background: rgba(0, 89, 220, 0.08);\n border: 1px dotted rgba(0, 89, 220, 0.8);\n pointer-events: all;\n }\n\n.react-flow__controls {\n box-shadow: 0 0 2px 1px rgba(0, 0, 0, 0.08);\n}\n\n.react-flow__controls-button {\n background: #fefefe;\n border-bottom: 1px solid #eee;\n display: flex;\n justify-content: center;\n align-items: center;\n width: 16px;\n height: 16px;\n cursor: pointer;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n padding: 5px;\n }\n\n.react-flow__controls-button svg {\n width: 100%;\n }\n\n.react-flow__controls-button:hover {\n background: #f4f4f4;\n }\n";
|
var css_248z = ".react-flow {\n width: 100%;\n height: 100%;\n position: relative;\n overflow: hidden;\n}\n\n.react-flow__renderer {\n width: 100%;\n height: 100%;\n position: absolute;\n}\n\n.react-flow__zoompane {\n width: 100%;\n height: 100%;\n position: absolute;\n top: 0;\n left: 0;\n z-index: 1;\n}\n\n.react-flow__selectionpane {\n width: 100%;\n height: 100%;\n position: absolute;\n top: 0;\n left: 0;\n z-index: 2;\n}\n\n.react-flow__selection {\n position: absolute;\n top: 0;\n left: 0;\n background: rgba(0, 89, 220, 0.08);\n border: 1px dotted rgba(0, 89, 220, 0.8);\n}\n\n.react-flow__edges {\n position: absolute;\n top: 0;\n left: 0;\n pointer-events: none;\n z-index: 2;\n}\n\n.react-flow__edge {\n pointer-events: all;\n}\n\n.react-flow__edge.animated path {\n stroke-dasharray: 5;\n -webkit-animation: dashdraw 0.5s linear infinite;\n animation: dashdraw 0.5s linear infinite;\n }\n\n.react-flow__edge.connection {\n stroke: '#ddd';\n pointer-events: none;\n }\n\n.react-flow__edge-path {\n fill: none;\n stroke: #bbb;\n stroke-width: 2;\n}\n\n.react-flow__edge-path.selected {\n stroke: #555;\n }\n\n.react-flow__edge-text {\n font-size: 12px;\n pointer-events: none;\n}\n\n.react-flow__edge-textbg {\n fill: white;\n}\n\n@-webkit-keyframes dashdraw {\n from {\n stroke-dashoffset: 10;\n }\n}\n\n@keyframes dashdraw {\n from {\n stroke-dashoffset: 10;\n }\n}\n\n.react-flow__nodes {\n width: 100%;\n height: 100%;\n position: absolute;\n z-index: 3;\n pointer-events: none;\n transform-origin: 0 0;\n}\n\n.is-interactive .react-flow__node {\n cursor: -webkit-grab;\n cursor: grab;\n }\n\n.is-interactive .react-flow__node:hover > * {\n box-shadow: 0 1px 5px 2px rgba(0, 0, 0, 0.08);\n }\n\n.is-interactive .react-flow__handle {\n cursor: crosshair;\n }\n\n.react-flow__node {\n position: absolute;\n color: #222;\n font-family: sans-serif;\n font-size: 12px;\n text-align: center;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n pointer-events: all;\n transform-origin: 0 0;\n}\n\n.react-flow__node.selected > * {\n box-shadow: 0 0 0 2px #555;\n }\n\n.react-flow__handle {\n position: absolute;\n width: 10px;\n height: 8px;\n background: rgba(255, 255, 255, 0.4);\n}\n\n.react-flow__handle.bottom {\n top: auto;\n left: 50%;\n bottom: 0;\n transform: translate(-50%, 0);\n }\n\n.react-flow__handle.top {\n left: 50%;\n top: 0;\n transform: translate(-50%, 0);\n }\n\n.react-flow__handle.left {\n top: 50%;\n left: 0;\n transform: translate(0, -50%);\n }\n\n.react-flow__handle.right {\n right: 0;\n top: 50%;\n transform: translate(0, -50%);\n }\n\n.react-flow__nodesselection {\n z-index: 3;\n position: absolute;\n width: 100%;\n height: 100%;\n top: 0;\n left: 0;\n transform-origin: left top;\n pointer-events: none;\n}\n\n.react-flow__nodesselection-rect {\n position: absolute;\n background: rgba(0, 89, 220, 0.08);\n border: 1px dotted rgba(0, 89, 220, 0.8);\n pointer-events: all;\n }\n\n.react-flow__controls {\n box-shadow: 0 0 2px 1px rgba(0, 0, 0, 0.08);\n}\n\n.react-flow__controls-button {\n background: #fefefe;\n border-bottom: 1px solid #eee;\n display: flex;\n justify-content: center;\n align-items: center;\n width: 16px;\n height: 16px;\n cursor: pointer;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n padding: 5px;\n }\n\n.react-flow__controls-button svg {\n width: 100%;\n }\n\n.react-flow__controls-button:hover {\n background: #f4f4f4;\n }\n";
|
||||||
styleInject(css_248z);
|
styleInject(css_248z);
|
||||||
|
|
||||||
var ReactFlow = function (_a) {
|
var ReactFlow = function (_a) {
|
||||||
|
|||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+51
-12
@@ -6903,7 +6903,7 @@ function renderEdge(edge, props, nodes, selectedElements, isInteractive) {
|
|||||||
var targetPosition = targetHandle ? targetHandle.position : Position.Top;
|
var targetPosition = targetHandle ? targetHandle.position : Position.Top;
|
||||||
var _c = getEdgePositions(sourceNode, sourceHandle, sourcePosition, targetNode, targetHandle, targetPosition), sourceX = _c.sourceX, sourceY = _c.sourceY, targetX = _c.targetX, targetY = _c.targetY;
|
var _c = getEdgePositions(sourceNode, sourceHandle, sourcePosition, targetNode, targetHandle, targetPosition), sourceX = _c.sourceX, sourceY = _c.sourceY, targetX = _c.targetX, targetY = _c.targetY;
|
||||||
var isSelected = selectedElements.some(function (elm) { return isEdge(elm) && elm.source === sourceId && elm.target === targetId; });
|
var isSelected = selectedElements.some(function (elm) { return isEdge(elm) && elm.source === sourceId && elm.target === targetId; });
|
||||||
return (React__default.createElement(EdgeComponent, { key: edge.id, id: edge.id, type: edge.type, onClick: props.onElementClick, selected: isSelected, animated: edge.animated, style: edge.style, source: sourceId, target: targetId, sourceHandleId: sourceHandleId, targetHandleId: targetHandleId, sourceX: sourceX, sourceY: sourceY, targetX: targetX, targetY: targetY, sourcePosition: sourcePosition, targetPosition: targetPosition, isInteractive: isInteractive }));
|
return (React__default.createElement(EdgeComponent, { key: edge.id, id: edge.id, type: edge.type, onClick: props.onElementClick, selected: isSelected, animated: edge.animated, label: edge.label, labelStyle: edge.labelStyle, labelShowBg: edge.labelShowBg, labelBgStyle: edge.labelBgStyle, style: edge.style, source: sourceId, target: targetId, sourceHandleId: sourceHandleId, targetHandleId: targetHandleId, sourceX: sourceX, sourceY: sourceY, targetX: targetX, targetY: targetY, sourcePosition: sourcePosition, targetPosition: targetPosition, isInteractive: isInteractive }));
|
||||||
}
|
}
|
||||||
var EdgeRenderer = React.memo(function (props) {
|
var EdgeRenderer = React.memo(function (props) {
|
||||||
var _a = useStoreState$1(function (s) { return ({
|
var _a = useStoreState$1(function (s) { return ({
|
||||||
@@ -9277,38 +9277,77 @@ function createNodeTypes(nodeTypes) {
|
|||||||
return __assign(__assign({}, standardTypes), specialTypes);
|
return __assign(__assign({}, standardTypes), specialTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var textBgPadding = 2;
|
||||||
|
var EdgeText = React.memo(function (_a) {
|
||||||
|
var x = _a.x, y = _a.y, label = _a.label, _b = _a.labelStyle, labelStyle = _b === void 0 ? {} : _b, _c = _a.labelShowBg, labelShowBg = _c === void 0 ? true : _c, _d = _a.labelBgStyle, labelBgStyle = _d === void 0 ? {} : _d;
|
||||||
|
var edgeRef = React.useRef(null);
|
||||||
|
var _e = React.useState({ x: 0, y: 0, width: 0, height: 0 }), edgeTextBbox = _e[0], setEdgeTextBbox = _e[1];
|
||||||
|
React.useEffect(function () {
|
||||||
|
if (edgeRef.current) {
|
||||||
|
var textBbox = edgeRef.current.getBBox();
|
||||||
|
setEdgeTextBbox({
|
||||||
|
x: textBbox.x,
|
||||||
|
y: textBbox.y,
|
||||||
|
width: textBbox.width,
|
||||||
|
height: textBbox.height,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
if (typeof label === 'undefined' || !label) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return (React__default.createElement("g", { transform: "translate(" + (x - edgeTextBbox.width / 2) + " " + (y - edgeTextBbox.height / 2) + ")" },
|
||||||
|
labelShowBg && (React__default.createElement("rect", { width: edgeTextBbox.width + 2 * textBgPadding, x: -textBgPadding, y: -textBgPadding, height: edgeTextBbox.height + 2 * textBgPadding, className: "react-flow__edge-textbg", style: labelBgStyle })),
|
||||||
|
React__default.createElement("text", { className: "react-flow__edge-text", y: edgeTextBbox.height / 2, dy: "0.3em", ref: edgeRef, style: labelStyle }, label)));
|
||||||
|
});
|
||||||
|
|
||||||
var BezierEdge = React.memo(function (_a) {
|
var BezierEdge = React.memo(function (_a) {
|
||||||
var sourceX = _a.sourceX, sourceY = _a.sourceY, targetX = _a.targetX, targetY = _a.targetY, _b = _a.sourcePosition, sourcePosition = _b === void 0 ? Position.Bottom : _b, _c = _a.targetPosition, targetPosition = _c === void 0 ? Position.Top : _c, _d = _a.style, style = _d === void 0 ? {} : _d;
|
var sourceX = _a.sourceX, sourceY = _a.sourceY, targetX = _a.targetX, targetY = _a.targetY, _b = _a.sourcePosition, sourcePosition = _b === void 0 ? Position.Bottom : _b, _c = _a.targetPosition, targetPosition = _c === void 0 ? Position.Top : _c, label = _a.label, labelStyle = _a.labelStyle, labelShowBg = _a.labelShowBg, labelBgStyle = _a.labelBgStyle, _d = _a.style, style = _d === void 0 ? {} : _d;
|
||||||
var yOffset = Math.abs(targetY - sourceY) / 2;
|
var yOffset = Math.abs(targetY - sourceY) / 2;
|
||||||
var centerY = targetY < sourceY ? targetY + yOffset : targetY - yOffset;
|
var centerY = targetY < sourceY ? targetY + yOffset : targetY - yOffset;
|
||||||
|
var xOffset = Math.abs(targetX - sourceX) / 2;
|
||||||
|
var centerX = targetX < sourceX ? targetX + xOffset : targetX - xOffset;
|
||||||
var dAttr = "M" + sourceX + "," + sourceY + " C" + sourceX + "," + centerY + " " + targetX + "," + centerY + " " + targetX + "," + targetY;
|
var dAttr = "M" + sourceX + "," + sourceY + " C" + sourceX + "," + centerY + " " + targetX + "," + centerY + " " + targetX + "," + targetY;
|
||||||
var leftAndRight = [Position.Left, Position.Right];
|
var leftAndRight = [Position.Left, Position.Right];
|
||||||
if (leftAndRight.includes(sourcePosition) && leftAndRight.includes(targetPosition)) {
|
if (leftAndRight.includes(sourcePosition) && leftAndRight.includes(targetPosition)) {
|
||||||
var xOffset = Math.abs(targetX - sourceX) / 2;
|
|
||||||
var 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 (leftAndRight.includes(sourcePosition) || leftAndRight.includes(targetPosition)) {
|
else if (leftAndRight.includes(sourcePosition) || leftAndRight.includes(targetPosition)) {
|
||||||
dAttr = "M" + sourceX + "," + sourceY + " C" + sourceX + "," + targetY + " " + sourceX + "," + targetY + " " + targetX + "," + targetY;
|
dAttr = "M" + sourceX + "," + sourceY + " C" + sourceX + "," + targetY + " " + sourceX + "," + targetY + " " + targetX + "," + targetY;
|
||||||
}
|
}
|
||||||
return React__default.createElement("path", __assign({}, style, { d: dAttr }));
|
var text = label ? (React__default.createElement(EdgeText, { x: centerX, y: centerY, label: label, labelStyle: labelStyle, labelShowBg: labelShowBg, labelBgStyle: labelBgStyle })) : null;
|
||||||
|
return (React__default.createElement("g", null,
|
||||||
|
React__default.createElement("path", { style: style, d: dAttr, className: "react-flow__edge-path" }),
|
||||||
|
text));
|
||||||
});
|
});
|
||||||
|
|
||||||
var StraightEdge = React.memo(function (_a) {
|
var StraightEdge = React.memo(function (_a) {
|
||||||
var sourceX = _a.sourceX, sourceY = _a.sourceY, targetX = _a.targetX, targetY = _a.targetY, _b = _a.style, style = _b === void 0 ? {} : _b;
|
var sourceX = _a.sourceX, sourceY = _a.sourceY, targetX = _a.targetX, targetY = _a.targetY, label = _a.label, labelStyle = _a.labelStyle, labelShowBg = _a.labelShowBg, labelBgStyle = _a.labelBgStyle, _b = _a.style, style = _b === void 0 ? {} : _b;
|
||||||
return (React__default.createElement("path", __assign({}, style, { d: "M " + sourceX + "," + sourceY + "L " + targetX + "," + targetY })));
|
var yOffset = Math.abs(targetY - sourceY) / 2;
|
||||||
|
var centerY = targetY < sourceY ? targetY + yOffset : targetY - yOffset;
|
||||||
|
var xOffset = Math.abs(targetX - sourceX) / 2;
|
||||||
|
var centerX = targetX < sourceX ? targetX + xOffset : targetX - xOffset;
|
||||||
|
var text = label ? (React__default.createElement(EdgeText, { x: centerX, y: centerY, label: label, labelStyle: labelStyle, labelShowBg: labelShowBg, labelBgStyle: labelBgStyle })) : null;
|
||||||
|
return (React__default.createElement("g", null,
|
||||||
|
React__default.createElement("path", { style: style, className: "react-flow__edge-path", d: "M " + sourceX + "," + sourceY + "L " + targetX + "," + targetY }),
|
||||||
|
text));
|
||||||
});
|
});
|
||||||
|
|
||||||
var StepEdge = React.memo(function (_a) {
|
var StepEdge = React.memo(function (_a) {
|
||||||
var sourceX = _a.sourceX, sourceY = _a.sourceY, targetX = _a.targetX, targetY = _a.targetY, _b = _a.style, style = _b === void 0 ? {} : _b;
|
var sourceX = _a.sourceX, sourceY = _a.sourceY, targetX = _a.targetX, targetY = _a.targetY, label = _a.label, labelStyle = _a.labelStyle, labelShowBg = _a.labelShowBg, labelBgStyle = _a.labelBgStyle, _b = _a.style, style = _b === void 0 ? {} : _b;
|
||||||
var yOffset = Math.abs(targetY - sourceY) / 2;
|
var yOffset = Math.abs(targetY - sourceY) / 2;
|
||||||
var centerY = targetY < sourceY ? targetY + yOffset : targetY - yOffset;
|
var centerY = targetY < sourceY ? targetY + yOffset : targetY - yOffset;
|
||||||
return (React__default.createElement("path", __assign({}, style, { d: "M " + sourceX + "," + sourceY + "L " + sourceX + "," + centerY + "L " + targetX + "," + centerY + "L " + targetX + "," + targetY })));
|
var xOffset = Math.abs(targetX - sourceX) / 2;
|
||||||
|
var centerX = targetX < sourceX ? targetX + xOffset : targetX - xOffset;
|
||||||
|
var text = label ? (React__default.createElement(EdgeText, { x: centerX, y: centerY, label: label, labelStyle: labelStyle, labelShowBg: labelShowBg, labelBgStyle: labelBgStyle })) : null;
|
||||||
|
return (React__default.createElement("g", null,
|
||||||
|
React__default.createElement("path", { style: style, className: "react-flow__edge-path", d: "M " + sourceX + "," + sourceY + "L " + sourceX + "," + centerY + "L " + targetX + "," + centerY + "L " + targetX + "," + targetY }),
|
||||||
|
text));
|
||||||
});
|
});
|
||||||
|
|
||||||
var wrapEdge = (function (EdgeComponent) {
|
var wrapEdge = (function (EdgeComponent) {
|
||||||
var EdgeWrapper = React.memo(function (_a) {
|
var EdgeWrapper = React.memo(function (_a) {
|
||||||
var id = _a.id, source = _a.source, target = _a.target, type = _a.type, animated = _a.animated, selected = _a.selected, onClick = _a.onClick, isInteractive = _a.isInteractive, rest = __rest(_a, ["id", "source", "target", "type", "animated", "selected", "onClick", "isInteractive"]);
|
var id = _a.id, source = _a.source, target = _a.target, type = _a.type, animated = _a.animated, selected = _a.selected, onClick = _a.onClick, isInteractive = _a.isInteractive, label = _a.label, labelStyle = _a.labelStyle, labelShowBg = _a.labelShowBg, labelBgStyle = _a.labelBgStyle, rest = __rest(_a, ["id", "source", "target", "type", "animated", "selected", "onClick", "isInteractive", "label", "labelStyle", "labelShowBg", "labelBgStyle"]);
|
||||||
var edgeClasses = classnames('react-flow__edge', { selected: selected, animated: animated });
|
var edgeClasses = classnames('react-flow__edge', { selected: selected, animated: animated });
|
||||||
var onEdgeClick = function () {
|
var onEdgeClick = function () {
|
||||||
if (!isInteractive) {
|
if (!isInteractive) {
|
||||||
@@ -9318,7 +9357,7 @@ var wrapEdge = (function (EdgeComponent) {
|
|||||||
onClick({ id: id, source: source, target: target, type: type });
|
onClick({ id: id, source: source, target: target, type: type });
|
||||||
};
|
};
|
||||||
return (React__default.createElement("g", { className: edgeClasses, onClick: onEdgeClick },
|
return (React__default.createElement("g", { className: edgeClasses, onClick: onEdgeClick },
|
||||||
React__default.createElement(EdgeComponent, __assign({ id: id, source: source, target: target, type: type, animated: animated, selected: selected, onClick: onClick }, rest))));
|
React__default.createElement(EdgeComponent, __assign({ id: id, source: source, target: target, type: type, animated: animated, selected: selected, onClick: onClick, label: label, labelStyle: labelStyle, labelShowBg: labelShowBg, labelBgStyle: labelBgStyle }, rest))));
|
||||||
});
|
});
|
||||||
EdgeWrapper.displayName = 'EdgeWrapper';
|
EdgeWrapper.displayName = 'EdgeWrapper';
|
||||||
return EdgeWrapper;
|
return EdgeWrapper;
|
||||||
@@ -9366,7 +9405,7 @@ function styleInject(css, ref) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var css_248z = ".react-flow {\n width: 100%;\n height: 100%;\n position: relative;\n overflow: hidden;\n}\n\n.react-flow__renderer {\n width: 100%;\n height: 100%;\n position: absolute;\n}\n\n.react-flow__zoompane {\n width: 100%;\n height: 100%;\n position: absolute;\n top: 0;\n left: 0;\n z-index: 1;\n}\n\n.react-flow__selectionpane {\n width: 100%;\n height: 100%;\n position: absolute;\n top: 0;\n left: 0;\n z-index: 2;\n}\n\n.react-flow__selection {\n position: absolute;\n top: 0;\n left: 0;\n background: rgba(0, 89, 220, 0.08);\n border: 1px dotted rgba(0, 89, 220, 0.8);\n}\n\n.react-flow__edges {\n position: absolute;\n top: 0;\n left: 0;\n pointer-events: none;\n z-index: 2;\n}\n\n.react-flow__edge {\n fill: none;\n stroke: #bbb;\n stroke-width: 2;\n pointer-events: all;\n}\n\n.react-flow__edge.selected {\n stroke: #555;\n }\n\n.react-flow__edge.animated {\n stroke-dasharray: 5;\n -webkit-animation: dashdraw 0.5s linear infinite;\n animation: dashdraw 0.5s linear infinite;\n }\n\n.react-flow__edge.connection {\n stroke: '#ddd';\n pointer-events: none;\n }\n\n@-webkit-keyframes dashdraw {\n from {\n stroke-dashoffset: 10;\n }\n}\n\n@keyframes dashdraw {\n from {\n stroke-dashoffset: 10;\n }\n}\n\n.react-flow__nodes {\n width: 100%;\n height: 100%;\n position: absolute;\n z-index: 3;\n pointer-events: none;\n transform-origin: 0 0;\n}\n\n.is-interactive .react-flow__node {\n cursor: -webkit-grab;\n cursor: grab;\n }\n\n.is-interactive .react-flow__node:hover > * {\n box-shadow: 0 1px 5px 2px rgba(0, 0, 0, 0.08);\n }\n\n.is-interactive .react-flow__handle {\n cursor: crosshair;\n }\n\n.react-flow__node {\n position: absolute;\n color: #222;\n font-family: sans-serif;\n font-size: 12px;\n text-align: center;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n pointer-events: all;\n transform-origin: 0 0;\n}\n\n.react-flow__node.selected > * {\n box-shadow: 0 0 0 2px #555;\n }\n\n.react-flow__handle {\n position: absolute;\n width: 10px;\n height: 8px;\n background: rgba(255, 255, 255, 0.4);\n}\n\n.react-flow__handle.bottom {\n top: auto;\n left: 50%;\n bottom: 0;\n transform: translate(-50%, 0);\n }\n\n.react-flow__handle.top {\n left: 50%;\n top: 0;\n transform: translate(-50%, 0);\n }\n\n.react-flow__handle.left {\n top: 50%;\n left: 0;\n transform: translate(0, -50%);\n }\n\n.react-flow__handle.right {\n right: 0;\n top: 50%;\n transform: translate(0, -50%);\n }\n\n.react-flow__nodesselection {\n z-index: 3;\n position: absolute;\n width: 100%;\n height: 100%;\n top: 0;\n left: 0;\n transform-origin: left top;\n pointer-events: none;\n}\n\n.react-flow__nodesselection-rect {\n position: absolute;\n background: rgba(0, 89, 220, 0.08);\n border: 1px dotted rgba(0, 89, 220, 0.8);\n pointer-events: all;\n }\n\n.react-flow__controls {\n box-shadow: 0 0 2px 1px rgba(0, 0, 0, 0.08);\n}\n\n.react-flow__controls-button {\n background: #fefefe;\n border-bottom: 1px solid #eee;\n display: flex;\n justify-content: center;\n align-items: center;\n width: 16px;\n height: 16px;\n cursor: pointer;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n padding: 5px;\n }\n\n.react-flow__controls-button svg {\n width: 100%;\n }\n\n.react-flow__controls-button:hover {\n background: #f4f4f4;\n }\n";
|
var css_248z = ".react-flow {\n width: 100%;\n height: 100%;\n position: relative;\n overflow: hidden;\n}\n\n.react-flow__renderer {\n width: 100%;\n height: 100%;\n position: absolute;\n}\n\n.react-flow__zoompane {\n width: 100%;\n height: 100%;\n position: absolute;\n top: 0;\n left: 0;\n z-index: 1;\n}\n\n.react-flow__selectionpane {\n width: 100%;\n height: 100%;\n position: absolute;\n top: 0;\n left: 0;\n z-index: 2;\n}\n\n.react-flow__selection {\n position: absolute;\n top: 0;\n left: 0;\n background: rgba(0, 89, 220, 0.08);\n border: 1px dotted rgba(0, 89, 220, 0.8);\n}\n\n.react-flow__edges {\n position: absolute;\n top: 0;\n left: 0;\n pointer-events: none;\n z-index: 2;\n}\n\n.react-flow__edge {\n pointer-events: all;\n}\n\n.react-flow__edge.animated path {\n stroke-dasharray: 5;\n -webkit-animation: dashdraw 0.5s linear infinite;\n animation: dashdraw 0.5s linear infinite;\n }\n\n.react-flow__edge.connection {\n stroke: '#ddd';\n pointer-events: none;\n }\n\n.react-flow__edge-path {\n fill: none;\n stroke: #bbb;\n stroke-width: 2;\n}\n\n.react-flow__edge-path.selected {\n stroke: #555;\n }\n\n.react-flow__edge-text {\n font-size: 12px;\n pointer-events: none;\n}\n\n.react-flow__edge-textbg {\n fill: white;\n}\n\n@-webkit-keyframes dashdraw {\n from {\n stroke-dashoffset: 10;\n }\n}\n\n@keyframes dashdraw {\n from {\n stroke-dashoffset: 10;\n }\n}\n\n.react-flow__nodes {\n width: 100%;\n height: 100%;\n position: absolute;\n z-index: 3;\n pointer-events: none;\n transform-origin: 0 0;\n}\n\n.is-interactive .react-flow__node {\n cursor: -webkit-grab;\n cursor: grab;\n }\n\n.is-interactive .react-flow__node:hover > * {\n box-shadow: 0 1px 5px 2px rgba(0, 0, 0, 0.08);\n }\n\n.is-interactive .react-flow__handle {\n cursor: crosshair;\n }\n\n.react-flow__node {\n position: absolute;\n color: #222;\n font-family: sans-serif;\n font-size: 12px;\n text-align: center;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n pointer-events: all;\n transform-origin: 0 0;\n}\n\n.react-flow__node.selected > * {\n box-shadow: 0 0 0 2px #555;\n }\n\n.react-flow__handle {\n position: absolute;\n width: 10px;\n height: 8px;\n background: rgba(255, 255, 255, 0.4);\n}\n\n.react-flow__handle.bottom {\n top: auto;\n left: 50%;\n bottom: 0;\n transform: translate(-50%, 0);\n }\n\n.react-flow__handle.top {\n left: 50%;\n top: 0;\n transform: translate(-50%, 0);\n }\n\n.react-flow__handle.left {\n top: 50%;\n left: 0;\n transform: translate(0, -50%);\n }\n\n.react-flow__handle.right {\n right: 0;\n top: 50%;\n transform: translate(0, -50%);\n }\n\n.react-flow__nodesselection {\n z-index: 3;\n position: absolute;\n width: 100%;\n height: 100%;\n top: 0;\n left: 0;\n transform-origin: left top;\n pointer-events: none;\n}\n\n.react-flow__nodesselection-rect {\n position: absolute;\n background: rgba(0, 89, 220, 0.08);\n border: 1px dotted rgba(0, 89, 220, 0.8);\n pointer-events: all;\n }\n\n.react-flow__controls {\n box-shadow: 0 0 2px 1px rgba(0, 0, 0, 0.08);\n}\n\n.react-flow__controls-button {\n background: #fefefe;\n border-bottom: 1px solid #eee;\n display: flex;\n justify-content: center;\n align-items: center;\n width: 16px;\n height: 16px;\n cursor: pointer;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n padding: 5px;\n }\n\n.react-flow__controls-button svg {\n width: 100%;\n }\n\n.react-flow__controls-button:hover {\n background: #f4f4f4;\n }\n";
|
||||||
styleInject(css_248z);
|
styleInject(css_248z);
|
||||||
|
|
||||||
var ReactFlow = function (_a) {
|
var ReactFlow = function (_a) {
|
||||||
|
|||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { EdgeBezierProps } from '../../types';
|
import { EdgeBezierProps } from '../../types';
|
||||||
declare const _default: React.MemoExoticComponent<({ sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, style, }: EdgeBezierProps) => JSX.Element>;
|
declare const _default: React.MemoExoticComponent<({ sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, label, labelStyle, labelShowBg, labelBgStyle, style, }: EdgeBezierProps) => JSX.Element>;
|
||||||
export default _default;
|
export default _default;
|
||||||
|
|||||||
Vendored
+4
@@ -0,0 +1,4 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { EdgeTextProps } from '../../types';
|
||||||
|
declare const _default: React.MemoExoticComponent<({ x, y, label, labelStyle, labelShowBg, labelBgStyle }: EdgeTextProps) => JSX.Element | null>;
|
||||||
|
export default _default;
|
||||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { EdgeProps } from '../../types';
|
import { EdgeProps } from '../../types';
|
||||||
declare const _default: React.MemoExoticComponent<({ sourceX, sourceY, targetX, targetY, style }: EdgeProps) => JSX.Element>;
|
declare const _default: React.MemoExoticComponent<({ sourceX, sourceY, targetX, targetY, label, labelStyle, labelShowBg, labelBgStyle, style }: EdgeProps) => JSX.Element>;
|
||||||
export default _default;
|
export default _default;
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { EdgeProps } from '../../types';
|
import { EdgeProps } from '../../types';
|
||||||
declare const _default: React.MemoExoticComponent<({ sourceX, sourceY, targetX, targetY, style }: EdgeProps) => JSX.Element>;
|
declare const _default: React.MemoExoticComponent<({ sourceX, sourceY, targetX, targetY, label, labelStyle, labelShowBg, labelBgStyle, style }: EdgeProps) => JSX.Element>;
|
||||||
export default _default;
|
export default _default;
|
||||||
|
|||||||
Vendored
+6
-2
@@ -1,14 +1,18 @@
|
|||||||
import React from 'react';
|
import React, { CSSProperties } from 'react';
|
||||||
import { ElementId, Edge, EdgeCompProps } from '../../types';
|
import { ElementId, Edge, EdgeCompProps } from '../../types';
|
||||||
interface EdgeWrapperProps {
|
interface EdgeWrapperProps {
|
||||||
id: ElementId;
|
id: ElementId;
|
||||||
source: ElementId;
|
source: ElementId;
|
||||||
target: ElementId;
|
target: ElementId;
|
||||||
type: any;
|
type: any;
|
||||||
|
label?: string;
|
||||||
|
labelStyle?: CSSProperties;
|
||||||
|
labelShowBg?: boolean;
|
||||||
|
labelBgStyle: CSSProperties;
|
||||||
onClick: (edge: Edge) => void;
|
onClick: (edge: Edge) => void;
|
||||||
animated: boolean;
|
animated: boolean;
|
||||||
selected: boolean;
|
selected: boolean;
|
||||||
isInteractive: boolean;
|
isInteractive: boolean;
|
||||||
}
|
}
|
||||||
declare const _default: (EdgeComponent: React.ComponentType<EdgeCompProps>) => React.MemoExoticComponent<({ id, source, target, type, animated, selected, onClick, isInteractive, ...rest }: EdgeWrapperProps) => JSX.Element>;
|
declare const _default: (EdgeComponent: React.ComponentType<EdgeCompProps>) => React.MemoExoticComponent<({ id, source, target, type, animated, selected, onClick, isInteractive, label, labelStyle, labelShowBg, labelBgStyle, ...rest }: EdgeWrapperProps) => JSX.Element>;
|
||||||
export default _default;
|
export default _default;
|
||||||
|
|||||||
Vendored
+3
-3
@@ -40,9 +40,9 @@ declare const ReactFlow: {
|
|||||||
output: ({ data, style, targetPosition }: import("../../types").NodeProps) => JSX.Element;
|
output: ({ data, style, targetPosition }: import("../../types").NodeProps) => JSX.Element;
|
||||||
};
|
};
|
||||||
edgeTypes: {
|
edgeTypes: {
|
||||||
default: React.MemoExoticComponent<({ sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, style, }: import("../../types").EdgeBezierProps) => JSX.Element>;
|
default: React.MemoExoticComponent<({ sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, label, labelStyle, labelShowBg, labelBgStyle, style, }: import("../../types").EdgeBezierProps) => JSX.Element>;
|
||||||
straight: React.MemoExoticComponent<({ sourceX, sourceY, targetX, targetY, style }: import("../../types").EdgeProps) => JSX.Element>;
|
straight: React.MemoExoticComponent<({ sourceX, sourceY, targetX, targetY, label, labelStyle, labelShowBg, labelBgStyle, style }: import("../../types").EdgeProps) => JSX.Element>;
|
||||||
step: React.MemoExoticComponent<({ sourceX, sourceY, targetX, targetY, style }: import("../../types").EdgeProps) => JSX.Element>;
|
step: React.MemoExoticComponent<({ sourceX, sourceY, targetX, targetY, label, labelStyle, labelShowBg, labelBgStyle, style }: import("../../types").EdgeProps) => JSX.Element>;
|
||||||
};
|
};
|
||||||
connectionLineType: string;
|
connectionLineType: string;
|
||||||
connectionLineStyle: {};
|
connectionLineStyle: {};
|
||||||
|
|||||||
Vendored
+23
-3
@@ -1,4 +1,4 @@
|
|||||||
import { CSSProperties, SVGAttributes } from 'react';
|
import { CSSProperties } from 'react';
|
||||||
export declare type ElementId = string;
|
export declare type ElementId = string;
|
||||||
export declare type Elements = Array<Node | Edge>;
|
export declare type Elements = Array<Node | Edge>;
|
||||||
export declare type Transform = [number, number, number];
|
export declare type Transform = [number, number, number];
|
||||||
@@ -51,7 +51,11 @@ export interface Edge {
|
|||||||
type?: string;
|
type?: string;
|
||||||
source: ElementId;
|
source: ElementId;
|
||||||
target: ElementId;
|
target: ElementId;
|
||||||
style?: SVGAttributes<{}>;
|
label?: string;
|
||||||
|
labelStyle?: CSSProperties;
|
||||||
|
labelShowBg?: boolean;
|
||||||
|
labelBgStyle?: CSSProperties;
|
||||||
|
style?: CSSProperties;
|
||||||
animated?: boolean;
|
animated?: boolean;
|
||||||
}
|
}
|
||||||
export interface EdgeProps {
|
export interface EdgeProps {
|
||||||
@@ -59,7 +63,11 @@ export interface EdgeProps {
|
|||||||
sourceY: number;
|
sourceY: number;
|
||||||
targetX: number;
|
targetX: number;
|
||||||
targetY: number;
|
targetY: number;
|
||||||
style?: SVGAttributes<{}>;
|
label?: string;
|
||||||
|
labelStyle?: CSSProperties;
|
||||||
|
labelShowBg?: boolean;
|
||||||
|
labelBgStyle?: CSSProperties;
|
||||||
|
style?: CSSProperties;
|
||||||
}
|
}
|
||||||
export interface EdgeBezierProps extends EdgeProps {
|
export interface EdgeBezierProps extends EdgeProps {
|
||||||
sourcePosition: Position;
|
sourcePosition: Position;
|
||||||
@@ -127,8 +135,20 @@ export interface EdgeCompProps {
|
|||||||
source: ElementId;
|
source: ElementId;
|
||||||
target: ElementId;
|
target: ElementId;
|
||||||
type: any;
|
type: any;
|
||||||
|
label?: string;
|
||||||
|
labelStyle?: CSSProperties;
|
||||||
|
labelShowBg?: boolean;
|
||||||
|
labelBgStyle?: CSSProperties;
|
||||||
onClick?: (edge: Edge) => void;
|
onClick?: (edge: Edge) => void;
|
||||||
animated?: boolean;
|
animated?: boolean;
|
||||||
selected?: boolean;
|
selected?: boolean;
|
||||||
}
|
}
|
||||||
|
export interface EdgeTextProps {
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
label?: string;
|
||||||
|
labelStyle?: CSSProperties;
|
||||||
|
labelShowBg?: boolean;
|
||||||
|
labelBgStyle?: CSSProperties;
|
||||||
|
}
|
||||||
export {};
|
export {};
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ const initialElements = [
|
|||||||
{ id: '2', data: { label: 'Node 2' }, position: { x: 100, y: 100 } },
|
{ id: '2', data: { label: 'Node 2' }, position: { x: 100, y: 100 } },
|
||||||
{ id: '3', data: { label: 'Node 3' }, position: { x: 400, y: 100 } },
|
{ id: '3', data: { label: 'Node 3' }, position: { x: 400, y: 100 } },
|
||||||
{ id: '4', data: { label: 'Node 4' }, position: { x: 400, y: 200 } },
|
{ id: '4', data: { label: 'Node 4' }, position: { x: 400, y: 200 } },
|
||||||
{ id: 'e1-2', source: '1', target: '2', animated: true },
|
{ id: 'e1-2', source: '1', target: '2', animated: true, label: 'edge text' },
|
||||||
{ id: 'e1-3', source: '1', target: '3' },
|
{ id: 'e1-3', source: '1', target: '3' },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
|
||||||
|
import ReactFlow, { removeElements, addEdge, MiniMap, Controls } from 'react-flow-renderer';
|
||||||
|
|
||||||
|
const onNodeDragStop = node => console.log('drag stop', node);
|
||||||
|
const onElementClick = element => console.log('click', element);
|
||||||
|
const onLoad = (graph) => {
|
||||||
|
graph.fitView();
|
||||||
|
};
|
||||||
|
|
||||||
|
const initialElements = [
|
||||||
|
{ id: '1', type: 'input', data: { label: 'Input Node 1' }, position: { x: 250, y: 0 } },
|
||||||
|
{ id: '2', data: { label: 'Node 2' }, position: { x: 150, y: 100 } },
|
||||||
|
{ id: '3', data: { label: 'Node 3' }, position: { x: 250, y: 200 } },
|
||||||
|
{ id: '4', data: { label: 'Node 4' }, position: { x: 400, y: 300 } },
|
||||||
|
{ id: '5', data: { label: 'Node 5' }, position: { x: 450, y: 400 } },
|
||||||
|
{ id: '6', type: 'output', data: { label: 'Output Node 5' }, position: { x: 250, y: 550 } },
|
||||||
|
{ id: '7', type: 'output', data: { label: 'Output Node 6' }, position: { x: 550, y: 550 } },
|
||||||
|
{ id: 'e1-2', source: '1', target: '2', label: 'bezier edge', labelBgStyle: { fillOpacity: 0.75 } },
|
||||||
|
{ id: 'e2-3', source: '2', target: '3', type: 'step', label: 'step edge' },
|
||||||
|
{ id: 'e3-4', source: '3', target: '4', type: 'straight', label: 'straight edge' },
|
||||||
|
{ 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-7', source: '5', target: '7', label: 'label with styled bg', labelBgStyle: { fill: '#eee', fillOpacity: 0.7 } },
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
const EdgesFlow = () => {
|
||||||
|
const [elements, setElements] = useState(initialElements);
|
||||||
|
|
||||||
|
const onElementsRemove = (elementsToRemove) => setElements(els => removeElements(elementsToRemove, els));
|
||||||
|
const onConnect = (params) => setElements(els => addEdge(params, els));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ReactFlow
|
||||||
|
elements={elements}
|
||||||
|
onElementClick={onElementClick}
|
||||||
|
onElementsRemove={onElementsRemove}
|
||||||
|
onConnect={onConnect}
|
||||||
|
onNodeDragStop={onNodeDragStop}
|
||||||
|
style={{ width: '100%', height: '100%' }}
|
||||||
|
onLoad={onLoad}
|
||||||
|
snapToGrid={true}
|
||||||
|
>
|
||||||
|
<MiniMap />
|
||||||
|
<Controls />
|
||||||
|
</ReactFlow>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default EdgesFlow;
|
||||||
@@ -18,13 +18,13 @@ const initialElements = [
|
|||||||
sourcePosition: 'right'
|
sourcePosition: 'right'
|
||||||
},
|
},
|
||||||
{ id: '4', data: { label: 'Node 4' }, position: { x: 500, y: 200 }, targetPosition: 'left' },
|
{ id: '4', data: { label: 'Node 4' }, position: { x: 500, y: 200 }, targetPosition: 'left' },
|
||||||
{ id: '5', type: 'output', data: { label: 'Output Node 5'}, position: { x: 300, y: 300 } },
|
{ id: '5', type: 'output', data: { label: 'Output Node 5' }, position: { x: 300, y: 300 } },
|
||||||
{ id: '6', type: 'output', data: { label: 'Output Node 6' }, position: { x: 600, y: 400 } },
|
{ id: '6', type: 'output', data: { label: 'Output Node 6' }, position: { x: 600, y: 400 } },
|
||||||
{ id: 'e1-2', source: '1', target: '2', animated: true },
|
{ id: 'e1-2', source: '1', target: '2', animated: true, label: 'edge text', labelBgStyle: { fillOpacity: 0.75 } },
|
||||||
{ id: 'e2-3', source: '2', target: '3', animated: true },
|
{ id: 'e2-3', source: '2', target: '3', animated: true },
|
||||||
{ id: 'e3-4', source: '3', target: '4', animated: true },
|
{ id: 'e3-4', source: '3', target: '4', animated: true },
|
||||||
{ id: 'e3-5', source: '4', target: '5', animated: true, type: 'step' },
|
{ id: 'e3-5', source: '4', target: '5', animated: true, type: 'step' },
|
||||||
{ id: 'e5-6b', source: '4', target: '6', type: 'step' },
|
{ id: 'e5-6b', source: '4', target: '6', type: 'step', label: 'styled label', labelStyle: { fill: 'red', fontWeight: 700 } },
|
||||||
]
|
]
|
||||||
|
|
||||||
const RichGraph = () => {
|
const RichGraph = () => {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import CustomNode from './CustomNode';
|
|||||||
import Stress from './Stress';
|
import Stress from './Stress';
|
||||||
import Inactive from './Inactive';
|
import Inactive from './Inactive';
|
||||||
import Empty from './Empty';
|
import Empty from './Empty';
|
||||||
|
import Edges from './Edges';
|
||||||
|
|
||||||
import './index.css';
|
import './index.css';
|
||||||
|
|
||||||
@@ -27,10 +28,14 @@ const routes = [{
|
|||||||
path: '/stress',
|
path: '/stress',
|
||||||
component: Stress,
|
component: Stress,
|
||||||
label: 'Stress'
|
label: 'Stress'
|
||||||
|
}, {
|
||||||
|
path: '/edges',
|
||||||
|
component: Edges,
|
||||||
|
label: 'Edges'
|
||||||
}, {
|
}, {
|
||||||
path: '/empty',
|
path: '/empty',
|
||||||
component: Empty
|
component: Empty
|
||||||
},{
|
}, {
|
||||||
path: '/inactive',
|
path: '/inactive',
|
||||||
component: Inactive
|
component: Inactive
|
||||||
}];
|
}];
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import React, { memo } from 'react';
|
import React, { memo } from 'react';
|
||||||
|
|
||||||
|
import EdgeText from './EdgeText';
|
||||||
import { EdgeBezierProps, Position } from '../../types';
|
import { EdgeBezierProps, Position } from '../../types';
|
||||||
|
|
||||||
export default memo(
|
export default memo(
|
||||||
@@ -10,23 +11,43 @@ export default memo(
|
|||||||
targetY,
|
targetY,
|
||||||
sourcePosition = Position.Bottom,
|
sourcePosition = Position.Bottom,
|
||||||
targetPosition = Position.Top,
|
targetPosition = Position.Top,
|
||||||
|
label,
|
||||||
|
labelStyle,
|
||||||
|
labelShowBg,
|
||||||
|
labelBgStyle,
|
||||||
style = {},
|
style = {},
|
||||||
}: 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;
|
||||||
|
|
||||||
|
const xOffset = Math.abs(targetX - sourceX) / 2;
|
||||||
|
const centerX = targetX < sourceX ? targetX + xOffset : targetX - xOffset;
|
||||||
|
|
||||||
let dAttr = `M${sourceX},${sourceY} C${sourceX},${centerY} ${targetX},${centerY} ${targetX},${targetY}`;
|
let dAttr = `M${sourceX},${sourceY} C${sourceX},${centerY} ${targetX},${centerY} ${targetX},${targetY}`;
|
||||||
|
|
||||||
const leftAndRight = [Position.Left, Position.Right];
|
const leftAndRight = [Position.Left, Position.Right];
|
||||||
if (leftAndRight.includes(sourcePosition) && leftAndRight.includes(targetPosition)) {
|
if (leftAndRight.includes(sourcePosition) && leftAndRight.includes(targetPosition)) {
|
||||||
const xOffset = Math.abs(targetX - sourceX) / 2;
|
|
||||||
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 (leftAndRight.includes(sourcePosition) || leftAndRight.includes(targetPosition)) {
|
} else if (leftAndRight.includes(sourcePosition) || leftAndRight.includes(targetPosition)) {
|
||||||
dAttr = `M${sourceX},${sourceY} C${sourceX},${targetY} ${sourceX},${targetY} ${targetX},${targetY}`;
|
dAttr = `M${sourceX},${sourceY} C${sourceX},${targetY} ${sourceX},${targetY} ${targetX},${targetY}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return <path {...style} d={dAttr} />;
|
const text = label ? (
|
||||||
|
<EdgeText
|
||||||
|
x={centerX}
|
||||||
|
y={centerY}
|
||||||
|
label={label}
|
||||||
|
labelStyle={labelStyle}
|
||||||
|
labelShowBg={labelShowBg}
|
||||||
|
labelBgStyle={labelBgStyle}
|
||||||
|
/>
|
||||||
|
) : null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<g>
|
||||||
|
<path style={style} d={dAttr} className="react-flow__edge-path" />
|
||||||
|
{text}
|
||||||
|
</g>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
import React, { memo, useRef, useState, useEffect } from 'react';
|
||||||
|
|
||||||
|
import { EdgeTextProps, Rect } from '../../types';
|
||||||
|
|
||||||
|
const textBgPadding = 2;
|
||||||
|
|
||||||
|
export default memo(({ x, y, label, labelStyle = {}, labelShowBg = true, labelBgStyle = {} }: EdgeTextProps) => {
|
||||||
|
const edgeRef = useRef<SVGTextElement>(null);
|
||||||
|
const [edgeTextBbox, setEdgeTextBbox] = useState<Rect>({ x: 0, y: 0, width: 0, height: 0 });
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (edgeRef.current) {
|
||||||
|
const textBbox = edgeRef.current.getBBox();
|
||||||
|
setEdgeTextBbox({
|
||||||
|
x: textBbox.x,
|
||||||
|
y: textBbox.y,
|
||||||
|
width: textBbox.width,
|
||||||
|
height: textBbox.height,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
if (typeof label === 'undefined' || !label) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<g transform={`translate(${x - edgeTextBbox.width / 2} ${y - edgeTextBbox.height / 2})`}>
|
||||||
|
{labelShowBg && (
|
||||||
|
<rect
|
||||||
|
width={edgeTextBbox.width + 2 * textBgPadding}
|
||||||
|
x={-textBgPadding}
|
||||||
|
y={-textBgPadding}
|
||||||
|
height={edgeTextBbox.height + 2 * textBgPadding}
|
||||||
|
className="react-flow__edge-textbg"
|
||||||
|
style={labelBgStyle}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<text className="react-flow__edge-text" y={edgeTextBbox.height / 2} dy="0.3em" ref={edgeRef} style={labelStyle}>
|
||||||
|
{label}
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
);
|
||||||
|
});
|
||||||
@@ -1,17 +1,36 @@
|
|||||||
import React, { memo } from 'react';
|
import React, { memo } from 'react';
|
||||||
|
|
||||||
|
import EdgeText from './EdgeText';
|
||||||
import { EdgeProps } from '../../types';
|
import { EdgeProps } from '../../types';
|
||||||
|
|
||||||
export default memo(
|
export default memo(
|
||||||
({ sourceX, sourceY, targetX, targetY, style = {} }: EdgeProps) => {
|
({ sourceX, sourceY, targetX, targetY, label, labelStyle, labelShowBg, labelBgStyle, style = {} }: 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;
|
||||||
|
|
||||||
return (
|
const xOffset = Math.abs(targetX - sourceX) / 2;
|
||||||
<path
|
const centerX = targetX < sourceX ? targetX + xOffset : targetX - xOffset;
|
||||||
{...style}
|
|
||||||
d={`M ${sourceX},${sourceY}L ${sourceX},${centerY}L ${targetX},${centerY}L ${targetX},${targetY}`}
|
const text = label ? (
|
||||||
|
<EdgeText
|
||||||
|
x={centerX}
|
||||||
|
y={centerY}
|
||||||
|
label={label}
|
||||||
|
labelStyle={labelStyle}
|
||||||
|
labelShowBg={labelShowBg}
|
||||||
|
labelBgStyle={labelBgStyle}
|
||||||
/>
|
/>
|
||||||
|
) : null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<g>
|
||||||
|
<path
|
||||||
|
style={style}
|
||||||
|
className="react-flow__edge-path"
|
||||||
|
d={`M ${sourceX},${sourceY}L ${sourceX},${centerY}L ${targetX},${centerY}L ${targetX},${targetY}`}
|
||||||
|
/>
|
||||||
|
{text}
|
||||||
|
</g>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,11 +1,32 @@
|
|||||||
import React, { memo } from 'react';
|
import React, { memo } from 'react';
|
||||||
|
|
||||||
|
import EdgeText from './EdgeText';
|
||||||
import { EdgeProps } from '../../types';
|
import { EdgeProps } from '../../types';
|
||||||
|
|
||||||
export default memo(
|
export default memo(
|
||||||
({ sourceX, sourceY, targetX, targetY, style = {} }: EdgeProps) => {
|
({ sourceX, sourceY, targetX, targetY, label, labelStyle, labelShowBg, labelBgStyle, style = {} }: 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 text = label ? (
|
||||||
|
<EdgeText
|
||||||
|
x={centerX}
|
||||||
|
y={centerY}
|
||||||
|
label={label}
|
||||||
|
labelStyle={labelStyle}
|
||||||
|
labelShowBg={labelShowBg}
|
||||||
|
labelBgStyle={labelBgStyle}
|
||||||
|
/>
|
||||||
|
) : null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<path {...style} d={`M ${sourceX},${sourceY}L ${targetX},${targetY}`} />
|
<g>
|
||||||
|
<path style={style} className="react-flow__edge-path" d={`M ${sourceX},${sourceY}L ${targetX},${targetY}`} />
|
||||||
|
{text}
|
||||||
|
</g>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { memo, ComponentType } from 'react';
|
import React, { memo, ComponentType, CSSProperties } from 'react';
|
||||||
import cx from 'classnames';
|
import cx from 'classnames';
|
||||||
|
|
||||||
import store from '../../store';
|
import store from '../../store';
|
||||||
@@ -9,6 +9,10 @@ interface EdgeWrapperProps {
|
|||||||
source: ElementId;
|
source: ElementId;
|
||||||
target: ElementId;
|
target: ElementId;
|
||||||
type: any;
|
type: any;
|
||||||
|
label?: string;
|
||||||
|
labelStyle?: CSSProperties;
|
||||||
|
labelShowBg?: boolean;
|
||||||
|
labelBgStyle: CSSProperties;
|
||||||
onClick: (edge: Edge) => void;
|
onClick: (edge: Edge) => void;
|
||||||
animated: boolean;
|
animated: boolean;
|
||||||
selected: boolean;
|
selected: boolean;
|
||||||
@@ -17,7 +21,21 @@ interface EdgeWrapperProps {
|
|||||||
|
|
||||||
export default (EdgeComponent: ComponentType<EdgeCompProps>) => {
|
export default (EdgeComponent: ComponentType<EdgeCompProps>) => {
|
||||||
const EdgeWrapper = memo(
|
const EdgeWrapper = memo(
|
||||||
({ id, source, target, type, animated, selected, onClick, isInteractive, ...rest }: EdgeWrapperProps) => {
|
({
|
||||||
|
id,
|
||||||
|
source,
|
||||||
|
target,
|
||||||
|
type,
|
||||||
|
animated,
|
||||||
|
selected,
|
||||||
|
onClick,
|
||||||
|
isInteractive,
|
||||||
|
label,
|
||||||
|
labelStyle,
|
||||||
|
labelShowBg,
|
||||||
|
labelBgStyle,
|
||||||
|
...rest
|
||||||
|
}: EdgeWrapperProps) => {
|
||||||
const edgeClasses = cx('react-flow__edge', { selected, animated });
|
const edgeClasses = cx('react-flow__edge', { selected, animated });
|
||||||
const onEdgeClick = (): void => {
|
const onEdgeClick = (): void => {
|
||||||
if (!isInteractive) {
|
if (!isInteractive) {
|
||||||
@@ -38,6 +56,10 @@ export default (EdgeComponent: ComponentType<EdgeCompProps>) => {
|
|||||||
animated={animated}
|
animated={animated}
|
||||||
selected={selected}
|
selected={selected}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
|
label={label}
|
||||||
|
labelStyle={labelStyle}
|
||||||
|
labelShowBg={labelShowBg}
|
||||||
|
labelBgStyle={labelBgStyle}
|
||||||
{...rest}
|
{...rest}
|
||||||
/>
|
/>
|
||||||
</g>
|
</g>
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ function getHandle(bounds: HandleElement[], handleId: ElementId | null): HandleE
|
|||||||
if (bounds.length === 1 || !handleId) {
|
if (bounds.length === 1 || !handleId) {
|
||||||
handle = bounds[0];
|
handle = bounds[0];
|
||||||
} else if (handleId) {
|
} else if (handleId) {
|
||||||
handle = bounds.find(d => d.id === handleId);
|
handle = bounds.find((d) => d.id === handleId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return handle;
|
return handle;
|
||||||
@@ -123,8 +123,8 @@ function renderEdge(
|
|||||||
const [sourceId, sourceHandleId] = edge.source.split('__');
|
const [sourceId, sourceHandleId] = edge.source.split('__');
|
||||||
const [targetId, targetHandleId] = edge.target.split('__');
|
const [targetId, targetHandleId] = edge.target.split('__');
|
||||||
|
|
||||||
const sourceNode = nodes.find(n => n.id === sourceId);
|
const sourceNode = nodes.find((n) => n.id === sourceId);
|
||||||
const targetNode = nodes.find(n => n.id === targetId);
|
const targetNode = 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}`);
|
||||||
@@ -155,7 +155,7 @@ function renderEdge(
|
|||||||
);
|
);
|
||||||
|
|
||||||
const isSelected = (selectedElements as Edge[]).some(
|
const isSelected = (selectedElements as Edge[]).some(
|
||||||
elm => isEdge(elm) && elm.source === sourceId && elm.target === targetId
|
(elm) => isEdge(elm) && elm.source === sourceId && elm.target === targetId
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -166,6 +166,10 @@ function renderEdge(
|
|||||||
onClick={props.onElementClick}
|
onClick={props.onElementClick}
|
||||||
selected={isSelected}
|
selected={isSelected}
|
||||||
animated={edge.animated}
|
animated={edge.animated}
|
||||||
|
label={edge.label}
|
||||||
|
labelStyle={edge.labelStyle}
|
||||||
|
labelShowBg={edge.labelShowBg}
|
||||||
|
labelBgStyle={edge.labelBgStyle}
|
||||||
style={edge.style}
|
style={edge.style}
|
||||||
source={sourceId}
|
source={sourceId}
|
||||||
target={targetId}
|
target={targetId}
|
||||||
@@ -191,7 +195,7 @@ const EdgeRenderer = memo((props: EdgeRendererProps) => {
|
|||||||
connectionPosition: { x, y },
|
connectionPosition: { x, y },
|
||||||
selectedElements,
|
selectedElements,
|
||||||
isInteractive,
|
isInteractive,
|
||||||
} = useStoreState(s => ({
|
} = useStoreState((s) => ({
|
||||||
transform: s.transform,
|
transform: s.transform,
|
||||||
edges: s.edges,
|
edges: s.edges,
|
||||||
nodes: s.nodes,
|
nodes: s.nodes,
|
||||||
|
|||||||
+20
-8
@@ -46,16 +46,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.react-flow__edge {
|
.react-flow__edge {
|
||||||
fill: none;
|
|
||||||
stroke: #bbb;
|
|
||||||
stroke-width: 2;
|
|
||||||
pointer-events: all;
|
pointer-events: all;
|
||||||
|
|
||||||
&.selected {
|
&.animated path {
|
||||||
stroke: #555;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.animated {
|
|
||||||
stroke-dasharray: 5;
|
stroke-dasharray: 5;
|
||||||
animation: dashdraw 0.5s linear infinite;
|
animation: dashdraw 0.5s linear infinite;
|
||||||
}
|
}
|
||||||
@@ -66,6 +59,25 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.react-flow__edge-path {
|
||||||
|
fill: none;
|
||||||
|
stroke: #bbb;
|
||||||
|
stroke-width: 2;
|
||||||
|
|
||||||
|
&.selected {
|
||||||
|
stroke: #555;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.react-flow__edge-text {
|
||||||
|
font-size: 12px;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.react-flow__edge-textbg {
|
||||||
|
fill: white;
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes dashdraw {
|
@keyframes dashdraw {
|
||||||
from {
|
from {
|
||||||
stroke-dashoffset: 10;
|
stroke-dashoffset: 10;
|
||||||
|
|||||||
+24
-3
@@ -1,4 +1,4 @@
|
|||||||
import { CSSProperties, SVGAttributes } from 'react';
|
import { CSSProperties } from 'react';
|
||||||
|
|
||||||
export type ElementId = string;
|
export type ElementId = string;
|
||||||
|
|
||||||
@@ -63,7 +63,11 @@ export interface Edge {
|
|||||||
type?: string;
|
type?: string;
|
||||||
source: ElementId;
|
source: ElementId;
|
||||||
target: ElementId;
|
target: ElementId;
|
||||||
style?: SVGAttributes<{}>;
|
label?: string;
|
||||||
|
labelStyle?: CSSProperties;
|
||||||
|
labelShowBg?: boolean;
|
||||||
|
labelBgStyle?: CSSProperties;
|
||||||
|
style?: CSSProperties;
|
||||||
animated?: boolean;
|
animated?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,7 +76,11 @@ export interface EdgeProps {
|
|||||||
sourceY: number;
|
sourceY: number;
|
||||||
targetX: number;
|
targetX: number;
|
||||||
targetY: number;
|
targetY: number;
|
||||||
style?: SVGAttributes<{}>;
|
label?: string;
|
||||||
|
labelStyle?: CSSProperties;
|
||||||
|
labelShowBg?: boolean;
|
||||||
|
labelBgStyle?: CSSProperties;
|
||||||
|
style?: CSSProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface EdgeBezierProps extends EdgeProps {
|
export interface EdgeBezierProps extends EdgeProps {
|
||||||
@@ -151,7 +159,20 @@ export interface EdgeCompProps {
|
|||||||
source: ElementId;
|
source: ElementId;
|
||||||
target: ElementId;
|
target: ElementId;
|
||||||
type: any;
|
type: any;
|
||||||
|
label?: string;
|
||||||
|
labelStyle?: CSSProperties;
|
||||||
|
labelShowBg?: boolean;
|
||||||
|
labelBgStyle?: CSSProperties;
|
||||||
onClick?: (edge: Edge) => void;
|
onClick?: (edge: Edge) => void;
|
||||||
animated?: boolean;
|
animated?: boolean;
|
||||||
selected?: boolean;
|
selected?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface EdgeTextProps {
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
label?: string;
|
||||||
|
labelStyle?: CSSProperties;
|
||||||
|
labelShowBg?: boolean;
|
||||||
|
labelBgStyle?: CSSProperties;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user