React Native使用echart——wrn-echarts

news/2024/4/25 19:59:36/文章来源:https://blog.csdn.net/iambool/article/details/129255879

这里写自定义目录标题

    • 前言
    • Tips
    • 详细使用过程如下
      • 1、开发环境搭建
      • 2、准备RN工程
      • 3、build App包
      • 4、 安装相关依赖
      • 5、试用Skia模式
      • 6、试用Svg模式
      • 7、封装Chart组件
      • 8、多个图表使用
    • 总结

前言

平时写图表相关需求,用得最多的图表库就是echarts。echarts在web端的表现已经相当成熟,官方对小程序端也提供了解决方案,而在RN方面却没有相应支持。有个 react-native-echarts-pro 是基于 echarts 做的,但本质还是基于webview实现,而我更倾向于基于RN的方案,毕竟原生的体验会比Web的更好一些。
经过一番寻找发现 wrn-echarts 满足需求,于是上手试了下,效果还不错 ~ 对实现原理感兴趣的可以看这里

Tips

1.如果你已经有APP包,可以忽略前面的打包流程,直接跳到第4步。
2.试用的完整代码放在github上了,地址:https://github.com/iambool/TestApp

详细使用过程如下

1、开发环境搭建

本地搭好RN开发环境,搭建过程网上一抓一大把,就不赘述了。

2、准备RN工程

因为是试用,所以我用expo新初始化了一个rn工程,叫TestApp。

npx create-expo-app TestApp

在这里插入图片描述

3、build App包

用命令行生成包ios android app包。这里ios建议用模拟器(不需要配证书),安卓我是连的真机

yarn android
yarn ios

生成包后,手机看到已经安装了这个应用,就代表成功啦。
在这里插入图片描述

4、 安装相关依赖

yarn add wrn-echarts echarts
yarn add @shopify/react-native-skia
yarn add react-native-svg

tip: 注意,如果你是在已有工程中安装,安装完成后要重新打个新包,不然缺少原生依赖会报错;

5、试用Skia模式

wrn-echarts支持两种渲染模式(Skia和Svg),先用Skia试一个简单的图表。大致分为这几个小步骤:

  • 引入echarts、图表组件等依赖
  • 注册图表组件
  • 创建图表实例,并设置图表的配置(option)
  • 页面销毁时要记得同步销毁图表实例

具体代码如下:

import { useRef, useEffect } from 'react';
import { View } from 'react-native';
/*** 一、引入echarts依赖,这里先试下折线图*/
import * as echarts from 'echarts/core';
import { LineChart } from 'echarts/charts';
import { GridComponent } from 'echarts/components';
import { SVGRenderer, SkiaChart } from 'wrn-echarts';/*** 二、注册需要用到的组件* SVGRenderer: 是必须注册的* LineChart: 因为用的折线图,所以要引入LineChart(如果不知道该引入哪些组件,就直接看报错,报错说缺什么就加什么)* GridComponent: 这个就是报错的时候提示,然后我加的hhh*/
echarts.use([SVGRenderer, LineChart, GridComponent]);export default () => {const skiaRef = useRef(null); // Ref用于保存图表实例useEffect(() => {/*** 四、图表配置*/const option = {xAxis: {type: 'category',data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],},yAxis: {type: 'value',},series: [{data: [150, 230, 224, 218, 135, 147, 260],type: 'line',},],};let chart;if (skiaRef.current) {/*** 五、初始化图表,指定下宽高*/chart = echarts.init(skiaRef.current, 'light', {renderer: 'svg',width: 400,height: 400,});chart.setOption(option);}/*** 六、页面关闭后要销毁图表实例*/return () => chart?.dispose();}, []);return (<View className='index'><SkiaChart ref={skiaRef} /></View>);
};

写完摇一摇手机,reload bundle包时出现了报错:

ERROR Invariant Violation: requireNativeComponent: “SkiaDomView” was not found in the UIManager.

google了一下,说是需要降级解决,于是做了版本降级:

@shopify/react-native-skia@0.1.157
react-native-svg@13.4.0

重新构建app后加载出来了,针不戳;(安卓遮住了点,看来应该自适应屏幕宽度)

