From 5c2c1eecad41401da932d5d5caab0d312b382da6 Mon Sep 17 00:00:00 2001 From: moklick Date: Thu, 10 Sep 2020 18:39:40 +0200 Subject: [PATCH] feat(paneview): add translateExtent option closes #479 --- README.md | 1 + src/container/GraphView/index.tsx | 10 ++++++++++ src/container/ReactFlow/index.tsx | 4 ++++ src/store/index.ts | 18 +++++++++++++++++- src/types/index.ts | 2 ++ 5 files changed, 34 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index aa541672..802887c5 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,7 @@ const BasicFlow = () => ; - `snapToGrid`: default: `false` - `snapGrid`: [x, y] array - default: `[16, 16]` - `onlyRenderVisibleNodes`: default: `true` +- `translateExtent`: [default `[[-∞, -∞], [+∞, +∞]]`](https://github.com/d3/d3-zoom#zoom_translateExtent) #### Event Handlers - `onElementClick(event: MouseEvent, element: Node | Edge)`: called when user clicks node or edge diff --git a/src/container/GraphView/index.tsx b/src/container/GraphView/index.tsx index 0baef218..88e2013c 100644 --- a/src/container/GraphView/index.tsx +++ b/src/container/GraphView/index.tsx @@ -24,6 +24,7 @@ import { OnConnectStartFunc, OnConnectStopFunc, OnConnectEndFunc, + TranslateExtent, } from '../../types'; export interface GraphViewProps { @@ -67,6 +68,7 @@ export interface GraphViewProps { maxZoom: number; defaultZoom: number; defaultPosition: [number, number]; + translateExtent?: TranslateExtent; arrowHeadColor: string; markerEndId?: string; zoomOnScroll: boolean; @@ -112,6 +114,7 @@ const GraphView = ({ maxZoom, defaultZoom, defaultPosition, + translateExtent, arrowHeadColor, markerEndId, zoomOnScroll, @@ -137,6 +140,7 @@ const GraphView = ({ const setElementsSelectable = useStoreActions((actions) => actions.setElementsSelectable); const setInitTransform = useStoreActions((actions) => actions.setInitTransform); const setMinMaxZoom = useStoreActions((actions) => actions.setMinMaxZoom); + const setTranslateExtent = useStoreActions((actions) => actions.setTranslateExtent); const fitView = useStoreActions((actions) => actions.fitView); const zoom = useStoreActions((actions) => actions.zoom); const zoomTo = useStoreActions((actions) => actions.zoomTo); @@ -254,6 +258,12 @@ const GraphView = ({ setMinMaxZoom({ minZoom, maxZoom }); }, [minZoom, maxZoom]); + useEffect(() => { + if (typeof translateExtent !== 'undefined') { + setTranslateExtent(translateExtent); + } + }, [translateExtent]); + return (
, 'on maxZoom: number; defaultZoom: number; defaultPosition: [number, number]; + translateExtent?: TranslateExtent; arrowHeadColor: string; markerEndId?: string; zoomOnScroll: boolean; @@ -125,6 +127,7 @@ const ReactFlow = ({ maxZoom, defaultZoom, defaultPosition, + translateExtent, arrowHeadColor, markerEndId, zoomOnScroll, @@ -176,6 +179,7 @@ const ReactFlow = ({ maxZoom={maxZoom} defaultZoom={defaultZoom} defaultPosition={defaultPosition} + translateExtent={translateExtent} arrowHeadColor={arrowHeadColor} markerEndId={markerEndId} zoomOnScroll={zoomOnScroll} diff --git a/src/store/index.ts b/src/store/index.ts index 913ba56e..9827092c 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -26,6 +26,7 @@ import { SetConnectionId, NodePosUpdate, FitViewParams, + TranslateExtent, } from '../types'; type TransformXYK = { @@ -65,6 +66,7 @@ export interface StoreModel { d3Initialised: boolean; minZoom: number; maxZoom: number; + translateExtent: TranslateExtent; nodesSelectionActive: boolean; selectionActive: boolean; @@ -116,6 +118,8 @@ export interface StoreModel { setMinMaxZoom: Action; + setTranslateExtent: Action; + setSnapGrid: Action; setConnectionPosition: Action; @@ -154,6 +158,10 @@ export const storeModel: StoreModel = { d3Initialised: false, minZoom: 0.5, maxZoom: 2, + translateExtent: [ + [Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY], + [Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY], + ], nodesSelectionActive: false, selectionActive: false, @@ -351,7 +359,7 @@ export const storeModel: StoreModel = { }), initD3: action((state, zoomPaneNode) => { - const d3ZoomInstance = zoom().scaleExtent([state.minZoom, state.maxZoom]); + const d3ZoomInstance = zoom().scaleExtent([state.minZoom, state.maxZoom]).translateExtent(state.translateExtent); const selection = select(zoomPaneNode).call(d3ZoomInstance); @@ -369,6 +377,14 @@ export const storeModel: StoreModel = { } }), + setTranslateExtent: action((state, translateExtent) => { + state.translateExtent = translateExtent; + + if (state.d3Zoom) { + state.d3Zoom.translateExtent(translateExtent); + } + }), + setConnectionPosition: action((state, position) => { state.connectionPosition = position; }), diff --git a/src/types/index.ts b/src/types/index.ts index 8837c769..7d02712a 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -272,3 +272,5 @@ export type FlowTransform = { y: number; zoom: number; }; + +export type TranslateExtent = [[number, number], [number, number]];