這一篇主要會介紹如何在React-Native中使用Echart,以及native-echart的原理,以及組件與表格之間的交互。本文所舉的例子設計echart的tooltip以及dispatchAction,這裏不清楚的朋友請看一下上一篇文章
ReactNative學習筆記七之圖表組件交互(上)html
在一開始打算使用echart的時候,我就選擇的是這個node,可是後來發現不能知足個人要求,因此,就根據他的原理本身修改了一下。
在這裏給一個原做者的github地址:
github.com/somonus/rea…node
若是在React-Native中直接使用echart會出現"undefined is not an object (evaluating 'ua.match')" when importing an incompatible (browser) library.
這個錯誤,這是因爲,Echart不支持ReactNative,可是使用js是能夠的啊,因此,基本思路是,寫一個html的網頁,而後加入echart,而後用ReactNative的Webview組件打開便可。
因此在工程中會有一個tpl.html
。
這時寫一個組件,封裝WebView,打開這個html:react
export default class NativeChart extends React.Component {
constructor(props) {
super(props);
}
componentWillReceiveProps(nextProps) {
if(nextProps.option !== this.props.option) {
this.refs.chart.reload();
}
}
webview: WebView
postMessage = (data) => {
this.webview.postMessage(data)
};
render() {
return (
<View style={{flex: 1, height: this.props.height || 400,}}>
<WebView
ref={chart => this.webview = chart}
scrollEnabled = {false}
onMessage={this.props.onMessage}
injectedJavaScript = {renderChart(this.props)}
style={{
height: this.props.height || 400,
}}
source={require('./tpl.html')}
/>
</View>
);
}
}複製代碼
這裏須要注意,在使用WebView的時候插入了一段js
代碼injectedJavaScript = {renderChart(this.props)}
這段代碼就是爲了渲染表格的:git
export default function renderChart(props) {
const height = props.height || 400;
return `
document.getElementById('main').style.height = "${height}px";
var myChart = echarts.init(document.getElementById('main'));
myChart.setOption(${toString(props.option)});
window.document.addEventListener('message', function (e) {
const message = JSON.parse(e.data);
if (message.command === 'get info') {
myChart.dispatchAction({type: 'showTip', seriesIndex: '1', dataIndex: '1'});
window.postMessage('success');
}
});
`
}複製代碼
也就是咱們將表格參數經過RN傳遞給他的組件,組件在經過js注入的方式傳入網頁當中,實現了echart的展現。github
native-echart在佈局上也不是單單的去使用上面封裝的NativeChart,而是使用再上面又包裹了一層:web
export default class Echart extends Component {
constructor(props) {
super(props);
}
// echart: NativeEchart
postMessage = (data) => {
this.refs.chart.postMessage(data);
};
render() {
return (
<Container width={this.props.width}>
<NativeEchart
ref="chart"
{...this.props} />
</Container>
);
}
}複製代碼
真正使用的是這個Echart,經過上述代碼咱們能夠發現,咱們傳入的width值是沒有意義的,只是被設定爲容器的寬度,並無真正設置到Echart當中,因此,這裏,開發者能夠根據本身的須要進行修改。json
正常來講,你用RN寫一個組件,是不能跟Webview中的組件進行交互的,可是經過RN的Webview進行交互。交互分爲RN->Echart以及Echart->RNreact-native
當RN中有組件想傳遞數據給Echart的時候,好比咱們的界面中有一個按鈕,點擊按鈕,echart會執行showtip的操做:bash
render() {
return (
<View style={styles.container}>
<Echarts
ref="chart"
option={this.state.option}
onMessage = {this.handleMessage}
height={200}/>
<TouchableHighlight onPress={this._onPressButton.bind(this)}>
<View style={styles.button}>
<Text style={styles.buttonText}>Press me!</Text>
</View>
</TouchableHighlight>
</View>
);
}複製代碼
點擊按鈕,執行_onPressButton:echarts
_onPressButton() {
var thiz = this;
const data = {
command: 'get info', // 代表意圖
payload: { // 代表內容
property: 'nickname'
}
}
thiz.refs.chart.postMessage(JSON.stringify(data));
}複製代碼
這裏須要注意一個問題,只有使用了this._onPressButton.bind(this),才能在裏面使用 thiz.refs.chart,若是用this._onPressButton,this表示的再也不是這個類,而是這個方法。
咱們能夠看到,點擊按鈕,實際調用的是Echart類的postMessage方法,發送了一個json過去。
在上面介紹代碼的時候也提到過:
postMessage = (data) => {
this.webview.postMessage(data)
};複製代碼
會調用到上述方法,把json傳遞給webview。
這是再看一下js內部:
window.document.addEventListener('message', function (e) {
const message = JSON.parse(e.data);
if (message.command === 'get info') {
myChart.dispatchAction({type: 'showTip', seriesIndex: '1', dataIndex: '1'});
window.postMessage('success');
}
});
有個監聽器,這個監聽器監聽到傳過來的json,進行dispatchAction操做myChart.dispatchAction({type: 'showTip', seriesIndex: '1', dataIndex: '1'});
看到上面一段代碼,能夠發現,除了dispatchAction還有一個window.postMessage('success');
這是回傳事件,也就是html中想ReactNative發送一個事件,上述代碼假設這是一個字符串success
。
這時咱們須要定義一個接收:
handleMessage = (evt: any) => {
const message = evt.nativeEvent.data
ToastAndroid.show(message, ToastAndroid.LONG)
}複製代碼
假設就是這樣吧。有了這個方法,咱們須要告知Webview:
<WebView
ref={chart => this.webview = chart}
scrollEnabled = {false}
onMessage={this.handleMessage}
injectedJavaScript = {renderChart(this.props)}
style={{
height: this.props.height || 400,
}}
source={require('./tpl.html')}
/>複製代碼
上述代碼中:onMessage={this.handleMessage}
這個就是指定Webview接收事件。
總體的交互到這裏就介紹完了,同時也介紹了一下native-echart的工做原理,須要的朋友也能夠本身進行修改。
以前文章合集:
Android文章合集
iOS文章合集
ReactNative文章合集
若是你也作ReactNative開發,並對ReactNative感興趣,歡迎關注個人公衆號,加入咱們的討論羣: