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

news2025/2/28 12:27:53

系列文章目录

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.coloradmin.cn/o/1888852.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【List】判断集合相等、集合拷贝

【List】判断集合相等、集合拷贝 【一】判断集合是否相等【1】☆使用list中的containAll【2】使用for循环遍历contains方法【3】将list先排序再转为String进行比较【4】使用list.retainAll()方法【5】使用MD5加密方式【6】转换为Java8中的新特性steam流再进行排序来进行比较 【…

2024 MWC上海:创新力量驱动未来先行,移远智慧点亮数字蓝海

6月26日&#xff0c;2024年世界移动通信大会&#xff08;MWC上海&#xff09;如期举行&#xff0c;今年的展会以“未来先行”为主题&#xff0c;涵盖“超越 5G、数智制造和人工智能经济”三大技术主题。移远通信作为全球物联网行业的引领者之一&#xff0c;今年不仅在展示内容上…

快速上手文心一言指令:解锁AI对话新纪元

快速上手文心一言指令 一、引言&#xff1a;文心一言的魅力所在二、准备工作&#xff1a;了解文心一言平台2.1 轻松注册&#xff0c;开启智能对话之旅2.2 深度探索&#xff0c;掌握界面布局奥秘2.2.1 输入框&#xff1a;智慧交流的起点2.2.2 回复区&#xff1a;即时反馈的窗口2…

初识Java(复习版)

一. 什么是Java Java是一种面向对象的编程语言&#xff0c;和C语言有所不同&#xff0c;C语言是一门面向过程的语言。偏底层实现&#xff0c;比较注重底层的逻辑实现。不能一味的说某一种语言特别好&#xff0c;每一种语言都是在特定的情况下有自己的优势。 二.Java语言发展史…

反射--通俗易懂

一、反射(Reflection) 反射就是:加载类&#xff0c;并允许以编程的方式解剖类中的各种成分(成员变量、方法、构造器等) 动态语言&#xff0c;是一类在运行时可以改变其结构的语言&#xff1a;例如新的函数、对象、甚至代码可以被引进&#xff0c;已有的函数可以被删除或是其他…

9.(vue3.x+vite)修改el-input,el-data-picker样式

效果预览 二:相关代码 <template><div style="padding: 50px"><el-input placeholder="请输入模型名称" style="width: 260px" /><br /

OpenELM:开启开放训练和推理框架的高效语言模型家族

随着大模型模型规模的增长&#xff0c;这些强大工具的透明度、可复现性和对数据偏见的敏感性也引起了人们的关注。这些问题不仅关系到研究的开放性和公平性&#xff0c;也关系到模型输出的可信度和安全性。为了应对这些挑战&#xff0c;Apple的研究团队发布了名为OpenELM的新一…

Real-Time 3D Graphics with WebGL2

WebGL渲染管线 下图是WebGL渲染管线的示意图: Vertex Buffer Objects (VBOs) VBOS中包含了用于描述几何体的信息。如&#xff0c;几何体的顶点坐标&#xff0c;法线坐标&#xff0c;颜色&#xff0c;纹理坐标等。 Index Buffer Objects (IBOs) IBOs中包含了描述顶点关系的信…

【Python机器学习】模型评估与改进——二分类指标

目录 1、错误类型 2、不平衡数据集 3、混淆矩阵 与精度的关系。 准确率、召回率与f-分数 分类报告 4、考虑不确定性 5、准确率-召回率曲线 6、受试者工作特征&#xff08;ROC&#xff09;与AUC 二分类可能是实践中最常见的机器学习应用&#xff0c;也是概念最简单的应…

Python | Leetcode Python题解之第206题反转链表

题目&#xff1a; 题解&#xff1a; # Definition for singly-linked list. # class ListNode: # def __init__(self, val0, nextNone): # self.val val # self.next next class Solution:def reverseList(self, head: Optional[ListNode]) -> Optio…

开源之夏|祝贺MatrixOne开源社区项目中选同学!

