[Feature] hide axes when series is empty#4521
Conversation
b3c51f2 to
fd653c9
Compare
xuefei1313
left a comment
There was a problem hiding this comment.
本次 PR 实现了 Cartesian 轴的 hideWhenEmpty 配置项,允许坐标轴在关联系列数据为空时自动隐藏,并在数据更新后自动恢复。
主要改进点:
- 状态分离:通过
_specVisible和_visible的分离,优雅地处理了用户配置可见性与运行时可见性的关系。 - 生命周期集成:在
BandAxisMixin和LinearAxisMixin中集成了可见性刷新逻辑,确保数据驱动的准确性。 - 渲染健壮性:在
BaseMark中增加了延迟初始化逻辑,解决了 Product 在隐藏期间可能被移除的问题。 - 性能考虑:在
AxisComponent中优化了collectData的空值处理。
建议:
- 确认
@since 2.0.20版本号是否与当前发布计划一致。 - 考虑到这是一个通用能力,未来可以评估是否扩展到极坐标轴。
总体代码质量很高,逻辑严密。
| (!this._skipBeforeLayouted || this.getCompiler().getLayoutState() !== LayoutState.before) | ||
| ) { | ||
| // A mark may lose its product when visibility toggles to false during compile. | ||
| // Later data/layout updates can make it visible again without triggering compile, |
There was a problem hiding this comment.
这里在 render 时延迟初始化 product 是为了支持从隐藏转为显示的状态。需要确认 _initProduct() 在没有传入 group 参数时是否能正确挂载到父级容器中(默认为 RootGroup),特别是对于 Series 中的 Mark,可能需要挂载到 SeriesGroup 下。
| protected _shouldComputeTickData() { | ||
| // 当轴被展示、或者强制要求计算 data 时再计算 data | ||
| return this.getVisible() || this._spec.forceInitTick; | ||
| return this._specVisible && (this.getVisible() || this._spec.forceInitTick || this._hideWhenEmpty); |
There was a problem hiding this comment.
如果 _hideWhenEmpty 为 true,即使当前 getVisible() 为 false(因为数据为空),也会返回 true 从而触发 _initData()。这符合“保留 tick 数据以备后续显示”的设计,但要确保在数据量极大时不会产生不必要的计算开销。
| protected _syncComponentVisibility() { | ||
| this._axisMark?.setVisible(this._visible); | ||
| this._gridMark?.setVisible(this._visible && this._spec.grid?.visible !== false); | ||
|
|
There was a problem hiding this comment.
collectData(0) 会遍历所有关联的 series。在 BandAxisMixin 和 LinearAxisMixin 的 domain 更新流中,此方法会被重复调用(一次用于 domain,一次用于 visibility)。建议考虑缓存 collect 结果或复用 domain 计算时的数据以优化性能。
xuefei1313
left a comment
There was a problem hiding this comment.
对 PR #4521 (实现轴在数据为空时自动隐藏功能) 的深度 Review 总结:
变更点分析
- Spec 扩展:在
ICartesianAxisCommonSpec中增加了hideWhenEmpty配置项。 - 可见性逻辑重构:将轴的可见性拆分为
_specVisible(用户配置) 和_visible(实际运行状态),支持根据数据收集情况动态切换。 - 数据流集成:在
mixin(Band/Linear) 的 domain 更新阶段触发可见性检查,并强制触发forceLayout以重新分配图表空间。 - Mark 延迟初始化:在
BaseMark的render阶段增加了对_product的懒初始化,以支持从隐藏状态恢复时的图元创建。
发现的问题与改进建议
- 性能优化:
_refreshVisibilityByData内部调用的collectData(0)在 domain 更新流程中会被重复执行。在大数据量或多系列场景下,建议缓存数据收集结果或复用 domain 计算时的数据统计信息。 - 渲染安全性:
BaseMark在 render 时调用_initProduct()需确保其默认挂载逻辑(通常挂载至 RootGroup)符合业务 mark (如 Series 下的 Mark) 的层级要求。 - 类型严谨性:在
_syncComponentVisibility中对getComponent()返回值转换为IGroup并调用setAttributes时,建议增加更严谨的类型校验。 - 测试覆盖:已提供的单元测试覆盖了初始渲染和数据更新场景,建议增加
updateSpec切换hideWhenEmpty开关的测试用例。
总体实现方案符合 VChart 架构设计,逻辑清晰。建议关注上述性能及类型细节。详细评论已在代码行中列出。
[中文版模板 / Chinese template]
🤔 This is a ...
🔗 Related issue link
close #4490
🔗 Related PR link
🐞 Bugserver case id
💡 Background and solution
Add an opt-in
hideWhenEmptyaxis option for cartesian axes. The axis should hide when its bound series produce no collected axis data, while preserving existing behavior by default. The implementation will separate user-configured visibility from runtime empty-data visibility so the axis can auto-hide and reappear afterupdateDataorupdateSpecwithout requiring chart remake.Language/Version: TypeScript 4.9.5
Primary Dependencies:
@visactor/vchart,@visactor/vutils,@visactor/vrender-componentsStorage: N/A
Testing: Jest
Target Platform: Web and cross-terminal chart runtimes supported by VChart
Project Type: Monorepo / Chart library
Performance Goals: No noticeable render or update regression; axis visibility recalculation should stay within existing axis domain update flow
Constraints: Cartesian axes only for this scope; must support runtime auto hide/show after data updates; must preserve existing behavior when option is unset
Scale/Scope: Public axis spec in
packages/vchartandpackages/vchart-types, axis runtime behavior in cartesian axis base flow, targeted unit regression coverage📝 Changelog
hideWhenEmptyfor cartesian axes so empty bound-series axes can hide and reappear automatically after data updates.☑️ Self-Check before Merge
🚀 Summary
copilot:summary
🔍 Walkthrough
copilot:walkthrough