chart: Add appear motion to Plot and every chart - #3296
Merged
Merged
Conversation
Charts now draw their data in the first time they are painted: line, area, candlestick and sankey charts reveal from the left, bars grow out of the zero line one after another, a pie sweeps clockwise and a radar grows from its center. Axes, grids and labels are there from the first frame, and the tooltip waits until the data is whole. Base adds `PlotMotion::with_appear`, `PlotAppear` and the `Plot::appear` / `Plot::appear_generation` hooks, and splits `Plot::interactive` from `Plot::id` so a chart with `interactive(false)` keeps its id for the appear and its path caches. Charts take `appear(false)` and `appear_key(key)`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The gallery is keyed on a generation the button bumps, so every chart gets fresh element state and draws in again. Release notes cover the chart appear motion and the `Plot::interactive` split. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ECharts, Chart.js and Highcharts all default to about a second of drawing in, ApexCharts to 800 ms and Recharts to 1500 ms. The design system's enter curve is an exponential ease-out, nine-tenths done in the first quarter, which made the 500 ms appear read as a flash; data now grows on ECharts' `cubicInOut`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The button joins `story_toolbar_group`, small and outlined like every other story's toolbar. The toolbar stays put while the gallery scrolls, so it holds the gap above the cards instead of the list's padding, and scrolled cards no longer run up against the button. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bars grow out of the zero line together instead of one after another, the way Chart.js, Recharts and ApexCharts draw them, and the appear eases on Chart.js' default `easeOutQuart` over its 1000 ms. Lines and areas keep the reveal from the left that ECharts, Highcharts and Recharts use, which also keeps their cached paths whole. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nges Every new `Plot` method has a default, so existing plots need no changes; the note belongs with the appear motion, not in the list of required migrations. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Summary
Charts now draw their data in the first time they are painted, over 1000 ms on Chart.js' default
easeOutQuart. The mainstream defaults are ECharts, Chart.js and Highcharts at 1000 ms, ApexCharts at 800 ms and Recharts at 1500 ms. The design system's enter curve, an exponential ease-out, made the draw-in read as a flash, so the appear uses its own curve. Each effect follows what the mainstream libraries do (checked against their sources):animateRotate, Recharts); leader-line labels fade in at the endAxes, grid lines and tick labels are there from the first frame, and the tooltip waits until the data is whole. New data paints in place, so charts fed live quotes never replay. Reduced motion skips the appear.
The chart story gets a Replay button that re-keys the gallery so every chart draws in again.
Public API
gpui-basegpui-componentOn
LineChart,AreaChart,BarChart,PieChart,RadarChart,CandlestickChartandSankeyChart:The theme projects
PlotMotion::with_appear(1000 ms, easeOutQuart).Breaking Changes
None at the source level. The three new
Plotmethods all have defaults (interactive→true,appear→ no-op,appear_generation→None), so an existing hand-written plot compiles and behaves exactly as before: with an id it tracks hover as it did, and it tracks no appear and asks for no frames.PlotMotiongains a field behind a builder, and its default adds no motion.Behavior changes worth knowing:
.appear(false).interactive(false)charts now return an id.Plot::idon them isSome(it wasNone), andPlot::interactiveisfalse. They still get no hitbox, but they now keep element state under that id. Like interactive charts, siblings built at one site without.id(...)share the appear state and path caches. That stays correct, but it rebuilds geometry more often.Performance
Once the appear is done, it costs nothing extra: no mask, no frame requests, and
PlotAppearreturns early without sampling the easing. The per-frame state key is allocation-free, and the theme is borrowed rather than cloned.A chart with
.appear(false)(or a hand-written plot that doesn't opt in) tracks no state and requests no frames. Covered by tests.Timing harness (not committed) on 100 line + 100 bar + 50 pie charts, 200 points each,
--release, avg CPU per frame:mainNo regression. Per type during the appear: line 140 ms, bar 139 ms, pie 0.86 ms (vs 0.32 ms steady, from re-tessellating while sweeping).
Test plan
cargo test -p gpui-base -p gpui-component -p gpui-kitinteractive(false)keeps its idcargo clippy -p gpui-base -p gpui-component --lib --tests