0
点赞
收藏
分享

微信扫一扫

react-native 使用 F2实现折线图


前言

最近工作入坑了​​react-native​​​,有实现折线图的需求,使用了阿里的​​antv/f2​​可视化库。

方案介绍:


  • react-native-webview
  • antv/f2

大概思路:

使用​​webview​​加载本地​​html​​文件,通过​​injectJavaScript​​加载​​js​​脚本

步骤

  1. 新建​​f2chart.html​​​,文件较大,文件地址:​​f2chart.html​​

在​​ios​​​中, 将此文件与组件放在同一目录,在​​andirod​​​中,手动将次文件放置在​​android/app/src/main/assets/f2chart.html​​ ,如果没有该文件夹,手动创建一个。

  1. 新建​​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) {
super(props);
this.chart = createRef();
}

// eslint-disable-next-line react/no-deprecated
componentWillReceiveProps(nextProps) {
const { data } = this.props;
if (data !== nextProps.data) {
this.reload();
this.chart.current.injectJavaScript(changeChartData(nextProps));
}
}

update = data => {};

onMessage = event => {
const {
nativeEvent: { data },
} = event;
const { onChange } = this.props;
const tooltip = JSON.parse(data);
onChange(tooltip);
};

reload = () => {
this.chart.current.reload();
};

onLoadEnd = () => {
setTimeout(() => {
this.chart.current.injectJavaScript(renderChart(this.props));
}, 10);
};

render() {
const { data, ...props } = this.props;
return (
<RNWebView
scrollEnabled={false}
javaScriptEnabled
ref={this.chart}
style={styles.webView}
injectedJavaScript={renderChart(this.props)}
source={source}
onLoadEnd={this.onLoadEnd}
originWhitelist={['*']}
onMessage={this.onMessage}
{...props}
/>
);
}
}

const styles = StyleSheet.create({
webView: {
flex: 1,
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.使用

import F2LineChart from 'F2LineChart'

render(){
return(
<View>
<F2LineChart data=[] />
</View>
)
}


举报

相关推荐

0 条评论