深入了解响应式React Native Echarts组件


Posted in Javascript onMay 29, 2019

前言

一种在 React Native 中封装的响应式 Echarts 组件,使用与示例请参见:react-native-echarts-demo

近年来,随着移动端对数据可视化的要求越来越高,类似 MPAndroidChart 这样的传统图表库已经不能满足产品经理日益变态的需求。前端领域数据可视化的发展相对繁荣一些,通过 WebView 在移动端使用 Echarts 这样功能强大的前端数据可视化库,是解决问题的好办法。

React Native 开发中,由于使用的是与前端相同的 JavaScript 语言,衔接 Echarts 的工作相对顺畅些,不过一些必要的组件封装还是能够大大提高开发效率的。

Echarts 官方推荐过一个第三方封装库:react-native-echarts(注:它对应的 nmp package 名字为native-echarts ),目前有 400+ stars 和 100+ 的周下载量,可见还是被广泛使用的。但是我们经过调研,发现 react-native-echarts 存在以下一些问题:

  • 该库已半年多未更新,Echarts 版本停留在 3.0 ,Android 端打包需手动添加 assets 的问题也一直未处理
  • 库的接口灵活度较低,比如只能通过 width、height 设置大小;无法使用 Echarts 扩展包;无法进行事件注册、WebView 通信等

由于用WebView 封装 Echarts 涉及到本地 html,不是纯 JavaScript 语言层面的功能,又没有 native 代码,所以做成 nmp package 并不是一个很好的选择,写成项目里的内部组件,自己进行配置反而是更方便更灵活的方案。

因此我们决定不使用第三方的 Echarts 封装库,自己写一个通用组件 WebChart 。为方便开发中使用,该组件具有以下特点:

  • 按照响应式进行设计,只需在 option 中配置好数据源,数据变化后图表就会自动刷新,更符合 React 的风格。
  • 我们的方案是在组件每次 update 时判断传入的 option 参数是否发生变化,如果变化通过 webView.postMessage ,以 JSON 的形式传入新的 option ,通知 Echarts 重新 setOption 。
  • 虽然 Echarts 本身会对 option 进行对比,但事先判断可以减少 update 导致的与 WebView 频繁通信,这一点在容器父组件中有大量异步请求时还是很明显的;在 WebView 内部,更新则是采用 Echarts 本身的 setOption 而无需 reload 整个 WebView
  • 利用 WebView 的 postMessage 和 onMessage 接口,可实现图表与其它 React Native 组件的事件通信
  • 通过组件的 exScript 参数,可为 WebView 添加任意脚本,使用灵活
  • 由于是自己写的组件, echarts 版本、扩展包,svg/canvas 、数据增量加载都可以自己设定

Demo 与使用方法

使用与示例请参见:react-native-echarts-demo,如果你需要直接使用,可按以下步骤移植:

将根目录下的 WebChart 组件文件夹拷到你项目中合适的地方
将 /android/app/src/main/assets/web 文件夹拷到你项目同样位置,没有 assets 文件夹需手动创建。
只需以上两步就可以在项目中使用 WebChart 组件了。

如果需要进一步定制的话,Echarts 代码在以上两个文件夹中的 index.html 里 <script /> 标签内,目前是放的是 4.0 完整版,无扩展包,可到官网下载所需的版本和扩展包替换;svg/canvas 、数据增量加载等可在 WebChart/index.js 中直接进行修改。在移动端,出于性能的考虑,我们一般使用 svg 的渲染模式。

WebChart 具体使用可参见 App.js ,style 的设置就和普通的 React Native 组件一样,可使用 flex ,也可设为定值。额外的三个参数:

  • option(object):赋给 setOption 的参数对象,发生变化后 WebChart 内部会自动调用 setOption ,实现响应式刷新。特别注意,JSON 解析时未进行函数的处理,所以需避免使用函数式的 formatter 和类形式的 LinearGradient ,和 demo 一样使用模板式和普通对象的吧
  • exScript(string):任何你想在 WebView 加载时执行的代码,一般会是事件注册之类的,推荐使用模板字面量
  • onMessage(function):WebView 内部触发 postMessage 之后的回调,postMessage 需先在 exScript 中进行设置,用于图表与其它 React Native 组件的通信

当然这是根据我们的业务需要设计的参数,你完全可以自由重新设定。

Echarts与React Native组件的通信

在 React Native 的 WebView 组件中,提供了 onMessage 和 postMessage 来进行 html 与组件的双向通信,具体使用可参加文档。

利用 webView.postMessage ,WebChart 实现了通知 Echarts 执行 setOption ;在 exScript 中,可利用 window.postMessage 实现 Echarts 的事件向 React Native 组件的通信。

一般我们会约定通信的 data 为这样格式的对象:

{
type: 'someType',
payload: {
value: 111,
},
}

由于 onMessage 和 postMessage 只能进行字符串的传递,在 exScript 需进行 JSON 序列化,类似这样:

exScript={`
chart.on('click', (params) => {
if(params.componentType === 'series') {
window.postMessage(JSON.stringify({
type: 'select',
payload: {
index: params.dataIndex,
},
}));
}
});
`}

