HarmonyOS Next系列之Echarts图表组件(折线图、柱状图、饼图等)实现(八)
系列文章目录
HarmonyOS Next 系列之省市区弹窗选择器实现(一)
HarmonyOS Next 系列之验证码输入组件实现(二)
HarmonyOS Next 系列之底部标签栏TabBar实现(三)
HarmonyOS Next 系列之HTTP请求封装和Token持久化存储(四)
HarmonyOS Next 系列之从手机选择图片或拍照上传功能实现(五)
HarmonyOS Next 系列之可移动悬浮按钮实现(六)
HarmonyOS Next 系列之沉浸式状态实现的多种方式(七)
HarmonyOS Next系列之Echarts图表组件(折线图、柱状图、饼图等)实现(八)
文章目录
- 系列文章目录
- 前言
- 一、实现原理分析
- 二、代码实现
- 1.项目内新建本地html文件引入echarts.min.js
- 2.Echart.ets组件封装
- 3.页面使用
- 三、配置项含函数需特殊处理
- 代码示例:
- 总结
前言
HarmonyOS Next(基于API11)实现Echarts图表组件(折线图、柱状图、饼图等)。
Echarts作为web端最流行开源的图表库,有着
多种图表类型,丰富的配置、强大的交互功能、可扩展性强等优点,如果能在鸿蒙上使用对于熟悉web开发同学将无缝衔接,大大减少开发和学习成本。
一、实现原理分析
echarts作为JavaScript实现的开源可视化库只能通过网页形式渲染,所以可以 通过web组件内嵌本地网页形式混合开发。web和应用交互则通过WebviewController.runJavaScript(code)形式往网页注入执行代码。
二、代码实现
1.项目内新建本地html文件引入echarts.min.js
resources/rawfile目录下新建echarts.html和添加echarts.min.js
echarts.html:
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0;" name="viewport"/><script src="./echarts.min.js"></script><style>*{padding:0;margin:0}body,html{height:100%;width:100%}#container{height:100%;width:100%}</style>
</head>
<body>
<div id="container"></div>
</body>
<script>const container = document.getElementById('container')let myChart = echarts.init(container);function setOption(option){myChart?.clear();myChart?.setOption(option)}</script>
</html>
echarts.min.js:
可以从官网在线定制下载echart.js定制
说明:此步骤新建了一个html文件引入了echarts.min.js并初始化echarts,定义了一个
setOption方法,后续通过调用该方法传入配置就能渲染出图表
2.Echart.ets组件封装
封装一个全局通用的echart组件,目录结构如上图所示,其中Echarts.ets为组件文件,ViewModel.ets为图表相关配置数据类型定义
Echarts.ets
import webview from '@ohos.web.webview'@Component
export default struct Echarts {//控制器controller: webview.WebviewController = new webview.WebviewController();//组件宽@Prop eWidth: string | number = '100%'//组件高,单位vp@Prop eHeight: string | number = 300//渲染完成回调renderCallBack: (e: Echarts) => void = () => {}//更新或渲染组件render(option: Record<string, ESObject> | string) {this.controller.runJavaScript(`setOption(${typeof option === 'string' ? option : JSON.stringify(option)})`)}build() {Column() {Web({ src: $rawfile('echarts.html'), controller: this.controller }).width('100%').height('100%').onPageEnd(e => {this.renderCallBack && this.renderCallBack(this)})}.width(this.eWidth).height(this.eHeight)}
}
说明:
组件定义了长宽属性,默认宽度100%,高度300vp,
renderCallBack回调函数作用把整个echarts组件实例暴露给引用页面。
render方法重新加载渲染组件,入参为图表配置,入参既可以是对象也可以是字符串,无论何种类型最终都将转换为字符串注入web执行。
在引用页面通过renderCallBack暴露出去的实例调用render方法即可自由刷新图表数据
ViewModel.ets:
/*** echart配置数据类型定义*/
export interface EChartsOption {grid?: EchartGrid,title?: EChartsTitle;tooltip?: EChartsTooltip;legend?: EChartsLegend;xAxis: EChartsXAxis;yAxis: EChartsYAxis;series: EChartsSeries[];
}export interface EchartGrid {top?: number|stringbottom?: number|stringleft?: number|stringright?: number|string
}export interface EChartsTitle {text?: string;
}export interface EChartsTooltip {}export interface EChartsLegend {show?:booleandata?: string[];
}export interface EChartsXAxis {type?: string;data: string[];axisLine?: XAxisAxisLine;axisTick?: XAxisAxisTickboundaryGap?: boolean | Array<string>axisLabel?: AxisLabel}export interface XAxisAxisLine {show?: boolean
}export interface XAxisAxisTick {show?: boolean
}export interface EChartsYAxis {type?: stringsplitLine?: YAxisSplitLinesplitNumber?: numbermin?: numbermax?: numberscale?: booleaninterval?: number}export interface AxisLabel {show?: booleanformatter?: string | ((value: number | string, index: number) => string)
}export interface YAxisSplitLine {lineStyle?: AxisSplitLineLineStyle
}export interface AxisSplitLineLineStyle {type?: string
}export interface EChartsSeries {name?: string;type?: string;data: number[];}
ViewModel.ets里面定义了一些常见的图表配置数据结构(类型),方便在引入页中引入使用,可以按需继添加扩展
3.页面使用
Index.ets
import Echarts from '../components/Echarts/Echarts'
import { EChartsOption } from '../components/Echarts/ViewModel'@Entry
@Component
struct Index {//图表实例myEchart: Echarts | null = null/** 图表配置*/option: EChartsOption = {//标题title: {text: '基础柱状图'},//图例legend: {data: ['访问量']},//x轴配置xAxis: {type: 'category',data: []},//y轴配置yAxis: {type: 'value'},//数据配置series: [{data: [],type: 'bar',//柱状图name: '访问量'}]};aboutToAppear(): void {this.getData()}//接口请求获取数据getData() {//模拟接口请求setTimeout(() => {//设置x轴数据this.option.xAxis.data = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']//设置y轴数据this.option.series[0].data = [120, 200, 150, 80, 70, 110, 130]//调用render重新渲染this.myEchart?.render(this.option)}, 2000)}// 组件实例chart?: Echarts;build() {Column() {Echarts({eHeight: 300,//回调renderCallBack: (e: Echarts) => {this.myEchart = e//初次渲染组件,接口获取数据是异步此时this.option可能还没有新数据this.myEchart.render(this.option)}})}.width('100%').height('100%')}
}
运行效果:
三、配置项含函数需特殊处理
对于配置项包含函数的情况,例如坐标轴标签设置AxisLabel.formatter字段可以是个函数类型,此时就需要特殊处理。这是因为当我们传递option为对象给render函数时候
this.controller.runJavaScript(`setOption(${typeof option === 'string' ? option : JSON.stringify(option)})`)
此时调用JSON.stringify把对象转换为字符串,而JSON.stringify入参内函数会直接被去掉。
因此我们需要自己把option处理成字符串传入即可
代码示例:
给折线图y轴刻度值加个万字
Index.ets
import Echarts from '../components/Echarts/Echarts'@Entry
@Component
struct Index {//图表配置@State option: string = ``//x轴数据@State xAxisData: string[] = [];//y轴数据@State seriesData: number[] = [];myEchart: Echarts | null = null;aboutToAppear(): void {this.getData()}/** 设置配置并重新渲染*/setOption() {this.option = `{title: {text: '基础柱折线图'},grid:{left:"15%"},legend:{data: ['访问量']},xAxis: {type: 'category',data: ${JSON.stringify(this.xAxisData)}},yAxis: {axisLabel: {show: true,formatter:(value, index)=> {return value + '万';}}},series: [{data: ${JSON.stringify(this.seriesData)},type: 'line',name:'访问量'}]}`this.myEchart?.render(this.option)}//接口请求获取数据getData() {//模拟接口请求setTimeout(() => {this.xAxisData = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']this.seriesData = [120, 200, 150, 80, 70, 110, 130]this.setOption()}, 2000)}// 组件实例chart?: Echarts;build() {Column() {Echarts({eHeight: 300,renderCallBack: (e: Echarts) => {this.myEchart = ethis.setOption()}})}.width('100%').height('100%')}
}
运行效果:
总结
当然作为混合开发产物性能自然比上不上原生,但是echarts有着跨平台兼容性好等优点,对付数据量不大、交互要求不高的场景绰绰有余。目前处于起步发展阶段的鸿蒙来说还没有一款稳定成熟、配置丰富能满足各种ui设计要求的官方或三方组件库。所以只要你的开发场景对性能要求不高,web形式的echart也是个不错的选择,尤其能实现各种定制化ui。
相关文章:

