feat: Zoom for cartesian charts - #216
Draft
georgylobko wants to merge 9 commits into
Draft
Conversation
georgylobko
requested review from
avinashbot
and removed request for
a team and
avinashbot
May 5, 2026 09:14
georgylobko
marked this pull request as draft
May 5, 2026 09:14
georgylobko
force-pushed
the
feat/zoom
branch
2 times, most recently
from
July 1, 2026 21:34
47cf11f to
1136df3
Compare
There was a problem hiding this comment.
Pull request overview
Adds end-user zoom interactions to the CartesianChart component, including drag-to-zoom and an accessible “zoom mode” with keyboard/pointer alternatives, plus the necessary API surface, styling, and tests to support it.
Changes:
- Introduces
zoom,zoomRange, andonZoomRangeChangeprops, plus ref methods (enterZoomMode,exitZoomMode,resetZoom) for programmatic control. - Implements zoom-mode UI/overlays (selection band, cursor/range dividers, portal-rendered cursor buttons) and controlled/uncontrolled zoom behaviors.
- Adds comprehensive unit tests and a dev page demonstrating uncontrolled vs controlled zoom usage.
Reviewed changes
Copilot reviewed 16 out of 17 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| src/test-utils/dom/cartesian-chart/index.ts | Extends CartesianChart test wrapper with zoom-control finders (including portal-rendered cursor buttons). |
| src/internal/components/zoom-cursor-buttons/test-classes/styles.scss | Adds test-only selectors for zoom cursor direction buttons. |
| src/internal/components/zoom-cursor-buttons/styles.scss | Adds styling for portal overlay and cursor direction buttons. |
| src/internal/components/zoom-cursor-buttons/portal-overlay.tsx | New portal overlay component to align cursor controls with a tracked element. |
| src/internal/components/zoom-cursor-buttons/direction-button.tsx | New direction button component used by zoom cursor controls. |
| src/core/styles.scss | Adds cursor styling for Highcharts navigator mask while dragging. |
| src/core/interfaces.ts | Extends cartesian i18n strings with zoom-related labels and announcements. |
| src/cartesian-chart/test-classes/styles.scss | Adds test selectors for zoom-related buttons. |
| src/cartesian-chart/styles.scss | Adds zoom controls positioning and selection-band/cursor-track styles. |
| src/cartesian-chart/interfaces.ts | Adds public zoom props (zoom, zoomRange) and zoom ref methods/events. |
| src/cartesian-chart/chart-cartesian-internal.tsx | Implements zoom mode state machine, overlays, keyboard/mouse interactions, and controlled/uncontrolled zoom handling. |
| src/cartesian-chart/tests/cartesian-chart-zoom.test.tsx | Adds unit tests covering zoom UI states, keyboard interactions, drag dividers, controlled mode, and i18n. |
| src/tests/snapshots/documenter.test.ts.snap | Updates API snapshot for new zoom props/events/ref methods and i18n strings. |
| pages/common/use-highcharts.ts | Refactors parameter typing/formatting (no functional change). |
| pages/01-cartesian-chart/zoom.page.tsx | Adds dev page demonstrating zoom behaviors and controlled/uncontrolled patterns. |
| pages/01-cartesian-chart/axes-and-thresholds.page.tsx | Reorders imports after adding the new zoom page (formatting-only). |
| .gitignore | Ignores common IDE directories (.idea, .vscode). |
Suppressed comments (2)
src/cartesian-chart/chart-cartesian-internal.tsx:839
zoomedis derived using truthiness (!!(e.userMin || e.userMax)), which misclassifies a zoom when either extreme is0(valid value). This can cause zoom-reset logic to run incorrectly for ranges that start/end at 0.
const zoomed = !!(e.userMin || e.userMax);
src/cartesian-chart/chart-cartesian-internal.tsx:679
- This effect attaches the keydown listener to the global
document, which breaks when the chart is rendered in a different document (e.g. iframe) and can also make cleanup run against the wrong document. Use the chart container'sownerDocumentinstead.
document.addEventListener("keydown", onKeyDown);
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+359
to
+363
| if (props.zoomRange === undefined) { | ||
| xAxis?.setExtremes(min, max); | ||
| setZoomMode("zoomed"); | ||
| setZoomedExtremes({ min, max }); | ||
| } |
Comment on lines
+51
to
+58
| if (track.current && ref.current && document.body.contains(ref.current)) { | ||
| const isRtl = getIsRtl(ref.current); | ||
| const { insetInlineStart, insetBlockStart, inlineSize, blockSize } = getLogicalBoundingClientRect( | ||
| track.current, | ||
| ); | ||
| const newX = (insetInlineStart + getScrollInlineStart(document.documentElement)) * (isRtl ? -1 : 1); | ||
| const newY = insetBlockStart + document.documentElement.scrollTop; | ||
| if (lastX !== newX || lastY !== newY) { |
Comment on lines
+798
to
+802
| // Move the cursor-tracking element into the chart container, so the direction buttons can be | ||
| // positioned relative to the plot through the portal overlay. | ||
| if (cursorTrackRef.current && !api.chart.container.contains(cursorTrackRef.current)) { | ||
| api.chart.container.style.position = "relative"; | ||
| api.chart.container.appendChild(cursorTrackRef.current); |
Comment on lines
+581
to
+585
| document.addEventListener("mouseup", onMouseUp); | ||
|
|
||
| return () => { | ||
| disposed = true; | ||
| document.removeEventListener("mouseup", onMouseUp); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Zoom functionality for cartesian charts.
Screen.Recording.2026-07-01.at.9.30.32.PM.mov
Related links, issue #, if available: n/a
How has this been tested?
Review checklist
The following items are to be evaluated by the author(s) and the reviewer(s).
Correctness
CONTRIBUTING.md.CONTRIBUTING.md.Security
checkSafeUrlfunction.Testing
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.