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