Skip to content

refactor: hookify min zoom, use in all charts - #446

Merged
rapids-bot[bot] merged 10 commits into
rapidsai:mainfrom
johallar:min-zoom-reusable-hook
Jul 28, 2026
Merged

refactor: hookify min zoom, use in all charts#446
rapids-bot[bot] merged 10 commits into
rapidsai:mainfrom
johallar:min-zoom-reusable-hook

Conversation

@johallar

@johallar johallar commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Description

  • Fixes a bug where users could zoom indefinitely from the operator timeline
  • Captures horizontal scrolling as well, so operator timelines can horizontal scroll

Related Issues

Fixes #445

Testing

  1. Hover over timeline and shift + scroll to scroll in as far as possible
  2. Expect it should stop at the minimum bin size
  3. Zoom back out
  4. Hover an operator timeline and shift + scroll to zoom as far as possible
  5. Expect it to stop at min bin size
  6. Horizontal scroll on timelines and operator timelines, should not require shift keypress.

Screenshots

Screen.Recording.2026-07-27.at.12.54.20.PM.mov

@johallar johallar added the bug Something isn't working label Jul 23, 2026
@johallar
johallar marked this pull request as ready for review July 27, 2026 18:59
@johallar
johallar requested a review from cmatzenbach as a code owner July 27, 2026 18:59
@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Timeline charts now share minimum zoom-span calculation, enforce the minimum during shift-wheel zooming, support horizontal wheel panning, and clean up chart listeners through a reusable navigation hook. Timeline and operator Gantt chart integrations apply the shared span to ECharts dataZoom controls.

Changes

Timeline zoom navigation

Layer / File(s) Summary
Shared minimum zoom-span calculation
ui/packages/@quent/components/src/lib/useMinZoomSpanPct.ts, ui/packages/@quent/components/src/lib/useMinZoomSpanPct.test.ts, ui/packages/@quent/components/src/timeline/TimelineController.tsx
Adds a capped, memoized minimum-span hook, tests its boundary behavior, and replaces duplicated duration-based calculations in TimelineController.
Wheel navigation behavior and cleanup
ui/packages/@quent/components/src/lib/useTimelineWheelNavigation.ts, ui/packages/@quent/components/src/lib/useTimelineWheelNavigation.test.ts
Adds horizontal wheel panning, shift-wheel minimum-span enforcement, dataZoom updates, and listener cleanup with tests.
Timeline chart integration
ui/packages/@quent/components/src/timeline/Timeline.tsx, ui/packages/@quent/components/src/operator-timeline/OperatorGanttChart.tsx
Applies the shared minimum span to ECharts dataZoom configurations and delegates chart wheel handling to the new navigation hook.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

  • rapidsai/quent#384: Refactors related capture-phase wheel panning for ECharts dataZoom windows.

Suggested labels: ui, non-breaking

Suggested reviewers: cmatzenbach, johanpel

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and matches the main change: refactoring min-zoom handling into hooks used across charts.
Description check ✅ Passed The description includes the purpose, linked issue, testing steps, and screenshots, matching the required template well.
Linked Issues check ✅ Passed The changes address #445 by enforcing the minimum zoom span and applying it across timeline charts, preventing unlimited zoom.
Out of Scope Changes check ✅ Passed The added hooks, chart wiring, and tests are all directly related to minimum zoom enforcement and scroll navigation.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Note

Quiet mode is enabled, so only the most important comments were posted inline. Other review comments are grouped below.

🟡 Other comments (1)
ui/packages/@quent/components/src/lib/useTimelineWheelNavigation.ts-31-38 (1)

31-38: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

atZoomLimit goes stale when minZoomSpanPct changes.

attachWheelNavigation is memoized with empty deps and only called from onChartReady, so updateZoomLimit re-evaluates exclusively on ECharts datazoom events. If durationSeconds (and therefore minZoomSpanPct) changes while the chart instance is alive and already zoomed to the floor, the cached flag keeps blocking Shift+scroll zoom-in until the next datazoom event — but such an event can no longer be produced, since zoom-in is what's being blocked.

