Skip to content

fix(graph): roam cannot be restarted after panning the graph out of its initial viewport - #21754

Open
gitlilimin wants to merge 1 commit into
apache:masterfrom
gitlilimin:fix/graph-roam-view-layer
Open

gitlilimin wants to merge 1 commit into
apache:masterfrom
gitlilimin:fix/graph-roam-view-layer

Conversation

@gitlilimin

Copy link
Copy Markdown

What does this PR do?

Fix a bug in the graph series where the roam (pan/zoom) trigger area is glued to the content layer instead of the view layer. After the user pans (or zooms) the graph, the area in which a new pan/zoom gesture can be started moves along with the content and can drift partially or completely out of the viewport, leaving "dead" regions where roam no longer responds.

Root cause

GraphView registers the roam controller's isInSelf check as coordinateSystem.containPoint([x, y]). In View.containPoint, the test rectangle is dataRect transformed by mtOverall, which includes the roam transform — so the trigger area itself pans/zooms together with the content.

With force layout this is even more confusing: nodes have no initial x/y, so dataRect falls back to viewRect (createView.ts, the isNaN(aspect) branch), making the trigger area a static rectangle (approximately the container at init, minus the aspect-preserving padding) that only moves with the roam transform.

Reproduce

  1. Open any force-layout graph with roam: true (e.g. enable roam on the official force layout example).
  2. Pan the graph in one direction for a while.
  3. Try to start a new pan by dragging from an area where the graph initially was not (or use the wheel to zoom there) — nothing happens. The interactive area has moved away together with the content.

Fix

Test the pointer against getViewRect() — the layout viewport in the view layer, which does not include the roam transform — instead of the roam-transformed dataRect. Falls back to the previous containPoint check if the coordinate system does not provide a view rect.

The existing roamTrigger: 'global' option is unaffected (it already bypasses this check entirely); this fix makes the default behavior (roamTrigger unset / 'self') consistent: the trigger area is the series viewport and no longer drifts with pan/zoom.

Test

  • Manually verified with a force-layout graph (~6k nodes / 2.5k edges, roam: true): before the fix, after panning, large dead areas appear where pan/zoom gestures are ignored; after the fix, roam can be started anywhere within the chart viewport regardless of previous pan/zoom.
  • npm run lint passes on the changed file; lib build (build:lib) compiles.

Note: other series that register a similar containPoint-based check (e.g. tree, sankey) may share the same pattern — happy to follow up if you think it is worth aligning.

…/zoom

The roam (pan/zoom) trigger area of the graph series was glued to the
content layer: GraphView registered the roam controller's isInSelf check
as coordinateSystem.containPoint(), which tests the pointer against
dataRect transformed by the roam matrix (mtOverall). The trigger area
therefore moved along with pan/zoom and could drift partially or
completely out of the viewport, leaving dead regions where roam could
no longer be started. With force layout dataRect even falls back to
viewRect (createView.ts isNaN branch), i.e. a static rect glued to the
content layer.

Test the pointer against getViewRect() - the layout viewport in the view
layer, which excludes the roam transform - and fall back to the previous
containPoint() check when no view rect is available.
@echarts-bot

echarts-bot Bot commented Sep 16, 2026

Copy link
Copy Markdown

Thanks for your contribution!
The community will review it ASAP. In the meanwhile, please checkout the coding standard and Wiki about How to make a pull request.

Please DO NOT commit the files in dist, i18n, and ssr/client/dist folders in a non-release pull request. These folders are for release use only.

To reviewers: If this PR is going to be described in the changelog in the future release, please make sure this PR has one of the following labels: PR: doc ready, PR: awaiting doc, PR: doc unchanged

This message is shown because the PR description doesn't contain the document related template.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant