news 2026/7/6 1:36:42

鸿蒙 ArkUI 数据可视化图例对照表:组件化设计与实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
鸿蒙 ArkUI 数据可视化图例对照表:组件化设计与实现


鸿蒙 ArkUI 数据可视化图例对照表:组件化设计与实现

一、引言

图例(Legend)是数据可视化中连接数据与视觉编码的桥梁。用户通过颜色与标签的对照关系快速理解图表含义。随着 HarmonyOS NEXT 普及,ArkTS 声明式 UI 成为主流,但新版 ArkUI 移除了 Table 等旧组件,使许多开发者对表格布局感到困惑。

本文以完整图例对照表为案例,讲解如何用 Row + Column 弹性布局、颜色矩形、文字标签和线性渐变 API 构建可复用的图例组件库。


二、需求分析与总体设计

2.1 功能需求

  1. 颜色标识:每个条目包含带圆角的颜色矩形。
  2. 标签文字:说明颜色对应的分类名称。
  3. 附加描述:辅助文字(温度范围、占比等)。
  4. 连续型图例:渐变色彩条配合刻度标签。
  5. 离散型图例:表格形式的多行分类。
  6. 多组并存:分割线区隔,可滚动浏览。

2.2 技术选型

需求方案理由
UI 框架ArkTS + ArkUI鸿蒙原生声明式框架
表格布局Row + Column + layoutWeightAPI 11+ 已移除 Table
颜色矩形Row + backgroundColor + borderRadius轻量高效
渐变条Row + linearGradient()原生 API
列表渲染ForEach + 数组内置能力

2.3 架构概览

Index(@Entry 根组件) └─ Scroll → Column ├─ 页面标题 ├─ GradientBar(连续型渐变图例) ├─ LegendTableGroup × 3 │ ├─ SectionTitle + 副标题 │ └─ 表格 Column → LegendTableRow 列表 │ ├─ ColorSwatch(色块) │ └─ LegendCell × 2 └─ 底部版权

三、核心组件实现

3.1 数据模型

interfaceLegendItem{color:ResourceColor;label:string;description:string;}

预置三种数据源(温度 / 占比 / 评分):

constTEMPERATURE_LEGENDS:LegendItem[]=[{color:'#FF4444',label:'高温',description:'≥ 35°C'},{color:'#FF8C00',label:'炎热',description:'30°C – 34°C'},{color:'#FFD700',label:'温暖',description:'20°C – 29°C'},{color:'#87CEEB',label:'凉爽',description:'10°C – 19°C'},{color:'#1E90FF',label:'寒冷',description:'0°C – 9°C'},{color:'#0000CD',label:'严寒',description:'< 0°C'},];constPROPORTION_LEGENDS:LegendItem[]=[{color:'#5470C6',label:'A 类',description:'销售额占比 45%'},{color:'#91CC75',label:'B 类',description:'销售额占比 28%'},{color:'#FAC858',label:'C 类',description:'销售额占比 15%'},{color:'#EE6666',label:'D 类',description:'销售额占比 12%'},];constLEVEL_LEGENDS:LegendItem[]=[{color:'#00BFFF',label:'优秀',description:'评分 ≥ 90'},{color:'#32CD32',label:'良好',description:'75 ≤ 评分 < 90'},{color:'#FFD700',label:'中等',description:'60 ≤ 评分 < 75'},{color:'#FF6347',label:'较差',description:'评分 < 60'},];

3.2 ColorSwatch(颜色矩形)

使用空 Row + backgroundColor,比 Shape + Rect 更轻量:

@Componentstruct ColorSwatch{swatchColor:ResourceColor='#5470C6';swatchSize:number=20;build(){Row().width(this.swatchSize).height(this.swatchSize).backgroundColor(this.swatchColor).borderRadius(4)}}

Shape + Rect 渲染有额外开销,空 Row 本质就是矩形区域,加 backgroundColor 即可。4px 圆角让色块不显生硬。

3.3 LegendCell(表格单元格)

封装 Text 通用样式:

@Componentstruct LegendCell{content:string='';fontWeight:FontWeight=FontWeight.Normal;fontColor:ResourceColor='#333333';build(){Text(this.content).fontSize(14).fontWeight(this.fontWeight).fontColor(this.fontColor).textAlign(TextAlign.Start).maxLines(1).textOverflow({overflow:TextOverflow.Ellipsis})}}

注意:API 11+ 中文字溢出省略语法已从.overflow(TextOverflow.Ellipsis)变为.textOverflow({ overflow: TextOverflow.Ellipsis }),这是迁移时最常见的坑。

3.4 LegendTableRow(表格行)

三列布局,支持表头/数据行双模式:

