系列文章目录HarmonyOS Next 系列之省市区弹窗选择器实现一HarmonyOS Next 系列之验证码输入组件实现二HarmonyOS Next 系列之底部标签栏TabBar实现三HarmonyOS Next 系列之HTTP请求封装和Token持久化存储四HarmonyOS Next 系列之从手机选择图片或拍照上传功能实现五HarmonyOS Next 系列之可移动悬浮按钮实现六HarmonyOS Next 系列之沉浸式状态实现的多种方式七HarmonyOS Next系列之Echarts图表组件折线图、柱状图、饼图等)实现八HarmonyOS Next系列之地图组件Map Kit使用九HarmonyOS Next系列之半圆环进度条实现十HarmonyOS Next 系列之列表下拉刷新和触底加载更多数据实现十一HarmonyOS Next系列之实现一个左右露出中间大两边小带缩放动画的轮播图十二HarmonyOS Next系列之水波纹动画特效实现十三HarmonyOS Next系列之华为账号一键登录功能实现十四系列文章目录2【鸿蒙】HarmonyOS NEXT开发快速入门教程之ArkTS语法装饰器上【鸿蒙】HarmonyOS NEXT开发快速入门教程之ArkTS语法装饰器下【鸿蒙】HarmonyOS NEXT应用开发快速入门教程之布局篇上【鸿蒙】HarmonyOS NEXT应用开发快速入门教程之布局篇下【鸿蒙】HarmonyOS Next 组件或页面之间的所有通信传参方法总结文章目录系列文章目录系列文章目录2前言一、实现原理分析二、代码实现1.项目内新建本地html文件引入echarts.min.js2.Echart.ets组件封装3.页面使用三、配置项含函数需特殊处理代码示例总结前言HarmonyOS Next基于API11实现Echarts图表组件折线图、柱状图、饼图等)。Echarts作为web端最流行开源的图表库有着多种图表类型丰富的配置、强大的交互功能、可扩展性强等优点如果能在鸿蒙上使用对于熟悉web开发同学将无缝衔接大大减少开发和学习成本。一、实现原理分析echarts作为JavaScript实现的开源可视化库只能通过网页形式渲染所以可以 通过web组件内嵌本地网页形式混合开发。web和应用交互则通过WebviewController.runJavaScript(code)形式往网页注入执行代码。二、代码实现1.项目内新建本地html文件引入echarts.min.jsresources/rawfile目录下新建echarts.html和添加echarts.min.jsecharts.html!DOCTYPEhtmlhtmlheadmeta charsetutf-8meta contentwidthdevice-width, initial-scale1.0, maximum-scale1.0, user-scalable0;nameviewport/script src./echarts.min.js/scriptstyle*{padding:0;margin:0}body,html{height:100%;width:100%}#container{height:100%;width:100%}/style/headbodydiv idcontainer/div/bodyscriptconstcontainerdocument.getElementById(container)letmyChartecharts.init(container);functionsetOption(option){myChart?.clear();myChart?.setOption(option)}/script/htmlecharts.min.js可以从官网在线定制下载echart.js定制说明此步骤新建了一个html文件引入了echarts.min.js并初始化echarts,定义了一个setOption方法后续通过调用该方法传入配置就能渲染出图表2.Echart.ets组件封装封装一个全局通用的echart组件目录结构如上图所示其中Echarts.ets为组件文件ViewModel.ets为图表相关配置数据类型定义Echarts.etsimportwebviewfromohos.web.webviewComponentexportdefaultstruct Echarts{//控制器controller:webview.WebviewControllernewwebview.WebviewController();//组件宽Prop eWidth:string|number100%//组件高单位vpProp eHeight:string|number300//渲染完成回调renderCallBack:(e:Echarts)void(){}//更新或渲染组件render(option:Recordstring,ESObject|string){this.controller.runJavaScript(setOption(${typeofoptionstring?option:JSON.stringify(option)}))}build(){Column(){Web({src:$rawfile(echarts.html),controller:this.controller}).width(100%).height(100%).onPageEnd(e{this.renderCallBackthis.renderCallBack(this)})}.width(this.eWidth).height(this.eHeight)}}说明组件定义了长宽属性默认宽度100%高度300vprenderCallBack回调函数作用把整个echarts组件实例暴露给引用页面。render方法重新加载渲染组件入参为图表配置入参既可以是对象也可以是字符串无论何种类型最终都将转换为字符串注入web执行。在引用页面通过renderCallBack暴露出去的实例调用render方法即可自由刷新图表数据ViewModel.ets:/** * echart配置数据类型定义 */exportinterfaceEChartsOption{grid?:EchartGrid,title?:EChartsTitle;tooltip?:EChartsTooltip;legend?:EChartsLegend;xAxis:EChartsXAxis;yAxis:EChartsYAxis;series:EChartsSeries[];}exportinterfaceEchartGrid{top?:number|string bottom?:number|string left?:number|string right?:number|string}exportinterfaceEChartsTitle{text?:string;}exportinterfaceEChartsTooltip{}exportinterfaceEChartsLegend{show?:boolean data?:string[];}exportinterfaceEChartsXAxis{type?:string;data:string[];axisLine?:XAxisAxisLine;axisTick?:XAxisAxisTick boundaryGap?:boolean|ArraystringaxisLabel?:AxisLabel}exportinterfaceXAxisAxisLine{show?:boolean}exportinterfaceXAxisAxisTick{show?:boolean}exportinterfaceEChartsYAxis{type?:string splitLine?:YAxisSplitLine splitNumber?:number min?:number max?:number scale?:boolean interval?:number}exportinterfaceAxisLabel{show?:boolean formatter?:string|((value:number|string,index:number)string)}exportinterfaceYAxisSplitLine{lineStyle?:AxisSplitLineLineStyle}exportinterfaceAxisSplitLineLineStyle{type?:string}exportinterfaceEChartsSeries{name?:string;type?:string;data:number[];}ViewModel.ets里面定义了一些常见的图表配置数据结构类型方便在引入页中引入使用可以按需继添加扩展3.页面使用Index.etsimportEchartsfrom../components/Echarts/Echartsimport{EChartsOption}from../components/Echarts/ViewModelEntry Component struct Index{//图表实例myEchart:Echarts|nullnull/* * 图表配置 */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.myEcharte//初次渲染组件接口获取数据是异步此时this.option可能还没有新数据this.myEchart.render(this.option)}})}.width(100%).height(100%)}}运行效果三、配置项含函数需特殊处理对于配置项包含函数的情况例如坐标轴标签设置AxisLabel.formatter字段可以是个函数类型此时就需要特殊处理。这是因为当我们传递option为对象给render函数时候this.controller.runJavaScript(setOption(${typeofoptionstring?option:JSON.stringify(option)}))此时调用JSON.stringify把对象转换为字符串而JSON.stringify入参内函数会直接被去掉。因此我们需要自己把option处理成字符串传入即可代码示例给折线图y轴刻度值加个万字Index.etsimportEchartsfrom../components/Echarts/EchartsEntry Component struct Index{//图表配置State option:string//x轴数据State xAxisData:string[][];//y轴数据State seriesData:number[][];myEchart:Echarts|nullnull;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.myEchartethis.setOption()}})}.width(100%).height(100%)}}运行效果总结当然作为混合开发产物性能自然比上不上原生但是echarts有着跨平台兼容性好等优点对付数据量不大、交互要求不高的场景绰绰有余。目前处于起步发展阶段的鸿蒙来说还没有一款稳定成熟、配置丰富能满足各种ui设计要求的官方或三方组件库。所以只要你的开发场景对性能要求不高web形式的echart也是个不错的选择尤其能实现各种定制化ui。