深入了解响应式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 相关文章推荐
fancybox1.3.1 基于Jquery的插件在IE中图片显示问题
Oct 01 Javascript
WEB前端设计师常用工具集锦
Dec 09 Javascript
jquery实现聚光灯效果的方法
Feb 06 Javascript
js+css简单实现网页换肤效果
Dec 29 Javascript
Vuejs实现带样式的单文件组件新方法
May 02 Javascript
Vue.js搭建移动端购物车界面
Jun 28 Javascript
将Sublime Text 3 添加到右键中的简单方法
Dec 12 Javascript
JavaScript使用享元模式实现文件上传优化操作示例
Aug 07 Javascript
AngularJS中ng-options实现下拉列表的数据绑定方法
Aug 13 Javascript
微信小程序实现底部导航
Nov 05 Javascript
详解Express笔记之动态渲染HTML(新手入坑)
Dec 13 Javascript
jQuery模仿ToDoList实现简单的待办事项列表
Dec 30 jQuery
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
PHP编程网上资源导航
2006/10/09 PHP
PHP5新特性: 更加面向对象化的PHP
2006/11/18 PHP
浅析关于PHP位运算的简单权限设计
2013/06/30 PHP
使用PHP静态变量当缓存的方法
2013/11/13 PHP
Smarty模板简单配置与使用方法示例
2016/05/23 PHP
PHP环形链表实现方法示例
2017/09/15 PHP
Referer原理与图片防盗链实现方法详解
2019/07/03 PHP
php使用redis的有序集合zset实现延迟队列应用示例
2020/02/20 PHP
sina的lightbox效果。
2007/01/09 Javascript
js限制input标签中只能输入中文
2015/06/26 Javascript
jQuery实现仿QQ空间装扮预览图片的鼠标提示效果代码
2015/10/30 Javascript
jquery自动补齐功能插件flexselect用法示例
2016/08/06 Javascript
详解js中Json的语法与格式
2016/11/22 Javascript
JavaScript实现body内任意节点的自定义属性功能示例
2017/09/18 Javascript
微信小程序表单验证功能完整实例
2017/12/01 Javascript
Vue-Router2.X多种路由实现方式总结
2018/02/09 Javascript
代码整洁之道(重构)
2018/10/25 Javascript
抖音上用记事本编写爱心小程序教程
2019/04/17 Javascript
js中let能否完全替代IIFE
2019/06/15 Javascript
JS 事件机制完整示例分析
2020/01/15 Javascript
JS前端基于canvas给图片添加水印
2020/11/11 Javascript
JavaScript实现HTML导航栏下拉菜单
2020/11/25 Javascript
[04:48]DOTA2上海特锦赛小组赛第三日 TOP10精彩集锦
2016/02/28 DOTA
python海龟绘图实例教程
2014/07/24 Python
python迭代器与生成器详解
2016/03/10 Python
Python模块结构与布局操作方法实例分析
2017/07/24 Python
基于Django contrib Comments 评论模块(详解)
2017/12/08 Python
python3实现163邮箱SMTP发送邮件
2018/05/22 Python
Python面向对象程序设计多继承和多态用法示例
2019/04/08 Python
美国餐厅用品和厨房设备批发网站:KaTom Restaurant Supply
2018/01/27 全球购物
CHARLES & KEITH加拿大官网:新加坡时尚品牌
2020/03/26 全球购物
2015年度信用社工作总结
2015/05/04 职场文书
拾金不昧通报表扬范文
2015/05/05 职场文书
就业意向书范本
2015/05/11 职场文书
呼啸山庄读书笔记
2015/06/29 职场文书
2015年征兵工作总结
2015/07/23 职场文书