diff --git a/example/src/CustomNode/index.tsx b/example/src/CustomNode/index.tsx index 8169dc52..d867a9c4 100644 --- a/example/src/CustomNode/index.tsx +++ b/example/src/CustomNode/index.tsx @@ -18,8 +18,8 @@ import ColorSelectorNode from './ColorSelectorNode'; const onInit = (reactFlowInstance: ReactFlowInstance) => { console.log('flow loaded:', reactFlowInstance); - reactFlowInstance.fitView(); }; + const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node); const onNodeClick = (_: MouseEvent, node: Node) => console.log('click', node); @@ -117,8 +117,9 @@ const CustomNodeFlow = () => { connectionLineStyle={connectionLineStyle} snapToGrid={true} snapGrid={snapGrid} - defaultZoom={1.5} - fitView + defaultZoom={0.3} + minZoom={0.3} + maxZoom={2} > { diff --git a/src/container/FlowRenderer/index.tsx b/src/container/FlowRenderer/index.tsx index 1eae6797..6b48feea 100644 --- a/src/container/FlowRenderer/index.tsx +++ b/src/container/FlowRenderer/index.tsx @@ -48,8 +48,11 @@ const FlowRenderer = ({ panOnScrollMode, zoomOnDoubleClick, panOnDrag, - defaultPosition, + translateExtent, + minZoom, + maxZoom, defaultZoom, + defaultPosition, preventScrolling, onSelectionContextMenu, noWheelClassName, @@ -84,8 +87,11 @@ const FlowRenderer = ({ panOnScrollMode={panOnScrollMode} zoomOnDoubleClick={zoomOnDoubleClick} panOnDrag={panOnDrag} - defaultPosition={defaultPosition} + translateExtent={translateExtent} + minZoom={minZoom} + maxZoom={maxZoom} defaultZoom={defaultZoom} + defaultPosition={defaultPosition} zoomActivationKeyCode={zoomActivationKeyCode} preventScrolling={preventScrolling} noWheelClassName={noWheelClassName} diff --git a/src/container/GraphView/index.tsx b/src/container/GraphView/index.tsx index f7774444..9b55e973 100644 --- a/src/container/GraphView/index.tsx +++ b/src/container/GraphView/index.tsx @@ -5,7 +5,14 @@ import NodeRenderer from '../NodeRenderer'; import EdgeRenderer from '../EdgeRenderer'; import Viewport from '../Viewport'; import useOnInitHandler from '../../hooks/useOnInitHandler'; -import { NodeTypesWrapped, EdgeTypesWrapped, ConnectionLineType, KeyCode, ReactFlowProps } from '../../types'; +import { + NodeTypesWrapped, + EdgeTypesWrapped, + ConnectionLineType, + KeyCode, + ReactFlowProps, + CoordinateExtent, +} from '../../types'; export interface GraphViewProps extends Omit { @@ -16,6 +23,9 @@ export interface GraphViewProps multiSelectionKeyCode: KeyCode | null; connectionLineType: ConnectionLineType; onlyRenderVisibleElements: boolean; + translateExtent: CoordinateExtent; + minZoom: number; + maxZoom: number; defaultZoom: number; defaultPosition: [number, number]; defaultMarkerColor: string; @@ -52,6 +62,9 @@ const GraphView = ({ onlyRenderVisibleElements, elementsSelectable, selectNodesOnDrag, + translateExtent, + minZoom, + maxZoom, defaultZoom, defaultPosition, preventScrolling, @@ -102,8 +115,11 @@ const GraphView = ({ panOnScrollSpeed={panOnScrollSpeed} panOnScrollMode={panOnScrollMode} panOnDrag={panOnDrag} - defaultPosition={defaultPosition} + translateExtent={translateExtent} + minZoom={minZoom} + maxZoom={maxZoom} defaultZoom={defaultZoom} + defaultPosition={defaultPosition} onSelectionContextMenu={onSelectionContextMenu} preventScrolling={preventScrolling} noDragClassName={noDragClassName} diff --git a/src/container/ReactFlow/index.tsx b/src/container/ReactFlow/index.tsx index 257d37f4..debdd3ae 100644 --- a/src/container/ReactFlow/index.tsx +++ b/src/container/ReactFlow/index.tsx @@ -26,6 +26,7 @@ import GraphView from '../GraphView'; import { createNodeTypes } from '../NodeRenderer/utils'; import { injectStyle, useNodeOrEdgeTypes } from './utils'; import Wrapper from './Wrapper'; +import { infiniteExtent } from '../../store/initialState'; if (__INJECT_STYLES__) { injectStyle(css as unknown as string); @@ -103,11 +104,11 @@ const ReactFlow = forwardRef( nodesDraggable, nodesConnectable, elementsSelectable, - minZoom, - maxZoom, + minZoom = 0.5, + maxZoom = 2, defaultZoom = 1, defaultPosition = initDefaultPosition, - translateExtent, + translateExtent = infiniteExtent, preventScrolling = true, nodeExtent, defaultMarkerColor = '#b1b1b7', @@ -177,6 +178,9 @@ const ReactFlow = forwardRef( zoomActivationKeyCode={zoomActivationKeyCode} onlyRenderVisibleElements={onlyRenderVisibleElements} selectNodesOnDrag={selectNodesOnDrag} + translateExtent={translateExtent} + minZoom={minZoom} + maxZoom={maxZoom} defaultZoom={defaultZoom} defaultPosition={defaultPosition} preventScrolling={preventScrolling} diff --git a/src/container/ZoomPane/index.tsx b/src/container/ZoomPane/index.tsx index 9c6075d9..fd309741 100644 --- a/src/container/ZoomPane/index.tsx +++ b/src/container/ZoomPane/index.tsx @@ -45,8 +45,11 @@ const ZoomPane = ({ selectionKeyPressed, elementsSelectable, panOnDrag = true, - defaultPosition = [0, 0], + translateExtent, + minZoom, + maxZoom, defaultZoom = 1, + defaultPosition = [0, 0], zoomActivationKeyCode, preventScrolling = true, children, @@ -56,6 +59,7 @@ const ZoomPane = ({ const store = useStoreApi(); const isZoomingOrPanning = useRef(false); const zoomPane = useRef(null); + const initialized = useRef(false); const prevTransform = useRef({ x: 0, y: 0, zoom: 0 }); const { d3Zoom, d3Selection, d3ZoomHandler } = useStore(selector, shallow); const zoomActivationKeyPressed = useKeyPress(zoomActivationKeyCode); @@ -63,8 +67,8 @@ const ZoomPane = ({ useResizeHandler(zoomPane); useEffect(() => { - if (zoomPane.current) { - const { minZoom, maxZoom, translateExtent } = store.getState(); + if (zoomPane.current && !initialized.current) { + initialized.current = true; const d3ZoomInstance = zoom().scaleExtent([minZoom, maxZoom]).translateExtent(translateExtent); const selection = select(zoomPane.current as Element).call(d3ZoomInstance);