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
+2 -1
View File
@@ -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]})"
+13 -2
View File
@@ -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]);
}); });
+36 -4
View File
@@ -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,
+14 -2
View File
@@ -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;
+5 -1
View File
@@ -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