Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fitView improvements #3821

Draft
wants to merge 1 commit into
base: next
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/react/src/components/StoreUpdater/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,8 @@ export function StoreUpdater(props: StoreUpdaterProps) {
else if (fieldName === 'translateExtent') setTranslateExtent(fieldValue as CoordinateExtent);
else if (fieldName === 'nodeExtent') setNodeExtent(fieldValue as CoordinateExtent);
// Renamed fields
else if (fieldName === 'fitView') store.setState({ fitViewOnInit: fieldValue as boolean });
else if (fieldName === 'fitViewOptions') store.setState({ fitViewOnInitOptions: fieldValue as FitViewOptions });
else if (fieldName === 'fitView') store.setState({ fitViewScheduled: fieldValue as boolean });
else if (fieldName === 'fitViewOptions') store.setState({ fitViewScheduled: fieldValue as FitViewOptions });
// General case
else store.setState({ [fieldName]: fieldValue });
}
Expand Down
35 changes: 21 additions & 14 deletions packages/react/src/hooks/useViewportHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,20 +50,27 @@ const useViewportHelper = (): ViewportHelperFunctions => {
fitView: (options) => {
const { nodes, width, height, nodeOrigin, minZoom, maxZoom, panZoom } = store.getState();

return panZoom
? fitView(
{
nodes,
width,
height,
nodeOrigin,
minZoom,
maxZoom,
panZoom,
},
options
)
: false;
if (!panZoom) {
return false;
}

if (options?.waitForInit) {
store.setState({ fitViewScheduled: options });
return true; // TODO: what should be returned here
}

return fitView(
{
nodes,
width,
height,
panZoom,
minZoom,
maxZoom,
nodeOrigin,
},
options
);
},
setCenter: (x, y, options) => {
const { width, height, maxZoom, panZoom } = store.getState();
Expand Down
38 changes: 19 additions & 19 deletions packages/react/src/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,17 +97,7 @@ const createRFStore = ({
// changes its dimensions, this function is called to measure the
// new dimensions and update the nodes.
updateNodeDimensions: (updates) => {
const {
onNodesChange,
fitView,
nodes,
nodeLookup,
fitViewOnInit,
fitViewDone,
fitViewOnInitOptions,
domNode,
nodeOrigin,
} = get();
const { onNodesChange, fitView, nodes, nodeLookup, fitViewScheduled, domNode, nodeOrigin } = get();
const changes: NodeDimensionChange[] = [];

const updatedNodes = updateNodeDimensionsSystem(
Expand All @@ -131,21 +121,26 @@ const createRFStore = ({

const nextNodes = updateAbsolutePositions(updatedNodes, nodeLookup, nodeOrigin);

// we call fitView once initially after all dimensions are set
let nextFitViewDone = fitViewDone;
if (!fitViewDone && fitViewOnInit) {
nextFitViewDone = fitView(nextNodes, {
...fitViewOnInitOptions,
nodes: fitViewOnInitOptions?.nodes || nextNodes,
});
let nextFitViewScheduled = fitViewScheduled;
if (fitViewScheduled) {
const fitViewOptions =
typeof fitViewScheduled === 'boolean'
? { nodes: nextNodes }
: {
...fitViewScheduled,
waitForInit: false,
nodes: fitViewScheduled.nodes ?? nextNodes,
};
const fitViewDone = fitView(nextNodes, fitViewOptions);
if (fitViewDone) nextFitViewScheduled = false;
}

// here we are cirmumventing the onNodesChange handler
// in order to be able to display nodes even if the user
// has not provided an onNodesChange handler.
// Nodes are only rendered if they have a width and height
// attribute which they get from this handler.
set({ nodes: nextNodes, fitViewDone: nextFitViewDone });
set({ nodes: nextNodes, fitViewScheduled: nextFitViewScheduled });

if (changes?.length > 0) {
onNodesChange?.(changes);
Expand Down Expand Up @@ -308,6 +303,11 @@ const createRFStore = ({
return false;
}

if (options?.waitForInit) {
set({ fitViewScheduled: options });
return true; // TODO: what should be returned here
}

return fitViewSystem(
{
nodes,
Expand Down
4 changes: 1 addition & 3 deletions packages/react/src/store/initialState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,7 @@ const getInitialState = ({
elementsSelectable: true,
elevateNodesOnSelect: true,
elevateEdgesOnSelect: false,
fitViewOnInit: false,
fitViewDone: false,
fitViewOnInitOptions: undefined,
fitViewScheduled: false,
selectNodesOnDrag: true,

multiSelectionActive: false,
Expand Down
4 changes: 1 addition & 3 deletions packages/react/src/types/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,7 @@ export type ReactFlowStore = {
connectOnClick: boolean;
defaultEdgeOptions?: DefaultEdgeOptions;

fitViewOnInit: boolean;
fitViewDone: boolean;
fitViewOnInitOptions: FitViewOptions | undefined;
fitViewScheduled: boolean | FitViewOptions;

onNodesDelete?: OnNodesDelete;
onEdgesDelete?: OnEdgesDelete;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,7 @@
store.syncViewport(viewport);

if (fitView !== undefined) {
store.fitViewOnInit.set(fitView);
}

if (fitViewOptions) {
store.fitViewOptions.set(fitViewOptions);
store.fitViewScheduled.set(fitViewOptions ?? true);
}

updateStore(store, {
Expand Down
26 changes: 18 additions & 8 deletions packages/svelte/src/lib/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,18 @@ export function createStore({
return;
}

if (!get(store.fitViewOnInitDone) && get(store.fitViewOnInit)) {
const fitViewOptions = get(store.fitViewOptions);
const fitViewOnInitDone = fitView(nextNodes, {
...fitViewOptions,
nodes: fitViewOptions?.nodes || nextNodes
});
store.fitViewOnInitDone.set(fitViewOnInitDone);
const fitViewScheduled = get(store.fitViewScheduled);
if (fitViewScheduled) {
const fitViewOptions =
typeof fitViewScheduled === 'boolean'
? { nodes: nextNodes }
: {
...fitViewScheduled,
waitForInit: false,
nodes: fitViewScheduled.nodes ?? nextNodes
};
const fitViewDone = fitView(nextNodes, fitViewOptions);
if (fitViewDone) store.fitViewScheduled.set(false);
}

store.nodes.set(nextNodes);
Expand All @@ -121,6 +126,11 @@ export function createStore({
return false;
}

if (options?.waitForInit) {
store.fitViewScheduled.set(options);
return true; // TODO: What should this return?
}

return fitViewUtil(
{
nodes,
Expand Down Expand Up @@ -330,7 +340,7 @@ export function createStore({
}

function reset() {
store.fitViewOnInitDone.set(false);
// store.fitViewOnInitDone.set(false); // TODO: what implications does this have
store.selectionRect.set(null);
store.selectionRectMode.set(null);
store.snapGrid.set(null);
Expand Down
5 changes: 2 additions & 3 deletions packages/svelte/src/lib/store/initial-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ export const getInitialStore = ({

let viewport: Viewport = { x: 0, y: 0, zoom: 1 };

// this is needed for SSR
if (fitView && width && height) {
const nodesWithDimensions = nextNodes.filter((node) => node.width && node.height);
const bounds = getNodesBounds(nodesWithDimensions, [0, 0]);
Expand All @@ -115,9 +116,7 @@ export const getInitialStore = ({
translateExtent: writable<CoordinateExtent>(infiniteExtent),
autoPanOnNodeDrag: writable<boolean>(true),
autoPanOnConnect: writable<boolean>(true),
fitViewOnInit: writable<boolean>(false),
fitViewOnInitDone: writable<boolean>(false),
fitViewOptions: writable<FitViewOptions>(undefined),
fitViewScheduled: writable<boolean | FitViewOptions>(false),
panZoom: writable<PanZoomInstance | null>(null),
snapGrid: writable<SnapGrid | null>(null),
dragging: writable<boolean>(false),
Expand Down
1 change: 1 addition & 0 deletions packages/system/src/types/general.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export type FitViewOptionsBase<NodeType extends NodeBase> = {
maxZoom?: number;
duration?: number;
nodes?: (NodeType | { id: NodeType['id'] })[];
waitForInit?: boolean;
};

export type Viewport = {
Expand Down