@Componentstruct LegendTableRow{color:ResourceColor='#5470C6';label:string='';desc:string='';isHeader:boolean=false;build(){Row(){Row(){if(this.isHeader){Text('#').fontSize(14).fontWeight(FontWeight.Bold).fontColor('#666666')}else{ColorSwatch({swatchColor:this.color,swatchSize:20})}}.width(60).justifyContent(FlexAlign.Center)LegendCell({content:this.label,fontWeight:this.isHeader?FontWeight.Bold:FontWeight.Medium,fontColor:this.isHeader?'#666666':'#333333'}).layoutWeight(1)LegendCell({content:this.desc,fontWeight:this.isHeader?FontWeight.Bold:FontWeight.Normal,fontColor:this.isHeader?'#666666':'#888888'}).layoutWeight(1.2)}.width('100%').height(this.isHeader?40:48).padding({left:8,right:8}).backgroundColor(this.isHeader?'#f8f9fa':Color.White).borderWidth({bottom:1}).borderColor({bottom:'#f0f0f0'})}}

三列弹性布局:首列固定 60px 居中;次列layoutWeight(1);第三列layoutWeight(1.2)略宽。isHeader控制表头/数据行的颜色、字号、背景差异。逐行底部分隔线避免整表双倍边框。

3.5 SectionTitle(区块标题)

左侧色条 + 粗体标题,色条颜色与图例主题一致:

@Componentstruct SectionTitle{title:string='';iconColor:ResourceColor='#5470C6';build(){Row(){Column().width(4).height(18).backgroundColor(this.iconColor).borderRadius({topLeft:2,bottomLeft:2})Text(this.title).fontSize(18).fontWeight(FontWeight.Bold).fontColor('#222222').margin({left:10})}.width('100%').alignItems(VerticalAlign.Center).margin({top:16,bottom:4})}}

3.6 GradientBar(连续型渐变条)

使用原生linearGradient()API,深蓝 → 红色六段渐变:

@Componentstruct GradientBar{build(){Column(){Row().width('100%').height(28).borderRadius(6).linearGradient({direction:GradientDirection.Right,colors:[['#0000CD',0.0],['#1E90FF',0.2],['#87CEEB',0.35],['#FFD700',0.5],['#FF8C00',0.7],['#FF4444',1.0],]})Row(){Text('低').fontSize(13).fontColor('#999999')Blank()Text('中').fontSize(13).fontColor('#999999')Blank()Text('高').fontSize(13).fontColor('#999999')}.width('100%').margin({top:4})}.width('100%')}}

色标偏移量非均匀分布(蓝色区宽、红色区紧),模拟"低温区间大"的感知。刻度通过Blank()自然三等分。注意linearGradient不可用于Shape.fill()——后者仅接受纯色ResourceColor

3.7 LegendTableGroup(表格组)

组装标题、副标题和表格行为完整区块:

@Componentstruct LegendTableGroup{title:string='';subtitle:string='';iconColor:ResourceColor='#5470C6';legends:LegendItem[]=[];build(){Column(){SectionTitle({title:this.title,iconColor:this.iconColor})Text(this.subtitle).fontSize(13).fontColor('#999999').width('100%').margin({bottom:8})Column(){LegendTableRow({color:'#555555',label:'标签',desc:'说明',isHeader:true})ForEach(this.legends,(item:LegendItem)=>{LegendTableRow({color:item.color,label:item.label,desc:item.description})})}.width('100%').border({width:{top:1,bottom:1},color:'#e0e0e0'}).borderRadius(8).clip(true)}.width('100%')}}

外层border({ top:1, bottom:1 })加上下边框,borderRadius(8)+clip(true)形成圆角卡片。

3.8 模拟 Table 的原理

Row + Column 替代原生 Table:首列固定宽,后续layoutWeight按比例分配;每行底部borderWidth({ bottom: 1 })分隔;isHeader切换表头/数据行样式。对固定结构的图例展示完全够用。


四、页面组装

4.1 主页面 Index

