1. 程式人生 > >通過百度echarts實現資料圖表展示功能

通過百度echarts實現資料圖表展示功能

現在我們在工作中,在開發中都會或多或少的用到圖表統計資料顯示給使用者。通過圖表可以很直觀的,直接的將資料呈現出來。這裡我就介紹說一下利用百度開源的echarts圖表技術實現的具體功能。

1、對於不太理解echarts是個怎樣技術的開發者來說,可以到echarts官網進行學習瞭解,官網有詳細的API文件和例項供大家參考學習。

2、以下是我在工作中實現整理出來的例項原始碼:

公用的支援js檔案 echarts.js、echarts.min.js,還有其他的圖表需要支援的js檔案也可以到官網下載

echarts.js

/*!
 * ECharts, a javascript interactive chart library.
 *
 * Copyright (c) 2015, Baidu Inc.
 * All rights reserved.
 *
 * LICENSE
 * https://github.com/ecomfe/echarts/blob/master/LICENSE.txt
 */

/**
 * @module echarts
 */
define(function (require) {

    var GlobalModel = require('./model/Global');
    var ExtensionAPI = require('./ExtensionAPI');
    var CoordinateSystemManager = require('./CoordinateSystem');
    var OptionManager = require('./model/OptionManager');

    var ComponentModel = require('./model/Component');
    var SeriesModel = require('./model/Series');

    var ComponentView = require('./view/Component');
    var ChartView = require('./view/Chart');
    var graphic = require('./util/graphic');

    var zrender = require('zrender');
    var zrUtil = require('zrender/core/util');
    var colorTool = require('zrender/tool/color');
    var env = require('zrender/core/env');
    var Eventful = require('zrender/mixin/Eventful');

    var each = zrUtil.each;

    var VISUAL_CODING_STAGES = ['echarts', 'chart', 'component'];

    // TODO Transform first or filter first
    var PROCESSOR_STAGES = ['transform', 'filter', 'statistic'];

    function createRegisterEventWithLowercaseName(method) {
        return function (eventName, handler, context) {
            // Event name is all lowercase
            eventName = eventName && eventName.toLowerCase();
            Eventful.prototype[method].call(this, eventName, handler, context);
        };
    }
    /**
     * @module echarts~MessageCenter
     */
    function MessageCenter() {
        Eventful.call(this);
    }
    MessageCenter.prototype.on = createRegisterEventWithLowercaseName('on');
    MessageCenter.prototype.off = createRegisterEventWithLowercaseName('off');
    MessageCenter.prototype.one = createRegisterEventWithLowercaseName('one');
    zrUtil.mixin(MessageCenter, Eventful);
    /**
     * @module echarts~ECharts
     */
    function ECharts (dom, theme, opts) {
        opts = opts || {};

        // Get theme by name
        if (typeof theme === 'string') {
            theme = themeStorage[theme];
        }

        if (theme) {
            each(optionPreprocessorFuncs, function (preProcess) {
                preProcess(theme);
            });
        }
        /**
         * @type {string}
         */
        this.id;
        /**
         * Group id
         * @type {string}
         */
        this.group;
        /**
         * @type {HTMLDomElement}
         * @private
         */
        this._dom = dom;
        /**
         * @type {module:zrender/ZRender}
         * @private
         */
        this._zr = zrender.init(dom, {
            renderer: opts.renderer || 'canvas',
            devicePixelRatio: opts.devicePixelRatio
        });

        /**
         * @type {Object}
         * @private
         */
        this._theme = zrUtil.clone(theme);

        /**
         * @type {Array.<module:echarts/view/Chart>}
         * @private
         */
        this._chartsViews = [];

        /**
         * @type {Object.<string, module:echarts/view/Chart>}
         * @private
         */
        this._chartsMap = {};

        /**
         * @type {Array.<module:echarts/view/Component>}
         * @private
         */
        this._componentsViews = [];

        /**
         * @type {Object.<string, module:echarts/view/Component>}
         * @private
         */
        this._componentsMap = {};

        /**
         * @type {module:echarts/ExtensionAPI}
         * @private
         */
        this._api = new ExtensionAPI(this);

        /**
         * @type {module:echarts/CoordinateSystem}
         * @private
         */
        this._coordSysMgr = new CoordinateSystemManager();

        Eventful.call(this);

        /**
         * @type {module:echarts~MessageCenter}
         * @private
         */
        this._messageCenter = new MessageCenter();

        // Init mouse events
        this._initEvents();

        // In case some people write `window.onresize = chart.resize`
        this.resize = zrUtil.bind(this.resize, this);
    }

    var echartsProto = ECharts.prototype;

    /**
     * @return {HTMLDomElement}
     */
    echartsProto.getDom = function () {
        return this._dom;
    };

    /**
     * @return {module:zrender~ZRender}
     */
    echartsProto.getZr = function () {
        return this._zr;
    };

    /**
     * @param {Object} option
     * @param {boolean} notMerge
     * @param {boolean} [notRefreshImmediately=false] Useful when setOption frequently.
     */
    echartsProto.setOption = function (option, notMerge, notRefreshImmediately) {
        if (!this._model || notMerge) {
            this._model = new GlobalModel(
                null, null, this._theme, new OptionManager(this._api)
            );
        }

        this._model.setOption(option, optionPreprocessorFuncs);

        updateMethods.prepareAndUpdate.call(this);

        !notRefreshImmediately && this._zr.refreshImmediately();
    };

    /**
     * @DEPRECATED
     */
    echartsProto.setTheme = function () {
        console.log('ECharts#setTheme() is DEPRECATED in ECharts 3.0');
    };

    /**
     * @return {module:echarts/model/Global}
     */
    echartsProto.getModel = function () {
        return this._model;
    };

    /**
     * @return {Object}
     */
    echartsProto.getOption = function () {
        return this._model.getOption();
    };

    /**
     * @return {number}
     */
    echartsProto.getWidth = function () {
        return this._zr.getWidth();
    };

    /**
     * @return {number}
     */
    echartsProto.getHeight = function () {
        return this._zr.getHeight();
    };

    /**
     * Get canvas which has all thing rendered
     * @param {Object} opts
     * @param {string} [opts.backgroundColor]
     */
    echartsProto.getRenderedCanvas = function (opts) {
        if (!env.canvasSupported) {
            return;
        }
        opts = opts || {};
        opts.pixelRatio = opts.pixelRatio || 1;
        opts.backgroundColor = opts.backgroundColor
            || this._model.get('backgroundColor');
        var zr = this._zr;
        var list = zr.storage.getDisplayList();
        // Stop animations
        zrUtil.each(list, function (el) {
            el.stopAnimation(true);
        });
        return zr.painter.getRenderedCanvas(opts);
    };
    /**
     * @return {string}
     * @param {Object} opts
     * @param {string} [opts.type='png']
     * @param {string} [opts.pixelRatio=1]
     * @param {string} [opts.backgroundColor]
     */
    echartsProto.getDataURL = function (opts) {
        opts = opts || {};
        var excludeComponents = opts.excludeComponents;
        var ecModel = this._model;
        var excludesComponentViews = [];
        var self = this;

        each(excludeComponents, function (componentType) {
            ecModel.eachComponent({
                mainType: componentType
            }, function (component) {
                var view = self._componentsMap[component.__viewId];
                if (!view.group.ignore) {
                    excludesComponentViews.push(view);
                    view.group.ignore = true;
                }
            });
        });

        var url = this.getRenderedCanvas(opts).toDataURL(
            'image/' + (opts && opts.type || 'png')
        );

        each(excludesComponentViews, function (view) {
            view.group.ignore = false;
        });
        return url;
    };


    /**
     * @return {string}
     * @param {Object} opts
     * @param {string} [opts.type='png']
     * @param {string} [opts.pixelRatio=1]
     * @param {string} [opts.backgroundColor]
     */
    echartsProto.getConnectedDataURL = function (opts) {
        if (!env.canvasSupported) {
            return;
        }
        var groupId = this.group;
        var mathMin = Math.min;
        var mathMax = Math.max;
        var MAX_NUMBER = Infinity;
        if (connectedGroups[groupId]) {
            var left = MAX_NUMBER;
            var top = MAX_NUMBER;
            var right = -MAX_NUMBER;
            var bottom = -MAX_NUMBER;
            var canvasList = [];
            var dpr = (opts && opts.pixelRatio) || 1;
            for (var id in instances) {
                var chart = instances[id];
                if (chart.group === groupId) {
                    var canvas = chart.getRenderedCanvas(
                        zrUtil.clone(opts)
                    );
                    var boundingRect = chart.getDom().getBoundingClientRect();
                    left = mathMin(boundingRect.left, left);
                    top = mathMin(boundingRect.top, top);
                    right = mathMax(boundingRect.right, right);
                    bottom = mathMax(boundingRect.bottom, bottom);
                    canvasList.push({
                        dom: canvas,
                        left: boundingRect.left,
                        top: boundingRect.top
                    });
                }
            }

            left *= dpr;
            top *= dpr;
            right *= dpr;
            bottom *= dpr;
            var width = right - left;
            var height = bottom - top;
            var targetCanvas = zrUtil.createCanvas();
            targetCanvas.width = width;
            targetCanvas.height = height;
            var zr = zrender.init(targetCanvas);

            each(canvasList, function (item) {
                var img = new graphic.Image({
                    style: {
                        x: item.left * dpr - left,
                        y: item.top * dpr - top,
                        image: item.dom
                    }
                });
                zr.add(img);
            });
            zr.refreshImmediately();

            return targetCanvas.toDataURL('image/' + (opts && opts.type || 'png'));
        }
        else {
            return this.getDataURL(opts);
        }
    };

    var updateMethods = {

        /**
         * @param {Object} payload
         * @private
         */
        update: function (payload) {
            // console.time && console.time('update');

            var ecModel = this._model;
            var api = this._api;
            var coordSysMgr = this._coordSysMgr;
            // update before setOption
            if (!ecModel) {
                return;
            }

            // Fixme First time update ?
            ecModel.restoreData();

            // TODO
            // Save total ecModel here for undo/redo (after restoring data and before processing data).
            // Undo (restoration of total ecModel) can be carried out in 'action' or outside API call.

            // Create new coordinate system each update
            // In LineView may save the old coordinate system and use it to get the orignal point
            coordSysMgr.create(this._model, this._api);

            processData.call(this, ecModel, api);

            stackSeriesData.call(this, ecModel);

            coordSysMgr.update(ecModel, api);

            doLayout.call(this, ecModel, payload);

            doVisualCoding.call(this, ecModel, payload);

            doRender.call(this, ecModel, payload);

            // Set background
            var backgroundColor = ecModel.get('backgroundColor') || 'transparent';

            var painter = this._zr.painter;
            // TODO all use clearColor ?
            if (painter.isSingleCanvas && painter.isSingleCanvas()) {
                this._zr.configLayer(0, {
                    clearColor: backgroundColor
                });
            }
            else {
                // In IE8
                if (!env.canvasSupported) {
                    var colorArr = colorTool.parse(backgroundColor);
                    backgroundColor = colorTool.stringify(colorArr, 'rgb');
                    if (colorArr[3] === 0) {
                        backgroundColor = 'transparent';
                    }
                }
                backgroundColor = backgroundColor;
                this._dom.style.backgroundColor = backgroundColor;
            }

            // console.time && console.timeEnd('update');
        },

        // PENDING
        /**
         * @param {Object} payload
         * @private
         */
        updateView: function (payload) {
            var ecModel = this._model;

            // update before setOption
            if (!ecModel) {
                return;
            }

            doLayout.call(this, ecModel, payload);

            doVisualCoding.call(this, ecModel, payload);

            invokeUpdateMethod.call(this, 'updateView', ecModel, payload);
        },

        /**
         * @param {Object} payload
         * @private
         */
        updateVisual: function (payload) {
            var ecModel = this._model;

            // update before setOption
            if (!ecModel) {
                return;
            }

            doVisualCoding.call(this, ecModel, payload);

            invokeUpdateMethod.call(this, 'updateVisual', ecModel, payload);
        },

        /**
         * @param {Object} payload
         * @private
         */
        updateLayout: function (payload) {
            var ecModel = this._model;

            // update before setOption
            if (!ecModel) {
                return;
            }

            doLayout.call(this, ecModel, payload);

            invokeUpdateMethod.call(this, 'updateLayout', ecModel, payload);
        },

        /**
         * @param {Object} payload
         * @private
         */
        highlight: function (payload) {
            toggleHighlight.call(this, 'highlight', payload);
        },

        /**
         * @param {Object} payload
         * @private
         */
        downplay: function (payload) {
            toggleHighlight.call(this, 'downplay', payload);
        },

        /**
         * @param {Object} payload
         * @private
         */
        prepareAndUpdate: function (payload) {
            var ecModel = this._model;

            prepareView.call(this, 'component', ecModel);

            prepareView.call(this, 'chart', ecModel);

            updateMethods.update.call(this, payload);
        }
    };

    /**
     * @param {Object} payload
     * @private
     */
    function toggleHighlight(method, payload) {
        var ecModel = this._model;

        // dispatchAction before setOption
        if (!ecModel) {
            return;
        }

        ecModel.eachComponent(
            {mainType: 'series', query: payload},
            function (seriesModel, index) {
                var chartView = this._chartsMap[seriesModel.__viewId];
                if (chartView && chartView.__alive) {
                    chartView[method](
                        seriesModel, ecModel, this._api, payload
                    );
                }
            },
            this
        );
    }

    /**
     * Resize the chart
     */
    echartsProto.resize = function () {
        this._zr.resize();

        var optionChanged = this._model && this._model.resetOption('media');
        updateMethods[optionChanged ? 'prepareAndUpdate' : 'update'].call(this);

        // Resize loading effect
        this._loadingFX && this._loadingFX.resize();
    };

    var defaultLoadingEffect = require('./loading/default');
    /**
     * Show loading effect
     * @param  {string} [name='default']
     * @param  {Object} [cfg]
     */
    echartsProto.showLoading = function (name, cfg) {
        if (zrUtil.isObject(name)) {
            cfg = name;
            name = 'default';
        }
        this.hideLoading();
        var el = defaultLoadingEffect(this._api, cfg);
        var zr = this._zr;
        this._loadingFX = el;

        zr.add(el);
    };

    /**
     * Hide loading effect
     */
    echartsProto.hideLoading = function () {
        this._loadingFX && this._zr.remove(this._loadingFX);
        this._loadingFX = null;
    };

    /**
     * @param {Object} eventObj
     * @return {Object}
     */
    echartsProto.makeActionFromEvent = function (eventObj) {
        var payload = zrUtil.extend({}, eventObj);
        payload.type = eventActionMap[eventObj.type];
        return payload;
    };

    /**
     * @pubilc
     * @param {Object} payload
     * @param {string} [payload.type] Action type
     * @param {boolean} [silent=false] Whether trigger event.
     */
    echartsProto.dispatchAction = function (payload, silent) {
        var actionWrap = actions[payload.type];
        if (actionWrap) {
            var actionInfo = actionWrap.actionInfo;
            var updateMethod = actionInfo.update || 'update';

            var payloads = [payload];
            var batched = false;
            // Batch action
            if (payload.batch) {
                batched = true;
                payloads = zrUtil.map(payload.batch, function (item) {
                    item = zrUtil.defaults(zrUtil.extend({}, item), payload);
                    item.batch = null;
                    return item;
                });
            }

            var eventObjBatch = [];
            var eventObj;
            var isHighlightOrDownplay = payload.type === 'highlight' || payload.type === 'downplay';
            for (var i = 0; i < payloads.length; i++) {
                var batchItem = payloads[i];
                // Action can specify the event by return it.
                eventObj = actionWrap.action(batchItem, this._model);
                // Emit event outside
                eventObj = eventObj || zrUtil.extend({}, batchItem);
                // Convert type to eventType
                eventObj.type = actionInfo.event || eventObj.type;
                eventObjBatch.push(eventObj);

                // Highlight and downplay are special.
                isHighlightOrDownplay && updateMethods[updateMethod].call(this, batchItem);
            }

            (updateMethod !== 'none' && !isHighlightOrDownplay)
                && updateMethods[updateMethod].call(this, payload);

            if (!silent) {
                // Follow the rule of action batch
                if (batched) {
                    eventObj = {
                        type: actionInfo.event || payload.type,
                        batch: eventObjBatch
                    };
                }
                else {
                    eventObj = eventObjBatch[0];
                }
                this._messageCenter.trigger(eventObj.type, eventObj);
            }
        }
    };

    /**
     * Register event
     * @method
     */
    echartsProto.on = createRegisterEventWithLowercaseName('on');
    echartsProto.off = createRegisterEventWithLowercaseName('off');
    echartsProto.one = createRegisterEventWithLowercaseName('one');

    /**
     * @param {string} methodName
     * @private
     */
    function invokeUpdateMethod(methodName, ecModel, payload) {
        var api = this._api;

        // Update all components
        each(this._componentsViews, function (component) {
            var componentModel = component.__model;
            component[methodName](componentModel, ecModel, api, payload);

            updateZ(componentModel, component);
        }, this);

        // Upate all charts
        ecModel.eachSeries(function (seriesModel, idx) {
            var chart = this._chartsMap[seriesModel.__viewId];
            chart[methodName](seriesModel, ecModel, api, payload);

            updateZ(seriesModel, chart);
        }, this);

    }

    /**
     * Prepare view instances of charts and components
     * @param  {module:echarts/model/Global} ecModel
     * @private
     */
    function prepareView(type, ecModel) {
        var isComponent = type === 'component';
        var viewList = isComponent ? this._componentsViews : this._chartsViews;
        var viewMap = isComponent ? this._componentsMap : this._chartsMap;
        var zr = this._zr;

        for (var i = 0; i < viewList.length; i++) {
            viewList[i].__alive = false;
        }

        ecModel[isComponent ? 'eachComponent' : 'eachSeries'](function (componentType, model) {
            if (isComponent) {
                if (componentType === 'series') {
                    return;
                }
            }
            else {
                model = componentType;
            }

            // Consider: id same and type changed.
            var viewId = model.id + '_' + model.type;
            var view = viewMap[viewId];
            if (!view) {
                var classType = ComponentModel.parseClassType(model.type);
                var Clazz = isComponent
                    ? ComponentView.getClass(classType.main, classType.sub)
                    : ChartView.getClass(classType.sub);
                if (Clazz) {
                    view = new Clazz();
                    view.init(ecModel, this._api);
                    viewMap[viewId] = view;
                    viewList.push(view);
                    zr.add(view.group);
                }
                else {
                    // Error
                    return;
                }
            }

            model.__viewId = viewId;
            view.__alive = true;
            view.__id = viewId;
            view.__model = model;
        }, this);

        for (var i = 0; i < viewList.length;) {
            var view = viewList[i];
            if (!view.__alive) {
                zr.remove(view.group);
                view.dispose(ecModel, this._api);
                viewList.splice(i, 1);
                delete viewMap[view.__id];
            }
            else {
                i++;
            }
        }
    }

    /**
     * Processor data in each series
     *
     * @param {module:echarts/model/Global} ecModel
     * @private
     */
    function processData(ecModel, api) {
        each(PROCESSOR_STAGES, function (stage) {
            each(dataProcessorFuncs[stage] || [], function (process) {
                process(ecModel, api);
            });
        });
    }

    /**
     * @private
     */
    function stackSeriesData(ecModel) {
        var stackedDataMap = {};
        ecModel.eachSeries(function (series) {
            var stack = series.get('stack');
            var data = series.getData();
            if (stack && data.type === 'list') {
                var previousStack = stackedDataMap[stack];
                if (previousStack) {
                    data.stackedOn = previousStack;
                }
                stackedDataMap[stack] = data;
            }
        });
    }

    /**
     * Layout before each chart render there series, after visual coding and data processing
     *
     * @param {module:echarts/model/Global} ecModel
     * @private
     */
    function doLayout(ecModel, payload) {
        var api = this._api;
        each(layoutFuncs, function (layout) {
            layout(ecModel, api, payload);
        });
    }

    /**
     * Code visual infomation from data after data processing
     *
     * @param {module:echarts/model/Global} ecModel
     * @private
     */
    function doVisualCoding(ecModel, payload) {
        each(VISUAL_CODING_STAGES, function (stage) {
            each(visualCodingFuncs[stage] || [], function (visualCoding) {
                visualCoding(ecModel, payload);
            });
        });
    }

    /**
     * Render each chart and component
     * @private
     */
    function doRender(ecModel, payload) {
        var api = this._api;
        // Render all components
        each(this._componentsViews, function (componentView) {
            var componentModel = componentView.__model;
            componentView.render(componentModel, ecModel, api, payload);

            updateZ(componentModel, componentView);
        }, this);

        each(this._chartsViews, function (chart) {
            chart.__alive = false;
        }, this);

        // Render all charts
        ecModel.eachSeries(function (seriesModel, idx) {
            var chartView = this._chartsMap[seriesModel.__viewId];
            chartView.__alive = true;
            chartView.render(seriesModel, ecModel, api, payload);

            chartView.group.silent = !!seriesModel.get('silent');

            updateZ(seriesModel, chartView);
        }, this);

        // Remove groups of unrendered charts
        each(this._chartsViews, function (chart) {
            if (!chart.__alive) {
                chart.remove(ecModel, api);
            }
        }, this);
    }

    var MOUSE_EVENT_NAMES = [
        'click', 'dblclick', 'mouseover', 'mouseout', 'mousedown', 'mouseup', 'globalout'
    ];
    /**
     * @private
     */
    echartsProto._initEvents = function () {
        each(MOUSE_EVENT_NAMES, function (eveName) {
            this._zr.on(eveName, function (e) {
                var ecModel = this.getModel();
                var el = e.target;
                if (el && el.dataIndex != null) {
                    var dataModel = el.dataModel || ecModel.getSeriesByIndex(el.seriesIndex);
                    var params = dataModel && dataModel.getDataParams(el.dataIndex, el.dataType) || {};
                    params.event = e;
                    params.type = eveName;
                    this.trigger(eveName, params);
                }
                // If element has custom eventData of components
                else if (el && el.eventData) {
                    this.trigger(eveName, el.eventData);
                }
            }, this);
        }, this);

        each(eventActionMap, function (actionType, eventType) {
            this._messageCenter.on(eventType, function (event) {
                this.trigger(eventType, event);
            }, this);
        }, this);
    };

    /**
     * @return {boolean}
     */
    echartsProto.isDisposed = function () {
        return this._disposed;
    };

    /**
     * Clear
     */
    echartsProto.clear = function () {
        this.setOption({}, true);
    };
    /**
     * Dispose instance
     */
    echartsProto.dispose = function () {
        this._disposed = true;
        var api = this._api;
        var ecModel = this._model;

        each(this._componentsViews, function (component) {
            component.dispose(ecModel, api);
        });
        each(this._chartsViews, function (chart) {
            chart.dispose(ecModel, api);
        });

        this._zr.dispose();

        delete instances[this.id];
    };

    zrUtil.mixin(ECharts, Eventful);

    /**
     * @param {module:echarts/model/Series|module:echarts/model/Component} model
     * @param {module:echarts/view/Component|module:echarts/view/Chart} view
     * @return {string}
     */
    function updateZ(model, view) {
        var z = model.get('z');
        var zlevel = model.get('zlevel');
        // Set z and zlevel
        view.group.traverse(function (el) {
            z != null && (el.z = z);
            zlevel != null && (el.zlevel = zlevel);
        });
    }
    /**
     * @type {Array.<Function>}
     * @inner
     */
    var actions = [];

    /**
     * Map eventType to actionType
     * @type {Object}
     */
    var eventActionMap = {};

    /**
     * @type {Array.<Function>}
     * @inner
     */
    var layoutFuncs = [];

    /**
     * Data processor functions of each stage
     * @type {Array.<Object.<string, Function>>}
     * @inner
     */
    var dataProcessorFuncs = {};

    /**
     * @type {Array.<Function>}
     * @inner
     */
    var optionPreprocessorFuncs = [];

    /**
     * Visual coding functions of each stage
     * @type {Array.<Object.<string, Function>>}
     * @inner
     */
    var visualCodingFuncs = {};
    /**
     * Theme storage
     * @type {Object.<key, Object>}
     */
    var themeStorage = {};


    var instances = {};
    var connectedGroups = {};

    var idBase = new Date() - 0;
    var groupIdBase = new Date() - 0;
    var DOM_ATTRIBUTE_KEY = '_echarts_instance_';
    /**
     * @alias module:echarts
     */
    var echarts = {
        /**
         * @type {number}
         */
        version: '3.1.10',
        dependencies: {
            zrender: '3.1.0'
        }
    };

    function enableConnect(chart) {

        var STATUS_PENDING = 0;
        var STATUS_UPDATING = 1;
        var STATUS_UPDATED = 2;
        var STATUS_KEY = '__connectUpdateStatus';
        function updateConnectedChartsStatus(charts, status) {
            for (var i = 0; i < charts.length; i++) {
                var otherChart = charts[i];
                otherChart[STATUS_KEY] = status;
            }
        }
        zrUtil.each(eventActionMap, function (actionType, eventType) {
            chart._messageCenter.on(eventType, function (event) {
                if (connectedGroups[chart.group] && chart[STATUS_KEY] !== STATUS_PENDING) {
                    var action = chart.makeActionFromEvent(event);
                    var otherCharts = [];
                    for (var id in instances) {
                        var otherChart = instances[id];
                        if (otherChart !== chart && otherChart.group === chart.group) {
                            otherCharts.push(otherChart);
                        }
                    }
                    updateConnectedChartsStatus(otherCharts, STATUS_PENDING);
                    each(otherCharts, function (otherChart) {
                        if (otherChart[STATUS_KEY] !== STATUS_UPDATING) {
                            otherChart.dispatchAction(action);
                        }
                    });
                    updateConnectedChartsStatus(otherCharts, STATUS_UPDATED);
                }
            });
        });

    }
    /**
     * @param {HTMLDomElement} dom
     * @param {Object} [theme]
     * @param {Object} opts
     */
    echarts.init = function (dom, theme, opts) {
        // Check version
        if ((zrender.version.replace('.', '') - 0) < (echarts.dependencies.zrender.replace('.', '') - 0)) {
            throw new Error(
                'ZRender ' + zrender.version
                + ' is too old for ECharts ' + echarts.version
                + '. Current version need ZRender '
                + echarts.dependencies.zrender + '+'
            );
        }
        if (!dom) {
            throw new Error('Initialize failed: invalid dom.');
        }

        var chart = new ECharts(dom, theme, opts);
        chart.id = 'ec_' + idBase++;
        instances[chart.id] = chart;

        dom.setAttribute &&
            dom.setAttribute(DOM_ATTRIBUTE_KEY, chart.id);

        enableConnect(chart);

        return chart;
    };

    /**
     * @return {string|Array.<module:echarts~ECharts>} groupId
     */
    echarts.connect = function (groupId) {
        // Is array of charts
        if (zrUtil.isArray(groupId)) {
            var charts = groupId;
            groupId = null;
            // If any chart has group
            zrUtil.each(charts, function (chart) {
                if (chart.group != null) {
                    groupId = chart.group;
                }
            });
            groupId = groupId || ('g_' + groupIdBase++);
            zrUtil.each(charts, function (chart) {
                chart.group = groupId;
            });
        }
        connectedGroups[groupId] = true;
        return groupId;
    };

    /**
     * @return {string} groupId
     */
    echarts.disConnect = function (groupId) {
        connectedGroups[groupId] = false;
    };

    /**
     * Dispose a chart instance
     * @param  {module:echarts~ECharts|HTMLDomElement|string} chart
     */
    echarts.dispose = function (chart) {
        if (zrUtil.isDom(chart)) {
            chart = echarts.getInstanceByDom(chart);
        }
        else if (typeof chart === 'string') {
            chart = instances[chart];
        }
        if ((chart instanceof ECharts) && !chart.isDisposed()) {
            chart.dispose();
        }
    };

    /**
     * @param  {HTMLDomElement} dom
     * @return {echarts~ECharts}
     */
    echarts.getInstanceByDom = function (dom) {
        var key = dom.getAttribute(DOM_ATTRIBUTE_KEY);
        return instances[key];
    };
    /**
     * @param {string} key
     * @return {echarts~ECharts}
     */
    echarts.getInstanceById = function (key) {
        return instances[key];
    };

    /**
     * Register theme
     */
    echarts.registerTheme = function (name, theme) {
        themeStorage[name] = theme;
    };

    /**
     * Register option preprocessor
     * @param {Function} preprocessorFunc
     */
    echarts.registerPreprocessor = function (preprocessorFunc) {
        optionPreprocessorFuncs.push(preprocessorFunc);
    };

    /**
     * @param {string} stage
     * @param {Function} processorFunc
     */
    echarts.registerProcessor = function (stage, processorFunc) {
        if (zrUtil.indexOf(PROCESSOR_STAGES, stage) < 0) {
            throw new Error('stage should be one of ' + PROCESSOR_STAGES);
        }
        var funcs = dataProcessorFuncs[stage] || (dataProcessorFuncs[stage] = []);
        funcs.push(processorFunc);
    };

    /**
     * Usage:
     * registerAction('someAction', 'someEvent', function () { ... });
     * registerAction('someAction', function () { ... });
     * registerAction(
     *     {type: 'someAction', event: 'someEvent', update: 'updateView'},
     *     function () { ... }
     * );
     *
     * @param {(string|Object)} actionInfo
     * @param {string} actionInfo.type
     * @param {string} [actionInfo.event]
     * @param {string} [actionInfo.update]
     * @param {string} [eventName]
     * @param {Function} action
     */
    echarts.registerAction = function (actionInfo, eventName, action) {
        if (typeof eventName === 'function') {
            action = eventName;
            eventName = '';
        }
        var actionType = zrUtil.isObject(actionInfo)
            ? actionInfo.type
            : ([actionInfo, actionInfo = {
                event: eventName
            }][0]);

        // Event name is all lowercase
        actionInfo.event = (actionInfo.event || actionType).toLowerCase();
        eventName = actionInfo.event;

        if (!actions[actionType]) {
            actions[actionType] = {action: action, actionInfo: actionInfo};
        }
        eventActionMap[eventName] = actionType;
    };

    /**
     * @param {string} type
     * @param {*} CoordinateSystem
     */
    echarts.registerCoordinateSystem = function (type, CoordinateSystem) {
        CoordinateSystemManager.register(type, CoordinateSystem);
    };

    /**
     * @param {*} layout
     */
    echarts.registerLayout = function (layout) {
        // PENDING All functions ?
        if (zrUtil.indexOf(layoutFuncs, layout) < 0) {
            layoutFuncs.push(layout);
        }
    };

    /**
     * @param {string} stage
     * @param {Function} visualCodingFunc
     */
    echarts.registerVisualCoding = function (stage, visualCodingFunc) {
        if (zrUtil.indexOf(VISUAL_CODING_STAGES, stage) < 0) {
            throw new Error('stage should be one of ' + VISUAL_CODING_STAGES);
        }
        var funcs = visualCodingFuncs[stage] || (visualCodingFuncs[stage] = []);
        funcs.push(visualCodingFunc);
    };

    /**
     * @param {Object} opts
     */
    echarts.extendChartView = function (opts) {
        return ChartView.extend(opts);
    };

    /**
     * @param {Object} opts
     */
    echarts.extendComponentModel = function (opts) {
        return ComponentModel.extend(opts);
    };

    /**
     * @param {Object} opts
     */
    echarts.extendSeriesModel = function (opts) {
        return SeriesModel.extend(opts);
    };

    /**
     * @param {Object} opts
     */
    echarts.extendComponentView = function (opts) {
        return ComponentView.extend(opts);
    };

    /**
     * ZRender need a canvas context to do measureText.
     * But in node environment canvas may be created by node-canvas.
     * So we need to specify how to create a canvas instead of using document.createElement('canvas')
     *
     * Be careful of using it in the browser.
     *
     * @param {Function} creator
     * @example
     *     var Canvas = require('canvas');
     *     var echarts = require('echarts');
     *     echarts.setCanvasCreator(function () {
     *         // Small size is enough.
     *         return new Canvas(32, 32);
     *     });
     */
    echarts.setCanvasCreator = function (creator) {
        zrUtil.createCanvas = creator;
    };

    echarts.registerVisualCoding('echarts', zrUtil.curry(
        require('./visual/seriesColor'), '', 'itemStyle'
    ));
    echarts.registerPreprocessor(require('./preprocessor/backwardCompat'));

    // Default action
    echarts.registerAction({
        type: 'highlight',
        event: 'highlight',
        update: 'highlight'
    }, zrUtil.noop);
    echarts.registerAction({
        type: 'downplay',
        event: 'downplay',
        update: 'downplay'
    }, zrUtil.noop);


    // --------
    // Exports
    // --------

    echarts.graphic = require('./util/graphic');
    echarts.number = require('./util/number');
    echarts.format = require('./util/format');
    echarts.matrix = require('zrender/core/matrix');
    echarts.vector = require('zrender/core/vector');

    echarts.util = {};
    each([
            'map', 'each', 'filter', 'indexOf', 'inherits',
            'reduce', 'filter', 'bind', 'curry', 'isArray',
            'isString', 'isObject', 'isFunction', 'extend'
        ],
        function (name) {
            echarts.util[name] = zrUtil[name];
        }
    );

    return echarts;
});

