package(svelte): use system fitView

This commit is contained in:
moklick
2023-02-19 16:15:42 +01:00
parent 0f62a3d07a
commit ba592ceea6
6 changed files with 72 additions and 12 deletions

View File

@@ -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",

View File

@@ -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]})"

View File

@@ -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]);
});

View File

@@ -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,

View File

@@ -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
View File

@@ -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