HarmonyOS Next系列之Echarts图表组件(折线图、柱状图、饼图等)实现(八)
系列文章目录 HarmonyOS Next 系列之省市区弹窗选择器实现(一) HarmonyOS Next 系列之验证码输入组件实现(二) HarmonyOS Next 系列之底部标签栏TabBar实现(三) HarmonyOS Next 系列之HTTP请求封装和Token…...

网上怎么样可以挣钱,分享几种可以让你在家赚钱的兼职项目
当今社会,压力越来越大,工作、家庭、生活等等,方方面面都需要钱,仅靠一份工作赚钱,已经很难满足我们的需求。所以很多人都会尝试做一些副业,兼职来补贴家用。 现在呢,有很多人都想在网上赚钱&am…...

【DevOps】运维过程中经常遇到的Http错误码问题分析(二)
目录 一、HTTP 错误400 Bad Request 1、理解 400 Bad Request 错误 2、排查 400 Bad Request 错误 3、常见的解决方法 二、HTTP 错误401 Unauthorized 1、理解 401 Unauthorized 错误 2、排查 401 Unauthorized 错误 3、常见的解决方法 一、HTTP 错误400 Bad Request …...

数据结构练习
1. 快速排序的非递归是通过栈来实现的,则前序与层次可以通过控制入栈的顺序来实现,因为递归是会一直开辟栈区空间,所以非递归的实现只需要一个栈的大小,而这个大小是小于递归所要的, 非递归与递归的时间复杂度是一样的…...

