fix: chart resize and dynamic y-axis for non-line chart types in Explore - #9808
Merged
nishantmonu51 merged 3 commits intoAug 18, 2026
Merged
Conversation
The explore timeseries area has two renderers: a custom SVG one for the default/line types, and Vega-Lite for grouped bar, stacked bar and stacked area. Neither the resize divider nor the dynamic y-axis toggle was wired into the Vega path. - Add `min-w-0` to the chart grid cells in `MetricsTimeSeriesCharts`. The `1fr` track's floor is its item's min-content size; the Vega `<canvas>` has an intrinsic pixel width, so the column could grow but never shrink past the last width Vega drew at. The container therefore never shrank, `contentRect` never fired, and the chart never re-rendered smaller. - Thread `dynamicYAxis` through `MeasureChart` and `TDDChart` into `createTDDCartesianSpec` as `zeroBasedOrigin`. The field was previously unset, and `builder.ts` emits `zero: false` whenever it is not `true`, so every Vega chart was permanently dynamic and bar charts drew from a non-zero baseline even with the toggle off. - Clamp the zero baseline in `BarChart` and the area generator in `TimeSeriesChart`. With a dynamic axis the domain can exclude zero, putting `yScale(0)` outside the clipped plot, which rendered bars as full-height slabs and flooded the area fill. `MeasureChartBody` and `MeasureChartTooltip` already clamped the same value. - Split `createEmbedOptions` into `createBaseEmbedOptions` plus a width/height spread at the call site. svelte-vega compares options key by key with `===`, ignoring width and height, so the fresh `tooltip`/`loader`/`config` objects made it tear down and re-embed the whole view on every frame of a drag. It now resizes the existing view and keeps brush state. Claude-Session: https://claude.ai/code/session_01DT291cEZct4NiwpGFbyq7o
Wiring `zeroBasedOrigin` through to the spec was not enough. Vega-Lite stacks
bar and area marks by default, and a stacked scale derives its domain from the
stack's start/end fields, which always span zero. `scale.zero: false` was
compiled into the Vega spec but had nothing to act on, so the toggle stayed
inert. Compiling the spec confirms it: the domain was
`{fields: ["total_start", "total_end"]}` in both states.
Add `createStackOverride`, which emits `stack: null` when the origin is not
zero-based, and apply it in the grouped bar, stacked bar and area builders. It
is guarded on the absence of a color field: un-stacking a multi-series chart
would overlap its marks rather than stack them, so those stay zero-based.
The single-series bar chart now compiles to `{field: "total_sales"}` with
`zero: false`. Covered by tests that compile all the way down to Vega, since
the `zero` flag alone does not tell you whether the axis is actually dynamic.
Claude-Session: https://claude.ai/code/session_01DT291cEZct4NiwpGFbyq7o
AdityaHegde
approved these changes
Aug 18, 2026
nishantmonu51
deleted the
nishant/fix-explore-chart-resize-and-dynamic-y-axis
branch
August 18, 2026 08:53
nishantmonu51
added a commit
that referenced
this pull request
Aug 18, 2026
…ore (#9808) * fix: chart resize and dynamic y-axis for non-line explore chart types The explore timeseries area has two renderers: a custom SVG one for the default/line types, and Vega-Lite for grouped bar, stacked bar and stacked area. Neither the resize divider nor the dynamic y-axis toggle was wired into the Vega path. - Add `min-w-0` to the chart grid cells in `MetricsTimeSeriesCharts`. The `1fr` track's floor is its item's min-content size; the Vega `<canvas>` has an intrinsic pixel width, so the column could grow but never shrink past the last width Vega drew at. The container therefore never shrank, `contentRect` never fired, and the chart never re-rendered smaller. - Thread `dynamicYAxis` through `MeasureChart` and `TDDChart` into `createTDDCartesianSpec` as `zeroBasedOrigin`. The field was previously unset, and `builder.ts` emits `zero: false` whenever it is not `true`, so every Vega chart was permanently dynamic and bar charts drew from a non-zero baseline even with the toggle off. - Clamp the zero baseline in `BarChart` and the area generator in `TimeSeriesChart`. With a dynamic axis the domain can exclude zero, putting `yScale(0)` outside the clipped plot, which rendered bars as full-height slabs and flooded the area fill. `MeasureChartBody` and `MeasureChartTooltip` already clamped the same value. - Split `createEmbedOptions` into `createBaseEmbedOptions` plus a width/height spread at the call site. svelte-vega compares options key by key with `===`, ignoring width and height, so the fresh `tooltip`/`loader`/`config` objects made it tear down and re-embed the whole view on every frame of a drag. It now resizes the existing view and keeps brush state. Claude-Session: https://claude.ai/code/session_01DT291cEZct4NiwpGFbyq7o * fix: disable implicit stacking so the dynamic y-axis takes effect Wiring `zeroBasedOrigin` through to the spec was not enough. Vega-Lite stacks bar and area marks by default, and a stacked scale derives its domain from the stack's start/end fields, which always span zero. `scale.zero: false` was compiled into the Vega spec but had nothing to act on, so the toggle stayed inert. Compiling the spec confirms it: the domain was `{fields: ["total_start", "total_end"]}` in both states. Add `createStackOverride`, which emits `stack: null` when the origin is not zero-based, and apply it in the grouped bar, stacked bar and area builders. It is guarded on the absence of a color field: un-stacking a multi-series chart would overlap its marks rather than stack them, so those stay zero-based. The single-series bar chart now compiles to `{field: "total_sales"}` with `zero: false`. Covered by tests that compile all the way down to Vega, since the `zero` flag alone does not tell you whether the axis is actually dynamic. Claude-Session: https://claude.ai/code/session_01DT291cEZct4NiwpGFbyq7o * chore: fix prettier formatting in tdd-chart-config.spec.ts Claude-Session: https://claude.ai/code/session_01Mj1YdKjgEEEwHNXwdhob6E (cherry picked from commit ce24ebc)
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.
Explore's timeseries area has two renderers: a custom SVG one for the default/line types, and Vega-Lite for grouped bar, stacked bar and stacked area (
usesVegaRendererinchart-series.ts). Neither the resize divider nor the dynamic y-axis toggle was wired into the Vega path.min-w-0to the chart grid cells inMetricsTimeSeriesCharts.svelte. A1frtrack's floor is its item's min-content size, and the Vega<canvas>has an intrinsic pixel width, so the column could grow but never shrink past the last width Vega drew at. The container therefore never shrank,bind:contentRectnever fired, and the chart never re-rendered smaller. The SVG chart is aw-full<svg>with no intrinsic width, which is why only the line chart resized correctly.dynamicYAxisthroughMeasureChartandTDDChartintocreateTDDCartesianSpecaszeroBasedOrigin. The field was previously never set, andbuilder.tsemitszero: falsewhenever it is nottrue, so every Vega chart was permanently dynamic — bar charts drew from a non-zero baseline even with the toggle off, and toggling it had no effect.zeroYinBarChart.svelteand the area generator'sy0inTimeSeriesChart.sveltevia a newclampToRangehelper. With a dynamic axis the domain can exclude zero, puttingyScale(0)outside the clipped plot, which rendered bars as full-height slabs and flooded the area fill.MeasureChartBodyandMeasureChartTooltipalready clamped the same value. Reachable in Explore whenever the default chart type falls under six points.createEmbedOptionsintocreateBaseEmbedOptionsplus awidth/heightspread at the call site. svelte-vega compares options key by key with===, ignoring width and height, so the freshtooltip/loader/configobjects made it tear down and re-embed the whole view on every frame of a drag. It now callsview.width()on the existing view, which also fixes brush state being lost on resize — something the existingspec/colorMappingmemoization was already trying to achieve. Applied toVegaRenderer.sveltetoo, since canvas dashboards hit the same path.Checklist:
https://claude.ai/code/session_01DT291cEZct4NiwpGFbyq7o