#HarmonyOS NEXT体验官#(基于Echarts)开发一个OpenHarmony三方库 原创
前言
我自己之前想做一期关于chart 图表功能演示,我找了一圈下来 大致有 官方的@ohos/mpchart 但是使用习惯不是特别喜欢,因为自己以前经常用百度Echarts,虽然他的体积这些比较大,但是功能是真的非常强大,所以思索良久下定决心来基于Echarts封装一个自己的OpenHarmony三方库
准备工作
- 安装好最新DevEco Studio 开发工具,创建一个新的空项目。
- 在 OpenHarmony三方库中心仓 注册账号。
- 在百度Echarts官网定制化下载需要的组件,注意不要勾选代码压缩选项,方便我们后面调试。
创建引入Static Library
模块
1.创建 Static Library
模块。
这里需要注意是要鼠标移动到项目名称目录上,然后右键 创建新模块,然后选 Static Library
静态模块,模块名称命名自己可以随意,我这里用的是hm_chart。
创建好模块之后的目录结构大致是这样的。
2.在我们项目中引入 Static Library
模块。
- 在项目
oh-package.json5
dependencies 中加载Static Library
模块文件,这里需要注意我们加了一个前缀@wuyan/
这里可以加也不可以加,但是如果加了的化要记住名称,我们后面有用到。
{
"name": "entry",
"version": "1.0.0",
"description": "Please describe the basic information.",
"main": "",
"author": "",
"license": "",
"dependencies": {
"@wuyan/hm_chart": "file:../hm_chart"
}
}
- 打开终端 执行
ohpm install
命令。
- 在项目首页
src/main/ets/pages/Index.ets
文件中删掉之前没有用的代码引入模块。
import {MainPage} from "@wuyan/hm_chart"
@Entry
@Component
struct Index {
build() {
RelativeContainer() {
MainPage();
}
.height('100%')
.width('100%')
}
}
打开右侧预览器 就可以看到如下页面。
封装Echarts 插件
1.将从Echarts 官网定制化界面下载好的 echarts.js文件放入到 hm_chart
模块中 /src/main/ets/components
目录下面
2.新建 InitCharts.js
文件 放在和 echarts.js 同目录下面。
import * as echarts from './echarts';
export class InitCharts{
constructor(ctx) {
this.myChart = echarts.init(ctx); //初始化
}
// 绘制图表
setOption(option){
this.myChart.setOption(option)
}
}
3.修改 MainPage.ets
文件绘制 canvas 并new InitCharts 初始化 eCharts。
import {InitCharts} from "./InitCharts"
@Component
export struct MainPage {
private settings: RenderingContextSettings = new RenderingContextSettings(true)
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
build() {
Column() {
Canvas(this.context)
.width('100%')
.height('100%')
.onReady(() => {
const myChart = new InitCharts(this.context)
})
}
}
}
让我们点击预览看看效果如何。好吧不出意外的报错了。
4.打开 echarts.js
文件 全局搜索 this.dom.getContext('2d')
找到这行代码 去掉this.dom
后面的.getContext('2d')
再试试预览效果,没报错了,离成功就很近了。
5.让我们来试一试 setOption
方法,官网上随便找了一段 option 配置,修改MainPage.ets
文件 加入 setOption
方法。
import {InitCharts} from "./InitCharts"
@Component
export struct MainPage {
private settings: RenderingContextSettings = new RenderingContextSettings(true)
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
build() {
Column() {
Canvas(this.context)
.width('100%')
.height('100%')
.onReady(() => {
const myChart = new InitCharts(this.context) //初始化
// 渲染图表
myChart.setOption({
title: {
text: 'Stacked Line'
},
tooltip: {
trigger: 'axis'
},
legend: {
data: ['Email', 'Union Ads', 'Video Ads', 'Direct', 'Search Engine']
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [
{
name: 'Email',
type: 'line',
stack: 'Total',
data: [120, 132, 101, 134, 90, 230, 210]
},
{
name: 'Union Ads',
type: 'line',
stack: 'Total',
data: [220, 182, 191, 234, 290, 330, 310]
},
{
name: 'Video Ads',
type: 'line',
stack: 'Total',
data: [150, 232, 201, 154, 190, 330, 410]
},
{
name: 'Direct',
type: 'line',
stack: 'Total',
data: [320, 332, 301, 334, 390, 330, 320]
},
{
name: 'Search Engine',
type: 'line',
stack: 'Total',
data: [820, 932, 901, 934, 1290, 1330, 1320]
}
]
})
})
}
}
}
非常完美,图表加载成功!
让我来点下看看,额… tooltip
legend
的事件都相应丢失了,看看源码是怎么个回事呢? 原来是Echarts 底层用的 addEventListener
监听的事件,但是 HarmonyOS NEXT
是没有这个方法的。
网上找资料肯定是找不到了,看看Echarts官网有没有解决方案,终于我看到了 跨平台方案 里面有个微信适配,因为其实微信也是没有相关dom 的 addEventListener 事件的。从官网echarts-for-weixin链接点过去找到了wx-canvas.js 果然有适配方案。
6.参照官网的思路,改造一下我们的 InitCharts.js
和 MainPage.ets
InitCharts.js
代码如下 添加了 onTouchEvent
绑定事件
import * as echarts from './echarts';
export class InitCharts{
constructor(ctx) {
this.myChart = echarts.init(ctx); //初始化
}
// 绘制图表
setOption(option){
this.myChart.setOption(option)
}
// 注册触摸事件
onTouchEvent(event){
const eventNames = [{
type: '0',
ecName: 'mousedown' //鼠标按下
}, {
type: '2',
ecName: 'mousemove' //鼠标移动
}, {
type: '1',
ecName: 'mouseup' // 鼠标离开
}, {
type: '1',
ecName: 'click'
}];
eventNames.forEach(item => {
if(event.type==item.type){
const touch = event.touches[0];
this.myChart.getZr().handler.dispatch(item.ecName, {
zrX: touch.x,
zrY: touch.y,
preventDefault: () => {},
stopImmediatePropagation: () => {},
stopPropagation: () => {}
});
}
});
}
}
MainPage.ets
代码如下 添加了 onTouch
事件
import {InitCharts} from "./InitCharts"
@Component
export struct MainPage {
private settings: RenderingContextSettings = new RenderingContextSettings(true)
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
private myChart:InitCharts|null = null
build() {
Column() {
Canvas(this.context)
.width('100%')
.height('100%')
.onReady(() => {
this.myChart = new InitCharts(this.context)
this.myChart.setOption({
title: {
text: 'Stacked Line'
},
tooltip: {
trigger: 'axis'
},
legend: {
data: ['Email', 'Union Ads', 'Video Ads', 'Direct', 'Search Engine']
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [
{
name: 'Email',
type: 'line',
stack: 'Total',
data: [120, 132, 101, 134, 90, 230, 210]
},
{
name: 'Union Ads',
type: 'line',
stack: 'Total',
data: [220, 182, 191, 234, 290, 330, 310]
},
{
name: 'Video Ads',
type: 'line',
stack: 'Total',
data: [150, 232, 201, 154, 190, 330, 410]
},
{
name: 'Direct',
type: 'line',
stack: 'Total',
data: [320, 332, 301, 334, 390, 330, 320]
},
{
name: 'Search Engine',
type: 'line',
stack: 'Total',
data: [820, 932, 901, 934, 1290, 1330, 1320]
}
]
})
})
.onTouch((event: TouchEvent)=>{
if(this.myChart){
this.myChart.onTouchEvent(event)
}
})
}
}
}
看看效果 legend
事件生效了, 但是 tooltip
还是没有反应。
经过分析发现是 echarts.js
源码中 Env
环境判断错误 导致识别成 node 服务器环境了。
7.打开 echarts.js
源码 搜索 new Env()
注释掉 env.node = true; env.svgSupported = true;
搜索 addEventListener
注释掉 el.addEventListener(name, handler, opt);el.removeEventListener(name, handler, opt);
最后再预览一下 看看效果。
打包发布插件
-
- 因为本文用到了插件前缀
@wuyan
,如果你也有想要有前缀,那需要去OpenHarmony三方库中心仓 组织管理中添加组织,我这里添加的是wuyan
。
- 因为本文用到了插件前缀
-
- 配置
oh-package.json5
内容,具体配置可以参考官网模块级oh-package.json5字段说明
我的oh-package.json5
配置如下
- 配置
{
"name": "@wuyan/hm_chart",
"version": "1.0.0",
"keywords":["chart","echarts","hm_chart"],
"description": "一个基于echarts 进行二次封装的插件,基本上完全支持echarts 的所有功能。",
"main": "Index.ets",
"author": "wuyan",
"license": "Apache-2.0",
ohos: {
org: 'wuyan',
},
"dependencies": {}
}
- 打开命令生成OHPM 公钥
说明 官方是 ~/.ssh_ohpm/mykey
我觉得反而不好理解,我这里直接用mykey
就是私钥的名称。
需要注意的是必须输入密码,这样在后续发布HAR包的时候有用到。
ssh-keygen -m PEM -t RSA -b 4096 -f mykey
执行成功后
- 将公钥文件(mykey.pub)添加至OpenHarmony三方库中心仓【认证管理】中。
- 将私钥文件路径配置到 .ohpmrc 文件中 key_path 字段上
需要注意的是用系统自带的窗口执行可能会报错 ohpm 无法识别
,所以推荐直接用我们开发工具的终端执行命令,后续发布HAR 包也是一样。
ohpm config set key_path E:\work\test\MyApplication\mykey
- 配置登录用户发布码,需要把
your-publishId
替换成你自己的发布码,位置在OpenHarmony三方库中心仓【个人中心】页面左边个人信息下,直接点复制发布码
即可拿到。
ohpm config set publish_id your-publishId
- 在我们之前创建的静态模块跟目录下创建 README.md
(描述信息)
,CHANGELOG.md(更新日志)
和 LICENSE(开源协议license)
四个文件,若文件缺失,内容缺少,内容必须真实,会导致上架至中心仓失败(有人工审核)
。
- 对开发后的库模块打成 HAR 包、发布HAR包。
打包
发布包<HAR路径>
等于你包文件的实际路径 我这里是E:\work\test\MyApplication\hm_chart\build\default\outputs\default\hm_chart.har
自己要根据自己实际项目情况修改。
ohpm publish <HAR路径>
详细教程可以参考官网帮助文档 里面介绍非常详细 认证管理 和贡献三方库
总结
本篇文章详细介绍了如何创建一个 OpenHarmony三方库
, 以及如何对Echarts 进行封装,在封装过程中出现的错误,进行思考调整,希望对你们后面创建自己的 OpenHarmony三方库
有所帮助,如果有问题欢迎评论区见。
最后我把代码进行整理并开源放在了gitee 上,有需要的可以下载下来研究研究。
创作不易,觉得本篇文章不错的留下一个赞呗。
问题更新
经过掘友@lwlizhe
提醒在模拟器上会报错global is not defined
,我的处理方案是在var root =
这行代码前面加上global定义var global={}
即可解决问题。