react native踩坑日记(3):react native使用E charts

项目中有图表模块,首先就想到了E charts,但是想再RN中使用可不仅仅是npm装一下就行了。

另外在介绍一个可以在RN中使用的图表库,因为没有中文文档,我这英语水平就放弃了,如有需要可点击此处查阅

下面讲述一下如何在RN中集成,并使用E charts

第一步

点击此处下载此npm包的zip包,把其中的src文件夹复制出来放到我们自己项目的目录下,放到哪自己定。为什么要这么做呢?

是因为我们需要修改其中的配置文件,通常在我们进行代码管理的时候是不上传node_modules文件夹的,这样我们做的修改仅仅是修改了自己本地的,部署或者他人使用都会重新下载最新的npm包,就造成了我们修改的不起作用,所以直接拷贝出来,放在本地方便修改,也方便使用。大概是这么个意思,如有要深入了解的可自行查阅。

第二步

修改WebView的引入位置,在最新版的RN中移除了WebView组件,未改变WebView的引入位置,就会报如下错误。
在这里插入图片描述
所以我们需要安装另外一个库:react-native-webview,安装命令如下

yarn add  react-native-webview // or
npm i react-native-webview --save

安装完成后,进入/src/components/Echarts/index.js
此src文件夹为上面拷贝出来的,下方所以src文件夹都为这个),
修改其中的WebView引用路径。只拿着一个当作列子,还有另外的WebView引入,同样也修改为如下样子

import {WebView} from 'react-native-webview';
第三步

修改E charts版本,react-native-echarts早在一两年轻就停止了维护,最新版本0.5X使用的E charts版本是3.X,在我使用的过程中发现,与最新版的E charts出入较大,很多API都不能使用,所以如有需要修改掉react-native-echarts引入的E charts文件。

