harden(charts): production-hardening pass (follow-up to #3672)#3694
Open
josephfarina wants to merge 17 commits into
Open
harden(charts): production-hardening pass (follow-up to #3672)#3694josephfarina wants to merge 17 commits into
josephfarina wants to merge 17 commits into
Conversation
Co-authored-by: Cursor <cursoragent@cursor.com>
…t net totals Co-authored-by: Cursor <cursoragent@cursor.com>
…ext barrel path Co-authored-by: Cursor <cursoragent@cursor.com>
…ows and whitespace paints Co-authored-by: Cursor <cursoragent@cursor.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
PR Analysis Report📚 Storybook PreviewView Storybook for this PR 🧪 Sandbox PreviewView Sandbox for this PR No new or modified components detected. Bundle Size Summary
Accessibility AuditStatus: No accessibility violations detected. Generated by PR Enrichment workflow | Storybook | Sandbox | View full report |
…d errorBar cap width Co-authored-by: Cursor <cursoragent@cursor.com>
…urce leak Co-authored-by: Cursor <cursoragent@cursor.com>
…eractive Co-authored-by: Cursor <cursoragent@cursor.com>
…ror crash Co-authored-by: Cursor <cursoragent@cursor.com>
…d, and stale hovered index Co-authored-by: Cursor <cursoragent@cursor.com>
…trings in formatters Co-authored-by: Cursor <cursoragent@cursor.com>
WebGL heatmap cells were sized to the shared x-scale's bar-padded bandwidth, leaving large gaps between columns while the local y-scale stayed tight — a sparse, asymmetric grid. Size cells to the band step (centered on the band) so they fill their slot: a proper contiguous heatmap, still axis-aligned. Co-authored-by: Cursor <cursoragent@cursor.com>
Cells were sized to xScale.bandwidth(), but the shared x band scale carries ~0.2 padding, so step > bandwidth left permanent gaps between columns that cellGap could not close (a sparse, striped grid instead of a contiguous heatmap). Size cells to the full band step and center them on the band so cellGap alone controls spacing. Applied to both the charts heatmapGL mark and the lab ChartHeatmapGL component. Co-authored-by: Cursor <cursoragent@cursor.com>
A heatmap's rows are categories (e.g. days), but the chart's y-axis was a linear value scale — so a left <ChartAxis> showed meaningless 0-N value ticks and the rows didn't correspond to the axis. Add an opt-in categorical y-axis: a series can declare `layout.yBandKey`, and the layout pass builds a shared `yBandScale` over that key's unique values, exposed on the series/chart context. ChartAxis prefers `yBandScale` for vertical axes, so the left axis renders the row labels aligned to each cell. heatmapGL now declares `dataKeys: []` + `layout.yBandKey` and draws rows from the shared band scale, keeping cells aligned with the axis and out of the linear y-domain / value tooltip. Co-authored-by: Cursor <cursoragent@cursor.com>
A heatmap's categorical y-axis leaves the linear y-domain degenerate and spanning zero, so ChartAxis' "draw the bottom edge line at zero" rule placed the x-axis line mid-plot, cutting across the cells. Anchor the bottom edge line to the plot edge whenever the y-axis is categorical (yBandScale present), and fill heatmap rows edge-to-edge (band padding 0) so the grid meets both axis lines. The WebGL heatmap story now enables the x and y axis lines, which frame the grid at its edges. Co-authored-by: Cursor <cursoragent@cursor.com>
For a categorical grid (heatmap), the x band scale still carried the bar-style outer padding (0.2), so columns were inset ~4-5px from the left/right axis lines while the rows (padding 0) sat flush top/bottom — an asymmetric, gappy look. When the y-axis is categorical, drop the x padding too so the grid fills the plot edge-to-edge and meets both axis lines flush on every side. Also hoists the yBandKey detection so x and y share it. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.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
Follow-up to #3672 (merged). A complete, line-by-line hardening pass over every file in
@astryxdesign/charts— defensive robustness and correctness only. No new features, no API/type-contract changes, no scope creep. Package stays private / canary-only. All 31 source files were audited one slice at a time, each change typecheck-gated; full verification (typecheck + lint + build + Storybook consumer typecheck) passes.Genuine bugs fixed
layout.ts) — mixed-sign andyBaseline: 'data'stacks rendered outside the scale and clipped; the domain now walks every layer boundary.dotGLInteractive) —readPixelssampled one row too high (top-edge miss); fixed totexH - 1 - py.tickCountcrash (ChartAxis/ChartGrid) — an out-of-range count reaching d3.ticks()throwsRangeError; now clamped.getChartColors) —Infinityslipped past the guard into a ~2^53Array.fromallocation (hang/OOM); now rejected.render-null card reappeared + stale hovered-index "undefined" card (ChartTooltip); plus NaN guards on the hover dots and crosshair.createProgramshader leak (webgl.ts) — shaders orphaned on the compile-failure path and never flagged for deletion after link.xPixelinput,Chartsize (a non-finiteheight/margin no longer collapses every scale),errorBarcap width, and date-only strings in formatters.Robustness / hygiene
'use client'on the barrel-exportedChartContext.xPixel/isBandScalehelpers (removed unsafe casts).Files audited and found already solid (left unchanged to avoid churn):
bar/line/area,heatmapGL/streamGL,dotGL,legend.ts,ChartSwatch,useChartColors,index.ts, and most oftypes.ts.Test plan
chartstypecheck, lint, build all cleanMade with Cursor
Update — categorical-y heatmap stacked on this branch
feat/charts-hardeningnow also carries the categorical-y heatmap fast-follow on top of the hardening pass: