@@ -97,6 +97,9 @@ const BasicFlow = () => <ReactFlow elements={elements} />;
|
|||||||
- `onMoveStart()`: called when user starts panning or zooming
|
- `onMoveStart()`: called when user starts panning or zooming
|
||||||
- `onMoveEnd()`: called when user ends panning or zooming
|
- `onMoveEnd()`: called when user ends panning or zooming
|
||||||
- `onSelectionChange(elements: Elements)`: called when user selects one or multiple elements
|
- `onSelectionChange(elements: Elements)`: called when user selects one or multiple elements
|
||||||
|
- `onSelectionDragStart(evt: MouseEvent, nodes: Node[])`: called when user starts to drag a selection
|
||||||
|
- `onSelectionDrag(evt: MouseEvent, nodes: Node[])`: called when user drags a selection
|
||||||
|
- `onSelectionDragStop(evt: MouseEvent, nodes: Node[])`: called when user stops to drag a selection
|
||||||
- `onPaneClick(event: MouseEvent)`: called when user clicks directly on the canvas
|
- `onPaneClick(event: MouseEvent)`: called when user clicks directly on the canvas
|
||||||
- `onPaneContextMenu(event: MouseEvent)`: called when user does a right-click on the canvas
|
- `onPaneContextMenu(event: MouseEvent)`: called when user does a right-click on the canvas
|
||||||
|
|
||||||
@@ -230,6 +233,10 @@ Your custom nodes are wrapped so that the basic functions like dragging or selec
|
|||||||
- `sourcePosition`: string
|
- `sourcePosition`: string
|
||||||
- `targetPosition`: string
|
- `targetPosition`: string
|
||||||
|
|
||||||
|
### Prevent dragging
|
||||||
|
|
||||||
|
If you have controls inside your custom node that should not drag the node you can add the class name `nodrag`.
|
||||||
|
|
||||||
## Handle Component
|
## Handle Component
|
||||||
|
|
||||||
We export a `Handle` component as a helper for your custom nodes:
|
We export a `Handle` component as a helper for your custom nodes:
|
||||||
@@ -422,6 +429,7 @@ const FlowWithMiniMap = () => (
|
|||||||
|
|
||||||
- `nodeColor`: string or function - If you pass a color as a string all nodes will get that color. If you pass a function you can return a color depending on the passed node.
|
- `nodeColor`: string or function - If you pass a color as a string all nodes will get that color. If you pass a function you can return a color depending on the passed node.
|
||||||
- `nodeBorderRadius`: number
|
- `nodeBorderRadius`: number
|
||||||
|
- `nodeClassName`: string or function for adding an additional class to the nodes inside the mini map
|
||||||
- `maskColor`: string
|
- `maskColor`: string
|
||||||
- `style`: css properties
|
- `style`: css properties
|
||||||
- `className`: additional class name
|
- `className`: additional class name
|
||||||
@@ -568,6 +576,11 @@ Returns all direct child nodes of the passed node
|
|||||||
|
|
||||||
`getOutgoers = (node: Node, elements: Elements): Node[]`
|
`getOutgoers = (node: Node, elements: Elements): Node[]`
|
||||||
|
|
||||||
|
### getConnectedEdges
|
||||||
|
|
||||||
|
Returns all edges that are connected to the passed nodes
|
||||||
|
|
||||||
|
`getConnectedEdges = (nodes: Node[], edges: Edge[]): Edge[]`
|
||||||
|
|
||||||
You can use these function as seen in [this example](/example/src/Overview/index.js#L40-L41) or use your own ones.
|
You can use these function as seen in [this example](/example/src/Overview/index.js#L40-L41) or use your own ones.
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ import ReactFlow, { removeElements, addEdge, MiniMap, Controls, Background, isNo
|
|||||||
|
|
||||||
const onNodeDragStart = (event, node) => console.log('drag start', node);
|
const onNodeDragStart = (event, node) => console.log('drag start', node);
|
||||||
const onNodeDragStop = (event, node) => console.log('drag stop', node);
|
const onNodeDragStop = (event, node) => console.log('drag stop', node);
|
||||||
|
const onSelectionDrag = (event, nodes) => console.log('selection drag', nodes);
|
||||||
|
const onSelectionDragStart = (event, nodes) => console.log('selection drag start', nodes);
|
||||||
|
const onSelectionDragStop = (event, nodes) => console.log('selection drag stop', nodes);
|
||||||
const onElementClick = (event, element) => console.log(`${isNode(element) ? 'node' : 'edge'} click:`, element);
|
const onElementClick = (event, element) => console.log(`${isNode(element) ? 'node' : 'edge'} click:`, element);
|
||||||
const onSelectionChange = (elements) => console.log('selection change', elements);
|
const onSelectionChange = (elements) => console.log('selection change', elements);
|
||||||
const onLoad = (reactFlowInstance) => {
|
const onLoad = (reactFlowInstance) => {
|
||||||
@@ -120,6 +123,9 @@ const OverviewFlow = () => {
|
|||||||
onConnect={onConnect}
|
onConnect={onConnect}
|
||||||
onNodeDragStart={onNodeDragStart}
|
onNodeDragStart={onNodeDragStart}
|
||||||
onNodeDragStop={onNodeDragStop}
|
onNodeDragStop={onNodeDragStop}
|
||||||
|
onSelectionDragStart={onSelectionDragStart}
|
||||||
|
onSelectionDrag={onSelectionDrag}
|
||||||
|
onSelectionDragStop={onSelectionDragStop}
|
||||||
onSelectionChange={onSelectionChange}
|
onSelectionChange={onSelectionChange}
|
||||||
onMoveEnd={onMoveEnd}
|
onMoveEnd={onMoveEnd}
|
||||||
onLoad={onLoad}
|
onLoad={onLoad}
|
||||||
|
|||||||
Generated
+69
-70
@@ -57,16 +57,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@babel/core": {
|
"@babel/core": {
|
||||||
"version": "7.11.1",
|
"version": "7.11.4",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.11.1.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.11.4.tgz",
|
||||||
"integrity": "sha512-XqF7F6FWQdKGGWAzGELL+aCO1p+lRY5Tj5/tbT3St1G8NaH70jhhDIKknIZaDans0OQBG5wRAldROLHSt44BgQ==",
|
"integrity": "sha512-5deljj5HlqRXN+5oJTY7Zs37iH3z3b++KjiKtIsJy1NrjOOVSEaJHEetLBhyu0aQOSNNZ/0IuEAan9GzRuDXHg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/code-frame": "^7.10.4",
|
"@babel/code-frame": "^7.10.4",
|
||||||
"@babel/generator": "^7.11.0",
|
"@babel/generator": "^7.11.4",
|
||||||
"@babel/helper-module-transforms": "^7.11.0",
|
"@babel/helper-module-transforms": "^7.11.0",
|
||||||
"@babel/helpers": "^7.10.4",
|
"@babel/helpers": "^7.10.4",
|
||||||
"@babel/parser": "^7.11.1",
|
"@babel/parser": "^7.11.4",
|
||||||
"@babel/template": "^7.10.4",
|
"@babel/template": "^7.10.4",
|
||||||
"@babel/traverse": "^7.11.0",
|
"@babel/traverse": "^7.11.0",
|
||||||
"@babel/types": "^7.11.0",
|
"@babel/types": "^7.11.0",
|
||||||
@@ -90,9 +90,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@babel/generator": {
|
"@babel/generator": {
|
||||||
"version": "7.11.0",
|
"version": "7.11.4",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.4.tgz",
|
||||||
"integrity": "sha512-fEm3Uzw7Mc9Xi//qU20cBKatTfs2aOtKqmvy/Vm7RkJEGFQ4xc9myCfbXxqK//ZS8MR/ciOHw6meGASJuKmDfQ==",
|
"integrity": "sha512-Rn26vueFx0eOoz7iifCN2UHT6rGtnkSGWSoDRIy8jZN3B91PzeSULbswfLoOWuTuAcNwpG/mxy+uCTDnZ9Mp1g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/types": "^7.11.0",
|
"@babel/types": "^7.11.0",
|
||||||
@@ -191,9 +191,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@babel/parser": {
|
"@babel/parser": {
|
||||||
"version": "7.11.3",
|
"version": "7.11.4",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.3.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.4.tgz",
|
||||||
"integrity": "sha512-REo8xv7+sDxkKvoxEywIdsNFiZLybwdI7hcT5uEPyQrSMB4YQ973BfC9OOrD/81MaIjh6UxdulIQXkjmiH3PcA==",
|
"integrity": "sha512-MggwidiH+E9j5Sh8pbrX5sJvMcsqS5o+7iB42M9/k0CD63MjYbdP4nhSh7uB5wnv2/RVzTZFTxzF/kIa5mrCqA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@babel/template": {
|
"@babel/template": {
|
||||||
@@ -1531,9 +1531,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@babel/parser": {
|
"@babel/parser": {
|
||||||
"version": "7.11.3",
|
"version": "7.11.4",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.3.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.4.tgz",
|
||||||
"integrity": "sha512-REo8xv7+sDxkKvoxEywIdsNFiZLybwdI7hcT5uEPyQrSMB4YQ973BfC9OOrD/81MaIjh6UxdulIQXkjmiH3PcA==",
|
"integrity": "sha512-MggwidiH+E9j5Sh8pbrX5sJvMcsqS5o+7iB42M9/k0CD63MjYbdP4nhSh7uB5wnv2/RVzTZFTxzF/kIa5mrCqA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@babel/template": {
|
"@babel/template": {
|
||||||
@@ -4240,9 +4240,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@octokit/types": {
|
"@octokit/types": {
|
||||||
"version": "5.4.0",
|
"version": "5.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-5.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-5.4.1.tgz",
|
||||||
"integrity": "sha512-D/uotqF69M50OIlwMqgyIg9PuLT2daOiBAYF0P40I2ekFA2ESwwBY5dxZe/UhXdPvIbNKDzuZmQrO7rMpuFbcg==",
|
"integrity": "sha512-OlMlSySBJoJ6uozkr/i03nO5dlYQyE05vmQNZhAh9MyO4DPBP88QlwsDVLmVjIMFssvIZB6WO0ctIGMRG+xsJQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/node": ">= 8"
|
"@types/node": ">= 8"
|
||||||
@@ -4277,9 +4277,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@sindresorhus/is": {
|
"@sindresorhus/is": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-3.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-3.1.2.tgz",
|
||||||
"integrity": "sha512-tLnujxFtfH7F+i5ghUfgGlJsvyCKvUnSMFMlWybFdX9/DdX8svb4Zwx1gV0gkkVCHXtmPSetoAR3QlKfOld6Tw==",
|
"integrity": "sha512-JiX9vxoKMmu8Y3Zr2RVathBL1Cdu4Nt4MuNWemt1Nc06A0RAin9c5FArkhGsyMBWfCu4zj+9b+GxtjAnE4qqLQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@svgr/babel-plugin-add-jsx-attribute": {
|
"@svgr/babel-plugin-add-jsx-attribute": {
|
||||||
@@ -6952,70 +6952,69 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"d3-color": {
|
"d3-color": {
|
||||||
"version": "1.4.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/d3-color/-/d3-color-2.0.0.tgz",
|
||||||
"integrity": "sha512-TzNPeJy2+iEepfiL92LAAB7fvnp/dV2YwANPVHdDWmYMm23qIJBYww3qT8I8C1wXrmrg4UWs7BKc2tKIgyjzHg=="
|
"integrity": "sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ=="
|
||||||
},
|
},
|
||||||
"d3-dispatch": {
|
"d3-dispatch": {
|
||||||
"version": "1.0.5",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-1.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-2.0.0.tgz",
|
||||||
"integrity": "sha512-vwKx+lAqB1UuCeklr6Jh1bvC4SZgbSqbkGBLClItFBIYH4vqDJCA7qfoy14lXmJdnBOdxndAMxjCbImJYW7e6g=="
|
"integrity": "sha512-S/m2VsXI7gAti2pBoLClFFTMOO1HTtT0j99AuXLoGFKO6deHDdnv6ZGTxSTTUTgO1zVcv82fCOtDjYK4EECmWA=="
|
||||||
},
|
},
|
||||||
"d3-drag": {
|
"d3-drag": {
|
||||||
"version": "1.2.4",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-1.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-2.0.0.tgz",
|
||||||
"integrity": "sha512-ICPurDETFAelF1CTHdIyiUM4PsyZLaM+7oIBhmyP+cuVjze5vDZ8V//LdOFjg0jGnFIZD/Sfmk0r95PSiu78rw==",
|
"integrity": "sha512-g9y9WbMnF5uqB9qKqwIIa/921RYWzlUDv9Jl1/yONQwxbOfszAWTCm8u7HOTgJgRDXiRZN56cHT9pd24dmXs8w==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"d3-dispatch": "1",
|
"d3-dispatch": "1 - 2",
|
||||||
"d3-selection": "1"
|
"d3-selection": "2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"d3-ease": {
|
"d3-ease": {
|
||||||
"version": "1.0.5",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-1.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-2.0.0.tgz",
|
||||||
"integrity": "sha512-Ct1O//ly5y5lFM9YTdu+ygq7LleSgSE4oj7vUt9tPLHUi8VCV7QoizGpdWRWAwCO9LdYzIrQDg97+hGVdsSGPQ=="
|
"integrity": "sha512-68/n9JWarxXkOWMshcT5IcjbB+agblQUaIsbnXmrzejn2O82n3p2A9R2zEB9HIEFWKFwPAEDDN8gR0VdSAyyAQ=="
|
||||||
},
|
},
|
||||||
"d3-interpolate": {
|
"d3-interpolate": {
|
||||||
"version": "1.3.2",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-1.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz",
|
||||||
"integrity": "sha512-NlNKGopqaz9qM1PXh9gBF1KSCVh+jSFErrSlD/4hybwoNX/gt1d8CDbDW+3i+5UOHhjC6s6nMvRxcuoMVNgL2w==",
|
"integrity": "sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"d3-color": "1"
|
"d3-color": "1 - 2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"d3-selection": {
|
"d3-selection": {
|
||||||
"version": "1.4.2",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-1.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-2.0.0.tgz",
|
||||||
"integrity": "sha512-SJ0BqYihzOjDnnlfyeHT0e30k0K1+5sR3d5fNueCNeuhZTnGw4M4o8mqJchSwgKMXCNFo+e2VTChiSJ0vYtXkg=="
|
"integrity": "sha512-XoGGqhLUN/W14NmaqcO/bb1nqjDAw5WtSYb2X8wiuQWvSZUsUVYsOSkOybUrNvcBjaywBdYPy03eXHMXjk9nZA=="
|
||||||
},
|
},
|
||||||
"d3-timer": {
|
"d3-timer": {
|
||||||
"version": "1.0.9",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-1.0.9.tgz",
|
"resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-2.0.0.tgz",
|
||||||
"integrity": "sha512-rT34J5HnQUHhcLvhSB9GjCkN0Ddd5Y8nCwDBG2u6wQEeYxT/Lf51fTFFkldeib/sE/J0clIe0pnCfs6g/lRbyg=="
|
"integrity": "sha512-TO4VLh0/420Y/9dO3+f9abDEFYeCUr2WZRlxJvbp4HPTQcSylXNiL6yZa9FIUvV1yRiFufl1bszTCLDqv9PWNA=="
|
||||||
},
|
},
|
||||||
"d3-transition": {
|
"d3-transition": {
|
||||||
"version": "1.2.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-2.0.0.tgz",
|
||||||
"integrity": "sha512-VJ7cmX/FPIPJYuaL2r1o1EMHLttvoIuZhhuAlRoOxDzogV8iQS6jYulDm3xEU3TqL80IZIhI551/ebmCMrkvhw==",
|
"integrity": "sha512-42ltAGgJesfQE3u9LuuBHNbGrI/AJjNL2OAUdclE70UE6Vy239GCBEYD38uBPoLeNsOhFStGpPI0BAOV+HMxog==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"d3-color": "1",
|
"d3-color": "1 - 2",
|
||||||
"d3-dispatch": "1",
|
"d3-dispatch": "1 - 2",
|
||||||
"d3-ease": "1",
|
"d3-ease": "1 - 2",
|
||||||
"d3-interpolate": "1",
|
"d3-interpolate": "1 - 2",
|
||||||
"d3-selection": "^1.1.0",
|
"d3-timer": "1 - 2"
|
||||||
"d3-timer": "1"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"d3-zoom": {
|
"d3-zoom": {
|
||||||
"version": "1.8.3",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-1.8.3.tgz",
|
"resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-2.0.0.tgz",
|
||||||
"integrity": "sha512-VoLXTK4wvy1a0JpH2Il+F2CiOhVu7VRXWF5M/LroMIh3/zBAC3WAt7QoIvPibOavVo20hN6/37vwAsdBejLyKQ==",
|
"integrity": "sha512-fFg7aoaEm9/jf+qfstak0IYpnesZLiMX6GZvXtUSdv8RH2o4E2qeelgdU09eKS6wGuiGMfcnMI0nTIqWzRHGpw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"d3-dispatch": "1",
|
"d3-dispatch": "1 - 2",
|
||||||
"d3-drag": "1",
|
"d3-drag": "2",
|
||||||
"d3-interpolate": "1",
|
"d3-interpolate": "1 - 2",
|
||||||
"d3-selection": "1",
|
"d3-selection": "2",
|
||||||
"d3-transition": "1"
|
"d3-transition": "2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dashdash": {
|
"dashdash": {
|
||||||
@@ -11038,9 +11037,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"release-it": {
|
"release-it": {
|
||||||
"version": "13.6.8",
|
"version": "13.6.9",
|
||||||
"resolved": "https://registry.npmjs.org/release-it/-/release-it-13.6.8.tgz",
|
"resolved": "https://registry.npmjs.org/release-it/-/release-it-13.6.9.tgz",
|
||||||
"integrity": "sha512-LY3dZEzAVRBdie0DMG0kdV4DWMTVPM+hvc5O5EmY0qIf+zPuMVu9QXS19La6KBhCI4kVhpwm7VZ8B7YMXTBKLA==",
|
"integrity": "sha512-bZEJBMCHiBPzKVZzCTYaGo+lYpunsX1/LSL1bO5RJ2+7G1glC91G5KIs29zgfHJEQfzE0q3tTEVV+b6gscGKvw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@iarna/toml": "2.2.5",
|
"@iarna/toml": "2.2.5",
|
||||||
@@ -11354,9 +11353,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"rollup": {
|
"rollup": {
|
||||||
"version": "2.26.4",
|
"version": "2.26.5",
|
||||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.26.4.tgz",
|
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.26.5.tgz",
|
||||||
"integrity": "sha512-6+qsGuP0MXGd7vlYmk72utm1MrgZj5GfXibGL+cRkKQ9+ZL/BnFThDl0D5bcl7AqlzMjAQXRAwZX1HVm22M/4Q==",
|
"integrity": "sha512-rCyFG3ZtQdnn9YwfuAVH0l/Om34BdO5lwCA0W6Hq+bNB21dVEBbCRxhaHOmu1G7OBFDWytbzAC104u7rxHwGjA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"fsevents": "~2.1.2"
|
"fsevents": "~2.1.2"
|
||||||
@@ -12364,9 +12363,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"typescript": {
|
"typescript": {
|
||||||
"version": "3.9.7",
|
"version": "4.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.7.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.2.tgz",
|
||||||
"integrity": "sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==",
|
"integrity": "sha512-e4ERvRV2wb+rRZ/IQeb3jm2VxBsirQLpQhdxplZ2MEzGvDkkMmPglecnNDfSUBivMjP93vRbngYYDQqQ/78bcQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"uglify-js": {
|
"uglify-js": {
|
||||||
|
|||||||
+6
-6
@@ -27,15 +27,15 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@welldone-software/why-did-you-render": "^4.3.1",
|
"@welldone-software/why-did-you-render": "^4.3.1",
|
||||||
"classcat": "^4.1.0",
|
"classcat": "^4.1.0",
|
||||||
"d3-selection": "^1.4.2",
|
"d3-selection": "^2.0.0",
|
||||||
"d3-zoom": "^1.8.3",
|
"d3-zoom": "^2.0.0",
|
||||||
"easy-peasy": "^3.3.1",
|
"easy-peasy": "^3.3.1",
|
||||||
"fast-deep-equal": "^3.1.3",
|
"fast-deep-equal": "^3.1.3",
|
||||||
"react-draggable": "^4.4.3",
|
"react-draggable": "^4.4.3",
|
||||||
"resize-observer": "^1.0.0"
|
"resize-observer": "^1.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.11.1",
|
"@babel/core": "^7.11.4",
|
||||||
"@babel/preset-env": "^7.11.0",
|
"@babel/preset-env": "^7.11.0",
|
||||||
"@babel/preset-react": "^7.10.4",
|
"@babel/preset-react": "^7.10.4",
|
||||||
"@svgr/rollup": "^5.4.0",
|
"@svgr/rollup": "^5.4.0",
|
||||||
@@ -51,8 +51,8 @@
|
|||||||
"prettier": "2.0.5",
|
"prettier": "2.0.5",
|
||||||
"prop-types": "^15.7.2",
|
"prop-types": "^15.7.2",
|
||||||
"react": "^16.13.1",
|
"react": "^16.13.1",
|
||||||
"release-it": "^13.6.8",
|
"release-it": "^13.6.9",
|
||||||
"rollup": "^2.26.4",
|
"rollup": "^2.26.5",
|
||||||
"rollup-plugin-babel": "^4.4.0",
|
"rollup-plugin-babel": "^4.4.0",
|
||||||
"rollup-plugin-bundle-size": "^1.0.3",
|
"rollup-plugin-bundle-size": "^1.0.3",
|
||||||
"rollup-plugin-commonjs": "^10.1.0",
|
"rollup-plugin-commonjs": "^10.1.0",
|
||||||
@@ -66,7 +66,7 @@
|
|||||||
"rollup-plugin-typescript2": "^0.27.2",
|
"rollup-plugin-typescript2": "^0.27.2",
|
||||||
"rollup-plugin-uglify": "^6.0.4",
|
"rollup-plugin-uglify": "^6.0.4",
|
||||||
"start-server-and-test": "^1.11.3",
|
"start-server-and-test": "^1.11.3",
|
||||||
"typescript": "^3.9.7"
|
"typescript": "^4.0.2"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": "^16.13.1"
|
"react": "^16.13.1"
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import React, { memo, CSSProperties } from 'react';
|
import React, { memo, CSSProperties } from 'react';
|
||||||
|
import cc from 'classcat';
|
||||||
|
|
||||||
interface MiniMapNodeProps {
|
interface MiniMapNodeProps {
|
||||||
x: number;
|
x: number;
|
||||||
@@ -6,17 +7,18 @@ interface MiniMapNodeProps {
|
|||||||
width: number;
|
width: number;
|
||||||
height: number;
|
height: number;
|
||||||
color: string;
|
color: string;
|
||||||
|
className: string;
|
||||||
borderRadius: number;
|
borderRadius: number;
|
||||||
style?: CSSProperties;
|
style?: CSSProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
const MiniMapNode = ({ x, y, width, height, style, color, borderRadius }: MiniMapNodeProps) => {
|
const MiniMapNode = ({ x, y, width, height, style, color, className, borderRadius }: MiniMapNodeProps) => {
|
||||||
const { background, backgroundColor } = style || {};
|
const { background, backgroundColor } = style || {};
|
||||||
const fill = (color || background || backgroundColor) as string;
|
const fill = (color || background || backgroundColor) as string;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<rect
|
<rect
|
||||||
className="react-flow__minimap-node"
|
className={cc(['react-flow__minimap-node', className])}
|
||||||
x={x}
|
x={x}
|
||||||
y={y}
|
y={y}
|
||||||
rx={borderRadius}
|
rx={borderRadius}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ type StringFunc = (node: Node) => string;
|
|||||||
|
|
||||||
interface MiniMapProps extends React.HTMLAttributes<SVGSVGElement> {
|
interface MiniMapProps extends React.HTMLAttributes<SVGSVGElement> {
|
||||||
nodeColor?: string | StringFunc;
|
nodeColor?: string | StringFunc;
|
||||||
|
nodeClassName?: string | StringFunc;
|
||||||
nodeBorderRadius?: number;
|
nodeBorderRadius?: number;
|
||||||
maskColor?: string;
|
maskColor?: string;
|
||||||
}
|
}
|
||||||
@@ -23,6 +24,7 @@ const MiniMap = ({
|
|||||||
style = { backgroundColor: '#f8f8f8' },
|
style = { backgroundColor: '#f8f8f8' },
|
||||||
className,
|
className,
|
||||||
nodeColor = '#ddd',
|
nodeColor = '#ddd',
|
||||||
|
nodeClassName = '',
|
||||||
nodeBorderRadius = 5,
|
nodeBorderRadius = 5,
|
||||||
maskColor = 'rgba(10, 10, 10, .25)',
|
maskColor = 'rgba(10, 10, 10, .25)',
|
||||||
}: MiniMapProps) => {
|
}: MiniMapProps) => {
|
||||||
@@ -35,6 +37,7 @@ const MiniMap = ({
|
|||||||
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;
|
||||||
|
const nodeClassNameFunc = (nodeClassName instanceof Function ? nodeClassName : () => nodeClassName) as StringFunc;
|
||||||
const hasNodes = nodes && nodes.length;
|
const hasNodes = nodes && nodes.length;
|
||||||
const bb = getRectOfNodes(nodes);
|
const bb = getRectOfNodes(nodes);
|
||||||
const viewBB: Rect = {
|
const viewBB: Rect = {
|
||||||
@@ -73,6 +76,7 @@ const MiniMap = ({
|
|||||||
width={node.__rf.width}
|
width={node.__rf.width}
|
||||||
height={node.__rf.height}
|
height={node.__rf.height}
|
||||||
style={node.style}
|
style={node.style}
|
||||||
|
className={nodeClassNameFunc(node)}
|
||||||
color={nodeColorFunc(node)}
|
color={nodeColorFunc(node)}
|
||||||
borderRadius={nodeBorderRadius}
|
borderRadius={nodeBorderRadius}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
* made a selectio with on or several nodes
|
* made a selectio with on or several nodes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { useState } from 'react';
|
import React, { useState, MouseEvent } from 'react';
|
||||||
import ReactDraggable from 'react-draggable';
|
import ReactDraggable from 'react-draggable';
|
||||||
|
|
||||||
import { useStoreState, useStoreActions } from '../../store/hooks';
|
import { useStoreState, useStoreActions } from '../../store/hooks';
|
||||||
@@ -27,7 +27,13 @@ function getStartPositions(nodes: Node[]): StartPositions {
|
|||||||
}, startPositions);
|
}, startPositions);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default () => {
|
export interface NodesSelectionProps {
|
||||||
|
onSelectionDragStart?: (event: MouseEvent, nodes: Node[]) => void;
|
||||||
|
onSelectionDrag?: (event: MouseEvent, nodes: Node[]) => void;
|
||||||
|
onSelectionDragStop?: (event: MouseEvent, nodes: Node[]) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ({ onSelectionDragStart, onSelectionDrag, onSelectionDragStop }: NodesSelectionProps) => {
|
||||||
const [offset, setOffset] = useState<XYPosition>({ x: 0, y: 0 });
|
const [offset, setOffset] = useState<XYPosition>({ x: 0, y: 0 });
|
||||||
const [startPositions, setStartPositions] = useState<StartPositions>({});
|
const [startPositions, setStartPositions] = useState<StartPositions>({});
|
||||||
|
|
||||||
@@ -61,6 +67,10 @@ export default () => {
|
|||||||
|
|
||||||
const nextStartPositions = getStartPositions(selectedNodes);
|
const nextStartPositions = getStartPositions(selectedNodes);
|
||||||
|
|
||||||
|
if (onSelectionDragStart) {
|
||||||
|
onSelectionDragStart(event, selectedNodes);
|
||||||
|
}
|
||||||
|
|
||||||
if (nextStartPositions) {
|
if (nextStartPositions) {
|
||||||
setOffset({ x: offsetX, y: offsetY });
|
setOffset({ x: offsetX, y: offsetY });
|
||||||
setStartPositions(nextStartPositions);
|
setStartPositions(nextStartPositions);
|
||||||
@@ -74,7 +84,17 @@ export default () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (selectedElements) {
|
if (selectedElements) {
|
||||||
selectedElements.filter(isNode).forEach((node) => {
|
const selectedNodes = selectedElements ? selectedElements.filter(isNode) : [];
|
||||||
|
|
||||||
|
if (onSelectionDrag) {
|
||||||
|
const selectionNodes = selectedNodes.map(
|
||||||
|
(selectedNode) => nodes.find((node) => node.id === selectedNode.id)! as Node
|
||||||
|
);
|
||||||
|
|
||||||
|
onSelectionDrag(event, selectionNodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
selectedNodes.forEach((node) => {
|
||||||
const pos: XYPosition = {
|
const pos: XYPosition = {
|
||||||
x: startPositions[node.id].x + scaledClient.x - selectedNodesBbox.x - offset.x - tX,
|
x: startPositions[node.id].x + scaledClient.x - selectedNodesBbox.x - offset.x - tX,
|
||||||
y: startPositions[node.id].y + scaledClient.y - selectedNodesBbox.y - offset.y - tY,
|
y: startPositions[node.id].y + scaledClient.y - selectedNodesBbox.y - offset.y - tY,
|
||||||
@@ -85,6 +105,16 @@ export default () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const onStop = (event: MouseEvent) => {
|
||||||
|
if (selectedElements && onSelectionDragStop) {
|
||||||
|
const selectedNodes = selectedElements
|
||||||
|
? selectedElements.filter(isNode).map((selectedNode) => nodes.find((node) => node.id === selectedNode.id)!)
|
||||||
|
: [];
|
||||||
|
|
||||||
|
onSelectionDragStop(event, selectedNodes);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="react-flow__nodesselection"
|
className="react-flow__nodesselection"
|
||||||
@@ -97,6 +127,7 @@ export default () => {
|
|||||||
grid={grid}
|
grid={grid}
|
||||||
onStart={(event) => onStart(event as MouseEvent)}
|
onStart={(event) => onStart(event as MouseEvent)}
|
||||||
onDrag={(event) => onDrag(event as MouseEvent)}
|
onDrag={(event) => onDrag(event as MouseEvent)}
|
||||||
|
onStop={(event) => onStop(event as MouseEvent)}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="react-flow__nodesselection-rect"
|
className="react-flow__nodesselection-rect"
|
||||||
|
|||||||
@@ -46,6 +46,9 @@ export interface GraphViewProps {
|
|||||||
onMoveEnd?: (flowTransform?: FlowTransform) => void;
|
onMoveEnd?: (flowTransform?: FlowTransform) => void;
|
||||||
onPaneClick?: (event: MouseEvent) => void;
|
onPaneClick?: (event: MouseEvent) => void;
|
||||||
onPaneContextMenu?: (event: MouseEvent) => void;
|
onPaneContextMenu?: (event: MouseEvent) => void;
|
||||||
|
onSelectionDragStart?: (event: MouseEvent, nodes: Node[]) => void;
|
||||||
|
onSelectionDrag?: (event: MouseEvent, nodes: Node[]) => void;
|
||||||
|
onSelectionDragStop?: (event: MouseEvent, nodes: Node[]) => void;
|
||||||
selectionKeyCode: number;
|
selectionKeyCode: number;
|
||||||
nodeTypes: NodeTypesType;
|
nodeTypes: NodeTypesType;
|
||||||
edgeTypes: EdgeTypesType;
|
edgeTypes: EdgeTypesType;
|
||||||
@@ -84,6 +87,9 @@ const GraphView = ({
|
|||||||
onNodeContextMenu,
|
onNodeContextMenu,
|
||||||
onNodeDragStart,
|
onNodeDragStart,
|
||||||
onNodeDragStop,
|
onNodeDragStop,
|
||||||
|
onSelectionDragStart,
|
||||||
|
onSelectionDrag,
|
||||||
|
onSelectionDragStop,
|
||||||
connectionLineType,
|
connectionLineType,
|
||||||
connectionLineStyle,
|
connectionLineStyle,
|
||||||
selectionKeyCode,
|
selectionKeyCode,
|
||||||
@@ -262,7 +268,13 @@ const GraphView = ({
|
|||||||
markerEndId={markerEndId}
|
markerEndId={markerEndId}
|
||||||
/>
|
/>
|
||||||
<UserSelection selectionKeyPressed={selectionKeyPressed} />
|
<UserSelection selectionKeyPressed={selectionKeyPressed} />
|
||||||
{nodesSelectionActive && <NodesSelection />}
|
{nodesSelectionActive && (
|
||||||
|
<NodesSelection
|
||||||
|
onSelectionDragStart={onSelectionDragStart}
|
||||||
|
onSelectionDrag={onSelectionDrag}
|
||||||
|
onSelectionDragStop={onSelectionDragStop}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
<div
|
<div
|
||||||
className="react-flow__zoompane"
|
className="react-flow__zoompane"
|
||||||
onClick={onZoomPaneClick}
|
onClick={onZoomPaneClick}
|
||||||
|
|||||||
@@ -53,6 +53,9 @@ export interface ReactFlowProps extends Omit<HTMLAttributes<HTMLDivElement>, 'on
|
|||||||
onMoveStart?: (flowTransform?: FlowTransform) => void;
|
onMoveStart?: (flowTransform?: FlowTransform) => void;
|
||||||
onMoveEnd?: (flowTransform?: FlowTransform) => void;
|
onMoveEnd?: (flowTransform?: FlowTransform) => void;
|
||||||
onSelectionChange?: (elements: Elements | null) => void;
|
onSelectionChange?: (elements: Elements | null) => void;
|
||||||
|
onSelectionDragStart?: (event: MouseEvent, nodes: Node[]) => void;
|
||||||
|
onSelectionDrag?: (event: MouseEvent, nodes: Node[]) => void;
|
||||||
|
onSelectionDragStop?: (event: MouseEvent, nodes: Node[]) => void;
|
||||||
onPaneClick?: (event: MouseEvent) => void;
|
onPaneClick?: (event: MouseEvent) => void;
|
||||||
onPaneContextMenu?: (event: MouseEvent) => void;
|
onPaneContextMenu?: (event: MouseEvent) => void;
|
||||||
nodeTypes: NodeTypesType;
|
nodeTypes: NodeTypesType;
|
||||||
@@ -103,6 +106,9 @@ const ReactFlow = ({
|
|||||||
onNodeDragStart,
|
onNodeDragStart,
|
||||||
onNodeDragStop,
|
onNodeDragStop,
|
||||||
onSelectionChange,
|
onSelectionChange,
|
||||||
|
onSelectionDragStart,
|
||||||
|
onSelectionDrag,
|
||||||
|
onSelectionDragStop,
|
||||||
connectionLineType,
|
connectionLineType,
|
||||||
connectionLineStyle,
|
connectionLineStyle,
|
||||||
deleteKeyCode,
|
deleteKeyCode,
|
||||||
@@ -175,6 +181,9 @@ const ReactFlow = ({
|
|||||||
paneMoveable={paneMoveable}
|
paneMoveable={paneMoveable}
|
||||||
onPaneClick={onPaneClick}
|
onPaneClick={onPaneClick}
|
||||||
onPaneContextMenu={onPaneContextMenu}
|
onPaneContextMenu={onPaneContextMenu}
|
||||||
|
onSelectionDragStart={onSelectionDragStart}
|
||||||
|
onSelectionDrag={onSelectionDrag}
|
||||||
|
onSelectionDragStop={onSelectionDragStop}
|
||||||
/>
|
/>
|
||||||
{onSelectionChange && <SelectionListener onSelectionChange={onSelectionChange} />}
|
{onSelectionChange && <SelectionListener onSelectionChange={onSelectionChange} />}
|
||||||
{children}
|
{children}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { useEffect, useRef, MutableRefObject } from 'react';
|
import { useEffect, useRef, MutableRefObject } from 'react';
|
||||||
import { event } from 'd3-selection';
|
|
||||||
|
|
||||||
import { useStoreState, useStoreActions } from '../store/hooks';
|
import { useStoreState, useStoreActions } from '../store/hooks';
|
||||||
import { FlowTransform } from '../types';
|
import { FlowTransform } from '../types';
|
||||||
@@ -53,7 +52,7 @@ export default ({
|
|||||||
if (selectionKeyPressed) {
|
if (selectionKeyPressed) {
|
||||||
d3Zoom.on('zoom', null);
|
d3Zoom.on('zoom', null);
|
||||||
} else {
|
} else {
|
||||||
d3Zoom.on('zoom', () => {
|
d3Zoom.on('zoom', (event: any) => {
|
||||||
updateTransform(event.transform);
|
updateTransform(event.transform);
|
||||||
|
|
||||||
if (onMove) {
|
if (onMove) {
|
||||||
@@ -68,7 +67,7 @@ export default ({
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (d3Zoom) {
|
if (d3Zoom) {
|
||||||
if (onMoveStart) {
|
if (onMoveStart) {
|
||||||
d3Zoom.on('start', () => {
|
d3Zoom.on('start', (event: any) => {
|
||||||
if (viewChanged(prevTransform.current, event.transform)) {
|
if (viewChanged(prevTransform.current, event.transform)) {
|
||||||
const flowTransform = eventToFlowTransform(event.transform);
|
const flowTransform = eventToFlowTransform(event.transform);
|
||||||
prevTransform.current = flowTransform;
|
prevTransform.current = flowTransform;
|
||||||
@@ -85,7 +84,7 @@ export default ({
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (d3Zoom) {
|
if (d3Zoom) {
|
||||||
if (onMoveEnd) {
|
if (onMoveEnd) {
|
||||||
d3Zoom.on('end', () => {
|
d3Zoom.on('end', (event: any) => {
|
||||||
if (viewChanged(prevTransform.current, event.transform)) {
|
if (viewChanged(prevTransform.current, event.transform)) {
|
||||||
const flowTransform = eventToFlowTransform(event.transform);
|
const flowTransform = eventToFlowTransform(event.transform);
|
||||||
prevTransform.current = flowTransform;
|
prevTransform.current = flowTransform;
|
||||||
@@ -101,7 +100,7 @@ export default ({
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (d3Zoom) {
|
if (d3Zoom) {
|
||||||
d3Zoom.filter(() => {
|
d3Zoom.filter((event: any) => {
|
||||||
if (!paneMoveable) {
|
if (!paneMoveable) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@ export { getBezierPath } from './components/Edges/BezierEdge';
|
|||||||
export { getSmoothStepPath } from './components/Edges/SmoothStepEdge';
|
export { getSmoothStepPath } from './components/Edges/SmoothStepEdge';
|
||||||
export { getMarkerEnd, getCenter as getEdgeCenter } from './components/Edges/utils';
|
export { getMarkerEnd, getCenter as getEdgeCenter } from './components/Edges/utils';
|
||||||
|
|
||||||
export { isNode, isEdge, removeElements, addEdge, getOutgoers } from './utils/graph';
|
export { isNode, isEdge, removeElements, addEdge, getOutgoers, getConnectedEdges } from './utils/graph';
|
||||||
|
|
||||||
export * from './additional-components';
|
export * from './additional-components';
|
||||||
export * from './types';
|
export * from './types';
|
||||||
|
|||||||
Reference in New Issue
Block a user