iOS安卓
iOS截图安卓截图

6、试用Svg模式

写个复杂点的动态排序柱状图,试试Svg模式,给Svg和Skia做个对比,完整代码看这里。

// ...此处省略一些不重要的代码// 注册需要用到的组件,BarChart-柱状图 LegendComponent-图例
echarts.use([SVGRenderer, BarChart, LegendComponent, GridComponent]);export default () => {const skiaRef = useRef(null);const svgRef = useRef(null);useEffect(() => {// Skia模式const skiaChartData = getData(); // 生成图表柱状图数据let skiaChart;let skiaInter;if (skiaRef.current) {skiaChart = echarts.init(skiaRef.current, 'light', {renderer: 'svg',width: 300,height: 300,});skiaChart.setOption(getDefaultOption(skiaChartData));setTimeout(function () {run(skiaChart, skiaChartData);}, 0);skiaInter = setInterval(function () {run(skiaChart, skiaChartData);}, 3000);}// Svg模式const svgChartData = getData();let svgChart;let svgInter;if (svgRef.current) {svgChart = echarts.init(svgRef.current, 'light', {renderer: 'svg',width: 300,height: 300,});svgChart.setOption(getDefaultOption(svgChartData));setTimeout(function () {run(svgChart, svgChartData);}, 0);svgInter = setInterval(function () {run(svgChart, svgChartData);}, 3000);}return () => {skiaChart?.dispose();svgChart?.dispose();// 定时器得清理掉,不然退出页面后还会运行clearInterval(skiaInter);clearInterval(svgInter);};}, []);return (<View><Text>skia如下</Text><SkiaChart ref={skiaRef} /><Text>svg如下</Text><SvgChart ref={svgRef} /></View>);
};

Skia和Svg模式,肉眼看不出明显差别

iOS安卓
在这里插入图片描述在这里插入图片描述

7、封装Chart组件

效果不错,不过每次使用都要把一堆东西引进去好烦,先简单封装下吧

import { useRef, useEffect } from 'react';
import * as echarts from 'echarts/core';
import { BarChart, LineChart, PieChart } from 'echarts/charts';
import {DataZoomComponent,GridComponent,LegendComponent,TitleComponent,ToolboxComponent,TooltipComponent,
} from 'echarts/components';
import {SVGRenderer,SvgChart as _SvgChart,SkiaChart as _SkiaChart,
} from 'wrn-echarts';
import { Dimensions } from 'react-native';// 注册需要用到的组件
echarts.use([DataZoomComponent,SVGRenderer,BarChart,GridComponent,LegendComponent,ToolboxComponent,TooltipComponent,TitleComponent,PieChart,LineChart
]);// 图表默认宽高
const CHART_WIDTH = Dimensions.get('screen').width; // 默认用手机屏幕宽度
const CHART_HEIGHT = 300;const Chart = ({option,onInit,width = CHART_WIDTH,height = CHART_HEIGHT,ChartComponent,
}) => {const chartRef = useRef(null);useEffect(() => {let chart;if (chartRef.current) {chart = echarts.init(chartRef.current, 'light', {renderer: 'svg',width,height,});option && chart.setOption(option);onInit?.(chart);}return () => chart?.dispose();}, [option]);return <ChartComponent ref={chartRef} />;
};const SkiaChart  = (props) => (<Chart {...props} ChartComponent={_SkiaChart} />
);
const SvgChart  = (props) => (<Chart {...props} ChartComponent={_SvgChart} />
);
// 对外只暴露这哥俩就行
export { SkiaChart, SvgChart };

8、多个图表使用

封装好了,咱就写个多图表同时使用的页面看看效果。这里写了个“电商数据分析”页面,分别有折线图、柱状图、饼图。下方是主要代码,用的svg模式,详细代码见这里。

// 页面代码
import { SkiaChart } from '../../components/Chart';
import { ScrollView, Text, View } from 'react-native';
import { StatusBar } from 'expo-status-bar';
import { useCallback, useEffect, useState } from 'react';
import {defaultActual,lineOption,salesStatus,salesVolume,userAnaly,getLineData
} from './contants';
import styles from './styles';
// 开启图表loading
const showChartLoading = (chart) =>chart.showLoading('default', {maskColor: '#305d9e',});
// 关闭图表loading
const hideChartLoading = (chart) => chart.hideLoading();export default () => {const [actual, setActual] = useState(defaultActual); // 记录实时数据useEffect(() => {// 假设循环请求数据const interv = setInterval(() => {const newActual = [];for (let it of actual) {newActual.push({...it,num: it.num + Math.floor((Math.random() * it.num) / 100),});}setActual(newActual);}, 200);return () => clearInterval(interv);}, [actual]);const onInitLineChart = useCallback((myChart) => {showChartLoading(myChart);// 模拟数据请求setTimeout(() => {myChart.setOption({series: getLineData,});hideChartLoading(myChart);}, 1000);}, []);const onInitUserChart = useCallback((myChart) => {// 模拟数据请求,跟onInitLineChart类似}, []);const onInitSaleChart = useCallback((myChart) => {// 模拟数据请求,跟onInitLineChart类似}, []);const onInitStatusChart = useCallback((myChart) => {// 模拟数据请求,跟onInitLineChart类似}, []);const chartList = [['订单走势', lineOption, onInitLineChart],['用户统计', userAnaly, onInitUserChart],['各品类销售统计', salesVolume, onInitSaleChart],['订单状态统计', salesStatus, onInitStatusChart],]return (<ScrollView style={styles.index}><StatusBarstyle="light"/><View><View style={styles.index_panel_header}><Text style={styles.index_panel_title}>实时数据</Text></View><View style={styles.index_panel_content}>{actual.map(({ title, num, unit }) => (<View key={title} style={styles.sale_item}><View  style={styles.sale_item_cell}><Text  style={styles.sale_item_text}>{title}</Text></View><View style={[styles.sale_item_cell, styles.num]}><Text style={styles.sale_item_num}>{num}</Text></View><View style={[styles.sale_item_cell, styles.unit]}><Text style={styles.sale_item_text}>{unit}</Text></View></View>))}</View></View>{chartList.map(([title, data, callback]) => (<View key={title}><View style={styles.index_panel_header}><Text style={styles.index_panel_title}>{title}</Text></View><View style={styles.index_panel_content}><SkiaChart option={data} onInit={callback} /></View></View>))}</ScrollView>);
};

重新加载bundle,看看效果图

iOS安卓
在这里插入图片描述在这里插入图片描述

渲染出来后,iOS上交互很丝滑,安卓上交互时感觉偶尔会有卡顿(不会是因为我手机太差吧…)。

再换Skia模式看看
在这里插入图片描述
emmm虽然可以,但是好像中文不能正常显示,安卓上中文都没有显示,iOS则是乱码。看了下文档,目前skia在安卓端还不支持中文,在iOS端可以通过设置字体为 'PingFang SC’显示中文,比如:

const option = {title: {text: '我是中文',textStyle: {fontFamily: 'PingFang SC' // 指定字体类型}},
}

但是每个显示中文的地方都要设置字体……那还是先用svg吧,我懒。

总结

使用了一段时间后,我总结了下:

  • 支持度上,wrn-echarts除了GL系列、地图类图表还不支持外,其余类型的图表都支持,对于日常业务来说已经非常enough了。echarts各种类型的图表实现,都可以在taro-playground上找到;
  • 交互上,iOS很丝滑,安卓有时会出现掉帧的情况;
  • 性能上,官方报告显示优于react-native-echarts-pro。
    • 个人试了下,不是超大数据量就不会有什么问题,但是数据量太大的时候(比如画大数据量的热力图),渲染速度明显下降了很多,这是一个等待官方去优化的点。
    • 另外页面内图表多的话,真机调试时加载速度会变慢,建议先用模拟器。
  • 中文支持,Svg模式支持中文,但Skia模式目前还不可以。

以上仅代表个人观点,有问题欢迎交流。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_75225.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

机器学习:基于朴素贝叶斯对花瓣花萼的宽度和长度分类预测

机器学习&#xff1a;基于朴素贝叶斯对花瓣花萼的宽度和长度分类预测 作者&#xff1a;AOAIYI 作者简介&#xff1a;Python领域新星作者、多项比赛获奖者&#xff1a;AOAIYI首页 &#x1f60a;&#x1f60a;&#x1f60a;如果觉得文章不错或能帮助到你学习&#xff0c;可以点赞…

毕业设计 基于51单片机环境监测设计 光照 PM2.5粉尘 温湿度 2.4G无线通信

基于51单片机环境监测设计 光照 PM2.5粉尘 温湿度 2.4G无线通信1、项目简介1.1 系统构成1.2 系统功能2、部分电路设计2.1 STC89C52单片机核心系统电路设计2.2 dht11温湿度检测电路设计2.3 NRF24L01无线通信电路设计3、部分代码展示3.1 NRF24L01初始化3.2 NRF24L01的SPI写时序3.…

【数据库】数据库基本概念和类型

一、数据库基本概念 1、数据 所谓数据&#xff08;Data&#xff09;是指对客观事物进行描述并可以鉴别的符号&#xff0c;这些符号是可识别的、抽象的。它不仅仅指狭义上的数字&#xff0c;而是有多种表现形式&#xff1a;字母、文字、文本、图形、音频、视频等。现在…

STM32开发(16)----CubeMX配置DMA

CubeMX配置DMA前言一、什么是DMA&#xff1f;二、实验过程1.CubeMX配置2.代码实现3.实验结果总结前言 本章介绍使用STM32CubeMX对DMA进行配置的方法&#xff0c;DMA的原理、概念和特点&#xff0c;配置各个步骤的功能&#xff0c;并通过串口DMA传输实验方式验证。 一、什么是…

【学习笔记汇总】Github Note

本科毕业设计 Internet of Things environmental monitoring system based on STM32 STM32系列单片机工程模板 【STM32F103_Libary】基于STM32F103开发板的工程模板 ST7735屏幕【STM32F103Template】基于STM32F103开发板的工程模板 ILI9341屏幕【STM32F103_LibaryFinalVersio…

服务拆分及远程调用

目录 服务拆分 服务拆分注意事项 服务间调用 步骤一&#xff1a;注册RestTemplate 步骤二&#xff1a;修改业务层代码 总结&#xff1a; 提供者和消费者 思考 服务调用关系 服务拆分 服务拆分注意事项 单一职责&#xff1a;不同微服务&#xff0c;不要重复开发相同业…

电压放大器和电流放大器的区别是什么意思

在日常电子实验测试中&#xff0c;很多电子工程师都会使用到电压放大器和电流放大器&#xff0c;但是很多新手工程师却无法区分两者的区别&#xff0c;下面就让安泰电子来为我们讲解电压放大器和电流放大器的区别是什么意思。 一、电压放大器介绍&#xff1a; 电压放大器是一种…

2023王道考研数据结构笔记第一章绪论

第一章 绪论 1.1 数据结构的基本概念 1.数据&#xff1a;数据是信息的载体&#xff0c;是描述客观事物属性的数、字符以及所有能输入到计算机中并被程序识别和处理的符号的集合。 2.数据元素&#xff1a;数据元素是数据的基本单位&#xff0c;通常作为一个整体进行考虑和处理…

【MySQL】数据库中锁和事务的相关知识点

1.事务的四大特点 原子性&#xff1a;事务中的所有操作要么都成功&#xff0c;要么都失败。所有的操作是一个不可分割的单位。一致性&#xff1a;一致性指的是事务执行前后&#xff0c;数据从一个合法性状态转移到另一个合法性状态。这个状态和业务有关&#xff0c;是自己定义…

Editor工具开发实用篇:EditorGUI/EditorGUILayout的区别和EditorGUILayout的方法介绍

目录 一&#xff1a;EditorGUI和EditorGUILayout区别 二&#xff1a;EditorGUILayout 1.EditorGUILayout.BeginFadeGroup(float value); 2.EditorGUILayout.BeginHorizontal EditorGUILayout.BeginVertical 3.EditorGUILayout.BeginScrollView 4.EditorGUILayout.BeginT…

sql-labs-Less1

靶场搭建好了&#xff0c;访问题目路径 http://127.0.0.1/sqli-labs-master/Less-1/ 我最开始在做sql-labs靶场的时候很迷茫&#xff0c;不知道最后到底要得到些什么&#xff0c;而现在我很清楚&#xff0c;sql注入可以获取数据库中的信息&#xff0c;而获取信息就是我们的目标…

概念+示例+横向对比+难点解析征服八大react hooks

8大hooks概念、使用场景 前言 对不同阶段的react开发者会有不同的效果&#xff0c;最终目的是能够对8大react hooks&#xff0c;完全理解&#xff0c;游刃有余。对比useState和useReducer&#xff0c;什么时候使用useMemo和useCallback&#xff0c;useEffect的参数… … use…

文献阅读笔记 # 面向大规模多版本软件系统的代码克隆检测加速技术

面向大规模多版本软件系统的代码克隆检测加速技术&#xff0c;方维康 吴毅坚 赵文耘&#xff0c;《计算机应用与软件》复旦大学软件学院、复旦大学上海市数据科学重点实验室2022 April 面向大规模多版本软件系统的代码克隆检测加速技术 摘要 很多代码克隆检测方法主要针对软…

【博学谷学习记录】超强总结,用心分享丨人工智能 多场景实战 常用英文缩写概念总结

目录PV(Page View)UV(Unique Visitor)CPM(Cost Per Mille)CPC(Cost Per Click)CPA(Cost Per Action)CPI(Cost Per Install)ACU(Average concurrent users)PCU(Peak concurrent users)ARPU(Average Revenue Per User)ARPPU(Average Revenue Per Paying User)LTV(Life Time Value…

Linux命令之lz4命令

一、lz4命令简介 LZ4是一种压缩格式&#xff0c;特点是压缩/解压缩速度超快(压缩率不如gzip)&#xff0c;如果你特别在意压缩速度&#xff0c;或者当前环境的CPU资源紧缺&#xff0c;可以考虑这种格式。lz4是一种非常快速的无损压缩算法&#xff0c;基于字节对齐LZ77系列压缩方…

西电计算机通信与网络(计网)简答题计算题核心考点汇总(期末真题+核心考点)

文章目录前言一、简答计算题真题概览二、网桥&#xff0c;交换机和路由器三、ARQ协议四、曼彻斯特编码和差分曼彻斯特编码五、CRC六、ARP协议七、LAN相关协议计算前言 主要针对西安电子科技大学《计算机通信与网络》的核心考点进行汇总&#xff0c;包含总共26章的核心简答。 【…

【Linux】Linux根文件系统扩容

场景&#xff1a;根文件系统需要至少100GB的剩余空间&#xff0c;但是目前就剩余91GB。因此&#xff0c;我们需要对根文件系统进行扩容。# df -h 文件系统 容量 已用 可用 已用% 挂载点 devtmpfs 3.9G 0 3.9G 0% /dev tmpfs …

密码暴力破解

密码的暴力破解准备工具功能简介Burp Intruder工作原理Intruder应用场景爆破实操准备工具 首先准备好BurpSuite和Dvwa作为测试工具和实验对象。 功能简介 Burp Intruder工作原理 Intruder在原始请求数据的基础上&#xff0c;通过修改各种请求参数&#xff0c;以获取不同的请…

flutter 微信聊天输入框

高仿微信聊天输入框&#xff0c;效果图如下&#xff08;目前都是静态展示&#xff0c;服务还没开始开发&#xff09;&#xff1a; 大家如果观察仔细的话 应该会发现&#xff0c;他输入框下面的高度 刚好就是 软键盘的高度&#xff1b;所以在这里就需要监听软键盘的高度。还要配…

Hbase资源隔离操作指南

1.检查集群的环境配置 1.1 HBase版本号确认> 5.11.0 引入rsgroup的Patch&#xff1a; [HBASE-6721] RegionServer Group based Assignment - ASF JIRA RegionServer Group based Assignment 社区支持版本&#xff1a;2.0.0 引入rsgroup的CDH版本 5.11.0 https://www.…