echarts.min.js
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.echarts=e():t.echarts=e()}(this,function(){return function(t){function e(n){if(i[n])return i[n].exports;var o=i[n]={exports:{},id:n,loaded:!1};return t[n].call(o.exports,o,o.exports,e),o.loaded=!0,o.exports}var i={};return e.m=t,e.c=i,e.p="",e(0)}([function(t,e,i){t.exports=i(2),i(85),i(79),i(90),i(165),i(283),i(272),i(293),i(248),i(244),i(240),i(279),i(288),i(226),i(231),i(237),i(268),i(261),i(36),i(178),i(198),i(308),i(305),i(214),i(189),i(168),i(321),i(184),i(183),i(312),i(190),i(206)},function(t,e,i){function n(t){if("object"==typeof t&&null!==t){var e=t;if(t instanceof Array){e=[];for(var i=0,o=t.length;o>i;i++)e[i]=n(t[i])}else if(!A(t)&&!I(t)){e={};for(var a in t)t.hasOwnProperty(a)&&(e[a]=n(t[a]))}return e}return t}function o(t,e,i){if(!M(e)||!M(t))return i?n(e):t;for(var a in e)if(e.hasOwnProperty(a)){var r=t[a],s=e[a];!M(s)||!M(r)||b(s)||b(r)||I(s)||I(r)||A(s)||A(r)?!i&&a in t||(t[a]=n(e[a],!0)):o(r,s,i)}return t}function a(t,e){for(var i=t[0],n=1,a=t.length;a>n;n++)i=o(i,t[n],e);return i}function r(t,e){for(var i in e)e.hasOwnProperty(i)&&(t[i]=e[i]);return t}function s(t,e,i){for(var n in e)e.hasOwnProperty(n)&&(i?null!=e[n]:null==t[n])&&(t[n]=e[n]);return t}function l(){return document.createElement("canvas")}function h(){return D||(D=G.createCanvas().getContext("2d")),D}function u(t,e){if(t){if(t.indexOf)return t.indexOf(e);for(var i=0,n=t.length;n>i;i++)if(t[i]===e)return i}return-1}function c(t,e){function i(){}var n=t.prototype;i.prototype=e.prototype,t.prototype=new i;for(var o in n)t.prototype[o]=n[o];t.prototype.constructor=t,t.superClass=e}function d(t,e,i){t="prototype"in t?t.prototype:t,e="prototype"in e?e.prototype:e,s(t,e,i)}function f(t){return t?"string"==typeof t?!1:"number"==typeof t.length:void 0}function p(t,e,i){if(t&&e)if(t.forEach&&t.forEach===O)t.forEach(e,i);else if(t.length===+t.length)for(var n=0,o=t.length;o>n;n++)e.call(i,t[n],n,t);else for(var a in t)t.hasOwnProperty(a)&&e.call(i,t[a],a,t)}function g(t,e,i){if(t&&e){if(t.map&&t.map===N)return t.map(e,i);for(var n=[],o=0,a=t.length;a>o;o++)n.push(e.call(i,t[o],o,t));return n}}function m(t,e,i,n){if(t&&e){if(t.reduce&&t.reduce===B)return t.reduce(e,i,n);for(var o=0,a=t.length;a>o;o++)i=e.call(n,i,t[o],o,t);return i}}function v(t,e,i){if(t&&e){if(t.filter&&t.filter===R)return t.filter(e,i);for(var n=[],o=0,a=t.length;a>o;o++)e.call(i,t[o],o,t)&&n.push(t[o]);return n}}function y(t,e,i){if(t&&e)for(var n=0,o=t.length;o>n;n++)if(e.call(i,t[n],n,t))return t[n]}function x(t,e){var i=V.call(arguments,2);return function(){return t.apply(e,i.concat(V.call(arguments)))}}function _(t){var e=V.call(arguments,1);return function(){return t.apply(this,e.concat(V.call(arguments)))}}function b(t){return"[object Array]"===z.call(t)}function w(t){return"function"==typeof t}function S(t){return"[object String]"===z.call(t)}function M(t){var e=typeof t;return"function"===e||!!t&&"object"==e}function A(t){return!!k[z.call(t)]||t instanceof P}function I(t){return t&&1===t.nodeType&&"string"==typeof t.nodeName}function T(t){for(var e=0,i=arguments.length;i>e;e++)if(null!=arguments[e])return arguments[e]}function L(){return Function.call.apply(V,arguments)}function C(t,e){if(!t)throw new Error(e)}var D,P=i(17),k={"[object Function]":1,"[object RegExp]":1,"[object Date]":1,"[object Error]":1,"[object CanvasGradient]":1},z=Object.prototype.toString,E=Array.prototype,O=E.forEach,R=E.filter,V=E.slice,N=E.map,B=E.reduce,G={inherits:c,mixin:d,clone:n,merge:o,mergeAll:a,extend:r,defaults:s,getContext:h,createCanvas:l,indexOf:u,slice:L,find:y,isArrayLike:f,each:p,map:g,reduce:m,filter:v,bind:x,curry:_,isArray:b,isString:S,isObject:M,isFunction:w,isBuildInObject:A,isDom:I,retrieve:T,assert:C,noop:function(){}};t.exports=G},function(t,e,i){function n(t){return function(e,i,n){e=e&&e.toLowerCase(),C.prototype[t].call(this,e,i,n)}}function o(){C.call(this)}function a(t,e,i){i=i||{},"string"==typeof e&&(e=W[e]),e&&D(F,function(t){t(e)}),this.id,this.group,this._dom=t,this._zr=A.init(t,{renderer:i.renderer||"canvas",devicePixelRatio:i.devicePixelRatio}),this._theme=I.clone(e),this._chartsViews=[],this._chartsMap={},this._componentsViews=[],this._componentsMap={},this._api=new v(this),this._coordSysMgr=new y,C.call(this),this._messageCenter=new o,this._initEvents(),this.resize=I.bind(this.resize,this)}function r(t,e){var i=this._model;i&&i.eachComponent({mainType:"series",query:e},function(n,o){var a=this._chartsMap[n.__viewId];a&&a.__alive&&a[t](n,i,this._api,e)},this)}function s(t,e,i){var n=this._api;D(this._componentsViews,function(o){var a=o.__model;o[t](a,e,n,i),p(a,o)},this),e.eachSeries(function(o,a){var r=this._chartsMap[o.__viewId];r[t](o,e,n,i),p(o,r)},this)}function l(t,e){for(var i="component"===t,n=i?this._componentsViews:this._chartsViews,o=i?this._componentsMap:this._chartsMap,a=this._zr,r=0;r<n.length;r++)n[r].__alive=!1;e[i?"eachComponent":"eachSeries"](function(t,r){if(i){if("series"===t)return}else r=t;var s=r.id+"_"+r.type,l=o[s];if(!l){var h=_.parseClassType(r.type),u=i?w.getClass(h.main,h.sub):S.getClass(h.sub);if(!u)return;l=new u,l.init(e,this._api),o[s]=l,n.push(l),a.add(l.group)}r.__viewId=s,l.__alive=!0,l.__id=s,l.__model=r},this);for(var r=0;r<n.length;){var s=n[r];s.__alive?r++:(a.remove(s.group),s.dispose(e,this._api),n.splice(r,1),delete o[s.__id])}}function h(t,e){D(k,function(i){D(G[i]||[],function(i){i(t,e)})})}function u(t){var e={};t.eachSeries(function(t){var i=t.get("stack"),n=t.getData();if(i&&"list"===n.type){var o=e[i];o&&(n.stackedOn=o),e[i]=n}})}function c(t,e){var i=this._api;D(B,function(n){n(t,i,e)})}function d(t,e){D(P,function(i){D(H[i]||[],function(i){i(t,e)})})}function f(t,e){var i=this._api;D(this._componentsViews,function(n){var o=n.__model;n.render(o,t,i,e),p(o,n)},this),D(this._chartsViews,function(t){t.__alive=!1},this),t.eachSeries(function(n,o){var a=this._chartsMap[n.__viewId];a.__alive=!0,a.render(n,t,i,e),a.group.silent=!!n.get("silent"),p(n,a)},this),D(this._chartsViews,function(e){e.__alive||e.remove(t,i)},this)}function p(t,e){var i=t.get("z"),n=t.get("zlevel");e.group.traverse(function(t){null!=i&&(t.z=i),null!=n&&(t.zlevel=n)})}function g(t){function e(t,e){for(var i=0;i<t.length;i++){var n=t[i];n[a]=e}}var i=0,n=1,o=2,a="__connectUpdateStatus";I.each(N,function(r,s){t._messageCenter.on(s,function(r){if(q[t.group]&&t[a]!==i){var s=t.makeActionFromEvent(r),l=[];for(var h in Z){var u=Z[h];u!==t&&u.group===t.group&&l.push(u)}e(l,i),D(l,function(t){t[a]!==n&&t.dispatchAction(s)}),e(l,o)}})})}/*!
	 * ECharts, a javascript interactive chart library.
	 *
	 * Copyright (c) 2015, Baidu Inc.
	 * All rights reserved.
	 *
	 * LICENSE
	 * https://github.com/ecomfe/echarts/blob/master/LICENSE.txt
	 */
var m=i(111),v=i(78),y=i(23),x=i(112),_=i(10),b=i(13),w=i(54),S=i(26),M=i(3),A=i(68),I=i(1),T=i(22),L=i(14),C=i(21),D=I.each,P=["echarts","chart","component"],k=["transform","filter","statistic"];o.prototype.on=n("on"),o.prototype.off=n("off"),o.prototype.one=n("one"),I.mixin(o,C);var z=a.prototype;z.getDom=function(){return this._dom},z.getZr=function(){return this._zr},z.setOption=function(t,e,i){this._model&&!e||(this._model=new m(null,null,this._theme,new x(this._api))),this._model.setOption(t,F),E.prepareAndUpdate.call(this),!i&&this._zr.refreshImmediately()},z.setTheme=function(){console.log("ECharts#setTheme() is DEPRECATED in ECharts 3.0")},z.getModel=function(){return this._model},z.getOption=function(){return this._model.getOption()},z.getWidth=function(){return this._zr.getWidth()},z.getHeight=function(){return this._zr.getHeight()},z.getRenderedCanvas=function(t){if(L.canvasSupported){t=t||{},t.pixelRatio=t.pixelRatio||1,t.backgroundColor=t.backgroundColor||this._model.get("backgroundColor");var e=this._zr,i=e.storage.getDisplayList();return I.each(i,function(t){t.stopAnimation(!0)}),e.painter.getRenderedCanvas(t)}},z.getDataURL=function(t){t=t||{};var e=t.excludeComponents,i=this._model,n=[],o=this;D(e,function(t){i.eachComponent({mainType:t},function(t){var e=o._componentsMap[t.__viewId];e.group.ignore||(n.push(e),e.group.ignore=!0)})});var a=this.getRenderedCanvas(t).toDataURL("image/"+(t&&t.type||"png"));return D(n,function(t){t.group.ignore=!1}),a},z.getConnectedDataURL=function(t){if(L.canvasSupported){var e=this.group,i=Math.min,n=Math.max,o=1/0;if(q[e]){var a=o,r=o,s=-o,l=-o,h=[],u=t&&t.pixelRatio||1;for(var c in Z){var d=Z[c];if(d.group===e){var f=d.getRenderedCanvas(I.clone(t)),p=d.getDom().getBoundingClientRect();a=i(p.left,a),r=i(p.top,r),s=n(p.right,s),l=n(p.bottom,l),h.push({dom:f,left:p.left,top:p.top})}}a*=u,r*=u,s*=u,l*=u;var g=s-a,m=l-r,v=I.createCanvas();v.width=g,v.height=m;var y=A.init(v);return D(h,function(t){var e=new M.Image({style:{x:t.left*u-a,y:t.top*u-r,image:t.dom}});y.add(e)}),y.refreshImmediately(),v.toDataURL("image/"+(t&&t.type||"png"))}return this.getDataURL(t)}};var E={update:function(t){var e=this._model,i=this._api,n=this._coordSysMgr;if(e){e.restoreData(),n.create(this._model,this._api),h.call(this,e,i),u.call(this,e),n.update(e,i),c.call(this,e,t),d.call(this,e,t),f.call(this,e,t);var o=e.get("backgroundColor")||"transparent",a=this._zr.painter;if(a.isSingleCanvas&&a.isSingleCanvas())this._zr.configLayer(0,{clearColor:o});else{if(!L.canvasSupported){var r=T.parse(o);o=T.stringify(r,"rgb"),0===r[3]&&(o="transparent")}o=o,this._dom.style.backgroundColor=o}}},updateView:function(t){var e=this._model;e&&(c.call(this,e,t),d.call(this,e,t),s.call(this,"updateView",e,t))},updateVisual:function(t){var e=this._model;e&&(d.call(this,e,t),s.call(this,"updateVisual",e,t))},updateLayout:function(t){var e=this._model;e&&(c.call(this,e,t),s.call(this,"updateLayout",e,t))},highlight:function(t){r.call(this,"highlight",t)},downplay:function(t){r.call(this,"downplay",t)},prepareAndUpdate:function(t){var e=this._model;l.call(this,"component",e),l.call(this,"chart",e),E.update.call(this,t)}};z.resize=function(){this._zr.resize();var t=this._model&&this._model.resetOption("media");E[t?"prepareAndUpdate":"update"].call(this),this._loadingFX&&this._loadingFX.resize()};var O=i(110);z.showLoading=function(t,e){I.isObject(t)&&(e=t,t="default"),this.hideLoading();var i=O(this._api,e),n=this._zr;this._loadingFX=i,n.add(i)},z.hideLoading=function(){this._loadingFX&&this._zr.remove(this._loadingFX),this._loadingFX=null},z.makeActionFromEvent=function(t){var e=I.extend({},t);return e.type=N[t.type],e},z.dispatchAction=function(t,e){var i=V[t.type];if(i){var n=i.actionInfo,o=n.update||"update",a=[t],r=!1;t.batch&&(r=!0,a=I.map(t.batch,function(e){return e=I.defaults(I.extend({},e),t),e.batch=null,e}));for(var s,l=[],h="highlight"===t.type||"downplay"===t.type,u=0;u<a.length;u++){var c=a[u];s=i.action(c,this._model),s=s||I.extend({},c),s.type=n.event||s.type,l.push(s),h&&E[o].call(this,c)}"none"!==o&&!h&&E[o].call(this,t),e||(s=r?{type:n.event||t.type,batch:l}:l[0],this._messageCenter.trigger(s.type,s))}},z.on=n("on"),z.off=n("off"),z.one=n("one");var R=["click","dblclick","mouseover","mouseout","mousedown","mouseup","globalout"];z._initEvents=function(){D(R,function(t){this._zr.on(t,function(e){var i=this.getModel(),n=e.target;if(n&&null!=n.dataIndex){var o=n.dataModel||i.getSeriesByIndex(n.seriesIndex),a=o&&o.getDataParams(n.dataIndex,n.dataType)||{};a.event=e,a.type=t,this.trigger(t,a)}else n&&n.eventData&&this.trigger(t,n.eventData)},this)},this),D(N,function(t,e){this._messageCenter.on(e,function(t){this.trigger(e,t)},this)},this)},z.isDisposed=function(){return this._disposed},z.clear=function(){this.setOption({},!0)},z.dispose=function(){this._disposed=!0;var t=this._api,e=this._model;D(this._componentsViews,function(i){i.dispose(e,t)}),D(this._chartsViews,function(i){i.dispose(e,t)}),this._zr.dispose(),delete Z[this.id]},I.mixin(a,C);var V=[],N={},B=[],G={},F=[],H={},W={},Z={},q={},j=new Date-0,U=new Date-0,X="_echarts_instance_",Y={version:"3.1.10",dependencies:{zrender:"3.1.0"}};Y.init=function(t,e,i){if(A.version.replace(".","")-0<Y.dependencies.zrender.replace(".","")-0)throw new Error("ZRender "+A.version+" is too old for ECharts "+Y.version+". Current version need ZRender "+Y.dependencies.zrender+"+");if(!t)throw new Error("Initialize failed: invalid dom.");var n=new a(t,e,i);return n.id="ec_"+j++,Z[n.id]=n,t.setAttribute&&t.setAttribute(X,n.id),g(n),n},Y.connect=function(t){if(I.isArray(t)){var e=t;t=null,I.each(e,function(e){null!=e.group&&(t=e.group)}),t=t||"g_"+U++,I.each(e,function(e){e.group=t})}return q[t]=!0,t},Y.disConnect=function(t){q[t]=!1},Y.dispose=function(t){I.isDom(t)?t=Y.getInstanceByDom(t):"string"==typeof t&&(t=Z[t]),t instanceof a&&!t.isDisposed()&&t.dispose()},Y.getInstanceByDom=function(t){var e=t.getAttribute(X);return Z[e]},Y.getInstanceById=function(t){return Z[t]},Y.registerTheme=function(t,e){W[t]=e},Y.registerPreprocessor=function(t){F.push(t)},Y.registerProcessor=function(t,e){if(I.indexOf(k,t)<0)throw new Error("stage should be one of "+k);var i=G[t]||(G[t]=[]);i.push(e)},Y.registerAction=function(t,e,i){"function"==typeof e&&(i=e,e="");var n=I.isObject(t)?t.type:[t,t={event:e}][0];t.event=(t.event||n).toLowerCase(),e=t.event,V[n]||(V[n]={action:i,actionInfo:t}),N[e]=n},Y.registerCoordinateSystem=function(t,e){y.register(t,e)},Y.registerLayout=function(t){I.indexOf(B,t)<0&&B.push(t)},Y.registerVisualCoding=function(t,e){if(I.indexOf(P,t)<0)throw new Error("stage should be one of "+P);var i=H[t]||(H[t]=[]);i.push(e)},Y.extendChartView=function(t){return S.extend(t)},Y.extendComponentModel=function(t){return _.extend(t)},Y.extendSeriesModel=function(t){return b.extend(t)},Y.extendComponentView=function(t){return w.extend(t)},Y.setCanvasCreator=function(t){I.createCanvas=t},Y.registerVisualCoding("echarts",I.curry(i(74),"","itemStyle")),Y.registerPreprocessor(i(119)),Y.registerAction({type:"highlight",event:"highlight",update:"highlight"},I.noop),Y.registerAction({type:"downplay",event:"downplay",update:"downplay"},I.noop),Y.graphic=i(3),Y.number=i(4),Y.format=i(9),Y.matrix=i(19),Y.vector=i(5),Y.util={},D(["map","each","filter","indexOf","inherits","reduce","filter","bind","curry","isArray","isString","isObject","isFunction","extend"],function(t){Y.util[t]=I[t]}),t.exports=Y},function(t,e,i){"use strict";function n(t){return null!=t&&"none"!=t}function o(t){return t instanceof S?t:_.lift(t,-.1)}function a(t){if(t.__hoverStlDirty){var e=t.style.stroke,i=t.style.fill,a=t.__hoverStl;a.fill=a.fill||(n(i)?o(i):null),a.stroke=a.stroke||(n(e)?o(e):null);var r={};for(var s in a)a.hasOwnProperty(s)&&(r[s]=t.style[s]);t.__normalStl=r,t.__hoverStlDirty=!1}}function r(t){t.__isHover||(a(t),t.setStyle(t.__hoverStl),t.z2+=1,t.__isHover=!0)}function s(t){if(t.__isHover){var e=t.__normalStl;e&&t.setStyle(e),t.z2-=1,t.__isHover=!1}}function l(t){"group"===t.type?t.traverse(function(t){"group"!==t.type&&r(t)}):r(t)}function h(t){"group"===t.type?t.traverse(function(t){"group"!==t.type&&s(t)}):s(t)}function u(t,e){t.__hoverStl=t.hoverStyle||e||{},t.__hoverStlDirty=!0,t.__isHover&&a(t)}function c(){!this.__isEmphasis&&l(this)}function d(){!this.__isEmphasis&&h(this)}function f(){this.__isEmphasis=!0,l(this)}function p(){this.__isEmphasis=!1,h(this)}function g(t,e,i,n,o,a){"function"==typeof o&&(a=o,o=null);var r=t?"Update":"",s=n&&n.getShallow("animationDuration"+r),l=n&&n.getShallow("animationEasing"+r),h=n&&n.getShallow("animationDelay"+r);"function"==typeof h&&(h=h(o)),n&&n.getShallow("animation")?e.animateTo(i,s,h||0,l,a):(e.attr(i),a&&a())}var m=i(1),v=i(156),y=Math.round,x=i(6),_=i(22),b=i(19),w=i(5),S=i(17),M={};M.Group=i(27),M.Image=i(46),M.Text=i(66),M.Circle=i(147),M.Sector=i(153),M.Ring=i(152),M.Polygon=i(149),M.Polyline=i(150),M.Rect=i(151),M.Line=i(148),M.BezierCurve=i(146),M.Arc=i(145),M.CompoundPath=i(140),M.LinearGradient=i(76),M.RadialGradient=i(141),M.BoundingRect=i(8),M.extendShape=function(t){return x.extend(t)},M.extendPath=function(t,e){return v.extendFromString(t,e)},M.makePath=function(t,e,i,n){var o=v.createFromString(t,e),a=o.getBoundingRect();if(i){var r=a.width/a.height;if("center"===n){var s,l=i.height*r;l<=i.width?s=i.height:(l=i.width,s=l/r);var h=i.x+i.width/2,u=i.y+i.height/2;i.x=h-l/2,i.y=u-s/2,i.width=l,i.height=s}this.resizePath(o,i)}return o},M.mergePath=v.mergePath,M.resizePath=function(t,e){if(t.applyTransform){var i=t.getBoundingRect(),n=i.calculateTransform(e);t.applyTransform(n)}},M.subPixelOptimizeLine=function(t){var e=M.subPixelOptimize,i=t.shape,n=t.style.lineWidth;return y(2*i.x1)===y(2*i.x2)&&(i.x1=i.x2=e(i.x1,n,!0)),y(2*i.y1)===y(2*i.y2)&&(i.y1=i.y2=e(i.y1,n,!0)),t},M.subPixelOptimizeRect=function(t){var e=M.subPixelOptimize,i=t.shape,n=t.style.lineWidth,o=i.x,a=i.y,r=i.width,s=i.height;return i.x=e(i.x,n,!0),i.y=e(i.y,n,!0),i.width=Math.max(e(o+r,n,!1)-i.x,0===r?0:1),i.height=Math.max(e(a+s,n,!1)-i.y,0===s?0:1),t},M.subPixelOptimize=function(t,e,i){var n=y(2*t);return(n+y(e))%2===0?n/2:(n+(i?1:-1))/2},M.setHoverStyle=function(t,e){"group"===t.type?t.traverse(function(t){"group"!==t.type&&u(t,e)}):u(t,e),t.on("mouseover",c).on("mouseout",d),t.on("emphasis",f).on("normal",p)},M.setText=function(t,e,i){var n=e.getShallow("position")||"inside",o=n.indexOf("inside")>=0?"white":i,a=e.getModel("textStyle");m.extend(t,{textDistance:e.getShallow("distance")||5,textFont:a.getFont(),textPosition:n,textFill:a.getTextColor()||o})},M.updateProps=m.curry(g,!0),M.initProps=m.curry(g,!1),M.getTransform=function(t,e){for(var i=b.identity([]);t&&t!==e;)b.mul(i,t.getLocalTransform(),i),t=t.parent;return i},M.applyTransform=function(t,e,i){return i&&(e=b.invert([],e)),w.applyTransform([],t,e)},M.transformDirection=function(t,e,i){var n=0===e[4]||0===e[5]||0===e[0]?1:Math.abs(2*e[4]/e[0]),o=0===e[4]||0===e[5]||0===e[2]?1:Math.abs(2*e[4]/e[2]),a=["left"===t?-n:"right"===t?n:0,"top"===t?-o:"bottom"===t?o:0];return a=M.applyTransform(a,e,i),Math.abs(a[0])>Math.abs(a[1])?a[0]>0?"right":"left":a[1]>0?"bottom":"top"},t.exports=M},function(t,e){function i(t){return t.replace(/^\s+/,"").replace(/\s+$/,"")}var n={},o=1e-4;n.linearMap=function(t,e,i,n){var o=e[1]-e[0],a=i[1]-i[0];if(0===o)return 0===a?i[0]:(i[0]+i[1])/2;if(n)if(o>0){if(t<=e[0])return i[0];if(t>=e[1])return i[1]}else{if(t>=e[0])return i[0];if(t<=e[1])return i[1]}else{if(t===e[0])return i[0];if(t===e[1])return i[1]}return(t-e[0])/o*a+i[0]},n.parsePercent=function(t,e){switch(t){case"center":case"middle":t="50%";break;case"left":case"top":t="0%";break;case"right":case"bottom":t="100%"}return"string"==typeof t?i(t).match(/%$/)?parseFloat(t)/100*e:parseFloat(t):null==t?NaN:+t},n.round=function(t){return+(+t).toFixed(10)},n.asc=function(t){return t.sort(function(t,e){return t-e}),t},n.getPrecision=function(t){if(isNaN(t))return 0;for(var e=1,i=0;Math.round(t*e)/e!==t;)e*=10,i++;return i},n.getPixelPrecision=function(t,e){var i=Math.log,n=Math.LN10,o=Math.floor(i(t[1]-t[0])/n),a=Math.round(i(Math.abs(e[1]-e[0]))/n);return Math.max(-o+a,0)},n.MAX_SAFE_INTEGER=9007199254740991,n.remRadian=function(t){var e=2*Math.PI;return(t%e+e)%e},n.isRadianAroundZero=function(t){return t>-o&&o>t},n.parseDate=function(t){return t instanceof Date?t:new Date("string"==typeof t?t.replace(/-/g,"/"):Math.round(t))},n.quantity=function(t){return Math.pow(10,Math.floor(Math.log(t)/Math.LN10))},n.nice=function(t,e){var i,o=n.quantity(t),a=t/o;return i=e?1.5>a?1:2.5>a?2:4>a?3:7>a?5:10:1>a?1:2>a?2:3>a?3:5>a?5:10,i*o},t.exports=n},function(t,e){var i="undefined"==typeof Float32Array?Array:Float32Array,n={create:function(t,e){var n=new i(2);return n[0]=t||0,n[1]=e||0,n},copy:function(t,e){return t[0]=e[0],t[1]=e[1],t},clone:function(t){var e=new i(2);return e[0]=t[0],e[1]=t[1],e},set:function(t,e,i){return t[0]=e,t[1]=i,t},add:function(t,e,i){return t[0]=e[0]+i[0],t[1]=e[1]+i[1],t},scaleAndAdd:function(t,e,i,n){return t[0]=e[0]+i[0]*n,t[1]=e[1]+i[1]*n,t},sub:function(t,e,i){return t[0]=e[0]-i[0],t[1]=e[1]-i[1],t},len:function(t){return Math.sqrt(this.lenSquare(t))},lenSquare:function(t){return t[0]*t[0]+t[1]*t[1]},mul:function(t,e,i){return t[0]=e[0]*i[0],t[1]=e[1]*i[1],t},div:function(t,e,i){return t[0]=e[0]/i[0],t[1]=e[1]/i[1],t},dot:function(t,e){return t[0]*e[0]+t[1]*e[1]},scale:function(t,e,i){return t[0]=e[0]*i,t[1]=e[1]*i,t},normalize:function(t,e){var i=n.len(e);return 0===i?(t[0]=0,t[1]=0):(t[0]=e[0]/i,t[1]=e[1]/i),t},distance:function(t,e){return Math.sqrt((t[0]-e[0])*(t[0]-e[0])+(t[1]-e[1])*(t[1]-e[1]))},distanceSquare:function(t,e){return(t[0]-e[0])*(t[0]-e[0])+(t[1]-e[1])*(t[1]-e[1])},negate:function(t,e){return t[0]=-e[0],t[1]=-e[1],t},lerp:function(t,e,i,n){return t[0]=e[0]+n*(i[0]-e[0]),t[1]=e[1]+n*(i[1]-e[1]),t},applyTransform:function(t,e,i){var n=e[0],o=e[1];return t[0]=i[0]*n+i[2]*o+i[4],t[1]=i[1]*n+i[3]*o+i[5],t},min:function(t,e,i){return t[0]=Math.min(e[0],i[0]),t[1]=Math.min(e[1],i[1]),t},max:function(t,e,i){return t[0]=Math.max(e[0],i[0]),t[1]=Math.max(e[1],i[1]),t}};n.length=n.len,n.lengthSquare=n.lenSquare,n.dist=n.distance,n.distSquare=n.distanceSquare,t.exports=n},function(t,e,i){function n(t){var e=t.fill;return null!=e&&"none"!==e}function o(t){var e=t.stroke;return null!=e&&"none"!==e&&t.lineWidth>0}function a(t){r.call(this,t),this.path=new l}var r=i(37),s=i(1),l=i(28),h=i(136),u=(i(17),Math.abs);a.prototype={constructor:a,type:"path",__dirtyPath:!0,strokeContainThreshold:5,brush:function(t){t.save();var e=this.style,i=this.path,a=o(e),r=n(e),s=r&&!!e.fill.colorStops,l=a&&!!e.stroke.colorStops;if(e.bind(t,this),this.setTransform(t),this.__dirtyPath){var h=this.getBoundingRect();s&&(this._fillGradient=e.getGradient(t,e.fill,h)),l&&(this._strokeGradient=e.getGradient(t,e.stroke,h))}s&&(t.fillStyle=this._fillGradient),l&&(t.strokeStyle=this._strokeGradient);var u=e.lineDash,c=e.lineDashOffset,d=!!t.setLineDash,f=this.getGlobalScale();i.setScale(f[0],f[1]),this.__dirtyPath||u&&!d&&a?(i=this.path.beginPath(t),u&&!d&&(i.setLineDash(u),i.setLineDashOffset(c)),this.buildPath(i,this.shape),this.__dirtyPath=!1):(t.beginPath(),this.path.rebuildPath(t)),r&&i.fill(t),u&&d&&(t.setLineDash(u),t.lineDashOffset=c),a&&i.stroke(t),null!=e.text&&this.drawRectText(t,this.getBoundingRect()),t.restore()},buildPath:function(t,e){},getBoundingRect:function(){var t=this._rect,e=this.style,i=!t;if(i){var a=this.path;this.__dirtyPath&&(a.beginPath(),this.buildPath(a,this.shape)),t=a.getBoundingRect()}if(this._rect=t,o(e)){var r=this._rectWithStroke||(this._rectWithStroke=t.clone());if(this.__dirty||i){r.copy(t);var s=e.lineWidth,l=e.strokeNoScale?this.getLineScale():1;n(e)||(s=Math.max(s,this.strokeContainThreshold)),l>1e-10&&(r.width+=s/l,r.height+=s/l,r.x-=s/l/2,r.y-=s/l/2)}return r}return t},contain:function(t,e){var i=this.transformCoordToLocal(t,e),a=this.getBoundingRect(),r=this.style;if(t=i[0],e=i[1],a.contain(t,e)){var s=this.path.data;if(o(r)){var l=r.lineWidth,u=r.strokeNoScale?this.getLineScale():1;if(u>1e-10&&(n(r)||(l=Math.max(l,this.strokeContainThreshold)),h.containStroke(s,l/u,t,e)))return!0}if(n(r))return h.contain(s,t,e)}return!1},dirty:function(t){0===arguments.length&&(t=!0),t&&(this.__dirtyPath=t,this._rect=null),this.__dirty=!0,this.__zr&&this.__zr.refresh(),this.__clipTarget&&this.__clipTarget.dirty()},animateShape:function(t){return this.animate("shape",t)},attrKV:function(t,e){"shape"===t?this.setShape(e):r.prototype.attrKV.call(this,t,e)},setShape:function(t,e){var i=this.shape;if(i){if(s.isObject(t))for(var n in t)i[n]=t[n];else i[t]=e;this.dirty(!0)}return this},getLineScale:function(){var t=this.transform;return t&&u(t[0]-1)>1e-10&&u(t[3]-1)>1e-10?Math.sqrt(u(t[0]*t[3]-t[2]*t[1])):1}},a.extend=function(t){var e=function(e){a.call(this,e),t.style&&this.style.extendFrom(t.style,!1);var i=t.shape;if(i){this.shape=this.shape||{};var n=this.shape;for(var o in i)!n.hasOwnProperty(o)&&i.hasOwnProperty(o)&&(n[o]=i[o])}t.init&&t.init.call(this,e)};s.inherits(e,a);for(var i in t)"style"!==i&&"shape"!==i&&(e.prototype[i]=t[i]);return e},s.inherits(a,r),t.exports=a},function(t,e,i){var n=i(9),o=i(4),a=i(1),r=["x","y","z","radius","angle"],s={};s.createNameEach=function(t,e){t=t.slice();var i=a.map(t,s.capitalFirst);e=(e||[]).slice();var n=a.map(e,s.capitalFirst);return function(o,r){a.each(t,function(t,a){for(var s={name:t,capital:i[a]},l=0;l<e.length;l++)s[e[l]]=t+n[l];o.call(r,s)})}},s.capitalFirst=function(t){return t?t.charAt(0).toUpperCase()+t.substr(1):t},s.eachAxisDim=s.createNameEach(r,["axisIndex","axis","index"]),s.normalizeToArray=function(t){return a.isArray(t)?t:null==t?[]:[t]},