手动安装Ruby 1.9.3并升级RubyGems
手动安装Ruby 1.9.3并升级RubyGems ###Ruby 1.9.3 p125安装 wget http://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.3-p125.tar.gz \ && tar -xzvf ruby-1.9.3-p125.tar.gz \ && cd ruby-1.9.3-p125 \ && ./configure --with-openssl-dir/usr/lib/op…...

go语言day11 错误 defer(),panic(),recover()
错误: 创建错误 1)fmt包下提供的方法 fmt.Errorf(" 格式化字符串信息 " , 空接口类型对象 ) 2)errors包下提供的方法 errors.New(" 字符串信息 ") 创建自定义错误 需要实现error接口,而error接口…...

构建docker镜像实战
构建docker镜像 构建基础容器镜像(Base Image)是创建容器化应用程序的第一步。基础镜像提供了一个最低限度的操作系统环境,您可以在其上安装所需的软件包和应用程序。 Dockerfile语法说明 Dockerfile 是 Docker 构建镜像的描述文件&#x…...

生信算法9 - 正则表达式匹配氨基酸序列、核型和字符串
建议在Jupyter实践。 1. 使用正则表达式匹配指定的氨基酸序列 import re# 氨基酸序列 seq VSVLTMFRYAGWLDRLYMLVGTQLAAIIHGVALPLMMLI# 正则表达式匹配 match re.search(r[A|G]W, seq)# 打印match及匹配到开始位置和结束位置 print(match) # <re.Match object; span(10, …...

