react-native-echarts在打包时出现的坑
react-native-echarts目前是RN开发中使用echarts图表最好的插件了,用法与Echarts完全一致,默认提供了三个属性:
- option (object): The option for echarts: Documentation。
- width (number): The width of the chart. The default value is the outer container width.
- height (number): The height of the chart. The default value is 400
1.首先是最基本的使用:
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View
} from 'react-native';
import Echarts from 'native-echarts';
export default class app extends Component {
render() {
const option = {
title: {
text: 'ECharts demo'
},
tooltip: {},
legend: {
data:['销量']
},
xAxis: {
data: ["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"]
},
yAxis: {},
series: [{
name: '销量',
type: 'bar',
data: [5, 20, 36, 10, 10, 20]
}]
};
return (
<Echarts option={option} height={300} />
);
}
}
AppRegistry.registerComponent('app', () => app);
当自定义tooltip时,由于react-native-echarts外层包裹了一层WebView,所以在配置项的函数内部不能拿到外部的变量
const deviceW = Dimensions.get('window').width / 750
option.tooltip.formatter = (params) => {
return `<div style="width: ${deviceW*690}px; font-size: ${deviceW*26}px;"></div>` // 此处deviceW并不生效,获取不到外部定义的变量
}
2.改进:
WebView将图表与外界的变量进行了隔离,只能另想他法,多传入一个属性,将外部变量变成可以供内部使用的变量
const deviceW = Dimensions.get('window').width / 750
let chartContext = {
width: deviceW
}
option.tooltip.formatter = (params) => {
return `<div style="width: ${chartContext.width*690}px; font-size: ${chartContext.width*26}px;"></div>` // 此处deviceW并不生效,获取不到外部定义的变量
}
<Echarts option={option} height={300} chartContext={chartContext} />
// 修改react-native-echarts包代码:
// renderChart.js
export default function renderChart(props) {
const height = `${props.height || 400}px`;
const width = props.width ? `${props.width}px` : "auto";
const chartContext = props.chartContext
return `
document.getElementById('main').style.height = "${height}";
document.getElementById('main').style.width = "${width}";
var myChart = echarts.init(document.getElementById('main'));
var chartContext = ${toString(chartContext)};
myChart.setOption(${toString(props.option)});
myChart.on('click', function(params) {
var seen = [];
var paramsString = JSON.stringify(params, function(key, val) {
if (val != null && typeof val == "object") {
if (seen.indexOf(val) >= 0) {
return;
}
seen.push(val);
}
return val;
});
window.postMessage(paramsString);
});
`
}
3.改进:
以上方案解决了配置项拿不到外部变量的问题,看起来很完美,运行代码也没有什么问题,不过,在项目打包时,又出了问题,图表显示不出来了,很诡异
原因:打包时,由于自定义属性是手动加的,打包时转换成了简写,不能被识别
// renderChart.js
var chartContext = ${toString(chartContext)}; 替换为
var g_chartContext = ${toString(chartContext)};
// 使用时,把chartContext 全都替换为g_chartContext 就可以了
option.tooltip.formatter = (params) => {
return `<div style="width: ${g_chartContext.width*690}px; font-size: ${g_chartContext.width*26}px;"></div>` // 此处deviceW并不生效,获取不到外部定义的变量
}
4.终极版:
import resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource'; export default class Assets { static fromModule(moduleId) { return resolveAssetSource(moduleId); } }
import Assets from 'emrn-common/utils/assets' <WebView ref="chart" scrollEnabled={false} injectedJavaScript={renderChart(this.props)} originWhitelist={['*']} style={{ height: this.props.height || 400, backgroundColor: this.props.backgroundColor || 'transparent' }} scalesPageToFit={Platform.OS === 'android'} // source={{ html: tpl, baseUrl: '' }} // source={source} source={{uri: Assets.fromModule(source).uri}} // onMessage={event => this.props.onPress ? this.props.onPress(JSON.parse(event.nativeEvent.data)) : null} />