@Entry@Componentstruct Index{build(){Scroll(){Column(){Text('数据可视化图例对照表').fontSize(26).fontWeight(FontWeight.Bold).fontColor('#1a1a2e').width('100%').margin({top:28,bottom:4})Text('Data Visualization Legend').fontSize(13).fontColor('#aaaaaa').width('100%').margin({bottom:20})SectionTitle({title:'连续型渐变图例 (Sequential)',iconColor:'#FF8C00'})Text('适用于热力图 / 气象图表').fontSize(13).fontColor('#999999').width('100%').margin({bottom:8})GradientBar()Divider().height(1).color('#eeeeee').margin({top:20,bottom:4})LegendTableGroup({title:'温度等级 (Temperature)',iconColor:'#FF4444',subtitle:'适用于热力图 / 气象图表',legends:TEMPERATURE_LEGENDS})LegendTableGroup({title:'占比分类 (Proportion)',iconColor:'#91CC75',subtitle:'适用于饼图 / 环形图 / 堆叠图',legends:PROPORTION_LEGENDS})LegendTableGroup({title:'评分等级 (Rating Level)',iconColor:'#00BFFF',subtitle:'适用于仪表盘 / 评分图 / 状态标识',legends:LEVEL_LEGENDS})Divider().height(1).color('#eeeeee').margin({top:24,bottom:12})Row(){Text('Powered by ').fontSize(12).fontColor('#bbbbbb')Text('HarmonyOS ArkUI').fontSize(12).fontColor('#5470C6').fontWeight(FontWeight.Medium)}.width('100%').justifyContent(FlexAlign.Center).margin({bottom:32})}.width('100%').padding({left:16,right:16})}.backgroundColor('#ffffff').height('100%')}}

主标题 #1a1a2e,区块标题 #222222,标签 #333333,描述 #888888。


五、常见问题与优化

私有属性限制:ArkTS 的private禁止构造传参,移除即可。TextOverflow 变更:API 11+ 改用.textOverflow({ overflow: TextOverflow.Ellipsis })LinearGradient:不可用于 Shape.fill(),需用容器组件.linearGradient()方法。Table 缺失:用 Row + Column + layoutWeight 替代。性能:ForEach 用 key 加速差异化更新;大数据量用 LazyForEach 虚拟列表。


六、扩展建议

主题系统:颜色值抽取为资源引用,支持深色模式。交互:点击筛选、折叠展开、长按提示。图例类型:形状/线型/大小/复合图例。国际化:用$r('app.string.xxx')实现多语言。动画:用animateToanimation添加入场效果。


七、总结

本文讲解了在鸿蒙 ArkUI 中用 Row + Column 弹性布局、颜色矩形、文字标签和线性渐变 API 构建图例组件库的方法。六个独立组件实现了高内聚低耦合。

关键语法:组件属性默认访问级别才能构造传参;textOverflow({ overflow: TextOverflow.Ellipsis })是 API 11+ 正确用法;linearGradient 不可用于 Shape.fill;用 Row + Column 替代已移除的 Table 组件。

本案例已在 HarmonyOS NEXT(API 6.1.1/24)编译通过,源码位于entry/src/main/ets/pages/Index.ets


    版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
    网站建设 2026/7/6 1:35:53

    燃料已燃,引擎轰鸣:具身智能从当下落地到未来星辰的应用全景

    从前面六大来源的深度拆解中&#xff0c;我们看到了具身智能数据的“燃料”是如何被开采、精炼和聚合的。那么&#xff0c;这些燃料究竟驱动着怎样的机器&#xff0c;又将把人类带向何方&#xff1f;这正是具身智能应用场景所回答的问题——它不仅关乎技术本身&#xff0c;更关…

    作者头像 李华
    网站建设 2026/7/6 1:33:03

    144、结构化输出:JSON Mode、Function Calling、Grammars 三种方案对比

    144、结构化输出:JSON Mode、Function Calling、Grammars 三种方案对比 从一次凌晨三点的事故说起 凌晨三点,生产告警炸了。用户上传的简历解析结果里,大模型返回的JSON字段skills变成了"Python, Java, Go"——一个字符串,而不是我们约定的数组。下游的数据库插…

    作者头像 李华
    网站建设 2026/7/6 1:30:51

    Java Swing贪吃蛇游戏完整实现(MVC架构+MySQL排行榜+音效系统)

    ## 一、项目简介这是一个基于 **Java Swing** 开发的经典贪吃蛇游戏&#xff0c;采用 **MVC架构** 设计&#xff0c;支持三种难度选择、MySQL排行榜存储、音效系统和多线程优化。该项目适合Java初学者学习GUI开发、设计模式和数据库操作。## 二、功能特性- &#x1f3ae; **完整…

    作者头像 李华
    网站建设 2026/7/6 1:28:57

    基于51单片机的超声波智能垃圾桶控制系统红外感应自动手动嵌入式143(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码

    基于51单片机的超声波智能垃圾桶控制系统红外感应自动手动嵌入式143(设计源文件万字报告讲解)&#xff08;支持资料、图片参考_相关定制&#xff09;_文章底部可以扫码 步进电机版本功能说明&#xff1a; LCD1602液晶显示当前垃圾满溢程度和当前电机状态超声波检测当前垃圾满溢…

    作者头像 李华