linux ext2文件系统浅析
文章目录 前言ext2内容概述实验准备二进制对比分析1 super block2 group desc3 block bitmap4 inode bitmap5 inode_tableinode 1inode 2inode 11inode 12 6 dir entry7 data区8 间接块9 块组 前言 网上关于ext2文件系统的博客有很多,但看完之后还是有些云里雾里&a…...

「树莓派入门」树莓派进阶02-传感器应用与交通灯项目
传感器是树莓派实现智能化的关键。通过本教程,你可以开始尝试使用传感器来增强树莓派的功能。 一、传感器在树莓派中的作用 传感器是树莓派与外界环境交互的重要工具。它们可以检测各种物理量,如光、声音、温度等,并将这些物理量转换为电信号,供树莓派读取和处理。 二、数…...

pytorch 指定GPU设备
使用os.environ["CUDA_VISIBLE_DEVICES"] 这种方法是通过环境变量限制可见的CUDA设备,从而在多个GPU的机器上只让PyTorch看到并使用指定的GPU。这种方式的好处是所有后续的CUDA调用都会使用这个GPU,并且代码中不需要显式地指定设备索引。 im…...

华为od-C卷200分题目6 - 5G 网络建设
华为od-C卷200分题目6 - 5G 网络建设 题目描述 现需要在某城市进行 5G 网络建设,已经选取 N 个地点设置 5G 基站,编号固定为 1 到 N,接下来需要各个基站之间使用光纤进行连接以确保基站能互联互通,不同基站之间架设光纤的成本各不…...

步进电机(STM32+28BYJ-48)
一、简介 步进电动机(stepping motor)把电脉冲信号变换成角位移以控制转子转动的执行机构。在自动控制装置中作为执行器。每输入一个脉冲信号,步进电动机前进一步,故又称脉冲电动机。步进电动机多用于数字式计算机的外部设备&…...

Node.js介绍 , 安装与使用
1.Node.js 1 什么是Node.js 官网:https://nodejs.org/zh-cn/ 中文学习网:http://nodejs.cn/learn1.Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。Node.js 使用了一个事件驱动、非阻塞式 I/O 的模型,使其轻量又高效。 2.前端的底层 html…...

JavaEE初阶-网络原理1
文章目录 前言一、UDP报头二、UDP校验和2.1 CRC2.2 md5 前言 学习一个网络协议,最主要就是学习的报文格式,对于UDP来说,应用层数据到达UDP之后,会给应用层数据报前面加上UDP报头。 UDP数据报UDP包头载荷 一、UDP报头 如上图UDP的…...

leetcode秋招冲刺 (专题16--18)
专题16:分治 题目169:多数元素(YES) 解题思路:使用哈希表可以统计出现次数的性质,直接统计就行。 给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊…...

学懂C#编程:实用方法——string字符串指定连接符拼接之 string.Join 的详细用法
在C#中,string.Join 方法用于将一个字符串数组或集合中的元素连接成一个单一的字符串,并在每个元素之间插入指定的分隔符。这个方法非常有用,特别是在需要将多个字符串合并成一个字符串时。以下是 string.Join 方法的详细用法: 方…...

Javascript常见数据结构和设计模式
在JavaScript中,常见的数据结构包括两大类:原始数据类型(Primitive Types)和对象类型(Object Types)。对象类型又可以进一步细分为多种内置对象、数组、函数等。下面是一些JavaScript中常见的数据结构&…...

【ChatGPT】全面解析 ChatGPT:从起源到未来
ChatGPT 是由 OpenAI 开发的一个基于 GPT(Generative Pre-training Transformer)架构的聊天机器人。通过自然语言处理(NLP)技术,ChatGPT 能够理解和生成语言,与人类进行对话。本文将深入探讨其起源、发展、…...

