Repository navigation
fix(charts): refuse a cartesian chart that declared no series binding at all (#4695) - #10353
Conversation
… at all
A bar / horizontal-bar / line / area / combo chart handed rows but no
`series` prop (`series === undefined`) drew axes, grid and legend around
zero marks and said nothing. It now renders the objectui#4683
`no-plottable-series` placeholder with its own sentence ("none was
declared") and a console warning naming the row keys. Pie, donut, funnel,
radar and scatter fall back to a `value` column and keep drawing.
The pin that recorded the old silence is rewritten to assert the refusal.
Refs objectui#4695
Co-Authored-By: Claude <noreply@anthropic.com>
…l; add changeset Two objectui#8650 cases pinned a bar chart with no series binding as "mounts and plots nothing". Under the objectui#4695 ruling that shape now refuses, so both wait for the `no-plottable-series` placeholder instead; the positive reading is kept (re-adding the retired read would plot and never refuse). Co-Authored-By: Claude <noreply@anthropic.com>
|
changeset-claim-re-read
|
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
Contract reviewServed-tier: 66/66 Adopted from an isolated at-tier reviewer by ① Derived judgments
② Semver level
③ Boundary flags
Implemented-by: VERDICT: PASS Seat decision: ACCEPT on top of the PASS. The boundary flags are pre-existing forwarding semantics or disclosed choices, and none asks for a fix in this PR. Next: update-branch, then ready + auto-merge once CI is green on the new head. Generated by Claude Code |
Fixes #4695
Clause-②: yes
What changed
A
bar/horizontal-bar/line/area/combochart (andcolumn, normalized tobar) handed data rows but no series binding at all (series === undefined) now refuses loudly instead of drawing axes, grid and legend around zero marks. This is maintainer ruling A on objectui#4695 (relayed in issue comment 5808476637).hasNoPlottableSeries(packages/plugin-charts/src/AdvancedChartImpl.tsx) now returns a discriminant,'empty'or'undeclared'or null, read on the RAW props in the outerAdvancedChartImplwrapper, beforeAdvancedChartImplInner'sseries = []default erases the difference. Its docstring (which used to record theundefinedomission as deliberate) is rewritten.ChartRefusalshell, samerole="status", samedata-chart-error="no-plottable-series"code. No second placeholder. Only the sentence differs:Xaxis."Xaxis."packages/i18n/src/locales/*untouched).The narrowed accept-set (for the contract review)
Now refuses (placeholder, no svg), only when
datahas at least one row and no category-axis refusal applies:chartTypeinbar,horizontal-bar,line,area,combo,column, or omitted (the renderer'sbardefault), withseriesabsent. ThroughChartRendererthat is an authored chart with noseries, nocategoriesand no y-axisfield(a malformedcategoriesor a retiredvaluekey included, since the normalizer yields no series for them).Still draws, unchanged:
barwithseries: [{ dataKey: 'est_hours' }]draws 2 bars, nodata-chart-error, no warning);pie,donut,funnel,radar,scatter(and the othervalue-fallback families) with no series. They fall back to thevaluecolumn, pinned for the undefined arm too;missing-category-key) still wins when both apply.Already refused before this PR, unchanged:
series: []on the same families (objectui#4683).Callers measured (PM hypothesis 4)
ChartRendereris the only importer ofAdvancedChartImpl(lazy). It forwardsspec.series ?? authored, soundefinedreaches the renderer only when the schema declared none ofseries/categories/ y-axis fields.ObjectChartforwardsbuildChartSeriesoutput (always an array) on the dataset path andaugmentedSeries(or nothing) otherwise;DashboardRendereralways builds aseriesarray. In every one of those, anundefinedseries on a cartesian family already drew zero marks, because the cartesian tail and the combo tail renderseries.map(...)and nothing else. So no caller drawing marks today can start refusing: the change turns silent empty frames into an explained refusal, and nothing else. Annotations (reference lines) with no series behave exactly as they already did underseries: []since objectui#4683.Pins
AdvancedChartImpl.unprojectedSeriesDimension.test.tsx: the pinleaves a caller that computed NO series binding at all untouchedis rewritten (not deleted) torefuses a caller that computed NO series binding at all, in its own sentence (objectui#4695). It asserts the placeholder,role="status", no svg, one warning citing objectui#4695, and that its text differs from the computed-and-empty refusal's. A newdescribeblock covers the undefined arm across the refusing families, thevalue-fallback families that keep drawing, the reverse control, and the no-rows case.ChartRenderer.foreignDialectRetired-8650.test.tsx: two cases pinned a bar with no series as "mounts and plots nothing" (malformedcategories, retiredvalue). That contradicts the ruling, so both now wait for theno-plottable-seriesrefusal. The positive reading is kept: re-adding the retired read would plot, no refusal would arrive, and thewaitForgoes red. This file is outside the claimed file surface. It is a test-only change forced by the ruling's "leave no pin contradicting it". None of the 23 open PRs touches it (their file lists were read).Verification (head
54f2e1d95)pnpm exec vitest run --maxWorkers=2 packages/plugin-charts/: 66 files / 599 tests passed at54f2e1d95.d9dedb5cb(plugin-charts, plugin-dashboard, plugin-report, plugin-view, plus every other chart-referencing test file across app-shell, console, schema-catalog, list, runner and others): 3414 passed, 2 failed. Those 2 are exactly the objectui#8650 pins above. After re-pointing them, both files pass (23/23).git checkout HEAD --,git diff HEADempty, blob hash matches HEAD): 4 red. They are the rewritten pin, the family loop, and both objectui#8650 cases. The other 19 in those files stay green.plugin-chartstype-check: exit 0, after building the dependency closure (--filter '@object-ui/plugin-charts^...' build).lint: exit 0, 0 errors.check:new-line-citations(0 new),check:control-bytes,check:changeset-claims,check:pending-changeset-literals,check:vi-mock-specifiers,check:vi-mock-inherit,check:vi-mock-override-shape,check:test-path-roots,check-changeset-presence.mjs,check-changeset-no-major.mjs: all exit 0.Acceptance notes
data-chart-errorcode for both arms is deliberate. The ruling says to reuse the channel, and the two arms share the failure ("cannot plot a series"). A machine consumer that needs the arm reads the sentence or the warning. If a distinct code is wanted, that is a one-line follow-up..changeset/4695-no-series-binding-refusal.md,@object-ui/plugin-charts: patch.Generated by Claude Code