qf-taro-echarts
Version:
为易观千帆taro项目开发,适用于Taro项目的ECharts图表组件
180 lines (162 loc) • 4.95 kB
JavaScript
import Taro from '@tarojs/taro'
import { View, Canvas } from '@tarojs/components'
import PropTypes from 'prop-types'
import _isEqual from 'lodash/isEqual.js'
import Nerv from 'nervjs'
import * as echarts from '../ec-canvas/echarts'
let Taro_ = Taro
if (process.env.TARO_ENV === 'h5') {
Taro_ = require('@tarojs/taro-h5').default
}
const commonFunc = (_this, chart) => {
const { option, loading, loadingConf } = _this.props
_this.beforeSetOption()
_this.chartInstance = chart
if (loading) {
_this.chartInstance.showLoading('default', loadingConf)
} else {
_this.chartInstance.setOption(option)
}
}
const initChart = ((type) => {
switch (type) {
case 'h5':
return (_this) => {
let chart = echarts.init(_this.chartRef.vnode.dom)
commonFunc(_this, chart)
}
case 'tt':
return (_this) => {
if (_this.chartRef) {
_this.chartRef.init((canvas, width, height, dpr) => {
const chart = echarts.init(canvas, null, {
width: width,
height: height,
devicePixelRatio: dpr
})
canvas.setChart(chart)
commonFunc(_this, chart)
return chart
})
}
}
default:
return (_this) => {
_this.chartRef.init((canvas, width, height, dpr) => {
const chart = echarts.init(canvas, null, {
width: width,
height: height,
devicePixelRatio: dpr
})
canvas.setChart(chart)
commonFunc(_this, chart)
return chart
})
}
}
})(process.env.TARO_ENV)
export default class Chart extends Taro_.Component {
config = {
component: true,
usingComponents: {
'ec-canvas': '../ec-canvas/ec-canvas'
}
}
componentDidMount() {
if (this.chartRef._single) {
console.warn('找不init重新请求')
this.setChartRef()
setTimeout(() => {
initChart(this)
}, 1200);
} else {
initChart(this)
}
}
componentWillReceiveProps(nextProps) {
const { option: newOption } = nextProps
console.warn('this.props.loading=====>',this.props.loading)
if (!_isEqual(nextProps, this.props)) {
this.refreshChart(newOption)
}
}
shouldComponentUpdate(nextProps) {
return !_isEqual(this.props, nextProps)
}
componentWillUnmount() {
// 销毁时
console.warn('销毁时清空chartRef')
this.setState({
chartRef: { _unmount_: true }
})
}
refreshChart = (newOption) => {
const { option, loading, loadingConf } = this.props
console.log('refreshChart',newOption,this.chartInstance)
if (this.chartInstance) {
if (loading) {
this.chartInstance.showLoading('default', loadingConf)
} else {
this.chartInstance.hideLoading()
this.chartInstance.setOption(newOption || option, true)
}
}
}
beforeSetOption = () => {
const { onBeforeSetOption } = this.props
onBeforeSetOption && onBeforeSetOption(echarts)
}
setChartRef = node => {
this.chartRef = node
console.warn('chartRef========>', this.chartRef)
}
getImagePath = () => {
const { chartRef } = this
console.warn('chartRef========>',chartRef)
if (process.env.TARO_ENV === 'h5') throw '该方法只在微信小程序上支持'
// if (process.env.TARO_ENV !== 'weapp') throw '该方法只在微信小程序上支持'
if (!chartRef || !chartRef.canvasToTempFilePath) {
throw 'getImagePath error'
}
return new Promise((resolve, reject) => {
chartRef.canvasToTempFilePath({
success: ({ tempFilePath }) => resolve(tempFilePath),
fail: () => reject('getImagePath fail')
})
})
}
render() {
const { canvasId, width, height, customStyle, loading, loadingConf } = this.props
let chartContainerStyle = `${customStyle}width:${width};height:${height};`
return (
<View style={chartContainerStyle}>
{
{
'h5': <View id={canvasId} ref={this.setChartRef} style={`width:${width};height:${height};`} />,
'weapp': <ec-canvas canvasId={canvasId} ref={this.setChartRef} ec={{ lazyLoad: false }} echeight={height} />,
'tt': <ec-canvas canvasId={canvasId} ref={this.setChartRef} ec={{ lazyLoad: false }} echeight={height} />,
'alipay': <ec-canvas canvasId={canvasId} ref={this.setChartRef} ec={{ lazyLoad: false }} />
}[process.env.TARO_ENV]
}
</View>
)
}
}
Chart.propTypes = {
canvasId: PropTypes.string,
width: PropTypes.string,
height: PropTypes.string,
customStyle: PropTypes.string,
loading: PropTypes.bool,
loadingConf: PropTypes.object,
option: PropTypes.object.isRequired,
onBeforeSetOption: PropTypes.func
}
Chart.defaultProps = {
width: '100%',
height: '200px',
customStyle: '',
loading: null,
loadingConf: null,
onBeforeSetOption: null
}