前言
最近工作入坑了react-native
,有实现折线图的需求,使用了阿里的antv/f2
可视化库。
方案介绍:
- react-native-webview
- antv/f2
大概思路:
使用webview
加载本地html
文件,通过injectJavaScript
加载js
脚本
步骤
- 新建
f2chart.html
,文件较大,文件地址:f2chart.html
在ios
中, 将此文件与组件放在同一目录,在andirod
中,手动将次文件放置在android/app/src/main/assets/f2chart.html
,如果没有该文件夹,手动创建一个。
- 新建
f2Chart
组件import React, { PureComponent, createRef } from 'react'; import { StyleSheet, Platform } from 'react-native'; import { WebView as RNWebView } from 'react-native-webview'; import renderChart, { changeChartData } from './renderChart';
const source = Platform.select({
// eslint-disable-next-line global-require
ios: require('./f2chart.html'),
android: { uri: 'file:///android_asset/f2chart.html' },
});
export default class Chart extends PureComponent {
constructor(props) {
代码语言:txt复制super(props);
代码语言:txt复制this.chart = createRef();
}
// eslint-disable-next-line react/no-deprecated
componentWillReceiveProps(nextProps) {
代码语言:txt复制const { data } = this.props;
代码语言:txt复制if (data !== nextProps.data) {
代码语言:txt复制 this.reload();
代码语言:txt复制 this.chart.current.injectJavaScript(changeChartData(nextProps));
代码语言:txt复制}
}
update = data => {};
onMessage = event => {
代码语言:txt复制const {
代码语言:txt复制 nativeEvent: { data },
代码语言:txt复制} = event;
代码语言:txt复制const { onChange } = this.props;
代码语言:txt复制const tooltip = JSON.parse(data);
代码语言:txt复制onChange(tooltip);
};
reload = () => {
代码语言:txt复制this.chart.current.reload();
};
onLoadEnd = () => {
代码语言:txt复制setTimeout(() => {
代码语言:txt复制 this.chart.current.injectJavaScript(renderChart(this.props));
代码语言:txt复制}, 10);
};
render() {
代码语言:txt复制const { data, ...props } = this.props;
代码语言:txt复制return (
代码语言:txt复制 <RNWebView
代码语言:txt复制 scrollEnabled={false}
代码语言:txt复制 javaScriptEnabled
代码语言:txt复制 ref={this.chart}
代码语言:txt复制 style={styles.webView}
代码语言:txt复制 injectedJavaScript={renderChart(this.props)}
代码语言:txt复制 source={source}
代码语言:txt复制 onLoadEnd={this.onLoadEnd}
代码语言:txt复制 originWhitelist={['*']}
代码语言:txt复制 onMessage={this.onMessage}
代码语言:txt复制 {...props}
代码语言:txt复制 />
代码语言:txt复制);
}
}
const styles = StyleSheet.create({
webView: {
代码语言:txt复制flex: 1,
代码语言:txt复制backgroundColor: 'transparent',
},
});
这里需要注意的是,在最新版本的react-native
中已经将WebView
脱离出来了,所以需要安装react-native-webview
yarn add react-native-webview -S
3.新建renderChart.js
export default function renderChart(props) {
const { data = [] } = props;
const chartData = data.map(c => {
return {
...c,
date: formatChartDate(c.date), // 将时间处理成 2020-03-12 12:00:00 格式
};
})
const lastData = chartData[chartData.length - 1];
const script = `
(function(){
const chart = new F2.Chart({
id: 'chart',
pixelRatio: window.devicePixelRatio,
padding: 'auto',
});
chart.source(${JSON.stringify(chartData)}, {
value: {
tickCount: 5,
min: 0,
ticks: [0, 25, 50, 75, 100],
sortable:false
},
date: {
type: 'timeCat',
range: [0, 1],
tickCount: 3,
}
});
chart.tooltip({
showCrosshairs:true,
crosshairsStyle: {
lineDash: [2]
},
alwaysShow:true,
showItemMarker: false,
background: {
radius: 2,
fill: 'rgb(229,35,97)',
padding: [ 2, 6 ]
},
tooltipMarkerStyle: {
fill: '#5B98FF', // 设置 tooltipMarker 的样式
radius: 4,
lineWidth: 2,
stroke: '#d9e5fc',
},
onShow: function(ev) {
const items = ev.items;
const value = items[0].value;
items[0].name = null;
items[0].value = value>0?' ' value '元' : '0.00';
}
});
chart.axis('value', {
label: function label(text, index, total) {
const textCfg = {
text
};
return textCfg;
}
});
chart.axis('date', {
label: function label(text, index, total) {
const textArr = text.split('-');
const month = textArr[1];
const textCfg = {
color:'#888B9C',
fontSize:'10',
text:textArr[0] '年' parseInt(month) '月'
};
if (index === 0) {
textCfg.textAlign = 'left';
} else if (index === total - 1) {
textCfg.textAlign = 'right';
}
return textCfg;
}
});
chart.line({
sortable: false
}).position('date*value').shape('smooth')
chart.area({
sortable: false
}).position('date*value').shape('smooth')
chart.render();
const item = ${JSON.stringify(lastData)}
const point = chart.getPosition(item);
chart.showTooltip(point);
})();
`;
return script;
}
具体配置可查询官方API
https://f2.antv.vision/zh/docs/api/f2
4.使用
代码语言:txt复制import F2LineChart from 'F2LineChart'
render(){
return(
<View>
<F2LineChart data=[] />
</View>
)
}
关于
- 文章首发于react-native 使用 F2实现折线图