溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

React Native中如何利用echarts畫圖表

發(fā)布時間:2023-03-17 09:36:29 來源:億速云 閱讀:143 作者:iii 欄目:web開發(fā)

這篇文章主要講解了“React Native中如何利用echarts畫圖表”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“React Native中如何利用echarts畫圖表”吧!

小提示

  • 如果你已經(jīng)有 APP 包,可以忽略前面的打包流程,直接跳到第 4 步。

詳細(xì)使用過程如下

1、開發(fā)環(huán)境搭建

本地搭好 RN 開發(fā)環(huán)境,搭建過程網(wǎng)上一抓一大把,就不贅述了。

2、準(zhǔn)備 RN 工程

因為是試用,所以我用 expo 新初始化了一個 rn 工程,叫 TestApp。

npx create-expo-app TestApp

React Native中如何利用echarts畫圖表

3、build App 包

用命令行生成包 ios android app 包。這里 ios 建議用模擬器(不需要配證書),安卓我是連的真機

yarn android
yarn ios

生成包后,手機看到已經(jīng)安裝了這個應(yīng)用,就代表成功啦。

React Native中如何利用echarts畫圖表

4、 安裝相關(guān)依賴

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

注意,如果你是在已有工程中安裝,安裝完成后要重新打個新包,不然缺少原生依賴會報錯;

5、試用 Skia 模式

@wuba/react-native-echarts 支持兩種渲染模式(Skia 和 Svg),先用 Skia 試一個簡單的圖表。大致分為這幾個小步驟:

  • 引入 echarts、圖表組件等依賴

  • 注冊圖表組件

  • 創(chuàng)建圖表實例,并設(shè)置圖表的配置(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 '@wuba/react-native-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);
    }
    /**
     * 六、頁面關(guān)閉后要銷毀圖表實例
     */
    return () => chart?.dispose();
  }, []);
  return (
    <View className='index'>
      <SkiaChart ref={skiaRef} />
    </View>
  );
};

寫完搖一搖手機,reload bundle 包時出現(xiàn)了報錯:

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

google 了一下,說是需要降級解決。其實是要跟 expo 版本對應(yīng),在安裝依賴的時候也會有類似這樣的提示,安裝提示的版本就可以了

React Native中如何利用echarts畫圖表

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

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

重新構(gòu)建 app 后加載出來了,針不戳;(安卓遮住了點,看來應(yīng)該自適應(yīng)屏幕寬度)

iOSAndroid
React Native中如何利用echarts畫圖表React Native中如何利用echarts畫圖表

6、試用 Svg 模式

寫個復(fù)雜點的動態(tài)排序柱狀圖,試試 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(); // 生成圖表柱狀圖數(shù)據(jù)
    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 組件

效果不錯,不過每次使用都要把一堆東西引進(jìn)去好煩,先簡單封裝下吧

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,
]);

// 圖表默認(rèn)寬高
const CHART_WIDTH = Dimensions.get('screen').width; // 默認(rèn)用手機屏幕寬度
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、多個圖表使用

封裝好了,咱就寫個多圖表同時使用的頁面看看效果。這里寫了個“電商數(shù)據(jù)分析”頁面,分別有折線圖、柱狀圖、餅圖。下方是主要代碼,用的 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',
  });
// 關(guān)閉圖表loading
const hideChartLoading = (chart) => chart.hideLoading();

export default () => {
  const [actual, setActual] = useState(defaultActual); // 記錄實時數(shù)據(jù)

  useEffect(() => {
    // 假設(shè)循環(huán)請求數(shù)據(jù)
    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);
    // 模擬數(shù)據(jù)請求
    setTimeout(() => {
      myChart.setOption({
        series: getLineData,
      });
      hideChartLoading(myChart);
    }, 1000);
  }, []);

  const onInitUserChart = useCallback((myChart) => {
    // 模擬數(shù)據(jù)請求,跟onInitLineChart類似
  }, []);
  const onInitSaleChart = useCallback((myChart) => {
    // 模擬數(shù)據(jù)請求,跟onInitLineChart類似
  }, []);
  const onInitStatusChart = useCallback((myChart) => {
    // 模擬數(shù)據(jù)請求,跟onInitLineChart類似
  }, []);

  const chartList = [
    ['訂單走勢', lineOption, onInitLineChart],
    ['用戶統(tǒng)計', userAnaly, onInitUserChart],
    ['各品類銷售統(tǒng)計', salesVolume, onInitSaleChart],
    ['訂單狀態(tài)統(tǒng)計', salesStatus, onInitStatusChart],
  ];

  return (
    <ScrollView style={styles.index}>
      <StatusBar style='light' />
      <View>
        <View style={styles.index_panel_header}>
          <Text style={styles.index_panel_title}>實時數(shù)據(jù)</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 則是亂碼??戳讼挛臋n,目前 skia 在安卓端還不支持中文,在 iOS 端可以通過設(shè)置字體為 'PingFang SC'顯示中文,比如:

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

但是每個顯示中文的地方都要設(shè)置字體……那還是先用 svg 吧。

感謝各位的閱讀,以上就是“React Native中如何利用echarts畫圖表”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對React Native中如何利用echarts畫圖表這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI