Rumah  >  Artikel  >  hujung hadapan web  >  Mari kita bincangkan tentang cara menggunakan echarts untuk melukis carta dalam React Native

Mari kita bincangkan tentang cara menggunakan echarts untuk melukis carta dalam React Native

青灯夜游
青灯夜游ke hadapan
2023-03-16 19:58:012246semak imbas

Bagaimana untuk melukis carta dalam React Native? Artikel berikut akan memperkenalkan kepada anda cara menggunakan React Native+Echarts untuk membangunkan halaman statistik data e-dagang yang sebenar, saya harap ia akan membantu anda!

Mari kita bincangkan tentang cara menggunakan echarts untuk melukis carta dalam React Native

Untuk keperluan berkaitan carta harian, perpustakaan carta yang paling banyak digunakan ialah echarts. Prestasi echarts di bahagian web agak matang, dan penyelesaian rasmi juga disediakan untuk bahagian program mini, tetapi tiada sokongan yang sepadan untuk RN. Kebanyakan penyelesaian yang ditemui di pasaran pada asasnya berdasarkan paparan web, dan saya lebih suka penyelesaian berdasarkan RN Lagipun, pengalaman asli akan lebih baik daripada yang web.

Jadi kami mengeluarkan @wuba/react-native-echarts untuk memenuhi permintaan. Mereka yang berminat dengan prinsip pelaksanaan boleh lihat di sini.

Seterusnya saya akan menggunakan @wuba/react-native-echarts untuk membuat aplikasi dalam projek sebenar Tangkapan skrin adalah seperti berikut:

Mari kita bincangkan tentang cara menggunakan echarts untuk melukis carta dalam React Native

Petua<.>

    Jika anda sudah mempunyai pakej APP, anda boleh mengabaikan proses pembungkusan sebelumnya dan terus ke langkah 4.
  • Kod lengkap untuk percubaan adalah pada github, alamat:
  • github.com/iambool/Tes...
Proses penggunaan terperinci adalah seperti berikut

1. Persediaan persekitaran pembangunan

Sediakan persekitaran pembangunan RN secara tempatan Proses pembinaan boleh didapati dalam talian, jadi saya tidak akan menerangkan secara terperinci.

2. Sediakan projek RN

Oleh kerana ia adalah percubaan, saya menggunakan ekspo untuk memulakan projek RN yang dipanggil TestApp.

npx create-expo-app TestApp

Mari kita bincangkan tentang cara menggunakan echarts untuk melukis carta dalam React Native

3. Bina pakej Apl

Gunakan baris arahan untuk menjana pakej apl android ios. Di sini adalah disyorkan untuk menggunakan simulator untuk ios (tiada sijil diperlukan). dipasang, yang bermaksud ia berjaya.

yarn android
yarn ios

4 Pasang kebergantungan berkaitan

Mari kita bincangkan tentang cara menggunakan echarts untuk melukis carta dalam React Native

Perhatikan bahawa jika anda memasang dalam projek sedia ada, anda perlu membuat pakej baharu selepas pemasangan. selesai , jika tidak, ralat akan dilaporkan jika kebergantungan asli tiada

5 Cuba mod Skia
yarn add @wuba/react-native-echarts echarts
yarn add @shopify/react-native-skia
yarn add react-native-svg

@wuba/react-native-echarts menyokong

dua mod pemaparan (Skia. dan Svg)

, Mari cuba carta mudah menggunakan Skia dahulu. Ia boleh dibahagikan secara kasar kepada langkah-langkah kecil ini:

Perkenalkan ecart, komponen carta dan kebergantungan lain

Daftar komponen carta
  • Buat contoh carta dan tetapkan carta konfigurasi ( pilihan)
  • Apabila halaman dimusnahkan, ingat untuk memusnahkan contoh carta secara serentak
  • Kod khusus adalah seperti berikut:
Selepas menulis , goncang telefon dan muat semula berkas. Ralat telah berlaku:

import { useRef, useEffect } from &#39;react&#39;;
import { View } from &#39;react-native&#39;;
/**
 * 一、引入echarts依赖,这里先试下折线图
 */
import * as echarts from &#39;echarts/core&#39;;
import { LineChart } from &#39;echarts/charts&#39;;
import { GridComponent } from &#39;echarts/components&#39;;
import { SVGRenderer, SkiaChart } from &#39;@wuba/react-native-echarts&#39;;

/**
 * 二、注册需要用到的组件
 * SVGRenderer: 是必须注册的
 * LineChart: 因为用的折线图,所以要引入LineChart(如果不知道该引入哪些组件,就直接看报错,报错说缺什么就加什么)
 * GridComponent: 这个就是报错的时候提示,然后我加的hhh
 */
echarts.use([SVGRenderer, LineChart, GridComponent]);

