赞
踩
HarmonyOS Next 系列之省市区弹窗选择器实现(一)
HarmonyOS Next 系列之验证码输入组件实现(二)
HarmonyOS Next 系列之底部标签栏TabBar实现(三)
HarmonyOS Next 系列之HTTP请求封装和Token持久化存储(四)
HarmonyOS Next 系列之从手机选择图片或拍照上传功能实现(五)
HarmonyOS Next 系列之可移动悬浮按钮实现(六)
HarmonyOS Next 系列之沉浸式状态实现的多种方式(七)
HarmonyOS Next系列之Echarts图表组件(折线图、柱状图、饼图等)实现(八)
HarmonyOS Next(基于API11)实现Echarts图表组件(折线图、柱状图、饼图等)。
Echarts作为web端最流行开源的图表库,有着
多种图表类型,丰富的配置、强大的交互功能、可扩展性强等优点,如果能在鸿蒙上使用对于熟悉web开发同学将无缝衔接,大大减少开发和学习成本。
echarts作为JavaScript实现的开源可视化库只能通过网页形式渲染,所以可以 通过web组件内嵌本地网页形式混合开发。web和应用交互则通过WebviewController.runJavaScript(code)形式往网页注入执行代码。
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方法,后续通过调用该方法传入配置就能渲染出图表
封装一个全局通用的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里面定义了一些常见的图表配置数据结构(类型),方便在引入页中引入使用,可以按需继添加扩展
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。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。