React Native中如何利用echarts画图表


这篇文章主要讲解了“React Native中如何利用echarts画图表”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“React Native中如何利用echarts画图表”吧!

小提示

  • 如果你已经有 APP 包,可以忽略前面的打包流程,直接跳到第 4 步。

详细使用过程如下

1、开发环境搭建

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

2、准备 RN 工程

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

npxcreate-expo-appTestApp

3、build App 包

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

yarnandroidyarnios

生成包后,手机看到已经安装了这个应用,就代表成功啦。

4、 安装相关依赖

yarnadd@wuba/react-native-echartsechartsyarnadd@shopify/react-native-skiayarnaddreact-native-svg

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

5、试用 Skia 模式

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

  • 引入 echarts、图表组件等依赖

  • 注册图表组件

  • 创建图表实例,并设置图表的配置(option)

  • 页面销毁时要记得同步销毁图表实例

具体代码如下:

import{useRef,useEffect}from'react';import{View}from'react-native';/***一、引入echarts依赖,这里先试下折线图*/import*asechartsfrom'echarts/core';import{LineChart}from'echarts/charts';import{Griponent}from'echartsponents';import{SVGRenderer,SkiaChart}from'@wuba/react-native-echarts';/***二、注册需要用到的组件*SVGRenderer:是必须注册的*LineChart:因为用的折线图,所以要引入LineChart(如果不知道该引入哪些组件,就直接看报错,报错说缺什么就加什么)*Griponent:这个就是报错的时候提示,然后我加的hhh*/echarts.use([SVGRenderer,LineChart,Griponent]);exportdefault()=>{constskiaRef=useRef(null);//Ref用于保存图表实例useEffect(()=>{/***四、图表配置*/constoption={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',},],};letchart;if(skiaRef.current){/***五、初始化图表,指定下宽高*/chart=echarts.init(skiaRef.current,'light',{renderer:'svg',width:400,height:400,});chart.setOption(option);}/***六、页面关闭后要销毁图表实例*/return()=>chart?.dispose();},[]);return(<ViewclassName='index'><SkiaChartref={skiaRef}/></View>);};

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

ERROR Invariant Violation: requireNativponent: "SkiaDomView" was not found in the UIManager.

google 了一下,说是需要降级解决。其实是要跟 expo 版本对应,在安装依赖的时候也会有类似这样的提示,安装提示的版本就可以了

于是按照提示做了版本降级:

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

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

iOSAndroid

6、试用 Svg 模式

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

//...此处省略一些不重要的代码//注册需要用到的组件,BarChart-柱状图Legenponent-图例echarts.use([SVGRenderer,BarChart,Legenponent,Griponent]);exportdefault()=>{constskiaRef=useRef(null);constsvgRef=useRef(null);useEffect(()=>{//Skia模式constskiaChartData=getData();//生成图表柱状图数据letskiaChart;letskiaInter;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模式constsvgChartData=getData();letsvgChart;letsvgInter;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><SkiaChartref={skiaRef}/><Text>svg如下</Text><SvgChartref={svgRef}/></View>);};

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

iOSAndroid

7、封装 Chart 组件

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

import{useRef,useEffect}from'react';import*asechartsfrom'echarts/core';import{BarChart,LineChart,PieChart}from'echarts/charts';import{DataZooponent,Griponent,Legenponent,Titlponent,Toolboponent,Tooltiponent,}from'echartsponents';import{SVGRenderer,SvgChartas_SvgChart,SkiaChartas_SkiaChart,}from'@wuba/react-native-echarts';import{Dimensions}from'react-native';//注册需要用到的组件echarts.use([DataZooponent,SVGRenderer,BarChart,Griponent,Legenponent,Toolboponent,Tooltiponent,Titlponent,PieChart,LineChart,]);//图表默认宽高constCHART_WIDTH=Dimensions.get('screen').width;//默认用手机屏幕宽度constCHART_HEIGHT=300;constChart=({option,onInit,width=CHART_WIDTH,height=CHART_HEIGHT,Charponent,})=>{constchartRef=useRef(null);useEffect(()=>{letchart;if(chartRef.current){chart=echarts.init(chartRef.current,'light',{renderer:'svg',width,height,});option&&chart.setOption(option);onInit?.(chart);}return()=>chart?.dispose();},[option]);return<Charponentref={chartRef}/>;};constSkiaChart=(props)=><Chart{...props}Charponent={_SkiaChart}/>;constSvgChart=(props)=><Chart{...props}Charponent={_SvgChart}/>;//对外只暴露这哥俩就行export{SkiaChart,SvgChart};

8、多个图表使用

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

//页面代码import{SkiaChart}from'../..ponents/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';importstylesfrom'./styles';//开启图表loadingconstshowChartLoading=(chart)=>chart.showLoading('default',{maskColor:'#305d9e',});//关闭图表loadingconsthideChartLoading=(chart)=>chart.hideLoading();exportdefault()=>{const[actual,setActual]=useState(defaultActual);//记录实时数据useEffect(()=>{//假设循环请求数据constinterv=setInterval(()=>{constnewActual=[];for(letitofactual){newActual.push({...it,num:it.num+Math.floor((Math.random()*it.num)/100),});}setActual(newActual);},200);return()=>clearInterval(interv);},[actual]);constonInitLineChart=useCallback((myChart)=>{showChartLoading(myChart);//模拟数据请求setTimeout(()=>{myChart.setOption({series:getLineData,});hideChartLoading(myChart);},1000);},[]);constonInitUserChart=useCallback((myChart)=>{//模拟数据请求,跟onInitLineChart类似},[]);constonInitSaleChart=useCallback((myChart)=>{//模拟数据请求,跟onInitLineChart类似},[]);constonInitStatusChart=useCallback((myChart)=>{//模拟数据请求,跟onInitLineChart类似},[]);constchartList=[['订单走势',lineOption,onInitLineChart],['用户统计',userAnaly,onInitUserChart],['各品类销售统计',salesVolume,onInitSaleChart],['订单状态统计',salesStatus,onInitStatusChart],];return(<ScrollViewstyle={styles.index}><StatusBarstyle='light'/><View><Viewstyle={styles.index_panel_header}><Textstyle={styles.index_panel_title}>实时数据</Text></View><Viewstyle={styles.index_panel_content}>{actual.map(({title,num,unit})=>(<Viewkey={title}style={styles.sale_item}><Viewstyle={styles.sale_item_cell}><Textstyle={styles.sale_item_text}>{title}</Text></View><Viewstyle={[styles.sale_item_cell,styles.num]}><Textstyle={styles.sale_item_num}>{num}</Text></View><Viewstyle={[styles.sale_item_cell,styles.unit]}><Textstyle={styles.sale_item_text}>{unit}</Text></View></View>))}</View></View>{chartList.map(([title,data,callback])=>(<Viewkey={title}><Viewstyle={styles.index_panel_header}><Textstyle={styles.index_panel_title}>{title}</Text></View><Viewstyle={styles.index_panel_content}><SkiaChartoption={data}onInit={callback}/></View></View>))}</ScrollView>);};

重新加载 bundle,看看效果图

iOSAndroid

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

再换 Skia 模式看看

emmm 虽然可以,但是好像中文不能正常显示,安卓上中文都没有显示,iOS 则是乱码。看了下文档,目前 skia 在安卓端还不支持中文,在 iOS 端可以通过设置字体为 'PingFang SC'显示中文,比如:

constoption={title:{text:'我是中文',textStyle:{fontFamily:'PingFangSC',//指定字体类型},},};

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

感谢各位的阅读,以上就是“React Native中如何利用echarts画图表”的内容了,经过本文的学习后,相信大家对React Native中如何利用echarts画图表这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是主机评测网,小编将为大家推送更多相关知识点的文章,欢迎关注!


上一篇:Redis怎么使用ZSET实现消息队列

下一篇:怎么使用Python+PyQt5自制监控小工具


Copyright © 2002-2019 测速网 https://www.inhv.cn/ 皖ICP备2023010105号 城市 地区 街道
温馨提示:部分文章图片数据来源与网络,仅供参考!版权归原作者所有,如有侵权请联系删除!
热门搜索