d2recharts
Version:
data driven react components of echarts
166 lines (153 loc) • 4.55 kB
JavaScript
;
/**
* d2recharts module
* @module d2recharts
* @see module:index
* @see https://github.com/hustcc/echarts-for-react/blob/master/src/echarts-for-react.js
*/
const React = require('react');
const echarts = require('echarts');
const elementResizeEvent = require('element-resize-event');
const _ = require('lodash');
import update from 'immutability-helper';
const propTypes = require('./prop-types');
const util = require('../util/index');
class Recharts extends React.Component {
componentDidMount() {
setTimeout(() => {
// first add
const me = this;
const echartObj = me.renderEchartDom();
const props = me.props;
const onEvents = props.onEvents || [];
_.forIn(onEvents, (eventFunc, eventName) => {
// ignore the event config which not satisfy
if (_.isString(eventName) && _.isFunction(eventFunc)) {
// binding event
echartObj.on(eventName, (param) => {
eventFunc(param, me, echartObj);
});
}
});
// on chart ready
if (_.isFunction(props.onChartReady)) {
props.onChartReady(me, echartObj);
}
// on resize
elementResizeEvent(me.wrapper, () => {
echartObj.resize();
});
if (window.navigator.userAgent.indexOf('Mobile') > -1) {
// 解决移动端滚动时,tootips 不消失的问题
document.body.onscroll = _.debounce(() => {
echartObj.dispatchAction({
type: 'hideTip'
})
}, 200);
}
}, 0);
}
componentDidUpdate(prevProps) {
// update
if (JSON.stringify(prevProps) !== JSON.stringify(this.props)) {
this.renderEchartDom();
}
}
componentWillUnmount() {
// remove
echarts.dispose(this.wrapper);
}
getEchartsInstance() {
// return the echart object
const me = this;
const props = me.props;
const option = props.option;
const theme = props.theme || option.theme;
return echarts.getInstanceByDom(me.wrapper) || echarts.init(me.wrapper, theme);
}
renderEchartDom() {
const me = this;
// render the dom
// init the echart object
let props = this.props;
const echartObj = me.getEchartsInstance();
/*
try {
// TODO 容错
echartObj.resize();
} catch (e) {
console.log('echartObj.resize fail');
}
*/
if (this.props.option.dataZoom) {
const h = echartObj.getHeight();
props = update(this.props, {
option: {
dataZoom: {
$set: _.map(this.props.option.dataZoom, (opt) => {
let newOpt = _.assign({}, opt);
if (opt.type !== 'inside') {
newOpt.top = h - 20;
newOpt.bottom = 0;
if (this.props.option.series.length === 1) {
// 双轴图datazoom偏移,单轴图时露出右侧端点
newOpt.right = 5;
}
}
return newOpt;
}),
}
}
});
}
if (props.option.xAxis && props.option.xAxis.data && !props.option.dataZoom) {
// different chart has different config, Scatter, Radar, Funnel, Pie, Bar
//
// props = update(props, {
// option: {
// xAxis: {
// axisLabel: {
// $merge: {
// interval: Math.round(props.option.xAxis.data.length / Math.floor(echartObj.getWidth() / 100)),
// }
// }
// }
// }
// });
}
// set the echart option
const option = util.pickExcept(props.option, ['width', 'height']);
echartObj.setOption(option, props.notMerge, props.lazyUpdate);
// set loading mask
if (props.showLoading) {
echartObj.showLoading();
} else {
echartObj.hideLoading();
}
// on chart ready
if (props.option && _.isFunction(props.option.onChartRendered)) {
props.option.onChartRendered(me, echartObj);
}
return echartObj;
}
render() {
const me = this;
const props = me.props;
const style = _.assign({
width: props.option.width || props.width,
height: props.option.height || props.height,
}, props.style);
// for render
return (
<div ref={(wrapper) => me.wrapper = wrapper} className={props.className} style={style}/>
);
}
}
Recharts.propTypes = propTypes.recharts;
Recharts.defaultProps = {
lazyUpdate: true,
notMerge: true,
width: 'auto',
height: '400px',
};
module.exports = Recharts;