export default () => {
  const skiaRef = useRef(null); // Ref用于保存图表实例
  useEffect(() => {
    /**
     * 四、图表配置
     */
    const option = {
      xAxis: {
        type: &#39;category&#39;,
        data: [&#39;Mon&#39;, &#39;Tue&#39;, &#39;Wed&#39;, &#39;Thu&#39;, &#39;Fri&#39;, &#39;Sat&#39;, &#39;Sun&#39;],
      },
      yAxis: {
        type: &#39;value&#39;,
      },
      series: [
        {
          data: [150, 230, 224, 218, 135, 147, 260],
          type: &#39;line&#39;,
        },
      ],
    };
    let chart;
    if (skiaRef.current) {
      /**
       * 五、初始化图表,指定下宽高
       */
      chart = echarts.init(skiaRef.current, &#39;light&#39;, {
        renderer: &#39;svg&#39;,
        width: 400,
        height: 400,
      });
      chart.setOption(option);
    }
    /**
     * 六、页面关闭后要销毁图表实例
     */
    return () => chart?.dispose();
  }, []);
  return (
    <View className=&#39;index&#39;>
      <SkiaChart ref={skiaRef} />
    </View>
  );
};
RALAT Pelanggaran Invarian: requireNativeComponent: "SkiaDomView" tidak ditemui dalam UIManager.

Google dan ia mengatakan bahawa ia perlu

diturunkan taraf

Diselesaikan. Malah, ia perlu sepadan dengan versi ekspo Apabila memasang dependensi, akan ada gesaan seperti ini. Hanya pasang versi yang digesa

Jadi saya menurunkan versi mengikut. kepada gesaan :

Mari kita bincangkan tentang cara menggunakan echarts untuk melukis carta dalam React Native

Selepas membina semula apl, ia dimuatkan dan pin tidak melekat; >

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, &#39;light&#39;, {
        renderer: &#39;svg&#39;,
        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, &#39;light&#39;, {
        renderer: &#39;svg&#39;,
        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 Android
Mari kita bincangkan tentang cara menggunakan echarts untuk melukis carta dalam React Native Mari kita bincangkan tentang cara menggunakan echarts untuk melukis carta dalam React Native

7、封装 Chart 组件

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

import { useRef, useEffect } from &#39;react&#39;;
import * as echarts from &#39;echarts/core&#39;;
import { BarChart, LineChart, PieChart } from &#39;echarts/charts&#39;;
import {
  DataZoomComponent,
  GridComponent,
  LegendComponent,
  TitleComponent,
  ToolboxComponent,
  TooltipComponent,
} from &#39;echarts/components&#39;;
import {
  SVGRenderer,
  SvgChart as _SvgChart,
  SkiaChart as _SkiaChart,
} from &#39;@wuba/react-native-echarts&#39;;
import { Dimensions } from &#39;react-native&#39;;

// 注册需要用到的组件
echarts.use([
  DataZoomComponent,
  SVGRenderer,
  BarChart,
  GridComponent,
  LegendComponent,
  ToolboxComponent,
  TooltipComponent,
  TitleComponent,
  PieChart,
  LineChart,
]);

// 图表默认宽高
const CHART_WIDTH = Dimensions.get(&#39;screen&#39;).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, &#39;light&#39;, {
        renderer: &#39;svg&#39;,
        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 &#39;../../components/Chart&#39;;
import { ScrollView, Text, View } from &#39;react-native&#39;;
import { StatusBar } from &#39;expo-status-bar&#39;;
import { useCallback, useEffect, useState } from &#39;react&#39;;
import {
  defaultActual,
  lineOption,
  salesStatus,
  salesVolume,
  userAnaly,
  getLineData,
} from &#39;./contants&#39;;
import styles from &#39;./styles&#39;;
// 开启图表loading
const showChartLoading = (chart) =>
  chart.showLoading(&#39;default&#39;, {
    maskColor: &#39;#305d9e&#39;,
  });
// 关闭图表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 = [
    [&#39;订单走势&#39;, lineOption, onInitLineChart],
    [&#39;用户统计&#39;, userAnaly, onInitUserChart],
    [&#39;各品类销售统计&#39;, salesVolume, onInitSaleChart],
    [&#39;订单状态统计&#39;, salesStatus, onInitStatusChart],
  ];

  return (
    <ScrollView style={styles.index}>
      <StatusBar style=&#39;light&#39; />
      <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 Android
Mari kita bincangkan tentang cara menggunakan echarts untuk melukis carta dalam React Native

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

再换 Skia 模式看看

Mari kita bincangkan tentang cara menggunakan echarts untuk melukis carta dalam React Native

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

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

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

总结

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

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

(学习视频分享:vuejs入门教程编程基础视频

Atas ialah kandungan terperinci Mari kita bincangkan tentang cara menggunakan echarts untuk melukis carta dalam React Native. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:juejin.cn. Jika ada pelanggaran, sila hubungi admin@php.cn Padam