一、引言

仪表盘(Gauge)是人类最古老的量化展示方式之一。从汽车仪表盘上的速度表、医疗设备上的血压计,到工业控制面板上的温度表——环形刻度盘以"指针+刻度+颜色分区"的组合,在极小的空间内同时传递了"当前值是多少"、“处于什么范围”、"离临界值还有多远"三层信息。

在移动应用的数据可视化场景中,Gauge 是最有"张力"的展示组件之一。与线性进度条(Progress)不同,Gauge 天然具有"视觉焦点"——它的圆形结构将用户的视线自然地吸引到中心,配合弧形轨迹和梯度色彩,创造了进度条难以达到的"紧迫感"和"氛围感"。当你需要让用户立刻注意到某个指标的状态时(比如 CPU 接近满载、体温接近危险区),Gauge 比任何表格和数字都更有效。

ArkUI 提供了原生的 Gauge 组件,专为环形仪表盘场景设计。通过 Gauge({ value, min, max }) 构造函数定义数值范围,通过 .startAngle().endAngle() 控制弧形的开口范围和方向,通过 .colors() 定义梯度色带(如绿→黄→红),通过 .strokeWidth() 控制环的粗细——这些参数组合起来,可以创造出从精致的圆形进度环到气势磅礴的半圆弧仪表等丰富多彩的视觉效果。

本文将通过一个完整的**“设备监控仪表盘”**实战案例,深入解析 Gauge 组件的构造方式、角度控制、梯度色彩映射、滑块联动和预设值快速切换。阅读完本文,你将能够:

  • 掌握 Gauge 的构造参数(value、min、max)和核心属性
  • 理解 startAngle 和 endAngle 对仪表盘弧形的影响
  • 使用 colors() 构建动态梯度色带映射
  • 实现 Gauge 与 Slider 的双向联动
  • 通过预设按钮实现快速数值切换
    在这里插入图片描述

二、Gauge 核心 API 详解

2.1 构造函数:value / min / max

Gauge 组件的构造函数接受三个核心参数:

Gauge({
  value: number,    // 当前值(指针指向的位置)
  min?: number,     // 最小值,默认 0
  max?: number,     // 最大值,默认 100
})

这三个参数定义了仪表盘的"数据域"。minmax 决定了刻度的范围,value 决定了指针(或填充弧)的当前位置。在我们的 Demo 中:

Gauge({ value: this.values[idx], min: 0, max: 100 })

四个仪表盘(CPU、内存、存储、温度)使用了不同的初始值(45、62、78、35),在页面上形成了从绿色(正常)到黄色(中度)再到红色(高负载)的完整梯度展示。

minmax 的值不需要是整数,也不必须是 0 和 100——它们可以是任意数值范围。比如一个体温计仪表盘可以设为 min: 35, max: 42,一个压力计可以设为 min: 0, max: 200

2.2 startAngle 与 endAngle:弧形的"开口"

startAngleendAngle 是 Gauge 组件最具视觉影响力的两个属性。它们控制仪表盘弧形的起始角度和终止角度,使用度数制(而非弧度制),从 3 点钟方向开始顺时针计算。

.startAngle(150)   // 从 150° 开始(大约 8 点钟方向)
.endAngle(390)     // 到 390° 结束(绕一圈多 30°,即 9 点钟方向)

常见的角度组合及其视觉效果:

用途 startAngle endAngle 视觉效果
圆形进度环 0 360 完整的圆环(无缺口)
大半圆弧 150 390 底部留一个 120° 的缺口,类似汽车仪表盘
半圆弧 180 360 上半圆环,类似速度表
大半弧(下方) 135 405 底部留 90° 缺口,环更宽
扇形 225 315 90° 扇形,类似音量指示

在我们的 Demo 中,四个仪表盘使用了不同的角度配置:

{ startAngle: 150, endAngle: 390 },  // CPU:240° 弧长,底部 120° 缺口
{ startAngle: 160, endAngle: 380 },  // 内存:220° 弧长,底部 140° 缺口
{ startAngle: 135, endAngle: 405 },  // 存储:270° 弧长,底部 90° 缺口
{ startAngle: 180, endAngle: 360 },  // 温度:180° 半圆弧

不同的角度配置产生了不同的"仪表盘个性"——存储空间使用最开放的弧度(270°),暗示"空间是充裕的";温度使用最收敛的半圆弧(180°),暗示"温度区间是有限的"。这是一种通过视觉元素传递语义的设计手法。

2.3 strokeWidth:环的视觉重量

.strokeWidth(18)  // 18vp 粗的环形

strokeWidth 控制仪表环的粗细(即线条宽度)。较细的环(如 8-12vp)显得精致、含蓄,适合用作小尺寸的状态指示;较粗的环(如 18-24vp)更有视觉重量,适合用作页面级的大指标展示。

在我们的 Demo 中:

{ strokeWidth: 18 },  // CPU:中等粗细,标准仪表
{ strokeWidth: 14 },  // 内存:稍细,精致感
{ strokeWidth: 22 },  // 存储:最粗,强调"空间"的视觉量感
{ strokeWidth: 16 },  // 温度:标准粗细