在本届「开源之夏 2024」活动中&#xff0c;MatrixOne开源社区共计上线3个项目任务&#xff0c;最终有 3位同学成功突围。接下来让我们看看每个项目的详细中选情况&#xff1a; 中选学生公示 项目名称&#xff1a;基于大语言模型的操作系统任务自动识别&#xff0c;拆解&#…

Seal^_^【送书活动第8期】——《ChatGLM3大模型本地化部署、应用开发与微调》

Seal^_^【送书活动第8期】——《ChatGLM3大模型本地化部署、应用开发与微调》 一、参与方式二、本期推荐图书2.1 作者建语2.2 编辑推建2.3 图书简介2.4 前 言2.5 目 录 三、正版购买 大模型领域 既是繁星点点的未知宇宙&#xff0c;也是蕴含无数可能的广阔天地&#xff0c; 正…

【Linux】—Hadoop运行环境搭建(完全分布式)

文章目录 前言一、模板虚拟机环境准备二、克隆虚拟机&#xff08;以hadoop102为例&#xff09;三、修改克隆机的IP四、安装JDK五、安装Hadoop&#xff08;完全分布式&#xff09;六、集群常用命令七、配置集群八、群起并测试集群九、配置历史服务器十、配置日志的聚集十一、集群…

华为DCN之:SDN和NFV

1. SDN概述 1.1 SDN的起源 SDN&#xff08;Software Defined Network&#xff09;即软件定义网络。是由斯坦福大学Clean Slate研究组提出的一种新型网络创新架构。其核心理念通过将网络设备控制平面与数据平面分离&#xff0c;从而实现了网络控制平面的集中控制&#xff0c;为…

电脑配置怎么看?3个方法轻松get,这些指标一看便知

无论是购买新电脑、升级现有配置&#xff0c;还是解决电脑运行问题&#xff0c;了解电脑的配置信息都显得尤为重要。那么&#xff0c;电脑配置怎么看&#xff1f;本文将为你介绍3个简单易行的方法&#xff0c;让你轻松获取电脑配置的关键指标&#xff0c;帮助你更好地了解和管理…

3.(vue3.x+vite)el-tree组件(数组结构数据转树结构数据)

1:效果预览 2:编写代码 (1)主页面 <template><el-tree ref="componentInfoTreeRef" :data="treeData

AOP基本概念

AOP&#xff08;Aspect-Oriented Programming&#xff0c;面向切面编程&#xff09;是一种编程范式&#xff0c;用于将横切关注点&#xff08;如日志记录、安全检查、事务管理等&#xff09;从业务逻辑中分离出来&#xff0c;以提高代码的模块化程度和可维护性。以下是AOP的核心…

参数污染漏洞(HPP)挖掘技巧及实战案例全汇总

目录 概念: 漏洞原理: 实战案例总结: 1. 逻辑漏洞(IDOR) 2. 绕过检测(WAF) 挖掘技巧: 修复方案: 概念: HTTP参数污染,也叫HPP(HTTP Parameter Pollution)。简单地讲就是给一个参数赋上两个或两个以上的值,由于现行的HTTP标准没有提及在遇到多个输入值给相…

2.2.3 C#中显示控件BDPictureBox 的实现----控件实现

2.2.3 C#中显示控件BDPictureBox 的实现----控件实现 1 界面控件布局 2图片内存Mat类说明 原始图片&#xff1a;m_raw_mat ,Display_Mat()调用时更新或者InitDisplay_Mat时更新局部放大显示图片&#xff1a;m_extract_zoom_mat&#xff0c;更新scale和scroll信息后更新overla…

第四届数字安全大会:AI时代数据安全策略与天空卫士创新实践

2024年6月22日&#xff0c;以 “新质•真能力”为主题的第四届数字安全大会在北京隆重召开。这场由数世咨询和CIO时代联合主办的行业盛会&#xff0c;集中探讨了大模型、数据治理与流通、以及安全运营等当前最前沿的议题。大会吸引了来自不同行业的首席信息官&#xff08;CIO&a…