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