项目中有图表模块,首先就想到了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',
},
});