Reading the span at wheel time removes the cache, the listener, and the staleness in one go; ECharts' own minSpan still provides the hard floor.

🐛 Proposed fix: evaluate the limit lazily
-      let atZoomLimit = false;
-      const updateZoomLimit = () => {
-        if (instance.isDisposed?.()) return;
-        const dataZoom = getDataZoomState(instance);
-        if (!dataZoom) return;
-        const spanPct = (dataZoom.end ?? 100) - (dataZoom.start ?? 0);
-        atZoomLimit = spanPct <= minZoomSpanPctRef.current * 1.01;
-      };
+      const isAtZoomLimit = () => {
+        if (instance.isDisposed?.()) return false;
+        const dataZoom = getDataZoomState(instance);
+        if (!dataZoom) return false;
+        const spanPct = (dataZoom.end ?? 100) - (dataZoom.start ?? 0);
+        return spanPct <= minZoomSpanPctRef.current * 1.01;
+      };
 
       const handleWheel = (event: WheelEvent) => {
         if (event.shiftKey) {
           const zoomDelta = event.deltaY || event.deltaX;
-          if (zoomDelta < 0 && atZoomLimit) {
+          if (zoomDelta < 0 && isAtZoomLimit()) {
             event.preventDefault();
             event.stopPropagation();
           }
           return;
         }
-      updateZoomLimit();
-      instance.on('datazoom', updateZoomLimit);
       wheelTarget.addEventListener('wheel', handleWheel, { capture: true, passive: false });
 
       cleanupRef.current = () => {
         wheelTarget.removeEventListener('wheel', handleWheel, { capture: true });
-        if (!instance.isDisposed?.()) instance.off('datazoom', updateZoomLimit);
       };

Note: useTimelineWheelNavigation.test.ts would need its emitDataZoom/off assertions updated accordingly.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ui/packages/`@quent/components/src/lib/useTimelineWheelNavigation.ts around
lines 31 - 38, Update attachWheelNavigation and its wheel-handler path to
evaluate the current zoom span lazily when handling Shift+scroll, rather than
caching atZoomLimit through updateZoomLimit or datazoom listeners. Remove the
stale flag and related listener bookkeeping while preserving ECharts minSpan as
the hard limit; adjust useTimelineWheelNavigation.test.ts expectations for the
removed emitDataZoom/off behavior.
🧹 Nitpick comments (3)
ui/packages/@quent/components/src/lib/useTimelineWheelNavigation.test.ts (2)

114-128: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add coverage for the pan clamp boundaries.

newStart is clamped by Math.max(0, Math.min(100 - spanPct, …)) in useTimelineWheelNavigation.ts (Line 67), and no test exercises either bound. Two cases — panning left at start: 0 and panning right at end: 100 — pin the window to the range edges instead of drifting out of bounds.

As per path instructions, tests should cover "observable behavior, fallback/unknown inputs, empty/error states" and "meaningful boundary coverage".

💚 Proposed additional cases
it.each([
  { dataZoom: { start: 0, end: 50 }, deltaX: -100, expected: 0 },
  { dataZoom: { start: 50, end: 100 }, deltaX: 100, expected: 50 },
])('clamps panning at the range edges', ({ dataZoom, deltaX, expected }) => {
  const chart = createChart(dataZoom);
  const { result } = renderHook(() => useTimelineWheelNavigation(10));
  act(() => result.current(chart.instance));

  act(() => {
    chart.dom.dispatchEvent(new WheelEvent('wheel', { deltaX, bubbles: true, cancelable: true }));
  });

  expect(chart.dispatchAction).toHaveBeenCalledWith(
    expect.objectContaining({ start: expected, end: expected + 50 })
  );
});
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ui/packages/`@quent/components/src/lib/useTimelineWheelNavigation.test.ts
around lines 114 - 128, Add boundary coverage to the useTimelineWheelNavigation
tests by parameterizing cases for panning left from start 0 and right from end
100. Dispatch the corresponding wheel events and assert chart.dispatchAction
receives a window clamped to the range edges, preserving the existing span.

Source: Path instructions


41-60: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Expected start: 30 silently encodes TIMELINE_SPACING.

The 1010px mock width and the expected 5% shift only line up because TIMELINE_SPACING.left + right === 10. Importing the constant and computing the expected delta makes the assertion self-explanatory and immune to spacing changes.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ui/packages/`@quent/components/src/lib/useTimelineWheelNavigation.test.ts
around lines 41 - 60, Update the horizontal wheel navigation test around
useTimelineWheelNavigation to import and use the TIMELINE_SPACING constant when
calculating the expected dataZoom start/end shift, rather than hardcoding start:
30 and end: 80. Preserve the existing event prevention and dispatch assertions
while deriving the delta from the mock chart width and configured spacing.
ui/packages/@quent/components/src/lib/useTimelineWheelNavigation.ts (1)

37-37: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Document the 1.01 tolerance.

The magic factor absorbs float drift between the dispatched span and ECharts' clamped span; a terse comment (or a named constant) keeps the intent from being read as an arbitrary fudge.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ui/packages/`@quent/components/src/lib/useTimelineWheelNavigation.ts at line
37, Document the purpose of the 1.01 tolerance in the atZoomLimit calculation
within useTimelineWheelNavigation, explaining that it compensates for
floating-point drift between the dispatched span and ECharts’ clamped span. Use
a concise inline comment or a clearly named constant without changing the
existing behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Other comments:
In `@ui/packages/`@quent/components/src/lib/useTimelineWheelNavigation.ts:
- Around line 31-38: Update attachWheelNavigation and its wheel-handler path to
evaluate the current zoom span lazily when handling Shift+scroll, rather than
caching atZoomLimit through updateZoomLimit or datazoom listeners. Remove the
stale flag and related listener bookkeeping while preserving ECharts minSpan as
the hard limit; adjust useTimelineWheelNavigation.test.ts expectations for the
removed emitDataZoom/off behavior.

---

Nitpick comments:
In `@ui/packages/`@quent/components/src/lib/useTimelineWheelNavigation.test.ts:
- Around line 114-128: Add boundary coverage to the useTimelineWheelNavigation
tests by parameterizing cases for panning left from start 0 and right from end
100. Dispatch the corresponding wheel events and assert chart.dispatchAction
receives a window clamped to the range edges, preserving the existing span.
- Around line 41-60: Update the horizontal wheel navigation test around
useTimelineWheelNavigation to import and use the TIMELINE_SPACING constant when
calculating the expected dataZoom start/end shift, rather than hardcoding start:
30 and end: 80. Preserve the existing event prevention and dispatch assertions
while deriving the delta from the mock chart width and configured spacing.

In `@ui/packages/`@quent/components/src/lib/useTimelineWheelNavigation.ts:
- Line 37: Document the purpose of the 1.01 tolerance in the atZoomLimit
calculation within useTimelineWheelNavigation, explaining that it compensates
for floating-point drift between the dispatched span and ECharts’ clamped span.
Use a concise inline comment or a clearly named constant without changing the
existing behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: QUIET

Plan: Enterprise

Run ID: 2b96eff3-6605-4fc9-adea-3edad0cba177

📥 Commits

Reviewing files that changed from the base of the PR and between b5ae4c7 and da631a6.

📒 Files selected for processing (7)
  • ui/packages/@quent/components/src/lib/useMinZoomSpanPct.test.ts
  • ui/packages/@quent/components/src/lib/useMinZoomSpanPct.ts
  • ui/packages/@quent/components/src/lib/useTimelineWheelNavigation.test.ts
  • ui/packages/@quent/components/src/lib/useTimelineWheelNavigation.ts
  • ui/packages/@quent/components/src/operator-timeline/OperatorGanttChart.tsx
  • ui/packages/@quent/components/src/timeline/Timeline.tsx
  • ui/packages/@quent/components/src/timeline/TimelineController.tsx

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
ui/packages/@quent/components/src/lib/useTimelineWheelNavigation.ts (2)

27-34: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Recompute the zoom-limit state when the minimum changes.

atZoomLimit is cached only on attachment and datazoom events. If minZoomSpanPct changes, the cached value can remain permanently stale—for example, a lowered minimum can remain blocked indefinitely, while a raised minimum may allow another zoom step. Derive the limit from the current dataZoom state in the wheel handler or synchronize it whenever the minimum changes.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ui/packages/`@quent/components/src/lib/useTimelineWheelNavigation.ts around
lines 27 - 34, Update the zoom-limit handling in useTimelineWheelNavigation so
changes to minZoomSpanPctRef.current are reflected before processing each wheel
action. Recompute atZoomLimit from the current getDataZoomState(instance) and
latest minimum, or synchronize it when the minimum changes, while preserving the
existing disposed-instance and missing-data guards.

46-70: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Do not consume wheel input unless navigation succeeds.

The handler currently swallows events that it cannot handle, which breaks parent/native scrolling. Validate the gesture, chart state, and resulting range before calling stopPropagation() or preventDefault().

  • ui/packages/@quent/components/src/lib/useTimelineWheelNavigation.ts#L46-L70: defer event consumption until after confirming horizontal dataZoom navigation and a changed range.
  • ui/packages/@quent/components/src/lib/useTimelineWheelNavigation.test.ts#L40-L76: add vertical propagation and boundary/no-dataZoom cases.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ui/packages/`@quent/components/src/lib/useTimelineWheelNavigation.ts around
lines 46 - 70, Defer event consumption in the wheel handler of
useTimelineWheelNavigation until after validating a horizontal gesture, a live
chart with dataZoom state, and a changed clamped range; only then call
stopPropagation, preventDefault, and dispatch dataZoom. In
ui/packages/@quent/components/src/lib/useTimelineWheelNavigation.ts lines 46-70,
preserve propagation for vertical, boundary, disposed, missing-dataZoom, and
no-op navigation cases. In
ui/packages/@quent/components/src/lib/useTimelineWheelNavigation.test.ts lines
40-76, add coverage confirming vertical gestures and boundary/no-dataZoom cases
are not consumed.
🧹 Nitpick comments (1)
ui/packages/@quent/components/src/lib/useTimelineWheelNavigation.test.ts (1)

35-35: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Keep the ECharts mock structurally typed.

as unknown as EChartsType bypasses checks on the mocked getOption, on, off, dispatchAction, and isDisposed surface. Use a Pick<EChartsType, ...>/Partial<EChartsType> fixture with satisfies, or a shared typed builder instead.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ui/packages/`@quent/components/src/lib/useTimelineWheelNavigation.test.ts at
line 35, Update the ECharts mock in the useTimelineWheelNavigation test to use a
structurally typed fixture, such as Pick or Partial of EChartsType with
satisfies, covering getOption, on, off, dispatchAction, and isDisposed. Remove
the as unknown as EChartsType cast while preserving the mock behavior.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@ui/packages/`@quent/components/src/lib/useTimelineWheelNavigation.ts:
- Around line 27-34: Update the zoom-limit handling in
useTimelineWheelNavigation so changes to minZoomSpanPctRef.current are reflected
before processing each wheel action. Recompute atZoomLimit from the current
getDataZoomState(instance) and latest minimum, or synchronize it when the
minimum changes, while preserving the existing disposed-instance and
missing-data guards.
- Around line 46-70: Defer event consumption in the wheel handler of
useTimelineWheelNavigation until after validating a horizontal gesture, a live
chart with dataZoom state, and a changed clamped range; only then call
stopPropagation, preventDefault, and dispatch dataZoom. In
ui/packages/@quent/components/src/lib/useTimelineWheelNavigation.ts lines 46-70,
preserve propagation for vertical, boundary, disposed, missing-dataZoom, and
no-op navigation cases. In
ui/packages/@quent/components/src/lib/useTimelineWheelNavigation.test.ts lines
40-76, add coverage confirming vertical gestures and boundary/no-dataZoom cases
are not consumed.

---

Nitpick comments:
In `@ui/packages/`@quent/components/src/lib/useTimelineWheelNavigation.test.ts:
- Line 35: Update the ECharts mock in the useTimelineWheelNavigation test to use
a structurally typed fixture, such as Pick or Partial of EChartsType with
satisfies, covering getOption, on, off, dispatchAction, and isDisposed. Remove
the as unknown as EChartsType cast while preserving the mock behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: QUIET

Plan: Enterprise

Run ID: 41e819e6-fc3d-4928-9399-3400e4958198

📥 Commits

Reviewing files that changed from the base of the PR and between da631a6 and f9305e6.

📒 Files selected for processing (2)
  • ui/packages/@quent/components/src/lib/useTimelineWheelNavigation.test.ts
  • ui/packages/@quent/components/src/lib/useTimelineWheelNavigation.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
ui/packages/@quent/components/src/lib/useTimelineWheelNavigation.ts (1)

37-48: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Do not intercept vertical wheel events.

Line 47 stops propagation before Line 48 confirms horizontal dominance. Vertical/diagonal wheel events therefore cannot reach parent wheel handlers despite being otherwise ignored. Move stopPropagation() below the guard and assert this in the vertical-wheel test.

Proposed fix
-        event.stopPropagation();
         if (event.deltaX === 0 || Math.abs(event.deltaX) <= Math.abs(event.deltaY)) return;
+        event.stopPropagation();
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ui/packages/`@quent/components/src/lib/useTimelineWheelNavigation.ts around
lines 37 - 48, Update handleWheel so the event.stopPropagation() call occurs
only after the event.deltaX zero/vertical-dominance guard, allowing vertical and
non-horizontal-dominant wheel events to reach parent handlers. Preserve
horizontal handling and add or update the vertical-wheel test to assert
propagation is not intercepted.
🧹 Nitpick comments (1)
ui/packages/@quent/components/src/lib/useTimelineWheelNavigation.test.ts (1)

12-32: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Type the ECharts fixture from its canonical API.

as unknown as EChartsType lets this mock drift from the methods the hook consumes. Define it with Pick<EChartsType, ...> or Partial<EChartsType> before the final narrow cast. As per coding guidelines, “Build test fixtures from canonical production or generated types using Pick, Partial, or shared builders instead of hand-written lookalike interfaces.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ui/packages/`@quent/components/src/lib/useTimelineWheelNavigation.test.ts
around lines 12 - 32, Update the createChart fixture to derive its type from the
canonical EChartsType API using Pick or Partial for the methods it supplies,
then apply only the necessary narrow cast to EChartsType. Replace the current
unknown-to-EChartsType cast while preserving the existing getDom, getOption,
dispatchAction, and isDisposed behavior.

Sources: Coding guidelines, Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@ui/packages/`@quent/components/src/lib/useTimelineWheelNavigation.ts:
- Around line 37-48: Update handleWheel so the event.stopPropagation() call
occurs only after the event.deltaX zero/vertical-dominance guard, allowing
vertical and non-horizontal-dominant wheel events to reach parent handlers.
Preserve horizontal handling and add or update the vertical-wheel test to assert
propagation is not intercepted.

---

Nitpick comments:
In `@ui/packages/`@quent/components/src/lib/useTimelineWheelNavigation.test.ts:
- Around line 12-32: Update the createChart fixture to derive its type from the
canonical EChartsType API using Pick or Partial for the methods it supplies,
then apply only the necessary narrow cast to EChartsType. Replace the current
unknown-to-EChartsType cast while preserving the existing getDom, getOption,
dispatchAction, and isDisposed behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: QUIET

Plan: Enterprise

Run ID: f30b5e39-48d3-4d81-a050-a3ead258bb6a

📥 Commits

Reviewing files that changed from the base of the PR and between f9305e6 and d7ca267.

📒 Files selected for processing (2)
  • ui/packages/@quent/components/src/lib/useTimelineWheelNavigation.test.ts
  • ui/packages/@quent/components/src/lib/useTimelineWheelNavigation.ts

@cmatzenbach cmatzenbach left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Two comments, nothing critical though. Works really well, great job solving the infinite scrolling issue.

Comment thread ui/packages/@quent/components/src/timeline/Timeline.tsx

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@ui/packages/`@quent/components/src/lib/useTimelineWheelNavigation.ts:
- Around line 41-47: Shifted vertical wheel input currently reaches ECharts
instead of panning. In useTimelineWheelNavigation, convert shifted vertical
deltaY into the horizontal pan delta and intercept the event before ECharts
handling; update useTimelineWheelNavigation.test.ts ranges 88-110 and 128-163 to
assert shifted input pans, does not invoke the ECharts wheel handler, and
preserves minimum-span behavior through panning.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: QUIET

Plan: Enterprise

Run ID: e4769929-49d4-4312-a24e-707ee238999e

📥 Commits

Reviewing files that changed from the base of the PR and between d7ca267 and 94a11d7.

📒 Files selected for processing (2)
  • ui/packages/@quent/components/src/lib/useTimelineWheelNavigation.test.ts
  • ui/packages/@quent/components/src/lib/useTimelineWheelNavigation.ts

Comment thread ui/packages/@quent/components/src/lib/useTimelineWheelNavigation.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@ui/packages/`@quent/components/src/operator-timeline/OperatorGanttChart.tsx:
- Around line 343-346: The OperatorGanttChart cleanup must explicitly detach
listeners when operators becomes empty or the chart instance is replaced. Update
the onChartReady/instance lifecycle around registerAxisPointerSync and
attachWheelNavigation to retain the cleanup handles and invoke them before
rendering the empty state and before attaching a new instance, rather than
relying on instanceRef.current changes or final unmount cleanup.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: QUIET

Plan: Enterprise

Run ID: 504205c7-6252-4dca-91a7-b1ac45eed534

📥 Commits

Reviewing files that changed from the base of the PR and between 94a11d7 and 127accd.

📒 Files selected for processing (1)
  • ui/packages/@quent/components/src/operator-timeline/OperatorGanttChart.tsx

@johallar

Copy link
Copy Markdown
Contributor Author

/merge

@rapids-bot
rapids-bot Bot merged commit 863157c into rapidsai:main Jul 28, 2026
15 checks passed
rapids-bot Bot pushed a commit that referenced this pull request Jul 28, 2026
# Description
* Upgrades echarts to 6.x
  * In order to do this we had to ditch the decimal millisecond timestamps which did not render correctly in 6. This now uses value type axes and use the "relative to start" seconds for the axes values (not timestamps).
  * This also allows us to have more precise bins, i've made them 10ns (previously 250)
  * Removes the `startTime` param since everything uses the relative seconds value now, big win IMO
* Removes ignored vulnerability 


## Related Issues

## Testing
* Timelines zoom as before (can zoom in further now but should still limit zoom as before)
* DAG data flow views work as before
Note: #445 Exists still, so the operator timeline won't stop you at the max zoom level and will break things, but will tackle that bug separately in #446

## Screenshots

Authors:
  - Joe O'Hallaron (https://github.com/johallar)

Approvers:
  - Chris Matzenbach (https://github.com/cmatzenbach)

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

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: operator timeline allows unlimited zoom

2 participants