html+css+js贪吃蛇游戏
贪吃蛇游戏🕹四个按钮控制方向🎮 源代码在图片后面 点赞❤️关注🙏收藏⭐️ 互粉必回🙏🙏😍😍😍 源代码📟 <!DOCTYPE html> <html lang"en"&…...

新手必学:掌握Excel中这些常用公式,轻松提升数据处理能力
各位同学好,今天和大家来分享几个常用函数公式的典型用法。 1、提取指定条件的不重复名单 如下图所示,某公司课程比赛,同一员工有多个比赛项目。希望从左侧的列表中,提取出财务部的参赛人员名单。F2单元格输入以下公式࿰…...

经济寒冬:竞品凶猛,你的产品如何求生?
那些年曾被竞品干掉的产品 1997年到2010年左右是国内互联网行业的快速发展和多元化发展的时期,这一时期涌现出来一大批优秀的产品,市场竞争越来越激烈。苹果 在20 世纪 80 年代,乔布斯的苹果电脑,在当时可是PC行业的老大…...

信号量——Linux并发之魂
欢迎来到 破晓的历程的 博客 引言 今天,我们继续学习Linux线程本分,在Linux条件变量中,我们对条件变量的做了详细的说明,今天我们要利用条件变量来引出我们的另一个话题——信号量内容的学习。 1.复习条件变量 在上一期博客中&…...

自动驾驶中的逆透视变换(Inverse Perspective Mapping,IPM)详解
前言 IPM(Inverse Perspective Mapping,逆透视变换)图的历史可以追溯到计算机视觉和图像处理领域的发展。逆透视变换是一种用于消除图像中透视效应的技术,使得原本由于透视产生的形变得以纠正,进而更准确地描述和理解图像中的场景。比如在行车中的车道线检测,泊车中的常见…...

Python地震波逆问题解构算法复杂信号分析
🎯要点 🎯时域、时频域以及时间和频率相关联偏振特性分析三种算法 | 🎯时域波参数估计算法 | 🎯机器学习模型波形指纹分析算法 | 🎯色散曲线和频率相关波分析算法 | 🎯动态倾斜校正算法 | 🎯声…...

C语言 -- 深入理解指针(二)
C语言 -- 深入理解指针(二) 1. 数组名的理解2. 使用指针访问数组3. 一维数组传参的本质4. 冒泡排序5. 二级指针6. 指针数组7. 指针数组模拟二维数组8. 字符指针变量9. 数组指针变量2.1数组指针变量是什么?2.2 数组指针变量怎么初始化 10. 二维…...

HTTP协议详解
HTTP协议详解 一、HTTP协议概述二、网络基础与HTTP2.1 TCP/IP协议2.2 发送HTTP请求过程2.3 HTTP请求的组成部分 三、HTTP报文HTTP请求报文HTTP响应报文 结语 一、HTTP协议概述 HTTP,即超文本传输协议(Hypertext Transfer Protocol)ÿ…...

一年时间业绩增长2倍,茅台保健酒业公司在川销售的“三板斧”
执笔 | 尼 奥 编辑 | 扬 灵 作为土地面积全国第5、人口总数全国第3、GDP全国第6的产酒、销酒大省,四川酒类消费总额已达800亿元,其中白酒市场规模达到500亿元。 近年来,随着省外名酒提升对四川市场重视,其市场份额也从20年前的3%…...

土豆炒肉做法
菜单:土豆、葱、铁辣子、纯瘦肉、淀粉、生抽、酱油、刀、案板、十三香、盐巴、擦板 流程: 洗土豆,削皮,擦成条,用凉水过滤两遍淀粉,顺便放个燥里洗肉,切成条,按照生抽、酱油、淀粉、…...

VPS拨号服务器:独享的高效与安全
在当今互联网高速发展的时代,虚拟私人服务器(VPS)已成为许多企业和个人用户托管网站、应用程序的首选。特别是带有拨号功能的VPS服务器,以其独特的优势受到广泛关注。本文将深入探讨VPS拨号服务器的独享特性,以及它如何…...