Merge pull request #876 from ambroseus/feat/fitview-exclude-hidden
feat(fitView): added option to exclude hidden nodes
This commit is contained in:
@@ -10,11 +10,13 @@ import LockIcon from '../../../assets/icons/lock.svg';
|
|||||||
import UnlockIcon from '../../../assets/icons/unlock.svg';
|
import UnlockIcon from '../../../assets/icons/unlock.svg';
|
||||||
|
|
||||||
import useZoomPanHelper from '../../hooks/useZoomPanHelper';
|
import useZoomPanHelper from '../../hooks/useZoomPanHelper';
|
||||||
|
import { FitViewParams } from '../../types';
|
||||||
|
|
||||||
export interface ControlProps extends React.HTMLAttributes<HTMLDivElement> {
|
export interface ControlProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||||
showZoom?: boolean;
|
showZoom?: boolean;
|
||||||
showFitView?: boolean;
|
showFitView?: boolean;
|
||||||
showInteractive?: boolean;
|
showInteractive?: boolean;
|
||||||
|
fitViewParams?: FitViewParams;
|
||||||
onZoomIn?: () => void;
|
onZoomIn?: () => void;
|
||||||
onZoomOut?: () => void;
|
onZoomOut?: () => void;
|
||||||
onFitView?: () => void;
|
onFitView?: () => void;
|
||||||
@@ -26,6 +28,7 @@ const Controls = ({
|
|||||||
showZoom = true,
|
showZoom = true,
|
||||||
showFitView = true,
|
showFitView = true,
|
||||||
showInteractive = true,
|
showInteractive = true,
|
||||||
|
fitViewParams,
|
||||||
onZoomIn,
|
onZoomIn,
|
||||||
onZoomOut,
|
onZoomOut,
|
||||||
onFitView,
|
onFitView,
|
||||||
@@ -49,9 +52,9 @@ const Controls = ({
|
|||||||
}, [zoomOut, onZoomOut]);
|
}, [zoomOut, onZoomOut]);
|
||||||
|
|
||||||
const onFitViewHandler = useCallback(() => {
|
const onFitViewHandler = useCallback(() => {
|
||||||
fitView?.();
|
fitView?.(fitViewParams);
|
||||||
onFitView?.();
|
onFitView?.();
|
||||||
}, [fitView, onFitView]);
|
}, [fitView, fitViewParams, onFitView]);
|
||||||
|
|
||||||
const onInteractiveChangeHandler = useCallback(() => {
|
const onInteractiveChangeHandler = useCallback(() => {
|
||||||
setInteractive?.(!isInteractive);
|
setInteractive?.(!isInteractive);
|
||||||
|
|||||||
@@ -6,12 +6,14 @@ import { clamp } from '../utils';
|
|||||||
import { getRectOfNodes } from '../utils/graph';
|
import { getRectOfNodes } from '../utils/graph';
|
||||||
import { FitViewParams, FlowTransform, ZoomPanHelperFunctions, Rect, Transform } from '../types';
|
import { FitViewParams, FlowTransform, ZoomPanHelperFunctions, Rect, Transform } from '../types';
|
||||||
|
|
||||||
|
const DEFAULT_PADDING = 0.1
|
||||||
|
|
||||||
const initialZoomPanHelper: ZoomPanHelperFunctions = {
|
const initialZoomPanHelper: ZoomPanHelperFunctions = {
|
||||||
zoomIn: () => {},
|
zoomIn: () => {},
|
||||||
zoomOut: () => {},
|
zoomOut: () => {},
|
||||||
zoomTo: (_: number) => {},
|
zoomTo: (_: number) => {},
|
||||||
transform: (_: FlowTransform) => {},
|
transform: (_: FlowTransform) => {},
|
||||||
fitView: (_: FitViewParams = { padding: 0.1 }) => {},
|
fitView: (_: FitViewParams = { padding: DEFAULT_PADDING, includeHiddenNodes: false }) => {},
|
||||||
setCenter: (_: number, __: number) => {},
|
setCenter: (_: number, __: number) => {},
|
||||||
fitBounds: (_: Rect) => {},
|
fitBounds: (_: Rect) => {},
|
||||||
initialized: false,
|
initialized: false,
|
||||||
@@ -23,7 +25,7 @@ const getTransformForBounds = (
|
|||||||
height: number,
|
height: number,
|
||||||
minZoom: number,
|
minZoom: number,
|
||||||
maxZoom: number,
|
maxZoom: number,
|
||||||
padding = 0.1
|
padding = DEFAULT_PADDING
|
||||||
): Transform => {
|
): Transform => {
|
||||||
const xZoom = width / (bounds.width * (1 + padding));
|
const xZoom = width / (bounds.width * (1 + padding));
|
||||||
const yZoom = height / (bounds.height * (1 + padding));
|
const yZoom = height / (bounds.height * (1 + padding));
|
||||||
@@ -37,7 +39,7 @@ const getTransformForBounds = (
|
|||||||
return [x, y, clampedZoom];
|
return [x, y, clampedZoom];
|
||||||
};
|
};
|
||||||
|
|
||||||
const usePanZoomHelper = (): ZoomPanHelperFunctions => {
|
const useZoomPanHelper = (): ZoomPanHelperFunctions => {
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
const d3Zoom = useStoreState((s) => s.d3Zoom);
|
const d3Zoom = useStoreState((s) => s.d3Zoom);
|
||||||
const d3Selection = useStoreState((s) => s.d3Selection);
|
const d3Selection = useStoreState((s) => s.d3Selection);
|
||||||
@@ -53,15 +55,16 @@ const usePanZoomHelper = (): ZoomPanHelperFunctions => {
|
|||||||
|
|
||||||
d3Zoom.transform(d3Selection, nextTransform);
|
d3Zoom.transform(d3Selection, nextTransform);
|
||||||
},
|
},
|
||||||
fitView: (options: FitViewParams = { padding: 0.1 }) => {
|
fitView: (options: FitViewParams = { padding: DEFAULT_PADDING, includeHiddenNodes: false }) => {
|
||||||
const { nodes, width, height, minZoom, maxZoom } = store.getState();
|
const { nodes, width, height, minZoom, maxZoom } = store.getState();
|
||||||
|
|
||||||
if (!nodes.length) {
|
if (!nodes.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bounds = getRectOfNodes(nodes);
|
const bounds = getRectOfNodes(options.includeHiddenNodes ? nodes : nodes.filter(node => !node.isHidden));
|
||||||
const [x, y, zoom] = getTransformForBounds(bounds, width, height, minZoom, maxZoom, options.padding);
|
const padding = options.padding || DEFAULT_PADDING
|
||||||
|
const [x, y, zoom] = getTransformForBounds(bounds, width, height, minZoom, maxZoom, padding);
|
||||||
const transform = zoomIdentity.translate(x, y).scale(zoom);
|
const transform = zoomIdentity.translate(x, y).scale(zoom);
|
||||||
|
|
||||||
d3Zoom.transform(d3Selection, transform);
|
d3Zoom.transform(d3Selection, transform);
|
||||||
@@ -76,7 +79,7 @@ const usePanZoomHelper = (): ZoomPanHelperFunctions => {
|
|||||||
|
|
||||||
d3Zoom.transform(d3Selection, transform);
|
d3Zoom.transform(d3Selection, transform);
|
||||||
},
|
},
|
||||||
fitBounds: (bounds: Rect, padding = 0.1) => {
|
fitBounds: (bounds: Rect, padding = DEFAULT_PADDING) => {
|
||||||
const { width, height, minZoom, maxZoom } = store.getState();
|
const { width, height, minZoom, maxZoom } = store.getState();
|
||||||
const [x, y, zoom] = getTransformForBounds(bounds, width, height, minZoom, maxZoom, padding);
|
const [x, y, zoom] = getTransformForBounds(bounds, width, height, minZoom, maxZoom, padding);
|
||||||
const transform = zoomIdentity.translate(x, y).scale(zoom);
|
const transform = zoomIdentity.translate(x, y).scale(zoom);
|
||||||
@@ -93,4 +96,4 @@ const usePanZoomHelper = (): ZoomPanHelperFunctions => {
|
|||||||
return zoomPanHelperFunctions;
|
return zoomPanHelperFunctions;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default usePanZoomHelper;
|
export default useZoomPanHelper;
|
||||||
|
|||||||
+2
-1
@@ -235,7 +235,8 @@ export interface WrapNodeProps<T = any> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type FitViewParams = {
|
export type FitViewParams = {
|
||||||
padding: number;
|
padding?: number;
|
||||||
|
includeHiddenNodes?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type FlowExportObject<T = any> = {
|
export type FlowExportObject<T = any> = {
|
||||||
|
|||||||
Reference in New Issue
Block a user