Merge branch 'main' into v10

This commit is contained in:
moklick
2021-12-04 01:01:25 +01:00
11 changed files with 2188 additions and 2776 deletions
+23 -17
View File
@@ -1,6 +1,7 @@
import { useMemo } from 'react';
import { zoomIdentity } from 'd3-zoom';
import shallow from 'zustand/shallow';
import { Selection as D3Selection } from 'd3';
import { useStoreApi, useStore } from '../store';
import { getRectOfNodeInternals, pointToRendererPoint, getTransformForBounds } from '../utils/graph';
@@ -25,6 +26,10 @@ const selector = (s: ReactFlowState) => ({
d3Selection: s.d3Selection,
});
const getTransition = (selection: D3Selection<Element, unknown, null, undefined>, duration: number = 0) => {
return selection.transition().duration(duration);
};
const useZoomPanHelper = (): ZoomPanHelperFunctions => {
const store = useStoreApi();
const { d3Zoom, d3Selection } = useStore(selector, shallow);
@@ -32,53 +37,54 @@ const useZoomPanHelper = (): ZoomPanHelperFunctions => {
const zoomPanHelperFunctions = useMemo<ZoomPanHelperFunctions>(() => {
if (d3Selection && d3Zoom) {
return {
zoomIn: () => d3Zoom.scaleBy(d3Selection, 1.2),
zoomOut: () => d3Zoom.scaleBy(d3Selection, 1 / 1.2),
zoomTo: (zoomLevel: number) => d3Zoom.scaleTo(d3Selection, zoomLevel),
zoomIn: (options) => d3Zoom.scaleBy(getTransition(d3Selection, options?.duration), 1.2),
zoomOut: (options) => d3Zoom.scaleBy(getTransition(d3Selection, options?.duration), 1 / 1.2),
zoomTo: (zoomLevel, options) =>
d3Zoom.scaleTo(getTransition(d3Selection, options?.duration), zoomLevel),
transform: (transform: FlowTransform) => {
const nextTransform = zoomIdentity.translate(transform.x, transform.y).scale(transform.zoom);
d3Zoom.transform(d3Selection, nextTransform);
d3Zoom.transform(getTransition(d3Selection), nextTransform);
},
fitView: (options: FitViewParams = { padding: DEFAULT_PADDING, includeHiddenNodes: false }) => {
fitView: (options) => {
const { nodeInternals, width, height, minZoom, maxZoom } = store.getState();
// @TODO: work with nodeInternals instead of converting it to an array
const nodes = Array.from(nodeInternals).map(([_, node]) => node);
if (!nodes.length) {
return;
}
const bounds = getRectOfNodeInternals(
options.includeHiddenNodes ? nodes : nodes.filter((node) => !node.hidden)
options?.includeHiddenNodes ? nodes : nodes.filter((node) => !node.hidden)
);
const [x, y, zoom] = getTransformForBounds(
bounds,
width,
height,
options.minZoom ?? minZoom,
options.maxZoom ?? maxZoom,
options.padding ?? DEFAULT_PADDING
options?.minZoom ?? minZoom,
options?.maxZoom ?? maxZoom,
options?.padding ?? DEFAULT_PADDING
);
const transform = zoomIdentity.translate(x, y).scale(zoom);
d3Zoom.transform(d3Selection, transform);
d3Zoom.transform(getTransition(d3Selection, options?.duration), transform);
},
setCenter: (x: number, y: number, zoom?: number) => {
setCenter: (x, y, options) => {
const { width, height, maxZoom } = store.getState();
const nextZoom = typeof zoom !== 'undefined' ? zoom : maxZoom;
const nextZoom = typeof options?.zoom !== 'undefined' ? options.zoom : maxZoom;
const centerX = width / 2 - x * nextZoom;
const centerY = height / 2 - y * nextZoom;
const transform = zoomIdentity.translate(centerX, centerY).scale(nextZoom);
d3Zoom.transform(d3Selection, transform);
d3Zoom.transform(getTransition(d3Selection, options?.duration), transform);
},
fitBounds: (bounds: Rect, padding = DEFAULT_PADDING) => {
fitBounds: (bounds, options) => {
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, options?.padding ?? DEFAULT_PADDING);
const transform = zoomIdentity.translate(x, y).scale(zoom);
d3Zoom.transform(d3Selection, transform);
d3Zoom.transform(getTransition(d3Selection, options?.duration), transform);
},
project: (position: XYPosition) => {
const { transform, snapToGrid, snapGrid } = store.getState();