HarmonyOS APP开发—"数据眼"健康追踪App,需要用到这个库

做一个健康追踪 App,每天的步数、心率、睡眠时长要用图表展示——自己用 Canvas 画图表?太累了。@ohos/mpchart 覆盖 7 大图表类型,手势缩放、数据高亮、自定义样式开箱即用。

📦 仓库地址:https://gitcode.com/CPF-ApplicationTPC/ohos_mpchart | 安装:ohpm install @ohos/mpchart


写在前面

"数据眼"是一个健康追踪 App,核心功能是把传感器采集的健康数据可视化:

  • 步数走势:最近 7 天每天的步数 → 柱状图
  • 心率曲线:今天 24 小时心率变化 → 折线图
  • 睡眠分布:深睡/浅睡/清醒占比 → 饼状图
  • 能力评估:心肺/力量/柔韧/平衡多维评分 → 雷达图

这些图表如果自己用 Canvas 画,每个都得写几百行:画轴、画网格、画数据点、处理手势缩放、处理点击高亮……4 种图表就是 2000+ 行代码。

@ohos/mpchart 提供了 7 大图表类型(线形/柱状/饼状/蜡烛/气泡/雷达/瀑布),自带手势交互和数据高亮,配置化使用,几十行就能出图。

这篇文章聊什么

  1. 步数柱状图——最近 7 天步数对比
  2. 心率折线图——24 小时心率曲线 + 缩放
  3. 睡眠饼状图——深睡/浅睡/清醒占比

步数

心率

睡眠

能力

传感器数据

数据处理

图表类型

BarChart 柱状图

LineChart 折线图

PieChart 饼状图

RadarChart 雷达图

手势缩放+点击高亮

渲染到 UI


第一步:安装

ohpm install @ohos/mpchart

无需任何权限(纯渲染组件)。


第二步:步数柱状图——最近 7 天

import {
  BarChart, BarChartModel, BarData, BarDataSet, BarEntry,
  JArrayList, XAxis, XAxisPosition, YAxis, Description,
  OnChartValueSelectedListener, Highlight, EntryOhos
} from '@ohos/mpchart'

@Entry
@Component
struct StepsChartPage {
  private barChart: BarChart = new BarChart()
  private model: BarChartModel = new BarChartModel()

  aboutToAppear() {
    // 模拟最近 7 天步数
    const steps = [8234, 10245, 6789, 9876, 12034, 5678, 8901]
    const days = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']

    const entries = new JArrayList<BarEntry>()
    steps.forEach((val, i) => entries.add(new BarEntry(i, val)))

    const dataSet = new BarDataSet(entries, '每日步数')
    dataSet.setColorByColor(0xFF4ECDC4) // 青绿色

    const barData = new BarData(dataSet)
    barData.setBarWidth(0.5)

    this.model.setData(barData)
    this.model.getXAxis().setPosition(XAxisPosition.BOTTOM)
    this.model.getXAxis().setValueFormatter((value) => days[Math.floor(value)] || '')
    this.model.getAxisLeft().setAxisMinimum(0)
    this.model.getAxisRight().setEnabled(false) // 隐藏右侧 Y 轴
    this.model.setDescription(new Description().setText('单位:步'))

    // 点击柱子高亮
    this.barChart.setOnChartValueSelectedListener({
      onValueSelected: (e: EntryOhos, h: Highlight) => {
        promptAction.showToast({
          message: `${days[Math.floor(e.getX())]}: ${e.getY()}`,
        })
      },
      onNothingSelected: () => {},
    })

    this.barChart.setModel(this.model)
  }

  build() {
    Column() {
      Text('本周步数').fontSize(20).fontWeight(FontWeight.Bold).padding(12)
      this.barChart
    }
    .width('100%').height(400)
  }
}

第三步:心率折线图——24 小时曲线

import {
  LineChart, LineChartModel, LineData, LineDataSet, LineEntry,
  JArrayList, XAxisPosition
} from '@ohos/mpchart'

// 24 小时心率数据(每小时一个点)
const heartRates = [62, 60, 58, 56, 55, 58, 64, 72, 80, 85, 78, 76,
                    74, 72, 70, 75, 82, 88, 92, 85, 76, 70, 66, 62]

const entries = new JArrayList<LineEntry>()
heartRates.forEach((hr, i) => entries.add(new LineEntry(i, hr)))

const dataSet = new LineDataSet(entries, '心率 (bpm)')
dataSet.setColorByColor(0xFFFF6B6B)  // 红色曲线
dataSet.setCircleColor(0xFFFF6B6B)
dataSet.setLineWidth(2)
dataSet.setDrawFilled(true) // 曲线下方填充
dataSet.setFillColor(0x33FF6B6B)

const model = new LineChartModel()
model.setData(new LineData(dataSet))
model.getXAxis().setPosition(XAxisPosition.BOTTOM)
model.getXAxis().setValueFormatter((v) => `${Math.floor(v)}:00`)
model.getAxisLeft().setAxisMinimum(40)
model.getAxisRight().setEnabled(false)
model.setDescription(new Description().setText('24h 心率'))

// 支持手势缩放(双指缩放看细节)
model.setPinchZoom(true)
model.setDoubleTapToZoomEnabled(true)

第四步:睡眠饼状图——占比分布

import {
  PieChart, PieChartModel, PieData, PieDataSet, PieEntry,
  JArrayList
} from '@ohos/mpchart'

// 睡眠分布:深睡 2h、浅睡 5h、REM 1.5h、清醒 0.5h
const entries = new JArrayList<PieEntry>()
entries.add(new PieEntry(2, '深睡'))
entries.add(new PieEntry(5, '浅睡'))
entries.add(new PieEntry(1.5, 'REM'))
entries.add(new PieEntry(0.5, '清醒'))

const dataSet = new PieDataSet(entries, '睡眠分布')
dataSet.setColors([0xFF6C5CE7, 0xFF74B9FF, 0xFFFDCB6E, 0xFFFF7675])
dataSet.setSliceSpace(2) // 扇区间隙

const model = new PieChartModel()
model.setData(new PieData(dataSet))
model.setUsePercentValues(true) // 显示百分比
model.setDescription(new Description().setText(''))

为什么"数据眼"选了 mpchart?

需求 自研 Canvas @ohos/mpchart
柱状图 200+ 行 30 行
折线图 300+ 行 30 行
饼状图 250+ 行 20 行
手势缩放 手写 ✅ 内置
点击高亮 手写 ✅ 内置
雷达图 400+ 行 30 行

总结

"数据眼"这个场景里,@ohos/mpchart 解决了三件事:

  1. 多图表覆盖——柱状/折线/饼状/雷达,一个库搞定健康数据可视化全家桶
  2. 交互开箱即用——手势缩放、点击高亮、数据选中,不用手写
  3. 高度自定义——颜色、轴、网格、动画、格式化器,细节全可控

如果你也在做健康、金融、电商、IoT 监控等需要数据可视化的 App,@ohos/mpchart 让你的图表 UI 告别从零造轮子,几十行出图不是梦。


Logo

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

更多推荐