HarmonyOS Next系列之Echarts图表组件(折线图、柱状图、饼图等)实现(八)

07-09 1208阅读

系列文章目录

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开发同学将无缝衔接,大大减少开发和学习成本。

        HarmonyOS Next系列之Echarts图表组件(折线图、柱状图、饼图等)实现(八)

        HarmonyOS Next系列之Echarts图表组件(折线图、柱状图、饼图等)实现(八)


        一、实现原理分析

        echarts作为JavaScript实现的开源可视化库只能通过网页形式渲染,所以可以 通过web组件内嵌本地网页形式混合开发。web和应用交互则通过WebviewController.runJavaScript(code)形式往网页注入执行代码。

        二、代码实现

        1.项目内新建本地html文件引入echarts.min.js

        resources/rawfile目录下新建echarts.html和添加echarts.min.js

        HarmonyOS Next系列之Echarts图表组件(折线图、柱状图、饼图等)实现(八)

        echarts.html:

        
        
            
            
            
            
                *{
             padding:0;
             margin:0
            }
            body,html{
               height:100%;
               width:100%
            }
            #container{
               height:100%;
               width:100%
            }
            
        
        
        
        const container = document.getElementById('container') let myChart = echarts.init(container); function setOption(option){ myChart?.clear(); myChart?.setOption(option) }

        echarts.min.js:

        可以从官网在线定制下载echart.js定制

        说明:此步骤新建了一个html文件引入了echarts.min.js并初始化echarts,定义了一个

        setOption方法,后续通过调用该方法传入配置就能渲染出图表

        2.Echart.ets组件封装

        HarmonyOS Next系列之Echarts图表组件(折线图、柱状图、饼图等)实现(八)

        封装一个全局通用的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) {
            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|string
          bottom?: number|string
          left?: number|string
          right?: number|string
        }
        export interface EChartsTitle {
          text?: string;
        }
        export interface EChartsTooltip {}
        export interface EChartsLegend {
          show?:boolean
          data?: string[];
        }
        export interface EChartsXAxis {
          type?: string;
          data: string[];
          axisLine?: XAxisAxisLine;
          axisTick?: XAxisAxisTick
          boundaryGap?: boolean | Array
          axisLabel?: AxisLabel
        }
        export interface XAxisAxisLine {
          show?: boolean
        }
        export interface XAxisAxisTick {
          show?: boolean
        }
        export interface EChartsYAxis {
          type?: string
          splitLine?: YAxisSplitLine
          splitNumber?: number
          min?: number
          max?: number
          scale?: boolean
          interval?: number
        }
        export interface AxisLabel {
          show?: boolean
          formatter?: 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%')
          }
        }
        

        运行效果:

        HarmonyOS Next系列之Echarts图表组件(折线图、柱状图、饼图等)实现(八)


        三、配置项含函数需特殊处理

        对于配置项包含函数的情况,例如坐标轴标签设置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 = e
                    this.setOption()
                  }
                })
            }
            .width('100%')
            .height('100%')
          }
        }
        

        运行效果:

        HarmonyOS Next系列之Echarts图表组件(折线图、柱状图、饼图等)实现(八)


        总结

        当然作为混合开发产物性能自然比上不上原生,但是echarts有着跨平台兼容性好等优点,对付数据量不大、交互要求不高的场景绰绰有余。目前处于起步发展阶段的鸿蒙来说还没有一款稳定成熟、配置丰富能满足各种ui设计要求的官方或三方组件库。所以只要你的开发场景对性能要求不高,web形式的echart也是个不错的选择,尤其能实现各种定制化ui。

VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]