2.4 colors():梯度色彩映射

colors() 是 Gauge 组件最强大的可视化特性。它接受一个 Array<[ResourceColor, number]> 类型的参数——每个元素是一个 [颜色, 百分比权重] 的元组:

.colors([
  ['#52C41A', 50],   // 绿色占 50%
  ['#FAAD14', 30],   // 黄色占 30%
  ['#FF4D4F', 20],   // 红色占 20%
])

系统会根据各颜色的百分比权重自动计算它们在弧上的分布。权重不一定要加起来等于 100——系统会自动进行归一化计算——但建议使用总和为 100 的权重以便于理解和维护。

在我们的 Demo 中,色彩映射是动态的——根据当前值的大小,绿色/黄色/红色的权重会变化:

function getColorStops(value: number): Array<[ResourceColor, number]> {
  if (value < 60) {
    // 低负载:绿色占主导
    return [['#52C41A', value], ['#FAAD14', 30], ['#FF4D4F', 10]];
  } else if (value < 80) {
    // 中负载:黄色占主导
    return [['#52C41A', 50], ['#FAAD14', value], ['#FF4D4F', 10]];
  } else {
    // 高负载:红色占主导
    return [['#52C41A', 50], ['#FAAD14', 30], ['#FF4D4F', value]];
  }
}

