Skip to content

Prevent query graph flickering during relayout - #170

Open
vogelsgesang wants to merge 1 commit into
mainfrom
fix-flicker-1
Open

Prevent query graph flickering during relayout#170
vogelsgesang wants to merge 1 commit into
mainfrom
fix-flicker-1

Conversation

@vogelsgesang

Copy link
Copy Markdown
Collaborator

So far, there was some flickering of the edge labels. This was caused because we recreated the node objects we passed into reactflow and reset the measured dimensions. Therefore, reactflow re-measured the nodes and while doing so hid the labels.

We now preserve React Flow's measured dimensions across layout updates so existing nodes remain initialized,

We use React Flow's dimension changes as the sole measurement source and remove the parallel ResizeObserver.

Drive-by fix: each QueryGraph now owns its rendering store, decoupling expansion, subtree, and measurement state between multiple graph instances on the same page.

So far, there was some flickering of the edge labels. This was caused
because we recreated the node objects we passed into reactflow and reset
the `measured` dimensions. Therefore, reactflow re-measured the nodes
and while doing so hid the labels.

We now preserve React Flow's measured dimensions across layout updates
so existing nodes remain initialized,

We use React Flow's dimension changes as the sole measurement source and
remove the parallel ResizeObserver.

Furthermore, each QueryGraph now owns its rendering store, decoupling
expansion, subtree, and measurement state between multiple graph
instances on the same page.
Comment on lines +40 to +41
// Keep React Flow's measurements in the controlled node objects. Dropping them when
// recomputing the layout makes React Flow repeatedly hide and re-initialize the nodes.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Keep React Flow's measurements in the controlled node objects. Dropping them when
// recomputing the layout makes React Flow repeatedly hide and re-initialize the nodes.
// Keep React Flow's measurements in the controlled node objects. Dropping them when
// recomputing the layout would cause React Flow to re-initialize the nodes, leading to visible
// flickering of the edge labels.

// Layout the tree, using the actual measured sizes of the DOM nodes
const nodeDimensions = useGraphRenderingStore((s) => s.nodeDimensions);
const expandedNodes = useGraphRenderingStore((s) => s.expandedNodes);
// Layout the tree using the dimensions measured by React Flow itself.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Layout the tree using the dimensions measured by React Flow itself.
// Layout the tree using the dimensions measured by React Flow

Comment thread query-graphs/README.md

`tree-layout.ts` positions the tree with [`d3-flextree`](https://github.com/Klortho/d3-flextree) on top of `d3-hierarchy`, then translates the result into react-flow nodes and edges.
Layout is driven by the **measured** DOM size of each node, so it runs in two passes: the first render uses a placeholder size and, once the `ResizeObserver` reports real dimensions, the tree re-lays-out with the correct sizes.
Layout is driven by the **measured** DOM size of each node, so it runs in two passes: react-flow measures new nodes after their first render, then the tree re-lays-out with the correct sizes. Those measurements are retained in the controlled node objects so react-flow does not re-initialize them on every layout.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Layout is driven by the **measured** DOM size of each node, so it runs in two passes: react-flow measures new nodes after their first render, then the tree re-lays-out with the correct sizes. Those measurements are retained in the controlled node objects so react-flow does not re-initialize them on every layout.
Layout is driven by the **measured** DOM size of each node, so it runs in two passes: react-flow measures new nodes after their first render, then the tree re-lays-out with the correct sizes.
Those measurements are retained in the controlled node objects so react-flow does not re-initialize them on every layout.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant