Merge pull request #2834 from wbkd/feat/fit-view-nodes-option

Feat/fit view nodes option
This commit is contained in:
Moritz Klack
2023-02-13 12:43:15 +01:00
committed by GitHub
5 changed files with 43 additions and 33 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@reactflow/core': patch
---
Add `nodes` to fit view options to allow fitting view only around specified set of nodes
@@ -1,4 +1,4 @@
import React, { useCallback } from 'react'; import { useCallback } from 'react';
import ReactFlow, { import ReactFlow, {
Controls, Controls,
ReactFlowProvider, ReactFlowProvider,
@@ -10,6 +10,8 @@ import ReactFlow, {
useEdgesState, useEdgesState,
MarkerType, MarkerType,
EdgeMarker, EdgeMarker,
Panel,
useReactFlow,
} from 'reactflow'; } from 'reactflow';
import dagre from 'dagre'; import dagre from 'dagre';
@@ -29,6 +31,7 @@ const nodeExtent: CoordinateExtent = [
const LayoutFlow = () => { const LayoutFlow = () => {
const [nodes, setNodes, onNodesChange] = useNodesState(initialItems.nodes); const [nodes, setNodes, onNodesChange] = useNodesState(initialItems.nodes);
const [edges, setEdges, onEdgesChange] = useEdgesState(initialItems.edges); const [edges, setEdges, onEdgesChange] = useEdgesState(initialItems.edges);
const { fitView } = useReactFlow();
const onConnect = useCallback( const onConnect = useCallback(
(connection: Connection) => { (connection: Connection) => {
@@ -85,31 +88,31 @@ const LayoutFlow = () => {
return ( return (
<div className={styles.layoutflow}> <div className={styles.layoutflow}>
<ReactFlowProvider> <ReactFlow
<ReactFlow nodes={nodes}
nodes={nodes} edges={edges}
edges={edges} onConnect={onConnect}
onConnect={onConnect} nodeExtent={nodeExtent}
nodeExtent={nodeExtent} onInit={() => onLayout('TB')}
onInit={() => onLayout('TB')} onNodesChange={onNodesChange}
onNodesChange={onNodesChange} onEdgesChange={onEdgesChange}
onEdgesChange={onEdgesChange} >
> <Controls />
<Controls /> </ReactFlow>
</ReactFlow> <Panel position="top-right">
<div className={styles.controls}> <button onClick={() => onLayout('TB')}>vertical layout</button>
<button onClick={() => onLayout('TB')} style={{ marginRight: 10 }}> <button onClick={() => onLayout('LR')}>horizontal layout</button>
vertical layout <button onClick={() => unselect()}>unselect nodes</button>
</button> <button onClick={() => changeMarker()}>change marker</button>
<button onClick={() => onLayout('LR')} style={{ marginRight: 10 }}> <button onClick={() => fitView()}>fitView</button>
horizontal layout <button onClick={() => fitView({ nodes: nodes.slice(0, 2) })}>fitView partially</button>
</button> </Panel>
<button onClick={() => unselect()}>unselect nodes</button>
<button onClick={() => changeMarker()}>change marker</button>
</div>
</ReactFlowProvider>
</div> </div>
); );
}; };
export default LayoutFlow; export default () => (
<ReactFlowProvider>
<LayoutFlow />
</ReactFlowProvider>
);
@@ -2,10 +2,3 @@
flex-grow: 1; flex-grow: 1;
position: relative; position: relative;
} }
.controls {
position: absolute;
right: 10px;
top: 10px;
z-index: 10;
}
+9 -1
View File
@@ -142,7 +142,15 @@ export function fitView(get: StoreApi<ReactFlowState>['getState'], options: Inte
const d3initialized = d3Zoom && d3Selection; const d3initialized = d3Zoom && d3Selection;
if (d3initialized && (isInitialFitView || !options.initial)) { 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); const nodesInitialized = nodes.every((n) => n.width && n.height);
+1
View File
@@ -76,6 +76,7 @@ export type FitViewOptions = {
minZoom?: number; minZoom?: number;
maxZoom?: number; maxZoom?: number;
duration?: number; duration?: number;
nodes?: (Partial<Node> & { id: Node['id'] })[];
}; };
export type OnConnectStartParams = { export type OnConnectStartParams = {