From 806c1dfa7725d956e912c75778f5e459bd03b9c9 Mon Sep 17 00:00:00 2001 From: braks <78412429+bcakmakoglu@users.noreply.github.com> Date: Mon, 6 Feb 2023 11:13:33 +0100 Subject: [PATCH 1/4] feat(core): add `nodes` option to `fitView` # What's changed? - Add `nodes` option to `fitView` - Allows `fitView` to only fit around a certain set of specified nodeIds --- packages/core/src/store/utils.ts | 6 +++++- packages/core/src/types/general.ts | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/core/src/store/utils.ts b/packages/core/src/store/utils.ts index caf860af..d7944141 100644 --- a/packages/core/src/store/utils.ts +++ b/packages/core/src/store/utils.ts @@ -141,7 +141,11 @@ export function fitView(get: StoreApi['getState'], options: Inte if ((options.initial && !fitViewOnInitDone && fitViewOnInit) || !options.initial) { if (d3Zoom && d3Selection) { - const nodes = getNodes().filter((n) => (options.includeHiddenNodes ? n.width && n.height : !n.hidden)); + let nodes: Node[] = getNodes().filter((n) => (options.includeHiddenNodes ? n.width && n.height : !n.hidden)); + + if (options.nodes?.length) { + nodes = nodes.filter((n) => options.nodes?.includes(n.id)) + } const nodesInitialized = nodes.every((n) => n.width && n.height); diff --git a/packages/core/src/types/general.ts b/packages/core/src/types/general.ts index 4abfa405..3c1dd4a8 100644 --- a/packages/core/src/types/general.ts +++ b/packages/core/src/types/general.ts @@ -76,6 +76,7 @@ export type FitViewOptions = { minZoom?: number; maxZoom?: number; duration?: number; + nodes?: string[]; }; export type OnConnectStartParams = { From 23424ea6750f092210f83df17a00c89adb910d96 Mon Sep 17 00:00:00 2001 From: braks <78412429+bcakmakoglu@users.noreply.github.com> Date: Mon, 6 Feb 2023 11:14:27 +0100 Subject: [PATCH 2/4] chore(changeset): add --- .changeset/witty-actors-clap.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/witty-actors-clap.md diff --git a/.changeset/witty-actors-clap.md b/.changeset/witty-actors-clap.md new file mode 100644 index 00000000..29fa7498 --- /dev/null +++ b/.changeset/witty-actors-clap.md @@ -0,0 +1,5 @@ +--- +'@reactflow/core': patch +--- + +Add `nodes` to fit view options to allow fitting view only around specified set of nodes From 3d65627de57249d976a74b744371788c62a5b304 Mon Sep 17 00:00:00 2001 From: braks <78412429+bcakmakoglu@users.noreply.github.com> Date: Mon, 6 Feb 2023 14:02:46 +0100 Subject: [PATCH 3/4] chore(core): cleanup node filter fn --- packages/core/src/store/utils.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/core/src/store/utils.ts b/packages/core/src/store/utils.ts index d7944141..0023db71 100644 --- a/packages/core/src/store/utils.ts +++ b/packages/core/src/store/utils.ts @@ -141,11 +141,16 @@ export function fitView(get: StoreApi['getState'], options: Inte if ((options.initial && !fitViewOnInitDone && fitViewOnInit) || !options.initial) { if (d3Zoom && d3Selection) { - let nodes: Node[] = getNodes().filter((n) => (options.includeHiddenNodes ? n.width && n.height : !n.hidden)); + const nodes = getNodes().filter((n) => { + const isVisible = (options.includeHiddenNodes ? n.width && n.height : !n.hidden); + let shouldInclude = true; - if (options.nodes?.length) { - nodes = nodes.filter((n) => options.nodes?.includes(n.id)) - } + if (options.nodes?.length) { + shouldInclude = options.nodes.includes(n.id); + } + + return isVisible && shouldInclude; + }); const nodesInitialized = nodes.every((n) => n.width && n.height); From a501f9a6436d2d95e86b1dd3b98d8a788844dafa Mon Sep 17 00:00:00 2001 From: moklick Date: Mon, 13 Feb 2023 12:42:22 +0100 Subject: [PATCH 4/4] refactor(fitview-nodes): cleanup --- .../vite-app/src/examples/Layouting/index.tsx | 53 ++++++++++--------- .../examples/Layouting/layouting.module.css | 7 --- packages/core/src/store/utils.ts | 7 ++- packages/core/src/types/general.ts | 2 +- 4 files changed, 32 insertions(+), 37 deletions(-) diff --git a/examples/vite-app/src/examples/Layouting/index.tsx b/examples/vite-app/src/examples/Layouting/index.tsx index 6e607551..9a9ed122 100644 --- a/examples/vite-app/src/examples/Layouting/index.tsx +++ b/examples/vite-app/src/examples/Layouting/index.tsx @@ -1,4 +1,4 @@ -import React, { useCallback } from 'react'; +import { useCallback } from 'react'; import ReactFlow, { Controls, ReactFlowProvider, @@ -10,6 +10,8 @@ import ReactFlow, { useEdgesState, MarkerType, EdgeMarker, + Panel, + useReactFlow, } from 'reactflow'; import dagre from 'dagre'; @@ -29,6 +31,7 @@ const nodeExtent: CoordinateExtent = [ const LayoutFlow = () => { const [nodes, setNodes, onNodesChange] = useNodesState(initialItems.nodes); const [edges, setEdges, onEdgesChange] = useEdgesState(initialItems.edges); + const { fitView } = useReactFlow(); const onConnect = useCallback( (connection: Connection) => { @@ -85,31 +88,31 @@ const LayoutFlow = () => { return (
- - onLayout('TB')} - onNodesChange={onNodesChange} - onEdgesChange={onEdgesChange} - > - - -
- - - - -
-
+ onLayout('TB')} + onNodesChange={onNodesChange} + onEdgesChange={onEdgesChange} + > + + + + + + + + + +
); }; -export default LayoutFlow; +export default () => ( + + + +); diff --git a/examples/vite-app/src/examples/Layouting/layouting.module.css b/examples/vite-app/src/examples/Layouting/layouting.module.css index b22c5ad9..28a4b5e6 100644 --- a/examples/vite-app/src/examples/Layouting/layouting.module.css +++ b/examples/vite-app/src/examples/Layouting/layouting.module.css @@ -2,10 +2,3 @@ flex-grow: 1; position: relative; } - -.controls { - position: absolute; - right: 10px; - top: 10px; - z-index: 10; -} diff --git a/packages/core/src/store/utils.ts b/packages/core/src/store/utils.ts index 9b5a4228..994fbf20 100644 --- a/packages/core/src/store/utils.ts +++ b/packages/core/src/store/utils.ts @@ -143,14 +143,13 @@ export function fitView(get: StoreApi['getState'], options: Inte if (d3initialized && (isInitialFitView || !options.initial)) { const nodes = getNodes().filter((n) => { - const isVisible = (options.includeHiddenNodes ? n.width && n.height : !n.hidden); - let shouldInclude = true; + const isVisible = options.includeHiddenNodes ? n.width && n.height : !n.hidden; if (options.nodes?.length) { - shouldInclude = options.nodes.includes(n.id); + return isVisible && options.nodes.some((optionNode) => optionNode.id === n.id); } - return isVisible && shouldInclude; + return isVisible; }); const nodesInitialized = nodes.every((n) => n.width && n.height); diff --git a/packages/core/src/types/general.ts b/packages/core/src/types/general.ts index bf9a779f..f628727e 100644 --- a/packages/core/src/types/general.ts +++ b/packages/core/src/types/general.ts @@ -76,7 +76,7 @@ export type FitViewOptions = { minZoom?: number; maxZoom?: number; duration?: number; - nodes?: string[]; + nodes?: (Partial & { id: Node['id'] })[]; }; export type OnConnectStartParams = {