Repository navigation
Commit 45c9be5
fix(plugin-charts): data labels print in their value axis's units and the tallest mark keeps its label on the chart (#27407)
<!-- claude-projects-attribution: {"github_login":"os-warren"} -->
_Requested by **Warren** · [project
thread](https://claude.ai/code/project/chan_01U5RdnAAmkSQmZbqh6FtqZ8?thread=cmsg_01U5RdnAAmkSQmZbqh6FtqZ8YKe7vvuJjvvPs61VEnCbHs)_
Fixes #27372
Clause-②: no
Metadata-protocol: none
## 维护者速读
- 改了什么:图表数据标签改用其所在数值轴自己的刻度格式化器(无作者格式时与轴同为紧凑单位,如
`174K`),并在开启数据标签时给竖向图表加顶部留白,最高柱的标签不再画到图外。
- 为什么改:HotCRM 18.2.0 浏览器走查第 2–3 行:标签印 `174000` 而轴印
`400K`;最高柱的值标签整段被裁掉。表格末列与全零图两行实测后不改,理由见下。
- 风险与回滚:只动 `@object-ui/plugin-charts` 的
`AdvancedChartImpl.tsx`;关闭数据标签的图表与横向柱图布局字节不变。回滚 = revert 本 PR。
- 先看:`AdvancedChartImpl.tsx` 的 `DATA_LABEL_CHART_MARGIN` 与 `dataLabel` /
`valueTickFormatterOf`;再看新测试
`AdvancedChartImpl.dataLabels-27372.test.tsx`。
- 两分钟验证:`pnpm --dir ui exec vitest run
packages/plugin-charts/src/AdvancedChartImpl.dataLabels-27372.test.tsx`,预期
11 passed。
- 需要你做的:无,席位落地。
## What changes
`ui/packages/plugin-charts/src/AdvancedChartImpl.tsx` only:
- **Row 2: data labels read in their axis's units.** `dataLabel` now
takes the tick formatter of the value axis the series is drawn against:
`yTickFormatter` on a single-axis chart, `leftYTickFormatter` /
`rightYTickFormatter` by the series' `yAxis` on a dual-axis chart
(`valueTickFormatterOf`), and by the series' axis id on a combo. Each of
those is already `formatterFor(axis.format) ?? formatYTick`, so an
authored `yAxis[].format` still wins and an axis without one gives its
labels the compact default. Before, the label called
`formatterFor(axis.format)` with no fallback and printed the raw number.
Dashboard charts are the common case: `chartConfig` carries no axis
format at all.
- **Row 3, tallest bar: label headroom.** With `showDataLabels` on, a
vertical bar, line, area or combo chart takes `DATA_LABEL_CHART_MARGIN`:
a top margin of recharts' 5px plus the label's offset (5px) and font
(11px). A margin rather than a domain pad, so an authored `yAxis.max`
keeps pinning the domain. Charts without data labels and horizontal bars
keep recharts' default margin. The label's font size and offset are now
named constants (`DATA_LABEL_FONT_PX`, `DATA_LABEL_OFFSET_PX`); their
values are unchanged.
- The unused `axisOfSeries` helper is replaced by
`valueTickFormatterOf`.
**Serial constraint with #27361:** this diff does not touch
`DatasetWidget.tsx` or `utils.ts` and does not regenerate the sdui
manifest, so it does not wait on #27361.
## Why
Rows 2–4 of #27355 (HotCRM's 18.2.0 browser pass), carded as #27372.
Each row was measured in real Chromium (`/opt/pw-browsers/chromium`) on
a fixture dashboard rendered by the real `DashboardRenderer`, with
dataset-bound bar, line, table and all-zero widgets and an
object-provider table, at 1280px (tables also at 768px and 390px).
HotCRM's metadata was not used.
| Row | Reading before (`c4c515ad`) | Reading after | Outcome |
|---|---|---|---|
| 2 | Label `174000` beside y ticks `0 / 100K / … / 400K` | Label
`174K`, ticks unchanged | done |
| 3a | Tallest label `400000` box top at −11px from the svg top: outside
the svg | `400K` box top at +5px: inside the svg | done |
| 3b | Dataset table: scroller `overflow-x: auto`, `scrollWidth` 910 vs
`clientWidth` 566, inside the card. Object-provider table: 971 vs 564,
inside the card | (no change) | will not do: not reproduced |
| 4 | All-zero bar and line: y ticks `0 1 2 3 4`, 5 grid/axis lines, the
line drawn on 0 | (no change) | will not do |
## Acceptance notes
- **Row 3b, not reproduced.** Neither dashboard table widget clips its
last column out of reach. The dataset `table` (DatasetWidget's flat
table) and the `provider: 'object'` table (ObjectDataTable →
`data-table`) each keep their own `overflow-auto` scroller inside the
card, and the last column scrolls into view at 1280, 768 and 390px. What
reads as a clip is the scroll edge with no visible scrollbar: headless
Chromium hides scrollbars by default, macOS shows them only while
scrolling, and `data-table` shows its scrollbar on hover only. A visible
overflow cue (an edge fade, say) would be polish, not a reachability
defect, so no table widget is changed. If HotCRM's screen shows a column
that cannot be scrolled to, the reading needed is the widget type and
the scroller's `scrollWidth` / `clientWidth` there.
- **Row 4, will not do.** The recorded decision in
`AdvancedChartImpl.tsx` (the "all-zero BAR drew 5,128 ink pixels of axes
and ticks" paragraph) stands: zero is a value, the measured chart draws
a usable zero baseline and ticks, and a "no data" state over real zeros
would be false.
- **Field format does not reach labels or ticks.** A measure's field
`currency` / `percent` format reaches neither the axis ticks nor the
labels on a dashboard chart (both read only `yAxis[].format`, which
`chartConfig` does not carry). Not widened here: the labels now match
the axis, which is the card's ask.
- A horizontal bar's labels sit in the band beside each bar and were not
measured as clipped; they get no new margin.
## Verification
Head `27cff9de`.
<details><summary>New pin:
<code>AdvancedChartImpl.dataLabels-27372.test.tsx</code> (11
cases)</summary>
- Compact default beside a compact axis, for bar, line and area
(`['174K', '400K', '251K', '92.5K']`, the axis itself asserted to read
`400K`).
- An authored `$0,0` format wins (`$174,000` …).
- Dual-axis bar and combo: each series prints in its own axis's units
(`174K …` left, `12.0 …` right with a right-axis `0.0` format).
- The tallest label's baseline minus the label font is ≥ 0 for bar,
line, area and combo; the plot top stays at 5px with labels off.
`pnpm --dir ui exec vitest run
packages/plugin-charts/src/AdvancedChartImpl.dataLabels-27372.test.tsx`
→ 11 passed.
</details>
<details><summary>Ablations (each fix reverted through
<code>scripts/ablation-replace.mjs</code>, restored blob =
HEAD)</summary>
- Formatter dropped from the `LabelList` (raw labels): 10 of 11 red
(`expected [ '174000', … ] to deeply equal [ '174K', … ]`); only the
labels-off margin case stays green.
- Top margin set back to 5px: exactly the 4 headroom cases red (`"400K"
is drawn above the chart surface: expected -11 to be greater than or
equal to 0`), the 7 others green.
</details>
<details><summary>Package and gates</summary>
- `pnpm --filter @object-ui/plugin-charts type-check` and `pnpm --dir ui
exec vitest run packages/plugin-charts/` → exit 0; Test Files 100 passed
(100), Tests 1292 passed | 9 skipped (1301), on 27cff9d.
- `eslint` on both touched files: 0 errors; warning count equal to
`c4c515ad` (41).
- `pnpm --dir ui run check:new-line-citations` → 0 new citations.
- `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack`: 35 derived, 35 run on 27cff9d; 34 exit 0
first pass. `pnpm --dir ui exec vitest run scripts/` exit 1 on one 15 s
timeout in `check-vi-mock-inherit.test.ts` (tree-sweep population test,
a load timeout on a shared box; this diff touches no `ui/scripts`
input); that file re-run alone under the lock: 83/83 passed, exit 0.
`--ran` reconciliation: 35 accounted, 0 NOT-MEASURED, 0 UNRUN.
</details>
## Human Minimum
- [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic.
(not touched)
- [x] 2. Every name I added uses the casing for its kind.
- [x] 3. No formatter ran; `pnpm lint` passes (touched files linted;
repo-wide lint is CI's).
- [x] 4. One issue, one branch off an up-to-date `main`, one pull
request.
- [x] 5. A change that publishes carries a changeset, and both
declaration lines are filled in here and in the changeset
(`@object-ui/plugin-charts` patch).
- [x] 6. `packages/spec` touched: n/a.
- [x] 7. No hand edits to `content/docs/references/`,
`packages/*/CHANGELOG.md` or `content/docs/releases/`.
- [x] 8. Title, body and comments are in English (the 维护者速读 block is the
dispatch order's required Chinese summary).
- [x] The *Before Submitting* list in CONTRIBUTING.md is done.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01JQwxbY75sPQWcfUg8cZQhg
---
_Generated by [Claude
Code](https://claude.ai/code/session_01JQwxbY75sPQWcfUg8cZQhg)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent b10fd65 commit 45c9be5
3 files changed
Lines changed: 220 additions & 11 deletions
File tree
- .changeset
- ui/packages/plugin-charts/src
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
482 | 482 | | |
483 | 483 | | |
484 | 484 | | |
| 485 | + | |
| 486 | + | |
| 487 | + | |
| 488 | + | |
| 489 | + | |
| 490 | + | |
| 491 | + | |
| 492 | + | |
| 493 | + | |
| 494 | + | |
| 495 | + | |
| 496 | + | |
| 497 | + | |
| 498 | + | |
| 499 | + | |
| 500 | + | |
| 501 | + | |
| 502 | + | |
| 503 | + | |
| 504 | + | |
| 505 | + | |
| 506 | + | |
| 507 | + | |
| 508 | + | |
| 509 | + | |
| 510 | + | |
| 511 | + | |
| 512 | + | |
| 513 | + | |
| 514 | + | |
485 | 515 | | |
486 | 516 | | |
487 | 517 | | |
| |||
2128 | 2158 | | |
2129 | 2159 | | |
2130 | 2160 | | |
2131 | | - | |
2132 | | - | |
2133 | | - | |
2134 | | - | |
2135 | 2161 | | |
2136 | 2162 | | |
2137 | 2163 | | |
| |||
2196 | 2222 | | |
2197 | 2223 | | |
2198 | 2224 | | |
| 2225 | + | |
| 2226 | + | |
| 2227 | + | |
| 2228 | + | |
| 2229 | + | |
| 2230 | + | |
2199 | 2231 | | |
2200 | 2232 | | |
2201 | 2233 | | |
| |||
2317 | 2349 | | |
2318 | 2350 | | |
2319 | 2351 | | |
2320 | | - | |
2321 | | - | |
| 2352 | + | |
| 2353 | + | |
| 2354 | + | |
| 2355 | + | |
| 2356 | + | |
| 2357 | + | |
| 2358 | + | |
| 2359 | + | |
2322 | 2360 | | |
2323 | | - | |
| 2361 | + | |
2324 | 2362 | | |
2325 | 2363 | | |
2326 | 2364 | | |
| |||
3034 | 3072 | | |
3035 | 3073 | | |
3036 | 3074 | | |
3037 | | - | |
| 3075 | + | |
3038 | 3076 | | |
3039 | 3077 | | |
3040 | 3078 | | |
| |||
3072 | 3110 | | |
3073 | 3111 | | |
3074 | 3112 | | |
3075 | | - | |
| 3113 | + | |
3076 | 3114 | | |
3077 | 3115 | | |
3078 | 3116 | | |
| |||
3122 | 3160 | | |
3123 | 3161 | | |
3124 | 3162 | | |
3125 | | - | |
| 3163 | + | |
3126 | 3164 | | |
3127 | 3165 | | |
3128 | 3166 | | |
| |||
3263 | 3301 | | |
3264 | 3302 | | |
3265 | 3303 | | |
3266 | | - | |
| 3304 | + | |
3267 | 3305 | | |
3268 | 3306 | | |
3269 | 3307 | | |
| |||
0 commit comments