以上就是我们封装的响应式 WebChart 组件及使用,完整代码请参见:react-native-echarts-demo。

在使用中,还有以下几个坑未解决,目前只能绕过,欢迎知道的同学指正:

  • 在 IOS 中,Echarts 好像渲染不出透明的效果,用 rgba 设置的颜色不能正常
  • React Native 的 WebView 好像 style.height 属性无效,因此不得不在外面套了个 View
  • 按现在的资源加载方式,index.html 在 Android 上会有两份。因为平台判断是运行时进行的,哪怕分开设置 index.anroid.js 和 index.ios.js 打包时也会都打包进去,而 Android 中又必须手动添加 assets
  • index.html 中必须内联引入 Echarts 的代码,外部引用单独的 js 文件好像无效

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
超越Jquery_01_isPlainObject分析与重构
Oct 20 Javascript
js中有关IE版本检测
Jan 04 Javascript
js 绑定键盘鼠标事件示例代码
Feb 12 Javascript
利用jQuery和CSS将背景图片拉伸
Oct 16 Javascript
jQuery实现图片文字淡入淡出效果
Dec 21 Javascript
深入解析AngularJS框架中$scope的作用与生命周期
Mar 05 Javascript
AngularJS上拉加载问题解决方法
May 23 Javascript
JS基于递归算法实现1,2,3,4,5,6,7,8,9倒序放入数组中的方法
Jan 03 Javascript
jQuery图片缩放插件smartZoom使用实例详解
Aug 25 jQuery
VUE2.0+Element-UI+Echarts封装的组件实例
Mar 02 Javascript
Node.js利用console输出日志文件的方法示例
Apr 27 Javascript
vue插槽slot的简单理解与用法实例分析
Mar 14 Javascript
node将geojson转shp返回给前端的实现方法
May 29 #Javascript
node学习笔记之读写文件与开启第一个web服务器操作示例
May 29 #Javascript
关于element-ui的隐藏组件el-scrollbar的使用
May 29 #Javascript
JS学习笔记之数组去重实现方法小结
May 29 #Javascript
基于Vue实现电商SKU组合算法问题
May 29 #Javascript
JS学习笔记之闭包小案例分析
May 29 #Javascript
JS学习笔记之贪吃蛇小游戏demo实例详解
May 29 #Javascript
You might like
用session做客户验证时的注意事项
2006/10/09 PHP
ThinkPHP有变量的where条件分页实例
2014/11/03 PHP
隐性调用php程序的方法
2015/06/13 PHP
php实现将二维关联数组转换成字符串的方法详解
2017/07/31 PHP
php数值计算num类简单操作示例
2020/05/15 PHP
defer属性导致引用JQuery的页面报“浏览器无法打开网站xxx,操作被中止”错误的解决方法
2010/04/27 Javascript
node.js中的path.normalize方法使用说明
2014/12/08 Javascript
javascript+canvas制作九宫格小程序
2014/12/28 Javascript
AngularJs学习第八篇 过滤器filter创建
2016/06/08 Javascript
JS阻止事件冒泡行为和闭包的方法
2016/06/16 Javascript
基于Vuejs实现购物车功能
2016/08/02 Javascript
Bootstrap的fileinput插件实现多文件上传的方法
2016/09/05 Javascript
微信小程序 下拉菜单简单实例
2017/04/13 Javascript
JavaScript定义函数的三种实现方法
2017/09/23 Javascript
封装微信小程序http拦截器过程解析
2019/08/13 Javascript
js面试题之异步问题的深入理解
2020/09/20 Javascript
[00:23]DOTA2群星共贺开放测试 25日无码时代来袭
2013/09/23 DOTA
[06:33]DOTA2亚洲邀请赛小组赛第二日 TOP10精彩集锦
2015/01/31 DOTA
Python异常处理总结
2014/08/15 Python
Python使用googletrans报错的解决方法
2018/09/25 Python
python使用pygame框架实现推箱子游戏
2018/11/20 Python
在python中使用xlrd获取合并单元格的方法
2018/12/26 Python
详解Python的数据库操作(pymysql)
2019/04/04 Python
python opencv 图像拼接的实现方法
2019/06/27 Python
python3 selenium自动化测试 强大的CSS定位方法
2019/08/23 Python
Virtualenv 搭建 Py项目运行环境的教程详解
2020/06/22 Python
HTML5中div、article、section的区别及使用介绍
2013/08/14 HTML / CSS
西班牙购买行李箱和背包网站:Maletas Greenwich
2019/10/08 全球购物
美国电子产品购物网站:BuyDig.com
2020/06/17 全球购物
环保建议书作文
2014/03/12 职场文书
新闻编辑求职信
2014/07/13 职场文书
个人求职自荐信范文
2015/03/06 职场文书
研究生导师推荐信
2015/03/25 职场文书
教师纪律作风整顿心得体会
2016/01/23 职场文书
2019年最新七夕唯美祝福语(60条)
2019/07/22 职场文书
Java常用工具类汇总 附示例代码
2021/06/26 Java/Android