package(svelte): use system fitView
This commit is contained in:
@@ -16,7 +16,8 @@
|
|||||||
".": "./index.js"
|
".": "./index.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@reactflow/system": "workspace:*",
|
"@reactflow/system": "workspace:11.5.5",
|
||||||
|
"@reactflow/utils": "workspace:^11.5.5",
|
||||||
"cc": "^3.0.1",
|
"cc": "^3.0.1",
|
||||||
"d3-drag": "^3.0.0",
|
"d3-drag": "^3.0.0",
|
||||||
"d3-selection": "^3.0.0",
|
"d3-selection": "^3.0.0",
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
import zoom from '$lib/hooks/zoom'
|
import zoom from '$lib/hooks/zoom'
|
||||||
import { useStore } from '$lib/store';
|
import { useStore } from '$lib/store';
|
||||||
|
|
||||||
const { transformStore } = useStore();
|
const { transformStore, d3Store } = useStore();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="react-flow__pane" use:zoom={{ transformStore }}>
|
<div class="react-flow__pane" use:zoom={{ transformStore, d3Store }}>
|
||||||
<div
|
<div
|
||||||
class="react-flow__viewport"
|
class="react-flow__viewport"
|
||||||
style="transform: translate({$transformStore[0]}px, {$transformStore[1]}px) scale({$transformStore[2]})"
|
style="transform: translate({$transformStore[0]}px, {$transformStore[1]}px) scale({$transformStore[2]})"
|
||||||
|
|||||||
@@ -3,14 +3,20 @@ import type { Writable } from 'svelte/store';
|
|||||||
import { select } from 'd3-selection';
|
import { select } from 'd3-selection';
|
||||||
import { zoom as d3Zoom, zoomIdentity } from 'd3-zoom';
|
import { zoom as d3Zoom, zoomIdentity } from 'd3-zoom';
|
||||||
import type { D3ZoomEvent } from 'd3-zoom';
|
import type { D3ZoomEvent } from 'd3-zoom';
|
||||||
import type { Transform } from '@reactflow/system';
|
import type { D3SelectionInstance, D3ZoomInstance, Transform } from '@reactflow/system';
|
||||||
|
|
||||||
const isWrappedWithClass = (event: any, className: string | undefined) =>
|
const isWrappedWithClass = (event: any, className: string | undefined) =>
|
||||||
event.target.closest(`.${className}`);
|
event.target.closest(`.${className}`);
|
||||||
|
|
||||||
export default function zoom(
|
export default function zoom(
|
||||||
domNode: Element,
|
domNode: Element,
|
||||||
{ transformStore }: { transformStore: Writable<Transform> }
|
{
|
||||||
|
transformStore,
|
||||||
|
d3Store
|
||||||
|
}: {
|
||||||
|
transformStore: Writable<Transform>;
|
||||||
|
d3Store: Writable<{ zoom: D3ZoomInstance | null; selection: D3SelectionInstance | null }>;
|
||||||
|
}
|
||||||
) {
|
) {
|
||||||
const d3ZoomInstance = d3Zoom();
|
const d3ZoomInstance = d3Zoom();
|
||||||
const selection = select(domNode).call(d3ZoomInstance);
|
const selection = select(domNode).call(d3ZoomInstance);
|
||||||
@@ -26,6 +32,11 @@ export default function zoom(
|
|||||||
d3ZoomHandler!.call(this, event, d);
|
d3ZoomHandler!.call(this, event, d);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
d3Store.set({
|
||||||
|
zoom: d3ZoomInstance,
|
||||||
|
selection
|
||||||
|
});
|
||||||
|
|
||||||
d3ZoomInstance.on('zoom', (event: D3ZoomEvent<HTMLDivElement, any>) => {
|
d3ZoomInstance.on('zoom', (event: D3ZoomEvent<HTMLDivElement, any>) => {
|
||||||
transformStore.set([event.transform.x, event.transform.y, event.transform.k]);
|
transformStore.set([event.transform.x, event.transform.y, event.transform.k]);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -7,8 +7,12 @@ import {
|
|||||||
type NodeDimensionUpdate,
|
type NodeDimensionUpdate,
|
||||||
type Edge,
|
type Edge,
|
||||||
Position,
|
Position,
|
||||||
internalsSymbol
|
internalsSymbol,
|
||||||
|
type NodeOrigin,
|
||||||
|
type D3ZoomInstance,
|
||||||
|
type D3SelectionInstance
|
||||||
} from '@reactflow/system';
|
} from '@reactflow/system';
|
||||||
|
import { fitView } from '@reactflow/utils';
|
||||||
|
|
||||||
import { getDimensions, getHandleBounds } from '../../utils';
|
import { getDimensions, getHandleBounds } from '../../utils';
|
||||||
import {
|
import {
|
||||||
@@ -24,6 +28,7 @@ type CreateStoreProps = {
|
|||||||
nodes: Node[];
|
nodes: Node[];
|
||||||
edges: Edge[];
|
edges: Edge[];
|
||||||
fitView: boolean;
|
fitView: boolean;
|
||||||
|
nodeOrigin?: NodeOrigin;
|
||||||
transform?: Transform;
|
transform?: Transform;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -37,6 +42,10 @@ type SvelteFlowStore = {
|
|||||||
edgesStore: Writable<CreateStoreProps['edges']>;
|
edgesStore: Writable<CreateStoreProps['edges']>;
|
||||||
heightStore: Writable<number>;
|
heightStore: Writable<number>;
|
||||||
widthStore: Writable<number>;
|
widthStore: Writable<number>;
|
||||||
|
d3Store: Writable<{
|
||||||
|
zoom: D3ZoomInstance | null;
|
||||||
|
selection: D3SelectionInstance | null;
|
||||||
|
}>;
|
||||||
transformStore: Writable<Transform>;
|
transformStore: Writable<Transform>;
|
||||||
edgesWithDataStore: Readable<EdgeWithData[]>;
|
edgesWithDataStore: Readable<EdgeWithData[]>;
|
||||||
updateNodePositions: (
|
updateNodePositions: (
|
||||||
@@ -51,12 +60,15 @@ export function createStore({
|
|||||||
nodes = [],
|
nodes = [],
|
||||||
edges = [],
|
edges = [],
|
||||||
transform = [0, 0, 1],
|
transform = [0, 0, 1],
|
||||||
|
nodeOrigin = [0, 0],
|
||||||
fitView: fitViewOnInit = false
|
fitView: fitViewOnInit = false
|
||||||
}: CreateStoreProps): SvelteFlowStore {
|
}: CreateStoreProps): SvelteFlowStore {
|
||||||
const nodesStore = writable(nodes.map((n) => ({ ...n, positionAbsolute: n.position })));
|
const nodesStore = writable(nodes.map((n) => ({ ...n, positionAbsolute: n.position })));
|
||||||
const edgesStore = writable(edges);
|
const edgesStore = writable(edges);
|
||||||
const heightStore = writable(500);
|
const heightStore = writable(500);
|
||||||
const widthStore = writable(500);
|
const widthStore = writable(500);
|
||||||
|
const nodeOriginStore = writable(nodeOrigin);
|
||||||
|
const d3Store = writable({ zoom: null, selection: null });
|
||||||
|
|
||||||
let fitViewOnInitDone = false;
|
let fitViewOnInitDone = false;
|
||||||
|
|
||||||
@@ -166,10 +178,29 @@ export function createStore({
|
|||||||
return node;
|
return node;
|
||||||
});
|
});
|
||||||
|
|
||||||
// const nextFitViewOnInitDone =
|
const { zoom: d3Zoom, selection: d3Selection } = get(d3Store);
|
||||||
// fitViewOnInitDone || (fitViewOnInit && !fitViewOnInitDone && fitView(get, { initial: true }));
|
|
||||||
|
|
||||||
// fitViewOnInitDone = nextFitViewOnInitDone;
|
const nextFitViewOnInitDone =
|
||||||
|
fitViewOnInitDone ||
|
||||||
|
(fitViewOnInit &&
|
||||||
|
!fitViewOnInitDone &&
|
||||||
|
!!d3Zoom &&
|
||||||
|
!!d3Selection &&
|
||||||
|
fitView(
|
||||||
|
{
|
||||||
|
nodes: get(nodesStore),
|
||||||
|
width: get(widthStore),
|
||||||
|
height: get(heightStore),
|
||||||
|
minZoom: 0.2,
|
||||||
|
maxZoom: 2,
|
||||||
|
d3Selection,
|
||||||
|
d3Zoom,
|
||||||
|
nodeOrigin: get(nodeOriginStore)
|
||||||
|
},
|
||||||
|
{}
|
||||||
|
));
|
||||||
|
|
||||||
|
fitViewOnInitDone = nextFitViewOnInitDone;
|
||||||
|
|
||||||
nodesStore.set(nextNodes);
|
nodesStore.set(nextNodes);
|
||||||
}
|
}
|
||||||
@@ -178,6 +209,7 @@ export function createStore({
|
|||||||
nodesStore,
|
nodesStore,
|
||||||
edgesStore,
|
edgesStore,
|
||||||
transformStore,
|
transformStore,
|
||||||
|
d3Store,
|
||||||
heightStore,
|
heightStore,
|
||||||
widthStore,
|
widthStore,
|
||||||
edgesWithDataStore,
|
edgesWithDataStore,
|
||||||
|
|||||||
@@ -70,6 +70,15 @@ export enum ConnectionMode {
|
|||||||
|
|
||||||
export type OnConnect = (connection: Connection) => void;
|
export type OnConnect = (connection: Connection) => void;
|
||||||
|
|
||||||
|
export type FitViewParams = {
|
||||||
|
nodes: Node[];
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
nodeOrigin: NodeOrigin;
|
||||||
|
d3Zoom: D3ZoomInstance;
|
||||||
|
d3Selection: D3SelectionInstance;
|
||||||
|
};
|
||||||
|
|
||||||
export type FitViewOptions = {
|
export type FitViewOptions = {
|
||||||
padding?: number;
|
padding?: number;
|
||||||
includeHiddenNodes?: boolean;
|
includeHiddenNodes?: boolean;
|
||||||
@@ -137,6 +146,9 @@ export type ViewportHelperFunctions = {
|
|||||||
viewportInitialized: boolean;
|
viewportInitialized: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type D3ZoomInstance = ZoomBehavior<Element, unknown>;
|
||||||
|
export type D3SelectionInstance = D3Selection<Element, unknown, null, undefined>;
|
||||||
|
|
||||||
export type ReactFlowStore = {
|
export type ReactFlowStore = {
|
||||||
rfId: string;
|
rfId: string;
|
||||||
width: number;
|
width: number;
|
||||||
@@ -152,8 +164,8 @@ export type ReactFlowStore = {
|
|||||||
paneDragging: boolean;
|
paneDragging: boolean;
|
||||||
noPanClassName: string;
|
noPanClassName: string;
|
||||||
|
|
||||||
d3Zoom: ZoomBehavior<Element, unknown> | null;
|
d3Zoom: D3ZoomInstance | null;
|
||||||
d3Selection: D3Selection<Element, unknown, null, undefined> | null;
|
d3Selection: D3SelectionInstance | null;
|
||||||
d3ZoomHandler: ((this: Element, event: any, d: unknown) => void) | undefined;
|
d3ZoomHandler: ((this: Element, event: any, d: unknown) => void) | undefined;
|
||||||
minZoom: number;
|
minZoom: number;
|
||||||
maxZoom: number;
|
maxZoom: number;
|
||||||
|
|||||||
Generated
+5
-1
@@ -310,7 +310,8 @@ importers:
|
|||||||
|
|
||||||
packages/svelte:
|
packages/svelte:
|
||||||
specifiers:
|
specifiers:
|
||||||
'@reactflow/system': workspace:*
|
'@reactflow/system': workspace:11.5.5
|
||||||
|
'@reactflow/utils': workspace:^11.5.5
|
||||||
'@sveltejs/adapter-auto': ^2.0.0
|
'@sveltejs/adapter-auto': ^2.0.0
|
||||||
'@sveltejs/kit': ^1.5.6
|
'@sveltejs/kit': ^1.5.6
|
||||||
'@sveltejs/package': ^1.0.2
|
'@sveltejs/package': ^1.0.2
|
||||||
@@ -334,6 +335,7 @@ importers:
|
|||||||
vite: ^4.1.1
|
vite: ^4.1.1
|
||||||
dependencies:
|
dependencies:
|
||||||
'@reactflow/system': link:../system
|
'@reactflow/system': link:../system
|
||||||
|
'@reactflow/utils': link:../utils
|
||||||
cc: registry.npmjs.org/cc/3.0.1
|
cc: registry.npmjs.org/cc/3.0.1
|
||||||
d3-drag: registry.npmjs.org/d3-drag/3.0.0
|
d3-drag: registry.npmjs.org/d3-drag/3.0.0
|
||||||
d3-selection: registry.npmjs.org/d3-selection/3.0.0
|
d3-selection: registry.npmjs.org/d3-selection/3.0.0
|
||||||
@@ -399,6 +401,7 @@ importers:
|
|||||||
'@types/node': ^18.7.16
|
'@types/node': ^18.7.16
|
||||||
'@types/react': '>=17'
|
'@types/react': '>=17'
|
||||||
'@types/react-dom': '>=17'
|
'@types/react-dom': '>=17'
|
||||||
|
d3-zoom: ^3.0.0
|
||||||
react: ^18.2.0
|
react: ^18.2.0
|
||||||
typescript: ^4.9.4
|
typescript: ^4.9.4
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -407,6 +410,7 @@ importers:
|
|||||||
'@types/d3-drag': registry.npmjs.org/@types/d3-drag/3.0.1
|
'@types/d3-drag': registry.npmjs.org/@types/d3-drag/3.0.1
|
||||||
'@types/d3-selection': registry.npmjs.org/@types/d3-selection/3.0.3
|
'@types/d3-selection': registry.npmjs.org/@types/d3-selection/3.0.3
|
||||||
'@types/d3-zoom': registry.npmjs.org/@types/d3-zoom/3.0.1
|
'@types/d3-zoom': registry.npmjs.org/@types/d3-zoom/3.0.1
|
||||||
|
d3-zoom: registry.npmjs.org/d3-zoom/3.0.0
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@reactflow/eslint-config': link:../../tooling/eslint-config
|
'@reactflow/eslint-config': link:../../tooling/eslint-config
|
||||||
'@reactflow/rollup-config': link:../../tooling/rollup-config
|
'@reactflow/rollup-config': link:../../tooling/rollup-config
|
||||||
|
|||||||
Reference in New Issue
Block a user