Skip to content

fix(core): 修复空状态后的单属性更新失效与图例截断 - #2138

Merged
xile611 merged 2 commits into
mainfrom
codex/fix-empty-state-attribute-invalidation
Sep 20, 2026
Merged

xile611 merged 2 commits into
mainfrom
codex/fix-empty-state-attribute-invalidation

Conversation

@xile611

@xile611 xile611 commented Sep 20, 2026

Copy link
Copy Markdown
Contributor

🤔 这个分支是...

  • Bug fix
  • 测试 case 更新

🔗 相关 issue 连接

原始问题见下方 chartspace4 用例;触发提交为 0f5ead77aperf(core): skip empty state attribute commits)。

🐞 Bugserver 用例 id

原始用例属于 chartspace4
stroke-series-color

💡 问题的背景&解决方案

固定宽度图例同时显示系列名和 value 时,默认空 selected 状态会保留 attributebaseAttributes 的共享存储。图例先测量文字,再调用 setAttribute('maxLineWidth', ...);单属性慢路径先修改共享对象,导致后续差异检测为空,未失效的文本缓存继续显示完整 test1,基准应为 t…

本次在 Graphic.setAttribute 慢路径写入前调用已有 detachAttributeFromBaseAttributes(),与 _setAttributescommitInternalBaseAttributes 对齐。保留普通单属性快速路径和空状态跳过提交优化,不在图例组件增加特殊处理,不修改公开 API 或依赖版本。

新增回归覆盖:

  • 空状态后的 width / x / fill 单属性更新分别产生正确的几何、变换、纯绘制失效;重复写入相同值不会产生额外失效,清除状态保留新基础值。
  • Electron Canvas 中固定宽度 label/value 图例的初始化截断,以及取消选择后重新选择的截断。

先运行新增测试确认失败,再实施一行运行时修复。真实图例对照结果为 test1t…;现有 should omit when label's width exceeds item's width 测试也由失败恢复通过。

📝 Changelog

Language Changelog
🇺🇸 English Fix stale geometry and text layout after single-attribute updates with an empty active state, including clipped legend labels.
🇨🇳 Chinese 修复空状态下单属性更新未触发几何和文本布局刷新的问题,恢复图例文字截断。

☑️ 自测

  • 推送钩子 rush test --only tag:package:7 个包的源码测试全部通过(1,229 个测试通过,既有 10 个测试跳过)。
  • core 源码测试:112 个测试文件、716 个测试通过,既有 3 个性能用例默认跳过。
  • 动画属性与状态集成测试:2 个文件、50 个测试通过。
  • Electron 图例测试:6 个测试通过。
  • rush compile -t @visactor/vrender-components:core / animate / kits / components 依赖链编译通过。
  • 修改文件 ESLint、提交钩子 Prettier/commitlint、git diff --check 通过。
  • 文档:已提交中文设计、实施计划和验证记录。
  • Demo:已有用例和新增组件回归测试覆盖,无新增使用方式。
  • Ts 类型定义:不需要修改。
  • Changelog:已提供。

10k 图元属性更新微基准(macOS arm64、Node v24.19.0;3 轮预热、7 轮中位数;空 graphic service,不含 Canvas 渲染):

场景 写入次数 修复前 修复后
无状态普通更新 200,000 7.256 ms 7.391 ms
空状态后首次更新 10,000 13.442 ms 14.389 ms
已分离后的持续更新 200,000 202.485 ms 200.400 ms

首次更新增加约 0.947 ms,并将正确产生形状失效的图元数从 0 恢复为 10,000。其余两类中位数变化约 +1.85% / -1.03%;结果用于检查属性路径成本,不代表端到端帧率。


🚀 Summary

copilot:summary

🔍 Walkthrough

copilot:walkthrough

@skie1997 skie1997 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review 完成,复核结论已评论到属性写入对应代码行,未发现明确的新增代码缺陷。

本地复核:属性分层 14 项、动画/状态集成 50 项、Electron 图例 6 项,共 70 项通过。使用 PR 源码及本机已有依赖;图例测试因本机 Node 类型与无关 table-series-number 组件的 setTimeout 类型冲突,关闭了 ts-jest diagnostics 后验证运行时行为,不能算作完整类型检查通过。远端 Unit test CI 为通过。

验证边界:Bug Server CI 返回 status=ok、totalCount=2354、successCount=2319,仍有 35 项未通过。本轮没有逐项核对这些截图差异,不能确认其均为修复带来的预期变化,建议合并前核对差异。

if (this.canCommitBaseAttributesByTouchedKeys()) {
this.commitBaseAttributeBySingleKey(key, value, !!forceUpdateTag, context);
} else {
this.detachAttributeFromBaseAttributes();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

已复核这处调用位置:空状态会让 attributebaseAttributes 保持共享,必须先分离、再写基础属性,后面的 _syncAttribute() 才能保留旧生效值并计算正确 delta。此处与 _setAttributes() / commitInternalBaseAttributes() 的已有慢路径一致,普通单属性快速路径不受影响。

本地属性分层和动画/状态相关 64 项测试通过,真实 Canvas 图例 6 项也通过(图例运行时验证关闭了本机不匹配类型导致的 ts-jest diagnostics)。本轮未发现需要修改的代码问题;全量截图回归仍有 35 项未通过,详见本次 review 总结。

@xile611
xile611 merged commit 0715984 into main Sep 20, 2026
9 of 10 checks passed
@xile611
xile611 deleted the codex/fix-empty-state-attribute-invalidation branch September 20, 2026 06:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants