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|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<string>
  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%')
  }
}

运行效果:

在这里插入图片描述


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

对于配置项包含函数的情况,例如坐标轴标签设置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%')
  }
}

运行效果:
在这里插入图片描述


总结

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/766667.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

KEYSIGHT N1092系列,DCA-M系列采样示波器连接与自检?

KEYSIGHT N1092系列 采样示波器&#xff0c;虽然省去了屏幕和操作系统&#xff0c;但根据不同的型号&#xff0c;可以配备不同数量的光口和电口&#xff0c;满足各种测试需求。本次介绍的具体型号为N1092D&#xff0c;它拥有4个光口&#xff0c;能够进行多种测试。 测试步骤详解…

UG NX二次开发(C++)-根据草图创建拉伸特征(UFun+NXOpen)

1、前言 UG NX是基于特征的三维建模软件,其中拉伸特征是一个很重要的特征,有读者问如何根据草图创建拉伸特征,我在这篇博客中讲述一下草图创建拉伸特征的UG NX二次开发方法,感兴趣的可以加入QQ群:749492565,或者在评论区留言。 2、在UG NX中创建草图,然后创建拉伸特征 …

OpenStack开源虚拟化平台(二)

目录 三、对象存储服务Swift&#xff08;一&#xff09;Swift特性&#xff08;二&#xff09;应用场景&#xff08;三&#xff09;Swift主要组件&#xff08;四&#xff09;Swift基本原理&#xff08;五&#xff09;实例分析 四、镜像服务Glance&#xff08;一&#xff09;Glan…

PostgreSQL的pg_filedump工具

PostgreSQL的pg_filedump工具 基础信息 OS版本&#xff1a;Red Hat Enterprise Linux Server release 7.9 (Maipo) DB版本&#xff1a;16.2 pg软件目录&#xff1a;/home/pg16/soft pg数据目录&#xff1a;/home/pg16/data 端口&#xff1a;5777pg_filedump 是一个工具&#x…

ubuntu运行qq音乐闪退

ubuntu运行qq音乐闪退 修改/usr/share/applications中的qqmusic.desktop&#xff0c;在Exec后加上 --no-sandbox,如下图所示&#xff1a; 该文件有可能是只读&#xff0c;权限不够的话用sudo vim qqmusic.desktop

PyCharm远程开发

PyCharm远程开发 1- 远程环境说明 每个人的本地电脑环境差别很大。各自在自己电脑上开发功能&#xff0c;测试/运行正常。但是将多个人的代码功能合并&#xff0c;运行服务器上&#xff0c;会出现各种版本兼容性问题。 在实际企业中&#xff0c;一般会有两套环境。第一套是测…

离子液体(ILs)在电化学领域应用前景广阔 海外企业占据全球市场主导地位

离子液体&#xff08;ILs&#xff09;在电化学领域应用前景广阔 海外企业占据全球市场主导地位 离子液体&#xff08;ILs&#xff09;又称离子性液体&#xff0c;指在室温或接近室温条件下&#xff0c;完全由阴阳离子组成的液态盐。与传统有机溶剂相比&#xff0c;离子液体具有…

短视频电商源码的优势及软件架构解析

短视频电商源码是目前电商行业中非常火热的一个新兴领域&#xff0c;它通过短视频内容和电商商品的结合&#xff0c;为用户提供了一种新的购物体验。下面将介绍短视频电商源码的优势以及软件架构。 首先&#xff0c;短视频电商源码具有以下几个优势&#xff1a; 1、创新的购物体…

观众为何偏爱采用多媒体互动技术的博物馆展览?

昔日踏入博物馆&#xff0c;映入眼帘的尽是静谧的展柜与沉默不语的展品&#xff0c;它们静静地诉说着过往的故事&#xff0c;却与参观者之间隔着一道无形的墙。但如今&#xff0c;想象力跨越了界限&#xff0c;多媒体互动技术如同魔法般降临&#xff0c;赋予这些历史遗珍以新的…

进程以及多线程编程

文章目录 什么是进程/任务&#xff08;Process/Task&#xff09;进程控制块抽象(PCB Process Control Block)PID(进程的 id /标识符)内存指针文件描述符表状态优先级上下文记账信息 线程(Thread)进程和线程的区别线程的优点: 多线程代码代码示例(继承Thread类的方式)sleep(休眠…