value 较小时,绿色(#52C41A)的权重跟随 value 增长而增长,给予足够的"健康区间"视觉占比。当 value 进入中负载时,黄色的权重跟随 value 增长。当 value 进入高负载时,红色的权重跟随 value 增长。

这种动态色彩映射让仪表盘不仅能"显示数值",还能"发出警告"——当参数接近危险区域时,红色部分自然扩大,产生一种视觉上的"压迫感",比单纯看数字变化要有力得多。

2.5 value 动态更新

value 属性可以通过链式调用动态更新:

Gauge({ value: this.values[idx], min: 0, max: 100 })

this.values[idx] 通过 Slider 或预设按钮发生变化时,Gauge 会自动重新渲染——指针会平滑地过渡到新位置(具体过渡效果取决于设备支持)。
在这里插入图片描述

三、实战:设备监控仪表盘

3.1 页面整体设计

设备监控仪表盘围绕"运维/监控"的场景设计,包含 4 个独立的 Gauge 卡片:

  1. CPU 使用率(⚙️)— 240° 弧长,18vp 粗,初始 45%
  2. 内存使用率(🧠)— 220° 弧长,14vp 细,初始 62%
  3. 存储空间(💿)— 270° 弧长,22vp 最粗,初始 78%
  4. 设备温度(🌡️)— 180° 半圆弧,16vp 粗,初始 35%

每个卡片包含:

  • 标题行(图标 + 标签 + 当前数值 + 状态标签)
  • Gauge 仪表(140vp 高的 Stack 容器)
  • 调节滑块(min 到 max 范围,步进 1)
  • 预设按钮(低/中/高三档快速跳转)

3.2 状态标签:数值→语义的映射

每个 Gauge 卡片右上角的状态标签将数值翻译为人类可读的语义:

function getStatusText(value: number): string {
  if (value >= 80) return '高负载';
  if (value >= 60) return '中度';
  return '正常';
}

function getStatusColor(value: number): string {
  if (value >= 80) return '#FF4D4F';  // 红色
  if (value >= 60) return '#FAAD14';  // 黄色
  return '#52C41A';                   // 绿色
}

状态标签的文字颜色背景色使用了与 Gauge 色彩映射相同的颜色:绿色=正常、黄色=中度、红色=高负载。这个一致性很重要——用户看仪表盘的颜色(红色弧段更多)和看标签的颜色(红色背景)得到同样的"这是个问题"的信号。如果仪表盘使用绿/黄/红但标签使用其他颜色,会造成认知上的不协调。

标签的文字和数值使用相同的颜色(通过 getStatusColor()),标签的背景使用颜色填充 + 白色文字,形成一种"药丸"(pill)式的徽标效果。

3.3 Slider 联动:拖拽即时的参数调节

每个 Gauge 卡片下方都有一个 Slider,用于调节该指标的值:

Slider({ value: this.values[idx], min: config.min, max: config.max, step: 1 })
  .onChange((value: number) => {
    const updated: number[] = [];
    for (let i = 0; i < this.values.length; i++) {
      if (i === idx) {
        updated.push(value);
      } else {
        updated.push(this.values[i]);
      }
    }
    this.values = updated;
  })

Slider 的拖动即时反映在 Gauge 上——这是 @State values 数组与 Gauge 的 value 属性双向绑定的效果。用户拖动 Slider 的瞬间:

  1. this.values[idx] 更新为新的数值
  2. Gauge 的 .value(this.values[idx]) 响应更新,指针移动到新位置
  3. 标题行中的数值显示同步更新
  4. getColorStops() 重新计算色带分布,颜色分区随之调整
  5. getStatusText()getStatusColor() 更新标签

前端的"深度响应"在这里体现得淋漓尽致——单一的 @State 变量变化驱动了 5 个不同视觉元素的同步更新。

3.4 预设按钮:低/中/高快速跳转

每个卡片底部有三个预设按钮(低/中/高),允许用户一键将指标跳转到典型值:

Text('低').onClick(() => { /* 设为 20 */ })
Text('中').onClick(() => { /* 设为 65 */ })
Text('高').onClick(() => { /* 设为 90 */ })

这三个预设值(20 / 65 / 90)分别对应三种状态——低(绿色主导)、中(黄色主导)、高(红色主导)。用户可以通过这三个按钮快速体验 Gauge 在三种不同状态下的视觉效果:

  • 点击"低":仪表盘变成绿/黄/红=20:30:10,绝大部分是绿色,标签显示"正常"
  • 点击"中":仪表盘变成绿/黄/红=50:65:10,黄色弧段显著扩大,标签显示"中度"
  • 点击"高":仪表盘变成绿/黄/红=50:30:90,红色弧段占据主导,标签显示"高负载"

预设按钮和 Slider 之间也保持了同步——点击预设按钮后,Slider 的滑块会自动跳转到对应的位置(因为 Slider 的 value 绑定到同一个 this.values[idx])。

3.5 不可变更新模式

由于 ArkTS 要求 @State 数组必须通过创建新数组来触发 UI 刷新,所有的数组更新都使用了"不可变更新"模式:

const updated: number[] = [];
for (let i = 0; i < this.values.length; i++) {
  if (i === idx) {
    updated.push(value);  // 创建新值
  } else {
    updated.push(this.values[i]);  // 保持旧值引用
  }
}
this.values = updated;  // 替换整个数组引用

这种模式在之前的文章中多次出现(GoalTrackerPage 的增减操作等),但值得再次强调:在 ArkTS 中,直接修改 @State 数组的元素(如 this.values[idx] = value)不会触发 UI 刷新。必须创建一个全新的数组并赋值给 this.values,ArkUI 的声明式刷新机制才能检测到变化并触发重新渲染。

四、完整代码结构

页面组件树:

Column
├── Row(标题栏:"设备监控")
└── Scroll
    └── Column
        ├── CPU 卡片
        │   ├── Row(⚙️ + "CPU 使用率" + 45% + "正常"标签)
        │   ├── Gauge(240°弧,18vp粗,动态色带)
        │   ├── Slider(0-100,步进1)
        │   └── Row(低/中/高 三个预设按钮)
        ├── 内存卡片
        │   └── (同上结构,220°弧,14vp细)
        ├── 存储卡片
        │   └── (同上结构,270°弧,22vp粗)
        └── 温度卡片
            └── (同上结构,180°半圆弧,16vp粗)

代码约 210 行,核心聚焦 Gauge 的 value/min/max 构造函数、startAngle/endAngle 角度控制、colors() 动态色带映射、strokeWidth 环粗控制,以及与 Slider 的双向联动。

五、总结

本文以设备监控仪表盘为应用场景,深入解析了 ArkUI Gauge 仪表盘组件的核心 API、角度控制和色彩映射。

回顾本文覆盖的核心要点:

  1. Gauge 的本质:环形仪表盘组件,通过 value(当前值)、min(最小值)、max(最大值)定义数据域,通过指针或填充弧的位置直观展示数值。

  2. 角度控制startAngleendAngle 定义弧形的形状,从半圆弧(180°-360°)到完整圆环(0°-360°)再到超大半圆弧(135°-405°),不同的角度范围赋予仪表盘不同的"性格"。

  3. 环粗控制strokeWidth 定义环的线条粗细,从精致的 8vp 到有分量的 24vp,根据指标的重要性和展示空间选择。配合不同的角度范围,相同的 strokeWidth 会产生不同的视觉重量。

  4. 梯度色彩映射colors(Array<[ResourceColor, number]>) 定义多段色带,每段由颜色和百分比权重组成。通过动态调整各段的权重,实现"数值越大、红色越多"的自适应色彩表达。这是 Gauge 最核心的可视化能力。

  5. 与 Slider 联动:Gauge 的 value 属性绑定到 @State 变量,与 Slider 共享同一数据源,实现拖拽即时的双向联动。配合预设按钮,用户可以快速体验不同数值下的仪表盘视觉效果。

  6. 状态语义化:通过 getStatusText()getStatusColor() 将抽象数值(如 78)翻译为人类可读的语义标签(如"中度"/黄色),与 Gauge 的色彩映射保持视觉语言一致。

Gauge 是 ArkUI 中最有"工业设计感"的组件之一。它天然携带了"仪表盘"的隐喻——指针、刻度、色区,这些视觉元素让人联想到飞机驾驶舱、汽车仪表盘、医疗监护仪——进而传递了一种"精确、实时、重要"的感觉。当你的应用需要展示某个关键指标时(CPU、心率、温度、进度、评分),不要只放一个数字——用一个 Gauge,让数据"说话"的方式更有力量。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