Apply axis format= in the native exporters#287
Conversation
`x_axis(format=)`/`y_axis(format=)` reached the wire and the browser honored it, but `_fmt_axis` dispatched on axis kind alone and never read `axis["format"]`. Every native target — SVG, PNG, JPEG, WebP and PDF — drew automatic labels, so `y_axis(format=".0%")` read 30% in the browser and 0.30 in the exported image, and `engine=chromium` disagreed with the default engine on the same figure. spec/api/styling.md recorded this as a known gap; close it rather than restate it, since the default export engine is native and the docs recommend `format=` with no caveat. Port the client grammar exactly: `_fmt_number_spec` mirrors `fmtNumberSpec` (prefix/group/digits/f/% /suffix, affixes only with an explicit `f` or `%`, fall back to the automatic formatter otherwise) and `_fmt_time_spec` mirrors `fmtTimeSpec` (the `%Y %m %d %H %M %S %b %B` subset, UTC, English months, unknown tokens copied verbatim, never falling back). The log-axis guard that keeps a decade below 1 from collapsing to "0" comes across too. One deliberate difference: group separators are the `,`/`.` pair rather than the viewer's locale. The browser reads `toLocaleString(undefined, ...)`, but a static export has no viewer and must be reproducible, so the same figure exports byte-identical everywhere. The two implementations are independent, so the test pins the grammar itself — both regexes must appear verbatim in js/src/30_ticks.ts — alongside the worked examples from the spec and an end-to-end check that an unsupported spec still degrades to automatic labels.
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Merging this PR will not alter performance
Comparing Footnotes
|
Stacked on #286.
Problem
x_axis(format=)/y_axis(format=)reached the wire and the browser honoredit, but
_fmt_axisdispatched on axis kind alone and never readaxis["format"]. Every native target — SVG, PNG, JPEG, WebP and PDF — drewautomatic labels.
So
y_axis(format=".0%")read 30% in the browser and 0.30 in theexported image, and
engine=chromiumdisagreed with the default engine on thesame figure.
Engine.autoresolves to native for every format, so this was thedefault path.
It also dropped the time grammar, not just numeric:
format="%Y/%m/%d"rendered
Jan 02.spec/api/styling.mdrecorded it as a known gap. Closing it rather thanrestating it, since the user-facing docs recommend
format=with no caveat.Before / after
y_axis(format=".0%"), native PNG, plus the browser for reference.0.10–0.30→10%–30%, matching the browser exactly.Also verified end to end:
$,.2f→$1,000.00,,.0fK→1,000K,%Y/%m/%d→2024/01/04,%b %Y→Jan 2024.Fix
Port the client grammar exactly:
_fmt_number_specmirrorsfmtNumberSpec— prefix / group / digits /f/%/ suffix, affixes only with an explicitfor%, fall back to theautomatic formatter otherwise.
_fmt_time_specmirrorsfmtTimeSpec— the%Y %m %d %H %M %S %b %Bsubset,UTC, English months, unknown tokens copied verbatim, never falling back.
"0"comesacross too.
One deliberate difference: group separators are the
,/.pair rather thanthe viewer's locale. The browser reads
toLocaleString(undefined, ...), but astatic export has no viewer and must be reproducible, so the same figure exports
byte-identical on every machine. Documented in the spec.
Testing
The two implementations are independent, so the test pins the grammar
itself — both regexes must appear verbatim in
js/src/30_ticks.ts— alongsidethe worked examples from the spec and an end-to-end check that an unsupported
spec still degrades to automatic labels rather than raising.
One quirk asserted deliberately:
"{:,.2f}"is not rejected, because{:and}are legal affixes under the shared grammar. Both sides agree on it; the testkeeps them agreeing rather than only covering the happy path.
Found during a customizability audit.