首先我们从E charts官网链接下载最新版本的E charts,可直接点击此处进行跳转,复制其中echarts.min.js中的代码(如果复制不了,可frok到自己的仓库进入编辑后全选复制

然后,进入到src/components/Echarts/echarts.min.js,把原有的内容删除也就是``中间的部分,替换成复制的内容。
在进入到/src/components/Echarts/tpl.html中,替换内容。
替换完成后就可使用最新版的E charts

至此就可以正常使用了,但是使用的过程中可能会遇到一些问题,分享给大家一个链接,可在这篇文章中找到自己遇到的问题,安装大佬的方法修改即可,跳转,也可以复制我修改过的。

下方代码解决了会一直刷新的问题

附上代码
/src/components/Echarts/index.js
import React, {Component} from 'react';
import {View, StyleSheet, Platform} from 'react-native';
import renderChart from './renderChart';
import {WebView} from 'react-native-webview';
import echarts from './echarts.min';

const iosPlatform = Platform.OS === 'ios' ? 'true' : 'false';

export default class App extends Component {
  constructor(props) {
    super(props);
    this.setNewOption = this.setNewOption.bind(this);
  }

  shouldComponentUpdate(nextProps, nextState) {
    const thisProps = this.props || {};
    nextProps = nextProps || {};
    if (Object.keys(thisProps).length !== Object.keys(nextProps).length) {
      return true;
    }
    for (const key in nextProps) {
      if (JSON.stringify(thisProps[key]) != JSON.stringify(nextProps[key])) {
        // console.log('props', key, thisProps[key], nextProps[key])
        return true;
      }
    }
    return false;
  }

  componentWillReceiveProps(nextProps) {
    if (nextProps.option !== this.props.option) {
      this.refs.chart.injectJavaScript(renderChart(nextProps, false));
    }
  }

  setNewOption(option) {
    this.refs.chart.postMessage(JSON.stringify(option));
  }

  render() {
    return (
      <View style={{flex: 1, height: this.props.height || 400}}>
        <WebView
          ref="chart"
          scrollEnabled={false}
          injectedJavaScript={renderChart(this.props, true)}
          style={{
            height: this.props.height || 400,
            backgroundColor: this.props.backgroundColor || 'transparent',
          }}
          scalesPageToFit={Platform.OS !== 'ios'}
          originWhitelist={['*']}
          source={
            iosPlatform === 'true'
              ? require('./tpl.html')
              : {uri: 'file:///android_asset/tpl_1.html'}
          }
          onMessage={(event) =>
            this.props.onPress
              ? this.props.onPress(JSON.parse(event.nativeEvent.data))
              : null
          }
        />
      </View>
    );
  }
}

src/components/Echarts/renderChart.js
import echarts from './echarts.min';
import toString from '../../util/toString';

export default function renderChart(props, isFirst) {
  const height = `${props.height || 400}px`;
  const width = props.width ? `${props.width}px` : 'auto';
  if (isFirst) {
    return `
    document.getElementById('main').style.height = "${height}px";
myChart = echarts.init(document.getElementById('main'));
myChart.setOption(${toString(props.option)});

`;
  } else {
    return `
document.getElementById('main').style.height = "${height}px";
myChart.setOption(${toString(props.option)});

`;
  }
}

在附上一个饼图组件
效果如图:
在这里插入图片描述

import React, {Component} from 'react';
import {StyleSheet, View} from 'react-native';
import OperationHead from './OperationHead';
import Echarts from './src/index';

export default class ReturnReport extends Component {
  render() {
    const option = {
      tooltip: {
        trigger: 'item',
        formatter: '{a} <br/>{b}: {c} ({d}%)',
      },
      legend: {
        icon: 'circle',
        orient: 'vertical',
        right: 50,
        top: 30,
        data: ['销售退货', '销售出库'],
        selectedMode: false,
        formatter: function (name) {
          var index = 0;
          var clientlabels = ['销售退货', '销售出库'];
          var clientcounts = [335, 310];
          clientlabels.forEach(function (value, i) {
            if (value == name) {
              index = i;
            }
          });
          return name + '         ' + clientcounts[index];
        },
      },
      series: [
        {
          name: '退货报表',
          type: 'pie',
          radius: ['60%', '70%'],
          center: ['25%', '40%'],
          avoidLabelOverlap: false,
          label: {
            show: false,
            position: 'center',
            formatter: '{d}%', // 显示百分比,
          },
          emphasis: {
            label: {
              show: true,
              fontSize: '16',
              fontWeight: 'bold',
            },
          },
          labelLine: {
            show: false,
          },
          data: [
            {
              value: 335,
              name: '销售退货',
              label: {show: true, fontSize: '16', fontWeight: 'bold'},
              itemStyle: {
                normal: {
                  color: {
                    type: 'linear',
                    x: 0,
                    y: 0,
                    x2: 0,
                    y2: 1,
                    colorStops: [
                      {
                        offset: 0,
                        color: '#DC0000', // 100% 处的颜色
                      },
                      {
                        offset: 1,
                        color: '#F5B96D', // 0% 处的颜色
                      },
                    ],
                  },
                },
              },
            },
            {
              value: 310,
              name: '销售出库',
              itemStyle: {
                normal: {
                  //颜色渐变
                  color: {
                    type: 'linear',
                    x: 0,
                    y: 0,
                    x2: 0,
                    y2: 1,
                    colorStops: [
                      {
                        offset: 0,
                        color: '#F2EFEF', // 100% 处的颜色
                      },
                      {
                        offset: 1,
                        color: '#FFFFFF', // 0% 处的颜色
                      },
                    ],
                  },
                },
              },
            },
          ],
        },
      ],
    };

    return (
      <View style={styles.ReturnReport}>
        <OperationHead title="退货报表" />
        <Echarts option={option} height={150} />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  ReturnReport: {
    width: 350,
    height: 174,
    backgroundColor: '#fff',
    borderRadius: 5,
    flexDirection: 'column',
    alignItems: 'center',
  },
});

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

琞、小菜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值