文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

React Native中如何利用echarts画图表

2023-07-05 13:14

关注

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

小提示

详细使用过程如下

1、开发环境搭建

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

2、准备 RN 工程

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

npx create-expo-app TestApp

React Native中如何利用echarts画图表

3、build App 包

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

yarn androidyarn ios

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

React Native中如何利用echarts画图表

4、 安装相关依赖

yarn add @wuba/react-native-echarts echartsyarn add @shopify/react-native-skiayarn add react-native-svg

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

5、试用 Skia 模式

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

具体代码如下:

import { useRef, useEffect } from 'react';import { View } from 'react-native';import * as echarts from 'echarts/core';import { LineChart } from 'echarts/charts';import { GridComponent } from 'echarts/components';import { SVGRenderer, SkiaChart } from '@wuba/react-native-echarts';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 了一下,说是需要降级解决。其实是要跟 expo 版本对应,在安装依赖的时候也会有类似这样的提示,安装提示的版本就可以了

React Native中如何利用echarts画图表

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

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

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

iOSAndroid
React Native中如何利用echarts画图表React Native中如何利用echarts画图表

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 模式,肉眼看不出明显差别

iOSAndroid
React Native中如何利用echarts画图表React Native中如何利用echarts画图表

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 '@wuba/react-native-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';// 开启图表loadingconst showChartLoading = (chart) =>  chart.showLoading('default', {    maskColor: '#305d9e',  });// 关闭图表loadingconst 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}>      <StatusBar style='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,看看效果图

iOSAndroid
React Native中如何利用echarts画图表

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

再换 Skia 模式看看

React Native中如何利用echarts画图表

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

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

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

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

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