UNPKG

san-echarts

Version:
335 lines (325 loc) 10.4 kB
/** * san-echarts * Copyright 2018 Baidu Inc. All rights reserved. * * @file Echarts的 San 组件 * @author kentpan */ import defered from './defered'; let echarts = require('echarts'); let context = window || global; if (!!context && (!context.echarts && !!echarts)) { context.echarts = echarts; } let plugsCache = {}; const echartsEvents = [ 'legendselectchanged', 'legendselected', 'legendunselected', 'datazoom', 'datarangeselected', 'timelinechanged', 'timelineplaychanged', 'restore', 'dataviewchanged', 'magictypechanged', 'geoselectchanged', 'geoselected', 'geounselected', 'pieselectchanged', 'pieselected', 'pieunselected', 'mapselectchanged', 'mapselected', 'mapunselected', 'axisareaselected', 'focusnodeadjacency', 'unfocusnodeadjacency', 'brush', 'brushselected', 'click', 'dblclick', 'mouseover', 'mouseout', 'mousedown', 'mouseup', 'globalout' ]; const echartsInstanceFunctions = [ 'setOption', 'getWidth', 'getHeight', 'getDom', 'getOption', 'resize', 'dispatchAction', 'convertToPixel', 'convertFromPixel', 'containPixel', 'showLoading', 'hideLoading', 'getDataURL', 'getConnectedDataURL', 'appendData', 'clear', 'isDisposed', 'dispose' ]; /** * [dataEmpty 检测echarts组件数据是否为空] * @param {[type]} series [description] * @return {[type]} [description] */ const dataIsEmpty = function (series) { let filterData = []; if (series instanceof Array) { filterData = series.filter(seri => { return !!seri.data.length; }); } return !filterData.length; }; /** * [bindEvents 注册on-xxx echarts事件] * @param {[type]} events [description] * @return {[type]} [description] */ const bindEvents = function (events) { let givenEvents = events && events.name ? [events] : this.data.get('givenEvents'); let chart = this.data.get('echartsInstance'); !!givenEvents.length && givenEvents.forEach(event => { // 检测是否为echarts内置事件 let name = checkEchartsEvents.call(this, event.name); let eventHandeler = args => { return this.fire(name, { event: name, chart: chart, params: args }); }; !!name && chart && (chart.off(name, eventHandeler), chart.on(name, eventHandeler, this)); }); }; /** * [checkEchartsEvents 检测是否为echarts内置事件] * @param {[type]} event [description] * @return {[type]} [description] */ const checkEchartsEvents = function(event) { let pass = null; !!~echartsEvents.indexOf(event) && (pass = event); return pass; }; const resizeHandler = function() { return this.resize(); }; /** * [autoResize 监听窗口resize事件] * @return {[type]} [description] */ const autoResize = function() { context.removeEventListener('resize', resizeHandler.bind(this)); context.addEventListener('resize', resizeHandler.bind(this)); }; const dispatchPlugs = function(next) { let plugs = Object.keys(plugsCache || {}); let promises = []; if (plugs.length) { plugs.map(name => { let plug = plugsCache[name]; let fn = plug.fn.call(this, plug.args); promises.push(fn); }); } defered.when(promises).then(result => { typeof next === 'function' && next.call(this, result); }).catch(err => { console.log(err, next); }); }; /** * [watchCharts 监听组件数据] * @return {[type]} [description] */ const watchCharts = function() { this.watch('data', (option, update) => { this.nextTick(() => { return this.initEcharts(); }); }); this.watch('config.theme', (theme, update) => { if (!theme || (!!update && theme !== update.value)) { return; } if (!!this.data.get('echartsInstance') && !!theme) { this.destroy(); } this.initEcharts(); }); this.watch('config.size', (size, update) => { (!!this.data.get('echartsInstance')) && this.nextTick(this.resize.bind(this)); }); this.watch('fullScreen', (full, update) => { setTimeout(() => { getRect.call(this, true); (!!this.data.get('echartsInstance')) && this.nextTick(this.resize.bind(this)); }, 200); }); this.watch('config.group', this.setGroup); }; /** * [initEcharts 初始化echarts] * @param {[type]} opts [description] * @param {Boolean} notMerge [description] * @return {[type]} [description] */ const initEcharts = function(opts, isMerge = true) { if ( !this.data.get('echarts') || !this.el || !this.data.get('data') ) { return; } let config = this.data.get('config'); if (config) { let option = opts || this.data.get('data') || {}; let theme = this.getTheme(); let chart = this.data.get('echartsInstance') || this.data.get('echarts').init(this.el, theme); if (!option.color) { option.color = this.data.get('chartsColors'); } let isEmpty = dataIsEmpty(this.data.get('data.series')); (!!isEmpty) ? this.nextTick(() => { return this.fire('data-empty', { element: this.el, chart: chart }); }) : chart.setOption(option, !!isMerge); // this.resize(); // 监听window.resize事件 autoResize.call(this); !this.data.get('echartsInstance') && this.data.set('echartsInstance', chart); // 注册echarts事件 bindEvents.call(this); this.nextTick(() => { return this.fire('complete', { element: this.el, chart: chart }); }); } this.hideLoading(); }; export default { template: ` <div class="{{!!config.dataLoaded ? 'echarts-dataLoaded' : ''}}" style="position: relative;min-height: 300px;height:{{config.size.height ? (config.size.height + 'px') : 'auto'}};"> <div class="san-lazyload" s-if="{{!config.dataLoaded}}"/> </div> `, initData() { return { echartsInstance: null, chartsColors: ['#87cefa', '#da70d6', '#32cd32', '#6495ed', '#ff69b4', '#ba55d3', '#cd5c5c', '#ffa500', '#40e0d0', '#1e90ff', '#ff6347', '#7b68ee', '#00fa9a', '#ffd700', '#6699FF', '#ff6666', '#3cb371', '#b8860b', '#30e0e0', '#1AC060', '#009EF5', '#BACF00', '#008A77', '#32CBF6', '#FEE14B', '#ff7f50'], chinaMapUrl: 'http://gallery.echartsjs.com/dep/echarts/map/js/china.js' } }, attached() { let givenEvents = this.givenANode.events; this.data.set('givenEvents', givenEvents); dispatchPlugs.call(this); watchCharts.call(this); this.extendIntanceFunctions(); }, registerPlugs(name, fn, args) { if (!!plugsCache[name]) { return console.error('plug: '+ name +' exists!'); } plugsCache[name] = { name: name, fn: fn, args: args }; console.info('plug: '+ name +' install success!'); }, extendIntanceFunctions() { // 附加echartsInstance Function(除group之外) echartsInstanceFunctions.map(instance => { if (typeof this[instance] !== 'function') { this[instance] = (...args) => { let INSTANCE = this.data.get('echartsInstance'); if (!!INSTANCE && typeof INSTANCE[instance] === 'function') { return INSTANCE[instance](...args); } }; } }); }, initEcharts(options) { if (!this.data.get('echarts') && !!echarts) { this.data.set('echarts', echarts); } if (!!options) { return this.data.set('data', options); } return dispatchPlugs.call(this, () => { this.data.set('config.dataLoaded', true); this.hideLoading(); initEcharts.call(this); }), this; }, showLoading() { this.data.get('echartsInstance') && this.data.get('echartsInstance').showLoading(); return this; }, hideLoading() { this.data.get('echartsInstance') && this.data.get('echartsInstance').hideLoading(); return this; }, getTheme() { return this.data.get('config.theme') || 'default'; }, resize(size) { let chart = this.data.get('echartsInstance'); chart && (!!size ? chart.resize(size) : chart.resize()); return this; }, clear() { (!!this.data.get('echartsInstance.clear')) && this.data.get('echartsInstance').clear(); return this; }, destroy() { context.removeEventListener('resize', resizeHandler.bind(this)); (!!this.data.get('echartsInstance.dispose')) && this.data.get('echartsInstance').dispose(); this.data.set('echartsInstance', null); return this; }, setGroup(group) { return this.connect(group), this; }, connect(group) { if (!!(group instanceof Array)) { group = group.map(chart => chart.chart); } echarts && echarts.connect(group); return this; }, disconnect(group) { echarts && echarts.disConnect(group); return this; }, registerMap(...args) { echarts && echarts.registerMap(...args); return this; }, registerTheme(...args) { echarts && echarts.registerTheme(...args); return this; }, graphic: echarts.graphic, getInstance() { return this.data ? this.data.get('echartsInstance') : null; } };