Skip to content

feat(chart): React-native tooltip for TimeseriesChart#537

Merged
mattrothenberg merged 11 commits into
cloudflare:mainfrom
Ankcorn:tankcorn/timeseries-tooltip-react
May 28, 2026
Merged

feat(chart): React-native tooltip for TimeseriesChart#537
mattrothenberg merged 11 commits into
cloudflare:mainfrom
Ankcorn:tankcorn/timeseries-tooltip-react

Conversation

@Ankcorn
Copy link
Copy Markdown
Member

@Ankcorn Ankcorn commented May 26, 2026

Why

The existing tooltip was built on ECharts' HTML-string formatter — inline styles, any types everywhere, getComputedStyle called on every mouse move to read CSS variables, and a dead dimColor variable that was computed but never used. It also couldn't escape its containing element, so tooltips were clipped when the chart was inside a constrained layout.

What changed

image image

Tooltip is now a proper React component rendered via createPortal into document.body, wrapped in a data-mode div so Kumo CSS variables resolve correctly despite being outside the component tree.

Positioning is decoupled from content (same architecture as ECharts' own implementation):

  • Content flows through React state via the updateAxisPointer event — one render cycle behind, imperceptible for text
  • Position is driven by direct DOM mutation in a native mousemove listener using transform: translate3d (GPU-composited, no layout cost). Quadrant-based anchoring flips the tooltip side when the cursor crosses the chart midpoint, with a cubic-bezier(0.23,1,0.32,1) transition on switches.

New props:

  • tooltipMode: "all" (default) | "single" — single mode shows only the series nearest the cursor, useful for dense charts
  • tooltipMaxItems: caps rows in "all" mode with a +N more footer (default 10)

Other improvements:

  • Values sorted descending so the highest series appears first
  • Date formatted as May 26, 13:04:21 instead of ISO string
  • Fallback value formatter uses toLocaleString — no scientific notation
  • findNearest binary search replaces ECharts series index lookup

Alternatives considered

Keeping ECharts' formatter but injecting computed CSS variable values — simpler but still getComputedStyle on every hover, still HTML strings, still no real types.


  • Reviews
  • bonk has reviewed the change
  • automated review not possible because: tooltip behaviour is visual/interactive, not unit-testable without a browser
  • Tests
  • Additional testing not necessary because: covered by the new ManySeriesChartDemo in the docs site which exercises truncation, formatting, and positioning

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 26, 2026

npm i https://pkg.pr.new/@cloudflare/kumo@537

commit: f82370a

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 26, 2026

Docs Preview

View docs preview

Commit: f82370a

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 26, 2026

Visual Regression Report — 16 changed, 23 unchanged

16 screenshot(s) with visual changes:

Button / With Icon

422 px (0.42%) changed

Before After Diff
Before After Diff

Button / Loading State

193 px (0.19%) changed

Before After Diff
Before After Diff

Button / Disabled State

232 px (0.23%) changed

Before After Diff
Before After Diff

Button / Link as Button

745 px (0.73%) changed

Before After Diff
Before After Diff

Dialog / Dialog Alert

744 px (0.73%) changed

Before After Diff
Before After Diff

Dialog / Dialog With Dropdown

130 px (0.13%) changed

Before After Diff
Before After Diff

Select / Select Basic

534 px (0.53%) changed

Before After Diff
Before After Diff

Select / Select Without Label

161 px (0.16%) changed

Before After Diff
Before After Diff

Select / Select With Description

889 px (0.75%) changed

Before After Diff
Before After Diff

Select / Select Loading

0 px (0%) changed

Before After Diff
Before After Diff

Select / Select Complex

1,090 px (0.92%) changed

Before After Diff
Before After Diff

Select / Select Disabled Items

176 px (0.17%) changed

Before After Diff
Before After Diff

Select / Select Grouped

194 px (0.19%) changed

Before After Diff
Before After Diff

Select / Select Grouped With Disabled

736 px (0.72%) changed

Before After Diff
Before After Diff

Select / Select Long List

1,683 px (1.42%) changed

Before After Diff
Before After Diff

Select (Open)

0 px (0%) changed

Before After Diff
Before After Diff
23 screenshot(s) unchanged
  • Button / Basic
  • Button / Variant: Primary
  • Button / Variant: Secondary
  • Button / Variant: Ghost
  • Button / Variant: Destructive
  • Button / Variant: Outline
  • Button / Variant: Secondary Destructive
  • Button / Sizes
  • Button / Icon Only
  • Button / Title
  • Dialog / Dialog With Actions
  • Dialog / Dialog Basic
  • Dialog / Dialog Confirmation
  • Dialog / Dialog With Select
  • Dialog / Dialog With Combobox
  • Dialog (Open)
  • Select / Select Sizes
  • Select / Select With Error
  • Select / Select Placeholder
  • Select / Select With Tooltip
  • Select / Select Custom Rendering
  • Select / Select Multiple
  • Select / Select Disabled Options

Generated by Kumo Visual Regression

@Ankcorn Ankcorn marked this pull request as ready for review May 26, 2026 16:59
@geoquant
Copy link
Copy Markdown
Collaborator

/bonk review

@ask-bonk
Copy link
Copy Markdown
Contributor

ask-bonk Bot commented May 26, 2026

UnknownError: ProviderInitError

github run

@ask-bonk
Copy link
Copy Markdown
Contributor

ask-bonk Bot commented May 26, 2026

@mattrothenberg Bonk workflow was cancelled.

View workflow run · To retry, trigger Bonk again.

@Ankcorn Ankcorn force-pushed the tankcorn/timeseries-tooltip-react branch from 71ebe97 to 0412910 Compare May 26, 2026 18:22
Ankcorn and others added 7 commits May 26, 2026 14:26
…rolled DOM mutation

- Replace manual mousemove/translate3d positioning with Base UI's
  Tooltip primitive and trackCursorAxis
- Add tooltipFollowCursor prop ('both' | 'x') for axis-locked mode
- Add tooltipMode and tooltipMaxItems props from Thomas's original work
- Memoize TooltipContent, cache Intl.NumberFormat at module scope
- Match tooltip styling to kumo's standard Tooltip (bg-kumo-base,
  outline-kumo-fill, shadow-kumo-tip-shadow)
- Add interactive TooltipFollowCursorDemo to timeseries docs page
- Register ToolboxComponent in chart demos to fix console warning
@mattrothenberg mattrothenberg force-pushed the tankcorn/timeseries-tooltip-react branch from 0412910 to becf88e Compare May 26, 2026 18:26
@mattrothenberg
Copy link
Copy Markdown
Collaborator

/bonk what do you think of these changes?

@mattrothenberg
Copy link
Copy Markdown
Collaborator

/bonk please thoroughly review our changes here, looking for subtle API breakages, performance issues, etc

@ask-bonk
Copy link
Copy Markdown
Contributor

ask-bonk Bot commented May 28, 2026

I fetched the PR diff, read all changed files plus the base EChart.tsx component, investigated Base UI Tooltip type definitions to verify trackCursorAxis/collisionAvoidance API compatibility, confirmed ECharts lowercases event names internally (so updateaxispointer is correct), ran the workspace typecheck, and cross-checked semantic token usage against existing Kumo components to prepare a thorough review.

github run

@mattrothenberg mattrothenberg merged commit 18f5e42 into cloudflare:main May 28, 2026
15 checks passed
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.

3 participants