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 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 6be6bae7..994fbf20 100644 --- a/packages/core/src/store/utils.ts +++ b/packages/core/src/store/utils.ts @@ -142,7 +142,15 @@ export function fitView(get: StoreApi['getState'], options: Inte const d3initialized = d3Zoom && d3Selection; if (d3initialized && (isInitialFitView || !options.initial)) { - const nodes = 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; + + if (options.nodes?.length) { + return isVisible && options.nodes.some((optionNode) => optionNode.id === n.id); + } + + 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 d9808e57..f628727e 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?: (Partial & { id: Node['id'] })[]; }; export type OnConnectStartParams = {