一张手绘笔记风格的知识信息图,主题为“HarmonyOS7 数据可视化:DataPanel 组件快速

前言

数据可视化是移动端应用的常见需求——展示使用时长分布、预算占比、投票结果等。如果引入第三方图表库,包体积增加不说,集成起来也要折腾一番。ArkUI 内置了一个轻量级的图表组件 DataPanel,传入数据就能自动生成柱状/饼状图表。

这篇文章用 DataPanel 做一个"应用使用时长占比"的可视化面板,支持动态更新数据。

为什么需要 DataPanel

在做数据统计类页面时,纯数字表格虽然精确,但不够直观。一个图表能让人一眼看出各项的比例关系。DataPanel 的价值就在于——不用引入任何依赖,几行代码就能出图。

方案 集成成本 图表类型 自定义能力

一张手绘比较表风格的信息图,主题是“为什么需要 DataPanel”。画面用三栏对比:左栏“Data

| DataPanel | 零成本,内置 | 饼图/柱状图 | 有限 |
| 第三方图表库 | 需引入 | 丰富 | 高度自定义 |
| Canvas 自绘 | 代码量大 | 任意 | 完全自定义 |

数据流向分析

DataPanel 的数据流很直接:

数据数组 → DataPanel 组件 → 自动计算比例 → 渲染图表

一张手绘流程图风格的技术教程插图,主题为“DataPanel 的数据流向分析”。画面从左到右依次绘制

你只需要提供一个 number[] 数组和一个最大值,组件自动处理剩余的计算和渲染逻辑。

核心实现

DataPanel 基础用法

DataPanel({
  values: [30, 20, 15, 25, 10],  // 各项数值
  max: 100                         // 最大值
})
  .width('100%').height(200)

values 数组中的每个数字代表一项的数值,max 是参考最大值。组件会自动计算各项的比例并渲染。

完整的可视化页面

@Entry
@Component
struct DataPanelChart {
  @State dataValues: number[] = [30, 20, 15, 25, 10]
  @State dataLabels: string[] = ['社交', '购物', '娱乐', '工具', '其他']

  build() {
    Column() {
      Scroll() {
        Column() {
          Text('DataPanel 数据面板')
            .fontSize(18).fontWeight(FontWeight.Bold).margin({ bottom: 8 })

          Column() {
            Text('应用使用时长占比')
              .fontSize(14).fontWeight(FontWeight.Medium).margin({ bottom: 12 })

            Column() {
              DataPanel({
                values: this.dataValues,
                max: 100
              })
                .width('100%').height(200)
            }
            .width('100%').alignItems(HorizontalAlign.Center)

            Column({ space: 4 }) {
              ForEach(this.dataLabels, (label: string, idx: number) => {
                Row() {
                  Column()
                    .width(12).height(12)
                    .backgroundColor([
                      '#4D96FF', '#FF6B6B', '#FFD93D', '#6BCB77', '#9B59B6'
                    ][idx])
                    .borderRadius(2)
                  Text(label).fontSize(12).margin({ left: 6 }).layoutWeight(1)
                  Text(`${this.dataValues[idx]}%`).fontSize(12)
                    .fontWeight(FontWeight.Medium)
                }
                .width('100%')
              })
            }
            .width('100%').margin({ top: 12 })

            Row({ space: 8 }) {
              Button('随机数据').onClick(() => {
                let arr: number[] = []
                for (let i = 0; i < 5; i++) {
                  arr.push(Math.floor(Math.random() * 40) + 5)
                }
                this.dataValues = arr
              })
              Button('均分').onClick(() => {
                this.dataValues = [20, 20, 20, 20, 20]
              })
            }
            .width('100%').justifyContent(FlexAlign.SpaceEvenly)
            .margin({ top: 12 })
          }
          .width('100%').backgroundColor('#FFFFFF').borderRadius(12).padding(16)
        }
        .width('100%')
      }
      .layoutWeight(1)
    }
    .width('100%').height('100%').backgroundColor('#F5F6FA').padding(16)
  }
}

关键代码解读

图例列表

图表下方的图例用了 ForEach 遍历标签数组,每项前面有个对应颜色的小方块。索引 idx 同时关联颜色数组和数值数组,保证图例和图表一一对应。

动态数据更新

"随机数据"按钮生成 5 个随机值赋给 this.dataValues。因为 DataPanel 绑定了这个状态变量,图表会即时刷新,展示新的数据分布。

"均分"按钮把所有值设为 20,展示均匀分布的效果。

状态管理讲解

DataPanel 的数据源是 @State dataValues: number[]。每次更新这个数组,组件都会重新渲染图表。配合 SliderTextInput 可以让用户手动调整数据:

Slider({ value: $$this.dataValues[0], min: 0, max: 100 })
  .onChange((value: number) => {
    this.dataValues[0] = value
    this.dataValues = [...this.dataValues] // 触发数组引用更新
  })

修改数组中某个元素后,需要重新赋值整个数组(this.dataValues = [...this.dataValues])才能触发 UI 刷新。这是 ArkUI 数组观察机制的特点。

最佳实践

  • 数据项控制在 5~8 个:太多项图表会很拥挤,可读性差
  • 提供图例:图表配上颜色对应的标签列表,用户才能理解每项代表什么
  • 数值归一化:传入前把数据归一化到 100 以内,便于设置 max
  • 动态交互:点击图表的某一项,高亮显示并展示详细数据

写在最后

DataPanel 虽然功能不如专业图表库丰富,但胜在零成本、轻量、开箱即用。做简单的数据占比展示完全够用。如果你的需求只是"给用户看个大概比例",它就是个真香组件。需要复杂交互和高度定制的时候,再考虑第三方方案也不迟。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