k8s部署单机版xxl-job

一、初始化数据库 https://github.com/xuxueli/xxl-job/blob/2.3.1/doc/db/tables_xxl_job.sql # # XXL-JOB v2.3.1 # Copyright (c) 2015-present, xuxueli.CREATE database if NOT EXISTS xxl_job default character set utf8mb4 collate utf8mb4_unicode_ci; use xxl_job;…

数据库安全:MySQL权限体系划分与实战操作

「作者简介」&#xff1a;冬奥会网络安全中国代表队&#xff0c;CSDN Top100&#xff0c;就职奇安信多年&#xff0c;以实战工作为基础著作 《网络安全自学教程》&#xff0c;适合基础薄弱的同学系统化的学习网络安全&#xff0c;用最短的时间掌握最核心的技术。 这一章节我们需…

第7章 Redis的噩梦:阻塞

文章目录 前言1 发现阻塞2.内在原因2.1API或数据结构使用不合理2.1.1如何发现慢查询2.1.2.如何发现大对象 2.2 CPU饱和2.3 持久化阻塞2.3.1fork阻塞2.3.2.AOF刷盘阻塞2.3.3.HugePage写操作阻塞 3 外在原因3.1CPU竞争3.2 内存交换3.3网络问题3.3.1连接拒绝 前言 Redis是典型的单…

【Altium】AD-PCB界面抬头显示设置

【更多软件使用问题请点击亿道电子官方网站】 1、 文档目标 PCB设计界面中抬头显示设置的方法 2、 问题场景 PCB设计界面中左上角有一个抬头显示悬浮窗口&#xff0c;这个窗口可以显示坐标&#xff0c;选中PCB中某个对象后还能显示它的具体信息。有用户不喜欢这个窗口&#x…

漆包线行业生产管理革新:万界星空科技MES系统解决方案

一、引言 在科技日新月异的今天&#xff0c;万界星空科技凭借其在智能制造领域的深厚积累&#xff0c;为漆包线行业量身打造了一套先进的生产管理执行系统&#xff08;MES&#xff09;解决方案。随着市场竞争的加剧&#xff0c;漆包线作为电气设备的核心材料&#xff0c;其生产…

Android手机删除的照片怎么找回来?3个详细教程,有效恢复

在这个充满科技魅力的时代&#xff0c;手机它不仅是我们的通讯工具&#xff0c;更是我们的娱乐中心、信息库和摄影工作室。然而&#xff0c;有时候&#xff0c;我们在享受科技带来的便利的同时&#xff0c;也会遭遇一些小小的困扰。 比如&#xff0c;你可能会在一次手抖中删除…

AI需求强劲推动韩国六月芯片出口创历史新高

据路透社7月1日报道&#xff0c;韩国产业通商资源部最新数据显示&#xff0c;韩国出口连续第九个月增长&#xff0c;六月份海外对芯片的持续且增强的需求将芯片出口额推至历史高位。这一出口增长势头同时带动韩国制造业采购经理指数&#xff08;PMI&#xff09;攀升至两年多以来…

《Linux开发笔记》C语言编译

C语言编译过程 编译过程主要分为四步&#xff1a;预处理、编译、汇编、链接 预处理&#xff1a;主要用于查找头文件、展开宏 编译&#xff1a;把.i文件编译成.s文件 汇编&#xff1a;把.s文件汇编为.o文件 链接&#xff1a;把多个.o文件链接成一个app 以上四个步骤主要由3个命…

java 程序、进程 、线程,cpu,并行、并发、启动线程两种方式

1、重写 Thread 父类方法 后创建实例调用 start 方法 2、将创建自实现 Runable 接口后的实例 作为参数传递给 Thread 的构造方法 两个条件同时存在&#xff0c;那个生效&#xff1f; new Thread(/* condition 1 */threadTest2) {Override/* condition 2 */public void run() {T…

【计算机毕业设计】基于Springboot的大学生就业招聘系统【源码+lw+部署文档】

包含论文源码的压缩包较大&#xff0c;请私信或者加我的绿色小软件获取 免责声明&#xff1a;资料部分来源于合法的互联网渠道收集和整理&#xff0c;部分自己学习积累成果&#xff0c;供大家学习参考与交流。收取的费用仅用于收集和整理资料耗费时间的酬劳。 本人尊重原创作者…