fix(plugin-report): 报表内嵌图表分桶 null 类目并转发作者声明的图表 chrome (#4877, #4878) - #4908
Conversation
…rt chrome (#4877, #4878) A dataset-bound report's embedded chart was the one chart surface that shared neither half of the ruled dataset/author split. It forwarded exactly six keys — chartType, data, height, isAnimationActive, series, xAxisKey. #4878 — the DATA half now routes through `buildChartSeries` (@object-ui/core), where the whole null-category family lives (#4466 / #4497 / #4673 / #4500 / #4508). The rows used to reach the renderer with a raw null category, which draws no mark: the group vanishes while the y-axis still accommodates it. The bucket label is resolved from the locale bundle at the call site, because core is React-free. #4020's three-level measure display name still outranks the label the derivation assigns. #4877 — the PRESENTATION half now routes through `chartConfigPresentation` and `mergeAuthoredSeries`, so the chrome (showLegend, showDataLabels, colors, subtitle, description, annotations, interaction, height) and the per-series presentation keys ReportChartSchema declares stop being inert metadata. `showLegend: false` was inverted in effect, not merely ignored. Both helpers moved from plugin-dashboard's DatasetWidget to @object-ui/core beside `buildChartSeries`, the derivation they merge onto, so the two surfaces lower one vocabulary once. DatasetWidget re-exports both names unchanged. Co-authored-by: Claude <noreply@anthropic.com>
…ons (#4877, #4878) The `en` bucket-label BOUNDARY case was written as "green on both sides". That is true of objectui#4500's own mutation (drop the `nullCategoryLabel` option, keep the routing — core's English floor and the `en` pack produce the same bytes through different channels) and FALSE of objectui#4878's, which removes the bucket entirely: with nothing bucketed there is no label to read in either language, and it measured red. Both files now carry the measured counts beside the predictions rather than a presumed direction. Co-authored-by: Claude <noreply@anthropic.com>
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
|
PM 验收:ACCEPT(#4877 + #4878 合单,批次 16,PM 会话 实物核验(已过):8 文件 +1116/−285 逐字对账;changeset 两个、分卡(chrome / null-bucket 各一);标识 0;releases 0;plugin-dashboard 的触碰在认领评论声明的文件面内(helper 上提路线)。 #4878(null 类目分桶):报表行改路由 #4877(作者面 chrome 键):走卡面第二条被许可路线 —— 有据偏离(全部接受)
CI(亲读终态):20 项全 completed,18 success + 2 skipped,零失败。 附带产出:新 finding #4906(报表 chart 缺 option 颜色/声明类目序派生,跨面漂移观察卡)。 → undraft + auto-merge (SQUASH)。 Generated by Claude Code |
Fixes #4878
Fixes #4877
数据集报表的内嵌图表,是唯一一个两半都没接上的图表面:它只转发六个键 ——
chartType、data、height、isAnimationActive、series、xAxisKey。两卡各修一半,同一条转发线,故合单。#4878 — DATA 半:改走
buildChartSeries,继承整个 null 家族前提复核(main 现状与卡述一致):
DatasetReportChart把relabelDimensions(state.rows, dimensionLabels)直通渲染器,链路上没有任何分桶。这正是 #4466 实测「一个 mark 都不画」的输入 —— 代价不是空图,而是静悄悄画错:主导分组消失,而 y 轴刻度仍按它撑开,图看上去完全合法。仪表盘与图表视图从来没有这个缺陷,因为它们走
buildChartSeries(@object-ui/core),null 家族的修复全在那里。现在报表也走它,于是这些性质是继承来的,而不是在第三个面上重新派生:(None)仍是另一个分组)承重约束①(#4020 三级显示名必须压过派生的
fields[].label) —— 已保住。buildChartSeries赋的label是fields[].label ?? name;#4020 的解析更高一级(作者chart.series[].label→headerLabel→ measure 名),所以落点处显式覆盖,并钉住了{ en, 'zh-CN' }记录形式:core 里没有 provider,它自己的取法是「第一个字符串胜出」,那正是 #4020 关掉的缺陷类。承重约束②(null 桶标签走 i18n bundle) ——
tt('chart.nullCategory', '(None)')在渲染器里解析后作为nullCategoryLabel传入,与仪表盘 #4500 的分工一致(core 无 React,拿不到 bundle)。zh 控制台读(未指定)。量到的转发键前后对照(DATA 半)
datarelabelDimensions(rows, …)直通,null 类目原样到达buildChartSeries(...).data,null 归入本地化桶xAxisKeyxAxisbuildChartSeries(...).xAxisKey(同值,同一处派生)series[{ dataKey, label }]#4877 — PRESENTATION 半:声明即生效
ReportChartSchema声明、而这条路径全部丢弃的键,现在按 #4229 的 data/presentation 分界下放。showLegend是其中最锋利的一个:它不是「被忽略」,而是效果被反转 ——AdvancedChartImpl算的是legendVisible = showLegend !== false,键缺席即图例开,于是作者写的false照样画出图例。量到的转发键前后对照(PRESENTATION 半)
showLegendshowDataLabelscolors(数组 → 位置调色板)colorscolors(记录 → 按类目着色)categoryColorssubtitle/descriptionannotations/interactionheight0会压塌绘图区)series[]的color/stack/type/yAxis/dashArray/opacity/variantseries[].name匹配后合并titleh3ariaseries 的匹配规则是
series[].name→ 派生dataKey,所以成员资格仍归数据集:作者点名一个本图不绘制的 measure,该条目被忽略,不能增删或改指一条 series。卡面警告的处理:
xAxis/yAxis是裸名字符串卡里点名的坑 —— 直接把报表 chart 喂给
mergeAuthoredPresentation会让axisPresentation读一个字符串,合成yAxis: [{}]这个「只声明自己存在」的空条目,而 y 轴条目的数量正是开启副轴的开关。这里从结构上规避,而不是加一道守卫:core 额外导出
mergeAuthoredSeries(只做 series 合并),报表调它。轴在这个面上是纯 DATA(它们就是选择集本身),所以那个面根本够不到读轴表现的代码。共享 helper 上提(卡面给的第二条路)
chartConfigPresentation与mergeAuthoredPresentation从plugin-dashboard/src/DatasetWidget.tsx移到@object-ui/core/src/utils/chart-presentation.ts,紧挨着它们所合并的那个派生buildChartSeries。理由是 #4389 的先例:两个 plugin 各写一份同样的分析标签网,被当作缺陷立卡并把纯数据的那半上提到 core。
ReportChartSchema与ChartConfigSchema声明的是同一套词汇,在报表侧再抄一份就是同一个缺陷再来一次。chart-series.ts一致;DatasetWidget以原名 re-export,模块公开面与渲染行为逐字节不变(其既有测试全绿,见下);aria为何不转发)随代码一起搬到了新模块头部。有据偏离清单
两处偏离卡面的键清单,均为刻意,并各有一条钉子把它记成决定而非疏漏:
aria不转发。 它是ReportChartSchema声明的键里,这条路径上唯一无人读取的那个:AdvancedChartImpl没有ariaprop,而本渲染器是把 schema 直接交给组件,并不经过SchemaRenderer的扁平 ARIA 注入(所以连仪表盘那条「扁平化」的可能性在这里都不存在)。转发它只是把「声明了却没人读」下移一层,而那正是本卡要消除的失败模式。这沿用仪表盘的既有裁定(其注释将此上报到 objectstack#5175 的收窄那一半;该编号属 objectstack 仓,本 PR 未独立核实)。title不转发。 本渲染器自己把它画成图上方的h3(卡里也确认title本就生效),再转发一次会在图表自身的 frame 里画出第二个标题。另有一处顺带的行为收紧:
height: 0之前直读会压塌绘图区,现在走白名单被丢弃、退回 280 默认 —— 与仪表盘同判据,已钉。验收证据(按卡分节)
反向验证:两卡各一次变异证负,方向先书面预判再跑
变异前已 commit,还原一律
git checkout 分支名 -- 文件路径(不用 stash,共享栈)。#4878 —— 把 DATA 半还原成改前那几行(rows 直通、series 手搓),#4877 的转发保持在位:
实测 5 红 / 5 绿,逐例吻合;
chartChrome.test.tsx19/19 全绿,证明变异只切到了 #4878。#4877 —— 去掉
...chromespread 并把 series 还原成手搓,#4878 的路由保持在位:实测 11 红 / 8 绿,逐例吻合;
chartNullCategory.test.tsx10/10 全绿。一处预判与模板预设不符,如实记录(已回写进测试文件头):
en桶标签那条 BOUNDARY 例,我原先按「两侧都绿」写注释。那对 #4500 自己的变异成立(去掉nullCategoryLabel选项但保留路由 —— core 的英文兜底与en语言包经不同通道产出同样的字节),对 #4878 的变异则不成立:桶本身被移除时,两种语言都没有标签可读,它必然红。两个测试文件现在都把实测计数写在预判旁边,而不是留一个想当然的方向。测试与门禁
vitest run packages/plugin-report/ packages/plugin-dashboard/ packages/core/Test Files 162 passed (162)/Tests 2584 passed (2584)vitest run packages/plugin-report/ packages/plugin-dashboard/ packages/core/src/utils/Test Files 106 passed (106)/Tests 1343 passed (1343)turbo run type-check --concurrency=2Tasks: 81 successful, 81 totalnode scripts/check-control-bytes.mjsOK (scanned 4390 tracked text file(s))node scripts/check-changeset-presence.mjs/check-changeset-no-major.mjsmajoreslint(改动文件)新增钉子 29 条:
DatasetReportRenderer.chartNullCategory.test.tsx(10)与DatasetReportRenderer.chartChrome.test.tsx(19)。既有的DatasetReportRenderer.chartMeasureLabel.test.tsx(#4020 的钉子)全程未改动且全绿 —— 那是承重约束①的独立见证。changeset 两个文件,按卡分开:
.changeset/report-chart-null-category-bucket.md(#4878)、.changeset/report-chart-authored-chrome.md(#4877,含 core / plugin-dashboard 的上提)。均为patch。相邻发现,未扩围
立卡 #4906(
finding标签,未指派):报表图表既不派生维度选项颜色(buildOptionColorMap→categoryColors),也不派生声明的类目顺序(buildCategoryOrder,framework#3588),而仪表盘两者都派生。今天没有东西渲染错 —— 调色板是位置式而非语义式、漏斗按值降序而非按声明管道序 —— 属跨面 drift,故按 observation 类立卡,不在本 PR 修。本 PR 为 draft,不挂 auto-merge,等 PM 验收。