(function webpackUniversalModuleDefinition(root, factory) {
	if(typeof exports === 'object' && typeof module === 'object')
		module.exports = factory();
	else if(typeof define === 'function' && define.amd)
		define([], factory);
	else if(typeof exports === 'object')
		exports["echarts"] = factory();
	else
		root["echarts"] = factory();
})(this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};

/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {

/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId])
/******/ 			return installedModules[moduleId].exports;

/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			exports: {},
/******/ 			id: moduleId,
/******/ 			loaded: false
/******/ 		};

/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);

/******/ 		// Flag the module as loaded
/******/ 		module.loaded = true;

/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}


/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = modules;

/******/ 	// expose the module cache
/******/ 	__webpack_require__.c = installedModules;

/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "";

/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * Export echarts as CommonJS module
	 */
	module.exports = __webpack_require__(1);

	// Import all charts and components
	__webpack_require__(113);
	__webpack_require__(139);
	__webpack_require__(146);
	__webpack_require__(155);
	__webpack_require__(159);

	__webpack_require__(169);
	__webpack_require__(193);
	__webpack_require__(205);
	__webpack_require__(226);
	__webpack_require__(230);
	__webpack_require__(234);
	__webpack_require__(251);
	__webpack_require__(257);
	__webpack_require__(264);
	__webpack_require__(270);
	__webpack_require__(274);
	__webpack_require__(283);
	__webpack_require__(287);
	__webpack_require__(290);
	__webpack_require__(313);

	__webpack_require__(319);
	__webpack_require__(320);
	__webpack_require__(321);
	__webpack_require__(327);
	__webpack_require__(298);
	__webpack_require__(331);
	__webpack_require__(344);
	__webpack_require__(235);
	__webpack_require__(291);
	__webpack_require__(347);
	__webpack_require__(358);

	__webpack_require__(362);

	__webpack_require__(363);
	__webpack_require__(376);

	__webpack_require__(391);
	__webpack_require__(397);
	__webpack_require__(400);

	__webpack_require__(403);
	__webpack_require__(412);

	__webpack_require__(424);


/***/ },
/* 1 */
/***/ function(module, exports, __webpack_require__) {

	// Enable DEV mode when using source code without build. which has no __DEV__ variable
	// In build process 'typeof __DEV__' will be replace with 'boolean'
	// So this code will be removed or disabled anyway after built.
	if (false) {
	    // In browser
	    if (typeof window !== 'undefined') {
	        window.__DEV__ = true;
	    }
	    // In node
	    else if (typeof global !== 'undefined') {
	        global.__DEV__ = true;
	    }
	}

	/*!
	 * 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
	 */


	    var env = __webpack_require__(2);

	    var GlobalModel = __webpack_require__(3);
	    var ExtensionAPI = __webpack_require__(75);
	    var CoordinateSystemManager = __webpack_require__(76);
	    var OptionManager = __webpack_require__(77);

	    var ComponentModel = __webpack_require__(69);
	    var SeriesModel = __webpack_require__(78);

	    var ComponentView = __webpack_require__(79);
	    var ChartView = __webpack_require__(80);
	    var graphic = __webpack_require__(18);
	    var modelUtil = __webpack_require__(5);
	    var throttle = __webpack_require__(81);

	    var zrender = __webpack_require__(82);
	    var zrUtil = __webpack_require__(4);
	    var colorTool = __webpack_require__(31);
	    var Eventful = __webpack_require__(25);
	    var timsort = __webpack_require__(86);

	    var each = zrUtil.each;
	    var parseClassType = ComponentModel.parseClassType;

	    var PRIORITY_PROCESSOR_FILTER = 1000;
	    var PRIORITY_PROCESSOR_STATISTIC = 5000;


	    var PRIORITY_VISUAL_LAYOUT = 1000;
	    var PRIORITY_VISUAL_GLOBAL = 2000;
	    var PRIORITY_VISUAL_CHART = 3000;
	    var PRIORITY_VISUAL_COMPONENT = 4000;
	    // FIXME
	    // necessary?
	    var PRIORITY_VISUAL_BRUSH = 5000;

	    // Main process have three entries: `setOption`, `dispatchAction` and `resize`,
	    // where they must not be invoked nestedly, except the only case: invoke
	    // dispatchAction with updateMethod "none" in main process.
	    // This flag is used to carry out this rule.
	    // All events will be triggered out side main process (i.e. when !this[IN_MAIN_PROCESS]).
	    var IN_MAIN_PROCESS = '__flagInMainProcess';
	    var HAS_GRADIENT_OR_PATTERN_BG = '__hasGradientOrPatternBg';
	    var OPTION_UPDATED = '__optionUpdated';
	    var ACTION_REG = /^[a-zA-Z0-9_]+$/;

	    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];
	        }

	        /**
	         * @type {string}
	         */
	        this.id;
	        /**
	         * Group id
	         * @type {string}
	         */
	        this.group;
	        /**
	         * @type {HTMLDomElement}
	         * @private
	         */
	        this._dom = dom;
	        /**
	         * @type {module:zrender/ZRender}
	         * @private
	         */
	        var zr = this._zr = zrender.init(dom, {
	            renderer: opts.renderer || 'canvas',
	            devicePixelRatio: opts.devicePixelRatio,
	            width: opts.width,
	            height: opts.height
	        });

	        /**
	         * Expect 60 pfs.
	         * @type {Function}
	         * @private
	         */
	        this._throttledZrFlush = throttle.throttle(zrUtil.bind(zr.flush, zr), 17);

	        /**
	         * @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/CoordinateSystem}
	         * @private
	         */
	        this._coordSysMgr = new CoordinateSystemManager();

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

	        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);

	        // Can't dispatch action during rendering procedure
	        this._pendingActions = [];
	        // Sort on demand
	        function prioritySortFunc(a, b) {
	            return a.prio - b.prio;
	        }
	        timsort(visualFuncs, prioritySortFunc);
	        timsort(dataProcessorFuncs, prioritySortFunc);

	        zr.animation.on('frame', this._onframe, this);

	        // ECharts instance can be used as value.
	        zrUtil.setAsPrimitive(this);
	    }

	    var echartsProto = ECharts.prototype;

	    echartsProto._onframe = function () {
	        // Lazy update
	        if (this[OPTION_UPDATED]) {
	            var silent = this[OPTION_UPDATED].silent;

	            this[IN_MAIN_PROCESS] = true;

	            updateMethods.prepareAndUpdate.call(this);

	            this[IN_MAIN_PROCESS] = false;

	            this[OPTION_UPDATED] = false;

	            flushPendingActions.call(this, silent);

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

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

	    /**
	     * Usage:
	     * chart.setOption(option, notMerge, lazyUpdate);
	     * chart.setOption(option, {
	     *     notMerge: ...,
	     *     lazyUpdate: ...,
	     *     silent: ...
	     * });
	     *
	     * @param {Object} option
	     * @param {Object|boolean} [opts] opts or notMerge.
	     * @param {boolean} [opts.notMerge=false]
	     * @param {boolean} [opts.lazyUpdate=false] Useful when setOption frequently.
	     */
	    echartsProto.setOption = function (option, notMerge, lazyUpdate) {
	        if (true) {
	            zrUtil.assert(!this[IN_MAIN_PROCESS], '`setOption` should not be called during main process.');
	        }

	        var silent;
	        if (zrUtil.isObject(notMerge)) {
	            lazyUpdate = notMerge.lazyUpdate;
	            silent = notMerge.silent;
	            notMerge = notMerge.notMerge;
	        }

	        this[IN_MAIN_PROCESS] = true;

	        if (!this._model || notMerge) {
	            var optionManager = new OptionManager(this._api);
	            var theme = this._theme;
	            var ecModel = this._model = new GlobalModel(null, null, theme, optionManager);
	            ecModel.init(null, null, theme, optionManager);
	        }

	        this._model.setOption(option, optionPreprocessorFuncs);

	        if (lazyUpdate) {
	            this[OPTION_UPDATED] = {silent: silent};
	            this[IN_MAIN_PROCESS] = false;
	        }
	        else {
	            updateMethods.prepareAndUpdate.call(this);
	            // Ensure zr refresh sychronously, and then pixel in canvas can be
	            // fetched after `setOption`.
	            this._zr.flush();

	            this[OPTION_UPDATED] = false;
	            this[IN_MAIN_PROCESS] = false;

	            flushPendingActions.call(this, silent);
	            triggerUpdatedEvent.call(this, silent);
	        }
	    };

	    /**
	     * @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 && this._model.getOption();
	    };

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

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

	    /**
	     * @return {number}
	     */
	    echartsProto.getDevicePixelRatio = function () {
	        return this._zr.painter.dpr || window.devicePixelRatio || 1;
	    };

	    /**
	     * 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]
	     * @param {string} [opts.excludeComponents]
	     */
	    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;

	            zrUtil.each(instances, function (chart, 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);
	        }
	    };

	    /**
	     * Convert from logical coordinate system to pixel coordinate system.
	     * See CoordinateSystem#convertToPixel.
	     * @param {string|Object} finder
	     *        If string, e.g., 'geo', means {geoIndex: 0}.
	     *        If Object, could contain some of these properties below:
	     *        {
	     *            seriesIndex / seriesId / seriesName,
	     *            geoIndex / geoId, geoName,
	     *            bmapIndex / bmapId / bmapName,
	     *            xAxisIndex / xAxisId / xAxisName,
	     *            yAxisIndex / yAxisId / yAxisName,
	     *            gridIndex / gridId / gridName,
	     *            ... (can be extended)
	     *        }
	     * @param {Array|number} value
	     * @return {Array|number} result
	     */
	    echartsProto.convertToPixel = zrUtil.curry(doConvertPixel, 'convertToPixel');

	    /**
	     * Convert from pixel coordinate system to logical coordinate system.
	     * See CoordinateSystem#convertFromPixel.
	     * @param {string|Object} finder
	     *        If string, e.g., 'geo', means {geoIndex: 0}.
	     *        If Object, could contain some of these properties below:
	     *        {
	     *            seriesIndex / seriesId / seriesName,
	     *            geoIndex / geoId / geoName,
	     *            bmapIndex / bmapId / bmapName,
	     *            xAxisIndex / xAxisId / xAxisName,
	     *            yAxisIndex / yAxisId / yAxisName
	     *            gridIndex / gridId / gridName,
	     *            ... (can be extended)
	     *        }
	     * @param {Array|number} value
	     * @return {Array|number} result
	     */
	    echartsProto.convertFromPixel = zrUtil.curry(doConvertPixel, 'convertFromPixel');

	    function doConvertPixel(methodName, finder, value) {
	        var ecModel = this._model;
	        var coordSysList = this._coordSysMgr.getCoordinateSystems();
	        var result;

	        finder = modelUtil.parseFinder(ecModel, finder);

	        for (var i = 0; i < coordSysList.length; i++) {
	            var coordSys = coordSysList[i];
	            if (coordSys[methodName]
	                && (result = coordSys[methodName](ecModel, finder, value)) != null
	            ) {
	                return result;
	            }
	        }

	        if (true) {
	            console.warn(
	                'No coordinate system that supports ' + methodName + ' found by the given finder.'
	            );
	        }
	    }

	    /**
	     * Is the specified coordinate systems or components contain the given pixel point.
	     * @param {string|Object} finder
	     *        If string, e.g., 'geo', means {geoIndex: 0}.
	     *        If Object, could contain some of these properties below:
	     *        {
	     *            seriesIndex / seriesId / seriesName,
	     *            geoIndex / geoId / geoName,
	     *            bmapIndex / bmapId / bmapName,
	     *            xAxisIndex / xAxisId / xAxisName,
	     *            yAxisIndex / yAxisId / yAxisName,
	     *            gridIndex / gridId / gridName,
	     *            ... (can be extended)
	     *        }
	     * @param {Array|number} value
	     * @return {boolean} result
	     */
	    echartsProto.containPixel = function (finder, value) {
	        var ecModel = this._model;
	        var result;

	        finder = modelUtil.parseFinder(ecModel, finder);

	        zrUtil.each(finder, function (models, key) {
	            key.indexOf('Models') >= 0 && zrUtil.each(models, function (model) {
	                var coordSys = model.coordinateSystem;
	                if (coordSys && coordSys.containPoint) {
	                    result |= !!coordSys.containPoint(value);
	                }
	                else if (key === 'seriesModels') {
	                    var view = this._chartsMap[model.__viewId];
	                    if (view && view.containPoint) {
	                        result |= view.containPoint(value, model);
	                    }
	                    else {
	                        if (true) {
	                            console.warn(key + ': ' + (view
	                                ? 'The found component do not support containPoint.'
	                                : 'No view mapping to the found component.'
	                            ));
	                        }
	                    }
	                }
	                else {
	                    if (true) {
	                        console.warn(key + ': containPoint is not supported');
	                    }
	                }
	            }, this);
	        }, this);

	        return !!result;
	    };

	    /**
	     * Get visual from series or data.
	     * @param {string|Object} finder
	     *        If string, e.g., 'series', means {seriesIndex: 0}.
	     *        If Object, could contain some of these properties below:
	     *        {
	     *            seriesIndex / seriesId / seriesName,
	     *            dataIndex / dataIndexInside
	     *        }
	     *        If dataIndex is not specified, series visual will be fetched,
	     *        but not data item visual.
	     *        If all of seriesIndex, seriesId, seriesName are not specified,
	     *        visual will be fetched from first series.
	     * @param {string} visualType 'color', 'symbol', 'symbolSize'
	     */
	    echartsProto.getVisual = function (finder, visualType) {
	        var ecModel = this._model;

	        finder = modelUtil.parseFinder(ecModel, finder, {defaultMainType: 'series'});

	        var seriesModel = finder.seriesModel;

	        if (true) {
	            if (!seriesModel) {
	                console.warn('There is no specified seires model');
	            }
	        }

	        var data = seriesModel.getData();

	        var dataIndexInside = finder.hasOwnProperty('dataIndexInside')
	            ? finder.dataIndexInside
	            : finder.hasOwnProperty('dataIndex')
	            ? data.indexOfRawIndex(finder.dataIndex)
	            : null;

	        return dataIndexInside != null
	            ? data.getItemVisual(dataIndexInside, visualType)
	            : data.getVisual(visualType);
	    };

	    /**
	     * Get view of corresponding component model
	     * @param  {module:echarts/model/Component} componentModel
	     * @return {module:echarts/view/Component}
	     */
	    echartsProto.getViewOfComponentModel = function (componentModel) {
	        return this._componentsMap[componentModel.__viewId];
	    };

	    /**
	     * Get view of corresponding series model
	     * @param  {module:echarts/model/Series} seriesModel
	     * @return {module:echarts/view/Chart}
	     */
	    echartsProto.getViewOfSeriesModel = function (seriesModel) {
	        return this._chartsMap[seriesModel.__viewId];
	    };


	    var updateMethods = {

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

	            var ecModel = this._model;
	            var api = this._api;
	            var coordSysMgr = this._coordSysMgr;
	            var zr = this._zr;
	            // 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);

	            doVisualEncoding.call(this, ecModel, payload);

	            doRender.call(this, ecModel, payload);

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

	            var painter = zr.painter;
	            // TODO all use clearColor ?
	            if (painter.isSingleCanvas && painter.isSingleCanvas()) {
	                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';
	                    }
	                }
	                if (backgroundColor.colorStops || backgroundColor.image) {
	                    // Gradient background
	                    // FIXME Fixed layer？
	                    zr.configLayer(0, {
	                        clearColor: backgroundColor
	                    });
	                    this[HAS_GRADIENT_OR_PATTERN_BG] = true;

	                    this._dom.style.background = 'transparent';
	                }
	                else {
	                    if (this[HAS_GRADIENT_OR_PATTERN_BG]) {
	                        zr.configLayer(0, {
	                            clearColor: null
	                        });
	                    }
	                    this[HAS_GRADIENT_OR_PATTERN_BG] = false;

	                    this._dom.style.background = backgroundColor;
	                }
	            }

	            each(postUpdateFuncs, function (func) {
	                func(ecModel, api);
	            });

	            // console.profile && console.profileEnd('update');
	        },

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

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

	            ecModel.eachSeries(function (seriesModel) {
	                seriesModel.getData().clearAllVisual();
	            });

	            doVisualEncoding.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;
	            }

	            ecModel.eachSeries(function (seriesModel) {
	                seriesModel.getData().clearAllVisual();
	            });

	            doVisualEncoding.call(this, ecModel, payload, true);

	            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
	         */
	        prepareAndUpdate: function (payload) {
	            var ecModel = this._model;

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

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

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

	    /**
	     * @private
	     */
	    function updateDirectly(ecIns, method, payload, mainType, subType) {
	        var ecModel = ecIns._model;

	        // broadcast
	        if (!mainType) {
	            each(ecIns._componentsViews.concat(ecIns._chartsViews), callView);
	            return;
	        }

	        var query = {};
	        query[mainType + 'Id'] = payload[mainType + 'Id'];
	        query[mainType + 'Index'] = payload[mainType + 'Index'];
	        query[mainType + 'Name'] = payload[mainType + 'Name'];

	        var condition = {mainType: mainType, query: query};
	        subType && (condition.subType = subType); // subType may be '' by parseClassType;

	        // If dispatchAction before setOption, do nothing.
	        ecModel && ecModel.eachComponent(condition, function (model, index) {
	            callView(ecIns[
	                mainType === 'series' ? '_chartsMap' : '_componentsMap'
	            ][model.__viewId]);
	        }, ecIns);

	        function callView(view) {
	            view && view.__alive && view[method] && view[method](
	                view.__model, ecModel, ecIns._api, payload
	            );
	        }
	    }

	    /**
	     * Resize the chart
	     * @param {Object} opts
	     * @param {number} [opts.width] Can be 'auto' (the same as null/undefined)
	     * @param {number} [opts.height] Can be 'auto' (the same as null/undefined)
	     * @param {boolean} [opts.silent=false]
	     */
	    echartsProto.resize = function (opts) {
	        if (true) {
	            zrUtil.assert(!this[IN_MAIN_PROCESS], '`resize` should not be called during main process.');
	        }

	        this[IN_MAIN_PROCESS] = true;

	        this._zr.resize(opts);

	        var optionChanged = this._model && this._model.resetOption('media');
	        var updateMethod = optionChanged ? 'prepareAndUpdate' : 'update';

	        updateMethods[updateMethod].call(this);

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

	        this[IN_MAIN_PROCESS] = false;

	        var silent = opts && opts.silent;

	        flushPendingActions.call(this, silent);

	        triggerUpdatedEvent.call(this, silent);
	    };

	    /**
	     * Show loading effect
	     * @param  {string} [name='default']
	     * @param  {Object} [cfg]
	     */
	    echartsProto.showLoading = function (name, cfg) {
	        if (zrUtil.isObject(name)) {
	            cfg = name;
	            name = '';
	        }
	        name = name || 'default';

	        this.hideLoading();
	        if (!loadingEffects[name]) {
	            if (true) {
	                console.warn('Loading effects ' + name + ' not exists.');
	            }
	            return;
	        }
	        var el = loadingEffects[name](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 {Object|boolean} [opt] If pass boolean, means opt.silent
	     * @param {boolean} [opt.silent=false] Whether trigger events.
	     * @param {boolean} [opt.flush=undefined]
	     *                  true: Flush immediately, and then pixel in canvas can be fetched
	     *                      immediately. Caution: it might affect performance.
	     *                  false: Not not flush.
	     *                  undefined: Auto decide whether perform flush.
	     */
	    echartsProto.dispatchAction = function (payload, opt) {
	        if (!zrUtil.isObject(opt)) {
	            opt = {silent: !!opt};
	        }

	        if (!actions[payload.type]) {
	            return;
	        }

	        // May dispatchAction in rendering procedure
	        if (this[IN_MAIN_PROCESS]) {
	            this._pendingActions.push(payload);
	            return;
	        }

	        doDispatchAction.call(this, payload, opt.silent);

	        if (opt.flush) {
	            this._zr.flush(true);
	        }
	        else if (opt.flush !== false && env.browser.weChat) {
	            // In WeChat embeded browser, `requestAnimationFrame` and `setInterval`
	            // hang when sliding page (on touch event), which cause that zr does not
	            // refresh util user interaction finished, which is not expected.
	            // But `dispatchAction` may be called too frequently when pan on touch
	            // screen, which impacts performance if do not throttle them.
	            this._throttledZrFlush();
	        }

	        flushPendingActions.call(this, opt.silent);

	        triggerUpdatedEvent.call(this, opt.silent);
	    };

	    function doDispatchAction(payload, silent) {
	        var payloadType = payload.type;
	        var escapeConnect = payload.escapeConnect;
	        var actionWrap = actions[payloadType];
	        var actionInfo = actionWrap.actionInfo;

	        var cptType = (actionInfo.update || 'update').split(':');
	        var updateMethod = cptType.pop();
	        cptType = cptType[0] != null && parseClassType(cptType[0]);

	        this[IN_MAIN_PROCESS] = true;

	        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 isHighDown = payloadType === 'highlight' || payloadType === 'downplay';

	        each(payloads, function (batchItem) {
	            // Action can specify the event by return it.
	            eventObj = actionWrap.action(batchItem, this._model, this._api);
	            // Emit event outside
	            eventObj = eventObj || zrUtil.extend({}, batchItem);
	            // Convert type to eventType
	            eventObj.type = actionInfo.event || eventObj.type;
	            eventObjBatch.push(eventObj);

	            // light update does not perform data process, layout and visual.
	            if (isHighDown) {
	                // method, payload, mainType, subType
	                updateDirectly(this, updateMethod, batchItem, 'series');
	            }
	            else if (cptType) {
	                updateDirectly(this, updateMethod, batchItem, cptType.main, cptType.sub);
	            }
	        }, this);

	        if (updateMethod !== 'none' && !isHighDown && !cptType) {
	            // Still dirty
	            if (this[OPTION_UPDATED]) {
	                // FIXME Pass payload ?
	                updateMethods.prepareAndUpdate.call(this, payload);
	                this[OPTION_UPDATED] = false;
	            }
	            else {
	                updateMethods[updateMethod].call(this, payload);
	            }
	        }

	        // Follow the rule of action batch
	        if (batched) {
	            eventObj = {
	                type: actionInfo.event || payloadType,
	                escapeConnect: escapeConnect,
	                batch: eventObjBatch
	            };
	        }
	        else {
	            eventObj = eventObjBatch[0];
	        }

	        this[IN_MAIN_PROCESS] = false;

	        !silent && this._messageCenter.trigger(eventObj.type, eventObj);
	    }

	    function flushPendingActions(silent) {
	        var pendingActions = this._pendingActions;
	        while (pendingActions.length) {
	            var payload = pendingActions.shift();
	            doDispatchAction.call(this, payload, silent);
	        }
	    }

	    function triggerUpdatedEvent(silent) {
	        !silent && this.trigger('updated');
	    }

	    /**
	     * 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);

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

	        // If use hover layer
	        updateHoverLayerStatus(this._zr, ecModel);

	        // Post render
	        each(postUpdateFuncs, function (func) {
	            func(ecModel, api);
	        });
	    }

	    /**
	     * 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 = '_ec_' + model.id + '_' + model.type;
	            var view = viewMap[viewId];
	            if (!view) {
	                var classType = 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 = view.__id = viewId;
	            view.__alive = true;
	            view.__model = model;
	            view.group.__ecComponentInfo = {
	                mainType: model.mainType,
	                index: model.componentIndex
	            };
	        }, 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];
	                view.__id = view.group.__ecComponentInfo = null;
	            }
	            else {
	                i++;
	            }
	        }
	    }

	    /**
	     * Processor data in each series
	     *
	     * @param {module:echarts/model/Global} ecModel
	     * @private
	     */
	    function processData(ecModel, api) {
	        each(dataProcessorFuncs, function (process) {
	            process.func(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];
	                // Avoid conflict with Object.prototype
	                if (stackedDataMap.hasOwnProperty(stack) && previousStack) {
	                    data.stackedOn = previousStack;
	                }
	                stackedDataMap[stack] = data;
	            }
	        });
	    }

	    /**
	     * Layout before each chart render there series, special visual encoding stage
	     *
	     * @param {module:echarts/model/Global} ecModel
	     * @private
	     */
	    function doLayout(ecModel, payload) {
	        var api = this._api;
	        each(visualFuncs, function (visual) {
	            if (visual.isLayout) {
	                visual.func(ecModel, api, payload);
	            }
	        });
	    }

	    /**
	     * Encode visual infomation from data after data processing
	     *
	     * @param {module:echarts/model/Global} ecModel
	     * @param {object} layout
	     * @param {boolean} [excludesLayout]
	     * @private
	     */
	    function doVisualEncoding(ecModel, payload, excludesLayout) {
	        var api = this._api;
	        ecModel.clearColorPalette();
	        ecModel.eachSeries(function (seriesModel) {
	            seriesModel.clearColorPalette();
	        });
	        each(visualFuncs, function (visual) {
	            (!excludesLayout || !visual.isLayout)
	                && visual.func(ecModel, api, 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);

	            updateProgressiveAndBlend(seriesModel, chartView);

	        }, this);

	        // If use hover layer
	        updateHoverLayerStatus(this._zr, ecModel);

	        // 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', 'mousemove',
	        'mousedown', 'mouseup', 'globalout', 'contextmenu'
	    ];
	    /**
	     * @private
	     */
	    echartsProto._initEvents = function () {
	        each(MOUSE_EVENT_NAMES, function (eveName) {
	            this._zr.on(eveName, function (e) {
	                var ecModel = this.getModel();
	                var el = e.target;
	                var params;

	                // no e.target when 'globalout'.
	                if (eveName === 'globalout') {
	                    params = {};
	                }
	                else if (el && el.dataIndex != null) {
	                    var dataModel = el.dataModel || ecModel.getSeriesByIndex(el.seriesIndex);
	                    params = dataModel && dataModel.getDataParams(el.dataIndex, el.dataType) || {};
	                }
	                // If element has custom eventData of components
	                else if (el && el.eventData) {
	                    params = zrUtil.extend({}, el.eventData);
	                }

	                if (params) {
	                    params.event = e;
	                    params.type = eveName;
	                    this.trigger(eveName, params);
	                }

	            }, 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({ series: [] }, true);
	    };

	    /**
	     * Dispose instance
	     */
	    echartsProto.dispose = function () {
	        if (this._disposed) {
	            if (true) {
	                console.warn('Instance ' + this.id + ' has been disposed');
	            }
	            return;
	        }
	        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);
	        });

	        // Dispose after all views disposed
	        this._zr.dispose();

	        delete instances[this.id];
	    };

	    zrUtil.mixin(ECharts, Eventful);

	    function updateHoverLayerStatus(zr, ecModel) {
	        var storage = zr.storage;
	        var elCount = 0;
	        storage.traverse(function (el) {
	            if (!el.isGroup) {
	                elCount++;
	            }
	        });
	        if (elCount > ecModel.get('hoverLayerThreshold') && !env.node) {
	            storage.traverse(function (el) {
	                if (!el.isGroup) {
	                    el.useHoverLayer = true;
	                }
	            });
	        }
	    }

	    /**
	     * Update chart progressive and blend.
	     * @param {module:echarts/model/Series|module:echarts/model/Component} model
	     * @param {module:echarts/view/Component|module:echarts/view/Chart} view
	     */
	    function updateProgressiveAndBlend(seriesModel, chartView) {
	        // Progressive configuration
	        var elCount = 0;
	        chartView.group.traverse(function (el) {
	            if (el.type !== 'group' && !el.ignore) {
	                elCount++;
	            }
	        });
	        var frameDrawNum = +seriesModel.get('progressive');
	        var needProgressive = elCount > seriesModel.get('progressiveThreshold') && frameDrawNum && !env.node;
	        if (needProgressive) {
	            chartView.group.traverse(function (el) {
	                // FIXME marker and other components
	                if (!el.isGroup) {
	                    el.progressive = needProgressive ?
	                        Math.floor(elCount++ / frameDrawNum) : -1;
	                    if (needProgressive) {
	                        el.stopAnimation(true);
	                    }
	                }
	            });
	        }

	        // Blend configration
	        var blendMode = seriesModel.get('blendMode') || null;
	        if (true) {
	            if (!env.canvasSupported && blendMode && blendMode !== 'source-over') {
	                console.warn('Only canvas support blendMode');
	            }
	        }
	        chartView.group.traverse(function (el) {
	            // FIXME marker and other components
	            if (!el.isGroup) {
	                el.setStyle('blend', blendMode);
	            }
	        });
	    }

	    /**
	     * @param {module:echarts/model/Series|module:echarts/model/Component} model
	     * @param {module:echarts/view/Component|module:echarts/view/Chart} view
	     */
	    function updateZ(model, view) {
	        var z = model.get('z');
	        var zlevel = model.get('zlevel');
	        // Set z and zlevel
	        view.group.traverse(function (el) {
	            if (el.type !== 'group') {
	                z != null && (el.z = z);
	                zlevel != null && (el.zlevel = zlevel);
	            }
	        });
	    }

	    function createExtensionAPI(ecInstance) {
	        var coordSysMgr = ecInstance._coordSysMgr;
	        return zrUtil.extend(new ExtensionAPI(ecInstance), {
	            // Inject methods
	            getCoordinateSystems: zrUtil.bind(
	                coordSysMgr.getCoordinateSystems, coordSysMgr
	            ),
	            getComponentByElement: function (el) {
	                while (el) {
	                    var modelInfo = el.__ecComponentInfo;
	                    if (modelInfo != null) {
	                        return ecInstance._model.getComponent(modelInfo.mainType, modelInfo.index);
	                    }
	                    el = el.parent;
	                }
	            }
	        });
	    }

	    /**
	     * @type {Object} key: actionType.
	     * @inner
	     */
	    var actions = {};

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

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

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

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

	    /**
	     * Visual encoding functions of each stage
	     * @type {Array.<Object.<string, Function>>}
	     * @inner
	     */
	    var visualFuncs = [];
	    /**
	     * Theme storage
	     * @type {Object.<key, Object>}
	     */
	    var themeStorage = {};
	    /**
	     * Loading effects
	     */
	    var loadingEffects = {};


	    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.6.2',
	        dependencies: {
	            zrender: '3.5.2'
	        }
	    };

	    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) {
	                    if (event && event.escapeConnect) {
	                        return;
	                    }

	                    var action = chart.makeActionFromEvent(event);
	                    var otherCharts = [];

	                    zrUtil.each(instances, function (otherChart) {
	                        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
	     * @param {number} [opts.devicePixelRatio] Use window.devicePixelRatio by default
	     * @param {string} [opts.renderer] Currently only 'canvas' is supported.
	     * @param {number} [opts.width] Use clientWidth of the input `dom` by default.
	     *                              Can be 'auto' (the same as null/undefined)
	     * @param {number} [opts.height] Use clientHeight of the input `dom` by default.
	     *                               Can be 'auto' (the same as null/undefined)
	     */
	    echarts.init = function (dom, theme, opts) {
	        if (true) {
	            // 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 existInstance = echarts.getInstanceByDom(dom);
	        if (existInstance) {
	            if (true) {
	                console.warn('There is a chart instance already initialized on the dom.');
	            }
	            return existInstance;
	        }

	        if (true) {
	            if (zrUtil.isDom(dom)
	                && dom.nodeName.toUpperCase() !== 'CANVAS'
	                && (
	                    (!dom.clientWidth && (!opts || opts.width == null))
	                    || (!dom.clientHeight && (!opts || opts.height == null))
	                )
	            ) {
	                console.warn('Can\'t get dom width or height');
	            }
	        }

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

	        if (dom.setAttribute) {
	            dom.setAttribute(DOM_ATTRIBUTE_KEY, chart.id);
	        }
	        else {
	            dom[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;
	    };

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

	    /**
	     * @return {string} groupId
	     */
	    echarts.disconnect = echarts.disConnect;

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

	    /**
	     * @param  {HTMLDomElement} dom
	     * @return {echarts~ECharts}
	     */
	    echarts.getInstanceByDom = function (dom) {
	        var key;
	        if (dom.getAttribute) {
	            key = dom.getAttribute(DOM_ATTRIBUTE_KEY);
	        }
	        else {
	            key = dom[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 {number} [priority=1000]
	     * @param {Function} processorFunc
	     */
	    echarts.registerProcessor = function (priority, processorFunc) {
	        if (typeof priority === 'function') {
	            processorFunc = priority;
	            priority = PRIORITY_PROCESSOR_FILTER;
	        }
	        if (true) {
	            if (isNaN(priority)) {
	                throw new Error('Unkown processor priority');
	            }
	        }
	        dataProcessorFuncs.push({
	            prio: priority,
	            func: processorFunc
	        });
	    };

	    /**
	     * Register postUpdater
	     * @param {Function} postUpdateFunc
	     */
	    echarts.registerPostUpdate = function (postUpdateFunc) {
	        postUpdateFuncs.push(postUpdateFunc);
	    };

	    /**
	     * 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;

	        // Validate action type and event name.
	        zrUtil.assert(ACTION_REG.test(actionType) && ACTION_REG.test(eventName));

	        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);
	    };

	    /**
	     * Get dimensions of specified coordinate system.
	     * @param {string} type
	     * @return {Array.<string|Object>}
	     */
	    echarts.getCoordinateSystemDimensions = function (type) {
	        var coordSysCreator = CoordinateSystemManager.get(type);
	        if (coordSysCreator) {
	            return coordSysCreator.getDimensionsInfo
	                    ? coordSysCreator.getDimensionsInfo()
	                    : coordSysCreator.dimensions.slice();
	        }
	    };

	    /**
	     * Layout is a special stage of visual encoding
	     * Most visual encoding like color are common for different chart
	     * But each chart has it's own layout algorithm
	     *
	     * @param {number} [priority=1000]
	     * @param {Function} layoutFunc
	     */
	    echarts.registerLayout = function (priority, layoutFunc) {
	        if (typeof priority === 'function') {
	            layoutFunc = priority;
	            priority = PRIORITY_VISUAL_LAYOUT;
	        }
	        if (true) {
	            if (isNaN(priority)) {
	                throw new Error('Unkown layout priority');
	            }
	        }
	        visualFuncs.push({
	            prio: priority,
	            func: layoutFunc,
	            isLayout: true
	        });
	    };

	    /**
	     * @param {number} [priority=3000]
	     * @param {Function} visualFunc
	     */
	    echarts.registerVisual = function (priority, visualFunc) {
	        if (typeof priority === 'function') {
	            visualFunc = priority;
	            priority = PRIORITY_VISUAL_CHART;
	        }
	        if (true) {
	            if (isNaN(priority)) {
	                throw new Error('Unkown visual priority');
	            }
	        }
	        visualFuncs.push({
	            prio: priority,
	            func: visualFunc
	        });
	    };

	    /**
	     * @param {string} name
	     */
	    echarts.registerLoading = function (name, loadingFx) {
	        loadingEffects[name] = loadingFx;
	    };

	    /**
	     * @param {Object} opts
	     * @param {string} [superClass]
	     */
	    echarts.extendComponentModel = function (opts/*, superClass*/) {
	        // var Clazz = ComponentModel;
	        // if (superClass) {
	        //     var classType = parseClassType(superClass);
	        //     Clazz = ComponentModel.getClass(classType.main, classType.sub, true);
	        // }
	        return ComponentModel.extend(opts);
	    };

	    /**
	     * @param {Object} opts
	     * @param {string} [superClass]
	     */
	    echarts.extendComponentView = function (opts/*, superClass*/) {
	        // var Clazz = ComponentView;
	        // if (superClass) {
	        //     var classType = parseClassType(superClass);
	        //     Clazz = ComponentView.getClass(classType.main, classType.sub, true);
	        // }
	        return ComponentView.extend(opts);
	    };

	    /**
	     * @param {Object} opts
	     * @param {string} [superClass]
	     */
	    echarts.extendSeriesModel = function (opts/*, superClass*/) {
	        // var Clazz = SeriesModel;
	        // if (superClass) {
	        //     superClass = 'series.' + superClass.replace('series.', '');
	        //     var classType = parseClassType(superClass);
	        //     Clazz = ComponentModel.getClass(classType.main, classType.sub, true);
	        // }
	        return SeriesModel.extend(opts);
	    };

	    /**
	     * @param {Object} opts
	     * @param {string} [superClass]
	     */
	    echarts.extendChartView = function (opts/*, superClass*/) {
	        // var Clazz = ChartView;
	        // if (superClass) {
	        //     superClass = superClass.replace('series.', '');
	        //     var classType = parseClassType(superClass);
	        //     Clazz = ChartView.getClass(classType.main, true);
	        // }
	        return ChartView.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.registerVisual(PRIORITY_VISUAL_GLOBAL, __webpack_require__(94));
	    echarts.registerPreprocessor(__webpack_require__(95));
	    echarts.registerLoading('default', __webpack_require__(97));

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


	    // --------
	    // Exports
	    // --------
	    echarts.zrender = zrender;

	    echarts.List = __webpack_require__(98);
	    echarts.Model = __webpack_require__(12);

	    echarts.Axis = __webpack_require__(100);

	    echarts.graphic = __webpack_require__(18);
	    echarts.number = __webpack_require__(7);
	    echarts.format = __webpack_require__(6);
	    echarts.throttle = throttle.throttle;
	    echarts.matrix = __webpack_require__(11);
	    echarts.vector = __webpack_require__(10);
	    echarts.color = __webpack_require__(31);

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

	    echarts.helper = __webpack_require__(108);


	    // PRIORITY
	    echarts.PRIORITY = {
	        PROCESSOR: {
	            FILTER: PRIORITY_PROCESSOR_FILTER,
	            STATISTIC: PRIORITY_PROCESSOR_STATISTIC
	        },
	        VISUAL: {
	            LAYOUT: PRIORITY_VISUAL_LAYOUT,
	            GLOBAL: PRIORITY_VISUAL_GLOBAL,
	            CHART: PRIORITY_VISUAL_CHART,
	            COMPONENT: PRIORITY_VISUAL_COMPONENT,
	            BRUSH: PRIORITY_VISUAL_BRUSH
	        }
	    };

	    module.exports = echarts;


/***/ },
/* 2 */
/***/ function(module, exports) {

	/**
	 * echarts设备环境识别
	 *
	 * @desc echarts基于Canvas，纯Javascript图表库，提供直观，生动，可交互，可个性化定制的数据统计图表。
	 * @author firede[firede@firede.us]
	 * @desc thanks zepto.
	 */

	    var env = {};
	    if (typeof navigator === 'undefined') {
	        // In node
	        env = {
	            browser: {},
	            os: {},
	            node: true,
	            // Assume canvas is supported
	            canvasSupported: true
	        };
	    }
	    else {
	        env = detect(navigator.userAgent);
	    }

	    module.exports = env;

	    // Zepto.js
	    // (c) 2010-2013 Thomas Fuchs
	    // Zepto.js may be freely distributed under the MIT license.

	    function detect(ua) {
	        var os = {};
	        var browser = {};
	        // var webkit = ua.match(/Web[kK]it[\/]{0,1}([\d.]+)/);
	        // var android = ua.match(/(Android);?[\s\/]+([\d.]+)?/);
	        // var ipad = ua.match(/(iPad).*OS\s([\d_]+)/);
	        // var ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/);
	        // var iphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/);
	        // var webos = ua.match(/(webOS|hpwOS)[\s\/]([\d.]+)/);
	        // var touchpad = webos && ua.match(/TouchPad/);
	        // var kindle = ua.match(/Kindle\/([\d.]+)/);
	        // var silk = ua.match(/Silk\/([\d._]+)/);
	        // var blackberry = ua.match(/(BlackBerry).*Version\/([\d.]+)/);
	        // var bb10 = ua.match(/(BB10).*Version\/([\d.]+)/);
	        // var rimtabletos = ua.match(/(RIM\sTablet\sOS)\s([\d.]+)/);
	        // var playbook = ua.match(/PlayBook/);
	        // var chrome = ua.match(/Chrome\/([\d.]+)/) || ua.match(/CriOS\/([\d.]+)/);
	        var firefox = ua.match(/Firefox\/([\d.]+)/);
	        // var safari = webkit && ua.match(/Mobile\//) && !chrome;
	        // var webview = ua.match(/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/) && !chrome;
	        var ie = ua.match(/MSIE\s([\d.]+)/)
	            // IE 11 Trident/7.0; rv:11.0
	            || ua.match(/Trident\/.+?rv:(([\d.]+))/);
	        var edge = ua.match(/Edge\/([\d.]+)/); // IE 12 and 12+

	        var weChat = (/micromessenger/i).test(ua);

	        // Todo: clean this up with a better OS/browser seperation:
	        // - discern (more) between multiple browsers on android
	        // - decide if kindle fire in silk mode is android or not
	        // - Firefox on Android doesn't specify the Android version
	        // - possibly devide in os, device and browser hashes

	        // if (browser.webkit = !!webkit) browser.version = webkit[1];

	        // if (android) os.android = true, os.version = android[2];
	        // if (iphone && !ipod) os.ios = os.iphone = true, os.version = iphone[2].replace(/_/g, '.');
	        // if (ipad) os.ios = os.ipad = true, os.version = ipad[2].replace(/_/g, '.');
	        // if (ipod) os.ios = os.ipod = true, os.version = ipod[3] ? ipod[3].replace(/_/g, '.') : null;
	        // if (webos) os.webos = true, os.version = webos[2];
	        // if (touchpad) os.touchpad = true;
	        // if (blackberry) os.blackberry = true, os.version = blackberry[2];
	        // if (bb10) os.bb10 = true, os.version = bb10[2];
	        // if (rimtabletos) os.rimtabletos = true, os.version = rimtabletos[2];
	        // if (playbook) browser.playbook = true;
	        // if (kindle) os.kindle = true, os.version = kindle[1];
	        // if (silk) browser.silk = true, browser.version = silk[1];
	        // if (!silk && os.android && ua.match(/Kindle Fire/)) browser.silk = true;
	        // if (chrome) browser.chrome = true, browser.version = chrome[1];
	        if (firefox) {
	            browser.firefox = true;
	            browser.version = firefox[1];
	        }
	        // if (safari && (ua.match(/Safari/) || !!os.ios)) browser.safari = true;
	        // if (webview) browser.webview = true;

	        if (ie) {
	            browser.ie = true;
	            browser.version = ie[1];
	        }

	        if (edge) {
	            browser.edge = true;
	            browser.version = edge[1];
	        }

	        // It is difficult to detect WeChat in Win Phone precisely, because ua can
	        // not be set on win phone. So we do not consider Win Phone.
	        if (weChat) {
	            browser.weChat = true;
	        }

	        // os.tablet = !!(ipad || playbook || (android && !ua.match(/Mobile/)) ||
	        //     (firefox && ua.match(/Tablet/)) || (ie && !ua.match(/Phone/) && ua.match(/Touch/)));
	        // os.phone  = !!(!os.tablet && !os.ipod && (android || iphone || webos ||
	        //     (chrome && ua.match(/Android/)) || (chrome && ua.match(/CriOS\/([\d.]+)/)) ||
	        //     (firefox && ua.match(/Mobile/)) || (ie && ua.match(/Touch/))));

	        return {
	            browser: browser,
	            os: os,
	            node: false,
	            // 原生canvas支持，改极端点了
	            // canvasSupported : !(browser.ie && parseFloat(browser.version) < 9)
	            canvasSupported : document.createElement('canvas').getContext ? true : false,
	            // @see <http://stackoverflow.com/questions/4817029/whats-the-best-way-to-detect-a-touch-screen-device-using-javascript>
	            // works on most browsers
	            // IE10/11 does not support touch event, and MS Edge supports them but not by
	            // default, so we dont check navigator.maxTouchPoints for them here.
	            touchEventsSupported: 'ontouchstart' in window && !browser.ie && !browser.edge,
	            // <http://caniuse.com/#search=pointer%20event>.
	            pointerEventsSupported: 'onpointerdown' in window
	                // Firefox supports pointer but not by default, only MS browsers are reliable on pointer
	                // events currently. So we dont use that on other browsers unless tested sufficiently.
	                // Although IE 10 supports pointer event, it use old style and is different from the
	                // standard. So we exclude that. (IE 10 is hardly used on touch device)
	                && (browser.edge || (browser.ie && browser.version >= 11))
	        };
	    }


/***/ },
/* 3 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * ECharts global model
	 *
	 * @module {echarts/model/Global}
	 */



	    /**
	     * Caution: If the mechanism should be changed some day, these cases
	     * should be considered:
	     *
	     * (1) In `merge option` mode, if using the same option to call `setOption`
	     * many times, the result should be the same (try our best to ensure that).
	     * (2) In `merge option` mode, if a component has no id/name specified, it
	     * will be merged by index, and the result sequence of the components is
	     * consistent to the original sequence.
	     * (3) `reset` feature (in toolbox). Find detailed info in comments about
	     * `mergeOption` in module:echarts/model/OptionManager.
	     */

	    var zrUtil = __webpack_require__(4);
	    var modelUtil = __webpack_require__(5);
	    var Model = __webpack_require__(12);
	    var each = zrUtil.each;
	    var filter = zrUtil.filter;
	    var map = zrUtil.map;
	    var isArray = zrUtil.isArray;
	    var indexOf = zrUtil.indexOf;
	    var isObject = zrUtil.isObject;

	    var ComponentModel = __webpack_require__(69);

	    var globalDefault = __webpack_require__(73);

	    var OPTION_INNER_KEY = '\0_ec_inner';

	    /**
	     * @alias module:echarts/model/Global
	     *
	     * @param {Object} option
	     * @param {module:echarts/model/Model} parentModel
	     * @param {Object} theme
	     */
	    var GlobalModel = Model.extend({

	        constructor: GlobalModel,

	        init: function (option, parentModel, theme, optionManager) {
	            theme = theme || {};

	            this.option = null; // Mark as not initialized.

	            /**
	             * @type {module:echarts/model/Model}
	             * @private
	             */
	            this._theme = new Model(theme);

	            /**
	             * @type {module:echarts/model/OptionManager}
	             */
	            this._optionManager = optionManager;
	        },

	        setOption: function (option, optionPreprocessorFuncs) {
	            zrUtil.assert(
	                !(OPTION_INNER_KEY in option),
	                'please use chart.getOption()'
	            );

	            this._optionManager.setOption(option, optionPreprocessorFuncs);

	            this.resetOption(null);
	        },

	        /**
	         * @param {string} type null/undefined: reset all.
	         *                      'recreate': force recreate all.
	         *                      'timeline': only reset timeline option
	         *                      'media': only reset media query option
	         * @return {boolean} Whether option changed.
	         */
	        resetOption: function (type) {
	            var optionChanged = false;
	            var optionManager = this._optionManager;

	            if (!type || type === 'recreate') {
	                var baseOption = optionManager.mountOption(type === 'recreate');

	                if (!this.option || type === 'recreate') {
	                    initBase.call(this, baseOption);
	                }
	                else {
	                    this.restoreData();
	                    this.mergeOption(baseOption);
	                }
	                optionChanged = true;
	            }

	            if (type === 'timeline' || type === 'media') {
	                this.restoreData();
	            }

	            if (!type || type === 'recreate' || type === 'timeline') {
	                var timelineOption = optionManager.getTimelineOption(this);
	                timelineOption && (this.mergeOption(timelineOption), optionChanged = true);
	            }

	            if (!type || type === 'recreate' || type === 'media') {
	                var mediaOptions = optionManager.getMediaOption(this, this._api);
	                if (mediaOptions.length) {
	                    each(mediaOptions, function (mediaOption) {
	                        this.mergeOption(mediaOption, optionChanged = true);
	                    }, this);
	                }
	            }

	            return optionChanged;
	        },

	        /**
	         * @protected
	         */
	        mergeOption: function (newOption) {
	            var option = this.option;
	            var componentsMap = this._componentsMap;
	            var newCptTypes = [];

	            // 如果不存在对应的 component model 则直接 merge
	            each(newOption, function (componentOption, mainType) {
	                if (componentOption == null) {
	                    return;
	                }

	                if (!ComponentModel.hasClass(mainType)) {
	                    option[mainType] = option[mainType] == null
	                        ? zrUtil.clone(componentOption)
	                        : zrUtil.merge(option[mainType], componentOption, true);
	                }
	                else {
	                    newCptTypes.push(mainType);
	                }
	            });

	            // FIXME OPTION 同步是否要改回原来的
	            ComponentModel.topologicalTravel(
	                newCptTypes, ComponentModel.getAllClassMainTypes(), visitComponent, this
	            );

	            this._seriesIndices = this._seriesIndices || [];

	            function visitComponent(mainType, dependencies) {
	                var newCptOptionList = modelUtil.normalizeToArray(newOption[mainType]);

	                var mapResult = modelUtil.mappingToExists(
	                    componentsMap.get(mainType), newCptOptionList
	                );

	                modelUtil.makeIdAndName(mapResult);

	                // Set mainType and complete subType.
	                each(mapResult, function (item, index) {
	                    var opt = item.option;
	                    if (isObject(opt)) {
	                        item.keyInfo.mainType = mainType;
	                        item.keyInfo.subType = determineSubType(mainType, opt, item.exist);
	                    }
	                });

	                var dependentModels = getComponentsByTypes(
	                    componentsMap, dependencies
	                );

	                option[mainType] = [];
	                componentsMap.set(mainType, []);

	                each(mapResult, function (resultItem, index) {
	                    var componentModel = resultItem.exist;
	                    var newCptOption = resultItem.option;

	                    zrUtil.assert(
	                        isObject(newCptOption) || componentModel,
	                        'Empty component definition'
	                    );

	                    // Consider where is no new option and should be merged using {},
	                    // see removeEdgeAndAdd in topologicalTravel and
	                    // ComponentModel.getAllClassMainTypes.
	                    if (!newCptOption) {
	                        componentModel.mergeOption({}, this);
	                        componentModel.optionUpdated({}, false);
	                    }
	                    else {
	                        var ComponentModelClass = ComponentModel.getClass(
	                            mainType, resultItem.keyInfo.subType, true
	                        );

	                        if (componentModel && componentModel instanceof ComponentModelClass) {
	                            componentModel.name = resultItem.keyInfo.name;
	                            componentModel.mergeOption(newCptOption, this);
	                            componentModel.optionUpdated(newCptOption, false);
	                        }
	                        else {
	                            // PENDING Global as parent ?
	                            var extraOpt = zrUtil.extend(
	                                {
	                                    dependentModels: dependentModels,
	                                    componentIndex: index
	                                },
	                                resultItem.keyInfo
	                            );
	                            componentModel = new ComponentModelClass(
	                                newCptOption, this, this, extraOpt
	                            );
	                            zrUtil.extend(componentModel, extraOpt);
	                            componentModel.init(newCptOption, this, this, extraOpt);
	                            // Call optionUpdated after init.
	                            // newCptOption has been used as componentModel.option
	                            // and may be merged with theme and default, so pass null
	                            // to avoid confusion.
	                            componentModel.optionUpdated(null, true);
	                        }
	                    }

	                    componentsMap.get(mainType)[index] = componentModel;
	                    option[mainType][index] = componentModel.option;
	                }, this);

	                // Backup series for filtering.
	                if (mainType === 'series') {
	                    this._seriesIndices = createSeriesIndices(componentsMap.get('series'));
	                }
	            }
	        },

	        /**
	         * Get option for output (cloned option and inner info removed)
	         * @public
	         * @return {Object}
	         */
	        getOption: function () {
	            var option = zrUtil.clone(this.option);

	            each(option, function (opts, mainType) {
	                if (ComponentModel.hasClass(mainType)) {
	                    var opts = modelUtil.normalizeToArray(opts);
	                    for (var i = opts.length - 1; i >= 0; i--) {
	                        // Remove options with inner id.
	                        if (modelUtil.isIdInner(opts[i])) {
	                            opts.splice(i, 1);
	                        }
	                    }
	                    option[mainType] = opts;
	                }
	            });

	            delete option[OPTION_INNER_KEY];

	            return option;
	        },

	        /**
	         * @return {module:echarts/model/Model}
	         */
	        getTheme: function () {
	            return this._theme;
	        },

	        /**
	         * @param {string} mainType
	         * @param {number} [idx=0]
	         * @return {module:echarts/model/Component}
	         */
	        getComponent: function (mainType, idx) {
	            var list = this._componentsMap.get(mainType);
	            if (list) {
	                return list[idx || 0];
	            }
	        },

	        /**
	         * If none of index and id and name used, return all components with mainType.
	         * @param {Object} condition
	         * @param {string} condition.mainType
	         * @param {string} [condition.subType] If ignore, only query by mainType
	         * @param {number|Array.<number>} [condition.index] Either input index or id or name.
	         * @param {string|Array.<string>} [condition.id] Either input index or id or name.
	         * @param {string|Array.<string>} [condition.name] Either input index or id or name.
	         * @return {Array.<module:echarts/model/Component>}
	         */
	        queryComponents: function (condition) {
	            var mainType = condition.mainType;
	            if (!mainType) {
	                return [];
	            }

	            var index = condition.index;
	            var id = condition.id;
	            var name = condition.name;

	            var cpts = this._componentsMap.get(mainType);

	            if (!cpts || !cpts.length) {
	                return [];
	            }

	            var result;

	            if (index != null) {
	                if (!isArray(index)) {
	                    index = [index];
	                }
	                result = filter(map(index, function (idx) {
	                    return cpts[idx];
	                }), function (val) {
	                    return !!val;
	                });
	            }
	            else if (id != null) {
	                var isIdArray = isArray(id);
	                result = filter(cpts, function (cpt) {
	                    return (isIdArray && indexOf(id, cpt.id) >= 0)
	                        || (!isIdArray && cpt.id === id);
	                });
	            }
	            else if (name != null) {
	                var isNameArray = isArray(name);
	                result = filter(cpts, function (cpt) {
	                    return (isNameArray && indexOf(name, cpt.name) >= 0)
	                        || (!isNameArray && cpt.name === name);
	                });
	            }
	            else {
	                // Return all components with mainType
	                result = cpts.slice();
	            }

	            return filterBySubType(result, condition);
	        },

	        /**
	         * The interface is different from queryComponents,
	         * which is convenient for inner usage.
	         *
	         * @usage
	         * var result = findComponents(
	         *     {mainType: 'dataZoom', query: {dataZoomId: 'abc'}}
	         * );
	         * var result = findComponents(
	         *     {mainType: 'series', subType: 'pie', query: {seriesName: 'uio'}}
	         * );
	         * var result = findComponents(
	         *     {mainType: 'series'},
	         *     function (model, index) {...}
	         * );
	         * // result like [component0, componnet1, ...]
	         *
	         * @param {Object} condition
	         * @param {string} condition.mainType Mandatory.
	         * @param {string} [condition.subType] Optional.
	         * @param {Object} [condition.query] like {xxxIndex, xxxId, xxxName},
	         *        where xxx is mainType.
	         *        If query attribute is null/undefined or has no index/id/name,
	         *        do not filtering by query conditions, which is convenient for
	         *        no-payload situations or when target of action is global.
	         * @param {Function} [condition.filter] parameter: component, return boolean.
	         * @return {Array.<module:echarts/model/Component>}
	         */
	        findComponents: function (condition) {
	            var query = condition.query;
	            var mainType = condition.mainType;

	            var queryCond = getQueryCond(query);
	            var result = queryCond
	                ? this.queryComponents(queryCond)
	                : this._componentsMap.get(mainType);

	            return doFilter(filterBySubType(result, condition));

	            function getQueryCond(q) {
	                var indexAttr = mainType + 'Index';
	                var idAttr = mainType + 'Id';
	                var nameAttr = mainType + 'Name';
	                return q && (
	                        q[indexAttr] != null
	                        || q[idAttr] != null
	                        || q[nameAttr] != null
	                    )
	                    ? {
	                        mainType: mainType,
	                        // subType will be filtered finally.
	                        index: q[indexAttr],
	                        id: q[idAttr],
	                        name: q[nameAttr]
	                    }
	                    : null;
	            }

	            function doFilter(res) {
	                return condition.filter
	                     ? filter(res, condition.filter)
	                     : res;
	            }
	        },

	        /**
	         * @usage
	         * eachComponent('legend', function (legendModel, index) {
	         *     ...
	         * });
	         * eachComponent(function (componentType, model, index) {
	         *     // componentType does not include subType
	         *     // (componentType is 'xxx' but not 'xxx.aa')
	         * });
	         * eachComponent(
	         *     {mainType: 'dataZoom', query: {dataZoomId: 'abc'}},
	         *     function (model, index) {...}
	         * );
	         * eachComponent(
	         *     {mainType: 'series', subType: 'pie', query: {seriesName: 'uio'}},
	         *     function (model, index) {...}
	         * );
	         *
	         * @param {string|Object=} mainType When mainType is object, the definition
	         *                                  is the same as the method 'findComponents'.
	         * @param {Function} cb
	         * @param {*} context
	         */
	        eachComponent: function (mainType, cb, context) {
	            var componentsMap = this._componentsMap;

	            if (typeof mainType === 'function') {
	                context = cb;
	                cb = mainType;
	                componentsMap.each(function (components, componentType) {
	                    each(components, function (component, index) {
	                        cb.call(context, componentType, component, index);
	                    });
	                });
	            }
	            else if (zrUtil.isString(mainType)) {
	                each(componentsMap.get(mainType), cb, context);
	            }
	            else if (isObject(mainType)) {
	                var queryResult = this.findComponents(mainType);
	                each(queryResult, cb, context);
	            }
	        },

	        /**
	         * @param {string} name
	         * @return {Array.<module:echarts/model/Series>}
	         */
	        getSeriesByName: function (name) {
	            var series = this._componentsMap.get('series');
	            return filter(series, function (oneSeries) {
	                return oneSeries.name === name;
	            });
	        },

	        /**
	         * @param {number} seriesIndex
	         * @return {module:echarts/model/Series}
	         */
	        getSeriesByIndex: function (seriesIndex) {
	            return this._componentsMap.get('series')[seriesIndex];
	        },

	        /**
	         * @param {string} subType
	         * @return {Array.<module:echarts/model/Series>}
	         */
	        getSeriesByType: function (subType) {
	            var series = this._componentsMap.get('series');
	            return filter(series, function (oneSeries) {
	                return oneSeries.subType === subType;
	            });
	        },

	        /**
	         * @return {Array.<module:echarts/model/Series>}
	         */
	        getSeries: function () {
	            return this._componentsMap.get('series').slice();
	        },

	        /**
	         * After filtering, series may be different
	         * frome raw series.
	         *
	         * @param {Function} cb
	         * @param {*} context
	         */
	        eachSeries: function (cb, context) {
	            assertSeriesInitialized(this);
	            each(this._seriesIndices, function (rawSeriesIndex) {
	                var series = this._componentsMap.get('series')[rawSeriesIndex];
	                cb.call(context, series, rawSeriesIndex);
	            }, this);
	        },

	        /**
	         * Iterate raw series before filtered.
	         *
	         * @param {Function} cb
	         * @param {*} context
	         */
	        eachRawSeries: function (cb, context) {
	            each(this._componentsMap.get('series'), cb, context);
	        },

	        /**
	         * After filtering, series may be different.
	         * frome raw series.
	         *
	         * @parma {string} subType
	         * @param {Function} cb
	         * @param {*} context
	         */
	        eachSeriesByType: function (subType, cb, context) {
	            assertSeriesInitialized(this);
	            each(this._seriesIndices, function (rawSeriesIndex) {
	                var series = this._componentsMap.get('series')[rawSeriesIndex];
	                if (series.subType === subType) {
	                    cb.call(context, series, rawSeriesIndex);
	                }
	            }, this);
	        },

	        /**
	         * Iterate raw series before filtered of given type.
	         *
	         * @parma {string} subType
	         * @param {Function} cb
	         * @param {*} context
	         */
	        eachRawSeriesByType: function (subType, cb, context) {
	            return each(this.getSeriesByType(subType), cb, context);
	        },

	        /**
	         * @param {module:echarts/model/Series} seriesModel
	         */
	        isSeriesFiltered: function (seriesModel) {
	            assertSeriesInitialized(this);
	            return zrUtil.indexOf(this._seriesIndices, seriesModel.componentIndex) < 0;
	        },

	        /**
	         * @return {Array.<number>}
	         */
	        getCurrentSeriesIndices: function () {
	            return (this._seriesIndices || []).slice();
	        },

	        /**
	         * @param {Function} cb
	         * @param {*} context
	         */
	        filterSeries: function (cb, context) {
	            assertSeriesInitialized(this);
	            var filteredSeries = filter(
	                this._componentsMap.get('series'), cb, context
	            );
	            this._seriesIndices = createSeriesIndices(filteredSeries);
	        },

	        restoreData: function () {
	            var componentsMap = this._componentsMap;

	            this._seriesIndices = createSeriesIndices(componentsMap.get('series'));

	            var componentTypes = [];
	            componentsMap.each(function (components, componentType) {
	                componentTypes.push(componentType);
	            });

	            ComponentModel.topologicalTravel(
	                componentTypes,
	                ComponentModel.getAllClassMainTypes(),
	                function (componentType, dependencies) {
	                    each(componentsMap.get(componentType), function (component) {
	                        component.restoreData();
	                    });
	                }
	            );
	        }

	    });

	    /**
	     * @inner
	     */
	    function mergeTheme(option, theme) {
	        zrUtil.each(theme, function (themeItem, name) {
	            // 如果有 component model 则把具体的 merge 逻辑交给该 model 处理
	            if (!ComponentModel.hasClass(name)) {
	                if (typeof themeItem === 'object') {
	                    option[name] = !option[name]
	                        ? zrUtil.clone(themeItem)
	                        : zrUtil.merge(option[name], themeItem, false);
	                }
	                else {
	                    if (option[name] == null) {
	                        option[name] = themeItem;
	                    }
	                }
	            }
	        });
	    }

	    function initBase(baseOption) {
	        baseOption = baseOption;

	        // Using OPTION_INNER_KEY to mark that this option can not be used outside,
	        // i.e. `chart.setOption(chart.getModel().option);` is forbiden.
	        this.option = {};
	        this.option[OPTION_INNER_KEY] = 1;

	        /**
	         * Init with series: [], in case of calling findSeries method
	         * before series initialized.
	         * @type {Object.<string, Array.<module:echarts/model/Model>>}
	         * @private
	         */
	        this._componentsMap = zrUtil.createHashMap({series: []});

	        /**
	         * Mapping between filtered series list and raw series list.
	         * key: filtered series indices, value: raw series indices.
	         * @type {Array.<nubmer>}
	         * @private
	         */
	        this._seriesIndices = null;

	        mergeTheme(baseOption, this._theme.option);

	        // TODO Needs clone when merging to the unexisted property
	        zrUtil.merge(baseOption, globalDefault, false);

	        this.mergeOption(baseOption);
	    }

	    /**
	     * @inner
	     * @param {Array.<string>|string} types model types
	     * @return {Object} key: {string} type, value: {Array.<Object>} models
	     */
	    function getComponentsByTypes(componentsMap, types) {
	        if (!zrUtil.isArray(types)) {
	            types = types ? [types] : [];
	        }

	        var ret = {};
	        each(types, function (type) {
	            ret[type] = (componentsMap.get(type) || []).slice();
	        });

	        return ret;
	    }

	    /**
	     * @inner
	     */
	    function determineSubType(mainType, newCptOption, existComponent) {
	        var subType = newCptOption.type
	            ? newCptOption.type
	            : existComponent
	            ? existComponent.subType
	            // Use determineSubType only when there is no existComponent.
	            : ComponentModel.determineSubType(mainType, newCptOption);

	        // tooltip, markline, markpoint may always has no subType
	        return subType;
	    }

	    /**
	     * @inner
	     */
	    function createSeriesIndices(seriesModels) {
	        return map(seriesModels, function (series) {
	            return series.componentIndex;
	        }) || [];
	    }

	    /**
	     * @inner
	     */
	    function filterBySubType(components, condition) {
	        // Using hasOwnProperty for restrict. Consider
	        // subType is undefined in user payload.
	        return condition.hasOwnProperty('subType')
	            ? filter(components, function (cpt) {
	                return cpt.subType === condition.subType;
	            })
	            : components;
	    }

	    /**
	     * @inner
	     */
	    function assertSeriesInitialized(ecModel) {
	        // Components that use _seriesIndices should depends on series component,
	        // which make sure that their initialization is after series.
	        if (true) {
	            if (!ecModel._seriesIndices) {
	                throw new Error('Option should contains series.');
	            }
	        }
	    }

	    zrUtil.mixin(GlobalModel, __webpack_require__(74));

	    module.exports = GlobalModel;


/***/ },
/* 4 */
/***/ function(module, exports) {

	/**
	 * @module zrender/core/util
	 */


	    // 用于处理merge时无法遍历Date等对象的问题
	    var BUILTIN_OBJECT = {
	        '[object Function]': 1,
	        '[object RegExp]': 1,
	        '[object Date]': 1,
	        '[object Error]': 1,
	        '[object CanvasGradient]': 1,
	        '[object CanvasPattern]': 1,
	        // For node-canvas
	        '[object Image]': 1,
	        '[object Canvas]': 1
	    };

	    var TYPED_ARRAY = {
	        '[object Int8Array]': 1,
	        '[object Uint8Array]': 1,
	        '[object Uint8ClampedArray]': 1,
	        '[object Int16Array]': 1,
	        '[object Uint16Array]': 1,
	        '[object Int32Array]': 1,
	        '[object Uint32Array]': 1,
	        '[object Float32Array]': 1,
	        '[object Float64Array]': 1
	    };

	    var objToString = Object.prototype.toString;

	    var arrayProto = Array.prototype;
	    var nativeForEach = arrayProto.forEach;
	    var nativeFilter = arrayProto.filter;
	    var nativeSlice = arrayProto.slice;
	    var nativeMap = arrayProto.map;
	    var nativeReduce = arrayProto.reduce;

	    /**
	     * Those data types can be cloned:
	     *     Plain object, Array, TypedArray, number, string, null, undefined.
	     * Those data types will be assgined using the orginal data:
	     *     BUILTIN_OBJECT
	     * Instance of user defined class will be cloned to a plain object, without
	     * properties in prototype.
	     * Other data types is not supported (not sure what will happen).
	     *
	     * Caution: do not support clone Date, for performance consideration.
	     * (There might be a large number of date in `series.data`).
	     * So date should not be modified in and out of echarts.
	     *
	     * @param {*} source
	     * @return {*} new
	     */
	    function clone(source) {
	        if (source == null || typeof source != 'object') {
	            return source;
	        }

	        var result = source;
	        var typeStr = objToString.call(source);

	        if (typeStr === '[object Array]') {
	            result = [];
	            for (var i = 0, len = source.length; i < len; i++) {
	                result[i] = clone(source[i]);
	            }
	        }
	        else if (TYPED_ARRAY[typeStr]) {
	            result = source.constructor.from(source);
	        }
	        else if (!BUILTIN_OBJECT[typeStr] && !isPrimitive(source) && !isDom(source)) {
	            result = {};
	            for (var key in source) {
	                if (source.hasOwnProperty(key)) {
	                    result[key] = clone(source[key]);
	                }
	            }
	        }

	        return result;
	    }

	    /**
	     * @memberOf module:zrender/core/util
	     * @param {*} target
	     * @param {*} source
	     * @param {boolean} [overwrite=false]
	     */
	    function merge(target, source, overwrite) {
	        // We should escapse that source is string
	        // and enter for ... in ...
	        if (!isObject(source) || !isObject(target)) {
	            return overwrite ? clone(source) : target;
	        }

	        for (var key in source) {
	            if (source.hasOwnProperty(key)) {
	                var targetProp = target[key];
	                var sourceProp = source[key];

	                if (isObject(sourceProp)
	                    && isObject(targetProp)
	                    && !isArray(sourceProp)
	                    && !isArray(targetProp)
	                    && !isDom(sourceProp)
	                    && !isDom(targetProp)
	                    && !isBuiltInObject(sourceProp)
	                    && !isBuiltInObject(targetProp)
	                    && !isPrimitive(sourceProp)
	                    && !isPrimitive(targetProp)
	                ) {
	                    // 如果需要递归覆盖，就递归调用merge
	                    merge(targetProp, sourceProp, overwrite);
	                }
	                else if (overwrite || !(key in target)) {
	                    // 否则只处理overwrite为true，或者在目标对象中没有此属性的情况
	                    // NOTE，在 target[key] 不存在的时候也是直接覆盖
	                    target[key] = clone(source[key], true);
	                }
	            }
	        }

	        return target;
	    }

	    /**
	     * @param {Array} targetAndSources The first item is target, and the rests are source.
	     * @param {boolean} [overwrite=false]
	     * @return {*} target
	     */
	    function mergeAll(targetAndSources, overwrite) {
	        var result = targetAndSources[0];
	        for (var i = 1, len = targetAndSources.length; i < len; i++) {
	            result = merge(result, targetAndSources[i], overwrite);
	        }
	        return result;
	    }

	    /**
	     * @param {*} target
	     * @param {*} source
	     * @memberOf module:zrender/core/util
	     */
	    function extend(target, source) {
	        for (var key in source) {
	            if (source.hasOwnProperty(key)) {
	                target[key] = source[key];
	            }
	        }
	        return target;
	    }

	    /**
	     * @param {*} target
	     * @param {*} source
	     * @param {boolen} [overlay=false]
	     * @memberOf module:zrender/core/util
	     */
	    function defaults(target, source, overlay) {
	        for (var key in source) {
	            if (source.hasOwnProperty(key)
	                && (overlay ? source[key] != null : target[key] == null)
	            ) {
	                target[key] = source[key];
	            }
	        }
	        return target;
	    }

	    function createCanvas() {
	        return document.createElement('canvas');
	    }
	    // FIXME
	    var _ctx;
	    function getContext() {
	        if (!_ctx) {
	            // Use util.createCanvas instead of createCanvas
	            // because createCanvas may be overwritten in different environment
	            _ctx = util.createCanvas().getContext('2d');
	        }
	        return _ctx;
	    }

	    /**
	     * 查询数组中元素的index
	     * @memberOf module:zrender/core/util
	     */
	    function indexOf(array, value) {
	        if (array) {
	            if (array.indexOf) {
	                return array.indexOf(value);
	            }
	            for (var i = 0, len = array.length; i < len; i++) {
	                if (array[i] === value) {
	                    return i;
	                }
	            }
	        }
	        return -1;
	    }

	    /**
	     * 构造类继承关系
	     *
	     * @memberOf module:zrender/core/util
	     * @param {Function} clazz 源类
	     * @param {Function} baseClazz 基类
	     */
	    function inherits(clazz, baseClazz) {
	        var clazzPrototype = clazz.prototype;
	        function F() {}
	        F.prototype = baseClazz.prototype;
	        clazz.prototype = new F();

	        for (var prop in clazzPrototype) {
	            clazz.prototype[prop] = clazzPrototype[prop];
	        }
	        clazz.prototype.constructor = clazz;
	        clazz.superClass = baseClazz;
	    }

	    /**
	     * @memberOf module:zrender/core/util
	     * @param {Object|Function} target
	     * @param {Object|Function} sorce
	     * @param {boolean} overlay
	     */
	    function mixin(target, source, overlay) {
	        target = 'prototype' in target ? target.prototype : target;
	        source = 'prototype' in source ? source.prototype : source;

	        defaults(target, source, overlay);
	    }

	    /**
	     * Consider typed array.
	     * @param {Array|TypedArray} data
	     */
	    function isArrayLike(data) {
	        if (! data) {
	            return;
	        }
	        if (typeof data == 'string') {
	            return false;
	        }
	        return typeof data.length == 'number';
	    }

	    /**
	     * 数组或对象遍历
	     * @memberOf module:zrender/core/util
	     * @param {Object|Array} obj
	     * @param {Function} cb
	     * @param {*} [context]
	     */
	    function each(obj, cb, context) {
	        if (!(obj && cb)) {
	            return;
	        }
	        if (obj.forEach && obj.forEach === nativeForEach) {
	            obj.forEach(cb, context);
	        }
	        else if (obj.length === +obj.length) {
	            for (var i = 0, len = obj.length; i < len; i++) {
	                cb.call(context, obj[i], i, obj);
	            }
	        }
	        else {
	            for (var key in obj) {
	                if (obj.hasOwnProperty(key)) {
	                    cb.call(context, obj[key], key, obj);
	                }
	            }
	        }
	    }

	    /**
	     * 数组映射
	     * @memberOf module:zrender/core/util
	     * @param {Array} obj
	     * @param {Function} cb
	     * @param {*} [context]
	     * @return {Array}
	     */
	    function map(obj, cb, context) {
	        if (!(obj && cb)) {
	            return;
	        }
	        if (obj.map && obj.map === nativeMap) {
	            return obj.map(cb, context);
	        }
	        else {
	            var result = [];
	            for (var i = 0, len = obj.length; i < len; i++) {
	                result.push(cb.call(context, obj[i], i, obj));
	            }
	            return result;
	        }
	    }

	    /**
	     * @memberOf module:zrender/core/util
	     * @param {Array} obj
	     * @param {Function} cb
	     * @param {Object} [memo]
	     * @param {*} [context]
	     * @return {Array}
	     */
	    function reduce(obj, cb, memo, context) {
	        if (!(obj && cb)) {
	            return;
	        }
	        if (obj.reduce && obj.reduce === nativeReduce) {
	            return obj.reduce(cb, memo, context);
	        }
	        else {
	            for (var i = 0, len = obj.length; i < len; i++) {
	                memo = cb.call(context, memo, obj[i], i, obj);
	            }
	            return memo;
	        }
	    }

	    /**
	     * 数组过滤
	     * @memberOf module:zrender/core/util
	     * @param {Array} obj
	     * @param {Function} cb
	     * @param {*} [context]
	     * @return {Array}
	     */
	    function filter(obj, cb, context) {
	        if (!(obj && cb)) {
	            return;
	        }
	        if (obj.filter && obj.filter === nativeFilter) {
	            return obj.filter(cb, context);
	        }
	        else {
	            var result = [];
	            for (var i = 0, len = obj.length; i < len; i++) {
	                if (cb.call(context, obj[i], i, obj)) {
	                    result.push(obj[i]);
	                }
	            }
	            return result;
	        }
	    }

	    /**
	     * 数组项查找
	     * @memberOf module:zrender/core/util
	     * @param {Array} obj
	     * @param {Function} cb
	     * @param {*} [context]
	     * @return {Array}
	     */
	    function find(obj, cb, context) {
	        if (!(obj && cb)) {
	            return;
	        }
	        for (var i = 0, len = obj.length; i < len; i++) {
	            if (cb.call(context, obj[i], i, obj)) {
	                return obj[i];
	            }
	        }
	    }

	    /**
	     * @memberOf module:zrender/core/util
	     * @param {Function} func
	     * @param {*} context
	     * @return {Function}
	     */
	    function bind(func, context) {
	        var args = nativeSlice.call(arguments, 2);
	        return function () {
	            return func.apply(context, args.concat(nativeSlice.call(arguments)));
	        };
	    }

	    /**
	     * @memberOf module:zrender/core/util
	     * @param {Function} func
	     * @return {Function}
	     */
	    function curry(func) {
	        var args = nativeSlice.call(arguments, 1);
	        return function () {
	            return func.apply(this, args.concat(nativeSlice.call(arguments)));
	        };
	    }

	    /**
	     * @memberOf module:zrender/core/util
	     * @param {*} value
	     * @return {boolean}
	     */
	    function isArray(value) {
	        return objToString.call(value) === '[object Array]';
	    }

	    /**
	     * @memberOf module:zrender/core/util
	     * @param {*} value
	     * @return {boolean}
	     */
	    function isFunction(value) {
	        return typeof value === 'function';
	    }

	    /**
	     * @memberOf module:zrender/core/util
	     * @param {*} value
	     * @return {boolean}
	     */
	    function isString(value) {
	        return objToString.call(value) === '[object String]';
	    }

	    /**
	     * @memberOf module:zrender/core/util
	     * @param {*} value
	     * @return {boolean}
	     */
	    function isObject(value) {
	        // Avoid a V8 JIT bug in Chrome 19-20.
	        // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
	        var type = typeof value;
	        return type === 'function' || (!!value && type == 'object');
	    }

	    /**
	     * @memberOf module:zrender/core/util
	     * @param {*} value
	     * @return {boolean}
	     */
	    function isBuiltInObject(value) {
	        return !!BUILTIN_OBJECT[objToString.call(value)];
	    }

	    /**
	     * @memberOf module:zrender/core/util
	     * @param {*} value
	     * @return {boolean}
	     */
	    function isDom(value) {
	        return typeof value === 'object'
	            && typeof value.nodeType === 'number'
	            && typeof value.ownerDocument === 'object';
	    }

	    /**
	     * Whether is exactly NaN. Notice isNaN('a') returns true.
	     * @param {*} value
	     * @return {boolean}
	     */
	    function eqNaN(value) {
	        return value !== value;
	    }

	    /**
	     * If value1 is not null, then return value1, otherwise judget rest of values.
	     * @memberOf module:zrender/core/util
	     * @return {*} Final value
	     */
	    function retrieve(values) {
	        for (var i = 0, len = arguments.length; i < len; i++) {
	            if (arguments[i] != null) {
	                return arguments[i];
	            }
	        }
	    }

	    /**
	     * @memberOf module:zrender/core/util
	     * @param {Array} arr
	     * @param {number} startIndex
	     * @param {number} endIndex
	     * @return {Array}
	     */
	    function slice() {
	        return Function.call.apply(nativeSlice, arguments);
	    }

	    /**
	     * @memberOf module:zrender/core/util
	     * @param {boolean} condition
	     * @param {string} message
	     */
	    function assert(condition, message) {
	        if (!condition) {
	            throw new Error(message);
	        }
	    }

	    var primitiveKey = '__ec_primitive__';
	    /**
	     * Set an object as primitive to be ignored traversing children in clone or merge
	     */
	    function setAsPrimitive(obj) {
	        obj[primitiveKey] = true;
	    }

	    function isPrimitive(obj) {
	        return obj[primitiveKey];
	    }

	    /**
	     * @constructor
	     * @param {Object} obj Only apply `ownProperty`.
	     */
	    function HashMap(obj) {
	        obj && each(obj, function (value, key) {
	            this.set(key, value);
	        }, this);
	    }

	    // Add prefix to avoid conflict with Object.prototype.
	    var HASH_MAP_PREFIX = '_ec_';
	    var HASH_MAP_PREFIX_LENGTH = 4;

	    HashMap.prototype = {
	        constructor: HashMap,
	        // Do not provide `has` method to avoid defining what is `has`.
	        // (We usually treat `null` and `undefined` as the same, different
	        // from ES6 Map).
	        get: function (key) {
	            return this[HASH_MAP_PREFIX + key];
	        },
	        set: function (key, value) {
	            this[HASH_MAP_PREFIX + key] = value;
	            // Comparing with invocation chaining, `return value` is more commonly
	            // used in this case: `var someVal = map.set('a', genVal());`
	            return value;
	        },
	        // Although util.each can be performed on this hashMap directly, user
	        // should not use the exposed keys, who are prefixed.
	        each: function (cb, context) {
	            context !== void 0 && (cb = bind(cb, context));
	            for (var prefixedKey in this) {
	                this.hasOwnProperty(prefixedKey)
	                    && cb(this[prefixedKey], prefixedKey.slice(HASH_MAP_PREFIX_LENGTH));
	            }
	        },
	        // Do not use this method if performance sensitive.
	        removeKey: function (key) {
	            delete this[key];
	        }
	    };

	    function createHashMap(obj) {
	        return new HashMap(obj);
	    }

	    var util = {
	        inherits: inherits,
	        mixin: mixin,
	        clone: clone,
	        merge: merge,
	        mergeAll: mergeAll,
	        extend: extend,
	        defaults: defaults,
	        getContext: getContext,
	        createCanvas: createCanvas,
	        indexOf: indexOf,
	        slice: slice,
	        find: find,
	        isArrayLike: isArrayLike,
	        each: each,
	        map: map,
	        reduce: reduce,
	        filter: filter,
	        bind: bind,
	        curry: curry,
	        isArray: isArray,
	        isString: isString,
	        isObject: isObject,
	        isFunction: isFunction,
	        isBuiltInObject: isBuiltInObject,
	        isDom: isDom,
	        eqNaN: eqNaN,
	        retrieve: retrieve,
	        assert: assert,
	        setAsPrimitive: setAsPrimitive,
	        createHashMap: createHashMap,
	        noop: function () {}
	    };
	    module.exports = util;



/***/ },
/* 5 */
/***/ function(module, exports, __webpack_require__) {

	

	    var formatUtil = __webpack_require__(6);
	    var nubmerUtil = __webpack_require__(7);
	    var Model = __webpack_require__(12);
	    var zrUtil = __webpack_require__(4);
	    var each = zrUtil.each;
	    var isObject = zrUtil.isObject;

	    var modelUtil = {};

	    /**
	     * If value is not array, then translate it to array.
	     * @param  {*} value
	     * @return {Array} [value] or value
	     */
	    modelUtil.normalizeToArray = function (value) {
	        return value instanceof Array
	            ? value
	            : value == null
	            ? []
	            : [value];
	    };

	    /**
	     * Sync default option between normal and emphasis like `position` and `show`
	     * In case some one will write code like
	     *     label: {
	     *         normal: {
	     *             show: false,
	     *             position: 'outside',
	     *             textStyle: {
	     *                 fontSize: 18
	     *             }
	     *         },
	     *         emphasis: {
	     *             show: true
	     *         }
	     *     }
	     * @param {Object} opt
	     * @param {Array.<string>} subOpts
	     */
	     modelUtil.defaultEmphasis = function (opt, subOpts) {
	        if (opt) {
	            var emphasisOpt = opt.emphasis = opt.emphasis || {};
	            var normalOpt = opt.normal = opt.normal || {};

	            // Default emphasis option from normal
	            each(subOpts, function (subOptName) {
	                var val = zrUtil.retrieve(emphasisOpt[subOptName], normalOpt[subOptName]);
	                if (val != null) {
	                    emphasisOpt[subOptName] = val;
	                }
	            });
	        }
	    };

	    modelUtil.LABEL_OPTIONS = ['position', 'offset', 'show', 'textStyle', 'distance', 'formatter'];

	    /**
	     * data could be [12, 2323, {value: 223}, [1221, 23], {value: [2, 23]}]
	     * This helper method retieves value from data.
	     * @param {string|number|Date|Array|Object} dataItem
	     * @return {number|string|Date|Array.<number|string|Date>}
	     */
	    modelUtil.getDataItemValue = function (dataItem) {
	        // Performance sensitive.
	        return dataItem && (dataItem.value == null ? dataItem : dataItem.value);
	    };

	    /**
	     * data could be [12, 2323, {value: 223}, [1221, 23], {value: [2, 23]}]
	     * This helper method determine if dataItem has extra option besides value
	     * @param {string|number|Date|Array|Object} dataItem
	     */
	    modelUtil.isDataItemOption = function (dataItem) {
	        return isObject(dataItem)
	            && !(dataItem instanceof Array);
	            // // markLine data can be array
	            // && !(dataItem[0] && isObject(dataItem[0]) && !(dataItem[0] instanceof Array));
	    };

	    /**
	     * This helper method convert value in data.
	     * @param {string|number|Date} value
	     * @param {Object|string} [dimInfo] If string (like 'x'), dimType defaults 'number'.
	     */
	    modelUtil.converDataValue = function (value, dimInfo) {
	        // Performance sensitive.
	        var dimType = dimInfo && dimInfo.type;
	        if (dimType === 'ordinal') {
	            return value;
	        }

	        if (dimType === 'time'
	            // spead up when using timestamp
	            && typeof value !== 'number'
	            && value != null
	            && value !== '-'
	        ) {
	            value = +nubmerUtil.parseDate(value);
	        }

	        // dimType defaults 'number'.
	        // If dimType is not ordinal and value is null or undefined or NaN or '-',
	        // parse to NaN.
	        return (value == null || value === '')
	            ? NaN : +value; // If string (like '-'), using '+' parse to NaN
	    };

	    /**
	     * Create a model proxy to be used in tooltip for edge data, markLine data, markPoint data.
	     * @param {module:echarts/data/List} data
	     * @param {Object} opt
	     * @param {string} [opt.seriesIndex]
	     * @param {Object} [opt.name]
	     * @param {Object} [opt.mainType]
	     * @param {Object} [opt.subType]
	     */
	    modelUtil.createDataFormatModel = function (data, opt) {
	        var model = new Model();
	        zrUtil.mixin(model, modelUtil.dataFormatMixin);
	        model.seriesIndex = opt.seriesIndex;
	        model.name = opt.name || '';
	        model.mainType = opt.mainType;
	        model.subType = opt.subType;

	        model.getData = function () {
	            return data;
	        };
	        return model;
	    };

	    // PENDING A little ugly
	    modelUtil.dataFormatMixin = {
	        /**
	         * Get params for formatter
	         * @param {number} dataIndex
	         * @param {string} [dataType]
	         * @return {Object}
	         */
	        getDataParams: function (dataIndex, dataType) {
	            var data = this.getData(dataType);
	            var rawValue = this.getRawValue(dataIndex, dataType);
	            var rawDataIndex = data.getRawIndex(dataIndex);
	            var name = data.getName(dataIndex, true);
	            var itemOpt = data.getRawDataItem(dataIndex);
	            var color = data.getItemVisual(dataIndex, 'color');

	            return {
	                componentType: this.mainType,
	                componentSubType: this.subType,
	                seriesType: this.mainType === 'series' ? this.subType : null,
	                seriesIndex: this.seriesIndex,
	                seriesId: this.id,
	                seriesName: this.name,
	                name: name,
	                dataIndex: rawDataIndex,
	                data: itemOpt,
	                dataType: dataType,
	                value: rawValue,
	                color: color,
	                marker: formatUtil.getTooltipMarker(color),

	                // Param name list for mapping `a`, `b`, `c`, `d`, `e`
	                $vars: ['seriesName', 'name', 'value']
	            };
	        },

	        /**
	         * Format label
	         * @param {number} dataIndex
	         * @param {string} [status='normal'] 'normal' or 'emphasis'
	         * @param {string} [dataType]
	         * @param {number} [dimIndex]
	         * @param {string} [labelProp='label']
	         * @return {string}
	         */
	        getFormattedLabel: function (dataIndex, status, dataType, dimIndex, labelProp) {
	            status = status || 'normal';
	            var data = this.getData(dataType);
	            var itemModel = data.getItemModel(dataIndex);

	            var params = this.getDataParams(dataIndex, dataType);
	            if (dimIndex != null && (params.value instanceof Array)) {
	                params.value = params.value[dimIndex];
	            }

	            var formatter = itemModel.get([labelProp || 'label', status, 'formatter']);

	            if (typeof formatter === 'function') {
	                params.status = status;
	                return formatter(params);
	            }
	            else if (typeof formatter === 'string') {
	                return formatUtil.formatTpl(formatter, params);
	            }
	        },

	        /**
	         * Get raw value in option
	         * @param {number} idx
	         * @param {string} [dataType]
	         * @return {Object}
	         */
	        getRawValue: function (idx, dataType) {
	            var data = this.getData(dataType);
	            var dataItem = data.getRawDataItem(idx);
	            if (dataItem != null) {
	                return (isObject(dataItem) && !(dataItem instanceof Array))
	                    ? dataItem.value : dataItem;
	            }
	        },

	        /**
	         * Should be implemented.
	         * @param {number} dataIndex
	         * @param {boolean} [multipleSeries=false]
	         * @param {number} [dataType]
	         * @return {string} tooltip string
	         */
	        formatTooltip: zrUtil.noop
	    };

	    /**
	     * Mapping to exists for merge.
	     *
	     * @public
	     * @param {Array.<Object>|Array.<module:echarts/model/Component>} exists
	     * @param {Object|Array.<Object>} newCptOptions
	     * @return {Array.<Object>} Result, like [{exist: ..., option: ...}, {}],
	     *                          index of which is the same as exists.
	     */
	    modelUtil.mappingToExists = function (exists, newCptOptions) {
	        // Mapping by the order by original option (but not order of
	        // new option) in merge mode. Because we should ensure
	        // some specified index (like xAxisIndex) is consistent with
	        // original option, which is easy to understand, espatially in
	        // media query. And in most case, merge option is used to
	        // update partial option but not be expected to change order.
	        newCptOptions = (newCptOptions || []).slice();

	        var result = zrUtil.map(exists || [], function (obj, index) {
	            return {exist: obj};
	        });

	        // Mapping by id or name if specified.
	        each(newCptOptions, function (cptOption, index) {
	            if (!isObject(cptOption)) {
	                return;
	            }

	            // id has highest priority.
	            for (var i = 0; i < result.length; i++) {
	                if (!result[i].option // Consider name: two map to one.
	                    && cptOption.id != null
	                    && result[i].exist.id === cptOption.id + ''
	                ) {
	                    result[i].option = cptOption;
	                    newCptOptions[index] = null;
	                    return;
	                }
	            }

	            for (var i = 0; i < result.length; i++) {
	                var exist = result[i].exist;
	                if (!result[i].option // Consider name: two map to one.
	                    // Can not match when both ids exist but different.
	                    && (exist.id == null || cptOption.id == null)
	                    && cptOption.name != null
	                    && !modelUtil.isIdInner(cptOption)
	                    && !modelUtil.isIdInner(exist)
	                    && exist.name === cptOption.name + ''
	                ) {
	                    result[i].option = cptOption;
	                    newCptOptions[index] = null;
	                    return;
	                }
	            }
	        });

	        // Otherwise mapping by index.
	        each(newCptOptions, function (cptOption, index) {
	            if (!isObject(cptOption)) {
	                return;
	            }

	            var i = 0;
	            for (; i < result.length; i++) {
	                var exist = result[i].exist;
	                if (!result[i].option
	                    // Existing model that already has id should be able to
	                    // mapped to (because after mapping performed model may
	                    // be assigned with a id, whish should not affect next
	                    // mapping), except those has inner id.
	                    && !modelUtil.isIdInner(exist)
	                    // Caution:
	                    // Do not overwrite id. But name can be overwritten,
	                    // because axis use name as 'show label text'.
	                    // 'exist' always has id and name and we dont
	                    // need to check it.
	                    && cptOption.id == null
	                ) {
	                    result[i].option = cptOption;
	                    break;
	                }
	            }

	            if (i >= result.length) {
	                result.push({option: cptOption});
	            }
	        });

	        return result;
	    };

	    /**
	     * Make id and name for mapping result (result of mappingToExists)
	     * into `keyInfo` field.
	     *
	     * @public
	     * @param {Array.<Object>} Result, like [{exist: ..., option: ...}, {}],
	     *                          which order is the same as exists.
	     * @return {Array.<Object>} The input.
	     */
	    modelUtil.makeIdAndName = function (mapResult) {
	        // We use this id to hash component models and view instances
	        // in echarts. id can be specified by user, or auto generated.

	        // The id generation rule ensures new view instance are able
	        // to mapped to old instance when setOption are called in
	        // no-merge mode. So we generate model id by name and plus
	        // type in view id.

	        // name can be duplicated among components, which is convenient
	        // to specify multi components (like series) by one name.

	        // Ensure that each id is distinct.
	        var idMap = zrUtil.createHashMap();

	        each(mapResult, function (item, index) {
	            var existCpt = item.exist;
	            existCpt && idMap.set(existCpt.id, item);
	        });

	        each(mapResult, function (item, index) {
	            var opt = item.option;

	            zrUtil.assert(
	                !opt || opt.id == null || !idMap.get(opt.id) || idMap.get(opt.id) === item,
	                'id duplicates: ' + (opt && opt.id)
	            );

	            opt && opt.id != null && idMap.set(opt.id, item);
	            !item.keyInfo && (item.keyInfo = {});
	        });

	        // Make name and id.
	        each(mapResult, function (item, index) {
	            var existCpt = item.exist;
	            var opt = item.option;
	            var keyInfo = item.keyInfo;

	            if (!isObject(opt)) {
	                return;
	            }

	            // name can be overwitten. Consider case: axis.name = '20km'.
	            // But id generated by name will not be changed, which affect
	            // only in that case: setOption with 'not merge mode' and view
	            // instance will be recreated, which can be accepted.
	            keyInfo.name = opt.name != null
	                ? opt.name + ''
	                : existCpt
	                ? existCpt.name
	                : '\0-'; // name may be displayed on screen, so use '-'.

	            if (existCpt) {
	                keyInfo.id = existCpt.id;
	            }
	            else if (opt.id != null) {
	                keyInfo.id = opt.id + '';
	            }
	            else {
	                // Consider this situatoin:
	                //  optionA: [{name: 'a'}, {name: 'a'}, {..}]
	                //  optionB [{..}, {name: 'a'}, {name: 'a'}]
	                // Series with the same name between optionA and optionB
	                // should be mapped.
	                var idNum = 0;
	                do {
	                    keyInfo.id = '\0' + keyInfo.name + '\0' + idNum++;
	                }
	                while (idMap.get(keyInfo.id));
	            }

	            idMap.set(keyInfo.id, item);
	        });
	    };

	    /**
	     * @public
	     * @param {Object} cptOption
	     * @return {boolean}
	     */
	    modelUtil.isIdInner = function (cptOption) {
	        return isObject(cptOption)
	            && cptOption.id
	            && (cptOption.id + '').indexOf('\0_ec_\0') === 0;
	    };

	    /**
	     * A helper for removing duplicate items between batchA and batchB,
	     * and in themselves, and categorize by series.
	     *
	     * @param {Array.<Object>} batchA Like: [{seriesId: 2, dataIndex: [32, 4, 5]}, ...]
	     * @param {Array.<Object>} batchB Like: [{seriesId: 2, dataIndex: [32, 4, 5]}, ...]
	     * @return {Array.<Array.<Object>, Array.<Object>>} result: [resultBatchA, resultBatchB]
	     */
	    modelUtil.compressBatches = function (batchA, batchB) {
	        var mapA = {};
	        var mapB = {};

	        makeMap(batchA || [], mapA);
	        makeMap(batchB || [], mapB, mapA);

	        return [mapToArray(mapA), mapToArray(mapB)];

	        function makeMap(sourceBatch, map, otherMap) {
	            for (var i = 0, len = sourceBatch.length; i < len; i++) {
	                var seriesId = sourceBatch[i].seriesId;
	                var dataIndices = modelUtil.normalizeToArray(sourceBatch[i].dataIndex);
	                var otherDataIndices = otherMap && otherMap[seriesId];

	                for (var j = 0, lenj = dataIndices.length; j < lenj; j++) {
	                    var dataIndex = dataIndices[j];

	                    if (otherDataIndices && otherDataIndices[dataIndex]) {
	                        otherDataIndices[dataIndex] = null;
	                    }
	                    else {
	                        (map[seriesId] || (map[seriesId] = {}))[dataIndex] = 1;
	                    }
	                }
	            }
	        }

	        function mapToArray(map, isData) {
	            var result = [];
	            for (var i in map) {
	                if (map.hasOwnProperty(i) && map[i] != null) {
	                    if (isData) {
	                        result.push(+i);
	                    }
	                    else {
	                        var dataIndices = mapToArray(map[i], true);
	                        dataIndices.length && result.push({seriesId: i, dataIndex: dataIndices});
	                    }
	                }
	            }
	            return result;
	        }
	    };

	    /**
	     * @param {module:echarts/data/List} data
	     * @param {Object} payload Contains dataIndex (means rawIndex) / dataIndexInside / name
	     *                         each of which can be Array or primary type.
	     * @return {number|Array.<number>} dataIndex If not found, return undefined/null.
	     */
	    modelUtil.queryDataIndex = function (data, payload) {
	        if (payload.dataIndexInside != null) {
	            return payload.dataIndexInside;
	        }
	        else if (payload.dataIndex != null) {
	            return zrUtil.isArray(payload.dataIndex)
	                ? zrUtil.map(payload.dataIndex, function (value) {
	                    return data.indexOfRawIndex(value);
	                })
	                : data.indexOfRawIndex(payload.dataIndex);
	        }
	        else if (payload.name != null) {
	            return zrUtil.isArray(payload.name)
	                ? zrUtil.map(payload.name, function (value) {
	                    return data.indexOfName(value);
	                })
	                : data.indexOfName(payload.name);
	        }
	    };

	    /**
	     * Enable property storage to any host object.
	     * Notice: Serialization is not supported.
	     *
	     * For example:
	     * var get = modelUitl.makeGetter();
	     *
	     * function some(hostObj) {
	     *      get(hostObj)._someProperty = 1212;
	     *      ...
	     * }
	     *
	     * @return {Function}
	     */
	    modelUtil.makeGetter = (function () {
	        var index = 0;
	        return function () {
	            var key = '\0__ec_prop_getter_' + index++;
	            return function (hostObj) {
	                return hostObj[key] || (hostObj[key] = {});
	            };
	        };
	    })();

	    /**
	     * @param {module:echarts/model/Global} ecModel
	     * @param {string|Object} finder
	     *        If string, e.g., 'geo', means {geoIndex: 0}.
	     *        If Object, could contain some of these properties below:
	     *        {
	     *            seriesIndex, seriesId, seriesName,
	     *            geoIndex, geoId, geoName,
	     *            bmapIndex, bmapId, bmapName,
	     *            xAxisIndex, xAxisId, xAxisName,
	     *            yAxisIndex, yAxisId, yAxisName,
	     *            gridIndex, gridId, gridName,
	     *            ... (can be extended)
	     *        }
	     *        Each properties can be number|string|Array.<number>|Array.<string>
	     *        For example, a finder could be
	     *        {
	     *            seriesIndex: 3,
	     *            geoId: ['aa', 'cc'],
	     *            gridName: ['xx', 'rr']
	     *        }
	     *        xxxIndex can be set as 'all' (means all xxx) or 'none' (means not specify)
	     *        If nothing or null/undefined specified, return nothing.
	     * @param {Object} [opt]
	     * @param {string} [opt.defaultMainType]
	     * @param {Array.<string>} [opt.includeMainTypes]
	     * @return {Object} result like:
	     *        {
	     *            seriesModels: [seriesModel1, seriesModel2],
	     *            seriesModel: seriesModel1, // The first model
	     *            geoModels: [geoModel1, geoModel2],
	     *            geoModel: geoModel1, // The first model
	     *            ...
	     *        }
	     */
	    modelUtil.parseFinder = function (ecModel, finder, opt) {
	        if (zrUtil.isString(finder)) {
	            var obj = {};
	            obj[finder + 'Index'] = 0;
	            finder = obj;
	        }

	        var defaultMainType = opt && opt.defaultMainType;
	        if (defaultMainType
	            && !has(finder, defaultMainType + 'Index')
	            && !has(finder, defaultMainType + 'Id')
	            && !has(finder, defaultMainType + 'Name')
	        ) {
	            finder[defaultMainType + 'Index'] = 0;
	        }

	        var result = {};

	        each(finder, function (value, key) {
	            var value = finder[key];

	            // Exclude 'dataIndex' and other illgal keys.
	            if (key === 'dataIndex' || key === 'dataIndexInside') {
	                result[key] = value;
	                return;
	            }

	            var parsedKey = key.match(/^(\w+)(Index|Id|Name)$/) || [];
	            var mainType = parsedKey[1];
	            var queryType = (parsedKey[2] || '').toLowerCase();

	            if (!mainType
	                || !queryType
	                || value == null
	                || (queryType === 'index' && value === 'none')
	                || (opt && opt.includeMainTypes && zrUtil.indexOf(opt.includeMainTypes, mainType) < 0)
	            ) {
	                return;
	            }

	            var queryParam = {mainType: mainType};
	            if (queryType !== 'index' || value !== 'all') {
	                queryParam[queryType] = value;
	            }

	            var models = ecModel.queryComponents(queryParam);
	            result[mainType + 'Models'] = models;
	            result[mainType + 'Model'] = models[0];
	        });

	        return result;
	    };

	    /**
	     * @see {module:echarts/data/helper/completeDimensions}
	     * @param {module:echarts/data/List} data
	     * @param {string|number} dataDim
	     * @return {string}
	     */
	    modelUtil.dataDimToCoordDim = function (data, dataDim) {
	        var dimensions = data.dimensions;
	        dataDim = data.getDimension(dataDim);
	        for (var i = 0; i < dimensions.length; i++) {
	            var dimItem = data.getDimensionInfo(dimensions[i]);
	            if (dimItem.name === dataDim) {
	                return dimItem.coordDim;
	            }
	        }
	    };

	    /**
	     * @see {module:echarts/data/helper/completeDimensions}
	     * @param {module:echarts/data/List} data
	     * @param {string} coordDim
	     * @return {Array.<string>} data dimensions on the coordDim.
	     */
	    modelUtil.coordDimToDataDim = function (data, coordDim) {
	        var dataDim = [];
	        each(data.dimensions, function (dimName) {
	            var dimItem = data.getDimensionInfo(dimName);
	            if (dimItem.coordDim === coordDim) {
	                dataDim[dimItem.coordDimIndex] = dimItem.name;
	            }
	        });
	        return dataDim;
	    };

	    /**
	     * @see {module:echarts/data/helper/completeDimensions}
	     * @param {module:echarts/data/List} data
	     * @param {string} otherDim Can be `otherDims`
	     *                        like 'label' or 'tooltip'.
	     * @return {Array.<string>} data dimensions on the otherDim.
	     */
	    modelUtil.otherDimToDataDim = function (data, otherDim) {
	        var dataDim = [];
	        each(data.dimensions, function (dimName) {
	            var dimItem = data.getDimensionInfo(dimName);
	            var otherDims = dimItem.otherDims;
	            var dimIndex = otherDims[otherDim];
	            if (dimIndex != null && dimIndex !== false) {
	                dataDim[dimIndex] = dimItem.name;
	            }
	        });
	        return dataDim;
	    };

	    function has(obj, prop) {
	        return obj && obj.hasOwnProperty(prop);
	    }

	    module.exports = modelUtil;



/***/ },
/* 6 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);
	    var numberUtil = __webpack_require__(7);
	    var textContain = __webpack_require__(8);

	    var formatUtil = {};

	    /**
	     * 每三位默认加,格式化
	     * @param {string|number} x
	     * @return {string}
	     */
	    formatUtil.addCommas = function (x) {
	        if (isNaN(x)) {
	            return '-';
	        }
	        x = (x + '').split('.');
	        return x[0].replace(/(\d{1,3})(?=(?:\d{3})+(?!\d))/g,'$1,')
	               + (x.length > 1 ? ('.' + x[1]) : '');
	    };

	    /**
	     * @param {string} str
	     * @param {boolean} [upperCaseFirst=false]
	     * @return {string} str
	     */
	    formatUtil.toCamelCase = function (str, upperCaseFirst) {
	        str = (str || '').toLowerCase().replace(/-(.)/g, function(match, group1) {
	            return group1.toUpperCase();
	        });

	        if (upperCaseFirst && str) {
	            str = str.charAt(0).toUpperCase() + str.slice(1);
	        }

	        return str;
	    };

	    /**
	     * Normalize css liked array configuration
	     * e.g.
	     *  3 => [3, 3, 3, 3]
	     *  [4, 2] => [4, 2, 4, 2]
	     *  [4, 3, 2] => [4, 3, 2, 3]
	     * @param {number|Array.<number>} val
	     */
	    formatUtil.normalizeCssArray = function (val) {
	        var len = val.length;
	        if (typeof (val) === 'number') {
	            return [val, val, val, val];
	        }
	        else if (len === 2) {
	            // vertical | horizontal
	            return [val[0], val[1], val[0], val[1]];
	        }
	        else if (len === 3) {
	            // top | horizontal | bottom
	            return [val[0], val[1], val[2], val[1]];
	        }
	        return val;
	    };

	    var encodeHTML = formatUtil.encodeHTML = function (source) {
	        return String(source)
	            .replace(/&/g, '&amp;')
	            .replace(/</g, '&lt;')
	            .replace(/>/g, '&gt;')
	            .replace(/"/g, '&quot;')
	            .replace(/'/g, '&#39;');
	    };

	    var TPL_VAR_ALIAS = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];

	    var wrapVar = function (varName, seriesIdx) {
	        return '{' + varName + (seriesIdx == null ? '' : seriesIdx) + '}';
	    };

	    /**
	     * Template formatter
	     * @param {string} tpl
	     * @param {Array.<Object>|Object} paramsList
	     * @param {boolean} [encode=false]
	     * @return {string}
	     */
	    formatUtil.formatTpl = function (tpl, paramsList, encode) {
	        if (!zrUtil.isArray(paramsList)) {
	            paramsList = [paramsList];
	        }
	        var seriesLen = paramsList.length;
	        if (!seriesLen) {
	            return '';
	        }

	        var $vars = paramsList[0].$vars || [];
	        for (var i = 0; i < $vars.length; i++) {
	            var alias = TPL_VAR_ALIAS[i];
	            var val = wrapVar(alias, 0);
	            tpl = tpl.replace(wrapVar(alias), encode ? encodeHTML(val) : val);
	        }
	        for (var seriesIdx = 0; seriesIdx < seriesLen; seriesIdx++) {
	            for (var k = 0; k < $vars.length; k++) {
	                var val = paramsList[seriesIdx][$vars[k]];
	                tpl = tpl.replace(
	                    wrapVar(TPL_VAR_ALIAS[k], seriesIdx),
	                    encode ? encodeHTML(val) : val
	                );
	            }
	        }

	        return tpl;
	    };

	    /**
	     * simple Template formatter
	     *
	     * @param {string} tpl
	     * @param {Object} param
	     * @param {boolean} [encode=false]
	     * @return {string}
	     */
	    formatUtil.formatTplSimple = function (tpl, param, encode) {
	        zrUtil.each(param, function (value, key) {
	            tpl = tpl.replace(
	                '{' + key + '}',
	                encode ? encodeHTML(value) : value
	            );
	        });
	        return tpl;
	    };

	    /**
	     * @param {string} color
	     * @param {string} [extraCssText]
	     * @return {string}
	     */
	    formatUtil.getTooltipMarker = function (color, extraCssText) {
	        return color
	            ? '<span style="display:inline-block;margin-right:5px;'
	                + 'border-radius:10px;width:9px;height:9px;background-color:'
	                + formatUtil.encodeHTML(color) + ';' + (extraCssText || '') + '"></span>'
	            : '';
	    };

	    /**
	     * @param {string} str
	     * @return {string}
	     * @inner
	     */
	    var s2d = function (str) {
	        return str < 10 ? ('0' + str) : str;
	    };

	    /**
	     * ISO Date format
	     * @param {string} tpl
	     * @param {number} value
	     * @param {boolean} [isUTC=false] Default in local time.
	     *           see `module:echarts/scale/Time`
	     *           and `module:echarts/util/number#parseDate`.
	     * @inner
	     */
	    formatUtil.formatTime = function (tpl, value, isUTC) {
	        if (tpl === 'week'
	            || tpl === 'month'
	            || tpl === 'quarter'
	            || tpl === 'half-year'
	            || tpl === 'year'
	        ) {
	            tpl = 'MM-dd\nyyyy';
	        }

	        var date = numberUtil.parseDate(value);
	        var utc = isUTC ? 'UTC' : '';
	        var y = date['get' + utc + 'FullYear']();
	        var M = date['get' + utc + 'Month']() + 1;
	        var d = date['get' + utc + 'Date']();
	        var h = date['get' + utc + 'Hours']();
	        var m = date['get' + utc + 'Minutes']();
	        var s = date['get' + utc + 'Seconds']();

	        tpl = tpl.replace('MM', s2d(M))
	            .toLowerCase()
	            .replace('yyyy', y)
	            .replace('yy', y % 100)
	            .replace('dd', s2d(d))
	            .replace('d', d)
	            .replace('hh', s2d(h))
	            .replace('h', h)
	            .replace('mm', s2d(m))
	            .replace('m', m)
	            .replace('ss', s2d(s))
	            .replace('s', s);

	        return tpl;
	    };

	    /**
	     * Capital first
	     * @param {string} str
	     * @return {string}
	     */
	    formatUtil.capitalFirst = function (str) {
	        return str ? str.charAt(0).toUpperCase() + str.substr(1) : str;
	    };

	    formatUtil.truncateText = textContain.truncateText;

	    module.exports = formatUtil;



/***/ },
/* 7 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * 数值处理模块
	 * @module echarts/util/number
	 */



	    var zrUtil = __webpack_require__(4);

	    var number = {};

	    var RADIAN_EPSILON = 1e-4;

	    function _trim(str) {
	        return str.replace(/^\s+/, '').replace(/\s+$/, '');
	    }

	    /**
	     * Linear mapping a value from domain to range
	     * @memberOf module:echarts/util/number
	     * @param  {(number|Array.<number>)} val
	     * @param  {Array.<number>} domain Domain extent domain[0] can be bigger than domain[1]
	     * @param  {Array.<number>} range  Range extent range[0] can be bigger than range[1]
	     * @param  {boolean} clamp
	     * @return {(number|Array.<number>}
	     */
	    number.linearMap = function (val, domain, range, clamp) {
	        var subDomain = domain[1] - domain[0];
	        var subRange = range[1] - range[0];

	        if (subDomain === 0) {
	            return subRange === 0
	                ? range[0]
	                : (range[0] + range[1]) / 2;
	        }

	        // Avoid accuracy problem in edge, such as
	        // 146.39 - 62.83 === 83.55999999999999.
	        // See echarts/test/ut/spec/util/number.js#linearMap#accuracyError
	        // It is a little verbose for efficiency considering this method
	        // is a hotspot.
	        if (clamp) {
	            if (subDomain > 0) {
	                if (val <= domain[0]) {
	                    return range[0];
	                }
	                else if (val >= domain[1]) {
	                    return range[1];
	                }
	            }
	            else {
	                if (val >= domain[0]) {
	                    return range[0];
	                }
	                else if (val <= domain[1]) {
	                    return range[1];
	                }
	            }
	        }
	        else {
	            if (val === domain[0]) {
	                return range[0];
	            }
	            if (val === domain[1]) {
	                return range[1];
	            }
	        }

	        return (val - domain[0]) / subDomain * subRange + range[0];
	    };

	    /**
	     * Convert a percent string to absolute number.
	     * Returns NaN if percent is not a valid string or number
	     * @memberOf module:echarts/util/number
	     * @param {string|number} percent
	     * @param {number} all
	     * @return {number}
	     */
	    number.parsePercent = function(percent, all) {
	        switch (percent) {
	            case 'center':
	            case 'middle':
	                percent = '50%';
	                break;
	            case 'left':
	            case 'top':
	                percent = '0%';
	                break;
	            case 'right':
	            case 'bottom':
	                percent = '100%';
	                break;
	        }
	        if (typeof percent === 'string') {
	            if (_trim(percent).match(/%$/)) {
	                return parseFloat(percent) / 100 * all;
	            }

	            return parseFloat(percent);
	        }

	        return percent == null ? NaN : +percent;
	    };

	    /**
	     * (1) Fix rounding error of float numbers.
	     * (2) Support return string to avoid scientific notation like '3.5e-7'.
	     *
	     * @param {number} x
	     * @param {number} [precision]
	     * @param {boolean} [returnStr]
	     * @return {number|string}
	     */
	    number.round = function (x, precision, returnStr) {
	        if (precision == null) {
	            precision = 10;
	        }
	        // Avoid range error
	        precision = Math.min(Math.max(0, precision), 20);
	        x = (+x).toFixed(precision);
	        return returnStr ? x : +x;
	    };

	    number.asc = function (arr) {
	        arr.sort(function (a, b) {
	            return a - b;
	        });
	        return arr;
	    };

	    /**
	     * Get precision
	     * @param {number} val
	     */
	    number.getPrecision = function (val) {
	        val = +val;
	        if (isNaN(val)) {
	            return 0;
	        }
	        // It is much faster than methods converting number to string as follows
	        //      var tmp = val.toString();
	        //      return tmp.length - 1 - tmp.indexOf('.');
	        // especially when precision is low
	        var e = 1;
	        var count = 0;
	        while (Math.round(val * e) / e !== val) {
	            e *= 10;
	            count++;
	        }
	        return count;
	    };

	    /**
	     * @param {string|number} val
	     * @return {number}
	     */
	    number.getPrecisionSafe = function (val) {
	        var str = val.toString();

	        // Consider scientific notation: '3.4e-12' '3.4e+12'
	        var eIndex = str.indexOf('e');
	        if (eIndex > 0) {
	            var precision = +str.slice(eIndex + 1);
	            return precision < 0 ? -precision : 0;
	        }
	        else {
	            var dotIndex = str.indexOf('.');
	            return dotIndex < 0 ? 0 : str.length - 1 - dotIndex;
	        }
	    };

	    /**
	     * Minimal dicernible data precisioin according to a single pixel.
	     *
	     * @param {Array.<number>} dataExtent
	     * @param {Array.<number>} pixelExtent
	     * @return {number} precision
	     */
	    number.getPixelPrecision = function (dataExtent, pixelExtent) {
	        var log = Math.log;
	        var LN10 = Math.LN10;
	        var dataQuantity = Math.floor(log(dataExtent[1] - dataExtent[0]) / LN10);
	        var sizeQuantity = Math.round(log(Math.abs(pixelExtent[1] - pixelExtent[0])) / LN10);
	        // toFixed() digits argument must be between 0 and 20.
	        var precision = Math.min(Math.max(-dataQuantity + sizeQuantity, 0), 20);
	        return !isFinite(precision) ? 20 : precision;
	    };

	    /**
	     * Get a data of given precision, assuring the sum of percentages
	     * in valueList is 1.
	     * The largest remainer method is used.
	     * https://en.wikipedia.org/wiki/Largest_remainder_method
	     *
	     * @param {Array.<number>} valueList a list of all data
	     * @param {number} idx index of the data to be processed in valueList
	     * @param {number} precision integer number showing digits of precision
	     * @return {number} percent ranging from 0 to 100
	     */
	    number.getPercentWithPrecision = function (valueList, idx, precision) {
	        if (!valueList[idx]) {
	            return 0;
	        }

	        var sum = zrUtil.reduce(valueList, function (acc, val) {
	            return acc + (isNaN(val) ? 0 : val);
	        }, 0);
	        if (sum === 0) {
	            return 0;
	        }

	        var digits = Math.pow(10, precision);
	        var votesPerQuota = zrUtil.map(valueList, function (val) {
	            return (isNaN(val) ? 0 : val) / sum * digits * 100;
	        });
	        var targetSeats = digits * 100;

	        var seats = zrUtil.map(votesPerQuota, function (votes) {
	            // Assign automatic seats.
	            return Math.floor(votes);
	        });
	        var currentSum = zrUtil.reduce(seats, function (acc, val) {
	            return acc + val;
	        }, 0);

	        var remainder = zrUtil.map(votesPerQuota, function (votes, idx) {
	            return votes - seats[idx];
	        });

	        // Has remainding votes.
	        while (currentSum < targetSeats) {
	            // Find next largest remainder.
	            var max = Number.NEGATIVE_INFINITY;
	            var maxId = null;
	            for (var i = 0, len = remainder.length; i < len; ++i) {
	                if (remainder[i] > max) {
	                    max = remainder[i];
	                    maxId = i;
	                }
	            }

	            // Add a vote to max remainder.
	            ++seats[maxId];
	            remainder[maxId] = 0;
	            ++currentSum;
	        }

	        return seats[idx] / digits;
	    };

	    // Number.MAX_SAFE_INTEGER, ie do not support.
	    number.MAX_SAFE_INTEGER = 9007199254740991;

	    /**
	     * To 0 - 2 * PI, considering negative radian.
	     * @param {number} radian
	     * @return {number}
	     */
	    number.remRadian = function (radian) {
	        var pi2 = Math.PI * 2;
	        return (radian % pi2 + pi2) % pi2;
	    };

	    /**
	     * @param {type} radian
	     * @return {boolean}
	     */
	    number.isRadianAroundZero = function (val) {
	        return val > -RADIAN_EPSILON && val < RADIAN_EPSILON;
	    };

	    var TIME_REG = /^(?:(\d{4})(?:[-\/](\d{1,2})(?:[-\/](\d{1,2})(?:[T ](\d{1,2})(?::(\d\d)(?::(\d\d)(?:[.,](\d+))?)?)?(Z|[\+\-]\d\d:?\d\d)?)?)?)?)?$/; // jshint ignore:line

	    /**
	     * @return {number} in minutes
	     */
	    number.getTimezoneOffset = function () {
	        return (new Date()).getTimezoneOffset();
	    };

	    /**
	     * @param {string|Date|number} value These values can be accepted:
	     *   + An instance of Date, represent a time in its own time zone.
	     *   + Or string in a subset of ISO 8601, only including:
	     *     + only year, month, date: '2012-03', '2012-03-01', '2012-03-01 05', '2012-03-01 05:06',
	     *     + separated with T or space: '2012-03-01T12:22:33.123', '2012-03-01 12:22:33.123',
	     *     + time zone: '2012-03-01T12:22:33Z', '2012-03-01T12:22:33+8000', '2012-03-01T12:22:33-05:00',
	     *     all of which will be treated as local time if time zone is not specified
	     *     (see <https://momentjs.com/>).
	     *   + Or other string format, including (all of which will be treated as loacal time):
	     *     '2012', '2012-3-1', '2012/3/1', '2012/03/01',
	     *     '2009/6/12 2:00', '2009/6/12 2:05:08', '2009/6/12 2:05:08.123'
	     *   + a timestamp, which represent a time in UTC.
	     * @return {Date} date
	     */
	    number.parseDate = function (value) {
	        if (value instanceof Date) {
	            return value;
	        }
	        else if (typeof value === 'string') {
	            // Different browsers parse date in different way, so we parse it manually.
	            // Some other issues:
	            // new Date('1970-01-01') is UTC,
	            // new Date('1970/01/01') and new Date('1970-1-01') is local.
	            // See issue #3623
	            var match = TIME_REG.exec(value);

	            if (!match) {
	                // return Invalid Date.
	                return new Date(NaN);
	            }

	            var timezoneOffset = number.getTimezoneOffset();
	            var timeOffset = !match[8]
	                ? 0
	                : match[8].toUpperCase() === 'Z'
	                ? timezoneOffset
	                : +match[8].slice(0, 3) * 60 + timezoneOffset;

	            // match[n] can only be string or undefined.
	            // But take care of '12' + 1 => '121'.
	            return new Date(
	                +match[1],
	                +(match[2] || 1) - 1,
	                +match[3] || 1,
	                +match[4] || 0,
	                +(match[5] || 0) - timeOffset,
	                +match[6] || 0,
	                +match[7] || 0
	            );
	        }
	        else if (value == null) {
	            return new Date(NaN);
	        }

	        return new Date(Math.round(value));
	    };

	    /**
	     * Quantity of a number. e.g. 0.1, 1, 10, 100
	     *
	     * @param  {number} val
	     * @return {number}
	     */
	    number.quantity = function (val) {
	        return Math.pow(10, quantityExponent(val));
	    };

	    function quantityExponent(val) {
	        return Math.floor(Math.log(val) / Math.LN10);
	    }

	    /**
	     * find a “nice” number approximately equal to x. Round the number if round = true,
	     * take ceiling if round = false. The primary observation is that the “nicest”
	     * numbers in decimal are 1, 2, and 5, and all power-of-ten multiples of these numbers.
	     *
	     * See "Nice Numbers for Graph Labels" of Graphic Gems.
	     *
	     * @param  {number} val Non-negative value.
	     * @param  {boolean} round
	     * @return {number}
	     */
	    number.nice = function (val, round) {
	        var exponent = quantityExponent(val);
	        var exp10 = Math.pow(10, exponent);
	        var f = val / exp10; // 1 <= f < 10
	        var nf;
	        if (round) {
	            if (f < 1.5) { nf = 1; }
	            else if (f < 2.5) { nf = 2; }
	            else if (f < 4) { nf = 3; }
	            else if (f < 7) { nf = 5; }
	            else { nf = 10; }
	        }
	        else {
	            if (f < 1) { nf = 1; }
	            else if (f < 2) { nf = 2; }
	            else if (f < 3) { nf = 3; }
	            else if (f < 5) { nf = 5; }
	            else { nf = 10; }
	        }
	        val = nf * exp10;

	        // Fix 3 * 0.1 === 0.30000000000000004 issue (see IEEE 754).
	        // 20 is the uppper bound of toFixed.
	        return exponent >= -20 ? +val.toFixed(exponent < 0 ? -exponent : 0) : val;
	    };

	    /**
	     * Order intervals asc, and split them when overlap.
	     * expect(numberUtil.reformIntervals([
	     *     {interval: [18, 62], close: [1, 1]},
	     *     {interval: [-Infinity, -70], close: [0, 0]},
	     *     {interval: [-70, -26], close: [1, 1]},
	     *     {interval: [-26, 18], close: [1, 1]},
	     *     {interval: [62, 150], close: [1, 1]},
	     *     {interval: [106, 150], close: [1, 1]},
	     *     {interval: [150, Infinity], close: [0, 0]}
	     * ])).toEqual([
	     *     {interval: [-Infinity, -70], close: [0, 0]},
	     *     {interval: [-70, -26], close: [1, 1]},
	     *     {interval: [-26, 18], close: [0, 1]},
	     *     {interval: [18, 62], close: [0, 1]},
	     *     {interval: [62, 150], close: [0, 1]},
	     *     {interval: [150, Infinity], close: [0, 0]}
	     * ]);
	     * @param {Array.<Object>} list, where `close` mean open or close
	     *        of the interval, and Infinity can be used.
	     * @return {Array.<Object>} The origin list, which has been reformed.
	     */
	    number.reformIntervals = function (list) {
	        list.sort(function (a, b) {
	            return littleThan(a, b, 0) ? -1 : 1;
	        });

	        var curr = -Infinity;
	        var currClose = 1;
	        for (var i = 0; i < list.length;) {
	            var interval = list[i].interval;
	            var close = list[i].close;

	            for (var lg = 0; lg < 2; lg++) {
	                if (interval[lg] <= curr) {
	                    interval[lg] = curr;
	                    close[lg] = !lg ? 1 - currClose : 1;
	                }
	                curr = interval[lg];
	                currClose = close[lg];
	            }

	            if (interval[0] === interval[1] && close[0] * close[1] !== 1) {
	                list.splice(i, 1);
	            }
	            else {
	                i++;
	            }
	        }

	        return list;

	        function littleThan(a, b, lg) {
	            return a.interval[lg] < b.interval[lg]
	                || (
	                    a.interval[lg] === b.interval[lg]
	                    && (
	                        (a.close[lg] - b.close[lg] === (!lg ? 1 : -1))
	                        || (!lg && littleThan(a, b, 1))
	                    )
	                );
	        }
	    };

	    /**
	     * parseFloat NaNs numeric-cast false positives (null|true|false|"")
	     * ...but misinterprets leading-number strings, particularly hex literals ("0x...")
	     * subtraction forces infinities to NaN
	     *
	     * @param {*} v
	     * @return {boolean}
	     */
	    number.isNumeric = function (v) {
	        return v - parseFloat(v) >= 0;
	    };

	    module.exports = number;


/***/ },
/* 8 */
/***/ function(module, exports, __webpack_require__) {

	

	    var textWidthCache = {};
	    var textWidthCacheCounter = 0;
	    var TEXT_CACHE_MAX = 5000;

	    var util = __webpack_require__(4);
	    var BoundingRect = __webpack_require__(9);
	    var retrieve = util.retrieve;

	    function getTextWidth(text, textFont) {
	        var key = text + ':' + textFont;
	        if (textWidthCache[key]) {
	            return textWidthCache[key];
	        }

	        var textLines = (text + '').split('\n');
	        var width = 0;

	        for (var i = 0, l = textLines.length; i < l; i++) {
	            // measureText 可以被覆盖以兼容不支持 Canvas 的环境
	            width = Math.max(textContain.measureText(textLines[i], textFont).width, width);
	        }

	        if (textWidthCacheCounter > TEXT_CACHE_MAX) {
	            textWidthCacheCounter = 0;
	            textWidthCache = {};
	        }
	        textWidthCacheCounter++;
	        textWidthCache[key] = width;

	        return width;
	    }

	    function getTextRect(text, textFont, textAlign, textBaseline) {
	        var textLineLen = ((text || '') + '').split('\n').length;

	        var width = getTextWidth(text, textFont);
	        // FIXME 高度计算比较粗暴
	        var lineHeight = getTextWidth('国', textFont);
	        var height = textLineLen * lineHeight;

	        var rect = new BoundingRect(0, 0, width, height);
	        // Text has a special line height property
	        rect.lineHeight = lineHeight;

	        switch (textBaseline) {
	            case 'bottom':
	            case 'alphabetic':
	                rect.y -= lineHeight;
	                break;
	            case 'middle':
	                rect.y -= lineHeight / 2;
	                break;
	            // case 'hanging':
	            // case 'top':
	        }

	        // FIXME Right to left language
	        switch (textAlign) {
	            case 'end':
	            case 'right':
	                rect.x -= rect.width;
	                break;
	            case 'center':
	                rect.x -= rect.width / 2;
	                break;
	            // case 'start':
	            // case 'left':
	        }

	        return rect;
	    }

	    function adjustTextPositionOnRect(textPosition, rect, textRect, distance) {

	        var x = rect.x;
	        var y = rect.y;

	        var height = rect.height;
	        var width = rect.width;

	        var textHeight = textRect.height;

	        var lineHeight = textRect.lineHeight;
	        var halfHeight = height / 2 - textHeight / 2 + lineHeight;

	        var textAlign = 'left';

	        switch (textPosition) {
	            case 'left':
	                x -= distance;
	                y += halfHeight;
	                textAlign = 'right';
	                break;
	            case 'right':
	                x += distance + width;
	                y += halfHeight;
	                textAlign = 'left';
	                break;
	            case 'top':
	                x += width / 2;
	                y -= distance + textHeight - lineHeight;
	                textAlign = 'center';
	                break;
	            case 'bottom':
	                x += width / 2;
	                y += height + distance + lineHeight;
	                textAlign = 'center';
	                break;
	            case 'inside':
	                x += width / 2;
	                y += halfHeight;
	                textAlign = 'center';
	                break;
	            case 'insideLeft':
	                x += distance;
	                y += halfHeight;
	                textAlign = 'left';
	                break;
	            case 'insideRight':
	                x += width - distance;
	                y += halfHeight;
	                textAlign = 'right';
	                break;
	            case 'insideTop':
	                x += width / 2;
	                y += distance + lineHeight;
	                textAlign = 'center';
	                break;
	            case 'insideBottom':
	                x += width / 2;
	                y += height - textHeight - distance + lineHeight;
	                textAlign = 'center';
	                break;
	            case 'insideTopLeft':
	                x += distance;
	                y += distance + lineHeight;
	                textAlign = 'left';
	                break;
	            case 'insideTopRight':
	                x += width - distance;
	                y += distance + lineHeight;
	                textAlign = 'right';
	                break;
	            case 'insideBottomLeft':
	                x += distance;
	                y += height - textHeight - distance + lineHeight;
	                break;
	            case 'insideBottomRight':
	                x += width - distance;
	                y += height - textHeight - distance + lineHeight;
	                textAlign = 'right';
	                break;
	        }

	        return {
	            x: x,
	            y: y,
	            textAlign: textAlign,
	            textBaseline: 'alphabetic'
	        };
	    }

	    /**
	     * Show ellipsis if overflow.
	     *
	     * @param  {string} text
	     * @param  {string} containerWidth
	     * @param  {string} textFont
	     * @param  {number} [ellipsis='...']
	     * @param  {Object} [options]
	     * @param  {number} [options.maxIterations=3]
	     * @param  {number} [options.minChar=0] If truncate result are less
	     *                  then minChar, ellipsis will not show, which is
	     *                  better for user hint in some cases.
	     * @param  {number} [options.placeholder=''] When all truncated, use the placeholder.
	     * @return {string}
	     */
	    function truncateText(text, containerWidth, textFont, ellipsis, options) {
	        if (!containerWidth) {
	            return '';
	        }

	        options = options || {};

	        ellipsis = retrieve(ellipsis, '...');
	        var maxIterations = retrieve(options.maxIterations, 2);
	        var minChar = retrieve(options.minChar, 0);
	        // FIXME
	        // Other languages?
	        var cnCharWidth = getTextWidth('国', textFont);
	        // FIXME
	        // Consider proportional font?
	        var ascCharWidth = getTextWidth('a', textFont);
	        var placeholder = retrieve(options.placeholder, '');

	        // Example 1: minChar: 3, text: 'asdfzxcv', truncate result: 'asdf', but not: 'a...'.
	        // Example 2: minChar: 3, text: '维度', truncate result: '维', but not: '...'.
	        var contentWidth = containerWidth = Math.max(0, containerWidth - 1); // Reserve some gap.
	        for (var i = 0; i < minChar && contentWidth >= ascCharWidth; i++) {
	            contentWidth -= ascCharWidth;
	        }

	        var ellipsisWidth = getTextWidth(ellipsis);
	        if (ellipsisWidth > contentWidth) {
	            ellipsis = '';
	            ellipsisWidth = 0;
	        }

	        contentWidth = containerWidth - ellipsisWidth;

	        var textLines = (text + '').split('\n');

	        for (var i = 0, len = textLines.length; i < len; i++) {
	            var textLine = textLines[i];
	            var lineWidth = getTextWidth(textLine, textFont);

	            if (lineWidth <= containerWidth) {
	                continue;
	            }

	            for (var j = 0;; j++) {
	                if (lineWidth <= contentWidth || j >= maxIterations) {
	                    textLine += ellipsis;
	                    break;
	                }

	                var subLength = j === 0
	                    ? estimateLength(textLine, contentWidth, ascCharWidth, cnCharWidth)
	                    : lineWidth > 0
	                    ? Math.floor(textLine.length * contentWidth / lineWidth)
	                    : 0;

	                textLine = textLine.substr(0, subLength);
	                lineWidth = getTextWidth(textLine, textFont);
	            }

	            if (textLine === '') {
	                textLine = placeholder;
	            }

	            textLines[i] = textLine;
	        }

	        return textLines.join('\n');
	    }

	    function estimateLength(text, contentWidth, ascCharWidth, cnCharWidth) {
	        var width = 0;
	        var i = 0;
	        for (var len = text.length; i < len && width < contentWidth; i++) {
	            var charCode = text.charCodeAt(i);
	            width += (0 <= charCode && charCode <= 127) ? ascCharWidth : cnCharWidth;
	        }
	        return i;
	    }

	    var textContain = {

	        getWidth: getTextWidth,

	        getBoundingRect: getTextRect,

	        adjustTextPositionOnRect: adjustTextPositionOnRect,

	        truncateText: truncateText,

	        measureText: function (text, textFont) {
	            var ctx = util.getContext();
	            ctx.font = textFont || '12px sans-serif';
	            return ctx.measureText(text);
	        }
	    };

	    module.exports = textContain;


/***/ },
/* 9 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	/**
	 * @module echarts/core/BoundingRect
	 */


	    var vec2 = __webpack_require__(10);
	    var matrix = __webpack_require__(11);

	    var v2ApplyTransform = vec2.applyTransform;
	    var mathMin = Math.min;
	    var mathMax = Math.max;
	    /**
	     * @alias module:echarts/core/BoundingRect
	     */
	    function BoundingRect(x, y, width, height) {

	        if (width < 0) {
	            x = x + width;
	            width = -width;
	        }
	        if (height < 0) {
	            y = y + height;
	            height = -height;
	        }

	        /**
	         * @type {number}
	         */
	        this.x = x;
	        /**
	         * @type {number}
	         */
	        this.y = y;
	        /**
	         * @type {number}
	         */
	        this.width = width;
	        /**
	         * @type {number}
	         */
	        this.height = height;
	    }

	    BoundingRect.prototype = {

	        constructor: BoundingRect,

	        /**
	         * @param {module:echarts/core/BoundingRect} other
	         */
	        union: function (other) {
	            var x = mathMin(other.x, this.x);
	            var y = mathMin(other.y, this.y);

	            this.width = mathMax(
	                    other.x + other.width,
	                    this.x + this.width
	                ) - x;
	            this.height = mathMax(
	                    other.y + other.height,
	                    this.y + this.height
	                ) - y;
	            this.x = x;
	            this.y = y;
	        },

	        /**
	         * @param {Array.<number>} m
	         * @methods
	         */
	        applyTransform: (function () {
	            var lt = [];
	            var rb = [];
	            var lb = [];
	            var rt = [];
	            return function (m) {
	                // In case usage like this
	                // el.getBoundingRect().applyTransform(el.transform)
	                // And element has no transform
	                if (!m) {
	                    return;
	                }
	                lt[0] = lb[0] = this.x;
	                lt[1] = rt[1] = this.y;
	                rb[0] = rt[0] = this.x + this.width;
	                rb[1] = lb[1] = this.y + this.height;

	                v2ApplyTransform(lt, lt, m);
	                v2ApplyTransform(rb, rb, m);
	                v2ApplyTransform(lb, lb, m);
	                v2ApplyTransform(rt, rt, m);

	                this.x = mathMin(lt[0], rb[0], lb[0], rt[0]);
	                this.y = mathMin(lt[1], rb[1], lb[1], rt[1]);
	                var maxX = mathMax(lt[0], rb[0], lb[0], rt[0]);
	                var maxY = mathMax(lt[1], rb[1], lb[1], rt[1]);
	                this.width = maxX - this.x;
	                this.height = maxY - this.y;
	            };
	        })(),

	        /**
	         * Calculate matrix of transforming from self to target rect
	         * @param  {module:zrender/core/BoundingRect} b
	         * @return {Array.<number>}
	         */
	        calculateTransform: function (b) {
	            var a = this;
	            var sx = b.width / a.width;
	            var sy = b.height / a.height;

	            var m = matrix.create();

	            // 矩阵右乘
	            matrix.translate(m, m, [-a.x, -a.y]);
	            matrix.scale(m, m, [sx, sy]);
	            matrix.translate(m, m, [b.x, b.y]);

	            return m;
	        },

	        /**
	         * @param {(module:echarts/core/BoundingRect|Object)} b
	         * @return {boolean}
	         */
	        intersect: function (b) {
	            if (!b) {
	                return false;
	            }

	            if (!(b instanceof BoundingRect)) {
	                // Normalize negative width/height.
	                b = BoundingRect.create(b);
	            }

	            var a = this;
	            var ax0 = a.x;
	            var ax1 = a.x + a.width;
	            var ay0 = a.y;
	            var ay1 = a.y + a.height;

	            var bx0 = b.x;
	            var bx1 = b.x + b.width;
	            var by0 = b.y;
	            var by1 = b.y + b.height;

	            return ! (ax1 < bx0 || bx1 < ax0 || ay1 < by0 || by1 < ay0);
	        },

	        contain: function (x, y) {
	            var rect = this;
	            return x >= rect.x
	                && x <= (rect.x + rect.width)
	                && y >= rect.y
	                && y <= (rect.y + rect.height);
	        },

	        /**
	         * @return {module:echarts/core/BoundingRect}
	         */
	        clone: function () {
	            return new BoundingRect(this.x, this.y, this.width, this.height);
	        },

	        /**
	         * Copy from another rect
	         */
	        copy: function (other) {
	            this.x = other.x;
	            this.y = other.y;
	            this.width = other.width;
	            this.height = other.height;
	        },

	        plain: function () {
	            return {
	                x: this.x,
	                y: this.y,
	                width: this.width,
	                height: this.height
	            };
	        }
	    };

	    /**
	     * @param {Object|module:zrender/core/BoundingRect} rect
	     * @param {number} rect.x
	     * @param {number} rect.y
	     * @param {number} rect.width
	     * @param {number} rect.height
	     * @return {module:zrender/core/BoundingRect}
	     */
	    BoundingRect.create = function (rect) {
	        return new BoundingRect(rect.x, rect.y, rect.width, rect.height);
	    };

	    module.exports = BoundingRect;


/***/ },
/* 10 */
/***/ function(module, exports) {

	
	    var ArrayCtor = typeof Float32Array === 'undefined'
	        ? Array
	        : Float32Array;

	    /**
	     * @typedef {Float32Array|Array.<number>} Vector2
	     */
	    /**
	     * 二维向量类
	     * @exports zrender/tool/vector
	     */
	    var vector = {
	        /**
	         * 创建一个向量
	         * @param {number} [x=0]
	         * @param {number} [y=0]
	         * @return {Vector2}
	         */
	        create: function (x, y) {
	            var out = new ArrayCtor(2);
	            if (x == null) {
	                x = 0;
	            }
	            if (y == null) {
	                y = 0;
	            }
	            out[0] = x;
	            out[1] = y;
	            return out;
	        },

	        /**
	         * 复制向量数据
	         * @param {Vector2} out
	         * @param {Vector2} v
	         * @return {Vector2}
	         */
	        copy: function (out, v) {
	            out[0] = v[0];
	            out[1] = v[1];
	            return out;
	        },

	        /**
	         * 克隆一个向量
	         * @param {Vector2} v
	         * @return {Vector2}
	         */
	        clone: function (v) {
	            var out = new ArrayCtor(2);
	            out[0] = v[0];
	            out[1] = v[1];
	            return out;
	        },

	        /**
	         * 设置向量的两个项
	         * @param {Vector2} out
	         * @param {number} a
	         * @param {number} b
	         * @return {Vector2} 结果
	         */
	        set: function (out, a, b) {
	            out[0] = a;
	            out[1] = b;
	            return out;
	        },

	        /**
	         * 向量相加
	         * @param {Vector2} out
	         * @param {Vector2} v1
	         * @param {Vector2} v2
	         */
	        add: function (out, v1, v2) {
	            out[0] = v1[0] + v2[0];
	            out[1] = v1[1] + v2[1];
	            return out;
	        },

	        /**
	         * 向量缩放后相加
	         * @param {Vector2} out
	         * @param {Vector2} v1
	         * @param {Vector2} v2
	         * @param {number} a
	         */
	        scaleAndAdd: function (out, v1, v2, a) {
	            out[0] = v1[0] + v2[0] * a;
	            out[1] = v1[1] + v2[1] * a;
	            return out;
	        },

	        /**
	         * 向量相减
	         * @param {Vector2} out
	         * @param {Vector2} v1
	         * @param {Vector2} v2
	         */
	        sub: function (out, v1, v2) {
	            out[0] = v1[0] - v2[0];
	            out[1] = v1[1] - v2[1];
	            return out;
	        },

	        /**
	         * 向量长度
	         * @param {Vector2} v
	         * @return {number}
	         */
	        len: function (v) {
	            return Math.sqrt(this.lenSquare(v));
	        },

	        /**
	         * 向量长度平方
	         * @param {Vector2} v
	         * @return {number}
	         */
	        lenSquare: function (v) {
	            return v[0] * v[0] + v[1] * v[1];
	        },

	        /**
	         * 向量乘法
	         * @param {Vector2} out
	         * @param {Vector2} v1
	         * @param {Vector2} v2
	         */
	        mul: function (out, v1, v2) {
	            out[0] = v1[0] * v2[0];
	            out[1] = v1[1] * v2[1];
	            return out;
	        },

	        /**
	         * 向量除法
	         * @param {Vector2} out
	         * @param {Vector2} v1
	         * @param {Vector2} v2
	         */
	        div: function (out, v1, v2) {
	            out[0] = v1[0] / v2[0];
	            out[1] = v1[1] / v2[1];
	            return out;
	        },

	        /**
	         * 向量点乘
	         * @param {Vector2} v1
	         * @param {Vector2} v2
	         * @return {number}
	         */
	        dot: function (v1, v2) {
	            return v1[0] * v2[0] + v1[1] * v2[1];
	        },

	        /**
	         * 向量缩放
	         * @param {Vector2} out
	         * @param {Vector2} v
	         * @param {number} s
	         */
	        scale: function (out, v, s) {
	            out[0] = v[0] * s;
	            out[1] = v[1] * s;
	            return out;
	        },

	        /**
	         * 向量归一化
	         * @param {Vector2} out
	         * @param {Vector2} v
	         */
	        normalize: function (out, v) {
	            var d = vector.len(v);
	            if (d === 0) {
	                out[0] = 0;
	                out[1] = 0;
	            }
	            else {
	                out[0] = v[0] / d;
	                out[1] = v[1] / d;
	            }
	            return out;
	        },

	        /**
	         * 计算向量间距离
	         * @param {Vector2} v1
	         * @param {Vector2} v2
	         * @return {number}
	         */
	        distance: function (v1, v2) {
	            return Math.sqrt(
	                (v1[0] - v2[0]) * (v1[0] - v2[0])
	                + (v1[1] - v2[1]) * (v1[1] - v2[1])
	            );
	        },

	        /**
	         * 向量距离平方
	         * @param {Vector2} v1
	         * @param {Vector2} v2
	         * @return {number}
	         */
	        distanceSquare: function (v1, v2) {
	            return (v1[0] - v2[0]) * (v1[0] - v2[0])
	                + (v1[1] - v2[1]) * (v1[1] - v2[1]);
	        },

	        /**
	         * 求负向量
	         * @param {Vector2} out
	         * @param {Vector2} v
	         */
	        negate: function (out, v) {
	            out[0] = -v[0];
	            out[1] = -v[1];
	            return out;
	        },

	        /**
	         * 插值两个点
	         * @param {Vector2} out
	         * @param {Vector2} v1
	         * @param {Vector2} v2
	         * @param {number} t
	         */
	        lerp: function (out, v1, v2, t) {
	            out[0] = v1[0] + t * (v2[0] - v1[0]);
	            out[1] = v1[1] + t * (v2[1] - v1[1]);
	            return out;
	        },

	        /**
	         * 矩阵左乘向量
	         * @param {Vector2} out
	         * @param {Vector2} v
	         * @param {Vector2} m
	         */
	        applyTransform: function (out, v, m) {
	            var x = v[0];
	            var y = v[1];
	            out[0] = m[0] * x + m[2] * y + m[4];
	            out[1] = m[1] * x + m[3] * y + m[5];
	            return out;
	        },
	        /**
	         * 求两个向量最小值
	         * @param  {Vector2} out
	         * @param  {Vector2} v1
	         * @param  {Vector2} v2
	         */
	        min: function (out, v1, v2) {
	            out[0] = Math.min(v1[0], v2[0]);
	            out[1] = Math.min(v1[1], v2[1]);
	            return out;
	        },
	        /**
	         * 求两个向量最大值
	         * @param  {Vector2} out
	         * @param  {Vector2} v1
	         * @param  {Vector2} v2
	         */
	        max: function (out, v1, v2) {
	            out[0] = Math.max(v1[0], v2[0]);
	            out[1] = Math.max(v1[1], v2[1]);
	            return out;
	        }
	    };

	    vector.length = vector.len;
	    vector.lengthSquare = vector.lenSquare;
	    vector.dist = vector.distance;
	    vector.distSquare = vector.distanceSquare;

	    module.exports = vector;



/***/ },
/* 11 */
/***/ function(module, exports) {

	
	    var ArrayCtor = typeof Float32Array === 'undefined'
	        ? Array
	        : Float32Array;
	    /**
	     * 3x2矩阵操作类
	     * @exports zrender/tool/matrix
	     */
	    var matrix = {
	        /**
	         * 创建一个单位矩阵
	         * @return {Float32Array|Array.<number>}
	         */
	        create : function() {
	            var out = new ArrayCtor(6);
	            matrix.identity(out);

	            return out;
	        },
	        /**
	         * 设置矩阵为单位矩阵
	         * @param {Float32Array|Array.<number>} out
	         */
	        identity : function(out) {
	            out[0] = 1;
	            out[1] = 0;
	            out[2] = 0;
	            out[3] = 1;
	            out[4] = 0;
	            out[5] = 0;
	            return out;
	        },
	        /**
	         * 复制矩阵
	         * @param {Float32Array|Array.<number>} out
	         * @param {Float32Array|Array.<number>} m
	         */
	        copy: function(out, m) {
	            out[0] = m[0];
	            out[1] = m[1];
	            out[2] = m[2];
	            out[3] = m[3];
	            out[4] = m[4];
	            out[5] = m[5];
	            return out;
	        },
	        /**
	         * 矩阵相乘
	         * @param {Float32Array|Array.<number>} out
	         * @param {Float32Array|Array.<number>} m1
	         * @param {Float32Array|Array.<number>} m2
	         */
	        mul : function (out, m1, m2) {
	            // Consider matrix.mul(m, m2, m);
	            // where out is the same as m2.
	            // So use temp variable to escape error.
	            var out0 = m1[0] * m2[0] + m1[2] * m2[1];
	            var out1 = m1[1] * m2[0] + m1[3] * m2[1];
	            var out2 = m1[0] * m2[2] + m1[2] * m2[3];
	            var out3 = m1[1] * m2[2] + m1[3] * m2[3];
	            var out4 = m1[0] * m2[4] + m1[2] * m2[5] + m1[4];
	            var out5 = m1[1] * m2[4] + m1[3] * m2[5] + m1[5];
	            out[0] = out0;
	            out[1] = out1;
	            out[2] = out2;
	            out[3] = out3;
	            out[4] = out4;
	            out[5] = out5;
	            return out;
	        },
	        /**
	         * 平移变换
	         * @param {Float32Array|Array.<number>} out
	         * @param {Float32Array|Array.<number>} a
	         * @param {Float32Array|Array.<number>} v
	         */
	        translate : function(out, a, v) {
	            out[0] = a[0];
	            out[1] = a[1];
	            out[2] = a[2];
	            out[3] = a[3];
	            out[4] = a[4] + v[0];
	            out[5] = a[5] + v[1];
	            return out;
	        },
	        /**
	         * 旋转变换
	         * @param {Float32Array|Array.<number>} out
	         * @param {Float32Array|Array.<number>} a
	         * @param {number} rad
	         */
	        rotate : function(out, a, rad) {
	            var aa = a[0];
	            var ac = a[2];
	            var atx = a[4];
	            var ab = a[1];
	            var ad = a[3];
	            var aty = a[5];
	            var st = Math.sin(rad);
	            var ct = Math.cos(rad);

	            out[0] = aa * ct + ab * st;
	            out[1] = -aa * st + ab * ct;
	            out[2] = ac * ct + ad * st;
	            out[3] = -ac * st + ct * ad;
	            out[4] = ct * atx + st * aty;
	            out[5] = ct * aty - st * atx;
	            return out;
	        },
	        /**
	         * 缩放变换
	         * @param {Float32Array|Array.<number>} out
	         * @param {Float32Array|Array.<number>} a
	         * @param {Float32Array|Array.<number>} v
	         */
	        scale : function(out, a, v) {
	            var vx = v[0];
	            var vy = v[1];
	            out[0] = a[0] * vx;
	            out[1] = a[1] * vy;
	            out[2] = a[2] * vx;
	            out[3] = a[3] * vy;
	            out[4] = a[4] * vx;
	            out[5] = a[5] * vy;
	            return out;
	        },
	        /**
	         * 求逆矩阵
	         * @param {Float32Array|Array.<number>} out
	         * @param {Float32Array|Array.<number>} a
	         */
	        invert : function(out, a) {

	            var aa = a[0];
	            var ac = a[2];
	            var atx = a[4];
	            var ab = a[1];
	            var ad = a[3];
	            var aty = a[5];

	            var det = aa * ad - ab * ac;
	            if (!det) {
	                return null;
	            }
	            det = 1.0 / det;

	            out[0] = ad * det;
	            out[1] = -ab * det;
	            out[2] = -ac * det;
	            out[3] = aa * det;
	            out[4] = (ac * aty - ad * atx) * det;
	            out[5] = (ab * atx - aa * aty) * det;
	            return out;
	        }
	    };

	    module.exports = matrix;



/***/ },
/* 12 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @module echarts/model/Model
	 */


	    var zrUtil = __webpack_require__(4);
	    var clazzUtil = __webpack_require__(13);
	    var env = __webpack_require__(2);

	    /**
	     * @alias module:echarts/model/Model
	     * @constructor
	     * @param {Object} option
	     * @param {module:echarts/model/Model} [parentModel]
	     * @param {module:echarts/model/Global} [ecModel]
	     */
	    function Model(option, parentModel, ecModel) {
	        /**
	         * @type {module:echarts/model/Model}
	         * @readOnly
	         */
	        this.parentModel = parentModel;

	        /**
	         * @type {module:echarts/model/Global}
	         * @readOnly
	         */
	        this.ecModel = ecModel;

	        /**
	         * @type {Object}
	         * @protected
	         */
	        this.option = option;

	        // Simple optimization
	        // if (this.init) {
	        //     if (arguments.length <= 4) {
	        //         this.init(option, parentModel, ecModel, extraOpt);
	        //     }
	        //     else {
	        //         this.init.apply(this, arguments);
	        //     }
	        // }
	    }

	    Model.prototype = {

	        constructor: Model,

	        /**
	         * Model 的初始化函数
	         * @param {Object} option
	         */
	        init: null,

	        /**
	         * 从新的 Option merge
	         */
	        mergeOption: function (option) {
	            zrUtil.merge(this.option, option, true);
	        },

	        /**
	         * @param {string|Array.<string>} path
	         * @param {boolean} [ignoreParent=false]
	         * @return {*}
	         */
	        get: function (path, ignoreParent) {
	            if (path == null) {
	                return this.option;
	            }

	            return doGet(
	                this.option,
	                this.parsePath(path),
	                !ignoreParent && getParent(this, path)
	            );
	        },

	        /**
	         * @param {string} key
	         * @param {boolean} [ignoreParent=false]
	         * @return {*}
	         */
	        getShallow: function (key, ignoreParent) {
	            var option = this.option;

	            var val = option == null ? option : option[key];
	            var parentModel = !ignoreParent && getParent(this, key);
	            if (val == null && parentModel) {
	                val = parentModel.getShallow(key);
	            }
	            return val;
	        },

	        /**
	         * @param {string|Array.<string>} [path]
	         * @param {module:echarts/model/Model} [parentModel]
	         * @return {module:echarts/model/Model}
	         */
	        getModel: function (path, parentModel) {
	            var obj = path == null
	                ? this.option
	                : doGet(this.option, path = this.parsePath(path));

	            var thisParentModel;
	            parentModel = parentModel || (
	                (thisParentModel = getParent(this, path))
	                    && thisParentModel.getModel(path)
	            );

	            return new Model(obj, parentModel, this.ecModel);
	        },

	        /**
	         * If model has option
	         */
	        isEmpty: function () {
	            return this.option == null;
	        },

	        restoreData: function () {},

	        // Pending
	        clone: function () {
	            var Ctor = this.constructor;
	            return new Ctor(zrUtil.clone(this.option));
	        },

	        setReadOnly: function (properties) {
	            clazzUtil.setReadOnly(this, properties);
	        },

	        // If path is null/undefined, return null/undefined.
	        parsePath: function(path) {
	            if (typeof path === 'string') {
	                path = path.split('.');
	            }
	            return path;
	        },

	        /**
	         * @param {Function} getParentMethod
	         *        param {Array.<string>|string} path
	         *        return {module:echarts/model/Model}
	         */
	        customizeGetParent: function (getParentMethod) {
	            clazzUtil.set(this, 'getParent', getParentMethod);
	        },

	        isAnimationEnabled: function () {
	            if (!env.node) {
	                if (this.option.animation != null) {
	                    return !!this.option.animation;
	                }
	                else if (this.parentModel) {
	                    return this.parentModel.isAnimationEnabled();
	                }
	            }
	        }
	    };

	    function doGet(obj, pathArr, parentModel) {
	        for (var i = 0; i < pathArr.length; i++) {
	            // Ignore empty
	            if (!pathArr[i]) {
	                continue;
	            }
	            // obj could be number/string/... (like 0)
	            obj = (obj && typeof obj === 'object') ? obj[pathArr[i]] : null;
	            if (obj == null) {
	                break;
	            }
	        }
	        if (obj == null && parentModel) {
	            obj = parentModel.get(pathArr);
	        }
	        return obj;
	    }

	    // `path` can be null/undefined
	    function getParent(model, path) {
	        var getParentMethod = clazzUtil.get(model, 'getParent');
	        return getParentMethod ? getParentMethod.call(model, path) : model.parentModel;
	    }

	    // Enable Model.extend.
	    clazzUtil.enableClassExtend(Model);

	    var mixin = zrUtil.mixin;
	    mixin(Model, __webpack_require__(14));
	    mixin(Model, __webpack_require__(16));
	    mixin(Model, __webpack_require__(17));
	    mixin(Model, __webpack_require__(68));

	    module.exports = Model;


/***/ },
/* 13 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);

	    var clazz = {};

	    var TYPE_DELIMITER = '.';
	    var IS_CONTAINER = '___EC__COMPONENT__CONTAINER___';
	    var MEMBER_PRIFIX = '\0ec_\0';

	    /**
	     * Hide private class member.
	     * The same behavior as `host[name] = value;` (can be right-value)
	     * @public
	     */
	    clazz.set = function (host, name, value) {
	        return (host[MEMBER_PRIFIX + name] = value);
	    };

	    /**
	     * Hide private class member.
	     * The same behavior as `host[name];`
	     * @public
	     */
	    clazz.get = function (host, name) {
	        return host[MEMBER_PRIFIX + name];
	    };

	    /**
	     * For hidden private class member.
	     * The same behavior as `host.hasOwnProperty(name);`
	     * @public
	     */
	    clazz.hasOwn = function (host, name) {
	        return host.hasOwnProperty(MEMBER_PRIFIX + name);
	    };

	    /**
	     * Notice, parseClassType('') should returns {main: '', sub: ''}
	     * @public
	     */
	    var parseClassType = clazz.parseClassType = function (componentType) {
	        var ret = {main: '', sub: ''};
	        if (componentType) {
	            componentType = componentType.split(TYPE_DELIMITER);
	            ret.main = componentType[0] || '';
	            ret.sub = componentType[1] || '';
	        }
	        return ret;
	    };

	    /**
	     * @public
	     */
	    function checkClassType(componentType) {
	        zrUtil.assert(
	            /^[a-zA-Z0-9_]+([.][a-zA-Z0-9_]+)?$/.test(componentType),
	            'componentType "' + componentType + '" illegal'
	        );
	    }

	    /**
	     * @public
	     */
	    clazz.enableClassExtend = function (RootClass, mandatoryMethods) {

	        RootClass.$constructor = RootClass;
	        RootClass.extend = function (proto) {

	            if (true) {
	                zrUtil.each(mandatoryMethods, function (method) {
	                    if (!proto[method]) {
	                        console.warn(
	                            'Method `' + method + '` should be implemented'
	                            + (proto.type ? ' in ' + proto.type : '') + '.'
	                        );
	                    }
	                });
	            }

	            var superClass = this;
	            var ExtendedClass = function () {
	                if (!proto.$constructor) {
	                    superClass.apply(this, arguments);
	                }
	                else {
	                    proto.$constructor.apply(this, arguments);
	                }
	            };

	            zrUtil.extend(ExtendedClass.prototype, proto);

	            ExtendedClass.extend = this.extend;
	            ExtendedClass.superCall = superCall;
	            ExtendedClass.superApply = superApply;
	            zrUtil.inherits(ExtendedClass, this);
	            ExtendedClass.superClass = superClass;

	            return ExtendedClass;
	        };
	    };

	    // superCall should have class info, which can not be fetch from 'this'.
	    // Consider this case:
	    // class A has method f,
	    // class B inherits class A, overrides method f, f call superApply('f'),
	    // class C inherits class B, do not overrides method f,
	    // then when method of class C is called, dead loop occured.
	    function superCall(context, methodName) {
	        var args = zrUtil.slice(arguments, 2);
	        return this.superClass.prototype[methodName].apply(context, args);
	    }

	    function superApply(context, methodName, args) {
	        return this.superClass.prototype[methodName].apply(context, args);
	    }

	    /**
	     * @param {Object} entity
	     * @param {Object} options
	     * @param {boolean} [options.registerWhenExtend]
	     * @public
	     */
	    clazz.enableClassManagement = function (entity, options) {
	        options = options || {};

	        /**
	         * Component model classes
	         * key: componentType,
	         * value:
	         *     componentClass, when componentType is 'xxx'
	         *     or Object.<subKey, componentClass>, when componentType is 'xxx.yy'
	         * @type {Object}
	         */
	        var storage = {};

	        entity.registerClass = function (Clazz, componentType) {
	            if (componentType) {
	                checkClassType(componentType);
	                componentType = parseClassType(componentType);

	                if (!componentType.sub) {
	                    if (true) {
	                        if (storage[componentType.main]) {
	                            console.warn(componentType.main + ' exists.');
	                        }
	                    }
	                    storage[componentType.main] = Clazz;
	                }
	                else if (componentType.sub !== IS_CONTAINER) {
	                    var container = makeContainer(componentType);
	                    container[componentType.sub] = Clazz;
	                }
	            }
	            return Clazz;
	        };

	        entity.getClass = function (componentMainType, subType, throwWhenNotFound) {
	            var Clazz = storage[componentMainType];

	            if (Clazz && Clazz[IS_CONTAINER]) {
	                Clazz = subType ? Clazz[subType] : null;
	            }

	            if (throwWhenNotFound && !Clazz) {
	                throw new Error(
	                    !subType
	                        ? componentMainType + '.' + 'type should be specified.'
	                        : 'Component ' + componentMainType + '.' + (subType || '') + ' not exists. Load it first.'
	                );
	            }

	            return Clazz;
	        };

	        entity.getClassesByMainType = function (componentType) {
	            componentType = parseClassType(componentType);

	            var result = [];
	            var obj = storage[componentType.main];

	            if (obj && obj[IS_CONTAINER]) {
	                zrUtil.each(obj, function (o, type) {
	                    type !== IS_CONTAINER && result.push(o);
	                });
	            }
	            else {
	                result.push(obj);
	            }

	            return result;
	        };

	        entity.hasClass = function (componentType) {
	            // Just consider componentType.main.
	            componentType = parseClassType(componentType);
	            return !!storage[componentType.main];
	        };

	        /**
	         * @return {Array.<string>} Like ['aa', 'bb'], but can not be ['aa.xx']
	         */
	        entity.getAllClassMainTypes = function () {
	            var types = [];
	            zrUtil.each(storage, function (obj, type) {
	                types.push(type);
	            });
	            return types;
	        };

	        /**
	         * If a main type is container and has sub types
	         * @param  {string}  mainType
	         * @return {boolean}
	         */
	        entity.hasSubTypes = function (componentType) {
	            componentType = parseClassType(componentType);
	            var obj = storage[componentType.main];
	            return obj && obj[IS_CONTAINER];
	        };

	        entity.parseClassType = parseClassType;

	        function makeContainer(componentType) {
	            var container = storage[componentType.main];
	            if (!container || !container[IS_CONTAINER]) {
	                container = storage[componentType.main] = {};
	                container[IS_CONTAINER] = true;
	            }
	            return container;
	        }

	        if (options.registerWhenExtend) {
	            var originalExtend = entity.extend;
	            if (originalExtend) {
	                entity.extend = function (proto) {
	                    var ExtendedClass = originalExtend.call(this, proto);
	                    return entity.registerClass(ExtendedClass, proto.type);
	                };
	            }
	        }

	        return entity;
	    };

	    /**
	     * @param {string|Array.<string>} properties
	     */
	    clazz.setReadOnly = function (obj, properties) {
	        // FIXME It seems broken in IE8 simulation of IE11
	        // if (!zrUtil.isArray(properties)) {
	        //     properties = properties != null ? [properties] : [];
	        // }
	        // zrUtil.each(properties, function (prop) {
	        //     var value = obj[prop];

	        //     Object.defineProperty
	        //         && Object.defineProperty(obj, prop, {
	        //             value: value, writable: false
	        //         });
	        //     zrUtil.isArray(obj[prop])
	        //         && Object.freeze
	        //         && Object.freeze(obj[prop]);
	        // });
	    };

	    module.exports = clazz;


/***/ },
/* 14 */
/***/ function(module, exports, __webpack_require__) {

	
	    var getLineStyle = __webpack_require__(15)(
	        [
	            ['lineWidth', 'width'],
	            ['stroke', 'color'],
	            ['opacity'],
	            ['shadowBlur'],
	            ['shadowOffsetX'],
	            ['shadowOffsetY'],
	            ['shadowColor']
	        ]
	    );
	    module.exports = {
	        getLineStyle: function (excludes) {
	            var style = getLineStyle.call(this, excludes);
	            var lineDash = this.getLineDash(style.lineWidth);
	            lineDash && (style.lineDash = lineDash);
	            return style;
	        },

	        getLineDash: function (lineWidth) {
	            if (lineWidth == null) {
	                lineWidth = 1;
	            }
	            var lineType = this.get('type');
	            var dotSize = Math.max(lineWidth, 2);
	            var dashSize = lineWidth * 4;
	            return (lineType === 'solid' || lineType == null) ? null
	                : (lineType === 'dashed' ? [dashSize, dashSize] : [dotSize, dotSize]);
	        }
	    };


/***/ },
/* 15 */
/***/ function(module, exports, __webpack_require__) {

	// TODO Parse shadow style
	// TODO Only shallow path support

	    var zrUtil = __webpack_require__(4);

	    module.exports = function (properties) {
	        // Normalize
	        for (var i = 0; i < properties.length; i++) {
	            if (!properties[i][1]) {
	               properties[i][1] = properties[i][0];
	            }
	        }
	        return function (excludes, includes) {
	            var style = {};
	            for (var i = 0; i < properties.length; i++) {
	                var propName = properties[i][1];
	                if ((excludes && zrUtil.indexOf(excludes, propName) >= 0)
	                    || (includes && zrUtil.indexOf(includes, propName) < 0)
	                ) {
	                    continue;
	                }
	                var val = this.getShallow(propName);
	                if (val != null) {
	                    style[properties[i][0]] = val;
	                }
	            }
	            return style;
	        };
	    };


/***/ },
/* 16 */
/***/ function(module, exports, __webpack_require__) {

	
	    module.exports = {
	        getAreaStyle: __webpack_require__(15)(
	            [
	                ['fill', 'color'],
	                ['shadowBlur'],
	                ['shadowOffsetX'],
	                ['shadowOffsetY'],
	                ['opacity'],
	                ['shadowColor']
	            ]
	        )
	    };


/***/ },
/* 17 */
/***/ function(module, exports, __webpack_require__) {

	

	    var textContain = __webpack_require__(8);
	    var graphicUtil = __webpack_require__(18);

	    module.exports = {
	        /**
	         * Get color property or get color from option.textStyle.color
	         * @return {string}
	         */
	        getTextColor: function () {
	            var ecModel = this.ecModel;
	            return this.getShallow('color')
	                || (ecModel && ecModel.get('textStyle.color'));
	        },

	        /**
	         * Create font string from fontStyle, fontWeight, fontSize, fontFamily
	         * @return {string}
	         */
	        getFont: function () {
	            return graphicUtil.getFont({
	                fontStyle: this.getShallow('fontStyle'),
	                fontWeight: this.getShallow('fontWeight'),
	                fontSize: this.getShallow('fontSize'),
	                fontFamily: this.getShallow('fontFamily')
	            }, this.ecModel);
	        },

	        getTextRect: function (text) {
	            return textContain.getBoundingRect(
	                text,
	                this.getFont(),
	                this.getShallow('align'),
	                this.getShallow('baseline')
	            );
	        },

	        truncateText: function (text, containerWidth, ellipsis, options) {
	            return textContain.truncateText(
	                text, containerWidth, this.getFont(), ellipsis, options
	            );
	        }
	    };


/***/ },
/* 18 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var zrUtil = __webpack_require__(4);

	    var pathTool = __webpack_require__(19);
	    var Path = __webpack_require__(20);
	    var colorTool = __webpack_require__(31);
	    var matrix = __webpack_require__(11);
	    var vector = __webpack_require__(10);
	    var Transformable = __webpack_require__(26);
	    var BoundingRect = __webpack_require__(9);

	    var round = Math.round;
	    var mathMax = Math.max;
	    var mathMin = Math.min;

	    var graphic = {};

	    graphic.Group = __webpack_require__(48);

	    graphic.Image = __webpack_require__(49);

	    graphic.Text = __webpack_require__(50);

	    graphic.Circle = __webpack_require__(51);

	    graphic.Sector = __webpack_require__(52);

	    graphic.Ring = __webpack_require__(53);

	    graphic.Polygon = __webpack_require__(54);

	    graphic.Polyline = __webpack_require__(58);

	    graphic.Rect = __webpack_require__(59);

	    graphic.Line = __webpack_require__(61);

	    graphic.BezierCurve = __webpack_require__(62);

	    graphic.Arc = __webpack_require__(63);

	    graphic.CompoundPath = __webpack_require__(64);

	    graphic.LinearGradient = __webpack_require__(65);

	    graphic.RadialGradient = __webpack_require__(67);

	    graphic.BoundingRect = BoundingRect;

	    /**
	     * Extend shape with parameters
	     */
	    graphic.extendShape = function (opts) {
	        return Path.extend(opts);
	    };

	    /**
	     * Extend path
	     */
	    graphic.extendPath = function (pathData, opts) {
	        return pathTool.extendFromString(pathData, opts);
	    };

	    /**
	     * Create a path element from path data string
	     * @param {string} pathData
	     * @param {Object} opts
	     * @param {module:zrender/core/BoundingRect} rect
	     * @param {string} [layout=cover] 'center' or 'cover'
	     */
	    graphic.makePath = function (pathData, opts, rect, layout) {
	        var path = pathTool.createFromString(pathData, opts);
	        var boundingRect = path.getBoundingRect();
	        if (rect) {
	            var aspect = boundingRect.width / boundingRect.height;

	            if (layout === 'center') {
	                // Set rect to center, keep width / height ratio.
	                var width = rect.height * aspect;
	                var height;
	                if (width <= rect.width) {
	                    height = rect.height;
	                }
	                else {
	                    width = rect.width;
	                    height = width / aspect;
	                }
	                var cx = rect.x + rect.width / 2;
	                var cy = rect.y + rect.height / 2;

	                rect.x = cx - width / 2;
	                rect.y = cy - height / 2;
	                rect.width = width;
	                rect.height = height;
	            }

	            graphic.resizePath(path, rect);
	        }
	        return path;
	    };

	    graphic.mergePath = pathTool.mergePath,

	    /**
	     * Resize a path to fit the rect
	     * @param {module:zrender/graphic/Path} path
	     * @param {Object} rect
	     */
	    graphic.resizePath = function (path, rect) {
	        if (!path.applyTransform) {
	            return;
	        }

	        var pathRect = path.getBoundingRect();

	        var m = pathRect.calculateTransform(rect);

	        path.applyTransform(m);
	    };

	    /**
	     * Sub pixel optimize line for canvas
	     *
	     * @param {Object} param
	     * @param {Object} [param.shape]
	     * @param {number} [param.shape.x1]
	     * @param {number} [param.shape.y1]
	     * @param {number} [param.shape.x2]
	     * @param {number} [param.shape.y2]
	     * @param {Object} [param.style]
	     * @param {number} [param.style.lineWidth]
	     * @return {Object} Modified param
	     */
	    graphic.subPixelOptimizeLine = function (param) {
	        var subPixelOptimize = graphic.subPixelOptimize;
	        var shape = param.shape;
	        var lineWidth = param.style.lineWidth;

	        if (round(shape.x1 * 2) === round(shape.x2 * 2)) {
	            shape.x1 = shape.x2 = subPixelOptimize(shape.x1, lineWidth, true);
	        }
	        if (round(shape.y1 * 2) === round(shape.y2 * 2)) {
	            shape.y1 = shape.y2 = subPixelOptimize(shape.y1, lineWidth, true);
	        }
	        return param;
	    };

	    /**
	     * Sub pixel optimize rect for canvas
	     *
	     * @param {Object} param
	     * @param {Object} [param.shape]
	     * @param {number} [param.shape.x]
	     * @param {number} [param.shape.y]
	     * @param {number} [param.shape.width]
	     * @param {number} [param.shape.height]
	     * @param {Object} [param.style]
	     * @param {number} [param.style.lineWidth]
	     * @return {Object} Modified param
	     */
	    graphic.subPixelOptimizeRect = function (param) {
	        var subPixelOptimize = graphic.subPixelOptimize;
	        var shape = param.shape;
	        var lineWidth = param.style.lineWidth;
	        var originX = shape.x;
	        var originY = shape.y;
	        var originWidth = shape.width;
	        var originHeight = shape.height;
	        shape.x = subPixelOptimize(shape.x, lineWidth, true);
	        shape.y = subPixelOptimize(shape.y, lineWidth, true);
	        shape.width = Math.max(
	            subPixelOptimize(originX + originWidth, lineWidth, false) - shape.x,
	            originWidth === 0 ? 0 : 1
	        );
	        shape.height = Math.max(
	            subPixelOptimize(originY + originHeight, lineWidth, false) - shape.y,
	            originHeight === 0 ? 0 : 1
	        );
	        return param;
	    };

	    /**
	     * Sub pixel optimize for canvas
	     *
	     * @param {number} position Coordinate, such as x, y
	     * @param {number} lineWidth Should be nonnegative integer.
	     * @param {boolean=} positiveOrNegative Default false (negative).
	     * @return {number} Optimized position.
	     */
	    graphic.subPixelOptimize = function (position, lineWidth, positiveOrNegative) {
	        // Assure that (position + lineWidth / 2) is near integer edge,
	        // otherwise line will be fuzzy in canvas.
	        var doubledPosition = round(position * 2);
	        return (doubledPosition + round(lineWidth)) % 2 === 0
	            ? doubledPosition / 2
	            : (doubledPosition + (positiveOrNegative ? 1 : -1)) / 2;
	    };

	    function hasFillOrStroke(fillOrStroke) {
	        return fillOrStroke != null && fillOrStroke != 'none';
	    }

	    function liftColor(color) {
	        return typeof color === 'string' ? colorTool.lift(color, -0.1) : color;
	    }

	    /**
	     * @private
	     */
	    function cacheElementStl(el) {
	        if (el.__hoverStlDirty) {
	            var stroke = el.style.stroke;
	            var fill = el.style.fill;

	            // Create hoverStyle on mouseover
	            var hoverStyle = el.__hoverStl;
	            hoverStyle.fill = hoverStyle.fill
	                || (hasFillOrStroke(fill) ? liftColor(fill) : null);
	            hoverStyle.stroke = hoverStyle.stroke
	                || (hasFillOrStroke(stroke) ? liftColor(stroke) : null);

	            var normalStyle = {};
	            for (var name in hoverStyle) {
	                if (hoverStyle.hasOwnProperty(name)) {
	                    normalStyle[name] = el.style[name];
	                }
	            }

	            el.__normalStl = normalStyle;

	            el.__hoverStlDirty = false;
	        }
	    }

	    /**
	     * @private
	     */
	    function doSingleEnterHover(el) {
	        if (el.__isHover) {
	            return;
	        }

	        cacheElementStl(el);

	        if (el.useHoverLayer) {
	            el.__zr && el.__zr.addHover(el, el.__hoverStl);
	        }
	        else {
	            el.setStyle(el.__hoverStl);
	            el.z2 += 1;
	        }

	        el.__isHover = true;
	    }

	    /**
	     * @inner
	     */
	    function doSingleLeaveHover(el) {
	        if (!el.__isHover) {
	            return;
	        }

	        var normalStl = el.__normalStl;
	        if (el.useHoverLayer) {
	            el.__zr && el.__zr.removeHover(el);
	        }
	        else {
	            normalStl && el.setStyle(normalStl);
	            el.z2 -= 1;
	        }

	        el.__isHover = false;
	    }

	    /**
	     * @inner
	     */
	    function doEnterHover(el) {
	        el.type === 'group'
	            ? el.traverse(function (child) {
	                if (child.type !== 'group') {
	                    doSingleEnterHover(child);
	                }
	            })
	            : doSingleEnterHover(el);
	    }

	    function doLeaveHover(el) {
	        el.type === 'group'
	            ? el.traverse(function (child) {
	                if (child.type !== 'group') {
	                    doSingleLeaveHover(child);
	                }
	            })
	            : doSingleLeaveHover(el);
	    }

	    /**
	     * @inner
	     */
	    function setElementHoverStl(el, hoverStl) {
	        // If element has sepcified hoverStyle, then use it instead of given hoverStyle
	        // Often used when item group has a label element and it's hoverStyle is different
	        el.__hoverStl = el.hoverStyle || hoverStl || {};
	        el.__hoverStlDirty = true;

	        if (el.__isHover) {
	            cacheElementStl(el);
	        }
	    }

	    /**
	     * @inner
	     */
	    function onElementMouseOver(e) {
	        if (this.__hoverSilentOnTouch && e.zrByTouch) {
	            return;
	        }

	        // Only if element is not in emphasis status
	        !this.__isEmphasis && doEnterHover(this);
	    }

	    /**
	     * @inner
	     */
	    function onElementMouseOut(e) {
	        if (this.__hoverSilentOnTouch && e.zrByTouch) {
	            return;
	        }

	        // Only if element is not in emphasis status
	        !this.__isEmphasis && doLeaveHover(this);
	    }

	    /**
	     * @inner
	     */
	    function enterEmphasis() {
	        this.__isEmphasis = true;
	        doEnterHover(this);
	    }

	    /**
	     * @inner
	     */
	    function leaveEmphasis() {
	        this.__isEmphasis = false;
	        doLeaveHover(this);
	    }

	    /**
	     * Set hover style of element.
	     * This method can be called repeatly without side-effects.
	     * @param {module:zrender/Element} el
	     * @param {Object} [hoverStyle]
	     * @param {Object} [opt]
	     * @param {boolean} [opt.hoverSilentOnTouch=false]
	     *        In touch device, mouseover event will be trigger on touchstart event
	     *        (see module:zrender/dom/HandlerProxy). By this mechanism, we can
	     *        conviniently use hoverStyle when tap on touch screen without additional
	     *        code for compatibility.
	     *        But if the chart/component has select feature, which usually also use
	     *        hoverStyle, there might be conflict between 'select-highlight' and
	     *        'hover-highlight' especially when roam is enabled (see geo for example).
	     *        In this case, hoverSilentOnTouch should be used to disable hover-highlight
	     *        on touch device.
	     */
	    graphic.setHoverStyle = function (el, hoverStyle, opt) {
	        el.__hoverSilentOnTouch = opt && opt.hoverSilentOnTouch;

	        el.type === 'group'
	            ? el.traverse(function (child) {
	                if (child.type !== 'group') {
	                    setElementHoverStl(child, hoverStyle);
	                }
	            })
	            : setElementHoverStl(el, hoverStyle);

	        // Duplicated function will be auto-ignored, see Eventful.js.
	        el.on('mouseover', onElementMouseOver)
	          .on('mouseout', onElementMouseOut);

	        // Emphasis, normal can be triggered manually
	        el.on('emphasis', enterEmphasis)
	          .on('normal', leaveEmphasis);
	    };

	    /**
	     * Set text option in the style
	     * @param {Object} textStyle
	     * @param {module:echarts/model/Model} labelModel
	     * @param {string} color
	     */
	    graphic.setText = function (textStyle, labelModel, color) {
	        var labelPosition = labelModel.getShallow('position') || 'inside';
	        var labelOffset = labelModel.getShallow('offset');
	        var labelColor = labelPosition.indexOf('inside') >= 0 ? 'white' : color;
	        var textStyleModel = labelModel.getModel('textStyle');
	        zrUtil.extend(textStyle, {
	            textDistance: labelModel.getShallow('distance') || 5,
	            textFont: textStyleModel.getFont(),
	            textPosition: labelPosition,
	            textOffset: labelOffset,
	            textFill: textStyleModel.getTextColor() || labelColor
	        });
	    };

	    graphic.getFont = function (opt, ecModel) {
	        var gTextStyleModel = ecModel && ecModel.getModel('textStyle');
	        return [
	            // FIXME in node-canvas fontWeight is before fontStyle
	            opt.fontStyle || gTextStyleModel && gTextStyleModel.getShallow('fontStyle') || '',
	            opt.fontWeight || gTextStyleModel && gTextStyleModel.getShallow('fontWeight') || '',
	            (opt.fontSize || gTextStyleModel && gTextStyleModel.getShallow('fontSize') || 12) + 'px',
	            opt.fontFamily || gTextStyleModel && gTextStyleModel.getShallow('fontFamily') || 'sans-serif'
	        ].join(' ');
	    };

	    function animateOrSetProps(isUpdate, el, props, animatableModel, dataIndex, cb) {
	        if (typeof dataIndex === 'function') {
	            cb = dataIndex;
	            dataIndex = null;
	        }
	        // Do not check 'animation' property directly here. Consider this case:
	        // animation model is an `itemModel`, whose does not have `isAnimationEnabled`
	        // but its parent model (`seriesModel`) does.
	        var animationEnabled = animatableModel && animatableModel.isAnimationEnabled();

	        if (animationEnabled) {
	            var postfix = isUpdate ? 'Update' : '';
	            var duration = animatableModel.getShallow('animationDuration' + postfix);
	            var animationEasing = animatableModel.getShallow('animationEasing' + postfix);
	            var animationDelay = animatableModel.getShallow('animationDelay' + postfix);
	            if (typeof animationDelay === 'function') {
	                animationDelay = animationDelay(
	                    dataIndex,
	                    animatableModel.getAnimationDelayParams
	                        ? animatableModel.getAnimationDelayParams(el, dataIndex)
	                        : null
	                );
	            }
	            if (typeof duration === 'function') {
	                duration = duration(dataIndex);
	            }

	            duration > 0
	                ? el.animateTo(props, duration, animationDelay || 0, animationEasing, cb)
	                : (el.stopAnimation(), el.attr(props), cb && cb());
	        }
	        else {
	            el.stopAnimation();
	            el.attr(props);
	            cb && cb();
	        }
	    }

	    /**
	     * Update graphic element properties with or without animation according to the configuration in series
	     * @param {module:zrender/Element} el
	     * @param {Object} props
	     * @param {module:echarts/model/Model} [animatableModel]
	     * @param {number} [dataIndex]
	     * @param {Function} [cb]
	     * @example
	     *     graphic.updateProps(el, {
	     *         position: [100, 100]
	     *     }, seriesModel, dataIndex, function () { console.log('Animation done!'); });
	     *     // Or
	     *     graphic.updateProps(el, {
	     *         position: [100, 100]
	     *     }, seriesModel, function () { console.log('Animation done!'); });
	     */
	    graphic.updateProps = function (el, props, animatableModel, dataIndex, cb) {
	        animateOrSetProps(true, el, props, animatableModel, dataIndex, cb);
	    };

	    /**
	     * Init graphic element properties with or without animation according to the configuration in series
	     * @param {module:zrender/Element} el
	     * @param {Object} props
	     * @param {module:echarts/model/Model} [animatableModel]
	     * @param {number} [dataIndex]
	     * @param {Function} cb
	     */
	    graphic.initProps = function (el, props, animatableModel, dataIndex, cb) {
	        animateOrSetProps(false, el, props, animatableModel, dataIndex, cb);
	    };

	    /**
	     * Get transform matrix of target (param target),
	     * in coordinate of its ancestor (param ancestor)
	     *
	     * @param {module:zrender/mixin/Transformable} target
	     * @param {module:zrender/mixin/Transformable} [ancestor]
	     */
	    graphic.getTransform = function (target, ancestor) {
	        var mat = matrix.identity([]);

	        while (target && target !== ancestor) {
	            matrix.mul(mat, target.getLocalTransform(), mat);
	            target = target.parent;
	        }

	        return mat;
	    };

	    /**
	     * Apply transform to an vertex.
	     * @param {Array.<number>} target [x, y]
	     * @param {Array.<number>|TypedArray.<number>|Object} transform Can be:
	     *      + Transform matrix: like [1, 0, 0, 1, 0, 0]
	     *      + {position, rotation, scale}, the same as `zrender/Transformable`.
	     * @param {boolean=} invert Whether use invert matrix.
	     * @return {Array.<number>} [x, y]
	     */
	    graphic.applyTransform = function (target, transform, invert) {
	        if (transform && !zrUtil.isArrayLike(transform)) {
	            transform = Transformable.getLocalTransform(transform);
	        }

	        if (invert) {
	            transform = matrix.invert([], transform);
	        }
	        return vector.applyTransform([], target, transform);
	    };

	    /**
	     * @param {string} direction 'left' 'right' 'top' 'bottom'
	     * @param {Array.<number>} transform Transform matrix: like [1, 0, 0, 1, 0, 0]
	     * @param {boolean=} invert Whether use invert matrix.
	     * @return {string} Transformed direction. 'left' 'right' 'top' 'bottom'
	     */
	    graphic.transformDirection = function (direction, transform, invert) {

	        // Pick a base, ensure that transform result will not be (0, 0).
	        var hBase = (transform[4] === 0 || transform[5] === 0 || transform[0] === 0)
	            ? 1 : Math.abs(2 * transform[4] / transform[0]);
	        var vBase = (transform[4] === 0 || transform[5] === 0 || transform[2] === 0)
	            ? 1 : Math.abs(2 * transform[4] / transform[2]);

	        var vertex = [
	            direction === 'left' ? -hBase : direction === 'right' ? hBase : 0,
	            direction === 'top' ? -vBase : direction === 'bottom' ? vBase : 0
	        ];

	        vertex = graphic.applyTransform(vertex, transform, invert);

	        return Math.abs(vertex[0]) > Math.abs(vertex[1])
	            ? (vertex[0] > 0 ? 'right' : 'left')
	            : (vertex[1] > 0 ? 'bottom' : 'top');
	    };

	    /**
	     * Apply group transition animation from g1 to g2.
	     * If no animatableModel, no animation.
	     */
	    graphic.groupTransition = function (g1, g2, animatableModel, cb) {
	        if (!g1 || !g2) {
	            return;
	        }

	        function getElMap(g) {
	            var elMap = {};
	            g.traverse(function (el) {
	                if (!el.isGroup && el.anid) {
	                    elMap[el.anid] = el;
	                }
	            });
	            return elMap;
	        }
	        function getAnimatableProps(el) {
	            var obj = {
	                position: vector.clone(el.position),
	                rotation: el.rotation
	            };
	            if (el.shape) {
	                obj.shape = zrUtil.extend({}, el.shape);
	            }
	            return obj;
	        }
	        var elMap1 = getElMap(g1);

	        g2.traverse(function (el) {
	            if (!el.isGroup && el.anid) {
	                var oldEl = elMap1[el.anid];
	                if (oldEl) {
	                    var newProp = getAnimatableProps(el);
	                    el.attr(getAnimatableProps(oldEl));
	                    graphic.updateProps(el, newProp, animatableModel, el.dataIndex);
	                }
	                // else {
	                //     if (el.previousProps) {
	                //         graphic.updateProps
	                //     }
	                // }
	            }
	        });
	    };

	    /**
	     * @param {Array.<Array.<number>>} points Like: [[23, 44], [53, 66], ...]
	     * @param {Object} rect {x, y, width, height}
	     * @return {Array.<Array.<number>>} A new clipped points.
	     */
	    graphic.clipPointsByRect = function (points, rect) {
	        return zrUtil.map(points, function (point) {
	            var x = point[0];
	            x = mathMax(x, rect.x);
	            x = mathMin(x, rect.x + rect.width);
	            var y = point[1];
	            y = mathMax(y, rect.y);
	            y = mathMin(y, rect.y + rect.height);
	            return [x, y];
	        });
	    };

	    /**
	     * @param {Object} targetRect {x, y, width, height}
	     * @param {Object} rect {x, y, width, height}
	     * @return {Object} A new clipped rect. If rect size are negative, return undefined.
	     */
	    graphic.clipRectByRect = function (targetRect, rect) {
	        var x = mathMax(targetRect.x, rect.x);
	        var x2 = mathMin(targetRect.x + targetRect.width, rect.x + rect.width);
	        var y = mathMax(targetRect.y, rect.y);
	        var y2 = mathMin(targetRect.y + targetRect.height, rect.y + rect.height);

	        if (x2 >= x && y2 >= y) {
	            return {
	                x: x,
	                y: y,
	                width: x2 - x,
	                height: y2 - y
	            };
	        }
	    };

	    module.exports = graphic;



/***/ },
/* 19 */
/***/ function(module, exports, __webpack_require__) {

	

	    var Path = __webpack_require__(20);
	    var PathProxy = __webpack_require__(36);
	    var transformPath = __webpack_require__(47);

	    // command chars
	    var cc = [
	        'm', 'M', 'l', 'L', 'v', 'V', 'h', 'H', 'z', 'Z',
	        'c', 'C', 'q', 'Q', 't', 'T', 's', 'S', 'a', 'A'
	    ];

	    var mathSqrt = Math.sqrt;
	    var mathSin = Math.sin;
	    var mathCos = Math.cos;
	    var PI = Math.PI;

	    var vMag = function(v) {
	        return Math.sqrt(v[0] * v[0] + v[1] * v[1]);
	    };
	    var vRatio = function(u, v) {
	        return (u[0] * v[0] + u[1] * v[1]) / (vMag(u) * vMag(v));
	    };
	    var vAngle = function(u, v) {
	        return (u[0] * v[1] < u[1] * v[0] ? -1 : 1)
	                * Math.acos(vRatio(u, v));
	    };

	    function processArc(x1, y1, x2, y2, fa, fs, rx, ry, psiDeg, cmd, path) {
	        var psi = psiDeg * (PI / 180.0);
	        var xp = mathCos(psi) * (x1 - x2) / 2.0
	                 + mathSin(psi) * (y1 - y2) / 2.0;
	        var yp = -1 * mathSin(psi) * (x1 - x2) / 2.0
	                 + mathCos(psi) * (y1 - y2) / 2.0;

	        var lambda = (xp * xp) / (rx * rx) + (yp * yp) / (ry * ry);

	        if (lambda > 1) {
	            rx *= mathSqrt(lambda);
	            ry *= mathSqrt(lambda);
	        }

	        var f = (fa === fs ? -1 : 1)
	            * mathSqrt((((rx * rx) * (ry * ry))
	                    - ((rx * rx) * (yp * yp))
	                    - ((ry * ry) * (xp * xp))) / ((rx * rx) * (yp * yp)
	                    + (ry * ry) * (xp * xp))
	                ) || 0;

	        var cxp = f * rx * yp / ry;
	        var cyp = f * -ry * xp / rx;

	        var cx = (x1 + x2) / 2.0
	                 + mathCos(psi) * cxp
	                 - mathSin(psi) * cyp;
	        var cy = (y1 + y2) / 2.0
	                + mathSin(psi) * cxp
	                + mathCos(psi) * cyp;

	        var theta = vAngle([ 1, 0 ], [ (xp - cxp) / rx, (yp - cyp) / ry ]);
	        var u = [ (xp - cxp) / rx, (yp - cyp) / ry ];
	        var v = [ (-1 * xp - cxp) / rx, (-1 * yp - cyp) / ry ];
	        var dTheta = vAngle(u, v);

	        if (vRatio(u, v) <= -1) {
	            dTheta = PI;
	        }
	        if (vRatio(u, v) >= 1) {
	            dTheta = 0;
	        }
	        if (fs === 0 && dTheta > 0) {
	            dTheta = dTheta - 2 * PI;
	        }
	        if (fs === 1 && dTheta < 0) {
	            dTheta = dTheta + 2 * PI;
	        }

	        path.addData(cmd, cx, cy, rx, ry, theta, dTheta, psi, fs);
	    }

	    function createPathProxyFromString(data) {
	        if (!data) {
	            return [];
	        }

	        // command string
	        var cs = data.replace(/-/g, ' -')
	            .replace(/  /g, ' ')
	            .replace(/ /g, ',')
	            .replace(/,,/g, ',');

	        var n;
	        // create pipes so that we can split the data
	        for (n = 0; n < cc.length; n++) {
	            cs = cs.replace(new RegExp(cc[n], 'g'), '|' + cc[n]);
	        }

	        // create array
	        var arr = cs.split('|');
	        // init context point
	        var cpx = 0;
	        var cpy = 0;

	        var path = new PathProxy();
	        var CMD = PathProxy.CMD;

	        var prevCmd;
	        for (n = 1; n < arr.length; n++) {
	            var str = arr[n];
	            var c = str.charAt(0);
	            var off = 0;
	            var p = str.slice(1).replace(/e,-/g, 'e-').split(',');
	            var cmd;

	            if (p.length > 0 && p[0] === '') {
	                p.shift();
	            }

	            for (var i = 0; i < p.length; i++) {
	                p[i] = parseFloat(p[i]);
	            }
	            while (off < p.length && !isNaN(p[off])) {
	                if (isNaN(p[0])) {
	                    break;
	                }
	                var ctlPtx;
	                var ctlPty;

	                var rx;
	                var ry;
	                var psi;
	                var fa;
	                var fs;

	                var x1 = cpx;
	                var y1 = cpy;

	                // convert l, H, h, V, and v to L
	                switch (c) {
	                    case 'l':
	                        cpx += p[off++];
	                        cpy += p[off++];
	                        cmd = CMD.L;
	                        path.addData(cmd, cpx, cpy);
	                        break;
	                    case 'L':
	                        cpx = p[off++];
	                        cpy = p[off++];
	                        cmd = CMD.L;
	                        path.addData(cmd, cpx, cpy);
	                        break;
	                    case 'm':
	                        cpx += p[off++];
	                        cpy += p[off++];
	                        cmd = CMD.M;
	                        path.addData(cmd, cpx, cpy);
	                        c = 'l';
	                        break;
	                    case 'M':
	                        cpx = p[off++];
	                        cpy = p[off++];
	                        cmd = CMD.M;
	                        path.addData(cmd, cpx, cpy);
	                        c = 'L';
	                        break;
	                    case 'h':
	                        cpx += p[off++];
	                        cmd = CMD.L;
	                        path.addData(cmd, cpx, cpy);
	                        break;
	                    case 'H':
	                        cpx = p[off++];
	                        cmd = CMD.L;
	                        path.addData(cmd, cpx, cpy);
	                        break;
	                    case 'v':
	                        cpy += p[off++];
	                        cmd = CMD.L;
	                        path.addData(cmd, cpx, cpy);
	                        break;
	                    case 'V':
	                        cpy = p[off++];
	                        cmd = CMD.L;
	                        path.addData(cmd, cpx, cpy);
	                        break;
	                    case 'C':
	                        cmd = CMD.C;
	                        path.addData(
	                            cmd, p[off++], p[off++], p[off++], p[off++], p[off++], p[off++]
	                        );
	                        cpx = p[off - 2];
	                        cpy = p[off - 1];
	                        break;
	                    case 'c':
	                        cmd = CMD.C;
	                        path.addData(
	                            cmd,
	                            p[off++] + cpx, p[off++] + cpy,
	                            p[off++] + cpx, p[off++] + cpy,
	                            p[off++] + cpx, p[off++] + cpy
	                        );
	                        cpx += p[off - 2];
	                        cpy += p[off - 1];
	                        break;
	                    case 'S':
	                        ctlPtx = cpx;
	                        ctlPty = cpy;
	                        var len = path.len();
	                        var pathData = path.data;
	                        if (prevCmd === CMD.C) {
	                            ctlPtx += cpx - pathData[len - 4];
	                            ctlPty += cpy - pathData[len - 3];
	                        }
	                        cmd = CMD.C;
	                        x1 = p[off++];
	                        y1 = p[off++];
	                        cpx = p[off++];
	                        cpy = p[off++];
	                        path.addData(cmd, ctlPtx, ctlPty, x1, y1, cpx, cpy);
	                        break;
	                    case 's':
	                        ctlPtx = cpx;
	                        ctlPty = cpy;
	                        var len = path.len();
	                        var pathData = path.data;
	                        if (prevCmd === CMD.C) {
	                            ctlPtx += cpx - pathData[len - 4];
	                            ctlPty += cpy - pathData[len - 3];
	                        }
	                        cmd = CMD.C;
	                        x1 = cpx + p[off++];
	                        y1 = cpy + p[off++];
	                        cpx += p[off++];
	                        cpy += p[off++];
	                        path.addData(cmd, ctlPtx, ctlPty, x1, y1, cpx, cpy);
	                        break;
	                    case 'Q':
	                        x1 = p[off++];
	                        y1 = p[off++];
	                        cpx = p[off++];
	                        cpy = p[off++];
	                        cmd = CMD.Q;
	                        path.addData(cmd, x1, y1, cpx, cpy);
	                        break;
	                    case 'q':
	                        x1 = p[off++] + cpx;
	                        y1 = p[off++] + cpy;
	                        cpx += p[off++];
	                        cpy += p[off++];
	                        cmd = CMD.Q;
	                        path.addData(cmd, x1, y1, cpx, cpy);
	                        break;
	                    case 'T':
	                        ctlPtx = cpx;
	                        ctlPty = cpy;
	                        var len = path.len();
	                        var pathData = path.data;
	                        if (prevCmd === CMD.Q) {
	                            ctlPtx += cpx - pathData[len - 4];
	                            ctlPty += cpy - pathData[len - 3];
	                        }
	                        cpx = p[off++];
	                        cpy = p[off++];
	                        cmd = CMD.Q;
	                        path.addData(cmd, ctlPtx, ctlPty, cpx, cpy);
	                        break;
	                    case 't':
	                        ctlPtx = cpx;
	                        ctlPty = cpy;
	                        var len = path.len();
	                        var pathData = path.data;
	                        if (prevCmd === CMD.Q) {
	                            ctlPtx += cpx - pathData[len - 4];
	                            ctlPty += cpy - pathData[len - 3];
	                        }
	                        cpx += p[off++];
	                        cpy += p[off++];
	                        cmd = CMD.Q;
	                        path.addData(cmd, ctlPtx, ctlPty, cpx, cpy);
	                        break;
	                    case 'A':
	                        rx = p[off++];
	                        ry = p[off++];
	                        psi = p[off++];
	                        fa = p[off++];
	                        fs = p[off++];

	                        x1 = cpx, y1 = cpy;
	                        cpx = p[off++];
	                        cpy = p[off++];
	                        cmd = CMD.A;
	                        processArc(
	                            x1, y1, cpx, cpy, fa, fs, rx, ry, psi, cmd, path
	                        );
	                        break;
	                    case 'a':
	                        rx = p[off++];
	                        ry = p[off++];
	                        psi = p[off++];
	                        fa = p[off++];
	                        fs = p[off++];

	                        x1 = cpx, y1 = cpy;
	                        cpx += p[off++];
	                        cpy += p[off++];
	                        cmd = CMD.A;
	                        processArc(
	                            x1, y1, cpx, cpy, fa, fs, rx, ry, psi, cmd, path
	                        );
	                        break;
	                }
	            }

	            if (c === 'z' || c === 'Z') {
	                cmd = CMD.Z;
	                path.addData(cmd);
	            }

	            prevCmd = cmd;
	        }

	        path.toStatic();

	        return path;
	    }

	    // TODO Optimize double memory cost problem
	    function createPathOptions(str, opts) {
	        var pathProxy = createPathProxyFromString(str);
	        opts = opts || {};
	        opts.buildPath = function (path) {
	            if (path.setData) {
	                path.setData(pathProxy.data);
	                // Svg and vml renderer don't have context
	                var ctx = path.getContext();
	                if (ctx) {
	                    path.rebuildPath(ctx);
	                }
	            }
	            else {
	                var ctx = path;
	                pathProxy.rebuildPath(ctx);
	            }
	        };

	        opts.applyTransform = function (m) {
	            transformPath(pathProxy, m);

	            this.dirty(true);
	        };

	        return opts;
	    }

	    module.exports = {
	        /**
	         * Create a Path object from path string data
	         * http://www.w3.org/TR/SVG/paths.html#PathData
	         * @param  {Object} opts Other options
	         */
	        createFromString: function (str, opts) {
	            return new Path(createPathOptions(str, opts));
	        },

	        /**
	         * Create a Path class from path string data
	         * @param  {string} str
	         * @param  {Object} opts Other options
	         */
	        extendFromString: function (str, opts) {
	            return Path.extend(createPathOptions(str, opts));
	        },

	        /**
	         * Merge multiple paths
	         */
	        // TODO Apply transform
	        // TODO stroke dash
	        // TODO Optimize double memory cost problem
	        mergePath: function (pathEls, opts) {
	            var pathList = [];
	            var len = pathEls.length;
	            for (var i = 0; i < len; i++) {
	                var pathEl = pathEls[i];
	                if (!pathEl.path) {
	                    pathEl.createPathProxy();
	                }
	                if (pathEl.__dirtyPath) {
	                    pathEl.buildPath(pathEl.path, pathEl.shape, true);
	                }
	                pathList.push(pathEl.path);
	            }

	            var pathBundle = new Path(opts);
	            // Need path proxy.
	            pathBundle.createPathProxy();
	            pathBundle.buildPath = function (path) {
	                path.appendPath(pathList);
	                // Svg and vml renderer don't have context
	                var ctx = path.getContext();
	                if (ctx) {
	                    path.rebuildPath(ctx);
	                }
	            };

	            return pathBundle;
	        }
	    };


/***/ },
/* 20 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * Path element
	 * @module zrender/graphic/Path
	 */



	    var Displayable = __webpack_require__(21);
	    var zrUtil = __webpack_require__(4);
	    var PathProxy = __webpack_require__(36);
	    var pathContain = __webpack_require__(39);

	    var Pattern = __webpack_require__(46);
	    var getCanvasPattern = Pattern.prototype.getCanvasPattern;

	    var abs = Math.abs;

	    var pathProxyForDraw = new PathProxy(true);
	    /**
	     * @alias module:zrender/graphic/Path
	     * @extends module:zrender/graphic/Displayable
	     * @constructor
	     * @param {Object} opts
	     */
	    function Path(opts) {
	        Displayable.call(this, opts);

	        /**
	         * @type {module:zrender/core/PathProxy}
	         * @readOnly
	         */
	        this.path = null;
	    }

	    Path.prototype = {

	        constructor: Path,

	        type: 'path',

	        __dirtyPath: true,

	        strokeContainThreshold: 5,

	        brush: function (ctx, prevEl) {
	            var style = this.style;
	            var path = this.path || pathProxyForDraw;
	            var hasStroke = style.hasStroke();
	            var hasFill = style.hasFill();
	            var fill = style.fill;
	            var stroke = style.stroke;
	            var hasFillGradient = hasFill && !!(fill.colorStops);
	            var hasStrokeGradient = hasStroke && !!(stroke.colorStops);
	            var hasFillPattern = hasFill && !!(fill.image);
	            var hasStrokePattern = hasStroke && !!(stroke.image);

	            style.bind(ctx, this, prevEl);
	            this.setTransform(ctx);

	            if (this.__dirty) {
	                var rect;
	                // Update gradient because bounding rect may changed
	                if (hasFillGradient) {
	                    rect = rect || this.getBoundingRect();
	                    this._fillGradient = style.getGradient(ctx, fill, rect);
	                }
	                if (hasStrokeGradient) {
	                    rect = rect || this.getBoundingRect();
	                    this._strokeGradient = style.getGradient(ctx, stroke, rect);
	                }
	            }
	            // Use the gradient or pattern
	            if (hasFillGradient) {
	                // PENDING If may have affect the state
	                ctx.fillStyle = this._fillGradient;
	            }
	            else if (hasFillPattern) {
	                ctx.fillStyle = getCanvasPattern.call(fill, ctx);
	            }
	            if (hasStrokeGradient) {
	                ctx.strokeStyle = this._strokeGradient;
	            }
	            else if (hasStrokePattern) {
	                ctx.strokeStyle = getCanvasPattern.call(stroke, ctx);
	            }

	            var lineDash = style.lineDash;
	            var lineDashOffset = style.lineDashOffset;

	            var ctxLineDash = !!ctx.setLineDash;

	            // Update path sx, sy
	            var scale = this.getGlobalScale();
	            path.setScale(scale[0], scale[1]);

	            // Proxy context
	            // Rebuild path in following 2 cases
	            // 1. Path is dirty
	            // 2. Path needs javascript implemented lineDash stroking.
	            //    In this case, lineDash information will not be saved in PathProxy
	            if (this.__dirtyPath
	                || (lineDash && !ctxLineDash && hasStroke)
	            ) {
	                path.beginPath(ctx);

	                // Setting line dash before build path
	                if (lineDash && !ctxLineDash) {
	                    path.setLineDash(lineDash);
	                    path.setLineDashOffset(lineDashOffset);
	                }

	                this.buildPath(path, this.shape, false);

	                // Clear path dirty flag
	                if (this.path) {
	                    this.__dirtyPath = false;
	                }
	            }
	            else {
	                // Replay path building
	                ctx.beginPath();
	                this.path.rebuildPath(ctx);
	            }

	            hasFill && path.fill(ctx);

	            if (lineDash && ctxLineDash) {
	                ctx.setLineDash(lineDash);
	                ctx.lineDashOffset = lineDashOffset;
	            }

	            hasStroke && path.stroke(ctx);

	            if (lineDash && ctxLineDash) {
	                // PENDING
	                // Remove lineDash
	                ctx.setLineDash([]);
	            }


	            this.restoreTransform(ctx);

	            // Draw rect text
	            if (style.text != null) {
	                this.drawRectText(ctx, this.getBoundingRect());
	            }
	        },

	        // When bundling path, some shape may decide if use moveTo to begin a new subpath or closePath
	        // Like in circle
	        buildPath: function (ctx, shapeCfg, inBundle) {},

	        createPathProxy: function () {
	            this.path = new PathProxy();
	        },

	        getBoundingRect: function () {
	            var rect = this._rect;
	            var style = this.style;
	            var needsUpdateRect = !rect;
	            if (needsUpdateRect) {
	                var path = this.path;
	                if (!path) {
	                    // Create path on demand.
	                    path = this.path = new PathProxy();
	                }
	                if (this.__dirtyPath) {
	                    path.beginPath();
	                    this.buildPath(path, this.shape, false);
	                }
	                rect = path.getBoundingRect();
	            }
	            this._rect = rect;

	            if (style.hasStroke()) {
	                // Needs update rect with stroke lineWidth when
	                // 1. Element changes scale or lineWidth
	                // 2. Shape is changed
	                var rectWithStroke = this._rectWithStroke || (this._rectWithStroke = rect.clone());
	                if (this.__dirty || needsUpdateRect) {
	                    rectWithStroke.copy(rect);
	                    // FIXME Must after updateTransform
	                    var w = style.lineWidth;
	                    // PENDING, Min line width is needed when line is horizontal or vertical
	                    var lineScale = style.strokeNoScale ? this.getLineScale() : 1;

	                    // Only add extra hover lineWidth when there are no fill
	                    if (!style.hasFill()) {
	                        w = Math.max(w, this.strokeContainThreshold || 4);
	                    }
	                    // Consider line width
	                    // Line scale can't be 0;
	                    if (lineScale > 1e-10) {
	                        rectWithStroke.width += w / lineScale;
	                        rectWithStroke.height += w / lineScale;
	                        rectWithStroke.x -= w / lineScale / 2;
	                        rectWithStroke.y -= w / lineScale / 2;
	                    }
	                }

	                // Return rect with stroke
	                return rectWithStroke;
	            }

	            return rect;
	        },

	        contain: function (x, y) {
	            var localPos = this.transformCoordToLocal(x, y);
	            var rect = this.getBoundingRect();
	            var style = this.style;
	            x = localPos[0];
	            y = localPos[1];

	            if (rect.contain(x, y)) {
	                var pathData = this.path.data;
	                if (style.hasStroke()) {
	                    var lineWidth = style.lineWidth;
	                    var lineScale = style.strokeNoScale ? this.getLineScale() : 1;
	                    // Line scale can't be 0;
	                    if (lineScale > 1e-10) {
	                        // Only add extra hover lineWidth when there are no fill
	                        if (!style.hasFill()) {
	                            lineWidth = Math.max(lineWidth, this.strokeContainThreshold);
	                        }
	                        if (pathContain.containStroke(
	                            pathData, lineWidth / lineScale, x, y
	                        )) {
	                            return true;
	                        }
	                    }
	                }
	                if (style.hasFill()) {
	                    return pathContain.contain(pathData, x, y);
	                }
	            }
	            return false;
	        },

	        /**
	         * @param  {boolean} dirtyPath
	         */
	        dirty: function (dirtyPath) {
	            if (dirtyPath == null) {
	                dirtyPath = true;
	            }
	            // Only mark dirty, not mark clean
	            if (dirtyPath) {
	                this.__dirtyPath = dirtyPath;
	                this._rect = null;
	            }

	            this.__dirty = true;

	            this.__zr && this.__zr.refresh();

	            // Used as a clipping path
	            if (this.__clipTarget) {
	                this.__clipTarget.dirty();
	            }
	        },

	        /**
	         * Alias for animate('shape')
	         * @param {boolean} loop
	         */
	        animateShape: function (loop) {
	            return this.animate('shape', loop);
	        },

	        // Overwrite attrKV
	        attrKV: function (key, value) {
	            // FIXME
	            if (key === 'shape') {
	                this.setShape(value);
	                this.__dirtyPath = true;
	                this._rect = null;
	            }
	            else {
	                Displayable.prototype.attrKV.call(this, key, value);
	            }
	        },

	        /**
	         * @param {Object|string} key
	         * @param {*} value
	         */
	        setShape: function (key, value) {
	            var shape = this.shape;
	            // Path from string may not have shape
	            if (shape) {
	                if (zrUtil.isObject(key)) {
	                    for (var name in key) {
	                        if (key.hasOwnProperty(name)) {
	                            shape[name] = key[name];
	                        }
	                    }
	                }
	                else {
	                    shape[key] = value;
	                }
	                this.dirty(true);
	            }
	            return this;
	        },

	        getLineScale: function () {
	            var m = this.transform;
	            // Get the line scale.
	            // Determinant of `m` means how much the area is enlarged by the
	            // transformation. So its square root can be used as a scale factor
	            // for width.
	            return m && abs(m[0] - 1) > 1e-10 && abs(m[3] - 1) > 1e-10
	                ? Math.sqrt(abs(m[0] * m[3] - m[2] * m[1]))
	                : 1;
	        }
	    };

	    /**
	     * 扩展一个 Path element, 比如星形，圆等。
	     * Extend a path element
	     * @param {Object} props
	     * @param {string} props.type Path type
	     * @param {Function} props.init Initialize
	     * @param {Function} props.buildPath Overwrite buildPath method
	     * @param {Object} [props.style] Extended default style config
	     * @param {Object} [props.shape] Extended default shape config
	     */
	    Path.extend = function (defaults) {
	        var Sub = function (opts) {
	            Path.call(this, opts);

	            if (defaults.style) {
	                // Extend default style
	                this.style.extendFrom(defaults.style, false);
	            }

	            // Extend default shape
	            var defaultShape = defaults.shape;
	            if (defaultShape) {
	                this.shape = this.shape || {};
	                var thisShape = this.shape;
	                for (var name in defaultShape) {
	                    if (
	                        ! thisShape.hasOwnProperty(name)
	                        && defaultShape.hasOwnProperty(name)
	                    ) {
	                        thisShape[name] = defaultShape[name];
	                    }
	                }
	            }

	            defaults.init && defaults.init.call(this, opts);
	        };

	        zrUtil.inherits(Sub, Path);

	        // FIXME 不能 extend position, rotation 等引用对象
	        for (var name in defaults) {
	            // Extending prototype values and methods
	            if (name !== 'style' && name !== 'shape') {
	                Sub.prototype[name] = defaults[name];
	            }
	        }

	        return Sub;
	    };

	    zrUtil.inherits(Path, Displayable);

	    module.exports = Path;


/***/ },
/* 21 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * 可绘制的图形基类
	 * Base class of all displayable graphic objects
	 * @module zrender/graphic/Displayable
	 */



	    var zrUtil = __webpack_require__(4);

	    var Style = __webpack_require__(22);

	    var Element = __webpack_require__(23);
	    var RectText = __webpack_require__(35);
	    // var Stateful = require('./mixin/Stateful');

	    /**
	     * @alias module:zrender/graphic/Displayable
	     * @extends module:zrender/Element
	     * @extends module:zrender/graphic/mixin/RectText
	     */
	    function Displayable(opts) {

	        opts = opts || {};

	        Element.call(this, opts);

	        // Extend properties
	        for (var name in opts) {
	            if (
	                opts.hasOwnProperty(name) &&
	                name !== 'style'
	            ) {
	                this[name] = opts[name];
	            }
	        }

	        /**
	         * @type {module:zrender/graphic/Style}
	         */
	        this.style = new Style(opts.style);

	        this._rect = null;
	        // Shapes for cascade clipping.
	        this.__clipPaths = [];

	        // FIXME Stateful must be mixined after style is setted
	        // Stateful.call(this, opts);
	    }

	    Displayable.prototype = {

	        constructor: Displayable,

	        type: 'displayable',

	        /**
	         * Displayable 是否为脏，Painter 中会根据该标记判断是否需要是否需要重新绘制
	         * Dirty flag. From which painter will determine if this displayable object needs brush
	         * @name module:zrender/graphic/Displayable#__dirty
	         * @type {boolean}
	         */
	        __dirty: true,

	        /**
	         * 图形是否可见，为true时不绘制图形，但是仍能触发鼠标事件
	         * If ignore drawing of the displayable object. Mouse event will still be triggered
	         * @name module:/zrender/graphic/Displayable#invisible
	         * @type {boolean}
	         * @default false
	         */
	        invisible: false,

	        /**
	         * @name module:/zrender/graphic/Displayable#z
	         * @type {number}
	         * @default 0
	         */
	        z: 0,

	        /**
	         * @name module:/zrender/graphic/Displayable#z
	         * @type {number}
	         * @default 0
	         */
	        z2: 0,

	        /**
	         * z层level，决定绘画在哪层canvas中
	         * @name module:/zrender/graphic/Displayable#zlevel
	         * @type {number}
	         * @default 0
	         */
	        zlevel: 0,

	        /**
	         * 是否可拖拽
	         * @name module:/zrender/graphic/Displayable#draggable
	         * @type {boolean}
	         * @default false
	         */
	        draggable: false,

	        /**
	         * 是否正在拖拽
	         * @name module:/zrender/graphic/Displayable#draggable
	         * @type {boolean}
	         * @default false
	         */
	        dragging: false,

	        /**
	         * 是否相应鼠标事件
	         * @name module:/zrender/graphic/Displayable#silent
	         * @type {boolean}
	         * @default false
	         */
	        silent: false,

	        /**
	         * If enable culling
	         * @type {boolean}
	         * @default false
	         */
	        culling: false,

	        /**
	         * Mouse cursor when hovered
	         * @name module:/zrender/graphic/Displayable#cursor
	         * @type {string}
	         */
	        cursor: 'pointer',

	        /**
	         * If hover area is bounding rect
	         * @name module:/zrender/graphic/Displayable#rectHover
	         * @type {string}
	         */
	        rectHover: false,

	        /**
	         * Render the element progressively when the value >= 0,
	         * usefull for large data.
	         * @type {number}
	         */
	        progressive: -1,

	        beforeBrush: function (ctx) {},

	        afterBrush: function (ctx) {},

	        /**
	         * 图形绘制方法
	         * @param {Canvas2DRenderingContext} ctx
	         */
	        // Interface
	        brush: function (ctx, prevEl) {},

	        /**
	         * 获取最小包围盒
	         * @return {module:zrender/core/BoundingRect}
	         */
	        // Interface
	        getBoundingRect: function () {},

	        /**
	         * 判断坐标 x, y 是否在图形上
	         * If displayable element contain coord x, y
	         * @param  {number} x
	         * @param  {number} y
	         * @return {boolean}
	         */
	        contain: function (x, y) {
	            return this.rectContain(x, y);
	        },

	        /**
	         * @param  {Function} cb
	         * @param  {}   context
	         */
	        traverse: function (cb, context) {
	            cb.call(context, this);
	        },

	        /**
	         * 判断坐标 x, y 是否在图形的包围盒上
	         * If bounding rect of element contain coord x, y
	         * @param  {number} x
	         * @param  {number} y
	         * @return {boolean}
	         */
	        rectContain: function (x, y) {
	            var coord = this.transformCoordToLocal(x, y);
	            var rect = this.getBoundingRect();
	            return rect.contain(coord[0], coord[1]);
	        },

	        /**
	         * 标记图形元素为脏，并且在下一帧重绘
	         * Mark displayable element dirty and refresh next frame
	         */
	        dirty: function () {
	            this.__dirty = true;

	            this._rect = null;

	            this.__zr && this.__zr.refresh();
	        },

	        /**
	         * 图形是否会触发事件
	         * If displayable object binded any event
	         * @return {boolean}
	         */
	        // TODO, 通过 bind 绑定的事件
	        // isSilent: function () {
	        //     return !(
	        //         this.hoverable || this.draggable
	        //         || this.onmousemove || this.onmouseover || this.onmouseout
	        //         || this.onmousedown || this.onmouseup || this.onclick
	        //         || this.ondragenter || this.ondragover || this.ondragleave
	        //         || this.ondrop
	        //     );
	        // },
	        /**
	         * Alias for animate('style')
	         * @param {boolean} loop
	         */
	        animateStyle: function (loop) {
	            return this.animate('style', loop);
	        },

	        attrKV: function (key, value) {
	            if (key !== 'style') {
	                Element.prototype.attrKV.call(this, key, value);
	            }
	            else {
	                this.style.set(value);
	            }
	        },

	        /**
	         * @param {Object|string} key
	         * @param {*} value
	         */
	        setStyle: function (key, value) {
	            this.style.set(key, value);
	            this.dirty(false);
	            return this;
	        },

	        /**
	         * Use given style object
	         * @param  {Object} obj
	         */
	        useStyle: function (obj) {
	            this.style = new Style(obj);
	            this.dirty(false);
	            return this;
	        }
	    };

	    zrUtil.inherits(Displayable, Element);

	    zrUtil.mixin(Displayable, RectText);
	    // zrUtil.mixin(Displayable, Stateful);

	    module.exports = Displayable;


/***/ },
/* 22 */
/***/ function(module, exports) {

	/**
	 * @module zrender/graphic/Style
	 */


	    var STYLE_COMMON_PROPS = [
	        ['shadowBlur', 0], ['shadowOffsetX', 0], ['shadowOffsetY', 0], ['shadowColor', '#000'],
	        ['lineCap', 'butt'], ['lineJoin', 'miter'], ['miterLimit', 10]
	    ];

	    // var SHADOW_PROPS = STYLE_COMMON_PROPS.slice(0, 4);
	    // var LINE_PROPS = STYLE_COMMON_PROPS.slice(4);

	    var Style = function (opts) {
	        this.extendFrom(opts);
	    };

	    function createLinearGradient(ctx, obj, rect) {
	        var x = obj.x == null ? 0 : obj.x;
	        var x2 = obj.x2 == null ? 1 : obj.x2;
	        var y = obj.y == null ? 0 : obj.y;
	        var y2 = obj.y2 == null ? 0 : obj.y2;

	        if (!obj.global) {
	            x = x * rect.width + rect.x;
	            x2 = x2 * rect.width + rect.x;
	            y = y * rect.height + rect.y;
	            y2 = y2 * rect.height + rect.y;
	        }

	        var canvasGradient = ctx.createLinearGradient(x, y, x2, y2);

	        return canvasGradient;
	    }

	    function createRadialGradient(ctx, obj, rect) {
	        var width = rect.width;
	        var height = rect.height;
	        var min = Math.min(width, height);

	        var x = obj.x == null ? 0.5 : obj.x;
	        var y = obj.y == null ? 0.5 : obj.y;
	        var r = obj.r == null ? 0.5 : obj.r;
	        if (!obj.global) {
	            x = x * width + rect.x;
	            y = y * height + rect.y;
	            r = r * min;
	        }

	        var canvasGradient = ctx.createRadialGradient(x, y, 0, x, y, r);

	        return canvasGradient;
	    }


	    Style.prototype = {

	        constructor: Style,

	        /**
	         * @type {string}
	         */
	        fill: '#000000',

	        /**
	         * @type {string}
	         */
	        stroke: null,

	        /**
	         * @type {number}
	         */
	        opacity: 1,

	        /**
	         * @type {Array.<number>}
	         */
	        lineDash: null,

	        /**
	         * @type {number}
	         */
	        lineDashOffset: 0,

	        /**
	         * @type {number}
	         */
	        shadowBlur: 0,

	        /**
	         * @type {number}
	         */
	        shadowOffsetX: 0,

	        /**
	         * @type {number}
	         */
	        shadowOffsetY: 0,

	        /**
	         * @type {number}
	         */
	        lineWidth: 1,

	        /**
	         * If stroke ignore scale
	         * @type {Boolean}
	         */
	        strokeNoScale: false,

	        // Bounding rect text configuration
	        // Not affected by element transform
	        /**
	         * @type {string}
	         */
	        text: null,

	        /**
	         * @type {string}
	         */
	        textFill: '#000',

	        /**
	         * @type {string}
	         */
	        textStroke: null,

	        /**
	         * 'inside', 'left', 'right', 'top', 'bottom'
	         * [x, y]
	         * @type {string|Array.<number>}
	         * @default 'inside'
	         */
	        textPosition: 'inside',

	        /**
	         * If not specified, use the boundingRect of a `displayable`.
	         * @type {Object}
	         */
	        textPositionRect: null,

	        /**
	         * [x, y]
	         * @type {Array.<number>}
	         */
	        textOffset: null,

	        /**
	         * @type {string}
	         */
	        textBaseline: null,

	        /**
	         * @type {string}
	         */
	        textAlign: null,

	        /**
	         * @type {string}
	         */
	        textVerticalAlign: null,

	        /**
	         * Only useful in Path and Image element
	         * @type {number}
	         */
	        textDistance: 5,

	        /**
	         * Only useful in Path and Image element
	         * @type {number}
	         */
	        textShadowBlur: 0,

	        /**
	         * Only useful in Path and Image element
	         * @type {number}
	         */
	        textShadowOffsetX: 0,

	        /**
	         * Only useful in Path and Image element
	         * @type {number}
	         */
	        textShadowOffsetY: 0,

	        /**
	         * If transform text
	         * Only useful in Path and Image element
	         * @type {boolean}
	         */
	        textTransform: false,

	        /**
	         * Text rotate around position of Path or Image
	         * Only useful in Path and Image element and textTransform is false.
	         */
	        textRotation: 0,

	        /**
	         * @type {string}
	         * https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation
	         */
	        blend: null,

	        /**
	         * @param {CanvasRenderingContext2D} ctx
	         */
	        bind: function (ctx, el, prevEl) {
	            var style = this;
	            var prevStyle = prevEl && prevEl.style;
	            var firstDraw = !prevStyle;

	            for (var i = 0; i < STYLE_COMMON_PROPS.length; i++) {
	                var prop = STYLE_COMMON_PROPS[i];
	                var styleName = prop[0];

	                if (firstDraw || style[styleName] !== prevStyle[styleName]) {
	                    // FIXME Invalid property value will cause style leak from previous element.
	                    ctx[styleName] = style[styleName] || prop[1];
	                }
	            }

	            if ((firstDraw || style.fill !== prevStyle.fill)) {
	                ctx.fillStyle = style.fill;
	            }
	            if ((firstDraw || style.stroke !== prevStyle.stroke)) {
	                ctx.strokeStyle = style.stroke;
	            }
	            if ((firstDraw || style.opacity !== prevStyle.opacity)) {
	                ctx.globalAlpha = style.opacity == null ? 1 : style.opacity;
	            }

	            if ((firstDraw || style.blend !== prevStyle.blend)) {
	                ctx.globalCompositeOperation = style.blend || 'source-over';
	            }
	            if (this.hasStroke()) {
	                var lineWidth = style.lineWidth;
	                ctx.lineWidth = lineWidth / (
	                    (this.strokeNoScale && el && el.getLineScale) ? el.getLineScale() : 1
	                );
	            }
	        },

	        hasFill: function () {
	            var fill = this.fill;
	            return fill != null && fill !== 'none';
	        },

	        hasStroke: function () {
	            var stroke = this.stroke;
	            return stroke != null && stroke !== 'none' && this.lineWidth > 0;
	        },

	        /**
	         * Extend from other style
	         * @param {zrender/graphic/Style} otherStyle
	         * @param {boolean} overwrite
	         */
	        extendFrom: function (otherStyle, overwrite) {
	            if (otherStyle) {
	                var target = this;
	                for (var name in otherStyle) {
	                    if (otherStyle.hasOwnProperty(name)
	                        && (overwrite || ! target.hasOwnProperty(name))
	                    ) {
	                        target[name] = otherStyle[name];
	                    }
	                }
	            }
	        },

	        /**
	         * Batch setting style with a given object
	         * @param {Object|string} obj
	         * @param {*} [obj]
	         */
	        set: function (obj, value) {
	            if (typeof obj === 'string') {
	                this[obj] = value;
	            }
	            else {
	                this.extendFrom(obj, true);
	            }
	        },

	        /**
	         * Clone
	         * @return {zrender/graphic/Style} [description]
	         */
	        clone: function () {
	            var newStyle = new this.constructor();
	            newStyle.extendFrom(this, true);
	            return newStyle;
	        },

	        getGradient: function (ctx, obj, rect) {
	            var method = obj.type === 'radial' ? createRadialGradient : createLinearGradient;
	            var canvasGradient = method(ctx, obj, rect);
	            var colorStops = obj.colorStops;
	            for (var i = 0; i < colorStops.length; i++) {
	                canvasGradient.addColorStop(
	                    colorStops[i].offset, colorStops[i].color
	                );
	            }
	            return canvasGradient;
	        }
	    };

	    var styleProto = Style.prototype;
	    for (var i = 0; i < STYLE_COMMON_PROPS.length; i++) {
	        var prop = STYLE_COMMON_PROPS[i];
	        if (!(prop[0] in styleProto)) {
	            styleProto[prop[0]] = prop[1];
	        }
	    }

	    // Provide for others
	    Style.getGradient = styleProto.getGradient;

	    module.exports = Style;


/***/ },
/* 23 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	/**
	 * @module zrender/Element
	 */


	    var guid = __webpack_require__(24);
	    var Eventful = __webpack_require__(25);
	    var Transformable = __webpack_require__(26);
	    var Animatable = __webpack_require__(27);
	    var zrUtil = __webpack_require__(4);

	    /**
	     * @alias module:zrender/Element
	     * @constructor
	     * @extends {module:zrender/mixin/Animatable}
	     * @extends {module:zrender/mixin/Transformable}
	     * @extends {module:zrender/mixin/Eventful}
	     */
	    var Element = function (opts) {

	        Transformable.call(this, opts);
	        Eventful.call(this, opts);
	        Animatable.call(this, opts);

	        /**
	         * 画布元素ID
	         * @type {string}
	         */
	        this.id = opts.id || guid();
	    };

	    Element.prototype = {

	        /**
	         * 元素类型
	         * Element type
	         * @type {string}
	         */
	        type: 'element',

	        /**
	         * 元素名字
	         * Element name
	         * @type {string}
	         */
	        name: '',

	        /**
	         * ZRender 实例对象，会在 element 添加到 zrender 实例中后自动赋值
	         * ZRender instance will be assigned when element is associated with zrender
	         * @name module:/zrender/Element#__zr
	         * @type {module:zrender/ZRender}
	         */
	        __zr: null,

	        /**
	         * 图形是否忽略，为true时忽略图形的绘制以及事件触发
	         * If ignore drawing and events of the element object
	         * @name module:/zrender/Element#ignore
	         * @type {boolean}
	         * @default false
	         */
	        ignore: false,

	        /**
	         * 用于裁剪的路径(shape)，所有 Group 内的路径在绘制时都会被这个路径裁剪
	         * 该路径会继承被裁减对象的变换
	         * @type {module:zrender/graphic/Path}
	         * @see http://www.w3.org/TR/2dcontext/#clipping-region
	         * @readOnly
	         */
	        clipPath: null,

	        /**
	         * Drift element
	         * @param  {number} dx dx on the global space
	         * @param  {number} dy dy on the global space
	         */
	        drift: function (dx, dy) {
	            switch (this.draggable) {
	                case 'horizontal':
	                    dy = 0;
	                    break;
	                case 'vertical':
	                    dx = 0;
	                    break;
	            }

	            var m = this.transform;
	            if (!m) {
	                m = this.transform = [1, 0, 0, 1, 0, 0];
	            }
	            m[4] += dx;
	            m[5] += dy;

	            this.decomposeTransform();
	            this.dirty(false);
	        },

	        /**
	         * Hook before update
	         */
	        beforeUpdate: function () {},
	        /**
	         * Hook after update
	         */
	        afterUpdate: function () {},
	        /**
	         * Update each frame
	         */
	        update: function () {
	            this.updateTransform();
	        },

	        /**
	         * @param  {Function} cb
	         * @param  {}   context
	         */
	        traverse: function (cb, context) {},

	        /**
	         * @protected
	         */
	        attrKV: function (key, value) {
	            if (key === 'position' || key === 'scale' || key === 'origin') {
	                // Copy the array
	                if (value) {
	                    var target = this[key];
	                    if (!target) {
	                        target = this[key] = [];
	                    }
	                    target[0] = value[0];
	                    target[1] = value[1];
	                }
	            }
	            else {
	                this[key] = value;
	            }
	        },

	        /**
	         * Hide the element
	         */
	        hide: function () {
	            this.ignore = true;
	            this.__zr && this.__zr.refresh();
	        },

	        /**
	         * Show the element
	         */
	        show: function () {
	            this.ignore = false;
	            this.__zr && this.__zr.refresh();
	        },

	        /**
	         * @param {string|Object} key
	         * @param {*} value
	         */
	        attr: function (key, value) {
	            if (typeof key === 'string') {
	                this.attrKV(key, value);
	            }
	            else if (zrUtil.isObject(key)) {
	                for (var name in key) {
	                    if (key.hasOwnProperty(name)) {
	                        this.attrKV(name, key[name]);
	                    }
	                }
	            }

	            this.dirty(false);

	            return this;
	        },

	        /**
	         * @param {module:zrender/graphic/Path} clipPath
	         */
	        setClipPath: function (clipPath) {
	            var zr = this.__zr;
	            if (zr) {
	                clipPath.addSelfToZr(zr);
	            }

	            // Remove previous clip path
	            if (this.clipPath && this.clipPath !== clipPath) {
	                this.removeClipPath();
	            }

	            this.clipPath = clipPath;
	            clipPath.__zr = zr;
	            clipPath.__clipTarget = this;

	            this.dirty(false);
	        },

	        /**
	         */
	        removeClipPath: function () {
	            var clipPath = this.clipPath;
	            if (clipPath) {
	                if (clipPath.__zr) {
	                    clipPath.removeSelfFromZr(clipPath.__zr);
	                }

	                clipPath.__zr = null;
	                clipPath.__clipTarget = null;
	                this.clipPath = null;

	                this.dirty(false);
	            }
	        },

	        /**
	         * Add self from zrender instance.
	         * Not recursively because it will be invoked when element added to storage.
	         * @param {module:zrender/ZRender} zr
	         */
	        addSelfToZr: function (zr) {
	            this.__zr = zr;
	            // 添加动画
	            var animators = this.animators;
	            if (animators) {
	                for (var i = 0; i < animators.length; i++) {
	                    zr.animation.addAnimator(animators[i]);
	                }
	            }

	            if (this.clipPath) {
	                this.clipPath.addSelfToZr(zr);
	            }
	        },

	        /**
	         * Remove self from zrender instance.
	         * Not recursively because it will be invoked when element added to storage.
	         * @param {module:zrender/ZRender} zr
	         */
	        removeSelfFromZr: function (zr) {
	            this.__zr = null;
	            // 移除动画
	            var animators = this.animators;
	            if (animators) {
	                for (var i = 0; i < animators.length; i++) {
	                    zr.animation.removeAnimator(animators[i]);
	                }
	            }

	            if (this.clipPath) {
	                this.clipPath.removeSelfFromZr(zr);
	            }
	        }
	    };

	    zrUtil.mixin(Element, Animatable);
	    zrUtil.mixin(Element, Transformable);
	    zrUtil.mixin(Element, Eventful);

	    module.exports = Element;


/***/ },
/* 24 */
/***/ function(module, exports) {

	/**
	 * zrender: 生成唯一id
	 *
	 * @author errorrik (errorrik@gmail.com)
	 */


	    var idStart = 0x0907;

	    module.exports = function () {
	        return idStart++;
	    };



/***/ },
/* 25 */
/***/ function(module, exports) {

	/**
	 * 事件扩展
	 * @module zrender/mixin/Eventful
	 * @author Kener (@Kener-林峰, kener.linfeng@gmail.com)
	 *         pissang (https://www.github.com/pissang)
	 */


	    var arrySlice = Array.prototype.slice;

	    /**
	     * 事件分发器
	     * @alias module:zrender/mixin/Eventful
	     * @constructor
	     */
	    var Eventful = function () {
	        this._$handlers = {};
	    };

	    Eventful.prototype = {

	        constructor: Eventful,

	        /**
	         * 单次触发绑定，trigger后销毁
	         *
	         * @param {string} event 事件名
	         * @param {Function} handler 响应函数
	         * @param {Object} context
	         */
	        one: function (event, handler, context) {
	            var _h = this._$handlers;

	            if (!handler || !event) {
	                return this;
	            }

	            if (!_h[event]) {
	                _h[event] = [];
	            }

	            for (var i = 0; i < _h[event].length; i++) {
	                if (_h[event][i].h === handler) {
	                    return this;
	                }
	            }

	            _h[event].push({
	                h: handler,
	                one: true,
	                ctx: context || this
	            });

	            return this;
	        },

	        /**
	         * 绑定事件
	         * @param {string} event 事件名
	         * @param {Function} handler 事件处理函数
	         * @param {Object} [context]
	         */
	        on: function (event, handler, context) {
	            var _h = this._$handlers;

	            if (!handler || !event) {
	                return this;
	            }

	            if (!_h[event]) {
	                _h[event] = [];
	            }

	            for (var i = 0; i < _h[event].length; i++) {
	                if (_h[event][i].h === handler) {
	                    return this;
	                }
	            }

	            _h[event].push({
	                h: handler,
	                one: false,
	                ctx: context || this
	            });

	            return this;
	        },

	        /**
	         * 是否绑定了事件
	         * @param  {string}  event
	         * @return {boolean}
	         */
	        isSilent: function (event) {
	            var _h = this._$handlers;
	            return _h[event] && _h[event].length;
	        },

	        /**
	         * 解绑事件
	         * @param {string} event 事件名
	         * @param {Function} [handler] 事件处理函数
	         */
	        off: function (event, handler) {
	            var _h = this._$handlers;

	            if (!event) {
	                this._$handlers = {};
	                return this;
	            }

	            if (handler) {
	                if (_h[event]) {
	                    var newList = [];
	                    for (var i = 0, l = _h[event].length; i < l; i++) {
	                        if (_h[event][i]['h'] != handler) {
	                            newList.push(_h[event][i]);
	                        }
	                    }
	                    _h[event] = newList;
	                }

	                if (_h[event] && _h[event].length === 0) {
	                    delete _h[event];
	                }
	            }
	            else {
	                delete _h[event];
	            }

	            return this;
	        },

	        /**
	         * 事件分发
	         *
	         * @param {string} type 事件类型
	         */
	        trigger: function (type) {
	            if (this._$handlers[type]) {
	                var args = arguments;
	                var argLen = args.length;

	                if (argLen > 3) {
	                    args = arrySlice.call(args, 1);
	                }

	                var _h = this._$handlers[type];
	                var len = _h.length;
	                for (var i = 0; i < len;) {
	                    // Optimize advise from backbone
	                    switch (argLen) {
	                        case 1:
	                            _h[i]['h'].call(_h[i]['ctx']);
	                            break;
	                        case 2:
	                            _h[i]['h'].call(_h[i]['ctx'], args[1]);
	                            break;
	                        case 3:
	                            _h[i]['h'].call(_h[i]['ctx'], args[1], args[2]);
	                            break;
	                        default:
	                            // have more than 2 given arguments
	                            _h[i]['h'].apply(_h[i]['ctx'], args);
	                            break;
	                    }

	                    if (_h[i]['one']) {
	                        _h.splice(i, 1);
	                        len--;
	                    }
	                    else {
	                        i++;
	                    }
	                }
	            }

	            return this;
	        },

	        /**
	         * 带有context的事件分发, 最后一个参数是事件回调的context
	         * @param {string} type 事件类型
	         */
	        triggerWithContext: function (type) {
	            if (this._$handlers[type]) {
	                var args = arguments;
	                var argLen = args.length;

	                if (argLen > 4) {
	                    args = arrySlice.call(args, 1, args.length - 1);
	                }
	                var ctx = args[args.length - 1];

	                var _h = this._$handlers[type];
	                var len = _h.length;
	                for (var i = 0; i < len;) {
	                    // Optimize advise from backbone
	                    switch (argLen) {
	                        case 1:
	                            _h[i]['h'].call(ctx);
	                            break;
	                        case 2:
	                            _h[i]['h'].call(ctx, args[1]);
	                            break;
	                        case 3:
	                            _h[i]['h'].call(ctx, args[1], args[2]);
	                            break;
	                        default:
	                            // have more than 2 given arguments
	                            _h[i]['h'].apply(ctx, args);
	                            break;
	                    }

	                    if (_h[i]['one']) {
	                        _h.splice(i, 1);
	                        len--;
	                    }
	                    else {
	                        i++;
	                    }
	                }
	            }

	            return this;
	        }
	    };

	    // 对象可以通过 onxxxx 绑定事件
	    /**
	     * @event module:zrender/mixin/Eventful#onclick
	     * @type {Function}
	     * @default null
	     */
	    /**
	     * @event module:zrender/mixin/Eventful#onmouseover
	     * @type {Function}
	     * @default null
	     */
	    /**
	     * @event module:zrender/mixin/Eventful#onmouseout
	     * @type {Function}
	     * @default null
	     */
	    /**
	     * @event module:zrender/mixin/Eventful#onmousemove
	     * @type {Function}
	     * @default null
	     */
	    /**
	     * @event module:zrender/mixin/Eventful#onmousewheel
	     * @type {Function}
	     * @default null
	     */
	    /**
	     * @event module:zrender/mixin/Eventful#onmousedown
	     * @type {Function}
	     * @default null
	     */
	    /**
	     * @event module:zrender/mixin/Eventful#onmouseup
	     * @type {Function}
	     * @default null
	     */
	    /**
	     * @event module:zrender/mixin/Eventful#ondrag
	     * @type {Function}
	     * @default null
	     */
	    /**
	     * @event module:zrender/mixin/Eventful#ondragstart
	     * @type {Function}
	     * @default null
	     */
	    /**
	     * @event module:zrender/mixin/Eventful#ondragend
	     * @type {Function}
	     * @default null
	     */
	    /**
	     * @event module:zrender/mixin/Eventful#ondragenter
	     * @type {Function}
	     * @default null
	     */
	    /**
	     * @event module:zrender/mixin/Eventful#ondragleave
	     * @type {Function}
	     * @default null
	     */
	    /**
	     * @event module:zrender/mixin/Eventful#ondragover
	     * @type {Function}
	     * @default null
	     */
	    /**
	     * @event module:zrender/mixin/Eventful#ondrop
	     * @type {Function}
	     * @default null
	     */

	    module.exports = Eventful;



/***/ },
/* 26 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	/**
	 * 提供变换扩展
	 * @module zrender/mixin/Transformable
	 * @author pissang (https://www.github.com/pissang)
	 */


	    var matrix = __webpack_require__(11);
	    var vector = __webpack_require__(10);
	    var mIdentity = matrix.identity;

	    var EPSILON = 5e-5;

	    function isNotAroundZero(val) {
	        return val > EPSILON || val < -EPSILON;
	    }

	    /**
	     * @alias module:zrender/mixin/Transformable
	     * @constructor
	     */
	    var Transformable = function (opts) {
	        opts = opts || {};
	        // If there are no given position, rotation, scale
	        if (!opts.position) {
	            /**
	             * 平移
	             * @type {Array.<number>}
	             * @default [0, 0]
	             */
	            this.position = [0, 0];
	        }
	        if (opts.rotation == null) {
	            /**
	             * 旋转
	             * @type {Array.<number>}
	             * @default 0
	             */
	            this.rotation = 0;
	        }
	        if (!opts.scale) {
	            /**
	             * 缩放
	             * @type {Array.<number>}
	             * @default [1, 1]
	             */
	            this.scale = [1, 1];
	        }
	        /**
	         * 旋转和缩放的原点
	         * @type {Array.<number>}
	         * @default null
	         */
	        this.origin = this.origin || null;
	    };

	    var transformableProto = Transformable.prototype;
	    transformableProto.transform = null;

	    /**
	     * 判断是否需要有坐标变换
	     * 如果有坐标变换, 则从position, rotation, scale以及父节点的transform计算出自身的transform矩阵
	     */
	    transformableProto.needLocalTransform = function () {
	        return isNotAroundZero(this.rotation)
	            || isNotAroundZero(this.position[0])
	            || isNotAroundZero(this.position[1])
	            || isNotAroundZero(this.scale[0] - 1)
	            || isNotAroundZero(this.scale[1] - 1);
	    };

	    transformableProto.updateTransform = function () {
	        var parent = this.parent;
	        var parentHasTransform = parent && parent.transform;
	        var needLocalTransform = this.needLocalTransform();

	        var m = this.transform;
	        if (!(needLocalTransform || parentHasTransform)) {
	            m && mIdentity(m);
	            return;
	        }

	        m = m || matrix.create();

	        if (needLocalTransform) {
	            this.getLocalTransform(m);
	        }
	        else {
	            mIdentity(m);
	        }

	        // 应用父节点变换
	        if (parentHasTransform) {
	            if (needLocalTransform) {
	                matrix.mul(m, parent.transform, m);
	            }
	            else {
	                matrix.copy(m, parent.transform);
	            }
	        }
	        // 保存这个变换矩阵
	        this.transform = m;

	        this.invTransform = this.invTransform || matrix.create();
	        matrix.invert(this.invTransform, m);
	    };

	    transformableProto.getLocalTransform = function (m) {
	        return Transformable.getLocalTransform(this, m);
	    };

	    /**
	     * 将自己的transform应用到context上
	     * @param {Context2D} ctx
	     */
	    transformableProto.setTransform = function (ctx) {
	        var m = this.transform;
	        var dpr = ctx.dpr || 1;
	        if (m) {
	            ctx.setTransform(dpr * m[0], dpr * m[1], dpr * m[2], dpr * m[3], dpr * m[4], dpr * m[5]);
	        }
	        else {
	            ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
	        }
	    };

	    transformableProto.restoreTransform = function (ctx) {
	        var dpr = ctx.dpr || 1;
	        ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
	    };

	    var tmpTransform = [];

	    /**
	     * 分解`transform`矩阵到`position`, `rotation`, `scale`
	     */
	    transformableProto.decomposeTransform = function () {
	        if (!this.transform) {
	            return;
	        }
	        var parent = this.parent;
	        var m = this.transform;
	        if (parent && parent.transform) {
	            // Get local transform and decompose them to position, scale, rotation
	            matrix.mul(tmpTransform, parent.invTransform, m);
	            m = tmpTransform;
	        }
	        var sx = m[0] * m[0] + m[1] * m[1];
	        var sy = m[2] * m[2] + m[3] * m[3];
	        var position = this.position;
	        var scale = this.scale;
	        if (isNotAroundZero(sx - 1)) {
	            sx = Math.sqrt(sx);
	        }
	        if (isNotAroundZero(sy - 1)) {
	            sy = Math.sqrt(sy);
	        }
	        if (m[0] < 0) {
	            sx = -sx;
	        }
	        if (m[3] < 0) {
	            sy = -sy;
	        }
	        position[0] = m[4];
	        position[1] = m[5];
	        scale[0] = sx;
	        scale[1] = sy;
	        this.rotation = Math.atan2(-m[1] / sy, m[0] / sx);
	    };

	    /**
	     * Get global scale
	     * @return {Array.<number>}
	     */
	    transformableProto.getGlobalScale = function () {
	        var m = this.transform;
	        if (!m) {
	            return [1, 1];
	        }
	        var sx = Math.sqrt(m[0] * m[0] + m[1] * m[1]);
	        var sy = Math.sqrt(m[2] * m[2] + m[3] * m[3]);
	        if (m[0] < 0) {
	            sx = -sx;
	        }
	        if (m[3] < 0) {
	            sy = -sy;
	        }
	        return [sx, sy];
	    };
	    /**
	     * 变换坐标位置到 shape 的局部坐标空间
	     * @method
	     * @param {number} x
	     * @param {number} y
	     * @return {Array.<number>}
	     */
	    transformableProto.transformCoordToLocal = function (x, y) {
	        var v2 = [x, y];
	        var invTransform = this.invTransform;
	        if (invTransform) {
	            vector.applyTransform(v2, v2, invTransform);
	        }
	        return v2;
	    };

	    /**
	     * 变换局部坐标位置到全局坐标空间
	     * @method
	     * @param {number} x
	     * @param {number} y
	     * @return {Array.<number>}
	     */
	    transformableProto.transformCoordToGlobal = function (x, y) {
	        var v2 = [x, y];
	        var transform = this.transform;
	        if (transform) {
	            vector.applyTransform(v2, v2, transform);
	        }
	        return v2;
	    };

	    /**
	     * @static
	     * @param {Object} target
	     * @param {Array.<number>} target.origin
	     * @param {number} target.rotation
	     * @param {Array.<number>} target.position
	     * @param {Array.<number>} [m]
	     */
	    Transformable.getLocalTransform = function (target, m) {
	        m = m || [];
	        mIdentity(m);

	        var origin = target.origin;
	        var scale = target.scale || [1, 1];
	        var rotation = target.rotation || 0;
	        var position = target.position || [0, 0];

	        if (origin) {
	            // Translate to origin
	            m[4] -= origin[0];
	            m[5] -= origin[1];
	        }
	        matrix.scale(m, m, scale);
	        if (rotation) {
	            matrix.rotate(m, m, rotation);
	        }
	        if (origin) {
	            // Translate back from origin
	            m[4] += origin[0];
	            m[5] += origin[1];
	        }

	        m[4] += position[0];
	        m[5] += position[1];

	        return m;
	    };

	    module.exports = Transformable;



/***/ },
/* 27 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	/**
	 * @module zrender/mixin/Animatable
	 */


	    var Animator = __webpack_require__(28);
	    var util = __webpack_require__(4);
	    var isString = util.isString;
	    var isFunction = util.isFunction;
	    var isObject = util.isObject;
	    var log = __webpack_require__(33);

	    /**
	     * @alias modue:zrender/mixin/Animatable
	     * @constructor
	     */
	    var Animatable = function () {

	        /**
	         * @type {Array.<module:zrender/animation/Animator>}
	         * @readOnly
	         */
	        this.animators = [];
	    };

	    Animatable.prototype = {

	        constructor: Animatable,

	        /**
	         * 动画
	         *
	         * @param {string} path 需要添加动画的属性获取路径，可以通过a.b.c来获取深层的属性
	         * @param {boolean} [loop] 动画是否循环
	         * @return {module:zrender/animation/Animator}
	         * @example:
	         *     el.animate('style', false)
	         *         .when(1000, {x: 10} )
	         *         .done(function(){ // Animation done })
	         *         .start()
	         */
	        animate: function (path, loop) {
	            var target;
	            var animatingShape = false;
	            var el = this;
	            var zr = this.__zr;
	            if (path) {
	                var pathSplitted = path.split('.');
	                var prop = el;
	                // If animating shape
	                animatingShape = pathSplitted[0] === 'shape';
	                for (var i = 0, l = pathSplitted.length; i < l; i++) {
	                    if (!prop) {
	                        continue;
	                    }
	                    prop = prop[pathSplitted[i]];
	                }
	                if (prop) {
	                    target = prop;
	                }
	            }
	            else {
	                target = el;
	            }

	            if (!target) {
	                log(
	                    'Property "'
	                    + path
	                    + '" is not existed in element '
	                    + el.id
	                );
	                return;
	            }

	            var animators = el.animators;

	            var animator = new Animator(target, loop);

	            animator.during(function (target) {
	                el.dirty(animatingShape);
	            })
	            .done(function () {
	                // FIXME Animator will not be removed if use `Animator#stop` to stop animation
	                animators.splice(util.indexOf(animators, animator), 1);
	            });

	            animators.push(animator);

	            // If animate after added to the zrender
	            if (zr) {
	                zr.animation.addAnimator(animator);
	            }

	            return animator;
	        },

	        /**
	         * 停止动画
	         * @param {boolean} forwardToLast If move to last frame before stop
	         */
	        stopAnimation: function (forwardToLast) {
	            var animators = this.animators;
	            var len = animators.length;
	            for (var i = 0; i < len; i++) {
	                animators[i].stop(forwardToLast);
	            }
	            animators.length = 0;

	            return this;
	        },

	        /**
	         * @param {Object} target
	         * @param {number} [time=500] Time in ms
	         * @param {string} [easing='linear']
	         * @param {number} [delay=0]
	         * @param {Function} [callback]
	         *
	         * @example
	         *  // Animate position
	         *  el.animateTo({
	         *      position: [10, 10]
	         *  }, function () { // done })
	         *
	         *  // Animate shape, style and position in 100ms, delayed 100ms, with cubicOut easing
	         *  el.animateTo({
	         *      shape: {
	         *          width: 500
	         *      },
	         *      style: {
	         *          fill: 'red'
	         *      }
	         *      position: [10, 10]
	         *  }, 100, 100, 'cubicOut', function () { // done })
	         */
	         // TODO Return animation key
	        animateTo: function (target, time, delay, easing, callback) {
	            // animateTo(target, time, easing, callback);
	            if (isString(delay)) {
	                callback = easing;
	                easing = delay;
	                delay = 0;
	            }
	            // animateTo(target, time, delay, callback);
	            else if (isFunction(easing)) {
	                callback = easing;
	                easing = 'linear';
	                delay = 0;
	            }
	            // animateTo(target, time, callback);
	            else if (isFunction(delay)) {
	                callback = delay;
	                delay = 0;
	            }
	            // animateTo(target, callback)
	            else if (isFunction(time)) {
	                callback = time;
	                time = 500;
	            }
	            // animateTo(target)
	            else if (!time) {
	                time = 500;
	            }
	            // Stop all previous animations
	            this.stopAnimation();
	            this._animateToShallow('', this, target, time, delay, easing, callback);

	            // Animators may be removed immediately after start
	            // if there is nothing to animate
	            var animators = this.animators.slice();
	            var count = animators.length;
	            function done() {
	                count--;
	                if (!count) {
	                    callback && callback();
	                }
	            }

	            // No animators. This should be checked before animators[i].start(),
	            // because 'done' may be executed immediately if no need to animate.
	            if (!count) {
	                callback && callback();
	            }
	            // Start after all animators created
	            // Incase any animator is done immediately when all animation properties are not changed
	            for (var i = 0; i < animators.length; i++) {
	                animators[i]
	                    .done(done)
	                    .start(easing);
	            }
	        },

	        /**
	         * @private
	         * @param {string} path=''
	         * @param {Object} source=this
	         * @param {Object} target
	         * @param {number} [time=500]
	         * @param {number} [delay=0]
	         *
	         * @example
	         *  // Animate position
	         *  el._animateToShallow({
	         *      position: [10, 10]
	         *  })
	         *
	         *  // Animate shape, style and position in 100ms, delayed 100ms
	         *  el._animateToShallow({
	         *      shape: {
	         *          width: 500
	         *      },
	         *      style: {
	         *          fill: 'red'
	         *      }
	         *      position: [10, 10]
	         *  }, 100, 100)
	         */
	        _animateToShallow: function (path, source, target, time, delay) {
	            var objShallow = {};
	            var propertyCount = 0;
	            for (var name in target) {
	                if (!target.hasOwnProperty(name)) {
	                    continue;
	                }

	                if (source[name] != null) {
	                    if (isObject(target[name]) && !util.isArrayLike(target[name])) {
	                        this._animateToShallow(
	                            path ? path + '.' + name : name,
	                            source[name],
	                            target[name],
	                            time,
	                            delay
	                        );
	                    }
	                    else {
	                        objShallow[name] = target[name];
	                        propertyCount++;
	                    }
	                }
	                else if (target[name] != null) {
	                    // Attr directly if not has property
	                    // FIXME, if some property not needed for element ?
	                    if (!path) {
	                        this.attr(name, target[name]);
	                    }
	                    else {  // Shape or style
	                        var props = {};
	                        props[path] = {};
	                        props[path][name] = target[name];
	                        this.attr(props);
	                    }
	                }
	            }

	            if (propertyCount > 0) {
	                this.animate(path, false)
	                    .when(time == null ? 500 : time, objShallow)
	                    .delay(delay || 0);
	            }

	            return this;
	        }
	    };

	    module.exports = Animatable;


/***/ },
/* 28 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @module echarts/animation/Animator
	 */


	    var Clip = __webpack_require__(29);
	    var color = __webpack_require__(31);
	    var util = __webpack_require__(4);
	    var isArrayLike = util.isArrayLike;

	    var arraySlice = Array.prototype.slice;

	    function defaultGetter(target, key) {
	        return target[key];
	    }

	    function defaultSetter(target, key, value) {
	        target[key] = value;
	    }

	    /**
	     * @param  {number} p0
	     * @param  {number} p1
	     * @param  {number} percent
	     * @return {number}
	     */
	    function interpolateNumber(p0, p1, percent) {
	        return (p1 - p0) * percent + p0;
	    }

	    /**
	     * @param  {string} p0
	     * @param  {string} p1
	     * @param  {number} percent
	     * @return {string}
	     */
	    function interpolateString(p0, p1, percent) {
	        return percent > 0.5 ? p1 : p0;
	    }

	    /**
	     * @param  {Array} p0
	     * @param  {Array} p1
	     * @param  {number} percent
	     * @param  {Array} out
	     * @param  {number} arrDim
	     */
	    function interpolateArray(p0, p1, percent, out, arrDim) {
	        var len = p0.length;
	        if (arrDim == 1) {
	            for (var i = 0; i < len; i++) {
	                out[i] = interpolateNumber(p0[i], p1[i], percent);
	            }
	        }
	        else {
	            var len2 = len && p0[0].length;
	            for (var i = 0; i < len; i++) {
	                for (var j = 0; j < len2; j++) {
	                    out[i][j] = interpolateNumber(
	                        p0[i][j], p1[i][j], percent
	                    );
	                }
	            }
	        }
	    }

	    // arr0 is source array, arr1 is target array.
	    // Do some preprocess to avoid error happened when interpolating from arr0 to arr1
	    function fillArr(arr0, arr1, arrDim) {
	        var arr0Len = arr0.length;
	        var arr1Len = arr1.length;
	        if (arr0Len !== arr1Len) {
	            // FIXME Not work for TypedArray
	            var isPreviousLarger = arr0Len > arr1Len;
	            if (isPreviousLarger) {
	                // Cut the previous
	                arr0.length = arr1Len;
	            }
	            else {
	                // Fill the previous
	                for (var i = arr0Len; i < arr1Len; i++) {
	                    arr0.push(
	                        arrDim === 1 ? arr1[i] : arraySlice.call(arr1[i])
	                    );
	                }
	            }
	        }
	        // Handling NaN value
	        var len2 = arr0[0] && arr0[0].length;
	        for (var i = 0; i < arr0.length; i++) {
	            if (arrDim === 1) {
	                if (isNaN(arr0[i])) {
	                    arr0[i] = arr1[i];
	                }
	            }
	            else {
	                for (var j = 0; j < len2; j++) {
	                    if (isNaN(arr0[i][j])) {
	                        arr0[i][j] = arr1[i][j];
	                    }
	                }
	            }
	        }
	    }

	    /**
	     * @param  {Array} arr0
	     * @param  {Array} arr1
	     * @param  {number} arrDim
	     * @return {boolean}
	     */
	    function isArraySame(arr0, arr1, arrDim) {
	        if (arr0 === arr1) {
	            return true;
	        }
	        var len = arr0.length;
	        if (len !== arr1.length) {
	            return false;
	        }
	        if (arrDim === 1) {
	            for (var i = 0; i < len; i++) {
	                if (arr0[i] !== arr1[i]) {
	                    return false;
	                }
	            }
	        }
	        else {
	            var len2 = arr0[0].length;
	            for (var i = 0; i < len; i++) {
	                for (var j = 0; j < len2; j++) {
	                    if (arr0[i][j] !== arr1[i][j]) {
	                        return false;
	                    }
	                }
	            }
	        }
	        return true;
	    }

	    /**
	     * Catmull Rom interpolate array
	     * @param  {Array} p0
	     * @param  {Array} p1
	     * @param  {Array} p2
	     * @param  {Array} p3
	     * @param  {number} t
	     * @param  {number} t2
	     * @param  {number} t3
	     * @param  {Array} out
	     * @param  {number} arrDim
	     */
	    function catmullRomInterpolateArray(
	        p0, p1, p2, p3, t, t2, t3, out, arrDim
	    ) {
	        var len = p0.length;
	        if (arrDim == 1) {
	            for (var i = 0; i < len; i++) {
	                out[i] = catmullRomInterpolate(
	                    p0[i], p1[i], p2[i], p3[i], t, t2, t3
	                );
	            }
	        }
	        else {
	            var len2 = p0[0].length;
	            for (var i = 0; i < len; i++) {
	                for (var j = 0; j < len2; j++) {
	                    out[i][j] = catmullRomInterpolate(
	                        p0[i][j], p1[i][j], p2[i][j], p3[i][j],
	                        t, t2, t3
	                    );
	                }
	            }
	        }
	    }

	    /**
	     * Catmull Rom interpolate number
	     * @param  {number} p0
	     * @param  {number} p1
	     * @param  {number} p2
	     * @param  {number} p3
	     * @param  {number} t
	     * @param  {number} t2
	     * @param  {number} t3
	     * @return {number}
	     */
	    function catmullRomInterpolate(p0, p1, p2, p3, t, t2, t3) {
	        var v0 = (p2 - p0) * 0.5;
	        var v1 = (p3 - p1) * 0.5;
	        return (2 * (p1 - p2) + v0 + v1) * t3
	                + (-3 * (p1 - p2) - 2 * v0 - v1) * t2
	                + v0 * t + p1;
	    }

	    function cloneValue(value) {
	        if (isArrayLike(value)) {
	            var len = value.length;
	            if (isArrayLike(value[0])) {
	                var ret = [];
	                for (var i = 0; i < len; i++) {
	                    ret.push(arraySlice.call(value[i]));
	                }
	                return ret;
	            }

	            return arraySlice.call(value);
	        }

	        return value;
	    }

	    function rgba2String(rgba) {
	        rgba[0] = Math.floor(rgba[0]);
	        rgba[1] = Math.floor(rgba[1]);
	        rgba[2] = Math.floor(rgba[2]);

	        return 'rgba(' + rgba.join(',') + ')';
	    }

	    function getArrayDim(keyframes) {
	        var lastValue = keyframes[keyframes.length - 1].value;
	        return isArrayLike(lastValue && lastValue[0]) ? 2 : 1;
	    }

	    function createTrackClip (animator, easing, oneTrackDone, keyframes, propName) {
	        var getter = animator._getter;
	        var setter = animator._setter;
	        var useSpline = easing === 'spline';

	        var trackLen = keyframes.length;
	        if (!trackLen) {
	            return;
	        }
	        // Guess data type
	        var firstVal = keyframes[0].value;
	        var isValueArray = isArrayLike(firstVal);
	        var isValueColor = false;
	        var isValueString = false;

	        // For vertices morphing
	        var arrDim = isValueArray ? getArrayDim(keyframes) : 0;

	        var trackMaxTime;
	        // Sort keyframe as ascending
	        keyframes.sort(function(a, b) {
	            return a.time - b.time;
	        });

	        trackMaxTime = keyframes[trackLen - 1].time;
	        // Percents of each keyframe
	        var kfPercents = [];
	        // Value of each keyframe
	        var kfValues = [];
	        var prevValue = keyframes[0].value;
	        var isAllValueEqual = true;
	        for (var i = 0; i < trackLen; i++) {
	            kfPercents.push(keyframes[i].time / trackMaxTime);
	            // Assume value is a color when it is a string
	            var value = keyframes[i].value;

	            // Check if value is equal, deep check if value is array
	            if (!((isValueArray && isArraySame(value, prevValue, arrDim))
	                || (!isValueArray && value === prevValue))) {
	                isAllValueEqual = false;
	            }
	            prevValue = value;

	            // Try converting a string to a color array
	            if (typeof value == 'string') {
	                var colorArray = color.parse(value);
	                if (colorArray) {
	                    value = colorArray;
	                    isValueColor = true;
	                }
	                else {
	                    isValueString = true;
	                }
	            }
	            kfValues.push(value);
	        }
	        if (isAllValueEqual) {
	            return;
	        }

	        var lastValue = kfValues[trackLen - 1];
	        // Polyfill array and NaN value
	        for (var i = 0; i < trackLen - 1; i++) {
	            if (isValueArray) {
	                fillArr(kfValues[i], lastValue, arrDim);
	            }
	            else {
	                if (isNaN(kfValues[i]) && !isNaN(lastValue) && !isValueString && !isValueColor) {
	                    kfValues[i] = lastValue;
	                }
	            }
	        }
	        isValueArray && fillArr(getter(animator._target, propName), lastValue, arrDim);

	        // Cache the key of last frame to speed up when
	        // animation playback is sequency
	        var lastFrame = 0;
	        var lastFramePercent = 0;
	        var start;
	        var w;
	        var p0;
	        var p1;
	        var p2;
	        var p3;

	        if (isValueColor) {
	            var rgba = [0, 0, 0, 0];
	        }

	        var onframe = function (target, percent) {
	            // Find the range keyframes
	            // kf1-----kf2---------current--------kf3
	            // find kf2 and kf3 and do interpolation
	            var frame;
	            // In the easing function like elasticOut, percent may less than 0
	            if (percent < 0) {
	                frame = 0;
	            }
	            else if (percent < lastFramePercent) {
	                // Start from next key
	                // PENDING start from lastFrame ?
	                start = Math.min(lastFrame + 1, trackLen - 1);
	                for (frame = start; frame >= 0; frame--) {
	                    if (kfPercents[frame] <= percent) {
	                        break;
	                    }
	                }
	                // PENDING really need to do this ?
	                frame = Math.min(frame, trackLen - 2);
	            }
	            else {
	                for (frame = lastFrame; frame < trackLen; frame++) {
	                    if (kfPercents[frame] > percent) {
	                        break;
	                    }
	                }
	                frame = Math.min(frame - 1, trackLen - 2);
	            }
	            lastFrame = frame;
	            lastFramePercent = percent;

	            var range = (kfPercents[frame + 1] - kfPercents[frame]);
	            if (range === 0) {
	                return;
	            }
	            else {
	                w = (percent - kfPercents[frame]) / range;
	            }
	            if (useSpline) {
	                p1 = kfValues[frame];
	                p0 = kfValues[frame === 0 ? frame : frame - 1];
	                p2 = kfValues[frame > trackLen - 2 ? trackLen - 1 : frame + 1];
	                p3 = kfValues[frame > trackLen - 3 ? trackLen - 1 : frame + 2];
	                if (isValueArray) {
	                    catmullRomInterpolateArray(
	                        p0, p1, p2, p3, w, w * w, w * w * w,
	                        getter(target, propName),
	                        arrDim
	                    );
	                }
	                else {
	                    var value;
	                    if (isValueColor) {
	                        value = catmullRomInterpolateArray(
	                            p0, p1, p2, p3, w, w * w, w * w * w,
	                            rgba, 1
	                        );
	                        value = rgba2String(rgba);
	                    }
	                    else if (isValueString) {
	                        // String is step(0.5)
	                        return interpolateString(p1, p2, w);
	                    }
	                    else {
	                        value = catmullRomInterpolate(
	                            p0, p1, p2, p3, w, w * w, w * w * w
	                        );
	                    }
	                    setter(
	                        target,
	                        propName,
	                        value
	                    );
	                }
	            }
	            else {
	                if (isValueArray) {
	                    interpolateArray(
	                        kfValues[frame], kfValues[frame + 1], w,
	                        getter(target, propName),
	                        arrDim
	                    );
	                }
	                else {
	                    var value;
	                    if (isValueColor) {
	                        interpolateArray(
	                            kfValues[frame], kfValues[frame + 1], w,
	                            rgba, 1
	                        );
	                        value = rgba2String(rgba);
	                    }
	                    else if (isValueString) {
	                        // String is step(0.5)
	                        return interpolateString(kfValues[frame], kfValues[frame + 1], w);
	                    }
	                    else {
	                        value = interpolateNumber(kfValues[frame], kfValues[frame + 1], w);
	                    }
	                    setter(
	                        target,
	                        propName,
	                        value
	                    );
	                }
	            }
	        };

	        var clip = new Clip({
	            target: animator._target,
	            life: trackMaxTime,
	            loop: animator._loop,
	            delay: animator._delay,
	            onframe: onframe,
	            ondestroy: oneTrackDone
	        });

	        if (easing && easing !== 'spline') {
	            clip.easing = easing;
	        }

	        return clip;
	    }

	    /**
	     * @alias module:zrender/animation/Animator
	     * @constructor
	     * @param {Object} target
	     * @param {boolean} loop
	     * @param {Function} getter
	     * @param {Function} setter
	     */
	    var Animator = function(target, loop, getter, setter) {
	        this._tracks = {};
	        this._target = target;

	        this._loop = loop || false;

	        this._getter = getter || defaultGetter;
	        this._setter = setter || defaultSetter;

	        this._clipCount = 0;

	        this._delay = 0;

	        this._doneList = [];

	        this._onframeList = [];

	        this._clipList = [];
	    };

	    Animator.prototype = {
	        /**
	         * 设置动画关键帧
	         * @param  {number} time 关键帧时间，单位是ms
	         * @param  {Object} props 关键帧的属性值，key-value表示
	         * @return {module:zrender/animation/Animator}
	         */
	        when: function(time /* ms */, props) {
	            var tracks = this._tracks;
	            for (var propName in props) {
	                if (!props.hasOwnProperty(propName)) {
	                    continue;
	                }

	                if (!tracks[propName]) {
	                    tracks[propName] = [];
	                    // Invalid value
	                    var value = this._getter(this._target, propName);
	                    if (value == null) {
	                        // zrLog('Invalid property ' + propName);
	                        continue;
	                    }
	                    // If time is 0
	                    //  Then props is given initialize value
	                    // Else
	                    //  Initialize value from current prop value
	                    if (time !== 0) {
	                        tracks[propName].push({
	                            time: 0,
	                            value: cloneValue(value)
	                        });
	                    }
	                }
	                tracks[propName].push({
	                    time: time,
	                    value: props[propName]
	                });
	            }
	            return this;
	        },
	        /**
	         * 添加动画每一帧的回调函数
	         * @param  {Function} callback
	         * @return {module:zrender/animation/Animator}
	         */
	        during: function (callback) {
	            this._onframeList.push(callback);
	            return this;
	        },

	        pause: function () {
	            for (var i = 0; i < this._clipList.length; i++) {
	                this._clipList[i].pause();
	            }
	            this._paused = true;
	        },

	        resume: function () {
	            for (var i = 0; i < this._clipList.length; i++) {
	                this._clipList[i].resume();
	            }
	            this._paused = false;
	        },

	        isPaused: function () {
	            return !!this._paused;
	        },

	        _doneCallback: function () {
	            // Clear all tracks
	            this._tracks = {};
	            // Clear all clips
	            this._clipList.length = 0;

	            var doneList = this._doneList;
	            var len = doneList.length;
	            for (var i = 0; i < len; i++) {
	                doneList[i].call(this);
	            }
	        },
	        /**
	         * 开始执行动画
	         * @param  {string|Function} easing
	         *         动画缓动函数，详见{@link module:zrender/animation/easing}
	         * @return {module:zrender/animation/Animator}
	         */
	        start: function (easing) {

	            var self = this;
	            var clipCount = 0;

	            var oneTrackDone = function() {
	                clipCount--;
	                if (!clipCount) {
	                    self._doneCallback();
	                }
	            };

	            var lastClip;
	            for (var propName in this._tracks) {
	                if (!this._tracks.hasOwnProperty(propName)) {
	                    continue;
	                }
	                var clip = createTrackClip(
	                    this, easing, oneTrackDone,
	                    this._tracks[propName], propName
	                );
	                if (clip) {
	                    this._clipList.push(clip);
	                    clipCount++;

	                    // If start after added to animation
	                    if (this.animation) {
	                        this.animation.addClip(clip);
	                    }

	                    lastClip = clip;
	                }
	            }

	            // Add during callback on the last clip
	            if (lastClip) {
	                var oldOnFrame = lastClip.onframe;
	                lastClip.onframe = function (target, percent) {
	                    oldOnFrame(target, percent);

	                    for (var i = 0; i < self._onframeList.length; i++) {
	                        self._onframeList[i](target, percent);
	                    }
	                };
	            }

	            if (!clipCount) {
	                this._doneCallback();
	            }
	            return this;
	        },
	        /**
	         * 停止动画
	         * @param {boolean} forwardToLast If move to last frame before stop
	         */
	        stop: function (forwardToLast) {
	            var clipList = this._clipList;
	            var animation = this.animation;
	            for (var i = 0; i < clipList.length; i++) {
	                var clip = clipList[i];
	                if (forwardToLast) {
	                    // Move to last frame before stop
	                    clip.onframe(this._target, 1);
	                }
	                animation && animation.removeClip(clip);
	            }
	            clipList.length = 0;
	        },
	        /**
	         * 设置动画延迟开始的时间
	         * @param  {number} time 单位ms
	         * @return {module:zrender/animation/Animator}
	         */
	        delay: function (time) {
	            this._delay = time;
	            return this;
	        },
	        /**
	         * 添加动画结束的回调
	         * @param  {Function} cb
	         * @return {module:zrender/animation/Animator}
	         */
	        done: function(cb) {
	            if (cb) {
	                this._doneList.push(cb);
	            }
	            return this;
	        },

	        /**
	         * @return {Array.<module:zrender/animation/Clip>}
	         */
	        getClips: function () {
	            return this._clipList;
	        }
	    };

	    module.exports = Animator;


/***/ },
/* 29 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * 动画主控制器
	 * @config target 动画对象，可以是数组，如果是数组的话会批量分发onframe等事件
	 * @config life(1000) 动画时长
	 * @config delay(0) 动画延迟时间
	 * @config loop(true)
	 * @config gap(0) 循环的间隔时间
	 * @config onframe
	 * @config easing(optional)
	 * @config ondestroy(optional)
	 * @config onrestart(optional)
	 *
	 * TODO pause
	 */


	    var easingFuncs = __webpack_require__(30);

	    function Clip(options) {

	        this._target = options.target;

	        // 生命周期
	        this._life = options.life || 1000;
	        // 延时
	        this._delay = options.delay || 0;
	        // 开始时间
	        // this._startTime = new Date().getTime() + this._delay;// 单位毫秒
	        this._initialized = false;

	        // 是否循环
	        this.loop = options.loop == null ? false : options.loop;

	        this.gap = options.gap || 0;

	        this.easing = options.easing || 'Linear';

	        this.onframe = options.onframe;
	        this.ondestroy = options.ondestroy;
	        this.onrestart = options.onrestart;

	        this._pausedTime = 0;
	        this._paused = false;
	    }

	    Clip.prototype = {

	        constructor: Clip,

	        step: function (globalTime, deltaTime) {
	            // Set startTime on first step, or _startTime may has milleseconds different between clips
	            // PENDING
	            if (!this._initialized) {
	                this._startTime = globalTime + this._delay;
	                this._initialized = true;
	            }

	            if (this._paused) {
	                this._pausedTime += deltaTime;
	                return;
	            }

	            var percent = (globalTime - this._startTime - this._pausedTime) / this._life;

	            // 还没开始
	            if (percent < 0) {
	                return;
	            }

	            percent = Math.min(percent, 1);

	            var easing = this.easing;
	            var easingFunc = typeof easing == 'string' ? easingFuncs[easing] : easing;
	            var schedule = typeof easingFunc === 'function'
	                ? easingFunc(percent)
	                : percent;

	            this.fire('frame', schedule);

	            // 结束
	            if (percent == 1) {
	                if (this.loop) {
	                    this.restart (globalTime);
	                    // 重新开始周期
	                    // 抛出而不是直接调用事件直到 stage.update 后再统一调用这些事件
	                    return 'restart';
	                }

	                // 动画完成将这个控制器标识为待删除
	                // 在Animation.update中进行批量删除
	                this._needsRemove = true;
	                return 'destroy';
	            }

	            return null;
	        },

	        restart: function (globalTime) {
	            var remainder = (globalTime - this._startTime - this._pausedTime) % this._life;
	            this._startTime = globalTime - remainder + this.gap;
	            this._pausedTime = 0;

	            this._needsRemove = false;
	        },

	        fire: function (eventType, arg) {
	            eventType = 'on' + eventType;
	            if (this[eventType]) {
	                this[eventType](this._target, arg);
	            }
	        },

	        pause: function () {
	            this._paused = true;
	        },

	        resume: function () {
	            this._paused = false;
	        }
	    };

	    module.exports = Clip;



/***/ },
/* 30 */
/***/ function(module, exports) {

	/**
	 * 缓动代码来自 https://github.com/sole/tween.js/blob/master/src/Tween.js
	 * @see http://sole.github.io/tween.js/examples/03_graphs.html
	 * @exports zrender/animation/easing
	 */

	    var easing = {
	        /**
	        * @param {number} k
	        * @return {number}
	        */
	        linear: function (k) {
	            return k;
	        },

	        /**
	        * @param {number} k
	        * @return {number}
	        */
	        quadraticIn: function (k) {
	            return k * k;
	        },
	        /**
	        * @param {number} k
	        * @return {number}
	        */
	        quadraticOut: function (k) {
	            return k * (2 - k);
	        },
	        /**
	        * @param {number} k
	        * @return {number}
	        */
	        quadraticInOut: function (k) {
	            if ((k *= 2) < 1) {
	                return 0.5 * k * k;
	            }
	            return -0.5 * (--k * (k - 2) - 1);
	        },

	        // 三次方的缓动（t^3）
	        /**
	        * @param {number} k
	        * @return {number}
	        */
	        cubicIn: function (k) {
	            return k * k * k;
	        },
	        /**
	        * @param {number} k
	        * @return {number}
	        */
	        cubicOut: function (k) {
	            return --k * k * k + 1;
	        },
	        /**
	        * @param {number} k
	        * @return {number}
	        */
	        cubicInOut: function (k) {
	            if ((k *= 2) < 1) {
	                return 0.5 * k * k * k;
	            }
	            return 0.5 * ((k -= 2) * k * k + 2);
	        },

	        // 四次方的缓动（t^4）
	        /**
	        * @param {number} k
	        * @return {number}
	        */
	        quarticIn: function (k) {
	            return k * k * k * k;
	        },
	        /**
	        * @param {number} k
	        * @return {number}
	        */
	        quarticOut: function (k) {
	            return 1 - (--k * k * k * k);
	        },
	        /**
	        * @param {number} k
	        * @return {number}
	        */
	        quarticInOut: function (k) {
	            if ((k *= 2) < 1) {
	                return 0.5 * k * k * k * k;
	            }
	            return -0.5 * ((k -= 2) * k * k * k - 2);
	        },

	        // 五次方的缓动（t^5）
	        /**
	        * @param {number} k
	        * @return {number}
	        */
	        quinticIn: function (k) {
	            return k * k * k * k * k;
	        },
	        /**
	        * @param {number} k
	        * @return {number}
	        */
	        quinticOut: function (k) {
	            return --k * k * k * k * k + 1;
	        },
	        /**
	        * @param {number} k
	        * @return {number}
	        */
	        quinticInOut: function (k) {
	            if ((k *= 2) < 1) {
	                return 0.5 * k * k * k * k * k;
	            }
	            return 0.5 * ((k -= 2) * k * k * k * k + 2);
	        },

	        // 正弦曲线的缓动（sin(t)）
	        /**
	        * @param {number} k
	        * @return {number}
	        */
	        sinusoidalIn: function (k) {
	            return 1 - Math.cos(k * Math.PI / 2);
	        },
	        /**
	        * @param {number} k
	        * @return {number}
	        */
	        sinusoidalOut: function (k) {
	            return Math.sin(k * Math.PI / 2);
	        },
	        /**
	        * @param {number} k
	        * @return {number}
	        */
	        sinusoidalInOut: function (k) {
	            return 0.5 * (1 - Math.cos(Math.PI * k));
	        },

	        // 指数曲线的缓动（2^t）
	        /**
	        * @param {number} k
	        * @return {number}
	        */
	        exponentialIn: function (k) {
	            return k === 0 ? 0 : Math.pow(1024, k - 1);
	        },
	        /**
	        * @param {number} k
	        * @return {number}
	        */
	        exponentialOut: function (k) {
	            return k === 1 ? 1 : 1 - Math.pow(2, -10 * k);
	        },
	        /**
	        * @param {number} k
	        * @return {number}
	        */
	        exponentialInOut: function (k) {
	            if (k === 0) {
	                return 0;
	            }
	            if (k === 1) {
	                return 1;
	            }
	            if ((k *= 2) < 1) {
	                return 0.5 * Math.pow(1024, k - 1);
	            }
	            return 0.5 * (-Math.pow(2, -10 * (k - 1)) + 2);
	        },

	        // 圆形曲线的缓动（sqrt(1-t^2)）
	        /**
	        * @param {number} k
	        * @return {number}
	        */
	        circularIn: function (k) {
	            return 1 - Math.sqrt(1 - k * k);
	        },
	        /**
	        * @param {number} k
	        * @return {number}
	        */
	        circularOut: function (k) {
	            return Math.sqrt(1 - (--k * k));
	        },
	        /**
	        * @param {number} k
	        * @return {number}
	        */
	        circularInOut: function (k) {
	            if ((k *= 2) < 1) {
	                return -0.5 * (Math.sqrt(1 - k * k) - 1);
	            }
	            return 0.5 * (Math.sqrt(1 - (k -= 2) * k) + 1);
	        },

	        // 创建类似于弹簧在停止前来回振荡的动画
	        /**
	        * @param {number} k
	        * @return {number}
	        */
	        elasticIn: function (k) {
	            var s;
	            var a = 0.1;
	            var p = 0.4;
	            if (k === 0) {
	                return 0;
	            }
	            if (k === 1) {
	                return 1;
	            }
	            if (!a || a < 1) {
	                a = 1; s = p / 4;
	            }
	            else {
	                s = p * Math.asin(1 / a) / (2 * Math.PI);
	            }
	            return -(a * Math.pow(2, 10 * (k -= 1)) *
	                        Math.sin((k - s) * (2 * Math.PI) / p));
	        },
	        /**
	        * @param {number} k
	        * @return {number}
	        */
	        elasticOut: function (k) {
	            var s;
	            var a = 0.1;
	            var p = 0.4;
	            if (k === 0) {
	                return 0;
	            }
	            if (k === 1) {
	                return 1;
	            }
	            if (!a || a < 1) {
	                a = 1; s = p / 4;
	            }
	            else {
	                s = p * Math.asin(1 / a) / (2 * Math.PI);
	            }
	            return (a * Math.pow(2, -10 * k) *
	                    Math.sin((k - s) * (2 * Math.PI) / p) + 1);
	        },
	        /**
	        * @param {number} k
	        * @return {number}
	        */
	        elasticInOut: function (k) {
	            var s;
	            var a = 0.1;
	            var p = 0.4;
	            if (k === 0) {
	                return 0;
	            }
	            if (k === 1) {
	                return 1;
	            }
	            if (!a || a < 1) {
	                a = 1; s = p / 4;
	            }
	            else {
	                s = p * Math.asin(1 / a) / (2 * Math.PI);
	            }
	            if ((k *= 2) < 1) {
	                return -0.5 * (a * Math.pow(2, 10 * (k -= 1))
	                    * Math.sin((k - s) * (2 * Math.PI) / p));
	            }
	            return a * Math.pow(2, -10 * (k -= 1))
	                    * Math.sin((k - s) * (2 * Math.PI) / p) * 0.5 + 1;

	        },

	        // 在某一动画开始沿指示的路径进行动画处理前稍稍收回该动画的移动
	        /**
	        * @param {number} k
	        * @return {number}
	        */
	        backIn: function (k) {
	            var s = 1.70158;
	            return k * k * ((s + 1) * k - s);
	        },
	        /**
	        * @param {number} k
	        * @return {number}
	        */
	        backOut: function (k) {
	            var s = 1.70158;
	            return --k * k * ((s + 1) * k + s) + 1;
	        },
	        /**
	        * @param {number} k
	        * @return {number}
	        */
	        backInOut: function (k) {
	            var s = 1.70158 * 1.525;
	            if ((k *= 2) < 1) {
	                return 0.5 * (k * k * ((s + 1) * k - s));
	            }
	            return 0.5 * ((k -= 2) * k * ((s + 1) * k + s) + 2);
	        },

	        // 创建弹跳效果
	        /**
	        * @param {number} k
	        * @return {number}
	        */
	        bounceIn: function (k) {
	            return 1 - easing.bounceOut(1 - k);
	        },
	        /**
	        * @param {number} k
	        * @return {number}
	        */
	        bounceOut: function (k) {
	            if (k < (1 / 2.75)) {
	                return 7.5625 * k * k;
	            }
	            else if (k < (2 / 2.75)) {
	                return 7.5625 * (k -= (1.5 / 2.75)) * k + 0.75;
	            }
	            else if (k < (2.5 / 2.75)) {
	                return 7.5625 * (k -= (2.25 / 2.75)) * k + 0.9375;
	            }
	            else {
	                return 7.5625 * (k -= (2.625 / 2.75)) * k + 0.984375;
	            }
	        },
	        /**
	        * @param {number} k
	        * @return {number}
	        */
	        bounceInOut: function (k) {
	            if (k < 0.5) {
	                return easing.bounceIn(k * 2) * 0.5;
	            }
	            return easing.bounceOut(k * 2 - 1) * 0.5 + 0.5;
	        }
	    };

	    module.exports = easing;




/***/ },
/* 31 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @module zrender/tool/color
	 */


	    var LRU = __webpack_require__(32);

	    var kCSSColorTable = {
	        'transparent': [0,0,0,0], 'aliceblue': [240,248,255,1],
	        'antiquewhite': [250,235,215,1], 'aqua': [0,255,255,1],
	        'aquamarine': [127,255,212,1], 'azure': [240,255,255,1],
	        'beige': [245,245,220,1], 'bisque': [255,228,196,1],
	        'black': [0,0,0,1], 'blanchedalmond': [255,235,205,1],
	        'blue': [0,0,255,1], 'blueviolet': [138,43,226,1],
	        'brown': [165,42,42,1], 'burlywood': [222,184,135,1],
	        'cadetblue': [95,158,160,1], 'chartreuse': [127,255,0,1],
	        'chocolate': [210,105,30,1], 'coral': [255,127,80,1],
	        'cornflowerblue': [100,149,237,1], 'cornsilk': [255,248,220,1],
	        'crimson': [220,20,60,1], 'cyan': [0,255,255,1],
	        'darkblue': [0,0,139,1], 'darkcyan': [0,139,139,1],
	        'darkgoldenrod': [184,134,11,1], 'darkgray': [169,169,169,1],
	        'darkgreen': [0,100,0,1], 'darkgrey': [169,169,169,1],
	        'darkkhaki': [189,183,107,1], 'darkmagenta': [139,0,139,1],
	        'darkolivegreen': [85,107,47,1], 'darkorange': [255,140,0,1],
	        'darkorchid': [153,50,204,1], 'darkred': [139,0,0,1],
	        'darksalmon': [233,150,122,1], 'darkseagreen': [143,188,143,1],
	        'darkslateblue': [72,61,139,1], 'darkslategray': [47,79,79,1],
	        'darkslategrey': [47,79,79,1], 'darkturquoise': [0,206,209,1],
	        'darkviolet': [148,0,211,1], 'deeppink': [255,20,147,1],
	        'deepskyblue': [0,191,255,1], 'dimgray': [105,105,105,1],
	        'dimgrey': [105,105,105,1], 'dodgerblue': [30,144,255,1],
	        'firebrick': [178,34,34,1], 'floralwhite': [255,250,240,1],
	        'forestgreen': [34,139,34,1], 'fuchsia': [255,0,255,1],
	        'gainsboro': [220,220,220,1], 'ghostwhite': [248,248,255,1],
	        'gold': [255,215,0,1], 'goldenrod': [218,165,32,1],
	        'gray': [128,128,128,1], 'green': [0,128,0,1],
	        'greenyellow': [173,255,47,1], 'grey': [128,128,128,1],
	        'honeydew': [240,255,240,1], 'hotpink': [255,105,180,1],
	        'indianred': [205,92,92,1], 'indigo': [75,0,130,1],
	        'ivory': [255,255,240,1], 'khaki': [240,230,140,1],
	        'lavender': [230,230,250,1], 'lavenderblush': [255,240,245,1],
	        'lawngreen': [124,252,0,1], 'lemonchiffon': [255,250,205,1],
	        'lightblue': [173,216,230,1], 'lightcoral': [240,128,128,1],
	        'lightcyan': [224,255,255,1], 'lightgoldenrodyellow': [250,250,210,1],
	        'lightgray': [211,211,211,1], 'lightgreen': [144,238,144,1],
	        'lightgrey': [211,211,211,1], 'lightpink': [255,182,193,1],
	        'lightsalmon': [255,160,122,1], 'lightseagreen': [32,178,170,1],
	        'lightskyblue': [135,206,250,1], 'lightslategray': [119,136,153,1],
	        'lightslategrey': [119,136,153,1], 'lightsteelblue': [176,196,222,1],
	        'lightyellow': [255,255,224,1], 'lime': [0,255,0,1],
	        'limegreen': [50,205,50,1], 'linen': [250,240,230,1],
	        'magenta': [255,0,255,1], 'maroon': [128,0,0,1],
	        'mediumaquamarine': [102,205,170,1], 'mediumblue': [0,0,205,1],
	        'mediumorchid': [186,85,211,1], 'mediumpurple': [147,112,219,1],
	        'mediumseagreen': [60,179,113,1], 'mediumslateblue': [123,104,238,1],
	        'mediumspringgreen': [0,250,154,1], 'mediumturquoise': [72,209,204,1],
	        'mediumvioletred': [199,21,133,1], 'midnightblue': [25,25,112,1],
	        'mintcream': [245,255,250,1], 'mistyrose': [255,228,225,1],
	        'moccasin': [255,228,181,1], 'navajowhite': [255,222,173,1],
	        'navy': [0,0,128,1], 'oldlace': [253,245,230,1],
	        'olive': [128,128,0,1], 'olivedrab': [107,142,35,1],
	        'orange': [255,165,0,1], 'orangered': [255,69,0,1],
	        'orchid': [218,112,214,1], 'palegoldenrod': [238,232,170,1],
	        'palegreen': [152,251,152,1], 'paleturquoise': [175,238,238,1],
	        'palevioletred': [219,112,147,1], 'papayawhip': [255,239,213,1],
	        'peachpuff': [255,218,185,1], 'peru': [205,133,63,1],
	        'pink': [255,192,203,1], 'plum': [221,160,221,1],
	        'powderblue': [176,224,230,1], 'purple': [128,0,128,1],
	        'red': [255,0,0,1], 'rosybrown': [188,143,143,1],
	        'royalblue': [65,105,225,1], 'saddlebrown': [139,69,19,1],
	        'salmon': [250,128,114,1], 'sandybrown': [244,164,96,1],
	        'seagreen': [46,139,87,1], 'seashell': [255,245,238,1],
	        'sienna': [160,82,45,1], 'silver': [192,192,192,1],
	        'skyblue': [135,206,235,1], 'slateblue': [106,90,205,1],
	        'slategray': [112,128,144,1], 'slategrey': [112,128,144,1],
	        'snow': [255,250,250,1], 'springgreen': [0,255,127,1],
	        'steelblue': [70,130,180,1], 'tan': [210,180,140,1],
	        'teal': [0,128,128,1], 'thistle': [216,191,216,1],
	        'tomato': [255,99,71,1], 'turquoise': [64,224,208,1],
	        'violet': [238,130,238,1], 'wheat': [245,222,179,1],
	        'white': [255,255,255,1], 'whitesmoke': [245,245,245,1],
	        'yellow': [255,255,0,1], 'yellowgreen': [154,205,50,1]
	    };

	    function clampCssByte(i) {  // Clamp to integer 0 .. 255.
	        i = Math.round(i);  // Seems to be what Chrome does (vs truncation).
	        return i < 0 ? 0 : i > 255 ? 255 : i;
	    }

	    function clampCssAngle(i) {  // Clamp to integer 0 .. 360.
	        i = Math.round(i);  // Seems to be what Chrome does (vs truncation).
	        return i < 0 ? 0 : i > 360 ? 360 : i;
	    }

	    function clampCssFloat(f) {  // Clamp to float 0.0 .. 1.0.
	        return f < 0 ? 0 : f > 1 ? 1 : f;
	    }

	    function parseCssInt(str) {  // int or percentage.
	        if (str.length && str.charAt(str.length - 1) === '%') {
	            return clampCssByte(parseFloat(str) / 100 * 255);
	        }
	        return clampCssByte(parseInt(str, 10));
	    }

	    function parseCssFloat(str) {  // float or percentage.
	        if (str.length && str.charAt(str.length - 1) === '%') {
	            return clampCssFloat(parseFloat(str) / 100);
	        }
	        return clampCssFloat(parseFloat(str));
	    }

	    function cssHueToRgb(m1, m2, h) {
	        if (h < 0) {
	            h += 1;
	        }
	        else if (h > 1) {
	            h -= 1;
	        }

	        if (h * 6 < 1) {
	            return m1 + (m2 - m1) * h * 6;
	        }
	        if (h * 2 < 1) {
	            return m2;
	        }
	        if (h * 3 < 2) {
	            return m1 + (m2 - m1) * (2/3 - h) * 6;
	        }
	        return m1;
	    }

	    function lerp(a, b, p) {
	        return a + (b - a) * p;
	    }

	    function setRgba(out, r, g, b, a) {
	        out[0] = r; out[1] = g; out[2] = b; out[3] = a;
	        return out;
	    }
	    function copyRgba(out, a) {
	        out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[3];
	        return out;
	    }
	    var colorCache = new LRU(20);
	    var lastRemovedArr = null;
	    function putToCache(colorStr, rgbaArr) {
	        // Reuse removed array
	        if (lastRemovedArr) {
	            copyRgba(lastRemovedArr, rgbaArr);
	        }
	        lastRemovedArr = colorCache.put(colorStr, lastRemovedArr || (rgbaArr.slice()));
	    }
	    /**
	     * @param {string} colorStr
	     * @param {Array.<number>} out
	     * @return {Array.<number>}
	     * @memberOf module:zrender/util/color
	     */
	    function parse(colorStr, rgbaArr) {
	        if (!colorStr) {
	            return;
	        }
	        rgbaArr = rgbaArr || [];

	        var cached = colorCache.get(colorStr);
	        if (cached) {
	            return copyRgba(rgbaArr, cached);
	        }

	        // colorStr may be not string
	        colorStr = colorStr + '';
	        // Remove all whitespace, not compliant, but should just be more accepting.
	        var str = colorStr.replace(/ /g, '').toLowerCase();

	        // Color keywords (and transparent) lookup.
	        if (str in kCSSColorTable) {
	            copyRgba(rgbaArr, kCSSColorTable[str]);
	            putToCache(colorStr, rgbaArr);
	            return rgbaArr;
	        }

	        // #abc and #abc123 syntax.
	        if (str.charAt(0) === '#') {
	            if (str.length === 4) {
	                var iv = parseInt(str.substr(1), 16);  // TODO(deanm): Stricter parsing.
	                if (!(iv >= 0 && iv <= 0xfff)) {
	                    setRgba(rgbaArr, 0, 0, 0, 1);
	                    return;  // Covers NaN.
	                }
	                setRgba(rgbaArr,
	                    ((iv & 0xf00) >> 4) | ((iv & 0xf00) >> 8),
	                    (iv & 0xf0) | ((iv & 0xf0) >> 4),
	                    (iv & 0xf) | ((iv & 0xf) << 4),
	                    1
	                );
	                putToCache(colorStr, rgbaArr);
	                return rgbaArr;
	            }
	            else if (str.length === 7) {
	                var iv = parseInt(str.substr(1), 16);  // TODO(deanm): Stricter parsing.
	                if (!(iv >= 0 && iv <= 0xffffff)) {
	                    setRgba(rgbaArr, 0, 0, 0, 1);
	                    return;  // Covers NaN.
	                }
	                setRgba(rgbaArr,
	                    (iv & 0xff0000) >> 16,
	                    (iv & 0xff00) >> 8,
	                    iv & 0xff,
	                    1
	                );
	                putToCache(colorStr, rgbaArr);
	                return rgbaArr;
	            }

	            return;
	        }
	        var op = str.indexOf('('), ep = str.indexOf(')');
	        if (op !== -1 && ep + 1 === str.length) {
	            var fname = str.substr(0, op);
	            var params = str.substr(op + 1, ep - (op + 1)).split(',');
	            var alpha = 1;  // To allow case fallthrough.
	            switch (fname) {
	                case 'rgba':
	                    if (params.length !== 4) {
	                        setRgba(rgbaArr, 0, 0, 0, 1);
	                        return;
	                    }
	                    alpha = parseCssFloat(params.pop()); // jshint ignore:line
	                // Fall through.
	                case 'rgb':
	                    if (params.length !== 3) {
	                        setRgba(rgbaArr, 0, 0, 0, 1);
	                        return;
	                    }
	                    setRgba(rgbaArr,
	                        parseCssInt(params[0]),
	                        parseCssInt(params[1]),
	                        parseCssInt(params[2]),
	                        alpha
	                    );
	                    putToCache(colorStr, rgbaArr);
	                    return rgbaArr;
	                case 'hsla':
	                    if (params.length !== 4) {
	                        setRgba(rgbaArr, 0, 0, 0, 1);
	                        return;
	                    }
	                    params[3] = parseCssFloat(params[3]);
	                    hsla2rgba(params, rgbaArr);
	                    putToCache(colorStr, rgbaArr);
	                    return rgbaArr;
	                case 'hsl':
	                    if (params.length !== 3) {
	                        setRgba(rgbaArr, 0, 0, 0, 1);
	                        return;
	                    }
	                    hsla2rgba(params, rgbaArr);
	                    putToCache(colorStr, rgbaArr);
	                    return rgbaArr;
	                default:
	                    return;
	            }
	        }

	        setRgba(rgbaArr, 0, 0, 0, 1);
	        return;
	    }

	    /**
	     * @param {Array.<number>} hsla
	     * @param {Array.<number>} rgba
	     * @return {Array.<number>} rgba
	     */
	    function hsla2rgba(hsla, rgba) {
	        var h = (((parseFloat(hsla[0]) % 360) + 360) % 360) / 360;  // 0 .. 1
	        // NOTE(deanm): According to the CSS spec s/l should only be
	        // percentages, but we don't bother and let float or percentage.
	        var s = parseCssFloat(hsla[1]);
	        var l = parseCssFloat(hsla[2]);
	        var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
	        var m1 = l * 2 - m2;

	        rgba = rgba || [];
	        setRgba(rgba,
	            clampCssByte(cssHueToRgb(m1, m2, h + 1 / 3) * 255),
	            clampCssByte(cssHueToRgb(m1, m2, h) * 255),
	            clampCssByte(cssHueToRgb(m1, m2, h - 1 / 3) * 255),
	            1
	        );

	        if (hsla.length === 4) {
	            rgba[3] = hsla[3];
	        }

	        return rgba;
	    }

	    /**
	     * @param {Array.<number>} rgba
	     * @return {Array.<number>} hsla
	     */
	    function rgba2hsla(rgba) {
	        if (!rgba) {
	            return;
	        }

	        // RGB from 0 to 255
	        var R = rgba[0] / 255;
	        var G = rgba[1] / 255;
	        var B = rgba[2] / 255;

	        var vMin = Math.min(R, G, B); // Min. value of RGB
	        var vMax = Math.max(R, G, B); // Max. value of RGB
	        var delta = vMax - vMin; // Delta RGB value

	        var L = (vMax + vMin) / 2;
	        var H;
	        var S;
	        // HSL results from 0 to 1
	        if (delta === 0) {
	            H = 0;
	            S = 0;
	        }
	        else {
	            if (L < 0.5) {
	                S = delta / (vMax + vMin);
	            }
	            else {
	                S = delta / (2 - vMax - vMin);
	            }

	            var deltaR = (((vMax - R) / 6) + (delta / 2)) / delta;
	            var deltaG = (((vMax - G) / 6) + (delta / 2)) / delta;
	            var deltaB = (((vMax - B) / 6) + (delta / 2)) / delta;

	            if (R === vMax) {
	                H = deltaB - deltaG;
	            }
	            else if (G === vMax) {
	                H = (1 / 3) + deltaR - deltaB;
	            }
	            else if (B === vMax) {
	                H = (2 / 3) + deltaG - deltaR;
	            }

	            if (H < 0) {
	                H += 1;
	            }

	            if (H > 1) {
	                H -= 1;
	            }
	        }

	        var hsla = [H * 360, S, L];

	        if (rgba[3] != null) {
	            hsla.push(rgba[3]);
	        }

	        return hsla;
	    }

	    /**
	     * @param {string} color
	     * @param {number} level
	     * @return {string}
	     * @memberOf module:zrender/util/color
	     */
	    function lift(color, level) {
	        var colorArr = parse(color);
	        if (colorArr) {
	            for (var i = 0; i < 3; i++) {
	                if (level < 0) {
	                    colorArr[i] = colorArr[i] * (1 - level) | 0;
	                }
	                else {
	                    colorArr[i] = ((255 - colorArr[i]) * level + colorArr[i]) | 0;
	                }
	            }
	            return stringify(colorArr, colorArr.length === 4 ? 'rgba' : 'rgb');
	        }
	    }

	    /**
	     * @param {string} color
	     * @return {string}
	     * @memberOf module:zrender/util/color
	     */
	    function toHex(color, level) {
	        var colorArr = parse(color);
	        if (colorArr) {
	            return ((1 << 24) + (colorArr[0] << 16) + (colorArr[1] << 8) + (+colorArr[2])).toString(16).slice(1);
	        }
	    }

	    /**
	     * Map value to color. Faster than mapToColor methods because color is represented by rgba array.
	     * @param {number} normalizedValue A float between 0 and 1.
	     * @param {Array.<Array.<number>>} colors List of rgba color array
	     * @param {Array.<number>} [out] Mapped gba color array
	     * @return {Array.<number>} will be null/undefined if input illegal.
	     */
	    function fastMapToColor(normalizedValue, colors, out) {
	        if (!(colors && colors.length)
	            || !(normalizedValue >= 0 && normalizedValue <= 1)
	        ) {
	            return;
	        }

	        out = out || [];

	        var value = normalizedValue * (colors.length - 1);
	        var leftIndex = Math.floor(value);
	        var rightIndex = Math.ceil(value);
	        var leftColor = colors[leftIndex];
	        var rightColor = colors[rightIndex];
	        var dv = value - leftIndex;
	        out[0] = clampCssByte(lerp(leftColor[0], rightColor[0], dv));
	        out[1] = clampCssByte(lerp(leftColor[1], rightColor[1], dv));
	        out[2] = clampCssByte(lerp(leftColor[2], rightColor[2], dv));
	        out[3] = clampCssFloat(lerp(leftColor[3], rightColor[3], dv));

	        return out;
	    }
	    /**
	     * @param {number} normalizedValue A float between 0 and 1.
	     * @param {Array.<string>} colors Color list.
	     * @param {boolean=} fullOutput Default false.
	     * @return {(string|Object)} Result color. If fullOutput,
	     *                           return {color: ..., leftIndex: ..., rightIndex: ..., value: ...},
	     * @memberOf module:zrender/util/color
	     */
	    function mapToColor(normalizedValue, colors, fullOutput) {
	        if (!(colors && colors.length)
	            || !(normalizedValue >= 0 && normalizedValue <= 1)
	        ) {
	            return;
	        }

	        var value = normalizedValue * (colors.length - 1);
	        var leftIndex = Math.floor(value);
	        var rightIndex = Math.ceil(value);
	        var leftColor = parse(colors[leftIndex]);
	        var rightColor = parse(colors[rightIndex]);
	        var dv = value - leftIndex;

	        var color = stringify(
	            [
	                clampCssByte(lerp(leftColor[0], rightColor[0], dv)),
	                clampCssByte(lerp(leftColor[1], rightColor[1], dv)),
	                clampCssByte(lerp(leftColor[2], rightColor[2], dv)),
	                clampCssFloat(lerp(leftColor[3], rightColor[3], dv))
	            ],
	            'rgba'
	        );

	        return fullOutput
	            ? {
	                color: color,
	                leftIndex: leftIndex,
	                rightIndex: rightIndex,
	                value: value
	            }
	            : color;
	    }

	    /**
	     * @param {string} color
	     * @param {number=} h 0 ~ 360, ignore when null.
	     * @param {number=} s 0 ~ 1, ignore when null.
	     * @param {number=} l 0 ~ 1, ignore when null.
	     * @return {string} Color string in rgba format.
	     * @memberOf module:zrender/util/color
	     */
	    function modifyHSL(color, h, s, l) {
	        color = parse(color);

	        if (color) {
	            color = rgba2hsla(color);
	            h != null && (color[0] = clampCssAngle(h));
	            s != null && (color[1] = parseCssFloat(s));
	            l != null && (color[2] = parseCssFloat(l));

	            return stringify(hsla2rgba(color), 'rgba');
	        }
	    }

	    /**
	     * @param {string} color
	     * @param {number=} alpha 0 ~ 1
	     * @return {string} Color string in rgba format.
	     * @memberOf module:zrender/util/color
	     */
	    function modifyAlpha(color, alpha) {
	        color = parse(color);

	        if (color && alpha != null) {
	            color[3] = clampCssFloat(alpha);
	            return stringify(color, 'rgba');
	        }
	    }

	    /**
	     * @param {Array.<number>} arrColor like [12,33,44,0.4]
	     * @param {string} type 'rgba', 'hsva', ...
	     * @return {string} Result color. (If input illegal, return undefined).
	     */
	    function stringify(arrColor, type) {
	        if (!arrColor || !arrColor.length) {
	            return;
	        }
	        var colorStr = arrColor[0] + ',' + arrColor[1] + ',' + arrColor[2];
	        if (type === 'rgba' || type === 'hsva' || type === 'hsla') {
	            colorStr += ',' + arrColor[3];
	        }
	        return type + '(' + colorStr + ')';
	    }

	    module.exports = {
	        parse: parse,
	        lift: lift,
	        toHex: toHex,
	        fastMapToColor: fastMapToColor,
	        mapToColor: mapToColor,
	        modifyHSL: modifyHSL,
	        modifyAlpha: modifyAlpha,
	        stringify: stringify
	    };




/***/ },
/* 32 */
/***/ function(module, exports) {

	// Simple LRU cache use doubly linked list
	// @module zrender/core/LRU


	    /**
	     * Simple double linked list. Compared with array, it has O(1) remove operation.
	     * @constructor
	     */
	    var LinkedList = function () {

	        /**
	         * @type {module:zrender/core/LRU~Entry}
	         */
	        this.head = null;

	        /**
	         * @type {module:zrender/core/LRU~Entry}
	         */
	        this.tail = null;

	        this._len = 0;
	    };

	    var linkedListProto = LinkedList.prototype;
	    /**
	     * Insert a new value at the tail
	     * @param  {} val
	     * @return {module:zrender/core/LRU~Entry}
	     */
	    linkedListProto.insert = function (val) {
	        var entry = new Entry(val);
	        this.insertEntry(entry);
	        return entry;
	    };

	    /**
	     * Insert an entry at the tail
	     * @param  {module:zrender/core/LRU~Entry} entry
	     */
	    linkedListProto.insertEntry = function (entry) {
	        if (!this.head) {
	            this.head = this.tail = entry;
	        }
	        else {
	            this.tail.next = entry;
	            entry.prev = this.tail;
	            entry.next = null;
	            this.tail = entry;
	        }
	        this._len++;
	    };

	    /**
	     * Remove entry.
	     * @param  {module:zrender/core/LRU~Entry} entry
	     */
	    linkedListProto.remove = function (entry) {
	        var prev = entry.prev;
	        var next = entry.next;
	        if (prev) {
	            prev.next = next;
	        }
	        else {
	            // Is head
	            this.head = next;
	        }
	        if (next) {
	            next.prev = prev;
	        }
	        else {
	            // Is tail
	            this.tail = prev;
	        }
	        entry.next = entry.prev = null;
	        this._len--;
	    };

	    /**
	     * @return {number}
	     */
	    linkedListProto.len = function () {
	        return this._len;
	    };

	    /**
	     * Clear list
	     */
	    linkedListProto.clear = function () {
	        this.head = this.tail = null;
	        this._len = 0;
	    };

	    /**
	     * @constructor
	     * @param {} val
	     */
	    var Entry = function (val) {
	        /**
	         * @type {}
	         */
	        this.value = val;

	        /**
	         * @type {module:zrender/core/LRU~Entry}
	         */
	        this.next;

	        /**
	         * @type {module:zrender/core/LRU~Entry}
	         */
	        this.prev;
	    };

	    /**
	     * LRU Cache
	     * @constructor
	     * @alias module:zrender/core/LRU
	     */
	    var LRU = function (maxSize) {

	        this._list = new LinkedList();

	        this._map = {};

	        this._maxSize = maxSize || 10;

	        this._lastRemovedEntry = null;
	    };

	    var LRUProto = LRU.prototype;

	    /**
	     * @param  {string} key
	     * @param  {} value
	     * @return {} Removed value
	     */
	    LRUProto.put = function (key, value) {
	        var list = this._list;
	        var map = this._map;
	        var removed = null;
	        if (map[key] == null) {
	            var len = list.len();
	            // Reuse last removed entry
	            var entry = this._lastRemovedEntry;

	            if (len >= this._maxSize && len > 0) {
	                // Remove the least recently used
	                var leastUsedEntry = list.head;
	                list.remove(leastUsedEntry);
	                delete map[leastUsedEntry.key];

	                removed = leastUsedEntry.value;
	                this._lastRemovedEntry = leastUsedEntry;
	            }

	            if (entry) {
	                entry.value = value;
	            }
	            else {
	                entry = new Entry(value);
	            }
	            entry.key = key;
	            list.insertEntry(entry);
	            map[key] = entry;
	        }

	        return removed;
	    };

	    /**
	     * @param  {string} key
	     * @return {}
	     */
	    LRUProto.get = function (key) {
	        var entry = this._map[key];
	        var list = this._list;
	        if (entry != null) {
	            // Put the latest used entry in the tail
	            if (entry !== list.tail) {
	                list.remove(entry);
	                list.insertEntry(entry);
	            }

	            return entry.value;
	        }
	    };

	    /**
	     * Clear the cache
	     */
	    LRUProto.clear = function () {
	        this._list.clear();
	        this._map = {};
	    };

	    module.exports = LRU;


/***/ },
/* 33 */
/***/ function(module, exports, __webpack_require__) {

	
	        var config = __webpack_require__(34);

	        /**
	         * @exports zrender/tool/log
	         * @author Kener (@Kener-林峰, kener.linfeng@gmail.com)
	         */
	        module.exports = function() {
	            if (config.debugMode === 0) {
	                return;
	            }
	            else if (config.debugMode == 1) {
	                for (var k in arguments) {
	                    throw new Error(arguments[k]);
	                }
	            }
	            else if (config.debugMode > 1) {
	                for (var k in arguments) {
	                    console.log(arguments[k]);
	                }
	            }
	        };

	        /* for debug
	        return function(mes) {
	            document.getElementById('wrong-message').innerHTML =
	                mes + ' ' + (new Date() - 0)
	                + '<br/>'
	                + document.getElementById('wrong-message').innerHTML;
	        };
	        */
	    


/***/ },
/* 34 */
/***/ function(module, exports) {

	
	    var dpr = 1;
	    // If in browser environment
	    if (typeof window !== 'undefined') {
	        dpr = Math.max(window.devicePixelRatio || 1, 1);
	    }
	    /**
	     * config默认配置项
	     * @exports zrender/config
	     * @author Kener (@Kener-林峰, kener.linfeng@gmail.com)
	     */
	    var config = {
	        /**
	         * debug日志选项：catchBrushException为true下有效
	         * 0 : 不生成debug数据，发布用
	         * 1 : 异常抛出，调试用
	         * 2 : 控制台输出，调试用
	         */
	        debugMode: 0,

	        // retina 屏幕优化
	        devicePixelRatio: dpr
	    };
	    module.exports = config;




/***/ },
/* 35 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * Mixin for drawing text in a element bounding rect
	 * @module zrender/mixin/RectText
	 */



	    var textContain = __webpack_require__(8);
	    var BoundingRect = __webpack_require__(9);

	    var tmpRect = new BoundingRect();

	    var RectText = function () {};

	    function parsePercent(value, maxValue) {
	        if (typeof value === 'string') {
	            if (value.lastIndexOf('%') >= 0) {
	                return parseFloat(value) / 100 * maxValue;
	            }
	            return parseFloat(value);
	        }
	        return value;
	    }

	    RectText.prototype = {

	        constructor: RectText,

	        /**
	         * Draw text in a rect with specified position.
	         * @param  {CanvasRenderingContext} ctx
	         * @param  {Object} rect Displayable rect
	         * @return {Object} textRect Alternative precalculated text bounding rect
	         */
	        drawRectText: function (ctx, rect, textRect) {
	            var style = this.style;
	            var text = style.text;
	            // Convert to string
	            text != null && (text += '');
	            if (!text) {
	                return;
	            }

	            // FIXME
	            ctx.save();

	            var x;
	            var y;
	            var textPosition = style.textPosition;
	            var textOffset = style.textOffset;
	            var distance = style.textDistance;
	            var align = style.textAlign;
	            var font = style.textFont || style.font;
	            var baseline = style.textBaseline;
	            var verticalAlign = style.textVerticalAlign;
	            rect = style.textPositionRect || rect;

	            textRect = textRect || textContain.getBoundingRect(text, font, align, baseline);

	            // Transform rect to view space
	            var transform = this.transform;
	            if (!style.textTransform) {
	                if (transform) {
	                    tmpRect.copy(rect);
	                    tmpRect.applyTransform(transform);
	                    rect = tmpRect;
	                }
	            }
	            else {
	                this.setTransform(ctx);
	            }

	            // Text position represented by coord
	            if (textPosition instanceof Array) {
	                // Percent
	                x = rect.x + parsePercent(textPosition[0], rect.width);
	                y = rect.y + parsePercent(textPosition[1], rect.height);
	                align = align || 'left';
	                baseline = baseline || 'top';

	                if (verticalAlign) {
	                    switch (verticalAlign) {
	                        case 'middle':
	                            y -= textRect.height / 2 - textRect.lineHeight / 2;
	                            break;
	                        case 'bottom':
	                            y -= textRect.height - textRect.lineHeight / 2;
	                            break;
	                        default:
	                            y += textRect.lineHeight / 2;
	                    }
	                    // Force bseline to be middle
	                    baseline = 'middle';
	                }
	            }
	            else {
	                var res = textContain.adjustTextPositionOnRect(
	                    textPosition, rect, textRect, distance
	                );
	                x = res.x;
	                y = res.y;
	                // Default align and baseline when has textPosition
	                align = align || res.textAlign;
	                baseline = baseline || res.textBaseline;
	            }

	            if (textOffset) {
	                x += textOffset[0];
	                y += textOffset[1];
	            }

	            // Use canvas default left textAlign. Giving invalid value will cause state not change
	            ctx.textAlign = align || 'left';
	            // Use canvas default alphabetic baseline
	            ctx.textBaseline = baseline || 'alphabetic';

	            var textFill = style.textFill;
	            var textStroke = style.textStroke;
	            textFill && (ctx.fillStyle = textFill);
	            textStroke && (ctx.strokeStyle = textStroke);

	            // TODO Invalid font
	            ctx.font = font || '12px sans-serif';

	            // Text shadow
	            // Always set shadowBlur and shadowOffset to avoid leak from displayable
	            ctx.shadowBlur = style.textShadowBlur;
	            ctx.shadowColor = style.textShadowColor || 'transparent';
	            ctx.shadowOffsetX = style.textShadowOffsetX;
	            ctx.shadowOffsetY = style.textShadowOffsetY;

	            var textLines = text.split('\n');

	            if (style.textRotation) {
	                transform && ctx.translate(transform[4], transform[5]);
	                ctx.rotate(style.textRotation);
	                transform && ctx.translate(-transform[4], -transform[5]);
	            }

	            for (var i = 0; i < textLines.length; i++) {
	                // Fill after stroke so the outline will not cover the main part.
	                textStroke && ctx.strokeText(textLines[i], x, y);
	                textFill && ctx.fillText(textLines[i], x, y);
	                y += textRect.lineHeight;
	            }

	            ctx.restore();
	        }
	    };

	    module.exports = RectText;


/***/ },
/* 36 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	/**
	 * Path 代理，可以在`buildPath`中用于替代`ctx`, 会保存每个path操作的命令到pathCommands属性中
	 * 可以用于 isInsidePath 判断以及获取boundingRect
	 *
	 * @module zrender/core/PathProxy
	 * @author Yi Shen (http://www.github.com/pissang)
	 */

	 // TODO getTotalLength, getPointAtLength


	    var curve = __webpack_require__(37);
	    var vec2 = __webpack_require__(10);
	    var bbox = __webpack_require__(38);
	    var BoundingRect = __webpack_require__(9);
	    var dpr = __webpack_require__(34).devicePixelRatio;

	    var CMD = {
	        M: 1,
	        L: 2,
	        C: 3,
	        Q: 4,
	        A: 5,
	        Z: 6,
	        // Rect
	        R: 7
	    };

	    // var CMD_MEM_SIZE = {
	    //     M: 3,
	    //     L: 3,
	    //     C: 7,
	    //     Q: 5,
	    //     A: 9,
	    //     R: 5,
	    //     Z: 1
	    // };

	    var min = [];
	    var max = [];
	    var min2 = [];
	    var max2 = [];
	    var mathMin = Math.min;
	    var mathMax = Math.max;
	    var mathCos = Math.cos;
	    var mathSin = Math.sin;
	    var mathSqrt = Math.sqrt;
	    var mathAbs = Math.abs;

	    var hasTypedArray = typeof Float32Array != 'undefined';

	    /**
	     * @alias module:zrender/core/PathProxy
	     * @constructor
	     */
	    var PathProxy = function (notSaveData) {

	        this._saveData = !(notSaveData || false);

	        if (this._saveData) {
	            /**
	             * Path data. Stored as flat array
	             * @type {Array.<Object>}
	             */
	            this.data = [];
	        }

	        this._ctx = null;
	    };

	    /**
	     * 快速计算Path包围盒（并不是最小包围盒）
	     * @return {Object}
	     */
	    PathProxy.prototype = {

	        constructor: PathProxy,

	        _xi: 0,
	        _yi: 0,

	        _x0: 0,
	        _y0: 0,
	        // Unit x, Unit y. Provide for avoiding drawing that too short line segment
	        _ux: 0,
	        _uy: 0,

	        _len: 0,

	        _lineDash: null,

	        _dashOffset: 0,

	        _dashIdx: 0,

	        _dashSum: 0,

	        /**
	         * @readOnly
	         */
	        setScale: function (sx, sy) {
	            this._ux = mathAbs(1 / dpr / sx) || 0;
	            this._uy = mathAbs(1 / dpr / sy) || 0;
	        },

	        getContext: function () {
	            return this._ctx;
	        },

	        /**
	         * @param  {CanvasRenderingContext2D} ctx
	         * @return {module:zrender/core/PathProxy}
	         */
	        beginPath: function (ctx) {

	            this._ctx = ctx;

	            ctx && ctx.beginPath();

	            ctx && (this.dpr = ctx.dpr);

	            // Reset
	            if (this._saveData) {
	                this._len = 0;
	            }

	            if (this._lineDash) {
	                this._lineDash = null;

	                this._dashOffset = 0;
	            }

	            return this;
	        },

	        /**
	         * @param  {number} x
	         * @param  {number} y
	         * @return {module:zrender/core/PathProxy}
	         */
	        moveTo: function (x, y) {
	            this.addData(CMD.M, x, y);
	            this._ctx && this._ctx.moveTo(x, y);

	            // x0, y0, xi, yi 是记录在 _dashedXXXXTo 方法中使用
	            // xi, yi 记录当前点, x0, y0 在 closePath 的时候回到起始点。
	            // 有可能在 beginPath 之后直接调用 lineTo，这时候 x0, y0 需要
	            // 在 lineTo 方法中记录，这里先不考虑这种情况，dashed line 也只在 IE10- 中不支持
	            this._x0 = x;
	            this._y0 = y;

	            this._xi = x;
	            this._yi = y;

	            return this;
	        },

	        /**
	         * @param  {number} x
	         * @param  {number} y
	         * @return {module:zrender/core/PathProxy}
	         */
	        lineTo: function (x, y) {
	            var exceedUnit = mathAbs(x - this._xi) > this._ux
	                || mathAbs(y - this._yi) > this._uy
	                // Force draw the first segment
	                || this._len < 5;

	            this.addData(CMD.L, x, y);

	            if (this._ctx && exceedUnit) {
	                this._needsDash() ? this._dashedLineTo(x, y)
	                    : this._ctx.lineTo(x, y);
	            }
	            if (exceedUnit) {
	                this._xi = x;
	                this._yi = y;
	            }

	            return this;
	        },

	        /**
	         * @param  {number} x1
	         * @param  {number} y1
	         * @param  {number} x2
	         * @param  {number} y2
	         * @param  {number} x3
	         * @param  {number} y3
	         * @return {module:zrender/core/PathProxy}
	         */
	        bezierCurveTo: function (x1, y1, x2, y2, x3, y3) {
	            this.addData(CMD.C, x1, y1, x2, y2, x3, y3);
	            if (this._ctx) {
	                this._needsDash() ? this._dashedBezierTo(x1, y1, x2, y2, x3, y3)
	                    : this._ctx.bezierCurveTo(x1, y1, x2, y2, x3, y3);
	            }
	            this._xi = x3;
	            this._yi = y3;
	            return this;
	        },

	        /**
	         * @param  {number} x1
	         * @param  {number} y1
	         * @param  {number} x2
	         * @param  {number} y2
	         * @return {module:zrender/core/PathProxy}
	         */
	        quadraticCurveTo: function (x1, y1, x2, y2) {
	            this.addData(CMD.Q, x1, y1, x2, y2);
	            if (this._ctx) {
	                this._needsDash() ? this._dashedQuadraticTo(x1, y1, x2, y2)
	                    : this._ctx.quadraticCurveTo(x1, y1, x2, y2);
	            }
	            this._xi = x2;
	            this._yi = y2;
	            return this;
	        },

	        /**
	         * @param  {number} cx
	         * @param  {number} cy
	         * @param  {number} r
	         * @param  {number} startAngle
	         * @param  {number} endAngle
	         * @param  {boolean} anticlockwise
	         * @return {module:zrender/core/PathProxy}
	         */
	        arc: function (cx, cy, r, startAngle, endAngle, anticlockwise) {
	            this.addData(
	                CMD.A, cx, cy, r, r, startAngle, endAngle - startAngle, 0, anticlockwise ? 0 : 1
	            );
	            this._ctx && this._ctx.arc(cx, cy, r, startAngle, endAngle, anticlockwise);

	            this._xi = mathCos(endAngle) * r + cx;
	            this._yi = mathSin(endAngle) * r + cx;
	            return this;
	        },

	        // TODO
	        arcTo: function (x1, y1, x2, y2, radius) {
	            if (this._ctx) {
	                this._ctx.arcTo(x1, y1, x2, y2, radius);
	            }
	            return this;
	        },

	        // TODO
	        rect: function (x, y, w, h) {
	            this._ctx && this._ctx.rect(x, y, w, h);
	            this.addData(CMD.R, x, y, w, h);
	            return this;
	        },

	        /**
	         * @return {module:zrender/core/PathProxy}
	         */
	        closePath: function () {
	            this.addData(CMD.Z);

	            var ctx = this._ctx;
	            var x0 = this._x0;
	            var y0 = this._y0;
	            if (ctx) {
	                this._needsDash() && this._dashedLineTo(x0, y0);
	                ctx.closePath();
	            }

	            this._xi = x0;
	            this._yi = y0;
	            return this;
	        },

	        /**
	         * Context 从外部传入，因为有可能是 rebuildPath 完之后再 fill。
	         * stroke 同样
	         * @param {CanvasRenderingContext2D} ctx
	         * @return {module:zrender/core/PathProxy}
	         */
	        fill: function (ctx) {
	            ctx && ctx.fill();
	            this.toStatic();
	        },

	        /**
	         * @param {CanvasRenderingContext2D} ctx
	         * @return {module:zrender/core/PathProxy}
	         */
	        stroke: function (ctx) {
	            ctx && ctx.stroke();
	            this.toStatic();
	        },

	        /**
	         * 必须在其它绘制命令前调用
	         * Must be invoked before all other path drawing methods
	         * @return {module:zrender/core/PathProxy}
	         */
	        setLineDash: function (lineDash) {
	            if (lineDash instanceof Array) {
	                this._lineDash = lineDash;

	                this._dashIdx = 0;

	                var lineDashSum = 0;
	                for (var i = 0; i < lineDash.length; i++) {
	                    lineDashSum += lineDash[i];
	                }
	                this._dashSum = lineDashSum;
	            }
	            return this;
	        },

	        /**
	         * 必须在其它绘制命令前调用
	         * Must be invoked before all other path drawing methods
	         * @return {module:zrender/core/PathProxy}
	         */
	        setLineDashOffset: function (offset) {
	            this._dashOffset = offset;
	            return this;
	        },

	        /**
	         *
	         * @return {boolean}
	         */
	        len: function () {
	            return this._len;
	        },

	        /**
	         * 直接设置 Path 数据
	         */
	        setData: function (data) {

	            var len = data.length;

	            if (! (this.data && this.data.length == len) && hasTypedArray) {
	                this.data = new Float32Array(len);
	            }

	            for (var i = 0; i < len; i++) {
	                this.data[i] = data[i];
	            }

	            this._len = len;
	        },

	        /**
	         * 添加子路径
	         * @param {module:zrender/core/PathProxy|Array.<module:zrender/core/PathProxy>} path
	         */
	        appendPath: function (path) {
	            if (!(path instanceof Array)) {
	                path = [path];
	            }
	            var len = path.length;
	            var appendSize = 0;
	            var offset = this._len;
	            for (var i = 0; i < len; i++) {
	                appendSize += path[i].len();
	            }
	            if (hasTypedArray && (this.data instanceof Float32Array)) {
	                this.data = new Float32Array(offset + appendSize);
	            }
	            for (var i = 0; i < len; i++) {
	                var appendPathData = path[i].data;
	                for (var k = 0; k < appendPathData.length; k++) {
	                    this.data[offset++] = appendPathData[k];
	                }
	            }
	            this._len = offset;
	        },

	        /**
	         * 填充 Path 数据。
	         * 尽量复用而不申明新的数组。大部分图形重绘的指令数据长度都是不变的。
	         */
	        addData: function (cmd) {
	            if (!this._saveData) {
	                return;
	            }

	            var data = this.data;
	            if (this._len + arguments.length > data.length) {
	                // 因为之前的数组已经转换成静态的 Float32Array
	                // 所以不够用时需要扩展一个新的动态数组
	                this._expandData();
	                data = this.data;
	            }
	            for (var i = 0; i < arguments.length; i++) {
	                data[this._len++] = arguments[i];
	            }

	            this._prevCmd = cmd;
	        },

	        _expandData: function () {
	            // Only if data is Float32Array
	            if (!(this.data instanceof Array)) {
	                var newData = [];
	                for (var i = 0; i < this._len; i++) {
	                    newData[i] = this.data[i];
	                }
	                this.data = newData;
	            }
	        },

	        /**
	         * If needs js implemented dashed line
	         * @return {boolean}
	         * @private
	         */
	        _needsDash: function () {
	            return this._lineDash;
	        },

	        _dashedLineTo: function (x1, y1) {
	            var dashSum = this._dashSum;
	            var offset = this._dashOffset;
	            var lineDash = this._lineDash;
	            var ctx = this._ctx;

	            var x0 = this._xi;
	            var y0 = this._yi;
	            var dx = x1 - x0;
	            var dy = y1 - y0;
	            var dist = mathSqrt(dx * dx + dy * dy);
	            var x = x0;
	            var y = y0;
	            var dash;
	            var nDash = lineDash.length;
	            var idx;
	            dx /= dist;
	            dy /= dist;

	            if (offset < 0) {
	                // Convert to positive offset
	                offset = dashSum + offset;
	            }
	            offset %= dashSum;
	            x -= offset * dx;
	            y -= offset * dy;

	            while ((dx > 0 && x <= x1) || (dx < 0 && x >= x1)
	            || (dx == 0 && ((dy > 0 && y <= y1) || (dy < 0 && y >= y1)))) {
	                idx = this._dashIdx;
	                dash = lineDash[idx];
	                x += dx * dash;
	                y += dy * dash;
	                this._dashIdx = (idx + 1) % nDash;
	                // Skip positive offset
	                if ((dx > 0 && x < x0) || (dx < 0 && x > x0) || (dy > 0 && y < y0) || (dy < 0 && y > y0)) {
	                    continue;
	                }
	                ctx[idx % 2 ? 'moveTo' : 'lineTo'](
	                    dx >= 0 ? mathMin(x, x1) : mathMax(x, x1),
	                    dy >= 0 ? mathMin(y, y1) : mathMax(y, y1)
	                );
	            }
	            // Offset for next lineTo
	            dx = x - x1;
	            dy = y - y1;
	            this._dashOffset = -mathSqrt(dx * dx + dy * dy);
	        },

	        // Not accurate dashed line to
	        _dashedBezierTo: function (x1, y1, x2, y2, x3, y3) {
	            var dashSum = this._dashSum;
	            var offset = this._dashOffset;
	            var lineDash = this._lineDash;
	            var ctx = this._ctx;

	            var x0 = this._xi;
	            var y0 = this._yi;
	            var t;
	            var dx;
	            var dy;
	            var cubicAt = curve.cubicAt;
	            var bezierLen = 0;
	            var idx = this._dashIdx;
	            var nDash = lineDash.length;

	            var x;
	            var y;

	            var tmpLen = 0;

	            if (offset < 0) {
	                // Convert to positive offset
	                offset = dashSum + offset;
	            }
	            offset %= dashSum;
	            // Bezier approx length
	            for (t = 0; t < 1; t += 0.1) {
	                dx = cubicAt(x0, x1, x2, x3, t + 0.1)
	                    - cubicAt(x0, x1, x2, x3, t);
	                dy = cubicAt(y0, y1, y2, y3, t + 0.1)
	                    - cubicAt(y0, y1, y2, y3, t);
	                bezierLen += mathSqrt(dx * dx + dy * dy);
	            }

	            // Find idx after add offset
	            for (; idx < nDash; idx++) {
	                tmpLen += lineDash[idx];
	                if (tmpLen > offset) {
	                    break;
	                }
	            }
	            t = (tmpLen - offset) / bezierLen;

	            while (t <= 1) {

	                x = cubicAt(x0, x1, x2, x3, t);
	                y = cubicAt(y0, y1, y2, y3, t);

	                // Use line to approximate dashed bezier
	                // Bad result if dash is long
	                idx % 2 ? ctx.moveTo(x, y)
	                    : ctx.lineTo(x, y);

	                t += lineDash[idx] / bezierLen;

	                idx = (idx + 1) % nDash;
	            }

	            // Finish the last segment and calculate the new offset
	            (idx % 2 !== 0) && ctx.lineTo(x3, y3);
	            dx = x3 - x;
	            dy = y3 - y;
	            this._dashOffset = -mathSqrt(dx * dx + dy * dy);
	        },

	        _dashedQuadraticTo: function (x1, y1, x2, y2) {
	            // Convert quadratic to cubic using degree elevation
	            var x3 = x2;
	            var y3 = y2;
	            x2 = (x2 + 2 * x1) / 3;
	            y2 = (y2 + 2 * y1) / 3;
	            x1 = (this._xi + 2 * x1) / 3;
	            y1 = (this._yi + 2 * y1) / 3;

	            this._dashedBezierTo(x1, y1, x2, y2, x3, y3);
	        },

	        /**
	         * 转成静态的 Float32Array 减少堆内存占用
	         * Convert dynamic array to static Float32Array
	         */
	        toStatic: function () {
	            var data = this.data;
	            if (data instanceof Array) {
	                data.length = this._len;
	                if (hasTypedArray) {
	                    this.data = new Float32Array(data);
	                }
	            }
	        },

	        /**
	         * @return {module:zrender/core/BoundingRect}
	         */
	        getBoundingRect: function () {
	            min[0] = min[1] = min2[0] = min2[1] = Number.MAX_VALUE;
	            max[0] = max[1] = max2[0] = max2[1] = -Number.MAX_VALUE;

	            var data = this.data;
	            var xi = 0;
	            var yi = 0;
	            var x0 = 0;
	            var y0 = 0;

	            for (var i = 0; i < data.length;) {
	                var cmd = data[i++];

	                if (i == 1) {
	                    // 如果第一个命令是 L, C, Q
	                    // 则 previous point 同绘制命令的第一个 point
	                    //
	                    // 第一个命令为 Arc 的情况下会在后面特殊处理
	                    xi = data[i];
	                    yi = data[i + 1];

	                    x0 = xi;
	                    y0 = yi;
	                }

	                switch (cmd) {
	                    case CMD.M:
	                        // moveTo 命令重新创建一个新的 subpath, 并且更新新的起点
	                        // 在 closePath 的时候使用
	                        x0 = data[i++];
	                        y0 = data[i++];
	                        xi = x0;
	                        yi = y0;
	                        min2[0] = x0;
	                        min2[1] = y0;
	                        max2[0] = x0;
	                        max2[1] = y0;
	                        break;
	                    case CMD.L:
	                        bbox.fromLine(xi, yi, data[i], data[i + 1], min2, max2);
	                        xi = data[i++];
	                        yi = data[i++];
	                        break;
	                    case CMD.C:
	                        bbox.fromCubic(
	                            xi, yi, data[i++], data[i++], data[i++], data[i++], data[i], data[i + 1],
	                            min2, max2
	                        );
	                        xi = data[i++];
	                        yi = data[i++];
	                        break;
	                    case CMD.Q:
	                        bbox.fromQuadratic(
	                            xi, yi, data[i++], data[i++], data[i], data[i + 1],
	                            min2, max2
	                        );
	                        xi = data[i++];
	                        yi = data[i++];
	                        break;
	                    case CMD.A:
	                        // TODO Arc 判断的开销比较大
	                        var cx = data[i++];
	                        var cy = data[i++];
	                        var rx = data[i++];
	                        var ry = data[i++];
	                        var startAngle = data[i++];
	                        var endAngle = data[i++] + startAngle;
	                        // TODO Arc 旋转
	                        var psi = data[i++];
	                        var anticlockwise = 1 - data[i++];

	                        if (i == 1) {
	                            // 直接使用 arc 命令
	                            // 第一个命令起点还未定义
	                            x0 = mathCos(startAngle) * rx + cx;
	                            y0 = mathSin(startAngle) * ry + cy;
	                        }

	                        bbox.fromArc(
	                            cx, cy, rx, ry, startAngle, endAngle,
	                            anticlockwise, min2, max2
	                        );

	                        xi = mathCos(endAngle) * rx + cx;
	                        yi = mathSin(endAngle) * ry + cy;
	                        break;
	                    case CMD.R:
	                        x0 = xi = data[i++];
	                        y0 = yi = data[i++];
	                        var width = data[i++];
	                        var height = data[i++];
	                        // Use fromLine
	                        bbox.fromLine(x0, y0, x0 + width, y0 + height, min2, max2);
	                        break;
	                    case CMD.Z:
	                        xi = x0;
	                        yi = y0;
	                        break;
	                }

	                // Union
	                vec2.min(min, min, min2);
	                vec2.max(max, max, max2);
	            }

	            // No data
	            if (i === 0) {
	                min[0] = min[1] = max[0] = max[1] = 0;
	            }

	            return new BoundingRect(
	                min[0], min[1], max[0] - min[0], max[1] - min[1]
	            );
	        },

	        /**
	         * Rebuild path from current data
	         * Rebuild path will not consider javascript implemented line dash.
	         * @param {CanvasRenderingContext} ctx
	         */
	        rebuildPath: function (ctx) {
	            var d = this.data;
	            var x0, y0;
	            var xi, yi;
	            var x, y;
	            var ux = this._ux;
	            var uy = this._uy;
	            var len = this._len;
	            for (var i = 0; i < len;) {
	                var cmd = d[i++];

	                if (i == 1) {
	                    // 如果第一个命令是 L, C, Q
	                    // 则 previous point 同绘制命令的第一个 point
	                    //
	                    // 第一个命令为 Arc 的情况下会在后面特殊处理
	                    xi = d[i];
	                    yi = d[i + 1];

	                    x0 = xi;
	                    y0 = yi;
	                }
	                switch (cmd) {
	                    case CMD.M:
	                        x0 = xi = d[i++];
	                        y0 = yi = d[i++];
	                        ctx.moveTo(xi, yi);
	                        break;
	                    case CMD.L:
	                        x = d[i++];
	                        y = d[i++];
	                        // Not draw too small seg between
	                        if (mathAbs(x - xi) > ux || mathAbs(y - yi) > uy || i === len - 1) {
	                            ctx.lineTo(x, y);
	                            xi = x;
	                            yi = y;
	                        }
	                        break;
	                    case CMD.C:
	                        ctx.bezierCurveTo(
	                            d[i++], d[i++], d[i++], d[i++], d[i++], d[i++]
	                        );
	                        xi = d[i - 2];
	                        yi = d[i - 1];
	                        break;
	                    case CMD.Q:
	                        ctx.quadraticCurveTo(d[i++], d[i++], d[i++], d[i++]);
	                        xi = d[i - 2];
	                        yi = d[i - 1];
	                        break;
	                    case CMD.A:
	                        var cx = d[i++];
	                        var cy = d[i++];
	                        var rx = d[i++];
	                        var ry = d[i++];
	                        var theta = d[i++];
	                        var dTheta = d[i++];
	                        var psi = d[i++];
	                        var fs = d[i++];
	                        var r = (rx > ry) ? rx : ry;
	                        var scaleX = (rx > ry) ? 1 : rx / ry;
	                        var scaleY = (rx > ry) ? ry / rx : 1;
	                        var isEllipse = Math.abs(rx - ry) > 1e-3;
	                        var endAngle = theta + dTheta;
	                        if (isEllipse) {
	                            ctx.translate(cx, cy);
	                            ctx.rotate(psi);
	                            ctx.scale(scaleX, scaleY);
	                            ctx.arc(0, 0, r, theta, endAngle, 1 - fs);
	                            ctx.scale(1 / scaleX, 1 / scaleY);
	                            ctx.rotate(-psi);
	                            ctx.translate(-cx, -cy);
	                        }
	                        else {
	                            ctx.arc(cx, cy, r, theta, endAngle, 1 - fs);
	                        }

	                        if (i == 1) {
	                            // 直接使用 arc 命令
	                            // 第一个命令起点还未定义
	                            x0 = mathCos(theta) * rx + cx;
	                            y0 = mathSin(theta) * ry + cy;
	                        }
	                        xi = mathCos(endAngle) * rx + cx;
	                        yi = mathSin(endAngle) * ry + cy;
	                        break;
	                    case CMD.R:
	                        x0 = xi = d[i];
	                        y0 = yi = d[i + 1];
	                        ctx.rect(d[i++], d[i++], d[i++], d[i++]);
	                        break;
	                    case CMD.Z:
	                        ctx.closePath();
	                        xi = x0;
	                        yi = y0;
	                }
	            }
	        }
	    };

	    PathProxy.CMD = CMD;

	    module.exports = PathProxy;


/***/ },
/* 37 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	/**
	 * 曲线辅助模块
	 * @module zrender/core/curve
	 * @author pissang(https://www.github.com/pissang)
	 */


	    var vec2 = __webpack_require__(10);
	    var v2Create = vec2.create;
	    var v2DistSquare = vec2.distSquare;
	    var mathPow = Math.pow;
	    var mathSqrt = Math.sqrt;

	    var EPSILON = 1e-8;
	    var EPSILON_NUMERIC = 1e-4;

	    var THREE_SQRT = mathSqrt(3);
	    var ONE_THIRD = 1 / 3;

	    // 临时变量
	    var _v0 = v2Create();
	    var _v1 = v2Create();
	    var _v2 = v2Create();
	    // var _v3 = vec2.create();

	    function isAroundZero(val) {
	        return val > -EPSILON && val < EPSILON;
	    }
	    function isNotAroundZero(val) {
	        return val > EPSILON || val < -EPSILON;
	    }
	    /**
	     * 计算三次贝塞尔值
	     * @memberOf module:zrender/core/curve
	     * @param  {number} p0
	     * @param  {number} p1
	     * @param  {number} p2
	     * @param  {number} p3
	     * @param  {number} t
	     * @return {number}
	     */
	    function cubicAt(p0, p1, p2, p3, t) {
	        var onet = 1 - t;
	        return onet * onet * (onet * p0 + 3 * t * p1)
	             + t * t * (t * p3 + 3 * onet * p2);
	    }

	    /**
	     * 计算三次贝塞尔导数值
	     * @memberOf module:zrender/core/curve
	     * @param  {number} p0
	     * @param  {number} p1
	     * @param  {number} p2
	     * @param  {number} p3
	     * @param  {number} t
	     * @return {number}
	     */
	    function cubicDerivativeAt(p0, p1, p2, p3, t) {
	        var onet = 1 - t;
	        return 3 * (
	            ((p1 - p0) * onet + 2 * (p2 - p1) * t) * onet
	            + (p3 - p2) * t * t
	        );
	    }

	    /**
	     * 计算三次贝塞尔方程根，使用盛金公式
	     * @memberOf module:zrender/core/curve
	     * @param  {number} p0
	     * @param  {number} p1
	     * @param  {number} p2
	     * @param  {number} p3
	     * @param  {number} val
	     * @param  {Array.<number>} roots
	     * @return {number} 有效根数目
	     */
	    function cubicRootAt(p0, p1, p2, p3, val, roots) {
	        // Evaluate roots of cubic functions
	        var a = p3 + 3 * (p1 - p2) - p0;
	        var b = 3 * (p2 - p1 * 2 + p0);
	        var c = 3 * (p1  - p0);
	        var d = p0 - val;

	        var A = b * b - 3 * a * c;
	        var B = b * c - 9 * a * d;
	        var C = c * c - 3 * b * d;

	        var n = 0;

	        if (isAroundZero(A) && isAroundZero(B)) {
	            if (isAroundZero(b)) {
	                roots[0] = 0;
	            }
	            else {
	                var t1 = -c / b;  //t1, t2, t3, b is not zero
	                if (t1 >= 0 && t1 <= 1) {
	                    roots[n++] = t1;
	                }
	            }
	        }
	        else {
	            var disc = B * B - 4 * A * C;

	            if (isAroundZero(disc)) {
	                var K = B / A;
	                var t1 = -b / a + K;  // t1, a is not zero
	                var t2 = -K / 2;  // t2, t3
	                if (t1 >= 0 && t1 <= 1) {
	                    roots[n++] = t1;
	                }
	                if (t2 >= 0 && t2 <= 1) {
	                    roots[n++] = t2;
	                }
	            }
	            else if (disc > 0) {
	                var discSqrt = mathSqrt(disc);
	                var Y1 = A * b + 1.5 * a * (-B + discSqrt);
	                var Y2 = A * b + 1.5 * a * (-B - discSqrt);
	                if (Y1 < 0) {
	                    Y1 = -mathPow(-Y1, ONE_THIRD);
	                }
	                else {
	                    Y1 = mathPow(Y1, ONE_THIRD);
	                }
	                if (Y2 < 0) {
	                    Y2 = -mathPow(-Y2, ONE_THIRD);
	                }
	                else {
	                    Y2 = mathPow(Y2, ONE_THIRD);
	                }
	                var t1 = (-b - (Y1 + Y2)) / (3 * a);
	                if (t1 >= 0 && t1 <= 1) {
	                    roots[n++] = t1;
	                }
	            }
	            else {
	                var T = (2 * A * b - 3 * a * B) / (2 * mathSqrt(A * A * A));
	                var theta = Math.acos(T) / 3;
	                var ASqrt = mathSqrt(A);
	                var tmp = Math.cos(theta);

	                var t1 = (-b - 2 * ASqrt * tmp) / (3 * a);
	                var t2 = (-b + ASqrt * (tmp + THREE_SQRT * Math.sin(theta))) / (3 * a);
	                var t3 = (-b + ASqrt * (tmp - THREE_SQRT * Math.sin(theta))) / (3 * a);
	                if (t1 >= 0 && t1 <= 1) {
	                    roots[n++] = t1;
	                }
	                if (t2 >= 0 && t2 <= 1) {
	                    roots[n++] = t2;
	                }
	                if (t3 >= 0 && t3 <= 1) {
	                    roots[n++] = t3;
	                }
	            }
	        }
	        return n;
	    }

	    /**
	     * 计算三次贝塞尔方程极限值的位置
	     * @memberOf module:zrender/core/curve
	     * @param  {number} p0
	     * @param  {number} p1
	     * @param  {number} p2
	     * @param  {number} p3
	     * @param  {Array.<number>} extrema
	     * @return {number} 有效数目
	     */
	    function cubicExtrema(p0, p1, p2, p3, extrema) {
	        var b = 6 * p2 - 12 * p1 + 6 * p0;
	        var a = 9 * p1 + 3 * p3 - 3 * p0 - 9 * p2;
	        var c = 3 * p1 - 3 * p0;

	        var n = 0;
	        if (isAroundZero(a)) {
	            if (isNotAroundZero(b)) {
	                var t1 = -c / b;
	                if (t1 >= 0 && t1 <=1) {
	                    extrema[n++] = t1;
	                }
	            }
	        }
	        else {
	            var disc = b * b - 4 * a * c;
	            if (isAroundZero(disc)) {
	                extrema[0] = -b / (2 * a);
	            }
	            else if (disc > 0) {
	                var discSqrt = mathSqrt(disc);
	                var t1 = (-b + discSqrt) / (2 * a);
	                var t2 = (-b - discSqrt) / (2 * a);
	                if (t1 >= 0 && t1 <= 1) {
	                    extrema[n++] = t1;
	                }
	                if (t2 >= 0 && t2 <= 1) {
	                    extrema[n++] = t2;
	                }
	            }
	        }
	        return n;
	    }

	    /**
	     * 细分三次贝塞尔曲线
	     * @memberOf module:zrender/core/curve
	     * @param  {number} p0
	     * @param  {number} p1
	     * @param  {number} p2
	     * @param  {number} p3
	     * @param  {number} t
	     * @param  {Array.<number>} out
	     */
	    function cubicSubdivide(p0, p1, p2, p3, t, out) {
	        var p01 = (p1 - p0) * t + p0;
	        var p12 = (p2 - p1) * t + p1;
	        var p23 = (p3 - p2) * t + p2;

	        var p012 = (p12 - p01) * t + p01;
	        var p123 = (p23 - p12) * t + p12;

	        var p0123 = (p123 - p012) * t + p012;
	        // Seg0
	        out[0] = p0;
	        out[1] = p01;
	        out[2] = p012;
	        out[3] = p0123;
	        // Seg1
	        out[4] = p0123;
	        out[5] = p123;
	        out[6] = p23;
	        out[7] = p3;
	    }

	    /**
	     * 投射点到三次贝塞尔曲线上，返回投射距离。
	     * 投射点有可能会有一个或者多个，这里只返回其中距离最短的一个。
	     * @param {number} x0
	     * @param {number} y0
	     * @param {number} x1
	     * @param {number} y1
	     * @param {number} x2
	     * @param {number} y2
	     * @param {number} x3
	     * @param {number} y3
	     * @param {number} x
	     * @param {number} y
	     * @param {Array.<number>} [out] 投射点
	     * @return {number}
	     */
	    function cubicProjectPoint(
	        x0, y0, x1, y1, x2, y2, x3, y3,
	        x, y, out
	    ) {
	        // http://pomax.github.io/bezierinfo/#projections
	        var t;
	        var interval = 0.005;
	        var d = Infinity;
	        var prev;
	        var next;
	        var d1;
	        var d2;

	        _v0[0] = x;
	        _v0[1] = y;

	        // 先粗略估计一下可能的最小距离的 t 值
	        // PENDING
	        for (var _t = 0; _t < 1; _t += 0.05) {
	            _v1[0] = cubicAt(x0, x1, x2, x3, _t);
	            _v1[1] = cubicAt(y0, y1, y2, y3, _t);
	            d1 = v2DistSquare(_v0, _v1);
	            if (d1 < d) {
	                t = _t;
	                d = d1;
	            }
	        }
	        d = Infinity;

	        // At most 32 iteration
	        for (var i = 0; i < 32; i++) {
	            if (interval < EPSILON_NUMERIC) {
	                break;
	            }
	            prev = t - interval;
	            next = t + interval;
	            // t - interval
	            _v1[0] = cubicAt(x0, x1, x2, x3, prev);
	            _v1[1] = cubicAt(y0, y1, y2, y3, prev);

	            d1 = v2DistSquare(_v1, _v0);

	            if (prev >= 0 && d1 < d) {
	                t = prev;
	                d = d1;
	            }
	            else {
	                // t + interval
	                _v2[0] = cubicAt(x0, x1, x2, x3, next);
	                _v2[1] = cubicAt(y0, y1, y2, y3, next);
	                d2 = v2DistSquare(_v2, _v0);

	                if (next <= 1 && d2 < d) {
	                    t = next;
	                    d = d2;
	                }
	                else {
	                    interval *= 0.5;
	                }
	            }
	        }
	        // t
	        if (out) {
	            out[0] = cubicAt(x0, x1, x2, x3, t);
	            out[1] = cubicAt(y0, y1, y2, y3, t);
	        }
	        // console.log(interval, i);
	        return mathSqrt(d);
	    }

	    /**
	     * 计算二次方贝塞尔值
	     * @param  {number} p0
	     * @param  {number} p1
	     * @param  {number} p2
	     * @param  {number} t
	     * @return {number}
	     */
	    function quadraticAt(p0, p1, p2, t) {
	        var onet = 1 - t;
	        return onet * (onet * p0 + 2 * t * p1) + t * t * p2;
	    }

	    /**
	     * 计算二次方贝塞尔导数值
	     * @param  {number} p0
	     * @param  {number} p1
	     * @param  {number} p2
	     * @param  {number} t
	     * @return {number}
	     */
	    function quadraticDerivativeAt(p0, p1, p2, t) {
	        return 2 * ((1 - t) * (p1 - p0) + t * (p2 - p1));
	    }

	    /**
	     * 计算二次方贝塞尔方程根
	     * @param  {number} p0
	     * @param  {number} p1
	     * @param  {number} p2
	     * @param  {number} t
	     * @param  {Array.<number>} roots
	     * @return {number} 有效根数目
	     */
	    function quadraticRootAt(p0, p1, p2, val, roots) {
	        var a = p0 - 2 * p1 + p2;
	        var b = 2 * (p1 - p0);
	        var c = p0 - val;

	        var n = 0;
	        if (isAroundZero(a)) {
	            if (isNotAroundZero(b)) {
	                var t1 = -c / b;
	                if (t1 >= 0 && t1 <= 1) {
	                    roots[n++] = t1;
	                }
	            }
	        }
	        else {
	            var disc = b * b - 4 * a * c;
	            if (isAroundZero(disc)) {
	                var t1 = -b / (2 * a);
	                if (t1 >= 0 && t1 <= 1) {
	                    roots[n++] = t1;
	                }
	            }
	            else if (disc > 0) {
	                var discSqrt = mathSqrt(disc);
	                var t1 = (-b + discSqrt) / (2 * a);
	                var t2 = (-b - discSqrt) / (2 * a);
	                if (t1 >= 0 && t1 <= 1) {
	                    roots[n++] = t1;
	                }
	                if (t2 >= 0 && t2 <= 1) {
	                    roots[n++] = t2;
	                }
	            }
	        }
	        return n;
	    }

	    /**
	     * 计算二次贝塞尔方程极限值
	     * @memberOf module:zrender/core/curve
	     * @param  {number} p0
	     * @param  {number} p1
	     * @param  {number} p2
	     * @return {number}
	     */
	    function quadraticExtremum(p0, p1, p2) {
	        var divider = p0 + p2 - 2 * p1;
	        if (divider === 0) {
	            // p1 is center of p0 and p2
	            return 0.5;
	        }
	        else {
	            return (p0 - p1) / divider;
	        }
	    }

	    /**
	     * 细分二次贝塞尔曲线
	     * @memberOf module:zrender/core/curve
	     * @param  {number} p0
	     * @param  {number} p1
	     * @param  {number} p2
	     * @param  {number} t
	     * @param  {Array.<number>} out
	     */
	    function quadraticSubdivide(p0, p1, p2, t, out) {
	        var p01 = (p1 - p0) * t + p0;
	        var p12 = (p2 - p1) * t + p1;
	        var p012 = (p12 - p01) * t + p01;

	        // Seg0
	        out[0] = p0;
	        out[1] = p01;
	        out[2] = p012;

	        // Seg1
	        out[3] = p012;
	        out[4] = p12;
	        out[5] = p2;
	    }

	    /**
	     * 投射点到二次贝塞尔曲线上，返回投射距离。
	     * 投射点有可能会有一个或者多个，这里只返回其中距离最短的一个。
	     * @param {number} x0
	     * @param {number} y0
	     * @param {number} x1
	     * @param {number} y1
	     * @param {number} x2
	     * @param {number} y2
	     * @param {number} x
	     * @param {number} y
	     * @param {Array.<number>} out 投射点
	     * @return {number}
	     */
	    function quadraticProjectPoint(
	        x0, y0, x1, y1, x2, y2,
	        x, y, out
	    ) {
	        // http://pomax.github.io/bezierinfo/#projections
	        var t;
	        var interval = 0.005;
	        var d = Infinity;

	        _v0[0] = x;
	        _v0[1] = y;

	        // 先粗略估计一下可能的最小距离的 t 值
	        // PENDING
	        for (var _t = 0; _t < 1; _t += 0.05) {
	            _v1[0] = quadraticAt(x0, x1, x2, _t);
	            _v1[1] = quadraticAt(y0, y1, y2, _t);
	            var d1 = v2DistSquare(_v0, _v1);
	            if (d1 < d) {
	                t = _t;
	                d = d1;
	            }
	        }
	        d = Infinity;

	        // At most 32 iteration
	        for (var i = 0; i < 32; i++) {
	            if (interval < EPSILON_NUMERIC) {
	                break;
	            }
	            var prev = t - interval;
	            var next = t + interval;
	            // t - interval
	            _v1[0] = quadraticAt(x0, x1, x2, prev);
	            _v1[1] = quadraticAt(y0, y1, y2, prev);

	            var d1 = v2DistSquare(_v1, _v0);

	            if (prev >= 0 && d1 < d) {
	                t = prev;
	                d = d1;
	            }
	            else {
	                // t + interval
	                _v2[0] = quadraticAt(x0, x1, x2, next);
	                _v2[1] = quadraticAt(y0, y1, y2, next);
	                var d2 = v2DistSquare(_v2, _v0);
	                if (next <= 1 && d2 < d) {
	                    t = next;
	                    d = d2;
	                }
	                else {
	                    interval *= 0.5;
	                }
	            }
	        }
	        // t
	        if (out) {
	            out[0] = quadraticAt(x0, x1, x2, t);
	            out[1] = quadraticAt(y0, y1, y2, t);
	        }
	        // console.log(interval, i);
	        return mathSqrt(d);
	    }

	    module.exports = {

	        cubicAt: cubicAt,

	        cubicDerivativeAt: cubicDerivativeAt,

	        cubicRootAt: cubicRootAt,

	        cubicExtrema: cubicExtrema,

	        cubicSubdivide: cubicSubdivide,

	        cubicProjectPoint: cubicProjectPoint,

	        quadraticAt: quadraticAt,

	        quadraticDerivativeAt: quadraticDerivativeAt,

	        quadraticRootAt: quadraticRootAt,

	        quadraticExtremum: quadraticExtremum,

	        quadraticSubdivide: quadraticSubdivide,

	        quadraticProjectPoint: quadraticProjectPoint
	    };


/***/ },
/* 38 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @author Yi Shen(https://github.com/pissang)
	 */


	    var vec2 = __webpack_require__(10);
	    var curve = __webpack_require__(37);

	    var bbox = {};
	    var mathMin = Math.min;
	    var mathMax = Math.max;
	    var mathSin = Math.sin;
	    var mathCos = Math.cos;

	    var start = vec2.create();
	    var end = vec2.create();
	    var extremity = vec2.create();

	    var PI2 = Math.PI * 2;
	    /**
	     * 从顶点数组中计算出最小包围盒，写入`min`和`max`中
	     * @module zrender/core/bbox
	     * @param {Array<Object>} points 顶点数组
	     * @param {number} min
	     * @param {number} max
	     */
	    bbox.fromPoints = function(points, min, max) {
	        if (points.length === 0) {
	            return;
	        }
	        var p = points[0];
	        var left = p[0];
	        var right = p[0];
	        var top = p[1];
	        var bottom = p[1];
	        var i;

	        for (i = 1; i < points.length; i++) {
	            p = points[i];
	            left = mathMin(left, p[0]);
	            right = mathMax(right, p[0]);
	            top = mathMin(top, p[1]);
	            bottom = mathMax(bottom, p[1]);
	        }

	        min[0] = left;
	        min[1] = top;
	        max[0] = right;
	        max[1] = bottom;
	    };

	    /**
	     * @memberOf module:zrender/core/bbox
	     * @param {number} x0
	     * @param {number} y0
	     * @param {number} x1
	     * @param {number} y1
	     * @param {Array.<number>} min
	     * @param {Array.<number>} max
	     */
	    bbox.fromLine = function (x0, y0, x1, y1, min, max) {
	        min[0] = mathMin(x0, x1);
	        min[1] = mathMin(y0, y1);
	        max[0] = mathMax(x0, x1);
	        max[1] = mathMax(y0, y1);
	    };

	    var xDim = [];
	    var yDim = [];
	    /**
	     * 从三阶贝塞尔曲线(p0, p1, p2, p3)中计算出最小包围盒，写入`min`和`max`中
	     * @memberOf module:zrender/core/bbox
	     * @param {number} x0
	     * @param {number} y0
	     * @param {number} x1
	     * @param {number} y1
	     * @param {number} x2
	     * @param {number} y2
	     * @param {number} x3
	     * @param {number} y3
	     * @param {Array.<number>} min
	     * @param {Array.<number>} max
	     */
	    bbox.fromCubic = function(
	        x0, y0, x1, y1, x2, y2, x3, y3, min, max
	    ) {
	        var cubicExtrema = curve.cubicExtrema;
	        var cubicAt = curve.cubicAt;
	        var i;
	        var n = cubicExtrema(x0, x1, x2, x3, xDim);
	        min[0] = Infinity;
	        min[1] = Infinity;
	        max[0] = -Infinity;
	        max[1] = -Infinity;

	        for (i = 0; i < n; i++) {
	            var x = cubicAt(x0, x1, x2, x3, xDim[i]);
	            min[0] = mathMin(x, min[0]);
	            max[0] = mathMax(x, max[0]);
	        }
	        n = cubicExtrema(y0, y1, y2, y3, yDim);
	        for (i = 0; i < n; i++) {
	            var y = cubicAt(y0, y1, y2, y3, yDim[i]);
	            min[1] = mathMin(y, min[1]);
	            max[1] = mathMax(y, max[1]);
	        }

	        min[0] = mathMin(x0, min[0]);
	        max[0] = mathMax(x0, max[0]);
	        min[0] = mathMin(x3, min[0]);
	        max[0] = mathMax(x3, max[0]);

	        min[1] = mathMin(y0, min[1]);
	        max[1] = mathMax(y0, max[1]);
	        min[1] = mathMin(y3, min[1]);
	        max[1] = mathMax(y3, max[1]);
	    };

	    /**
	     * 从二阶贝塞尔曲线(p0, p1, p2)中计算出最小包围盒，写入`min`和`max`中
	     * @memberOf module:zrender/core/bbox
	     * @param {number} x0
	     * @param {number} y0
	     * @param {number} x1
	     * @param {number} y1
	     * @param {number} x2
	     * @param {number} y2
	     * @param {Array.<number>} min
	     * @param {Array.<number>} max
	     */
	    bbox.fromQuadratic = function(x0, y0, x1, y1, x2, y2, min, max) {
	        var quadraticExtremum = curve.quadraticExtremum;
	        var quadraticAt = curve.quadraticAt;
	        // Find extremities, where derivative in x dim or y dim is zero
	        var tx =
	            mathMax(
	                mathMin(quadraticExtremum(x0, x1, x2), 1), 0
	            );
	        var ty =
	            mathMax(
	                mathMin(quadraticExtremum(y0, y1, y2), 1), 0
	            );

	        var x = quadraticAt(x0, x1, x2, tx);
	        var y = quadraticAt(y0, y1, y2, ty);

	        min[0] = mathMin(x0, x2, x);
	        min[1] = mathMin(y0, y2, y);
	        max[0] = mathMax(x0, x2, x);
	        max[1] = mathMax(y0, y2, y);
	    };

	    /**
	     * 从圆弧中计算出最小包围盒，写入`min`和`max`中
	     * @method
	     * @memberOf module:zrender/core/bbox
	     * @param {number} x
	     * @param {number} y
	     * @param {number} rx
	     * @param {number} ry
	     * @param {number} startAngle
	     * @param {number} endAngle
	     * @param {number} anticlockwise
	     * @param {Array.<number>} min
	     * @param {Array.<number>} max
	     */
	    bbox.fromArc = function (
	        x, y, rx, ry, startAngle, endAngle, anticlockwise, min, max
	    ) {
	        var vec2Min = vec2.min;
	        var vec2Max = vec2.max;

	        var diff = Math.abs(startAngle - endAngle);


	        if (diff % PI2 < 1e-4 && diff > 1e-4) {
	            // Is a circle
	            min[0] = x - rx;
	            min[1] = y - ry;
	            max[0] = x + rx;
	            max[1] = y + ry;
	            return;
	        }

	        start[0] = mathCos(startAngle) * rx + x;
	        start[1] = mathSin(startAngle) * ry + y;

	        end[0] = mathCos(endAngle) * rx + x;
	        end[1] = mathSin(endAngle) * ry + y;

	        vec2Min(min, start, end);
	        vec2Max(max, start, end);

	        // Thresh to [0, Math.PI * 2]
	        startAngle = startAngle % (PI2);
	        if (startAngle < 0) {
	            startAngle = startAngle + PI2;
	        }
	        endAngle = endAngle % (PI2);
	        if (endAngle < 0) {
	            endAngle = endAngle + PI2;
	        }

	        if (startAngle > endAngle && !anticlockwise) {
	            endAngle += PI2;
	        }
	        else if (startAngle < endAngle && anticlockwise) {
	            startAngle += PI2;
	        }
	        if (anticlockwise) {
	            var tmp = endAngle;
	            endAngle = startAngle;
	            startAngle = tmp;
	        }

	        // var number = 0;
	        // var step = (anticlockwise ? -Math.PI : Math.PI) / 2;
	        for (var angle = 0; angle < endAngle; angle += Math.PI / 2) {
	            if (angle > startAngle) {
	                extremity[0] = mathCos(angle) * rx + x;
	                extremity[1] = mathSin(angle) * ry + y;

	                vec2Min(min, extremity, min);
	                vec2Max(max, extremity, max);
	            }
	        }
	    };

	    module.exports = bbox;



/***/ },
/* 39 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var CMD = __webpack_require__(36).CMD;
	    var line = __webpack_require__(40);
	    var cubic = __webpack_require__(41);
	    var quadratic = __webpack_require__(42);
	    var arc = __webpack_require__(43);
	    var normalizeRadian = __webpack_require__(44).normalizeRadian;
	    var curve = __webpack_require__(37);

	    var windingLine = __webpack_require__(45);

	    var containStroke = line.containStroke;

	    var PI2 = Math.PI * 2;

	    var EPSILON = 1e-4;

	    function isAroundEqual(a, b) {
	        return Math.abs(a - b) < EPSILON;
	    }

	    // 临时数组
	    var roots = [-1, -1, -1];
	    var extrema = [-1, -1];

	    function swapExtrema() {
	        var tmp = extrema[0];
	        extrema[0] = extrema[1];
	        extrema[1] = tmp;
	    }

	    function windingCubic(x0, y0, x1, y1, x2, y2, x3, y3, x, y) {
	        // Quick reject
	        if (
	            (y > y0 && y > y1 && y > y2 && y > y3)
	            || (y < y0 && y < y1 && y < y2 && y < y3)
	        ) {
	            return 0;
	        }
	        var nRoots = curve.cubicRootAt(y0, y1, y2, y3, y, roots);
	        if (nRoots === 0) {
	            return 0;
	        }
	        else {
	            var w = 0;
	            var nExtrema = -1;
	            var y0_, y1_;
	            for (var i = 0; i < nRoots; i++) {
	                var t = roots[i];

	                // Avoid winding error when intersection point is the connect point of two line of polygon
	                var unit = (t === 0 || t === 1) ? 0.5 : 1;

	                var x_ = curve.cubicAt(x0, x1, x2, x3, t);
	                if (x_ < x) { // Quick reject
	                    continue;
	                }
	                if (nExtrema < 0) {
	                    nExtrema = curve.cubicExtrema(y0, y1, y2, y3, extrema);
	                    if (extrema[1] < extrema[0] && nExtrema > 1) {
	                        swapExtrema();
	                    }
	                    y0_ = curve.cubicAt(y0, y1, y2, y3, extrema[0]);
	                    if (nExtrema > 1) {
	                        y1_ = curve.cubicAt(y0, y1, y2, y3, extrema[1]);
	                    }
	                }
	                if (nExtrema == 2) {
	                    // 分成三段单调函数
	                    if (t < extrema[0]) {
	                        w += y0_ < y0 ? unit : -unit;
	                    }
	                    else if (t < extrema[1]) {
	                        w += y1_ < y0_ ? unit : -unit;
	                    }
	                    else {
	                        w += y3 < y1_ ? unit : -unit;
	                    }
	                }
	                else {
	                    // 分成两段单调函数
	                    if (t < extrema[0]) {
	                        w += y0_ < y0 ? unit : -unit;
	                    }
	                    else {
	                        w += y3 < y0_ ? unit : -unit;
	                    }
	                }
	            }
	            return w;
	        }
	    }

	    function windingQuadratic(x0, y0, x1, y1, x2, y2, x, y) {
	        // Quick reject
	        if (
	            (y > y0 && y > y1 && y > y2)
	            || (y < y0 && y < y1 && y < y2)
	        ) {
	            return 0;
	        }
	        var nRoots = curve.quadraticRootAt(y0, y1, y2, y, roots);
	        if (nRoots === 0) {
	            return 0;
	        }
	        else {
	            var t = curve.quadraticExtremum(y0, y1, y2);
	            if (t >= 0 && t <= 1) {
	                var w = 0;
	                var y_ = curve.quadraticAt(y0, y1, y2, t);
	                for (var i = 0; i < nRoots; i++) {
	                    // Remove one endpoint.
	                    var unit = (roots[i] === 0 || roots[i] === 1) ? 0.5 : 1;

	                    var x_ = curve.quadraticAt(x0, x1, x2, roots[i]);
	                    if (x_ < x) {   // Quick reject
	                        continue;
	                    }
	                    if (roots[i] < t) {
	                        w += y_ < y0 ? unit : -unit;
	                    }
	                    else {
	                        w += y2 < y_ ? unit : -unit;
	                    }
	                }
	                return w;
	            }
	            else {
	                // Remove one endpoint.
	                var unit = (roots[0] === 0 || roots[0] === 1) ? 0.5 : 1;

	                var x_ = curve.quadraticAt(x0, x1, x2, roots[0]);
	                if (x_ < x) {   // Quick reject
	                    return 0;
	                }
	                return y2 < y0 ? unit : -unit;
	            }
	        }
	    }

	    // TODO
	    // Arc 旋转
	    function windingArc(
	        cx, cy, r, startAngle, endAngle, anticlockwise, x, y
	    ) {
	        y -= cy;
	        if (y > r || y < -r) {
	            return 0;
	        }
	        var tmp = Math.sqrt(r * r - y * y);
	        roots[0] = -tmp;
	        roots[1] = tmp;

	        var diff = Math.abs(startAngle - endAngle);
	        if (diff < 1e-4) {
	            return 0;
	        }
	        if (diff % PI2 < 1e-4) {
	            // Is a circle
	            startAngle = 0;
	            endAngle = PI2;
	            var dir = anticlockwise ? 1 : -1;
	            if (x >= roots[0] + cx && x <= roots[1] + cx) {
	                return dir;
	            } else {
	                return 0;
	            }
	        }

	        if (anticlockwise) {
	            var tmp = startAngle;
	            startAngle = normalizeRadian(endAngle);
	            endAngle = normalizeRadian(tmp);
	        }
	        else {
	            startAngle = normalizeRadian(startAngle);
	            endAngle = normalizeRadian(endAngle);
	        }
	        if (startAngle > endAngle) {
	            endAngle += PI2;
	        }

	        var w = 0;
	        for (var i = 0; i < 2; i++) {
	            var x_ = roots[i];
	            if (x_ + cx > x) {
	                var angle = Math.atan2(y, x_);
	                var dir = anticlockwise ? 1 : -1;
	                if (angle < 0) {
	                    angle = PI2 + angle;
	                }
	                if (
	                    (angle >= startAngle && angle <= endAngle)
	                    || (angle + PI2 >= startAngle && angle + PI2 <= endAngle)
	                ) {
	                    if (angle > Math.PI / 2 && angle < Math.PI * 1.5) {
	                        dir = -dir;
	                    }
	                    w += dir;
	                }
	            }
	        }
	        return w;
	    }

	    function containPath(data, lineWidth, isStroke, x, y) {
	        var w = 0;
	        var xi = 0;
	        var yi = 0;
	        var x0 = 0;
	        var y0 = 0;

	        for (var i = 0; i < data.length;) {
	            var cmd = data[i++];
	            // Begin a new subpath
	            if (cmd === CMD.M && i > 1) {
	                // Close previous subpath
	                if (!isStroke) {
	                    w += windingLine(xi, yi, x0, y0, x, y);
	                }
	                // 如果被任何一个 subpath 包含
	                // if (w !== 0) {
	                //     return true;
	                // }
	            }

	            if (i == 1) {
	                // 如果第一个命令是 L, C, Q
	                // 则 previous point 同绘制命令的第一个 point
	                //
	                // 第一个命令为 Arc 的情况下会在后面特殊处理
	                xi = data[i];
	                yi = data[i + 1];

	                x0 = xi;
	                y0 = yi;
	            }

	            switch (cmd) {
	                case CMD.M:
	                    // moveTo 命令重新创建一个新的 subpath, 并且更新新的起点
	                    // 在 closePath 的时候使用
	                    x0 = data[i++];
	                    y0 = data[i++];
	                    xi = x0;
	                    yi = y0;
	                    break;
	                case CMD.L:
	                    if (isStroke) {
	                        if (containStroke(xi, yi, data[i], data[i + 1], lineWidth, x, y)) {
	                            return true;
	                        }
	                    }
	                    else {
	                        // NOTE 在第一个命令为 L, C, Q 的时候会计算出 NaN
	                        w += windingLine(xi, yi, data[i], data[i + 1], x, y) || 0;
	                    }
	                    xi = data[i++];
	                    yi = data[i++];
	                    break;
	                case CMD.C:
	                    if (isStroke) {
	                        if (cubic.containStroke(xi, yi,
	                            data[i++], data[i++], data[i++], data[i++], data[i], data[i + 1],
	                            lineWidth, x, y
	                        )) {
	                            return true;
	                        }
	                    }
	                    else {
	                        w += windingCubic(
	                            xi, yi,
	                            data[i++], data[i++], data[i++], data[i++], data[i], data[i + 1],
	                            x, y
	                        ) || 0;
	                    }
	                    xi = data[i++];
	                    yi = data[i++];
	                    break;
	                case CMD.Q:
	                    if (isStroke) {
	                        if (quadratic.containStroke(xi, yi,
	                            data[i++], data[i++], data[i], data[i + 1],
	                            lineWidth, x, y
	                        )) {
	                            return true;
	                        }
	                    }
	                    else {
	                        w += windingQuadratic(
	                            xi, yi,
	                            data[i++], data[i++], data[i], data[i + 1],
	                            x, y
	                        ) || 0;
	                    }
	                    xi = data[i++];
	                    yi = data[i++];
	                    break;
	                case CMD.A:
	                    // TODO Arc 判断的开销比较大
	                    var cx = data[i++];
	                    var cy = data[i++];
	                    var rx = data[i++];
	                    var ry = data[i++];
	                    var theta = data[i++];
	                    var dTheta = data[i++];
	                    // TODO Arc 旋转
	                    var psi = data[i++];
	                    var anticlockwise = 1 - data[i++];
	                    var x1 = Math.cos(theta) * rx + cx;
	                    var y1 = Math.sin(theta) * ry + cy;
	                    // 不是直接使用 arc 命令
	                    if (i > 1) {
	                        w += windingLine(xi, yi, x1, y1, x, y);
	                    }
	                    else {
	                        // 第一个命令起点还未定义
	                        x0 = x1;
	                        y0 = y1;
	                    }
	                    // zr 使用scale来模拟椭圆, 这里也对x做一定的缩放
	                    var _x = (x - cx) * ry / rx + cx;
	                    if (isStroke) {
	                        if (arc.containStroke(
	                            cx, cy, ry, theta, theta + dTheta, anticlockwise,
	                            lineWidth, _x, y
	                        )) {
	                            return true;
	                        }
	                    }
	                    else {
	                        w += windingArc(
	                            cx, cy, ry, theta, theta + dTheta, anticlockwise,
	                            _x, y
	                        );
	                    }
	                    xi = Math.cos(theta + dTheta) * rx + cx;
	                    yi = Math.sin(theta + dTheta) * ry + cy;
	                    break;
	                case CMD.R:
	                    x0 = xi = data[i++];
	                    y0 = yi = data[i++];
	                    var width = data[i++];
	                    var height = data[i++];
	                    var x1 = x0 + width;
	                    var y1 = y0 + height;
	                    if (isStroke) {
	                        if (containStroke(x0, y0, x1, y0, lineWidth, x, y)
	                          || containStroke(x1, y0, x1, y1, lineWidth, x, y)
	                          || containStroke(x1, y1, x0, y1, lineWidth, x, y)
	                          || containStroke(x0, y1, x0, y0, lineWidth, x, y)
	                        ) {
	                            return true;
	                        }
	                    }
	                    else {
	                        // FIXME Clockwise ?
	                        w += windingLine(x1, y0, x1, y1, x, y);
	                        w += windingLine(x0, y1, x0, y0, x, y);
	                    }
	                    break;
	                case CMD.Z:
	                    if (isStroke) {
	                        if (containStroke(
	                            xi, yi, x0, y0, lineWidth, x, y
	                        )) {
	                            return true;
	                        }
	                    }
	                    else {
	                        // Close a subpath
	                        w += windingLine(xi, yi, x0, y0, x, y);
	                        // 如果被任何一个 subpath 包含
	                        // FIXME subpaths may overlap
	                        // if (w !== 0) {
	                        //     return true;
	                        // }
	                    }
	                    xi = x0;
	                    yi = y0;
	                    break;
	            }
	        }
	        if (!isStroke && !isAroundEqual(yi, y0)) {
	            w += windingLine(xi, yi, x0, y0, x, y) || 0;
	        }
	        return w !== 0;
	    }

	    module.exports = {
	        contain: function (pathData, x, y) {
	            return containPath(pathData, 0, false, x, y);
	        },

	        containStroke: function (pathData, lineWidth, x, y) {
	            return containPath(pathData, lineWidth, true, x, y);
	        }
	    };


/***/ },
/* 40 */
/***/ function(module, exports) {

	
	    module.exports = {
	        /**
	         * 线段包含判断
	         * @param  {number}  x0
	         * @param  {number}  y0
	         * @param  {number}  x1
	         * @param  {number}  y1
	         * @param  {number}  lineWidth
	         * @param  {number}  x
	         * @param  {number}  y
	         * @return {boolean}
	         */
	        containStroke: function (x0, y0, x1, y1, lineWidth, x, y) {
	            if (lineWidth === 0) {
	                return false;
	            }
	            var _l = lineWidth;
	            var _a = 0;
	            var _b = x0;
	            // Quick reject
	            if (
	                (y > y0 + _l && y > y1 + _l)
	                || (y < y0 - _l && y < y1 - _l)
	                || (x > x0 + _l && x > x1 + _l)
	                || (x < x0 - _l && x < x1 - _l)
	            ) {
	                return false;
	            }

	            if (x0 !== x1) {
	                _a = (y0 - y1) / (x0 - x1);
	                _b = (x0 * y1 - x1 * y0) / (x0 - x1) ;
	            }
	            else {
	                return Math.abs(x - x0) <= _l / 2;
	            }
	            var tmp = _a * x - y + _b;
	            var _s = tmp * tmp / (_a * _a + 1);
	            return _s <= _l / 2 * _l / 2;
	        }
	    };


/***/ },
/* 41 */
/***/ function(module, exports, __webpack_require__) {

	

	    var curve = __webpack_require__(37);

	    module.exports = {
	        /**
	         * 三次贝塞尔曲线描边包含判断
	         * @param  {number}  x0
	         * @param  {number}  y0
	         * @param  {number}  x1
	         * @param  {number}  y1
	         * @param  {number}  x2
	         * @param  {number}  y2
	         * @param  {number}  x3
	         * @param  {number}  y3
	         * @param  {number}  lineWidth
	         * @param  {number}  x
	         * @param  {number}  y
	         * @return {boolean}
	         */
	        containStroke: function(x0, y0, x1, y1, x2, y2, x3, y3, lineWidth, x, y) {
	            if (lineWidth === 0) {
	                return false;
	            }
	            var _l = lineWidth;
	            // Quick reject
	            if (
	                (y > y0 + _l && y > y1 + _l && y > y2 + _l && y > y3 + _l)
	                || (y < y0 - _l && y < y1 - _l && y < y2 - _l && y < y3 - _l)
	                || (x > x0 + _l && x > x1 + _l && x > x2 + _l && x > x3 + _l)
	                || (x < x0 - _l && x < x1 - _l && x < x2 - _l && x < x3 - _l)
	            ) {
	                return false;
	            }
	            var d = curve.cubicProjectPoint(
	                x0, y0, x1, y1, x2, y2, x3, y3,
	                x, y, null
	            );
	            return d <= _l / 2;
	        }
	    };


/***/ },
/* 42 */
/***/ function(module, exports, __webpack_require__) {

	

	    var curve = __webpack_require__(37);

	    module.exports = {
	        /**
	         * 二次贝塞尔曲线描边包含判断
	         * @param  {number}  x0
	         * @param  {number}  y0
	         * @param  {number}  x1
	         * @param  {number}  y1
	         * @param  {number}  x2
	         * @param  {number}  y2
	         * @param  {number}  lineWidth
	         * @param  {number}  x
	         * @param  {number}  y
	         * @return {boolean}
	         */
	        containStroke: function (x0, y0, x1, y1, x2, y2, lineWidth, x, y) {
	            if (lineWidth === 0) {
	                return false;
	            }
	            var _l = lineWidth;
	            // Quick reject
	            if (
	                (y > y0 + _l && y > y1 + _l && y > y2 + _l)
	                || (y < y0 - _l && y < y1 - _l && y < y2 - _l)
	                || (x > x0 + _l && x > x1 + _l && x > x2 + _l)
	                || (x < x0 - _l && x < x1 - _l && x < x2 - _l)
	            ) {
	                return false;
	            }
	            var d = curve.quadraticProjectPoint(
	                x0, y0, x1, y1, x2, y2,
	                x, y, null
	            );
	            return d <= _l / 2;
	        }
	    };


/***/ },
/* 43 */
/***/ function(module, exports, __webpack_require__) {

	

	    var normalizeRadian = __webpack_require__(44).normalizeRadian;
	    var PI2 = Math.PI * 2;

	    module.exports = {
	        /**
	         * 圆弧描边包含判断
	         * @param  {number}  cx
	         * @param  {number}  cy
	         * @param  {number}  r
	         * @param  {number}  startAngle
	         * @param  {number}  endAngle
	         * @param  {boolean}  anticlockwise
	         * @param  {number} lineWidth
	         * @param  {number}  x
	         * @param  {number}  y
	         * @return {Boolean}
	         */
	        containStroke: function (
	            cx, cy, r, startAngle, endAngle, anticlockwise,
	            lineWidth, x, y
	        ) {

	            if (lineWidth === 0) {
	                return false;
	            }
	            var _l = lineWidth;

	            x -= cx;
	            y -= cy;
	            var d = Math.sqrt(x * x + y * y);

	            if ((d - _l > r) || (d + _l < r)) {
	                return false;
	            }
	            if (Math.abs(startAngle - endAngle) % PI2 < 1e-4) {
	                // Is a circle
	                return true;
	            }
	            if (anticlockwise) {
	                var tmp = startAngle;
	                startAngle = normalizeRadian(endAngle);
	                endAngle = normalizeRadian(tmp);
	            } else {
	                startAngle = normalizeRadian(startAngle);
	                endAngle = normalizeRadian(endAngle);
	            }
	            if (startAngle > endAngle) {
	                endAngle += PI2;
	            }

	            var angle = Math.atan2(y, x);
	            if (angle < 0) {
	                angle += PI2;
	            }
	            return (angle >= startAngle && angle <= endAngle)
	                || (angle + PI2 >= startAngle && angle + PI2 <= endAngle);
	        }
	    };


/***/ },
/* 44 */
/***/ function(module, exports) {

	

	    var PI2 = Math.PI * 2;
	    module.exports = {
	        normalizeRadian: function(angle) {
	            angle %= PI2;
	            if (angle < 0) {
	                angle += PI2;
	            }
	            return angle;
	        }
	    };


/***/ },
/* 45 */
/***/ function(module, exports) {

	
	    module.exports = function windingLine(x0, y0, x1, y1, x, y) {
	        if ((y > y0 && y > y1) || (y < y0 && y < y1)) {
	            return 0;
	        }
	        // Ignore horizontal line
	        if (y1 === y0) {
	            return 0;
	        }
	        var dir = y1 < y0 ? 1 : -1;
	        var t = (y - y0) / (y1 - y0);

	        // Avoid winding error when intersection point is the connect point of two line of polygon
	        if (t === 1 || t === 0) {
	            dir = y1 < y0 ? 0.5 : -0.5;
	        }

	        var x_ = t * (x1 - x0) + x0;

	        return x_ > x ? dir : 0;
	    };


/***/ },
/* 46 */
/***/ function(module, exports) {

	

	    var Pattern = function (image, repeat) {
	        // Should do nothing more in this constructor. Because gradient can be
	        // declard by `color: {image: ...}`, where this constructor will not be called.

	        this.image = image;
	        this.repeat = repeat;

	        // Can be cloned
	        this.type = 'pattern';
	    };

	    Pattern.prototype.getCanvasPattern = function (ctx) {
	        return ctx.createPattern(this.image, this.repeat || 'repeat');
	    };

	    module.exports = Pattern;


/***/ },
/* 47 */
/***/ function(module, exports, __webpack_require__) {

	

	    var CMD = __webpack_require__(36).CMD;
	    var vec2 = __webpack_require__(10);
	    var v2ApplyTransform = vec2.applyTransform;

	    var points = [[], [], []];
	    var mathSqrt = Math.sqrt;
	    var mathAtan2 = Math.atan2;
	    function transformPath(path, m) {
	        var data = path.data;
	        var cmd;
	        var nPoint;
	        var i;
	        var j;
	        var k;
	        var p;

	        var M = CMD.M;
	        var C = CMD.C;
	        var L = CMD.L;
	        var R = CMD.R;
	        var A = CMD.A;
	        var Q = CMD.Q;

	        for (i = 0, j = 0; i < data.length;) {
	            cmd = data[i++];
	            j = i;
	            nPoint = 0;

	            switch (cmd) {
	                case M:
	                    nPoint = 1;
	                    break;
	                case L:
	                    nPoint = 1;
	                    break;
	                case C:
	                    nPoint = 3;
	                    break;
	                case Q:
	                    nPoint = 2;
	                    break;
	                case A:
	                    var x = m[4];
	                    var y = m[5];
	                    var sx = mathSqrt(m[0] * m[0] + m[1] * m[1]);
	                    var sy = mathSqrt(m[2] * m[2] + m[3] * m[3]);
	                    var angle = mathAtan2(-m[1] / sy, m[0] / sx);
	                    // cx
	                    data[i] *= sx;
	                    data[i++] += x;
	                    // cy
	                    data[i] *= sy;
	                    data[i++] += y;
	                    // Scale rx and ry
	                    // FIXME Assume psi is 0 here
	                    data[i++] *= sx;
	                    data[i++] *= sy;

	                    // Start angle
	                    data[i++] += angle;
	                    // end angle
	                    data[i++] += angle;
	                    // FIXME psi
	                    i += 2;
	                    j = i;
	                    break;
	                case R:
	                    // x0, y0
	                    p[0] = data[i++];
	                    p[1] = data[i++];
	                    v2ApplyTransform(p, p, m);
	                    data[j++] = p[0];
	                    data[j++] = p[1];
	                    // x1, y1
	                    p[0] += data[i++];
	                    p[1] += data[i++];
	                    v2ApplyTransform(p, p, m);
	                    data[j++] = p[0];
	                    data[j++] = p[1];
	            }

	            for (k = 0; k < nPoint; k++) {
	                var p = points[k];
	                p[0] = data[i++];
	                p[1] = data[i++];

	                v2ApplyTransform(p, p, m);
	                // Write back
	                data[j++] = p[0];
	                data[j++] = p[1];
	            }
	        }
	    }

	    module.exports = transformPath;


/***/ },
/* 48 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * Group是一个容器，可以插入子节点，Group的变换也会被应用到子节点上
	 * @module zrender/graphic/Group
	 * @example
	 *     var Group = require('zrender/lib/container/Group');
	 *     var Circle = require('zrender/lib/graphic/shape/Circle');
	 *     var g = new Group();
	 *     g.position[0] = 100;
	 *     g.position[1] = 100;
	 *     g.add(new Circle({
	 *         style: {
	 *             x: 100,
	 *             y: 100,
	 *             r: 20,
	 *         }
	 *     }));
	 *     zr.add(g);
	 */


	    var zrUtil = __webpack_require__(4);
	    var Element = __webpack_require__(23);
	    var BoundingRect = __webpack_require__(9);

	    /**
	     * @alias module:zrender/graphic/Group
	     * @constructor
	     * @extends module:zrender/mixin/Transformable
	     * @extends module:zrender/mixin/Eventful
	     */
	    var Group = function (opts) {

	        opts = opts || {};

	        Element.call(this, opts);

	        for (var key in opts) {
	            if (opts.hasOwnProperty(key)) {
	                this[key] = opts[key];
	            }
	        }

	        this._children = [];

	        this.__storage = null;

	        this.__dirty = true;
	    };

	    Group.prototype = {

	        constructor: Group,

	        isGroup: true,

	        /**
	         * @type {string}
	         */
	        type: 'group',

	        /**
	         * 所有子孙元素是否响应鼠标事件
	         * @name module:/zrender/container/Group#silent
	         * @type {boolean}
	         * @default false
	         */
	        silent: false,

	        /**
	         * @return {Array.<module:zrender/Element>}
	         */
	        children: function () {
	            return this._children.slice();
	        },

	        /**
	         * 获取指定 index 的儿子节点
	         * @param  {number} idx
	         * @return {module:zrender/Element}
	         */
	        childAt: function (idx) {
	            return this._children[idx];
	        },

	        /**
	         * 获取指定名字的儿子节点
	         * @param  {string} name
	         * @return {module:zrender/Element}
	         */
	        childOfName: function (name) {
	            var children = this._children;
	            for (var i = 0; i < children.length; i++) {
	                if (children[i].name === name) {
	                    return children[i];
	                }
	             }
	        },

	        /**
	         * @return {number}
	         */
	        childCount: function () {
	            return this._children.length;
	        },

	        /**
	         * 添加子节点到最后
	         * @param {module:zrender/Element} child
	         */
	        add: function (child) {
	            if (child && child !== this && child.parent !== this) {

	                this._children.push(child);

	                this._doAdd(child);
	            }

	            return this;
	        },

	        /**
	         * 添加子节点在 nextSibling 之前
	         * @param {module:zrender/Element} child
	         * @param {module:zrender/Element} nextSibling
	         */
	        addBefore: function (child, nextSibling) {
	            if (child && child !== this && child.parent !== this
	                && nextSibling && nextSibling.parent === this) {

	                var children = this._children;
	                var idx = children.indexOf(nextSibling);

	                if (idx >= 0) {
	                    children.splice(idx, 0, child);
	                    this._doAdd(child);
	                }
	            }

	            return this;
	        },

	        _doAdd: function (child) {
	            if (child.parent) {
	                child.parent.remove(child);
	            }

	            child.parent = this;

	            var storage = this.__storage;
	            var zr = this.__zr;
	            if (storage && storage !== child.__storage) {

	                storage.addToStorage(child);

	                if (child instanceof Group) {
	                    child.addChildrenToStorage(storage);
	                }
	            }

	            zr && zr.refresh();
	        },

	        /**
	         * 移除子节点
	         * @param {module:zrender/Element} child
	         */
	        remove: function (child) {
	            var zr = this.__zr;
	            var storage = this.__storage;
	            var children = this._children;

	            var idx = zrUtil.indexOf(children, child);
	            if (idx < 0) {
	                return this;
	            }
	            children.splice(idx, 1);

	            child.parent = null;

	            if (storage) {

	                storage.delFromStorage(child);

	                if (child instanceof Group) {
	                    child.delChildrenFromStorage(storage);
	                }
	            }

	            zr && zr.refresh();

	            return this;
	        },

	        /**
	         * 移除所有子节点
	         */
	        removeAll: function () {
	            var children = this._children;
	            var storage = this.__storage;
	            var child;
	            var i;
	            for (i = 0; i < children.length; i++) {
	                child = children[i];
	                if (storage) {
	                    storage.delFromStorage(child);
	                    if (child instanceof Group) {
	                        child.delChildrenFromStorage(storage);
	                    }
	                }
	                child.parent = null;
	            }
	            children.length = 0;

	            return this;
	        },

	        /**
	         * 遍历所有子节点
	         * @param  {Function} cb
	         * @param  {}   context
	         */
	        eachChild: function (cb, context) {
	            var children = this._children;
	            for (var i = 0; i < children.length; i++) {
	                var child = children[i];
	                cb.call(context, child, i);
	            }
	            return this;
	        },

	        /**
	         * 深度优先遍历所有子孙节点
	         * @param  {Function} cb
	         * @param  {}   context
	         */
	        traverse: function (cb, context) {
	            for (var i = 0; i < this._children.length; i++) {
	                var child = this._children[i];
	                cb.call(context, child);

	                if (child.type === 'group') {
	                    child.traverse(cb, context);
	                }
	            }
	            return this;
	        },

	        addChildrenToStorage: function (storage) {
	            for (var i = 0; i < this._children.length; i++) {
	                var child = this._children[i];
	                storage.addToStorage(child);
	                if (child instanceof Group) {
	                    child.addChildrenToStorage(storage);
	                }
	            }
	        },

	        delChildrenFromStorage: function (storage) {
	            for (var i = 0; i < this._children.length; i++) {
	                var child = this._children[i];
	                storage.delFromStorage(child);
	                if (child instanceof Group) {
	                    child.delChildrenFromStorage(storage);
	                }
	            }
	        },

	        dirty: function () {
	            this.__dirty = true;
	            this.__zr && this.__zr.refresh();
	            return this;
	        },

	        /**
	         * @return {module:zrender/core/BoundingRect}
	         */
	        getBoundingRect: function (includeChildren) {
	            // TODO Caching
	            var rect = null;
	            var tmpRect = new BoundingRect(0, 0, 0, 0);
	            var children = includeChildren || this._children;
	            var tmpMat = [];

	            for (var i = 0; i < children.length; i++) {
	                var child = children[i];
	                if (child.ignore || child.invisible) {
	                    continue;
	                }

	                var childRect = child.getBoundingRect();
	                var transform = child.getLocalTransform(tmpMat);
	                // TODO
	                // The boundingRect cacluated by transforming original
	                // rect may be bigger than the actual bundingRect when rotation
	                // is used. (Consider a circle rotated aginst its center, where
	                // the actual boundingRect should be the same as that not be
	                // rotated.) But we can not find better approach to calculate
	                // actual boundingRect yet, considering performance.
	                if (transform) {
	                    tmpRect.copy(childRect);
	                    tmpRect.applyTransform(transform);
	                    rect = rect || tmpRect.clone();
	                    rect.union(tmpRect);
	                }
	                else {
	                    rect = rect || childRect.clone();
	                    rect.union(childRect);
	                }
	            }
	            return rect || tmpRect;
	        }
	    };

	    zrUtil.inherits(Group, Element);

	    module.exports = Group;


/***/ },
/* 49 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * Image element
	 * @module zrender/graphic/Image
	 */



	    var Displayable = __webpack_require__(21);
	    var BoundingRect = __webpack_require__(9);
	    var zrUtil = __webpack_require__(4);

	    var LRU = __webpack_require__(32);
	    var globalImageCache = new LRU(50);
	    /**
	     * @alias zrender/graphic/Image
	     * @extends module:zrender/graphic/Displayable
	     * @constructor
	     * @param {Object} opts
	     */
	    function ZImage(opts) {
	        Displayable.call(this, opts);
	    }

	    ZImage.prototype = {

	        constructor: ZImage,

	        type: 'image',

	        brush: function (ctx, prevEl) {
	            var style = this.style;
	            var src = style.image;
	            var image;

	            // Must bind each time
	            style.bind(ctx, this, prevEl);
	            // style.image is a url string
	            if (typeof src === 'string') {
	                image = this._image;
	            }
	            // style.image is an HTMLImageElement or HTMLCanvasElement or Canvas
	            else {
	                image = src;
	            }
	            // FIXME Case create many images with src
	            if (!image && src) {
	                // Try get from global image cache
	                var cachedImgObj = globalImageCache.get(src);
	                if (!cachedImgObj) {
	                    // Create a new image
	                    image = new Image();
	                    image.onload = function () {
	                        image.onload = null;
	                        for (var i = 0; i < cachedImgObj.pending.length; i++) {
	                            cachedImgObj.pending[i].dirty();
	                        }
	                    };
	                    cachedImgObj = {
	                        image: image,
	                        pending: [this]
	                    };
	                    image.src = src;
	                    globalImageCache.put(src, cachedImgObj);
	                    this._image = image;
	                    return;
	                }
	                else {
	                    image = cachedImgObj.image;
	                    this._image = image;
	                    // Image is not complete finish, add to pending list
	                    if (!image.width || !image.height) {
	                        cachedImgObj.pending.push(this);
	                        return;
	                    }
	                }
	            }

	            if (image) {
	                // 图片已经加载完成
	                // if (image.nodeName.toUpperCase() == 'IMG') {
	                //     if (!image.complete) {
	                //         return;
	                //     }
	                // }
	                // Else is canvas

	                var x = style.x || 0;
	                var y = style.y || 0;
	                // 图片加载失败
	                if (!image.width || !image.height) {
	                    return;
	                }
	                var width = style.width;
	                var height = style.height;
	                var aspect = image.width / image.height;
	                if (width == null && height != null) {
	                    // Keep image/height ratio
	                    width = height * aspect;
	                }
	                else if (height == null && width != null) {
	                    height = width / aspect;
	                }
	                else if (width == null && height == null) {
	                    width = image.width;
	                    height = image.height;
	                }

	                // 设置transform
	                this.setTransform(ctx);

	                if (style.sWidth && style.sHeight) {
	                    var sx = style.sx || 0;
	                    var sy = style.sy || 0;
	                    ctx.drawImage(
	                        image,
	                        sx, sy, style.sWidth, style.sHeight,
	                        x, y, width, height
	                    );
	                }
	                else if (style.sx && style.sy) {
	                    var sx = style.sx;
	                    var sy = style.sy;
	                    var sWidth = width - sx;
	                    var sHeight = height - sy;
	                    ctx.drawImage(
	                        image,
	                        sx, sy, sWidth, sHeight,
	                        x, y, width, height
	                    );
	                }
	                else {
	                    ctx.drawImage(image, x, y, width, height);
	                }

	                this.restoreTransform(ctx);

	                // Draw rect text
	                if (style.text != null) {
	                    this.drawRectText(ctx, this.getBoundingRect());
	                }

	            }
	        },

	        getBoundingRect: function () {
	            var style = this.style;
	            if (! this._rect) {
	                this._rect = new BoundingRect(
	                    style.x || 0, style.y || 0, style.width || 0, style.height || 0
	                );
	            }
	            return this._rect;
	        }
	    };

	    zrUtil.inherits(ZImage, Displayable);

	    module.exports = ZImage;


/***/ },
/* 50 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * Text element
	 * @module zrender/graphic/Text
	 *
	 * TODO Wrapping
	 *
	 * Text not support gradient
	 */



	    var Displayable = __webpack_require__(21);
	    var zrUtil = __webpack_require__(4);
	    var textContain = __webpack_require__(8);

	    /**
	     * @alias zrender/graphic/Text
	     * @extends module:zrender/graphic/Displayable
	     * @constructor
	     * @param {Object} opts
	     */
	    var Text = function (opts) {
	        Displayable.call(this, opts);
	    };

	    Text.prototype = {

	        constructor: Text,

	        type: 'text',

	        brush: function (ctx, prevEl) {
	            var style = this.style;
	            var x = style.x || 0;
	            var y = style.y || 0;
	            // Convert to string
	            var text = style.text;

	            // Convert to string
	            text != null && (text += '');

	            // Always bind style
	            style.bind(ctx, this, prevEl);

	            if (text) {

	                this.setTransform(ctx);

	                var textBaseline;
	                var textAlign = style.textAlign;
	                var font = style.textFont || style.font;
	                if (style.textVerticalAlign) {
	                    var rect = textContain.getBoundingRect(
	                        text, font, style.textAlign, 'top'
	                    );
	                    // Ignore textBaseline
	                    textBaseline = 'middle';
	                    switch (style.textVerticalAlign) {
	                        case 'middle':
	                            y -= rect.height / 2 - rect.lineHeight / 2;
	                            break;
	                        case 'bottom':
	                            y -= rect.height - rect.lineHeight / 2;
	                            break;
	                        default:
	                            y += rect.lineHeight / 2;
	                    }
	                }
	                else {
	                    textBaseline = style.textBaseline;
	                }

	                // TODO Invalid font
	                ctx.font = font || '12px sans-serif';
	                ctx.textAlign = textAlign || 'left';
	                // Use canvas default left textAlign. Giving invalid value will cause state not change
	                if (ctx.textAlign !== textAlign) {
	                    ctx.textAlign = 'left';
	                }
	                // FIXME in text contain default is top
	                ctx.textBaseline = textBaseline || 'alphabetic';
	                // Use canvas default alphabetic baseline
	                if (ctx.textBaseline !== textBaseline) {
	                    ctx.textBaseline = 'alphabetic';
	                }

	                var lineHeight = textContain.measureText('国', ctx.font).width;

	                var textLines = text.split('\n');
	                for (var i = 0; i < textLines.length; i++) {
	                    // Fill after stroke so the outline will not cover the main part.
	                    style.hasStroke() && ctx.strokeText(textLines[i], x, y);
	                    style.hasFill() && ctx.fillText(textLines[i], x, y);
	                    y += lineHeight;
	                }

	                this.restoreTransform(ctx);
	            }
	        },

	        getBoundingRect: function () {
	            var style = this.style;
	            if (!this._rect) {
	                var textVerticalAlign = style.textVerticalAlign;
	                var rect = textContain.getBoundingRect(
	                    style.text + '', style.textFont || style.font, style.textAlign,
	                    textVerticalAlign ? 'top' : style.textBaseline
	                );
	                switch (textVerticalAlign) {
	                    case 'middle':
	                        rect.y -= rect.height / 2;
	                        break;
	                    case 'bottom':
	                        rect.y -= rect.height;
	                        break;
	                }
	                rect.x += style.x || 0;
	                rect.y += style.y || 0;
	                if (style.hasStroke()) {
	                    var w = style.lineWidth;
	                    rect.x -= w / 2;
	                    rect.y -= w / 2;
	                    rect.width += w;
	                    rect.height += w;
	                }
	                this._rect = rect;
	            }

	            return this._rect;
	        }
	    };

	    zrUtil.inherits(Text, Displayable);

	    module.exports = Text;


/***/ },
/* 51 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	/**
	 * 圆形
	 * @module zrender/shape/Circle
	 */



	    module.exports = __webpack_require__(20).extend({

	        type: 'circle',

	        shape: {
	            cx: 0,
	            cy: 0,
	            r: 0
	        },


	        buildPath : function (ctx, shape, inBundle) {
	            // Better stroking in ShapeBundle
	            // Always do it may have performence issue ( fill may be 2x more cost)
	            if (inBundle) {
	                ctx.moveTo(shape.cx + shape.r, shape.cy);
	            }
	            // else {
	            //     if (ctx.allocate && !ctx.data.length) {
	            //         ctx.allocate(ctx.CMD_MEM_SIZE.A);
	            //     }
	            // }
	            // Better stroking in ShapeBundle
	            // ctx.moveTo(shape.cx + shape.r, shape.cy);
	            ctx.arc(shape.cx, shape.cy, shape.r, 0, Math.PI * 2, true);
	        }
	    });



/***/ },
/* 52 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * 扇形
	 * @module zrender/graphic/shape/Sector
	 */



	    var env = __webpack_require__(2);
	    var Path = __webpack_require__(20);

	    var shadowTemp = [
	        ['shadowBlur', 0],
	        ['shadowColor', '#000'],
	        ['shadowOffsetX', 0],
	        ['shadowOffsetY', 0]
	    ];

	    module.exports = Path.extend({

	        type: 'sector',

	        shape: {

	            cx: 0,

	            cy: 0,

	            r0: 0,

	            r: 0,

	            startAngle: 0,

	            endAngle: Math.PI * 2,

	            clockwise: true
	        },

	        brush: (env.browser.ie && env.browser.version >= 11) // version: '11.0'
	            // Fix weird bug in some version of IE11 (like 11.0.9600.17801),
	            // where exception "unexpected call to method or property access"
	            // might be thrown when calling ctx.fill after a path whose area size
	            // is zero is drawn and ctx.clip() is called and shadowBlur is set.
	            // (e.g.,
	            //  ctx.moveTo(10, 10);
	            //  ctx.lineTo(20, 10);
	            //  ctx.closePath();
	            //  ctx.clip();
	            //  ctx.shadowBlur = 10;
	            //  ...
	            //  ctx.fill();
	            // )
	            ? function () {
	                var clipPaths = this.__clipPaths;
	                var style = this.style;
	                var modified;

	                if (clipPaths) {
	                    for (var i = 0; i < clipPaths.length; i++) {
	                        var shape = clipPaths[i] && clipPaths[i].shape;
	                        if (shape && shape.startAngle === shape.endAngle) {
	                            for (var j = 0; j < shadowTemp.length; j++) {
	                                shadowTemp[j][2] = style[shadowTemp[j][0]];
	                                style[shadowTemp[j][0]] = shadowTemp[j][1];
	                            }
	                            modified = true;
	                            break;
	                        }
	                    }
	                }

	                Path.prototype.brush.apply(this, arguments);

	                if (modified) {
	                    for (var j = 0; j < shadowTemp.length; j++) {
	                        style[shadowTemp[j][0]] = shadowTemp[j][2];
	                    }
	                }
	            }
	            : Path.prototype.brush,

	        buildPath: function (ctx, shape) {

	            var x = shape.cx;
	            var y = shape.cy;
	            var r0 = Math.max(shape.r0 || 0, 0);
	            var r = Math.max(shape.r, 0);
	            var startAngle = shape.startAngle;
	            var endAngle = shape.endAngle;
	            var clockwise = shape.clockwise;

	            var unitX = Math.cos(startAngle);
	            var unitY = Math.sin(startAngle);

	            ctx.moveTo(unitX * r0 + x, unitY * r0 + y);

	            ctx.lineTo(unitX * r + x, unitY * r + y);

	            ctx.arc(x, y, r, startAngle, endAngle, !clockwise);

	            ctx.lineTo(
	                Math.cos(endAngle) * r0 + x,
	                Math.sin(endAngle) * r0 + y
	            );

	            if (r0 !== 0) {
	                ctx.arc(x, y, r0, endAngle, startAngle, clockwise);
	            }

	            ctx.closePath();
	        }
	    });



/***/ },
/* 53 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * 圆环
	 * @module zrender/graphic/shape/Ring
	 */


	    module.exports = __webpack_require__(20).extend({

	        type: 'ring',

	        shape: {
	            cx: 0,
	            cy: 0,
	            r: 0,
	            r0: 0
	        },

	        buildPath: function (ctx, shape) {
	            var x = shape.cx;
	            var y = shape.cy;
	            var PI2 = Math.PI * 2;
	            ctx.moveTo(x + shape.r, y);
	            ctx.arc(x, y, shape.r, 0, PI2, false);
	            ctx.moveTo(x + shape.r0, y);
	            ctx.arc(x, y, shape.r0, 0, PI2, true);
	        }
	    });



/***/ },
/* 54 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * 多边形
	 * @module zrender/shape/Polygon
	 */


	    var polyHelper = __webpack_require__(55);

	    module.exports = __webpack_require__(20).extend({
	        
	        type: 'polygon',

	        shape: {
	            points: null,

	            smooth: false,

	            smoothConstraint: null
	        },

	        buildPath: function (ctx, shape) {
	            polyHelper.buildPath(ctx, shape, true);
	        }
	    });


/***/ },
/* 55 */
/***/ function(module, exports, __webpack_require__) {

	

	    var smoothSpline = __webpack_require__(56);
	    var smoothBezier = __webpack_require__(57);

	    module.exports = {
	        buildPath: function (ctx, shape, closePath) {
	            var points = shape.points;
	            var smooth = shape.smooth;
	            if (points && points.length >= 2) {
	                if (smooth && smooth !== 'spline') {
	                    var controlPoints = smoothBezier(
	                        points, smooth, closePath, shape.smoothConstraint
	                    );

	                    ctx.moveTo(points[0][0], points[0][1]);
	                    var len = points.length;
	                    for (var i = 0; i < (closePath ? len : len - 1); i++) {
	                        var cp1 = controlPoints[i * 2];
	                        var cp2 = controlPoints[i * 2 + 1];
	                        var p = points[(i + 1) % len];
	                        ctx.bezierCurveTo(
	                            cp1[0], cp1[1], cp2[0], cp2[1], p[0], p[1]
	                        );
	                    }
	                }
	                else {
	                    if (smooth === 'spline') {
	                        points = smoothSpline(points, closePath);
	                    }

	                    ctx.moveTo(points[0][0], points[0][1]);
	                    for (var i = 1, l = points.length; i < l; i++) {
	                        ctx.lineTo(points[i][0], points[i][1]);
	                    }
	                }

	                closePath && ctx.closePath();
	            }
	        }
	    };


/***/ },
/* 56 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * Catmull-Rom spline 插值折线
	 * @module zrender/shape/util/smoothSpline
	 * @author pissang (https://www.github.com/pissang)
	 *         Kener (@Kener-林峰, kener.linfeng@gmail.com)
	 *         errorrik (errorrik@gmail.com)
	 */

	    var vec2 = __webpack_require__(10);

	    /**
	     * @inner
	     */
	    function interpolate(p0, p1, p2, p3, t, t2, t3) {
	        var v0 = (p2 - p0) * 0.5;
	        var v1 = (p3 - p1) * 0.5;
	        return (2 * (p1 - p2) + v0 + v1) * t3
	                + (-3 * (p1 - p2) - 2 * v0 - v1) * t2
	                + v0 * t + p1;
	    }

	    /**
	     * @alias module:zrender/shape/util/smoothSpline
	     * @param {Array} points 线段顶点数组
	     * @param {boolean} isLoop
	     * @return {Array}
	     */
	    module.exports = function (points, isLoop) {
	        var len = points.length;
	        var ret = [];

	        var distance = 0;
	        for (var i = 1; i < len; i++) {
	            distance += vec2.distance(points[i - 1], points[i]);
	        }

	        var segs = distance / 2;
	        segs = segs < len ? len : segs;
	        for (var i = 0; i < segs; i++) {
	            var pos = i / (segs - 1) * (isLoop ? len : len - 1);
	            var idx = Math.floor(pos);

	            var w = pos - idx;

	            var p0;
	            var p1 = points[idx % len];
	            var p2;
	            var p3;
	            if (!isLoop) {
	                p0 = points[idx === 0 ? idx : idx - 1];
	                p2 = points[idx > len - 2 ? len - 1 : idx + 1];
	                p3 = points[idx > len - 3 ? len - 1 : idx + 2];
	            }
	            else {
	                p0 = points[(idx - 1 + len) % len];
	                p2 = points[(idx + 1) % len];
	                p3 = points[(idx + 2) % len];
	            }

	            var w2 = w * w;
	            var w3 = w * w2;

	            ret.push([
	                interpolate(p0[0], p1[0], p2[0], p3[0], w, w2, w3),
	                interpolate(p0[1], p1[1], p2[1], p3[1], w, w2, w3)
	            ]);
	        }
	        return ret;
	    };



/***/ },
/* 57 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * 贝塞尔平滑曲线
	 * @module zrender/shape/util/smoothBezier
	 * @author pissang (https://www.github.com/pissang)
	 *         Kener (@Kener-林峰, kener.linfeng@gmail.com)
	 *         errorrik (errorrik@gmail.com)
	 */


	    var vec2 = __webpack_require__(10);
	    var v2Min = vec2.min;
	    var v2Max = vec2.max;
	    var v2Scale = vec2.scale;
	    var v2Distance = vec2.distance;
	    var v2Add = vec2.add;

	    /**
	     * 贝塞尔平滑曲线
	     * @alias module:zrender/shape/util/smoothBezier
	     * @param {Array} points 线段顶点数组
	     * @param {number} smooth 平滑等级, 0-1
	     * @param {boolean} isLoop
	     * @param {Array} constraint 将计算出来的控制点约束在一个包围盒内
	     *                           比如 [[0, 0], [100, 100]], 这个包围盒会与
	     *                           整个折线的包围盒做一个并集用来约束控制点。
	     * @param {Array} 计算出来的控制点数组
	     */
	    module.exports = function (points, smooth, isLoop, constraint) {
	        var cps = [];

	        var v = [];
	        var v1 = [];
	        var v2 = [];
	        var prevPoint;
	        var nextPoint;

	        var min, max;
	        if (constraint) {
	            min = [Infinity, Infinity];
	            max = [-Infinity, -Infinity];
	            for (var i = 0, len = points.length; i < len; i++) {
	                v2Min(min, min, points[i]);
	                v2Max(max, max, points[i]);
	            }
	            // 与指定的包围盒做并集
	            v2Min(min, min, constraint[0]);
	            v2Max(max, max, constraint[1]);
	        }

	        for (var i = 0, len = points.length; i < len; i++) {
	            var point = points[i];

	            if (isLoop) {
	                prevPoint = points[i ? i - 1 : len - 1];
	                nextPoint = points[(i + 1) % len];
	            }
	            else {
	                if (i === 0 || i === len - 1) {
	                    cps.push(vec2.clone(points[i]));
	                    continue;
	                }
	                else {
	                    prevPoint = points[i - 1];
	                    nextPoint = points[i + 1];
	                }
	            }

	            vec2.sub(v, nextPoint, prevPoint);

	            // use degree to scale the handle length
	            v2Scale(v, v, smooth);

	            var d0 = v2Distance(point, prevPoint);
	            var d1 = v2Distance(point, nextPoint);
	            var sum = d0 + d1;
	            if (sum !== 0) {
	                d0 /= sum;
	                d1 /= sum;
	            }

	            v2Scale(v1, v, -d0);
	            v2Scale(v2, v, d1);
	            var cp0 = v2Add([], point, v1);
	            var cp1 = v2Add([], point, v2);
	            if (constraint) {
	                v2Max(cp0, cp0, min);
	                v2Min(cp0, cp0, max);
	                v2Max(cp1, cp1, min);
	                v2Min(cp1, cp1, max);
	            }
	            cps.push(cp0);
	            cps.push(cp1);
	        }

	        if (isLoop) {
	            cps.push(cps.shift());
	        }

	        return cps;
	    };



/***/ },
/* 58 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @module zrender/graphic/shape/Polyline
	 */


	    var polyHelper = __webpack_require__(55);

	    module.exports = __webpack_require__(20).extend({
	        
	        type: 'polyline',

	        shape: {
	            points: null,

	            smooth: false,

	            smoothConstraint: null
	        },

	        style: {
	            stroke: '#000',

	            fill: null
	        },

	        buildPath: function (ctx, shape) {
	            polyHelper.buildPath(ctx, shape, false);
	        }
	    });


/***/ },
/* 59 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * 矩形
	 * @module zrender/graphic/shape/Rect
	 */


	    var roundRectHelper = __webpack_require__(60);

	    module.exports = __webpack_require__(20).extend({

	        type: 'rect',

	        shape: {
	            // 左上、右上、右下、左下角的半径依次为r1、r2、r3、r4
	            // r缩写为1         相当于 [1, 1, 1, 1]
	            // r缩写为[1]       相当于 [1, 1, 1, 1]
	            // r缩写为[1, 2]    相当于 [1, 2, 1, 2]
	            // r缩写为[1, 2, 3] 相当于 [1, 2, 3, 2]
	            r: 0,

	            x: 0,
	            y: 0,
	            width: 0,
	            height: 0
	        },

	        buildPath: function (ctx, shape) {
	            var x = shape.x;
	            var y = shape.y;
	            var width = shape.width;
	            var height = shape.height;
	            if (!shape.r) {
	                ctx.rect(x, y, width, height);
	            }
	            else {
	                roundRectHelper.buildPath(ctx, shape);
	            }
	            ctx.closePath();
	            return;
	        }
	    });



/***/ },
/* 60 */
/***/ function(module, exports) {

	

	    module.exports = {
	        buildPath: function (ctx, shape) {
	            var x = shape.x;
	            var y = shape.y;
	            var width = shape.width;
	            var height = shape.height;
	            var r = shape.r;
	            var r1;
	            var r2;
	            var r3;
	            var r4;

	            // Convert width and height to positive for better borderRadius
	            if (width < 0) {
	                x = x + width;
	                width = -width;
	            }
	            if (height < 0) {
	                y = y + height;
	                height = -height;
	            }

	            if (typeof r === 'number') {
	                r1 = r2 = r3 = r4 = r;
	            }
	            else if (r instanceof Array) {
	                if (r.length === 1) {
	                    r1 = r2 = r3 = r4 = r[0];
	                }
	                else if (r.length === 2) {
	                    r1 = r3 = r[0];
	                    r2 = r4 = r[1];
	                }
	                else if (r.length === 3) {
	                    r1 = r[0];
	                    r2 = r4 = r[1];
	                    r3 = r[2];
	                }
	                else {
	                    r1 = r[0];
	                    r2 = r[1];
	                    r3 = r[2];
	                    r4 = r[3];
	                }
	            }
	            else {
	                r1 = r2 = r3 = r4 = 0;
	            }

	            var total;
	            if (r1 + r2 > width) {
	                total = r1 + r2;
	                r1 *= width / total;
	                r2 *= width / total;
	            }
	            if (r3 + r4 > width) {
	                total = r3 + r4;
	                r3 *= width / total;
	                r4 *= width / total;
	            }
	            if (r2 + r3 > height) {
	                total = r2 + r3;
	                r2 *= height / total;
	                r3 *= height / total;
	            }
	            if (r1 + r4 > height) {
	                total = r1 + r4;
	                r1 *= height / total;
	                r4 *= height / total;
	            }
	            ctx.moveTo(x + r1, y);
	            ctx.lineTo(x + width - r2, y);
	            r2 !== 0 && ctx.quadraticCurveTo(
	                x + width, y, x + width, y + r2
	            );
	            ctx.lineTo(x + width, y + height - r3);
	            r3 !== 0 && ctx.quadraticCurveTo(
	                x + width, y + height, x + width - r3, y + height
	            );
	            ctx.lineTo(x + r4, y + height);
	            r4 !== 0 && ctx.quadraticCurveTo(
	                x, y + height, x, y + height - r4
	            );
	            ctx.lineTo(x, y + r1);
	            r1 !== 0 && ctx.quadraticCurveTo(x, y, x + r1, y);
	        }
	    };


/***/ },
/* 61 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * 直线
	 * @module zrender/graphic/shape/Line
	 */

	    module.exports = __webpack_require__(20).extend({

	        type: 'line',

	        shape: {
	            // Start point
	            x1: 0,
	            y1: 0,
	            // End point
	            x2: 0,
	            y2: 0,

	            percent: 1
	        },

	        style: {
	            stroke: '#000',
	            fill: null
	        },

	        buildPath: function (ctx, shape) {
	            var x1 = shape.x1;
	            var y1 = shape.y1;
	            var x2 = shape.x2;
	            var y2 = shape.y2;
	            var percent = shape.percent;

	            if (percent === 0) {
	                return;
	            }

	            ctx.moveTo(x1, y1);

	            if (percent < 1) {
	                x2 = x1 * (1 - percent) + x2 * percent;
	                y2 = y1 * (1 - percent) + y2 * percent;
	            }
	            ctx.lineTo(x2, y2);
	        },

	        /**
	         * Get point at percent
	         * @param  {number} percent
	         * @return {Array.<number>}
	         */
	        pointAt: function (p) {
	            var shape = this.shape;
	            return [
	                shape.x1 * (1 - p) + shape.x2 * p,
	                shape.y1 * (1 - p) + shape.y2 * p
	            ];
	        }
	    });



/***/ },
/* 62 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	/**
	 * 贝塞尔曲线
	 * @module zrender/shape/BezierCurve
	 */


	    var curveTool = __webpack_require__(37);
	    var vec2 = __webpack_require__(10);
	    var quadraticSubdivide = curveTool.quadraticSubdivide;
	    var cubicSubdivide = curveTool.cubicSubdivide;
	    var quadraticAt = curveTool.quadraticAt;
	    var cubicAt = curveTool.cubicAt;
	    var quadraticDerivativeAt = curveTool.quadraticDerivativeAt;
	    var cubicDerivativeAt = curveTool.cubicDerivativeAt;

	    var out = [];

	    function someVectorAt(shape, t, isTangent) {
	        var cpx2 = shape.cpx2;
	        var cpy2 = shape.cpy2;
	        if (cpx2 === null || cpy2 === null) {
	            return [
	                (isTangent ? cubicDerivativeAt : cubicAt)(shape.x1, shape.cpx1, shape.cpx2, shape.x2, t),
	                (isTangent ? cubicDerivativeAt : cubicAt)(shape.y1, shape.cpy1, shape.cpy2, shape.y2, t)
	            ];
	        }
	        else {
	            return [
	                (isTangent ? quadraticDerivativeAt : quadraticAt)(shape.x1, shape.cpx1, shape.x2, t),
	                (isTangent ? quadraticDerivativeAt : quadraticAt)(shape.y1, shape.cpy1, shape.y2, t)
	            ];
	        }
	    }
	    module.exports = __webpack_require__(20).extend({

	        type: 'bezier-curve',

	        shape: {
	            x1: 0,
	            y1: 0,
	            x2: 0,
	            y2: 0,
	            cpx1: 0,
	            cpy1: 0,
	            // cpx2: 0,
	            // cpy2: 0

	            // Curve show percent, for animating
	            percent: 1
	        },

	        style: {
	            stroke: '#000',
	            fill: null
	        },

	        buildPath: function (ctx, shape) {
	            var x1 = shape.x1;
	            var y1 = shape.y1;
	            var x2 = shape.x2;
	            var y2 = shape.y2;
	            var cpx1 = shape.cpx1;
	            var cpy1 = shape.cpy1;
	            var cpx2 = shape.cpx2;
	            var cpy2 = shape.cpy2;
	            var percent = shape.percent;
	            if (percent === 0) {
	                return;
	            }

	            ctx.moveTo(x1, y1);

	            if (cpx2 == null || cpy2 == null) {
	                if (percent < 1) {
	                    quadraticSubdivide(
	                        x1, cpx1, x2, percent, out
	                    );
	                    cpx1 = out[1];
	                    x2 = out[2];
	                    quadraticSubdivide(
	                        y1, cpy1, y2, percent, out
	                    );
	                    cpy1 = out[1];
	                    y2 = out[2];
	                }

	                ctx.quadraticCurveTo(
	                    cpx1, cpy1,
	                    x2, y2
	                );
	            }
	            else {
	                if (percent < 1) {
	                    cubicSubdivide(
	                        x1, cpx1, cpx2, x2, percent, out
	                    );
	                    cpx1 = out[1];
	                    cpx2 = out[2];
	                    x2 = out[3];
	                    cubicSubdivide(
	                        y1, cpy1, cpy2, y2, percent, out
	                    );
	                    cpy1 = out[1];
	                    cpy2 = out[2];
	                    y2 = out[3];
	                }
	                ctx.bezierCurveTo(
	                    cpx1, cpy1,
	                    cpx2, cpy2,
	                    x2, y2
	                );
	            }
	        },

	        /**
	         * Get point at percent
	         * @param  {number} t
	         * @return {Array.<number>}
	         */
	        pointAt: function (t) {
	            return someVectorAt(this.shape, t, false);
	        },

	        /**
	         * Get tangent at percent
	         * @param  {number} t
	         * @return {Array.<number>}
	         */
	        tangentAt: function (t) {
	            var p = someVectorAt(this.shape, t, true);
	            return vec2.normalize(p, p);
	        }
	    });



/***/ },
/* 63 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * 圆弧
	 * @module zrender/graphic/shape/Arc
	 */
	 

	    module.exports = __webpack_require__(20).extend({

	        type: 'arc',

	        shape: {

	            cx: 0,

	            cy: 0,

	            r: 0,

	            startAngle: 0,

	            endAngle: Math.PI * 2,

	            clockwise: true
	        },

	        style: {

	            stroke: '#000',

	            fill: null
	        },

	        buildPath: function (ctx, shape) {

	            var x = shape.cx;
	            var y = shape.cy;
	            var r = Math.max(shape.r, 0);
	            var startAngle = shape.startAngle;
	            var endAngle = shape.endAngle;
	            var clockwise = shape.clockwise;

	            var unitX = Math.cos(startAngle);
	            var unitY = Math.sin(startAngle);

	            ctx.moveTo(unitX * r + x, unitY * r + y);
	            ctx.arc(x, y, r, startAngle, endAngle, !clockwise);
	        }
	    });


/***/ },
/* 64 */
/***/ function(module, exports, __webpack_require__) {

	// CompoundPath to improve performance


	    var Path = __webpack_require__(20);

	    module.exports = Path.extend({

	        type: 'compound',

	        shape: {

	            paths: null
	        },

	        _updatePathDirty: function () {
	            var dirtyPath = this.__dirtyPath;
	            var paths = this.shape.paths;
	            for (var i = 0; i < paths.length; i++) {
	                // Mark as dirty if any subpath is dirty
	                dirtyPath = dirtyPath || paths[i].__dirtyPath;
	            }
	            this.__dirtyPath = dirtyPath;
	            this.__dirty = this.__dirty || dirtyPath;
	        },

	        beforeBrush: function () {
	            this._updatePathDirty();
	            var paths = this.shape.paths || [];
	            var scale = this.getGlobalScale();
	            // Update path scale
	            for (var i = 0; i < paths.length; i++) {
	                if (!paths[i].path) {
	                    paths[i].createPathProxy();
	                }
	                paths[i].path.setScale(scale[0], scale[1]);
	            }
	        },

	        buildPath: function (ctx, shape) {
	            var paths = shape.paths || [];
	            for (var i = 0; i < paths.length; i++) {
	                paths[i].buildPath(ctx, paths[i].shape, true);
	            }
	        },

	        afterBrush: function () {
	            var paths = this.shape.paths;
	            for (var i = 0; i < paths.length; i++) {
	                paths[i].__dirtyPath = false;
	            }
	        },

	        getBoundingRect: function () {
	            this._updatePathDirty();
	            return Path.prototype.getBoundingRect.call(this);
	        }
	    });


/***/ },
/* 65 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var zrUtil = __webpack_require__(4);

	    var Gradient = __webpack_require__(66);

	    /**
	     * x, y, x2, y2 are all percent from 0 to 1
	     * @param {number} [x=0]
	     * @param {number} [y=0]
	     * @param {number} [x2=1]
	     * @param {number} [y2=0]
	     * @param {Array.<Object>} colorStops
	     * @param {boolean} [globalCoord=false]
	     */
	    var LinearGradient = function (x, y, x2, y2, colorStops, globalCoord) {
	        // Should do nothing more in this constructor. Because gradient can be
	        // declard by `color: {type: 'linear', colorStops: ...}`, where
	        // this constructor will not be called.

	        this.x = x == null ? 0 : x;

	        this.y = y == null ? 0 : y;

	        this.x2 = x2 == null ? 1 : x2;

	        this.y2 = y2 == null ? 0 : y2;

	        // Can be cloned
	        this.type = 'linear';

	        // If use global coord
	        this.global = globalCoord || false;

	        Gradient.call(this, colorStops);
	    };

	    LinearGradient.prototype = {

	        constructor: LinearGradient
	    };

	    zrUtil.inherits(LinearGradient, Gradient);

	    module.exports = LinearGradient;


/***/ },
/* 66 */
/***/ function(module, exports) {

	

	    /**
	     * @param {Array.<Object>} colorStops
	     */
	    var Gradient = function (colorStops) {

	        this.colorStops = colorStops || [];
	    };

	    Gradient.prototype = {

	        constructor: Gradient,

	        addColorStop: function (offset, color) {
	            this.colorStops.push({

	                offset: offset,

	                color: color
	            });
	        }
	    };

	    module.exports = Gradient;


/***/ },
/* 67 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var zrUtil = __webpack_require__(4);

	    var Gradient = __webpack_require__(66);

	    /**
	     * x, y, r are all percent from 0 to 1
	     * @param {number} [x=0.5]
	     * @param {number} [y=0.5]
	     * @param {number} [r=0.5]
	     * @param {Array.<Object>} [colorStops]
	     * @param {boolean} [globalCoord=false]
	     */
	    var RadialGradient = function (x, y, r, colorStops, globalCoord) {
	        // Should do nothing more in this constructor. Because gradient can be
	        // declard by `color: {type: 'radial', colorStops: ...}`, where
	        // this constructor will not be called.

	        this.x = x == null ? 0.5 : x;

	        this.y = y == null ? 0.5 : y;

	        this.r = r == null ? 0.5 : r;

	        // Can be cloned
	        this.type = 'radial';

	        // If use global coord
	        this.global = globalCoord || false;

	        Gradient.call(this, colorStops);
	    };

	    RadialGradient.prototype = {

	        constructor: RadialGradient
	    };

	    zrUtil.inherits(RadialGradient, Gradient);

	    module.exports = RadialGradient;


/***/ },
/* 68 */
/***/ function(module, exports, __webpack_require__) {

	
	    var getItemStyle = __webpack_require__(15)(
	        [
	            ['fill', 'color'],
	            ['stroke', 'borderColor'],
	            ['lineWidth', 'borderWidth'],
	            ['opacity'],
	            ['shadowBlur'],
	            ['shadowOffsetX'],
	            ['shadowOffsetY'],
	            ['shadowColor'],
	            ['textPosition'],
	            ['textAlign']
	        ]
	    );
	    module.exports = {
	        getItemStyle: function (excludes, includes) {
	            var style = getItemStyle.call(this, excludes, includes);
	            var lineDash = this.getBorderLineDash();
	            lineDash && (style.lineDash = lineDash);
	            return style;
	        },

	        getBorderLineDash: function () {
	            var lineType = this.get('borderType');
	            return (lineType === 'solid' || lineType == null) ? null
	                : (lineType === 'dashed' ? [5, 5] : [1, 1]);
	        }
	    };


/***/ },
/* 69 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * Component model
	 *
	 * @module echarts/model/Component
	 */


	    var Model = __webpack_require__(12);
	    var zrUtil = __webpack_require__(4);
	    var arrayPush = Array.prototype.push;
	    var componentUtil = __webpack_require__(70);
	    var clazzUtil = __webpack_require__(13);
	    var layout = __webpack_require__(71);

	    /**
	     * @alias module:echarts/model/Component
	     * @constructor
	     * @param {Object} option
	     * @param {module:echarts/model/Model} parentModel
	     * @param {module:echarts/model/Model} ecModel
	     */
	    var ComponentModel = Model.extend({

	        type: 'component',

	        /**
	         * @readOnly
	         * @type {string}
	         */
	        id: '',

	        /**
	         * @readOnly
	         */
	        name: '',

	        /**
	         * @readOnly
	         * @type {string}
	         */
	        mainType: '',

	        /**
	         * @readOnly
	         * @type {string}
	         */
	        subType: '',

	        /**
	         * @readOnly
	         * @type {number}
	         */
	        componentIndex: 0,

	        /**
	         * @type {Object}
	         * @protected
	         */
	        defaultOption: null,

	        /**
	         * @type {module:echarts/model/Global}
	         * @readOnly
	         */
	        ecModel: null,

	        /**
	         * key: componentType
	         * value:  Component model list, can not be null.
	         * @type {Object.<string, Array.<module:echarts/model/Model>>}
	         * @readOnly
	         */
	        dependentModels: [],

	        /**
	         * @type {string}
	         * @readOnly
	         */
	        uid: null,

	        /**
	         * Support merge layout params.
	         * Only support 'box' now (left/right/top/bottom/width/height).
	         * @type {string|Object} Object can be {ignoreSize: true}
	         * @readOnly
	         */
	        layoutMode: null,

	        $constructor: function (option, parentModel, ecModel, extraOpt) {
	            Model.call(this, option, parentModel, ecModel, extraOpt);

	            this.uid = componentUtil.getUID('componentModel');
	        },


	        init: function (option, parentModel, ecModel, extraOpt) {
	            this.mergeDefaultAndTheme(option, ecModel);
	        },

	        mergeDefaultAndTheme: function (option, ecModel) {
	            var layoutMode = this.layoutMode;
	            var inputPositionParams = layoutMode
	                ? layout.getLayoutParams(option) : {};

	            var themeModel = ecModel.getTheme();
	            zrUtil.merge(option, themeModel.get(this.mainType));
	            zrUtil.merge(option, this.getDefaultOption());

	            if (layoutMode) {
	                layout.mergeLayoutParam(option, inputPositionParams, layoutMode);
	            }
	        },

	        mergeOption: function (option, extraOpt) {
	            zrUtil.merge(this.option, option, true);

	            var layoutMode = this.layoutMode;
	            if (layoutMode) {
	                layout.mergeLayoutParam(this.option, option, layoutMode);
	            }
	        },

	        // Hooker after init or mergeOption
	        optionUpdated: function (newCptOption, isInit) {},

	        getDefaultOption: function () {
	            if (!clazzUtil.hasOwn(this, '__defaultOption')) {
	                var optList = [];
	                var Class = this.constructor;
	                while (Class) {
	                    var opt = Class.prototype.defaultOption;
	                    opt && optList.push(opt);
	                    Class = Class.superClass;
	                }

	                var defaultOption = {};
	                for (var i = optList.length - 1; i >= 0; i--) {
	                    defaultOption = zrUtil.merge(defaultOption, optList[i], true);
	                }
	                clazzUtil.set(this, '__defaultOption', defaultOption);
	            }
	            return clazzUtil.get(this, '__defaultOption');
	        },

	        getReferringComponents: function (mainType) {
	            return this.ecModel.queryComponents({
	                mainType: mainType,
	                index: this.get(mainType + 'Index', true),
	                id: this.get(mainType + 'Id', true)
	            });
	        }

	    });

	    // Reset ComponentModel.extend, add preConstruct.
	    // clazzUtil.enableClassExtend(
	    //     ComponentModel,
	    //     function (option, parentModel, ecModel, extraOpt) {
	    //         // Set dependentModels, componentIndex, name, id, mainType, subType.
	    //         zrUtil.extend(this, extraOpt);

	    //         this.uid = componentUtil.getUID('componentModel');

	    //         // this.setReadOnly([
	    //         //     'type', 'id', 'uid', 'name', 'mainType', 'subType',
	    //         //     'dependentModels', 'componentIndex'
	    //         // ]);
	    //     }
	    // );

	    // Add capability of registerClass, getClass, hasClass, registerSubTypeDefaulter and so on.
	    clazzUtil.enableClassManagement(
	        ComponentModel, {registerWhenExtend: true}
	    );
	    componentUtil.enableSubTypeDefaulter(ComponentModel);

	    // Add capability of ComponentModel.topologicalTravel.
	    componentUtil.enableTopologicalTravel(ComponentModel, getDependencies);

	    function getDependencies(componentType) {
	        var deps = [];
	        zrUtil.each(ComponentModel.getClassesByMainType(componentType), function (Clazz) {
	            arrayPush.apply(deps, Clazz.prototype.dependencies || []);
	        });
	        // Ensure main type
	        return zrUtil.map(deps, function (type) {
	            return clazzUtil.parseClassType(type).main;
	        });
	    }

	    zrUtil.mixin(ComponentModel, __webpack_require__(72));

	    module.exports = ComponentModel;


/***/ },
/* 70 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);
	    var clazz = __webpack_require__(13);

	    var parseClassType = clazz.parseClassType;

	    var base = 0;

	    var componentUtil = {};

	    var DELIMITER = '_';

	    /**
	     * @public
	     * @param {string} type
	     * @return {string}
	     */
	    componentUtil.getUID = function (type) {
	        // Considering the case of crossing js context,
	        // use Math.random to make id as unique as possible.
	        return [(type || ''), base++, Math.random()].join(DELIMITER);
	    };

	    /**
	     * @inner
	     */
	    componentUtil.enableSubTypeDefaulter = function (entity) {

	        var subTypeDefaulters = {};

	        entity.registerSubTypeDefaulter = function (componentType, defaulter) {
	            componentType = parseClassType(componentType);
	            subTypeDefaulters[componentType.main] = defaulter;
	        };

	        entity.determineSubType = function (componentType, option) {
	            var type = option.type;
	            if (!type) {
	                var componentTypeMain = parseClassType(componentType).main;
	                if (entity.hasSubTypes(componentType) && subTypeDefaulters[componentTypeMain]) {
	                    type = subTypeDefaulters[componentTypeMain](option);
	                }
	            }
	            return type;
	        };

	        return entity;
	    };

	    /**
	     * Topological travel on Activity Network (Activity On Vertices).
	     * Dependencies is defined in Model.prototype.dependencies, like ['xAxis', 'yAxis'].
	     *
	     * If 'xAxis' or 'yAxis' is absent in componentTypeList, just ignore it in topology.
	     *
	     * If there is circle dependencey, Error will be thrown.
	     *
	     */
	    componentUtil.enableTopologicalTravel = function (entity, dependencyGetter) {

	        /**
	         * @public
	         * @param {Array.<string>} targetNameList Target Component type list.
	         *                                           Can be ['aa', 'bb', 'aa.xx']
	         * @param {Array.<string>} fullNameList By which we can build dependency graph.
	         * @param {Function} callback Params: componentType, dependencies.
	         * @param {Object} context Scope of callback.
	         */
	        entity.topologicalTravel = function (targetNameList, fullNameList, callback, context) {
	            if (!targetNameList.length) {
	                return;
	            }

	            var result = makeDepndencyGraph(fullNameList);
	            var graph = result.graph;
	            var stack = result.noEntryList;

	            var targetNameSet = {};
	            zrUtil.each(targetNameList, function (name) {
	                targetNameSet[name] = true;
	            });

	            while (stack.length) {
	                var currComponentType = stack.pop();
	                var currVertex = graph[currComponentType];
	                var isInTargetNameSet = !!targetNameSet[currComponentType];
	                if (isInTargetNameSet) {
	                    callback.call(context, currComponentType, currVertex.originalDeps.slice());
	                    delete targetNameSet[currComponentType];
	                }
	                zrUtil.each(
	                    currVertex.successor,
	                    isInTargetNameSet ? removeEdgeAndAdd : removeEdge
	                );
	            }

	            zrUtil.each(targetNameSet, function () {
	                throw new Error('Circle dependency may exists');
	            });

	            function removeEdge(succComponentType) {
	                graph[succComponentType].entryCount--;
	                if (graph[succComponentType].entryCount === 0) {
	                    stack.push(succComponentType);
	                }
	            }

	            // Consider this case: legend depends on series, and we call
	            // chart.setOption({series: [...]}), where only series is in option.
	            // If we do not have 'removeEdgeAndAdd', legendModel.mergeOption will
	            // not be called, but only sereis.mergeOption is called. Thus legend
	            // have no chance to update its local record about series (like which
	            // name of series is available in legend).
	            function removeEdgeAndAdd(succComponentType) {
	                targetNameSet[succComponentType] = true;
	                removeEdge(succComponentType);
	            }
	        };

	        /**
	         * DepndencyGraph: {Object}
	         * key: conponentType,
	         * value: {
	         *     successor: [conponentTypes...],
	         *     originalDeps: [conponentTypes...],
	         *     entryCount: {number}
	         * }
	         */
	        function makeDepndencyGraph(fullNameList) {
	            var graph = {};
	            var noEntryList = [];

	            zrUtil.each(fullNameList, function (name) {

	                var thisItem = createDependencyGraphItem(graph, name);
	                var originalDeps = thisItem.originalDeps = dependencyGetter(name);

	                var availableDeps = getAvailableDependencies(originalDeps, fullNameList);
	                thisItem.entryCount = availableDeps.length;
	                if (thisItem.entryCount === 0) {
	                    noEntryList.push(name);
	                }

	                zrUtil.each(availableDeps, function (dependentName) {
	                    if (zrUtil.indexOf(thisItem.predecessor, dependentName) < 0) {
	                        thisItem.predecessor.push(dependentName);
	                    }
	                    var thatItem = createDependencyGraphItem(graph, dependentName);
	                    if (zrUtil.indexOf(thatItem.successor, dependentName) < 0) {
	                        thatItem.successor.push(name);
	                    }
	                });
	            });

	            return {graph: graph, noEntryList: noEntryList};
	        }

	        function createDependencyGraphItem(graph, name) {
	            if (!graph[name]) {
	                graph[name] = {predecessor: [], successor: []};
	            }
	            return graph[name];
	        }

	        function getAvailableDependencies(originalDeps, fullNameList) {
	            var availableDeps = [];
	            zrUtil.each(originalDeps, function (dep) {
	                zrUtil.indexOf(fullNameList, dep) >= 0 && availableDeps.push(dep);
	            });
	            return availableDeps;
	        }
	    };

	    module.exports = componentUtil;


/***/ },
/* 71 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	// Layout helpers for each component positioning


	    var zrUtil = __webpack_require__(4);
	    var BoundingRect = __webpack_require__(9);
	    var numberUtil = __webpack_require__(7);
	    var formatUtil = __webpack_require__(6);
	    var parsePercent = numberUtil.parsePercent;
	    var each = zrUtil.each;

	    var layout = {};

	    /**
	     * @public
	     */
	    var LOCATION_PARAMS = layout.LOCATION_PARAMS = [
	        'left', 'right', 'top', 'bottom', 'width', 'height'
	    ];

	    /**
	     * @public
	     */
	    var HV_NAMES = layout.HV_NAMES = [
	        ['width', 'left', 'right'],
	        ['height', 'top', 'bottom']
	    ];

	    function boxLayout(orient, group, gap, maxWidth, maxHeight) {
	        var x = 0;
	        var y = 0;
	        if (maxWidth == null) {
	            maxWidth = Infinity;
	        }
	        if (maxHeight == null) {
	            maxHeight = Infinity;
	        }
	        var currentLineMaxSize = 0;
	        group.eachChild(function (child, idx) {
	            var position = child.position;
	            var rect = child.getBoundingRect();
	            var nextChild = group.childAt(idx + 1);
	            var nextChildRect = nextChild && nextChild.getBoundingRect();
	            var nextX;
	            var nextY;
	            if (orient === 'horizontal') {
	                var moveX = rect.width + (nextChildRect ? (-nextChildRect.x + rect.x) : 0);
	                nextX = x + moveX;
	                // Wrap when width exceeds maxWidth or meet a `newline` group
	                if (nextX > maxWidth || child.newline) {
	                    x = 0;
	                    nextX = moveX;
	                    y += currentLineMaxSize + gap;
	                    currentLineMaxSize = rect.height;
	                }
	                else {
	                    currentLineMaxSize = Math.max(currentLineMaxSize, rect.height);
	                }
	            }
	            else {
	                var moveY = rect.height + (nextChildRect ? (-nextChildRect.y + rect.y) : 0);
	                nextY = y + moveY;
	                // Wrap when width exceeds maxHeight or meet a `newline` group
	                if (nextY > maxHeight || child.newline) {
	                    x += currentLineMaxSize + gap;
	                    y = 0;
	                    nextY = moveY;
	                    currentLineMaxSize = rect.width;
	                }
	                else {
	                    currentLineMaxSize = Math.max(currentLineMaxSize, rect.width);
	                }
	            }

	            if (child.newline) {
	                return;
	            }

	            position[0] = x;
	            position[1] = y;

	            orient === 'horizontal'
	                ? (x = nextX + gap)
	                : (y = nextY + gap);
	        });
	    }

	    /**
	     * VBox or HBox layouting
	     * @param {string} orient
	     * @param {module:zrender/container/Group} group
	     * @param {number} gap
	     * @param {number} [width=Infinity]
	     * @param {number} [height=Infinity]
	     */
	    layout.box = boxLayout;

	    /**
	     * VBox layouting
	     * @param {module:zrender/container/Group} group
	     * @param {number} gap
	     * @param {number} [width=Infinity]
	     * @param {number} [height=Infinity]
	     */
	    layout.vbox = zrUtil.curry(boxLayout, 'vertical');

	    /**
	     * HBox layouting
	     * @param {module:zrender/container/Group} group
	     * @param {number} gap
	     * @param {number} [width=Infinity]
	     * @param {number} [height=Infinity]
	     */
	    layout.hbox = zrUtil.curry(boxLayout, 'horizontal');

	    /**
	     * If x or x2 is not specified or 'center' 'left' 'right',
	     * the width would be as long as possible.
	     * If y or y2 is not specified or 'middle' 'top' 'bottom',
	     * the height would be as long as possible.
	     *
	     * @param {Object} positionInfo
	     * @param {number|string} [positionInfo.x]
	     * @param {number|string} [positionInfo.y]
	     * @param {number|string} [positionInfo.x2]
	     * @param {number|string} [positionInfo.y2]
	     * @param {Object} containerRect
	     * @param {string|number} margin
	     * @return {Object} {width, height}
	     */
	    layout.getAvailableSize = function (positionInfo, containerRect, margin) {
	        var containerWidth = containerRect.width;
	        var containerHeight = containerRect.height;

	        var x = parsePercent(positionInfo.x, containerWidth);
	        var y = parsePercent(positionInfo.y, containerHeight);
	        var x2 = parsePercent(positionInfo.x2, containerWidth);
	        var y2 = parsePercent(positionInfo.y2, containerHeight);

	        (isNaN(x) || isNaN(parseFloat(positionInfo.x))) && (x = 0);
	        (isNaN(x2) || isNaN(parseFloat(positionInfo.x2))) && (x2 = containerWidth);
	        (isNaN(y) || isNaN(parseFloat(positionInfo.y))) && (y = 0);
	        (isNaN(y2) || isNaN(parseFloat(positionInfo.y2))) && (y2 = containerHeight);

	        margin = formatUtil.normalizeCssArray(margin || 0);

	        return {
	            width: Math.max(x2 - x - margin[1] - margin[3], 0),
	            height: Math.max(y2 - y - margin[0] - margin[2], 0)
	        };
	    };

	    /**
	     * Parse position info.
	     *
	     * @param {Object} positionInfo
	     * @param {number|string} [positionInfo.left]
	     * @param {number|string} [positionInfo.top]
	     * @param {number|string} [positionInfo.right]
	     * @param {number|string} [positionInfo.bottom]
	     * @param {number|string} [positionInfo.width]
	     * @param {number|string} [positionInfo.height]
	     * @param {number|string} [positionInfo.aspect] Aspect is width / height
	     * @param {Object} containerRect
	     * @param {string|number} [margin]
	     *
	     * @return {module:zrender/core/BoundingRect}
	     */
	    layout.getLayoutRect = function (
	        positionInfo, containerRect, margin
	    ) {
	        margin = formatUtil.normalizeCssArray(margin || 0);

	        var containerWidth = containerRect.width;
	        var containerHeight = containerRect.height;

	        var left = parsePercent(positionInfo.left, containerWidth);
	        var top = parsePercent(positionInfo.top, containerHeight);
	        var right = parsePercent(positionInfo.right, containerWidth);
	        var bottom = parsePercent(positionInfo.bottom, containerHeight);
	        var width = parsePercent(positionInfo.width, containerWidth);
	        var height = parsePercent(positionInfo.height, containerHeight);

	        var verticalMargin = margin[2] + margin[0];
	        var horizontalMargin = margin[1] + margin[3];
	        var aspect = positionInfo.aspect;

	        // If width is not specified, calculate width from left and right
	        if (isNaN(width)) {
	            width = containerWidth - right - horizontalMargin - left;
	        }
	        if (isNaN(height)) {
	            height = containerHeight - bottom - verticalMargin - top;
	        }

	        // If width and height are not given
	        // 1. Graph should not exceeds the container
	        // 2. Aspect must be keeped
	        // 3. Graph should take the space as more as possible
	        if (isNaN(width) && isNaN(height)) {
	            if (aspect > containerWidth / containerHeight) {
	                width = containerWidth * 0.8;
	            }
	            else {
	                height = containerHeight * 0.8;
	            }
	        }

	        if (aspect != null) {
	            // Calculate width or height with given aspect
	            if (isNaN(width)) {
	                width = aspect * height;
	            }
	            if (isNaN(height)) {
	                height = width / aspect;
	            }
	        }

	        // If left is not specified, calculate left from right and width
	        if (isNaN(left)) {
	            left = containerWidth - right - width - horizontalMargin;
	        }
	        if (isNaN(top)) {
	            top = containerHeight - bottom - height - verticalMargin;
	        }

	        // Align left and top
	        switch (positionInfo.left || positionInfo.right) {
	            case 'center':
	                left = containerWidth / 2 - width / 2 - margin[3];
	                break;
	            case 'right':
	                left = containerWidth - width - horizontalMargin;
	                break;
	        }
	        switch (positionInfo.top || positionInfo.bottom) {
	            case 'middle':
	            case 'center':
	                top = containerHeight / 2 - height / 2 - margin[0];
	                break;
	            case 'bottom':
	                top = containerHeight - height - verticalMargin;
	                break;
	        }
	        // If something is wrong and left, top, width, height are calculated as NaN
	        left = left || 0;
	        top = top || 0;
	        if (isNaN(width)) {
	            // Width may be NaN if only one value is given except width
	            width = containerWidth - left - (right || 0);
	        }
	        if (isNaN(height)) {
	            // Height may be NaN if only one value is given except height
	            height = containerHeight - top - (bottom || 0);
	        }

	        var rect = new BoundingRect(left + margin[3], top + margin[0], width, height);
	        rect.margin = margin;
	        return rect;
	    };


	    /**
	     * Position a zr element in viewport
	     *  Group position is specified by either
	     *  {left, top}, {right, bottom}
	     *  If all properties exists, right and bottom will be igonred.
	     *
	     * Logic:
	     *     1. Scale (against origin point in parent coord)
	     *     2. Rotate (against origin point in parent coord)
	     *     3. Traslate (with el.position by this method)
	     * So this method only fixes the last step 'Traslate', which does not affect
	     * scaling and rotating.
	     *
	     * If be called repeatly with the same input el, the same result will be gotten.
	     *
	     * @param {module:zrender/Element} el Should have `getBoundingRect` method.
	     * @param {Object} positionInfo
	     * @param {number|string} [positionInfo.left]
	     * @param {number|string} [positionInfo.top]
	     * @param {number|string} [positionInfo.right]
	     * @param {number|string} [positionInfo.bottom]
	     * @param {Object} containerRect
	     * @param {string|number} margin
	     * @param {Object} [opt]
	     * @param {Array.<number>} [opt.hv=[1,1]] Only horizontal or only vertical.
	     * @param {Array.<number>} [opt.boundingMode='all']
	     *        Specify how to calculate boundingRect when locating.
	     *        'all': Position the boundingRect that is transformed and uioned
	     *               both itself and its descendants.
	     *               This mode simplies confine the elements in the bounding
	     *               of their container (e.g., using 'right: 0').
	     *        'raw': Position the boundingRect that is not transformed and only itself.
	     *               This mode is useful when you want a element can overflow its
	     *               container. (Consider a rotated circle needs to be located in a corner.)
	     *               In this mode positionInfo.width/height can only be number.
	     */
	    layout.positionElement = function (el, positionInfo, containerRect, margin, opt) {
	        var h = !opt || !opt.hv || opt.hv[0];
	        var v = !opt || !opt.hv || opt.hv[1];
	        var boundingMode = opt && opt.boundingMode || 'all';

	        if (!h && !v) {
	            return;
	        }

	        var rect;
	        if (boundingMode === 'raw') {
	            rect = el.type === 'group'
	                ? new BoundingRect(0, 0, +positionInfo.width || 0, +positionInfo.height || 0)
	                : el.getBoundingRect();
	        }
	        else {
	            rect = el.getBoundingRect();
	            if (el.needLocalTransform()) {
	                var transform = el.getLocalTransform();
	                // Notice: raw rect may be inner object of el,
	                // which should not be modified.
	                rect = rect.clone();
	                rect.applyTransform(transform);
	            }
	        }

	        positionInfo = layout.getLayoutRect(
	            zrUtil.defaults(
	                {width: rect.width, height: rect.height},
	                positionInfo
	            ),
	            containerRect,
	            margin
	        );

	        // Because 'tranlate' is the last step in transform
	        // (see zrender/core/Transformable#getLocalTransfrom),
	        // we can just only modify el.position to get final result.
	        var elPos = el.position;
	        var dx = h ? positionInfo.x - rect.x : 0;
	        var dy = v ? positionInfo.y - rect.y : 0;

	        el.attr('position', boundingMode === 'raw' ? [dx, dy] : [elPos[0] + dx, elPos[1] + dy]);
	    };

	    /**
	     * @param {Object} option Contains some of the properties in HV_NAMES.
	     * @param {number} hvIdx 0: horizontal; 1: vertical.
	     */
	    layout.sizeCalculable = function (option, hvIdx) {
	        return option[HV_NAMES[hvIdx][0]] != null
	            || (option[HV_NAMES[hvIdx][1]] != null && option[HV_NAMES[hvIdx][2]] != null);
	    };

	    /**
	     * Consider Case:
	     * When defulat option has {left: 0, width: 100}, and we set {right: 0}
	     * through setOption or media query, using normal zrUtil.merge will cause
	     * {right: 0} does not take effect.
	     *
	     * @example
	     * ComponentModel.extend({
	     *     init: function () {
	     *         ...
	     *         var inputPositionParams = layout.getLayoutParams(option);
	     *         this.mergeOption(inputPositionParams);
	     *     },
	     *     mergeOption: function (newOption) {
	     *         newOption && zrUtil.merge(thisOption, newOption, true);
	     *         layout.mergeLayoutParam(thisOption, newOption);
	     *     }
	     * });
	     *
	     * @param {Object} targetOption
	     * @param {Object} newOption
	     * @param {Object|string} [opt]
	     * @param {boolean|Array.<boolean>} [opt.ignoreSize=false] Some component must has width and height.
	     */
	    layout.mergeLayoutParam = function (targetOption, newOption, opt) {
	        !zrUtil.isObject(opt) && (opt = {});

	        var ignoreSize = opt.ignoreSize;
	        !zrUtil.isArray(ignoreSize) && (ignoreSize = [ignoreSize, ignoreSize]);

	        var hResult = merge(HV_NAMES[0], 0);
	        var vResult = merge(HV_NAMES[1], 1);

	        copy(HV_NAMES[0], targetOption, hResult);
	        copy(HV_NAMES[1], targetOption, vResult);

	        function merge(names, hvIdx) {
	            var newParams = {};
	            var newValueCount = 0;
	            var merged = {};
	            var mergedValueCount = 0;
	            var enoughParamNumber = 2;

	            each(names, function (name) {
	                merged[name] = targetOption[name];
	            });
	            each(names, function (name) {
	                // Consider case: newOption.width is null, which is
	                // set by user for removing width setting.
	                hasProp(newOption, name) && (newParams[name] = merged[name] = newOption[name]);
	                hasValue(newParams, name) && newValueCount++;
	                hasValue(merged, name) && mergedValueCount++;
	            });

	            if (ignoreSize[hvIdx]) {
	                // Only one of left/right is premitted to exist.
	                if (hasValue(newOption, names[1])) {
	                    merged[names[2]] = null;
	                }
	                else if (hasValue(newOption, names[2])) {
	                    merged[names[1]] = null;
	                }
	                return merged;
	            }

	            // Case: newOption: {width: ..., right: ...},
	            // or targetOption: {right: ...} and newOption: {width: ...},
	            // There is no conflict when merged only has params count
	            // little than enoughParamNumber.
	            if (mergedValueCount === enoughParamNumber || !newValueCount) {
	                return merged;
	            }
	            // Case: newOption: {width: ..., right: ...},
	            // Than we can make sure user only want those two, and ignore
	            // all origin params in targetOption.
	            else if (newValueCount >= enoughParamNumber) {
	                return newParams;
	            }
	            else {
	                // Chose another param from targetOption by priority.
	                for (var i = 0; i < names.length; i++) {
	                    var name = names[i];
	                    if (!hasProp(newParams, name) && hasProp(targetOption, name)) {
	                        newParams[name] = targetOption[name];
	                        break;
	                    }
	                }
	                return newParams;
	            }
	        }

	        function hasProp(obj, name) {
	            return obj.hasOwnProperty(name);
	        }

	        function hasValue(obj, name) {
	            return obj[name] != null && obj[name] !== 'auto';
	        }

	        function copy(names, target, source) {
	            each(names, function (name) {
	                target[name] = source[name];
	            });
	        }
	    };

	    /**
	     * Retrieve 'left', 'right', 'top', 'bottom', 'width', 'height' from object.
	     * @param {Object} source
	     * @return {Object} Result contains those props.
	     */
	    layout.getLayoutParams = function (source) {
	        return layout.copyLayoutParams({}, source);
	    };

	    /**
	     * Retrieve 'left', 'right', 'top', 'bottom', 'width', 'height' from object.
	     * @param {Object} source
	     * @return {Object} Result contains those props.
	     */
	    layout.copyLayoutParams = function (target, source) {
	        source && target && each(LOCATION_PARAMS, function (name) {
	            source.hasOwnProperty(name) && (target[name] = source[name]);
	        });
	        return target;
	    };

	    module.exports = layout;



/***/ },
/* 72 */
/***/ function(module, exports) {

	

	    module.exports = {
	        getBoxLayoutParams: function () {
	            return {
	                left: this.get('left'),
	                top: this.get('top'),
	                right: this.get('right'),
	                bottom: this.get('bottom'),
	                width: this.get('width'),
	                height: this.get('height')
	            };
	        }
	    };


/***/ },
/* 73 */
/***/ function(module, exports) {

	
	    var platform = '';
	    // Navigator not exists in node
	    if (typeof navigator !== 'undefined') {
	        platform = navigator.platform || '';
	    }
	    module.exports = {
	        // 全图默认背景
	        // backgroundColor: 'rgba(0,0,0,0)',

	        // https://dribbble.com/shots/1065960-Infographic-Pie-chart-visualization
	        // color: ['#5793f3', '#d14a61', '#fd9c35', '#675bba', '#fec42c', '#dd4444', '#d4df5a', '#cd4870'],
	        // 浅色
	        // color: ['#bcd3bb', '#e88f70', '#edc1a5', '#9dc5c8', '#e1e8c8', '#7b7c68', '#e5b5b5', '#f0b489', '#928ea8', '#bda29a'],
	        // color: ['#cc5664', '#9bd6ec', '#ea946e', '#8acaaa', '#f1ec64', '#ee8686', '#a48dc1', '#5da6bc', '#b9dcae'],
	        // 深色
	        color: ['#c23531','#2f4554', '#61a0a8', '#d48265', '#91c7ae','#749f83',  '#ca8622', '#bda29a','#6e7074', '#546570', '#c4ccd3'],

	        // 默认需要 Grid 配置项
	        // grid: {},
	        // 主题，主题
	        textStyle: {
	            // color: '#000',
	            // decoration: 'none',
	            // PENDING
	            fontFamily: platform.match(/^Win/) ? 'Microsoft YaHei' : 'sans-serif',
	            // fontFamily: 'Arial, Verdana, sans-serif',
	            fontSize: 12,
	            fontStyle: 'normal',
	            fontWeight: 'normal'
	        },

	        // http://blogs.adobe.com/webplatform/2014/02/24/using-blend-modes-in-html-canvas/
	        // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation
	        // Default is source-over
	        blendMode: null,

	        animation: 'auto',
	        animationDuration: 1000,
	        animationDurationUpdate: 300,
	        animationEasing: 'exponentialOut',
	        animationEasingUpdate: 'cubicOut',

	        animationThreshold: 2000,
	        // Configuration for progressive/incremental rendering
	        progressiveThreshold: 3000,
	        progressive: 400,

	        // Threshold of if use single hover layer to optimize.
	        // It is recommended that `hoverLayerThreshold` is equivalent to or less than
	        // `progressiveThreshold`, otherwise hover will cause restart of progressive,
	        // which is unexpected.
	        // see example <echarts/test/heatmap-large.html>.
	        hoverLayerThreshold: 3000,

	        // See: module:echarts/scale/Time
	        useUTC: false
	    };


/***/ },
/* 74 */
/***/ function(module, exports, __webpack_require__) {

	

	    var classUtil = __webpack_require__(13);
	    var set = classUtil.set;
	    var get = classUtil.get;

	    module.exports = {
	        clearColorPalette: function () {
	            set(this, 'colorIdx', 0);
	            set(this, 'colorNameMap', {});
	        },

	        getColorFromPalette: function (name, scope) {
	            scope = scope || this;
	            var colorIdx = get(scope, 'colorIdx') || 0;
	            var colorNameMap = get(scope, 'colorNameMap') || set(scope, 'colorNameMap', {});
	            // Use `hasOwnProperty` to avoid conflict with Object.prototype.
	            if (colorNameMap.hasOwnProperty(name)) {
	                return colorNameMap[name];
	            }
	            var colorPalette = this.get('color', true) || [];
	            if (!colorPalette.length) {
	                return;
	            }

	            var color = colorPalette[colorIdx];
	            if (name) {
	                colorNameMap[name] = color;
	            }
	            set(scope, 'colorIdx', (colorIdx + 1) % colorPalette.length);

	            return color;
	        }
	    };


/***/ },
/* 75 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var zrUtil = __webpack_require__(4);

	    var echartsAPIList = [
	        'getDom', 'getZr', 'getWidth', 'getHeight', 'getDevicePixelRatio', 'dispatchAction', 'isDisposed',
	        'on', 'off', 'getDataURL', 'getConnectedDataURL', 'getModel', 'getOption',
	        'getViewOfComponentModel', 'getViewOfSeriesModel'
	    ];
	    // And `getCoordinateSystems` and `getComponentByElement` will be injected in echarts.js

	    function ExtensionAPI(chartInstance) {
	        zrUtil.each(echartsAPIList, function (name) {
	            this[name] = zrUtil.bind(chartInstance[name], chartInstance);
	        }, this);
	    }

	    module.exports = ExtensionAPI;


/***/ },
/* 76 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var zrUtil = __webpack_require__(4);

	    var coordinateSystemCreators = {};

	    function CoordinateSystemManager() {

	        this._coordinateSystems = [];
	    }

	    CoordinateSystemManager.prototype = {

	        constructor: CoordinateSystemManager,

	        create: function (ecModel, api) {
	            var coordinateSystems = [];
	            zrUtil.each(coordinateSystemCreators, function (creater, type) {
	                var list = creater.create(ecModel, api);
	                coordinateSystems = coordinateSystems.concat(list || []);
	            });

	            this._coordinateSystems = coordinateSystems;
	        },

	        update: function (ecModel, api) {
	            zrUtil.each(this._coordinateSystems, function (coordSys) {
	                // FIXME MUST have
	                coordSys.update && coordSys.update(ecModel, api);
	            });
	        },

	        getCoordinateSystems: function () {
	            return this._coordinateSystems.slice();
	        }
	    };

	    CoordinateSystemManager.register = function (type, coordinateSystemCreator) {
	        coordinateSystemCreators[type] = coordinateSystemCreator;
	    };

	    CoordinateSystemManager.get = function (type) {
	        return coordinateSystemCreators[type];
	    };

	    module.exports = CoordinateSystemManager;


/***/ },
/* 77 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * ECharts option manager
	 *
	 * @module {echarts/model/OptionManager}
	 */



	    var zrUtil = __webpack_require__(4);
	    var modelUtil = __webpack_require__(5);
	    var ComponentModel = __webpack_require__(69);
	    var each = zrUtil.each;
	    var clone = zrUtil.clone;
	    var map = zrUtil.map;
	    var merge = zrUtil.merge;

	    var QUERY_REG = /^(min|max)?(.+)$/;

	    /**
	     * TERM EXPLANATIONS:
	     *
	     * [option]:
	     *
	     *     An object that contains definitions of components. For example:
	     *     var option = {
	     *         title: {...},
	     *         legend: {...},
	     *         visualMap: {...},
	     *         series: [
	     *             {data: [...]},
	     *             {data: [...]},
	     *             ...
	     *         ]
	     *     };
	     *
	     * [rawOption]:
	     *
	     *     An object input to echarts.setOption. 'rawOption' may be an
	     *     'option', or may be an object contains multi-options. For example:
	     *     var option = {
	     *         baseOption: {
	     *             title: {...},
	     *             legend: {...},
	     *             series: [
	     *                 {data: [...]},
	     *                 {data: [...]},
	     *                 ...
	     *             ]
	     *         },
	     *         timeline: {...},
	     *         options: [
	     *             {title: {...}, series: {data: [...]}},
	     *             {title: {...}, series: {data: [...]}},
	     *             ...
	     *         ],
	     *         media: [
	     *             {
	     *                 query: {maxWidth: 320},
	     *                 option: {series: {x: 20}, visualMap: {show: false}}
	     *             },
	     *             {
	     *                 query: {minWidth: 320, maxWidth: 720},
	     *                 option: {series: {x: 500}, visualMap: {show: true}}
	     *             },
	     *             {
	     *                 option: {series: {x: 1200}, visualMap: {show: true}}
	     *             }
	     *         ]
	     *     };
	     *
	     * @alias module:echarts/model/OptionManager
	     * @param {module:echarts/ExtensionAPI} api
	     */
	    function OptionManager(api) {

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

	        /**
	         * @private
	         * @type {Array.<number>}
	         */
	        this._timelineOptions = [];

	        /**
	         * @private
	         * @type {Array.<Object>}
	         */
	        this._mediaList = [];

	        /**
	         * @private
	         * @type {Object}
	         */
	        this._mediaDefault;

	        /**
	         * -1, means default.
	         * empty means no media.
	         * @private
	         * @type {Array.<number>}
	         */
	        this._currentMediaIndices = [];

	        /**
	         * @private
	         * @type {Object}
	         */
	        this._optionBackup;

	        /**
	         * @private
	         * @type {Object}
	         */
	        this._newBaseOption;
	    }

	    // timeline.notMerge is not supported in ec3. Firstly there is rearly
	    // case that notMerge is needed. Secondly supporting 'notMerge' requires
	    // rawOption cloned and backuped when timeline changed, which does no
	    // good to performance. What's more, that both timeline and setOption
	    // method supply 'notMerge' brings complex and some problems.
	    // Consider this case:
	    // (step1) chart.setOption({timeline: {notMerge: false}, ...}, false);
	    // (step2) chart.setOption({timeline: {notMerge: true}, ...}, false);

	    OptionManager.prototype = {

	        constructor: OptionManager,

	        /**
	         * @public
	         * @param {Object} rawOption Raw option.
	         * @param {module:echarts/model/Global} ecModel
	         * @param {Array.<Function>} optionPreprocessorFuncs
	         * @return {Object} Init option
	         */
	        setOption: function (rawOption, optionPreprocessorFuncs) {
	            rawOption = clone(rawOption, true);

	            // FIXME
	            // 如果 timeline options 或者 media 中设置了某个属性，而baseOption中没有设置，则进行警告。

	            var oldOptionBackup = this._optionBackup;
	            var newParsedOption = parseRawOption.call(
	                this, rawOption, optionPreprocessorFuncs, !oldOptionBackup
	            );
	            this._newBaseOption = newParsedOption.baseOption;

	            // For setOption at second time (using merge mode);
	            if (oldOptionBackup) {
	                // Only baseOption can be merged.
	                mergeOption(oldOptionBackup.baseOption, newParsedOption.baseOption);

	                // For simplicity, timeline options and media options do not support merge,
	                // that is, if you `setOption` twice and both has timeline options, the latter
	                // timeline opitons will not be merged to the formers, but just substitude them.
	                if (newParsedOption.timelineOptions.length) {
	                    oldOptionBackup.timelineOptions = newParsedOption.timelineOptions;
	                }
	                if (newParsedOption.mediaList.length) {
	                    oldOptionBackup.mediaList = newParsedOption.mediaList;
	                }
	                if (newParsedOption.mediaDefault) {
	                    oldOptionBackup.mediaDefault = newParsedOption.mediaDefault;
	                }
	            }
	            else {
	                this._optionBackup = newParsedOption;
	            }
	        },

	        /**
	         * @param {boolean} isRecreate
	         * @return {Object}
	         */
	        mountOption: function (isRecreate) {
	            var optionBackup = this._optionBackup;

	            // TODO
	            // 如果没有reset功能则不clone。

	            this._timelineOptions = map(optionBackup.timelineOptions, clone);
	            this._mediaList = map(optionBackup.mediaList, clone);
	            this._mediaDefault = clone(optionBackup.mediaDefault);
	            this._currentMediaIndices = [];

	            return clone(isRecreate
	                // this._optionBackup.baseOption, which is created at the first `setOption`
	                // called, and is merged into every new option by inner method `mergeOption`
	                // each time `setOption` called, can be only used in `isRecreate`, because
	                // its reliability is under suspicion. In other cases option merge is
	                // performed by `model.mergeOption`.
	                ? optionBackup.baseOption : this._newBaseOption
	            );
	        },

	        /**
	         * @param {module:echarts/model/Global} ecModel
	         * @return {Object}
	         */
	        getTimelineOption: function (ecModel) {
	            var option;
	            var timelineOptions = this._timelineOptions;

	            if (timelineOptions.length) {
	                // getTimelineOption can only be called after ecModel inited,
	                // so we can get currentIndex from timelineModel.
	                var timelineModel = ecModel.getComponent('timeline');
	                if (timelineModel) {
	                    option = clone(
	                        timelineOptions[timelineModel.getCurrentIndex()],
	                        true
	                    );
	                }
	            }

	            return option;
	        },

	        /**
	         * @param {module:echarts/model/Global} ecModel
	         * @return {Array.<Object>}
	         */
	        getMediaOption: function (ecModel) {
	            var ecWidth = this._api.getWidth();
	            var ecHeight = this._api.getHeight();
	            var mediaList = this._mediaList;
	            var mediaDefault = this._mediaDefault;
	            var indices = [];
	            var result = [];

	            // No media defined.
	            if (!mediaList.length && !mediaDefault) {
	                return result;
	            }

	            // Multi media may be applied, the latter defined media has higher priority.
	            for (var i = 0, len = mediaList.length; i < len; i++) {
	                if (applyMediaQuery(mediaList[i].query, ecWidth, ecHeight)) {
	                    indices.push(i);
	                }
	            }

	            // FIXME
	            // 是否mediaDefault应该强制用户设置，否则可能修改不能回归。
	            if (!indices.length && mediaDefault) {
	                indices = [-1];
	            }

	            if (indices.length && !indicesEquals(indices, this._currentMediaIndices)) {
	                result = map(indices, function (index) {
	                    return clone(
	                        index === -1 ? mediaDefault.option : mediaList[index].option
	                    );
	                });
	            }
	            // Otherwise return nothing.

	            this._currentMediaIndices = indices;

	            return result;
	        }
	    };

	    function parseRawOption(rawOption, optionPreprocessorFuncs, isNew) {
	        var timelineOptions = [];
	        var mediaList = [];
	        var mediaDefault;
	        var baseOption;

	        // Compatible with ec2.
	        var timelineOpt = rawOption.timeline;

	        if (rawOption.baseOption) {
	            baseOption = rawOption.baseOption;
	        }

	        // For timeline
	        if (timelineOpt || rawOption.options) {
	            baseOption = baseOption || {};
	            timelineOptions = (rawOption.options || []).slice();
	        }

	        // For media query
	        if (rawOption.media) {
	            baseOption = baseOption || {};
	            var media = rawOption.media;
	            each(media, function (singleMedia) {
	                if (singleMedia && singleMedia.option) {
	                    if (singleMedia.query) {
	                        mediaList.push(singleMedia);
	                    }
	                    else if (!mediaDefault) {
	                        // Use the first media default.
	                        mediaDefault = singleMedia;
	                    }
	                }
	            });
	        }

	        // For normal option
	        if (!baseOption) {
	            baseOption = rawOption;
	        }

	        // Set timelineOpt to baseOption in ec3,
	        // which is convenient for merge option.
	        if (!baseOption.timeline) {
	            baseOption.timeline = timelineOpt;
	        }

	        // Preprocess.
	        each([baseOption].concat(timelineOptions)
	            .concat(zrUtil.map(mediaList, function (media) {
	                return media.option;
	            })),
	            function (option) {
	                each(optionPreprocessorFuncs, function (preProcess) {
	                    preProcess(option, isNew);
	                });
	            }
	        );

	        return {
	            baseOption: baseOption,
	            timelineOptions: timelineOptions,
	            mediaDefault: mediaDefault,
	            mediaList: mediaList
	        };
	    }

	    /**
	     * @see <http://www.w3.org/TR/css3-mediaqueries/#media1>
	     * Support: width, height, aspectRatio
	     * Can use max or min as prefix.
	     */
	    function applyMediaQuery(query, ecWidth, ecHeight) {
	        var realMap = {
	            width: ecWidth,
	            height: ecHeight,
	            aspectratio: ecWidth / ecHeight // lowser case for convenientce.
	        };

	        var applicatable = true;

	        zrUtil.each(query, function (value, attr) {
	            var matched = attr.match(QUERY_REG);

	            if (!matched || !matched[1] || !matched[2]) {
	                return;
	            }

	            var operator = matched[1];
	            var realAttr = matched[2].toLowerCase();

	            if (!compare(realMap[realAttr], value, operator)) {
	                applicatable = false;
	            }
	        });

	        return applicatable;
	    }

	    function compare(real, expect, operator) {
	        if (operator === 'min') {
	            return real >= expect;
	        }
	        else if (operator === 'max') {
	            return real <= expect;
	        }
	        else { // Equals
	            return real === expect;
	        }
	    }

	    function indicesEquals(indices1, indices2) {
	        // indices is always order by asc and has only finite number.
	        return indices1.join(',') === indices2.join(',');
	    }

	    /**
	     * Consider case:
	     * `chart.setOption(opt1);`
	     * Then user do some interaction like dataZoom, dataView changing.
	     * `chart.setOption(opt2);`
	     * Then user press 'reset button' in toolbox.
	     *
	     * After doing that all of the interaction effects should be reset, the
	     * chart should be the same as the result of invoke
	     * `chart.setOption(opt1); chart.setOption(opt2);`.
	     *
	     * Although it is not able ensure that
	     * `chart.setOption(opt1); chart.setOption(opt2);` is equivalents to
	     * `chart.setOption(merge(opt1, opt2));` exactly,
	     * this might be the only simple way to implement that feature.
	     *
	     * MEMO: We've considered some other approaches:
	     * 1. Each model handle its self restoration but not uniform treatment.
	     *     (Too complex in logic and error-prone)
	     * 2. Use a shadow ecModel. (Performace expensive)
	     */
	    function mergeOption(oldOption, newOption) {
	        newOption = newOption || {};

	        each(newOption, function (newCptOpt, mainType) {
	            if (newCptOpt == null) {
	                return;
	            }

	            var oldCptOpt = oldOption[mainType];

	            if (!ComponentModel.hasClass(mainType)) {
	                oldOption[mainType] = merge(oldCptOpt, newCptOpt, true);
	            }
	            else {
	                newCptOpt = modelUtil.normalizeToArray(newCptOpt);
	                oldCptOpt = modelUtil.normalizeToArray(oldCptOpt);

	                var mapResult = modelUtil.mappingToExists(oldCptOpt, newCptOpt);

	                oldOption[mainType] = map(mapResult, function (item) {
	                    return (item.option && item.exist)
	                        ? merge(item.exist, item.option, true)
	                        : (item.exist || item.option);
	                });
	            }
	        });
	    }

	    module.exports = OptionManager;


/***/ },
/* 78 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var zrUtil = __webpack_require__(4);
	    var formatUtil = __webpack_require__(6);
	    var classUtil = __webpack_require__(13);
	    var modelUtil = __webpack_require__(5);
	    var ComponentModel = __webpack_require__(69);
	    var colorPaletteMixin = __webpack_require__(74);
	    var env = __webpack_require__(2);
	    var layout = __webpack_require__(71);

	    var set = classUtil.set;
	    var get = classUtil.get;
	    var encodeHTML = formatUtil.encodeHTML;
	    var addCommas = formatUtil.addCommas;

	    var SeriesModel = ComponentModel.extend({

	        type: 'series.__base__',

	        /**
	         * @readOnly
	         */
	        seriesIndex: 0,

	        // coodinateSystem will be injected in the echarts/CoordinateSystem
	        coordinateSystem: null,

	        /**
	         * @type {Object}
	         * @protected
	         */
	        defaultOption: null,

	        /**
	         * Data provided for legend
	         * @type {Function}
	         */
	        // PENDING
	        legendDataProvider: null,

	        /**
	         * Access path of color for visual
	         */
	        visualColorAccessPath: 'itemStyle.normal.color',

	        /**
	         * Support merge layout params.
	         * Only support 'box' now (left/right/top/bottom/width/height).
	         * @type {string|Object} Object can be {ignoreSize: true}
	         * @readOnly
	         */
	        layoutMode: null,

	        init: function (option, parentModel, ecModel, extraOpt) {

	            /**
	             * @type {number}
	             * @readOnly
	             */
	            this.seriesIndex = this.componentIndex;

	            this.mergeDefaultAndTheme(option, ecModel);

	            var data = this.getInitialData(option, ecModel);
	            if (true) {
	                zrUtil.assert(data, 'getInitialData returned invalid data.');
	            }
	            /**
	             * @type {module:echarts/data/List|module:echarts/data/Tree|module:echarts/data/Graph}
	             * @private
	             */
	            set(this, 'dataBeforeProcessed', data);

	            // If we reverse the order (make data firstly, and then make
	            // dataBeforeProcessed by cloneShallow), cloneShallow will
	            // cause data.graph.data !== data when using
	            // module:echarts/data/Graph or module:echarts/data/Tree.
	            // See module:echarts/data/helper/linkList
	            this.restoreData();
	        },

	        /**
	         * Util for merge default and theme to option
	         * @param  {Object} option
	         * @param  {module:echarts/model/Global} ecModel
	         */
	        mergeDefaultAndTheme: function (option, ecModel) {
	            var layoutMode = this.layoutMode;
	            var inputPositionParams = layoutMode
	                ? layout.getLayoutParams(option) : {};

	            zrUtil.merge(
	                option,
	                ecModel.getTheme().get(this.subType)
	            );
	            zrUtil.merge(option, this.getDefaultOption());

	            // Default label emphasis `position` and `show`
	            // FIXME Set label in mergeOption
	            modelUtil.defaultEmphasis(option.label, modelUtil.LABEL_OPTIONS);

	            this.fillDataTextStyle(option.data);

	            if (layoutMode) {
	                layout.mergeLayoutParam(option, inputPositionParams, layoutMode);
	            }
	        },

	        mergeOption: function (newSeriesOption, ecModel) {
	            newSeriesOption = zrUtil.merge(this.option, newSeriesOption, true);
	            this.fillDataTextStyle(newSeriesOption.data);

	            var layoutMode = this.layoutMode;
	            if (layoutMode) {
	                layout.mergeLayoutParam(this.option, newSeriesOption, layoutMode);
	            }

	            var data = this.getInitialData(newSeriesOption, ecModel);
	            // TODO Merge data?
	            if (data) {
	                set(this, 'data', data);
	                set(this, 'dataBeforeProcessed', data.cloneShallow());
	            }
	        },

	        fillDataTextStyle: function (data) {
	            // Default data label emphasis `position` and `show`
	            // FIXME Tree structure data ?
	            // FIXME Performance ?
	            if (data) {
	                for (var i = 0; i < data.length; i++) {
	                    if (data[i] && data[i].label) {
	                        modelUtil.defaultEmphasis(data[i].label, modelUtil.LABEL_OPTIONS);
	                    }
	                }
	            }
	        },

	        /**
	         * Init a data structure from data related option in series
	         * Must be overwritten
	         */
	        getInitialData: function () {},

	        /**
	         * @param {string} [dataType]
	         * @return {module:echarts/data/List}
	         */
	        getData: function (dataType) {
	            var data = get(this, 'data');
	            return dataType == null ? data : data.getLinkedData(dataType);
	        },

	        /**
	         * @param {module:echarts/data/List} data
	         */
	        setData: function (data) {
	            set(this, 'data', data);
	        },

	        /**
	         * Get data before processed
	         * @return {module:echarts/data/List}
	         */
	        getRawData: function () {
	            return get(this, 'dataBeforeProcessed');
	        },

	        /**
	         * Coord dimension to data dimension.
	         *
	         * By default the result is the same as dimensions of series data.
	         * But in some series data dimensions are different from coord dimensions (i.e.
	         * candlestick and boxplot). Override this method to handle those cases.
	         *
	         * Coord dimension to data dimension can be one-to-many
	         *
	         * @param {string} coordDim
	         * @return {Array.<string>} dimensions on the axis.
	         */
	        coordDimToDataDim: function (coordDim) {
	            return modelUtil.coordDimToDataDim(this.getData(), coordDim);
	        },

	        /**
	         * Convert data dimension to coord dimension.
	         *
	         * @param {string|number} dataDim
	         * @return {string}
	         */
	        dataDimToCoordDim: function (dataDim) {
	            return modelUtil.dataDimToCoordDim(this.getData(), dataDim);
	        },

	        /**
	         * Get base axis if has coordinate system and has axis.
	         * By default use coordSys.getBaseAxis();
	         * Can be overrided for some chart.
	         * @return {type} description
	         */
	        getBaseAxis: function () {
	            var coordSys = this.coordinateSystem;
	            return coordSys && coordSys.getBaseAxis && coordSys.getBaseAxis();
	        },

	        // FIXME
	        /**
	         * Default tooltip formatter
	         *
	         * @param {number} dataIndex
	         * @param {boolean} [multipleSeries=false]
	         * @param {number} [dataType]
	         */
	        formatTooltip: function (dataIndex, multipleSeries, dataType) {
	            function formatArrayValue(value) {
	                var vertially = zrUtil.reduce(value, function (vertially, val, idx) {
	                    var dimItem = data.getDimensionInfo(idx);
	                    return vertially |= dimItem && dimItem.tooltip !== false && dimItem.tooltipName != null;
	                }, 0);

	                var result = [];
	                var tooltipDims = modelUtil.otherDimToDataDim(data, 'tooltip');

	                tooltipDims.length
	                    ? zrUtil.each(tooltipDims, function (dimIdx) {
	                        setEachItem(data.get(dimIdx, dataIndex), dimIdx);
	                    })
	                    // By default, all dims is used on tooltip.
	                    : zrUtil.each(value, setEachItem);

	                function setEachItem(val, dimIdx) {
	                    var dimInfo = data.getDimensionInfo(dimIdx);
	                    // If `dimInfo.tooltip` is not set, show tooltip.
	                    if (!dimInfo || dimInfo.otherDims.tooltip === false) {
	                        return;
	                    }
	                    var dimType = dimInfo.type;
	                    var valStr = (vertially ? '- ' + (dimInfo.tooltipName || dimInfo.name) + ': ' : '')
	                        + (dimType === 'ordinal'
	                            ? val + ''
	                            : dimType === 'time'
	                            ? (multipleSeries ? '' : formatUtil.formatTime('yyyy/MM/dd hh:mm:ss', val))
	                            : addCommas(val)
	                        );
	                    valStr && result.push(encodeHTML(valStr));
	                }

	                return (vertially ? '<br/>' : '') + result.join(vertially ? '<br/>' : ', ');
	            }

	            var data = get(this, 'data');

	            var value = this.getRawValue(dataIndex);
	            var formattedValue = zrUtil.isArray(value)
	                ? formatArrayValue(value) : encodeHTML(addCommas(value));
	            var name = data.getName(dataIndex);

	            var color = data.getItemVisual(dataIndex, 'color');
	            if (zrUtil.isObject(color) && color.colorStops) {
	                color = (color.colorStops[0] || {}).color;
	            }
	            color = color || 'transparent';

	            var colorEl = formatUtil.getTooltipMarker(color);

	            var seriesName = this.name;
	            // FIXME
	            if (seriesName === '\0-') {
	                // Not show '-'
	                seriesName = '';
	            }
	            seriesName = seriesName
	                ? encodeHTML(seriesName) + (!multipleSeries ? '<br/>' : ': ')
	                : '';
	            return !multipleSeries
	                ? seriesName + colorEl
	                    + (name
	                        ? encodeHTML(name) + ': ' + formattedValue
	                        : formattedValue
	                    )
	                : colorEl + seriesName + formattedValue;
	        },

	        /**
	         * @return {boolean}
	         */
	        isAnimationEnabled: function () {
	            if (env.node) {
	                return false;
	            }

	            var animationEnabled = this.getShallow('animation');
	            if (animationEnabled) {
	                if (this.getData().count() > this.getShallow('animationThreshold')) {
	                    animationEnabled = false;
	                }
	            }
	            return animationEnabled;
	        },

	        restoreData: function () {
	            set(this, 'data', get(this, 'dataBeforeProcessed').cloneShallow());
	        },

	        getColorFromPalette: function (name, scope) {
	            var ecModel = this.ecModel;
	            // PENDING
	            var color = colorPaletteMixin.getColorFromPalette.call(this, name, scope);
	            if (!color) {
	                color = ecModel.getColorFromPalette(name, scope);
	            }
	            return color;
	        },

	        /**
	         * Get data indices for show tooltip content. See tooltip.
	         * @abstract
	         * @param {Array.<string>|string} dim
	         * @param {Array.<number>} value
	         * @param {module:echarts/coord/single/SingleAxis} baseAxis
	         * @return {Object} {dataIndices, nestestValue}.
	         */
	        getAxisTooltipData: null,

	        /**
	         * See tooltip.
	         * @abstract
	         * @param {number} dataIndex
	         * @return {Array.<number>} Point of tooltip. null/undefined can be returned.
	         */
	        getTooltipPosition: null
	    });

	    zrUtil.mixin(SeriesModel, modelUtil.dataFormatMixin);
	    zrUtil.mixin(SeriesModel, colorPaletteMixin);

	    module.exports = SeriesModel;


/***/ },
/* 79 */
/***/ function(module, exports, __webpack_require__) {

	

	    var Group = __webpack_require__(48);
	    var componentUtil = __webpack_require__(70);
	    var clazzUtil = __webpack_require__(13);

	    var Component = function () {
	        /**
	         * @type {module:zrender/container/Group}
	         * @readOnly
	         */
	        this.group = new Group();

	        /**
	         * @type {string}
	         * @readOnly
	         */
	        this.uid = componentUtil.getUID('viewComponent');
	    };

	    Component.prototype = {

	        constructor: Component,

	        init: function (ecModel, api) {},

	        render: function (componentModel, ecModel, api, payload) {},

	        dispose: function () {}

	    };

	    var componentProto = Component.prototype;
	    componentProto.updateView
	        = componentProto.updateLayout
	        = componentProto.updateVisual
	        = function (seriesModel, ecModel, api, payload) {
	            // Do nothing;
	        };
	    // Enable Component.extend.
	    clazzUtil.enableClassExtend(Component);

	    // Enable capability of registerClass, getClass, hasClass, registerSubTypeDefaulter and so on.
	    clazzUtil.enableClassManagement(Component, {registerWhenExtend: true});

	    module.exports = Component;


/***/ },
/* 80 */
/***/ function(module, exports, __webpack_require__) {

	

	    var Group = __webpack_require__(48);
	    var componentUtil = __webpack_require__(70);
	    var clazzUtil = __webpack_require__(13);
	    var modelUtil = __webpack_require__(5);
	    var zrUtil = __webpack_require__(4);

	    function Chart() {

	        /**
	         * @type {module:zrender/container/Group}
	         * @readOnly
	         */
	        this.group = new Group();

	        /**
	         * @type {string}
	         * @readOnly
	         */
	        this.uid = componentUtil.getUID('viewChart');
	    }

	    Chart.prototype = {

	        type: 'chart',

	        /**
	         * Init the chart
	         * @param  {module:echarts/model/Global} ecModel
	         * @param  {module:echarts/ExtensionAPI} api
	         */
	        init: function (ecModel, api) {},

	        /**
	         * Render the chart
	         * @param  {module:echarts/model/Series} seriesModel
	         * @param  {module:echarts/model/Global} ecModel
	         * @param  {module:echarts/ExtensionAPI} api
	         * @param  {Object} payload
	         */
	        render: function (seriesModel, ecModel, api, payload) {},

	        /**
	         * Highlight series or specified data item
	         * @param  {module:echarts/model/Series} seriesModel
	         * @param  {module:echarts/model/Global} ecModel
	         * @param  {module:echarts/ExtensionAPI} api
	         * @param  {Object} payload
	         */
	        highlight: function (seriesModel, ecModel, api, payload) {
	            toggleHighlight(seriesModel.getData(), payload, 'emphasis');
	        },

	        /**
	         * Downplay series or specified data item
	         * @param  {module:echarts/model/Series} seriesModel
	         * @param  {module:echarts/model/Global} ecModel
	         * @param  {module:echarts/ExtensionAPI} api
	         * @param  {Object} payload
	         */
	        downplay: function (seriesModel, ecModel, api, payload) {
	            toggleHighlight(seriesModel.getData(), payload, 'normal');
	        },

	        /**
	         * Remove self
	         * @param  {module:echarts/model/Global} ecModel
	         * @param  {module:echarts/ExtensionAPI} api
	         */
	        remove: function (ecModel, api) {
	            this.group.removeAll();
	        },

	        /**
	         * Dispose self
	         * @param  {module:echarts/model/Global} ecModel
	         * @param  {module:echarts/ExtensionAPI} api
	         */
	        dispose: function () {}

	        /**
	         * The view contains the given point.
	         * @interface
	         * @param {Array.<number>} point
	         * @return {boolean}
	         */
	        // containPoint: function () {}

	    };

	    var chartProto = Chart.prototype;
	    chartProto.updateView
	        = chartProto.updateLayout
	        = chartProto.updateVisual
	        = function (seriesModel, ecModel, api, payload) {
	            this.render(seriesModel, ecModel, api, payload);
	        };

	    /**
	     * Set state of single element
	     * @param  {module:zrender/Element} el
	     * @param  {string} state
	     */
	    function elSetState(el, state) {
	        if (el) {
	            el.trigger(state);
	            if (el.type === 'group') {
	                for (var i = 0; i < el.childCount(); i++) {
	                    elSetState(el.childAt(i), state);
	                }
	            }
	        }
	    }
	    /**
	     * @param  {module:echarts/data/List} data
	     * @param  {Object} payload
	     * @param  {string} state 'normal'|'emphasis'
	     * @inner
	     */
	    function toggleHighlight(data, payload, state) {
	        var dataIndex = modelUtil.queryDataIndex(data, payload);

	        if (dataIndex != null) {
	            zrUtil.each(modelUtil.normalizeToArray(dataIndex), function (dataIdx) {
	                elSetState(data.getItemGraphicEl(dataIdx), state);
	            });
	        }
	        else {
	            data.eachItemGraphicEl(function (el) {
	                elSetState(el, state);
	            });
	        }
	    }

	    // Enable Chart.extend.
	    clazzUtil.enableClassExtend(Chart, ['dispose']);

	    // Add capability of registerClass, getClass, hasClass, registerSubTypeDefaulter and so on.
	    clazzUtil.enableClassManagement(Chart, {registerWhenExtend: true});

	    module.exports = Chart;


/***/ },
/* 81 */
/***/ function(module, exports) {

	

	    var lib = {};

	    var ORIGIN_METHOD = '\0__throttleOriginMethod';
	    var RATE = '\0__throttleRate';
	    var THROTTLE_TYPE = '\0__throttleType';

	    /**
	     * @public
	     * @param {(Function)} fn
	     * @param {number} [delay=0] Unit: ms.
	     * @param {boolean} [debounce=false]
	     *        true: If call interval less than `delay`, only the last call works.
	     *        false: If call interval less than `delay, call works on fixed rate.
	     * @return {(Function)} throttled fn.
	     */
	    lib.throttle = function (fn, delay, debounce) {

	        var currCall;
	        var lastCall = 0;
	        var lastExec = 0;
	        var timer = null;
	        var diff;
	        var scope;
	        var args;
	        var debounceNextCall;

	        delay = delay || 0;

	        function exec() {
	            lastExec = (new Date()).getTime();
	            timer = null;
	            fn.apply(scope, args || []);
	        }

	        var cb = function () {
	            currCall = (new Date()).getTime();
	            scope = this;
	            args = arguments;
	            var thisDelay = debounceNextCall || delay;
	            var thisDebounce = debounceNextCall || debounce;
	            debounceNextCall = null;
	            diff = currCall - (thisDebounce ? lastCall : lastExec) - thisDelay;

	            clearTimeout(timer);

	            if (thisDebounce) {
	                timer = setTimeout(exec, thisDelay);
	            }
	            else {
	                if (diff >= 0) {
	                    exec();
	                }
	                else {
	                    timer = setTimeout(exec, -diff);
	                }
	            }

	            lastCall = currCall;
	        };

	        /**
	         * Clear throttle.
	         * @public
	         */
	        cb.clear = function () {
	            if (timer) {
	                clearTimeout(timer);
	                timer = null;
	            }
	        };

	        /**
	         * Enable debounce once.
	         */
	        cb.debounceNextCall = function (debounceDelay) {
	            debounceNextCall = debounceDelay;
	        };

	        return cb;
	    };

	    /**
	     * Create throttle method or update throttle rate.
	     *
	     * @example
	     * ComponentView.prototype.render = function () {
	     *     ...
	     *     throttle.createOrUpdate(
	     *         this,
	     *         '_dispatchAction',
	     *         this.model.get('throttle'),
	     *         'fixRate'
	     *     );
	     * };
	     * ComponentView.prototype.remove = function () {
	     *     throttle.clear(this, '_dispatchAction');
	     * };
	     * ComponentView.prototype.dispose = function () {
	     *     throttle.clear(this, '_dispatchAction');
	     * };
	     *
	     * @public
	     * @param {Object} obj
	     * @param {string} fnAttr
	     * @param {number} [rate]
	     * @param {string} [throttleType='fixRate'] 'fixRate' or 'debounce'
	     * @return {Function} throttled function.
	     */
	    lib.createOrUpdate = function (obj, fnAttr, rate, throttleType) {
	        var fn = obj[fnAttr];

	        if (!fn) {
	            return;
	        }

	        var originFn = fn[ORIGIN_METHOD] || fn;
	        var lastThrottleType = fn[THROTTLE_TYPE];
	        var lastRate = fn[RATE];

	        if (lastRate !== rate || lastThrottleType !== throttleType) {
	            if (rate == null || !throttleType) {
	                return (obj[fnAttr] = originFn);
	            }

	            fn = obj[fnAttr] = lib.throttle(
	                originFn, rate, throttleType === 'debounce'
	            );
	            fn[ORIGIN_METHOD] = originFn;
	            fn[THROTTLE_TYPE] = throttleType;
	            fn[RATE] = rate;
	        }

	        return fn;
	    };

	    /**
	     * Clear throttle. Example see throttle.createOrUpdate.
	     *
	     * @public
	     * @param {Object} obj
	     * @param {string} fnAttr
	     */
	    lib.clear = function (obj, fnAttr) {
	        var fn = obj[fnAttr];
	        if (fn && fn[ORIGIN_METHOD]) {
	            obj[fnAttr] = fn[ORIGIN_METHOD];
	        }
	    };

	    module.exports = lib;



/***/ },
/* 82 */
/***/ function(module, exports, __webpack_require__) {

	/*!
	 * ZRender, a high performance 2d drawing library.
	 *
	 * Copyright (c) 2013, Baidu Inc.
	 * All rights reserved.
	 *
	 * LICENSE
	 * https://github.com/ecomfe/zrender/blob/master/LICENSE.txt
	 */
	// Global defines

	    var guid = __webpack_require__(24);
	    var env = __webpack_require__(2);
	    var zrUtil = __webpack_require__(4);

	    var Handler = __webpack_require__(83);
	    var Storage = __webpack_require__(85);
	    var Animation = __webpack_require__(87);
	    var HandlerProxy = __webpack_require__(90);

	    var useVML = !env.canvasSupported;

	    var painterCtors = {
	        canvas: __webpack_require__(92)
	    };

	    var instances = {};    // ZRender实例map索引

	    var zrender = {};

	    /**
	     * @type {string}
	     */
	    zrender.version = '3.5.2';

	    /**
	     * Initializing a zrender instance
	     * @param {HTMLElement} dom
	     * @param {Object} opts
	     * @param {string} [opts.renderer='canvas'] 'canvas' or 'svg'
	     * @param {number} [opts.devicePixelRatio]
	     * @param {number|string} [opts.width] Can be 'auto' (the same as null/undefined)
	     * @param {number|string} [opts.height] Can be 'auto' (the same as null/undefined)
	     * @return {module:zrender/ZRender}
	     */
	    zrender.init = function(dom, opts) {
	        var zr = new ZRender(guid(), dom, opts);
	        instances[zr.id] = zr;
	        return zr;
	    };

	    /**
	     * Dispose zrender instance
	     * @param {module:zrender/ZRender} zr
	     */
	    zrender.dispose = function (zr) {
	        if (zr) {
	            zr.dispose();
	        }
	        else {
	            for (var key in instances) {
	                if (instances.hasOwnProperty(key)) {
	                    instances[key].dispose();
	                }
	            }
	            instances = {};
	        }

	        return zrender;
	    };

	    /**
	     * Get zrender instance by id
	     * @param {string} id zrender instance id
	     * @return {module:zrender/ZRender}
	     */
	    zrender.getInstance = function (id) {
	        return instances[id];
	    };

	    zrender.registerPainter = function (name, Ctor) {
	        painterCtors[name] = Ctor;
	    };

	    function delInstance(id) {
	        delete instances[id];
	    }

	    /**
	     * @module zrender/ZRender
	     */
	    /**
	     * @constructor
	     * @alias module:zrender/ZRender
	     * @param {string} id
	     * @param {HTMLDomElement} dom
	     * @param {Object} opts
	     * @param {string} [opts.renderer='canvas'] 'canvas' or 'svg'
	     * @param {number} [opts.devicePixelRatio]
	     * @param {number} [opts.width] Can be 'auto' (the same as null/undefined)
	     * @param {number} [opts.height] Can be 'auto' (the same as null/undefined)
	     */
	    var ZRender = function(id, dom, opts) {

	        opts = opts || {};

	        /**
	         * @type {HTMLDomElement}
	         */
	        this.dom = dom;

	        /**
	         * @type {string}
	         */
	        this.id = id;

	        var self = this;
	        var storage = new Storage();

	        var rendererType = opts.renderer;
	        // TODO WebGL
	        if (useVML) {
	            if (!painterCtors.vml) {
	                throw new Error('You need to require \'zrender/vml/vml\' to support IE8');
	            }
	            rendererType = 'vml';
	        }
	        else if (!rendererType || !painterCtors[rendererType]) {
	            rendererType = 'canvas';
	        }
	        var painter = new painterCtors[rendererType](dom, storage, opts);

	        this.storage = storage;
	        this.painter = painter;

	        var handerProxy = !env.node ? new HandlerProxy(painter.getViewportRoot()) : null;
	        this.handler = new Handler(storage, painter, handerProxy, painter.root);

	        /**
	         * @type {module:zrender/animation/Animation}
	         */
	        this.animation = new Animation({
	            stage: {
	                update: zrUtil.bind(this.flush, this)
	            }
	        });
	        this.animation.start();

	        /**
	         * @type {boolean}
	         * @private
	         */
	        this._needsRefresh;

	        // 修改 storage.delFromStorage, 每次删除元素之前删除动画
	        // FIXME 有点ugly
	        var oldDelFromStorage = storage.delFromStorage;
	        var oldAddToStorage = storage.addToStorage;

	        storage.delFromStorage = function (el) {
	            oldDelFromStorage.call(storage, el);

	            el && el.removeSelfFromZr(self);
	        };

	        storage.addToStorage = function (el) {
	            oldAddToStorage.call(storage, el);

	            el.addSelfToZr(self);
	        };
	    };

	    ZRender.prototype = {

	        constructor: ZRender,
	        /**
	         * 获取实例唯一标识
	         * @return {string}
	         */
	        getId: function () {
	            return this.id;
	        },

	        /**
	         * 添加元素
	         * @param  {module:zrender/Element} el
	         */
	        add: function (el) {
	            this.storage.addRoot(el);
	            this._needsRefresh = true;
	        },

	        /**
	         * 删除元素
	         * @param  {module:zrender/Element} el
	         */
	        remove: function (el) {
	            this.storage.delRoot(el);
	            this._needsRefresh = true;
	        },

	        /**
	         * Change configuration of layer
	         * @param {string} zLevel
	         * @param {Object} config
	         * @param {string} [config.clearColor=0] Clear color
	         * @param {string} [config.motionBlur=false] If enable motion blur
	         * @param {number} [config.lastFrameAlpha=0.7] Motion blur factor. Larger value cause longer trailer
	        */
	        configLayer: function (zLevel, config) {
	            this.painter.configLayer(zLevel, config);
	            this._needsRefresh = true;
	        },

	        /**
	         * Repaint the canvas immediately
	         */
	        refreshImmediately: function () {
	            // Clear needsRefresh ahead to avoid something wrong happens in refresh
	            // Or it will cause zrender refreshes again and again.
	            this._needsRefresh = false;
	            this.painter.refresh();
	            /**
	             * Avoid trigger zr.refresh in Element#beforeUpdate hook
	             */
	            this._needsRefresh = false;
	        },

	        /**
	         * Mark and repaint the canvas in the next frame of browser
	         */
	        refresh: function() {
	            this._needsRefresh = true;
	        },

	        /**
	         * Perform all refresh
	         */
	        flush: function () {
	            if (this._needsRefresh) {
	                this.refreshImmediately();
	            }
	            if (this._needsRefreshHover) {
	                this.refreshHoverImmediately();
	            }
	        },

	        /**
	         * Add element to hover layer
	         * @param  {module:zrender/Element} el
	         * @param {Object} style
	         */
	        addHover: function (el, style) {
	            if (this.painter.addHover) {
	                this.painter.addHover(el, style);
	                this.refreshHover();
	            }
	        },

	        /**
	         * Add element from hover layer
	         * @param  {module:zrender/Element} el
	         */
	        removeHover: function (el) {
	            if (this.painter.removeHover) {
	                this.painter.removeHover(el);
	                this.refreshHover();
	            }
	        },

	        /**
	         * Clear all hover elements in hover layer
	         * @param  {module:zrender/Element} el
	         */
	        clearHover: function () {
	            if (this.painter.clearHover) {
	                this.painter.clearHover();
	                this.refreshHover();
	            }
	        },

	        /**
	         * Refresh hover in next frame
	         */
	        refreshHover: function () {
	            this._needsRefreshHover = true;
	        },

	        /**
	         * Refresh hover immediately
	         */
	        refreshHoverImmediately: function () {
	            this._needsRefreshHover = false;
	            this.painter.refreshHover && this.painter.refreshHover();
	        },

	        /**
	         * Resize the canvas.
	         * Should be invoked when container size is changed
	         * @param {Object} [opts]
	         * @param {number|string} [opts.width] Can be 'auto' (the same as null/undefined)
	         * @param {number|string} [opts.height] Can be 'auto' (the same as null/undefined)
	         */
	        resize: function(opts) {
	            opts = opts || {};
	            this.painter.resize(opts.width, opts.height);
	            this.handler.resize();
	        },

	        /**
	         * Stop and clear all animation immediately
	         */
	        clearAnimation: function () {
	            this.animation.clear();
	        },

	        /**
	         * Get container width
	         */
	        getWidth: function() {
	            return this.painter.getWidth();
	        },

	        /**
	         * Get container height
	         */
	        getHeight: function() {
	            return this.painter.getHeight();
	        },

	        /**
	         * Export the canvas as Base64 URL
	         * @param {string} type
	         * @param {string} [backgroundColor='#fff']
	         * @return {string} Base64 URL
	         */
	        // toDataURL: function(type, backgroundColor) {
	        //     return this.painter.getRenderedCanvas({
	        //         backgroundColor: backgroundColor
	        //     }).toDataURL(type);
	        // },

	        /**
	         * Converting a path to image.
	         * It has much better performance of drawing image rather than drawing a vector path.
	         * @param {module:zrender/graphic/Path} e
	         * @param {number} width
	         * @param {number} height
	         */
	        pathToImage: function(e, dpr) {
	            return this.painter.pathToImage(e, dpr);
	        },

	        /**
	         * Set default cursor
	         * @param {string} [cursorStyle='default'] 例如 crosshair
	         */
	        setCursorStyle: function (cursorStyle) {
	            this.handler.setCursorStyle(cursorStyle);
	        },

	        /**
	         * Find hovered element
	         * @param {number} x
	         * @param {number} y
	         * @return {Object} {target, topTarget}
	         */
	        findHover: function (x, y) {
	            return this.handler.findHover(x, y);
	        },

	        /**
	         * Bind event
	         *
	         * @param {string} eventName Event name
	         * @param {Function} eventHandler Handler function
	         * @param {Object} [context] Context object
	         */
	        on: function(eventName, eventHandler, context) {
	            this.handler.on(eventName, eventHandler, context);
	        },

	        /**
	         * Unbind event
	         * @param {string} eventName Event name
	         * @param {Function} [eventHandler] Handler function
	         */
	        off: function(eventName, eventHandler) {
	            this.handler.off(eventName, eventHandler);
	        },

	        /**
	         * Trigger event manually
	         *
	         * @param {string} eventName Event name
	         * @param {event=} event Event object
	         */
	        trigger: function (eventName, event) {
	            this.handler.trigger(eventName, event);
	        },


	        /**
	         * Clear all objects and the canvas.
	         */
	        clear: function () {
	            this.storage.delRoot();
	            this.painter.clear();
	        },

	        /**
	         * Dispose self.
	         */
	        dispose: function () {
	            this.animation.stop();

	            this.clear();
	            this.storage.dispose();
	            this.painter.dispose();
	            this.handler.dispose();

	            this.animation =
	            this.storage =
	            this.painter =
	            this.handler = null;

	            delInstance(this.id);
	        }
	    };

	    module.exports = zrender;



/***/ },
/* 83 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	/**
	 * Handler
	 * @module zrender/Handler
	 * @author Kener (@Kener-林峰, kener.linfeng@gmail.com)
	 *         errorrik (errorrik@gmail.com)
	 *         pissang (shenyi.914@gmail.com)
	 */


	    var util = __webpack_require__(4);
	    var Draggable = __webpack_require__(84);

	    var Eventful = __webpack_require__(25);

	    var SILENT = 'silent';

	    function makeEventPacket(eveType, targetInfo, event) {
	        return {
	            type: eveType,
	            event: event,
	            // target can only be an element that is not silent.
	            target: targetInfo.target,
	            // topTarget can be a silent element.
	            topTarget: targetInfo.topTarget,
	            cancelBubble: false,
	            offsetX: event.zrX,
	            offsetY: event.zrY,
	            gestureEvent: event.gestureEvent,
	            pinchX: event.pinchX,
	            pinchY: event.pinchY,
	            pinchScale: event.pinchScale,
	            wheelDelta: event.zrDelta,
	            zrByTouch: event.zrByTouch
	        };
	    }

	    function EmptyProxy () {}
	    EmptyProxy.prototype.dispose = function () {};

	    var handlerNames = [
	        'click', 'dblclick', 'mousewheel', 'mouseout',
	        'mouseup', 'mousedown', 'mousemove', 'contextmenu'
	    ];
	    /**
	     * @alias module:zrender/Handler
	     * @constructor
	     * @extends module:zrender/mixin/Eventful
	     * @param {module:zrender/Storage} storage Storage instance.
	     * @param {module:zrender/Painter} painter Painter instance.
	     * @param {module:zrender/dom/HandlerProxy} proxy HandlerProxy instance.
	     * @param {HTMLElement} painterRoot painter.root (not painter.getViewportRoot()).
	     */
	    var Handler = function(storage, painter, proxy, painterRoot) {
	        Eventful.call(this);

	        this.storage = storage;

	        this.painter = painter;

	        this.painterRoot = painterRoot;

	        proxy = proxy || new EmptyProxy();

	        /**
	         * Proxy of event. can be Dom, WebGLSurface, etc.
	         */
	        this.proxy = proxy;

	        // Attach handler
	        proxy.handler = this;

	        /**
	         * {target, topTarget}
	         * @private
	         * @type {Object}
	         */
	        this._hovered = {};

	        /**
	         * @private
	         * @type {Date}
	         */
	        this._lastTouchMoment;

	        /**
	         * @private
	         * @type {number}
	         */
	        this._lastX;

	        /**
	         * @private
	         * @type {number}
	         */
	        this._lastY;


	        Draggable.call(this);

	        util.each(handlerNames, function (name) {
	            proxy.on && proxy.on(name, this[name], this);
	        }, this);
	    };

	    Handler.prototype = {

	        constructor: Handler,

	        mousemove: function (event) {
	            var x = event.zrX;
	            var y = event.zrY;

	            var lastHovered = this._hovered;
	            var hovered = this._hovered = this.findHover(x, y);
	            var hoveredTarget = hovered.target;
	            var lastHoveredTarget = lastHovered.target;

	            var proxy = this.proxy;
	            proxy.setCursor && proxy.setCursor(hoveredTarget ? hoveredTarget.cursor : 'default');

	            // Mouse out on previous hovered element
	            if (lastHoveredTarget && hoveredTarget !== lastHoveredTarget && lastHoveredTarget.__zr) {
	                this.dispatchToElement(lastHovered, 'mouseout', event);
	            }

	            // Mouse moving on one element
	            this.dispatchToElement(hovered, 'mousemove', event);

	            // Mouse over on a new element
	            if (hoveredTarget && hoveredTarget !== lastHoveredTarget) {
	                this.dispatchToElement(hovered, 'mouseover', event);
	            }
	        },

	        mouseout: function (event) {
	            this.dispatchToElement(this._hovered, 'mouseout', event);

	            // There might be some doms created by upper layer application
	            // at the same level of painter.getViewportRoot() (e.g., tooltip
	            // dom created by echarts), where 'globalout' event should not
	            // be triggered when mouse enters these doms. (But 'mouseout'
	            // should be triggered at the original hovered element as usual).
	            var element = event.toElement || event.relatedTarget;
	            var innerDom;
	            do {
	                element = element && element.parentNode;
	            }
	            while (element && element.nodeType != 9 && !(
	                innerDom = element === this.painterRoot
	            ));

	            !innerDom && this.trigger('globalout', {event: event});
	        },

	        /**
	         * Resize
	         */
	        resize: function (event) {
	            this._hovered = {};
	        },

	        /**
	         * Dispatch event
	         * @param {string} eventName
	         * @param {event=} eventArgs
	         */
	        dispatch: function (eventName, eventArgs) {
	            var handler = this[eventName];
	            handler && handler.call(this, eventArgs);
	        },

	        /**
	         * Dispose
	         */
	        dispose: function () {

	            this.proxy.dispose();

	            this.storage =
	            this.proxy =
	            this.painter = null;
	        },

	        /**
	         * 设置默认的cursor style
	         * @param {string} [cursorStyle='default'] 例如 crosshair
	         */
	        setCursorStyle: function (cursorStyle) {
	            var proxy = this.proxy;
	            proxy.setCursor && proxy.setCursor(cursorStyle);
	        },

	        /**
	         * 事件分发代理
	         *
	         * @private
	         * @param {Object} targetInfo {target, topTarget} 目标图形元素
	         * @param {string} eventName 事件名称
	         * @param {Object} event 事件对象
	         */
	        dispatchToElement: function (targetInfo, eventName, event) {
	            targetInfo = targetInfo || {};
	            var eventHandler = 'on' + eventName;
	            var eventPacket = makeEventPacket(eventName, targetInfo, event);

	            var el = targetInfo.target;
	            while (el) {
	                el[eventHandler]
	                    && (eventPacket.cancelBubble = el[eventHandler].call(el, eventPacket));

	                el.trigger(eventName, eventPacket);

	                el = el.parent;

	                if (eventPacket.cancelBubble) {
	                    break;
	                }
	            }

	            if (!eventPacket.cancelBubble) {
	                // 冒泡到顶级 zrender 对象
	                this.trigger(eventName, eventPacket);
	                // 分发事件到用户自定义层
	                // 用户有可能在全局 click 事件中 dispose，所以需要判断下 painter 是否存在
	                this.painter && this.painter.eachOtherLayer(function (layer) {
	                    if (typeof(layer[eventHandler]) == 'function') {
	                        layer[eventHandler].call(layer, eventPacket);
	                    }
	                    if (layer.trigger) {
	                        layer.trigger(eventName, eventPacket);
	                    }
	                });
	            }
	        },

	        /**
	         * @private
	         * @param {number} x
	         * @param {number} y
	         * @param {module:zrender/graphic/Displayable} exclude
	         * @return {model:zrender/Element}
	         * @method
	         */
	        findHover: function(x, y, exclude) {
	            var list = this.storage.getDisplayList();
	            var out = {};

	            for (var i = list.length - 1; i >= 0 ; i--) {
	                var hoverCheckResult;
	                if (list[i] !== exclude
	                    // getDisplayList may include ignored item in VML mode
	                    && !list[i].ignore
	                    && (hoverCheckResult = isHover(list[i], x, y))
	                ) {
	                    !out.topTarget && (out.topTarget = list[i]);
	                    if (hoverCheckResult !== SILENT) {
	                        out.target = list[i];
	                        break;
	                    }
	                }
	            }

	            return out;
	        }
	    };

	    // Common handlers
	    util.each(['click', 'mousedown', 'mouseup', 'mousewheel', 'dblclick', 'contextmenu'], function (name) {
	        Handler.prototype[name] = function (event) {
	            // Find hover again to avoid click event is dispatched manually. Or click is triggered without mouseover
	            var hovered = this.findHover(event.zrX, event.zrY);
	            var hoveredTarget = hovered.target;

	            if (name === 'mousedown') {
	                this._downel = hoveredTarget;
	                // In case click triggered before mouseup
	                this._upel = hoveredTarget;
	            }
	            else if (name === 'mosueup') {
	                this._upel = hoveredTarget;
	            }
	            else if (name === 'click') {
	                if (this._downel !== this._upel) {
	                    return;
	                }
	            }

	            this.dispatchToElement(hovered, name, event);
	        };
	    });

	    function isHover(displayable, x, y) {
	        if (displayable[displayable.rectHover ? 'rectContain' : 'contain'](x, y)) {
	            var el = displayable;
	            var isSilent;
	            while (el) {
	                // If clipped by ancestor.
	                // FIXME: If clipPath has neither stroke nor fill,
	                // el.clipPath.contain(x, y) will always return false.
	                if (el.clipPath && !el.clipPath.contain(x, y))  {
	                    return false;
	                }
	                if (el.silent) {
	                    isSilent = true;
	                }
	                el = el.parent;
	            }
	            return isSilent ? SILENT : true;
	        }

	        return false;
	    }

	    util.mixin(Handler, Eventful);
	    util.mixin(Handler, Draggable);

	    module.exports = Handler;



/***/ },
/* 84 */
/***/ function(module, exports) {

	// TODO Draggable for group
	// FIXME Draggable on element which has parent rotation or scale

	    function Draggable() {

	        this.on('mousedown', this._dragStart, this);
	        this.on('mousemove', this._drag, this);
	        this.on('mouseup', this._dragEnd, this);
	        this.on('globalout', this._dragEnd, this);
	        // this._dropTarget = null;
	        // this._draggingTarget = null;

	        // this._x = 0;
	        // this._y = 0;
	    }

	    Draggable.prototype = {

	        constructor: Draggable,

	        _dragStart: function (e) {
	            var draggingTarget = e.target;
	            if (draggingTarget && draggingTarget.draggable) {
	                this._draggingTarget = draggingTarget;
	                draggingTarget.dragging = true;
	                this._x = e.offsetX;
	                this._y = e.offsetY;

	                this.dispatchToElement(param(draggingTarget, e), 'dragstart', e.event);
	            }
	        },

	        _drag: function (e) {
	            var draggingTarget = this._draggingTarget;
	            if (draggingTarget) {

	                var x = e.offsetX;
	                var y = e.offsetY;

	                var dx = x - this._x;
	                var dy = y - this._y;
	                this._x = x;
	                this._y = y;

	                draggingTarget.drift(dx, dy, e);
	                this.dispatchToElement(param(draggingTarget, e), 'drag', e.event);

	                var dropTarget = this.findHover(x, y, draggingTarget).target;
	                var lastDropTarget = this._dropTarget;
	                this._dropTarget = dropTarget;

	                if (draggingTarget !== dropTarget) {
	                    if (lastDropTarget && dropTarget !== lastDropTarget) {
	                        this.dispatchToElement(param(lastDropTarget, e), 'dragleave', e.event);
	                    }
	                    if (dropTarget && dropTarget !== lastDropTarget) {
	                        this.dispatchToElement(param(dropTarget, e), 'dragenter', e.event);
	                    }
	                }
	            }
	        },

	        _dragEnd: function (e) {
	            var draggingTarget = this._draggingTarget;

	            if (draggingTarget) {
	                draggingTarget.dragging = false;
	            }

	            this.dispatchToElement(param(draggingTarget, e), 'dragend', e.event);

	            if (this._dropTarget) {
	                this.dispatchToElement(param(this._dropTarget, e), 'drop', e.event);
	            }

	            this._draggingTarget = null;
	            this._dropTarget = null;
	        }

	    };

	    function param(target, e) {
	        return {target: target, topTarget: e && e.topTarget};
	    }

	    module.exports = Draggable;


/***/ },
/* 85 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	/**
	 * Storage内容仓库模块
	 * @module zrender/Storage
	 * @author Kener (@Kener-林峰, kener.linfeng@gmail.com)
	 * @author errorrik (errorrik@gmail.com)
	 * @author pissang (https://github.com/pissang/)
	 */


	    var util = __webpack_require__(4);
	    var env = __webpack_require__(2);

	    var Group = __webpack_require__(48);

	    // Use timsort because in most case elements are partially sorted
	    // https://jsfiddle.net/pissang/jr4x7mdm/8/
	    var timsort = __webpack_require__(86);

	    function shapeCompareFunc(a, b) {
	        if (a.zlevel === b.zlevel) {
	            if (a.z === b.z) {
	                // if (a.z2 === b.z2) {
	                //     // FIXME Slow has renderidx compare
	                //     // http://stackoverflow.com/questions/20883421/sorting-in-javascript-should-every-compare-function-have-a-return-0-statement
	                //     // https://github.com/v8/v8/blob/47cce544a31ed5577ffe2963f67acb4144ee0232/src/js/array.js#L1012
	                //     return a.__renderidx - b.__renderidx;
	                // }
	                return a.z2 - b.z2;
	            }
	            return a.z - b.z;
	        }
	        return a.zlevel - b.zlevel;
	    }
	    /**
	     * 内容仓库 (M)
	     * @alias module:zrender/Storage
	     * @constructor
	     */
	    var Storage = function () {
	        this._roots = [];

	        this._displayList = [];

	        this._displayListLen = 0;
	    };

	    Storage.prototype = {

	        constructor: Storage,

	        /**
	         * @param  {Function} cb
	         *
	         */
	        traverse: function (cb, context) {
	            for (var i = 0; i < this._roots.length; i++) {
	                this._roots[i].traverse(cb, context);
	            }
	        },

	        /**
	         * 返回所有图形的绘制队列
	         * @param {boolean} [update=false] 是否在返回前更新该数组
	         * @param {boolean} [includeIgnore=false] 是否包含 ignore 的数组, 在 update 为 true 的时候有效
	         *
	         * 详见{@link module:zrender/graphic/Displayable.prototype.updateDisplayList}
	         * @return {Array.<module:zrender/graphic/Displayable>}
	         */
	        getDisplayList: function (update, includeIgnore) {
	            includeIgnore = includeIgnore || false;
	            if (update) {
	                this.updateDisplayList(includeIgnore);
	            }
	            return this._displayList;
	        },

	        /**
	         * 更新图形的绘制队列。
	         * 每次绘制前都会调用，该方法会先深度优先遍历整个树，更新所有Group和Shape的变换并且把所有可见的Shape保存到数组中，
	         * 最后根据绘制的优先级（zlevel > z > 插入顺序）排序得到绘制队列
	         * @param {boolean} [includeIgnore=false] 是否包含 ignore 的数组
	         */
	        updateDisplayList: function (includeIgnore) {
	            this._displayListLen = 0;
	            var roots = this._roots;
	            var displayList = this._displayList;
	            for (var i = 0, len = roots.length; i < len; i++) {
	                this._updateAndAddDisplayable(roots[i], null, includeIgnore);
	            }
	            displayList.length = this._displayListLen;

	            // for (var i = 0, len = displayList.length; i < len; i++) {
	            //     displayList[i].__renderidx = i;
	            // }

	            // displayList.sort(shapeCompareFunc);
	            env.canvasSupported && timsort(displayList, shapeCompareFunc);
	        },

	        _updateAndAddDisplayable: function (el, clipPaths, includeIgnore) {

	            if (el.ignore && !includeIgnore) {
	                return;
	            }

	            el.beforeUpdate();

	            if (el.__dirty) {

	                el.update();

	            }

	            el.afterUpdate();

	            var userSetClipPath = el.clipPath;
	            if (userSetClipPath) {

	                // FIXME 效率影响
	                if (clipPaths) {
	                    clipPaths = clipPaths.slice();
	                }
	                else {
	                    clipPaths = [];
	                }

	                var currentClipPath = userSetClipPath;
	                var parentClipPath = el;
	                // Recursively add clip path
	                while (currentClipPath) {
	                    // clipPath 的变换是基于使用这个 clipPath 的元素
	                    currentClipPath.parent = parentClipPath;
	                    currentClipPath.updateTransform();

	                    clipPaths.push(currentClipPath);

	                    parentClipPath = currentClipPath;
	                    currentClipPath = currentClipPath.clipPath;
	                }
	            }

	            if (el.isGroup) {
	                var children = el._children;

	                for (var i = 0; i < children.length; i++) {
	                    var child = children[i];

	                    // Force to mark as dirty if group is dirty
	                    // FIXME __dirtyPath ?
	                    if (el.__dirty) {
	                        child.__dirty = true;
	                    }

	                    this._updateAndAddDisplayable(child, clipPaths, includeIgnore);
	                }

	                // Mark group clean here
	                el.__dirty = false;

	            }
	            else {
	                el.__clipPaths = clipPaths;

	                this._displayList[this._displayListLen++] = el;
	            }
	        },

	        /**
	         * 添加图形(Shape)或者组(Group)到根节点
	         * @param {module:zrender/Element} el
	         */
	        addRoot: function (el) {
	            if (el.__storage === this) {
	                return;
	            }

	            if (el instanceof Group) {
	                el.addChildrenToStorage(this);
	            }

	            this.addToStorage(el);
	            this._roots.push(el);
	        },

	        /**
	         * 删除指定的图形(Shape)或者组(Group)
	         * @param {string|Array.<string>} [el] 如果为空清空整个Storage
	         */
	        delRoot: function (el) {
	            if (el == null) {
	                // 不指定el清空
	                for (var i = 0; i < this._roots.length; i++) {
	                    var root = this._roots[i];
	                    if (root instanceof Group) {
	                        root.delChildrenFromStorage(this);
	                    }
	                }

	                this._roots = [];
	                this._displayList = [];
	                this._displayListLen = 0;

	                return;
	            }

	            if (el instanceof Array) {
	                for (var i = 0, l = el.length; i < l; i++) {
	                    this.delRoot(el[i]);
	                }
	                return;
	            }


	            var idx = util.indexOf(this._roots, el);
	            if (idx >= 0) {
	                this.delFromStorage(el);
	                this._roots.splice(idx, 1);
	                if (el instanceof Group) {
	                    el.delChildrenFromStorage(this);
	                }
	            }
	        },

	        addToStorage: function (el) {
	            el.__storage = this;
	            el.dirty(false);

	            return this;
	        },

	        delFromStorage: function (el) {
	            if (el) {
	                el.__storage = null;
	            }

	            return this;
	        },

	        /**
	         * 清空并且释放Storage
	         */
	        dispose: function () {
	            this._renderList =
	            this._roots = null;
	        },

	        displayableSortFunc: shapeCompareFunc
	    };

	    module.exports = Storage;



/***/ },
/* 86 */
/***/ function(module, exports) {

	// https://github.com/mziccard/node-timsort

	    var DEFAULT_MIN_MERGE = 32;

	    var DEFAULT_MIN_GALLOPING = 7;

	    var DEFAULT_TMP_STORAGE_LENGTH = 256;

	    function minRunLength(n) {
	        var r = 0;

	        while (n >= DEFAULT_MIN_MERGE) {
	            r |= n & 1;
	            n >>= 1;
	        }

	        return n + r;
	    }

	    function makeAscendingRun(array, lo, hi, compare) {
	        var runHi = lo + 1;

	        if (runHi === hi) {
	            return 1;
	        }

	        if (compare(array[runHi++], array[lo]) < 0) {
	            while (runHi < hi && compare(array[runHi], array[runHi - 1]) < 0) {
	                runHi++;
	            }

	            reverseRun(array, lo, runHi);
	        }
	        else {
	            while (runHi < hi && compare(array[runHi], array[runHi - 1]) >= 0) {
	                runHi++;
	            }
	        }

	        return runHi - lo;
	    }

	    function reverseRun(array, lo, hi) {
	        hi--;

	        while (lo < hi) {
	            var t = array[lo];
	            array[lo++] = array[hi];
	            array[hi--] = t;
	        }
	    }

	    function binaryInsertionSort(array, lo, hi, start, compare) {
	        if (start === lo) {
	            start++;
	        }

	        for (; start < hi; start++) {
	            var pivot = array[start];

	            var left = lo;
	            var right = start;
	            var mid;

	            while (left < right) {
	                mid = left + right >>> 1;

	                if (compare(pivot, array[mid]) < 0) {
	                    right = mid;
	                }
	                else {
	                    left = mid + 1;
	                }
	            }

	            var n = start - left;

	            switch (n) {
	                case 3:
	                    array[left + 3] = array[left + 2];

	                case 2:
	                    array[left + 2] = array[left + 1];

	                case 1:
	                    array[left + 1] = array[left];
	                    break;
	                default:
	                    while (n > 0) {
	                        array[left + n] = array[left + n - 1];
	                        n--;
	                    }
	            }

	            array[left] = pivot;
	        }
	    }

	    function gallopLeft(value, array, start, length, hint, compare) {
	        var lastOffset = 0;
	        var maxOffset = 0;
	        var offset = 1;

	        if (compare(value, array[start + hint]) > 0) {
	            maxOffset = length - hint;

	            while (offset < maxOffset && compare(value, array[start + hint + offset]) > 0) {
	                lastOffset = offset;
	                offset = (offset << 1) + 1;

	                if (offset <= 0) {
	                    offset = maxOffset;
	                }
	            }

	            if (offset > maxOffset) {
	                offset = maxOffset;
	            }

	            lastOffset += hint;
	            offset += hint;
	        }
	        else {
	            maxOffset = hint + 1;
	            while (offset < maxOffset && compare(value, array[start + hint - offset]) <= 0) {
	                lastOffset = offset;
	                offset = (offset << 1) + 1;

	                if (offset <= 0) {
	                    offset = maxOffset;
	                }
	            }
	            if (offset > maxOffset) {
	                offset = maxOffset;
	            }

	            var tmp = lastOffset;
	            lastOffset = hint - offset;
	            offset = hint - tmp;
	        }

	        lastOffset++;
	        while (lastOffset < offset) {
	            var m = lastOffset + (offset - lastOffset >>> 1);

	            if (compare(value, array[start + m]) > 0) {
	                lastOffset = m + 1;
	            }
	            else {
	                offset = m;
	            }
	        }
	        return offset;
	    }

	    function gallopRight(value, array, start, length, hint, compare) {
	        var lastOffset = 0;
	        var maxOffset = 0;
	        var offset = 1;

	        if (compare(value, array[start + hint]) < 0) {
	            maxOffset = hint + 1;

	            while (offset < maxOffset && compare(value, array[start + hint - offset]) < 0) {
	                lastOffset = offset;
	                offset = (offset << 1) + 1;

	                if (offset <= 0) {
	                    offset = maxOffset;
	                }
	            }

	            if (offset > maxOffset) {
	                offset = maxOffset;
	            }

	            var tmp = lastOffset;
	            lastOffset = hint - offset;
	            offset = hint - tmp;
	        }
	        else {
	            maxOffset = length - hint;

	            while (offset < maxOffset && compare(value, array[start + hint + offset]) >= 0) {
	                lastOffset = offset;
	                offset = (offset << 1) + 1;

	                if (offset <= 0) {
	                    offset = maxOffset;
	                }
	            }

	            if (offset > maxOffset) {
	                offset = maxOffset;
	            }

	            lastOffset += hint;
	            offset += hint;
	        }

	        lastOffset++;

	        while (lastOffset < offset) {
	            var m = lastOffset + (offset - lastOffset >>> 1);

	            if (compare(value, array[start + m]) < 0) {
	                offset = m;
	            }
	            else {
	                lastOffset = m + 1;
	            }
	        }

	        return offset;
	    }

	    function TimSort(array, compare) {
	        var minGallop = DEFAULT_MIN_GALLOPING;
	        var length = 0;
	        var tmpStorageLength = DEFAULT_TMP_STORAGE_LENGTH;
	        var stackLength = 0;
	        var runStart;
	        var runLength;
	        var stackSize = 0;

	        length = array.length;

	        if (length < 2 * DEFAULT_TMP_STORAGE_LENGTH) {
	            tmpStorageLength = length >>> 1;
	        }

	        var tmp = [];

	        stackLength = length < 120 ? 5 : length < 1542 ? 10 : length < 119151 ? 19 : 40;

	        runStart = [];
	        runLength = [];

	        function pushRun(_runStart, _runLength) {
	            runStart[stackSize] = _runStart;
	            runLength[stackSize] = _runLength;
	            stackSize += 1;
	        }

	        function mergeRuns() {
	            while (stackSize > 1) {
	                var n = stackSize - 2;

	                if (n >= 1 && runLength[n - 1] <= runLength[n] + runLength[n + 1] || n >= 2 && runLength[n - 2] <= runLength[n] + runLength[n - 1]) {
	                    if (runLength[n - 1] < runLength[n + 1]) {
	                        n--;
	                    }
	                }
	                else if (runLength[n] > runLength[n + 1]) {
	                    break;
	                }
	                mergeAt(n);
	            }
	        }

	        function forceMergeRuns() {
	            while (stackSize > 1) {
	                var n = stackSize - 2;

	                if (n > 0 && runLength[n - 1] < runLength[n + 1]) {
	                    n--;
	                }

	                mergeAt(n);
	            }
	        }

	        function mergeAt(i) {
	            var start1 = runStart[i];
	            var length1 = runLength[i];
	            var start2 = runStart[i + 1];
	            var length2 = runLength[i + 1];

	            runLength[i] = length1 + length2;

	            if (i === stackSize - 3) {
	                runStart[i + 1] = runStart[i + 2];
	                runLength[i + 1] = runLength[i + 2];
	            }

	            stackSize--;

	            var k = gallopRight(array[start2], array, start1, length1, 0, compare);
	            start1 += k;
	            length1 -= k;

	            if (length1 === 0) {
	                return;
	            }

	            length2 = gallopLeft(array[start1 + length1 - 1], array, start2, length2, length2 - 1, compare);

	            if (length2 === 0) {
	                return;
	            }

	            if (length1 <= length2) {
	                mergeLow(start1, length1, start2, length2);
	            }
	            else {
	                mergeHigh(start1, length1, start2, length2);
	            }
	        }

	        function mergeLow(start1, length1, start2, length2) {
	            var i = 0;

	            for (i = 0; i < length1; i++) {
	                tmp[i] = array[start1 + i];
	            }

	            var cursor1 = 0;
	            var cursor2 = start2;
	            var dest = start1;

	            array[dest++] = array[cursor2++];

	            if (--length2 === 0) {
	                for (i = 0; i < length1; i++) {
	                    array[dest + i] = tmp[cursor1 + i];
	                }
	                return;
	            }

	            if (length1 === 1) {
	                for (i = 0; i < length2; i++) {
	                    array[dest + i] = array[cursor2 + i];
	                }
	                array[dest + length2] = tmp[cursor1];
	                return;
	            }

	            var _minGallop = minGallop;
	            var count1, count2, exit;

	            while (1) {
	                count1 = 0;
	                count2 = 0;
	                exit = false;

	                do {
	                    if (compare(array[cursor2], tmp[cursor1]) < 0) {
	                        array[dest++] = array[cursor2++];
	                        count2++;
	                        count1 = 0;

	                        if (--length2 === 0) {
	                            exit = true;
	                            break;
	                        }
	                    }
	                    else {
	                        array[dest++] = tmp[cursor1++];
	                        count1++;
	                        count2 = 0;
	                        if (--length1 === 1) {
	                            exit = true;
	                            break;
	                        }
	                    }
	                } while ((count1 | count2) < _minGallop);

	                if (exit) {
	                    break;
	                }

	                do {
	                    count1 = gallopRight(array[cursor2], tmp, cursor1, length1, 0, compare);

	                    if (count1 !== 0) {
	                        for (i = 0; i < count1; i++) {
	                            array[dest + i] = tmp[cursor1 + i];
	                        }

	                        dest += count1;
	                        cursor1 += count1;
	                        length1 -= count1;
	                        if (length1 <= 1) {
	                            exit = true;
	                            break;
	                        }
	                    }

	                    array[dest++] = array[cursor2++];

	                    if (--length2 === 0) {
	                        exit = true;
	                        break;
	                    }

	                    count2 = gallopLeft(tmp[cursor1], array, cursor2, length2, 0, compare);

	                    if (count2 !== 0) {
	                        for (i = 0; i < count2; i++) {
	                            array[dest + i] = array[cursor2 + i];
	                        }

	                        dest += count2;
	                        cursor2 += count2;
	                        length2 -= count2;

	                        if (length2 === 0) {
	                            exit = true;
	                            break;
	                        }
	                    }
	                    array[dest++] = tmp[cursor1++];

	                    if (--length1 === 1) {
	                        exit = true;
	                        break;
	                    }

	                    _minGallop--;
	                } while (count1 >= DEFAULT_MIN_GALLOPING || count2 >= DEFAULT_MIN_GALLOPING);

	                if (exit) {
	                    break;
	                }

	                if (_minGallop < 0) {
	                    _minGallop = 0;
	                }

	                _minGallop += 2;
	            }

	            minGallop = _minGallop;

	            minGallop < 1 && (minGallop = 1);

	            if (length1 === 1) {
	                for (i = 0; i < length2; i++) {
	                    array[dest + i] = array[cursor2 + i];
	                }
	                array[dest + length2] = tmp[cursor1];
	            }
	            else if (length1 === 0) {
	                throw new Error();
	                // throw new Error('mergeLow preconditions were not respected');
	            }
	            else {
	                for (i = 0; i < length1; i++) {
	                    array[dest + i] = tmp[cursor1 + i];
	                }
	            }
	        }

	        function mergeHigh (start1, length1, start2, length2) {
	            var i = 0;

	            for (i = 0; i < length2; i++) {
	                tmp[i] = array[start2 + i];
	            }

	            var cursor1 = start1 + length1 - 1;
	            var cursor2 = length2 - 1;
	            var dest = start2 + length2 - 1;
	            var customCursor = 0;
	            var customDest = 0;

	            array[dest--] = array[cursor1--];

	            if (--length1 === 0) {
	                customCursor = dest - (length2 - 1);

	                for (i = 0; i < length2; i++) {
	                    array[customCursor + i] = tmp[i];
	                }

	                return;
	            }

	            if (length2 === 1) {
	                dest -= length1;
	                cursor1 -= length1;
	                customDest = dest + 1;
	                customCursor = cursor1 + 1;

	                for (i = length1 - 1; i >= 0; i--) {
	                    array[customDest + i] = array[customCursor + i];
	                }

	                array[dest] = tmp[cursor2];
	                return;
	            }

	            var _minGallop = minGallop;

	            while (true) {
	                var count1 = 0;
	                var count2 = 0;
	                var exit = false;

	                do {
	                    if (compare(tmp[cursor2], array[cursor1]) < 0) {
	                        array[dest--] = array[cursor1--];
	                        count1++;
	                        count2 = 0;
	                        if (--length1 === 0) {
	                            exit = true;
	                            break;
	                        }
	                    }
	                    else {
	                        array[dest--] = tmp[cursor2--];
	                        count2++;
	                        count1 = 0;
	                        if (--length2 === 1) {
	                            exit = true;
	                            break;
	                        }
	                    }
	                } while ((count1 | count2) < _minGallop);

	                if (exit) {
	                    break;
	                }

	                do {
	                    count1 = length1 - gallopRight(tmp[cursor2], array, start1, length1, length1 - 1, compare);

	                    if (count1 !== 0) {
	                        dest -= count1;
	                        cursor1 -= count1;
	                        length1 -= count1;
	                        customDest = dest + 1;
	                        customCursor = cursor1 + 1;

	                        for (i = count1 - 1; i >= 0; i--) {
	                            array[customDest + i] = array[customCursor + i];
	                        }

	                        if (length1 === 0) {
	                            exit = true;
	                            break;
	                        }
	                    }

	                    array[dest--] = tmp[cursor2--];

	                    if (--length2 === 1) {
	                        exit = true;
	                        break;
	                    }

	                    count2 = length2 - gallopLeft(array[cursor1], tmp, 0, length2, length2 - 1, compare);

	                    if (count2 !== 0) {
	                        dest -= count2;
	                        cursor2 -= count2;
	                        length2 -= count2;
	                        customDest = dest + 1;
	                        customCursor = cursor2 + 1;

	                        for (i = 0; i < count2; i++) {
	                            array[customDest + i] = tmp[customCursor + i];
	                        }

	                        if (length2 <= 1) {
	                            exit = true;
	                            break;
	                        }
	                    }

	                    array[dest--] = array[cursor1--];

	                    if (--length1 === 0) {
	                        exit = true;
	                        break;
	                    }

	                    _minGallop--;
	                } while (count1 >= DEFAULT_MIN_GALLOPING || count2 >= DEFAULT_MIN_GALLOPING);

	                if (exit) {
	                    break;
	                }

	                if (_minGallop < 0) {
	                    _minGallop = 0;
	                }

	                _minGallop += 2;
	            }

	            minGallop = _minGallop;

	            if (minGallop < 1) {
	                minGallop = 1;
	            }

	            if (length2 === 1) {
	                dest -= length1;
	                cursor1 -= length1;
	                customDest = dest + 1;
	                customCursor = cursor1 + 1;

	                for (i = length1 - 1; i >= 0; i--) {
	                    array[customDest + i] = array[customCursor + i];
	                }

	                array[dest] = tmp[cursor2];
	            }
	            else if (length2 === 0) {
	                throw new Error();
	                // throw new Error('mergeHigh preconditions were not respected');
	            }
	            else {
	                customCursor = dest - (length2 - 1);
	                for (i = 0; i < length2; i++) {
	                    array[customCursor + i] = tmp[i];
	                }
	            }
	        }

	        this.mergeRuns = mergeRuns;
	        this.forceMergeRuns = forceMergeRuns;
	        this.pushRun = pushRun;
	    }

	    function sort(array, compare, lo, hi) {
	        if (!lo) {
	            lo = 0;
	        }
	        if (!hi) {
	            hi = array.length;
	        }

	        var remaining = hi - lo;

	        if (remaining < 2) {
	            return;
	        }

	        var runLength = 0;

	        if (remaining < DEFAULT_MIN_MERGE) {
	            runLength = makeAscendingRun(array, lo, hi, compare);
	            binaryInsertionSort(array, lo, hi, lo + runLength, compare);
	            return;
	        }

	        var ts = new TimSort(array, compare);

	        var minRun = minRunLength(remaining);

	        do {
	            runLength = makeAscendingRun(array, lo, hi, compare);
	            if (runLength < minRun) {
	                var force = remaining;
	                if (force > minRun) {
	                    force = minRun;
	                }

	                binaryInsertionSort(array, lo, lo + force, lo + runLength, compare);
	                runLength = force;
	            }

	            ts.pushRun(lo, runLength);
	            ts.mergeRuns();

	            remaining -= runLength;
	            lo += runLength;
	        } while (remaining !== 0);

	        ts.forceMergeRuns();
	    }

	    module.exports = sort;


/***/ },
/* 87 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	/**
	 * 动画主类, 调度和管理所有动画控制器
	 *
	 * @module zrender/animation/Animation
	 * @author pissang(https://github.com/pissang)
	 */
	// TODO Additive animation
	// http://iosoteric.com/additive-animations-animatewithduration-in-ios-8/
	// https://developer.apple.com/videos/wwdc2014/#236


	    var util = __webpack_require__(4);
	    var Dispatcher = __webpack_require__(88).Dispatcher;

	    var requestAnimationFrame = __webpack_require__(89);

	    var Animator = __webpack_require__(28);
	    /**
	     * @typedef {Object} IZRenderStage
	     * @property {Function} update
	     */

	    /**
	     * @alias module:zrender/animation/Animation
	     * @constructor
	     * @param {Object} [options]
	     * @param {Function} [options.onframe]
	     * @param {IZRenderStage} [options.stage]
	     * @example
	     *     var animation = new Animation();
	     *     var obj = {
	     *         x: 100,
	     *         y: 100
	     *     };
	     *     animation.animate(node.position)
	     *         .when(1000, {
	     *             x: 500,
	     *             y: 500
	     *         })
	     *         .when(2000, {
	     *             x: 100,
	     *             y: 100
	     *         })
	     *         .start('spline');
	     */
	    var Animation = function (options) {

	        options = options || {};

	        this.stage = options.stage || {};

	        this.onframe = options.onframe || function() {};

	        // private properties
	        this._clips = [];

	        this._running = false;

	        this._time;

	        this._pausedTime;

	        this._pauseStart;

	        this._paused = false;

	        Dispatcher.call(this);
	    };

	    Animation.prototype = {

	        constructor: Animation,
	        /**
	         * 添加 clip
	         * @param {module:zrender/animation/Clip} clip
	         */
	        addClip: function (clip) {
	            this._clips.push(clip);
	        },
	        /**
	         * 添加 animator
	         * @param {module:zrender/animation/Animator} animator
	         */
	        addAnimator: function (animator) {
	            animator.animation = this;
	            var clips = animator.getClips();
	            for (var i = 0; i < clips.length; i++) {
	                this.addClip(clips[i]);
	            }
	        },
	        /**
	         * 删除动画片段
	         * @param {module:zrender/animation/Clip} clip
	         */
	        removeClip: function(clip) {
	            var idx = util.indexOf(this._clips, clip);
	            if (idx >= 0) {
	                this._clips.splice(idx, 1);
	            }
	        },

	        /**
	         * 删除动画片段
	         * @param {module:zrender/animation/Animator} animator
	         */
	        removeAnimator: function (animator) {
	            var clips = animator.getClips();
	            for (var i = 0; i < clips.length; i++) {
	                this.removeClip(clips[i]);
	            }
	            animator.animation = null;
	        },

	        _update: function() {

	            var time = new Date().getTime() - this._pausedTime;
	            var delta = time - this._time;
	            var clips = this._clips;
	            var len = clips.length;

	            var deferredEvents = [];
	            var deferredClips = [];
	            for (var i = 0; i < len; i++) {
	                var clip = clips[i];
	                var e = clip.step(time, delta);
	                // Throw out the events need to be called after
	                // stage.update, like destroy
	                if (e) {
	                    deferredEvents.push(e);
	                    deferredClips.push(clip);
	                }
	            }

	            // Remove the finished clip
	            for (var i = 0; i < len;) {
	                if (clips[i]._needsRemove) {
	                    clips[i] = clips[len - 1];
	                    clips.pop();
	                    len--;
	                }
	                else {
	                    i++;
	                }
	            }

	            len = deferredEvents.length;
	            for (var i = 0; i < len; i++) {
	                deferredClips[i].fire(deferredEvents[i]);
	            }

	            this._time = time;

	            this.onframe(delta);

	            this.trigger('frame', delta);

	            if (this.stage.update) {
	                this.stage.update();
	            }
	        },

	        _startLoop: function () {
	            var self = this;

	            this._running = true;

	            function step() {
	                if (self._running) {

	                    requestAnimationFrame(step);

	                    !self._paused && self._update();
	                }
	            }

	            requestAnimationFrame(step);
	        },

	        /**
	         * 开始运行动画
	         */
	        start: function () {

	            this._time = new Date().getTime();
	            this._pausedTime = 0;

	            this._startLoop();
	        },
	        /**
	         * 停止运行动画
	         */
	        stop: function () {
	            this._running = false;
	        },

	        /**
	         * Pause
	         */
	        pause: function () {
	            if (!this._paused) {
	                this._pauseStart = new Date().getTime();
	                this._paused = true;
	            }
	        },

	        /**
	         * Resume
	         */
	        resume: function () {
	            if (this._paused) {
	                this._pausedTime += (new Date().getTime()) - this._pauseStart;
	                this._paused = false;
	            }
	        },

	        /**
	         * 清除所有动画片段
	         */
	        clear: function () {
	            this._clips = [];
	        },
	        /**
	         * 对一个目标创建一个animator对象，可以指定目标中的属性使用动画
	         * @param  {Object} target
	         * @param  {Object} options
	         * @param  {boolean} [options.loop=false] 是否循环播放动画
	         * @param  {Function} [options.getter=null]
	         *         如果指定getter函数，会通过getter函数取属性值
	         * @param  {Function} [options.setter=null]
	         *         如果指定setter函数，会通过setter函数设置属性值
	         * @return {module:zrender/animation/Animation~Animator}
	         */
	        // TODO Gap
	        animate: function (target, options) {
	            options = options || {};

	            var animator = new Animator(
	                target,
	                options.loop,
	                options.getter,
	                options.setter
	            );

	            this.addAnimator(animator);

	            return animator;
	        }
	    };

	    util.mixin(Animation, Dispatcher);

	    module.exports = Animation;



/***/ },
/* 88 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	/**
	 * 事件辅助类
	 * @module zrender/core/event
	 * @author Kener (@Kener-林峰, kener.linfeng@gmail.com)
	 */


	    var Eventful = __webpack_require__(25);
	    var env = __webpack_require__(2);

	    var isDomLevel2 = (typeof window !== 'undefined') && !!window.addEventListener;

	    function getBoundingClientRect(el) {
	        // BlackBerry 5, iOS 3 (original iPhone) don't have getBoundingRect
	        return el.getBoundingClientRect ? el.getBoundingClientRect() : {left: 0, top: 0};
	    }

	    // `calculate` is optional, default false
	    function clientToLocal(el, e, out, calculate) {
	        out = out || {};

	        // According to the W3C Working Draft, offsetX and offsetY should be relative
	        // to the padding edge of the target element. The only browser using this convention
	        // is IE. Webkit uses the border edge, Opera uses the content edge, and FireFox does
	        // not support the properties.
	        // (see http://www.jacklmoore.com/notes/mouse-position/)
	        // In zr painter.dom, padding edge equals to border edge.

	        // FIXME
	        // When mousemove event triggered on ec tooltip, target is not zr painter.dom, and
	        // offsetX/Y is relative to e.target, where the calculation of zrX/Y via offsetX/Y
	        // is too complex. So css-transfrom dont support in this case temporarily.
	        if (calculate || !env.canvasSupported) {
	            defaultGetZrXY(el, e, out);
	        }
	        // Caution: In FireFox, layerX/layerY Mouse position relative to the closest positioned
	        // ancestor element, so we should make sure el is positioned (e.g., not position:static).
	        // BTW1, Webkit don't return the same results as FF in non-simple cases (like add
	        // zoom-factor, overflow / opacity layers, transforms ...)
	        // BTW2, (ev.offsetY || ev.pageY - $(ev.target).offset().top) is not correct in preserve-3d.
	        // <https://bugs.jquery.com/ticket/8523#comment:14>
	        // BTW3, In ff, offsetX/offsetY is always 0.
	        else if (env.browser.firefox && e.layerX != null && e.layerX !== e.offsetX) {
	            out.zrX = e.layerX;
	            out.zrY = e.layerY;
	        }
	        // For IE6+, chrome, safari, opera. (When will ff support offsetX?)
	        else if (e.offsetX != null) {
	            out.zrX = e.offsetX;
	            out.zrY = e.offsetY;
	        }
	        // For some other device, e.g., IOS safari.
	        else {
	            defaultGetZrXY(el, e, out);
	        }

	        return out;
	    }

	    function defaultGetZrXY(el, e, out) {
	        // This well-known method below does not support css transform.
	        var box = getBoundingClientRect(el);
	        out.zrX = e.clientX - box.left;
	        out.zrY = e.clientY - box.top;
	    }

	    /**
	     * 如果存在第三方嵌入的一些dom触发的事件，或touch事件，需要转换一下事件坐标.
	     * `calculate` is optional, default false.
	     */
	    function normalizeEvent(el, e, calculate) {

	        e = e || window.event;

	        if (e.zrX != null) {
	            return e;
	        }

	        var eventType = e.type;
	        var isTouch = eventType && eventType.indexOf('touch') >= 0;

	        if (!isTouch) {
	            clientToLocal(el, e, e, calculate);
	            e.zrDelta = (e.wheelDelta) ? e.wheelDelta / 120 : -(e.detail || 0) / 3;
	        }
	        else {
	            var touch = eventType != 'touchend'
	                ? e.targetTouches[0]
	                : e.changedTouches[0];
	            touch && clientToLocal(el, touch, e, calculate);
	        }

	        return e;
	    }

	    function addEventListener(el, name, handler) {
	        if (isDomLevel2) {
	            el.addEventListener(name, handler);
	        }
	        else {
	            el.attachEvent('on' + name, handler);
	        }
	    }

	    function removeEventListener(el, name, handler) {
	        if (isDomLevel2) {
	            el.removeEventListener(name, handler);
	        }
	        else {
	            el.detachEvent('on' + name, handler);
	        }
	    }

	    /**
	     * preventDefault and stopPropagation.
	     * Notice: do not do that in zrender. Upper application
	     * do that if necessary.
	     *
	     * @memberOf module:zrender/core/event
	     * @method
	     * @param {Event} e : event对象
	     */
	    var stop = isDomLevel2
	        ? function (e) {
	            e.preventDefault();
	            e.stopPropagation();
	            e.cancelBubble = true;
	        }
	        : function (e) {
	            e.returnValue = false;
	            e.cancelBubble = true;
	        };

	    module.exports = {
	        clientToLocal: clientToLocal,
	        normalizeEvent: normalizeEvent,
	        addEventListener: addEventListener,
	        removeEventListener: removeEventListener,

	        stop: stop,
	        // 做向上兼容
	        Dispatcher: Eventful
	    };



/***/ },
/* 89 */
/***/ function(module, exports) {

	

	    module.exports = (typeof window !== 'undefined' &&
	                ((window.requestAnimationFrame && window.requestAnimationFrame.bind(window))
	                // https://github.com/ecomfe/zrender/issues/189#issuecomment-224919809
	                || (window.msRequestAnimationFrame && window.msRequestAnimationFrame.bind(window))
	                || window.mozRequestAnimationFrame
	                || window.webkitRequestAnimationFrame)
	            )
	            || function (func) {
	                setTimeout(func, 16);
	            };



/***/ },
/* 90 */
/***/ function(module, exports, __webpack_require__) {

	

	    var eventTool = __webpack_require__(88);
	    var zrUtil = __webpack_require__(4);
	    var Eventful = __webpack_require__(25);
	    var env = __webpack_require__(2);
	    var GestureMgr = __webpack_require__(91);

	    var addEventListener = eventTool.addEventListener;
	    var removeEventListener = eventTool.removeEventListener;
	    var normalizeEvent = eventTool.normalizeEvent;

	    var TOUCH_CLICK_DELAY = 300;

	    var mouseHandlerNames = [
	        'click', 'dblclick', 'mousewheel', 'mouseout',
	        'mouseup', 'mousedown', 'mousemove', 'contextmenu'
	    ];

	    var touchHandlerNames = [
	        'touchstart', 'touchend', 'touchmove'
	    ];

	    var pointerEventNames = {
	        pointerdown: 1, pointerup: 1, pointermove: 1, pointerout: 1
	    };

	    var pointerHandlerNames = zrUtil.map(mouseHandlerNames, function (name) {
	        var nm = name.replace('mouse', 'pointer');
	        return pointerEventNames[nm] ? nm : name;
	    });

	    function eventNameFix(name) {
	        return (name === 'mousewheel' && env.browser.firefox) ? 'DOMMouseScroll' : name;
	    }

	    function processGesture(proxy, event, stage) {
	        var gestureMgr = proxy._gestureMgr;

	        stage === 'start' && gestureMgr.clear();

	        var gestureInfo = gestureMgr.recognize(
	            event,
	            proxy.handler.findHover(event.zrX, event.zrY, null).target,
	            proxy.dom
	        );

	        stage === 'end' && gestureMgr.clear();

	        // Do not do any preventDefault here. Upper application do that if necessary.
	        if (gestureInfo) {
	            var type = gestureInfo.type;
	            event.gestureEvent = type;

	            proxy.handler.dispatchToElement({target: gestureInfo.target}, type, gestureInfo.event);
	        }
	    }

	    // function onMSGestureChange(proxy, event) {
	    //     if (event.translationX || event.translationY) {
	    //         // mousemove is carried by MSGesture to reduce the sensitivity.
	    //         proxy.handler.dispatchToElement(event.target, 'mousemove', event);
	    //     }
	    //     if (event.scale !== 1) {
	    //         event.pinchX = event.offsetX;
	    //         event.pinchY = event.offsetY;
	    //         event.pinchScale = event.scale;
	    //         proxy.handler.dispatchToElement(event.target, 'pinch', event);
	    //     }
	    // }

	    /**
	     * Prevent mouse event from being dispatched after Touch Events action
	     * @see <https://github.com/deltakosh/handjs/blob/master/src/hand.base.js>
	     * 1. Mobile browsers dispatch mouse events 300ms after touchend.
	     * 2. Chrome for Android dispatch mousedown for long-touch about 650ms
	     * Result: Blocking Mouse Events for 700ms.
	     */
	    function setTouchTimer(instance) {
	        instance._touching = true;
	        clearTimeout(instance._touchTimer);
	        instance._touchTimer = setTimeout(function () {
	            instance._touching = false;
	        }, 700);
	    }


	    var domHandlers = {
	        /**
	         * Mouse move handler
	         * @inner
	         * @param {Event} event
	         */
	        mousemove: function (event) {
	            event = normalizeEvent(this.dom, event);

	            this.trigger('mousemove', event);
	        },

	        /**
	         * Mouse out handler
	         * @inner
	         * @param {Event} event
	         */
	        mouseout: function (event) {
	            event = normalizeEvent(this.dom, event);

	            var element = event.toElement || event.relatedTarget;
	            if (element != this.dom) {
	                while (element && element.nodeType != 9) {
	                    // 忽略包含在root中的dom引起的mouseOut
	                    if (element === this.dom) {
	                        return;
	                    }

	                    element = element.parentNode;
	                }
	            }

	            this.trigger('mouseout', event);
	        },

	        /**
	         * Touch开始响应函数
	         * @inner
	         * @param {Event} event
	         */
	        touchstart: function (event) {
	            // Default mouse behaviour should not be disabled here.
	            // For example, page may needs to be slided.
	            event = normalizeEvent(this.dom, event);

	            // Mark touch, which is useful in distinguish touch and
	            // mouse event in upper applicatoin.
	            event.zrByTouch = true;

	            this._lastTouchMoment = new Date();

	            processGesture(this, event, 'start');

	            // In touch device, trigger `mousemove`(`mouseover`) should
	            // be triggered, and must before `mousedown` triggered.
	            domHandlers.mousemove.call(this, event);

	            domHandlers.mousedown.call(this, event);

	            setTouchTimer(this);
	        },

	        /**
	         * Touch移动响应函数
	         * @inner
	         * @param {Event} event
	         */
	        touchmove: function (event) {

	            event = normalizeEvent(this.dom, event);

	            // Mark touch, which is useful in distinguish touch and
	            // mouse event in upper applicatoin.
	            event.zrByTouch = true;

	            processGesture(this, event, 'change');

	            // Mouse move should always be triggered no matter whether
	            // there is gestrue event, because mouse move and pinch may
	            // be used at the same time.
	            domHandlers.mousemove.call(this, event);

	            setTouchTimer(this);
	        },

	        /**
	         * Touch结束响应函数
	         * @inner
	         * @param {Event} event
	         */
	        touchend: function (event) {

	            event = normalizeEvent(this.dom, event);

	            // Mark touch, which is useful in distinguish touch and
	            // mouse event in upper applicatoin.
	            event.zrByTouch = true;

	            processGesture(this, event, 'end');

	            domHandlers.mouseup.call(this, event);

	            // Do not trigger `mouseout` here, in spite of `mousemove`(`mouseover`) is
	            // triggered in `touchstart`. This seems to be illogical, but by this mechanism,
	            // we can conveniently implement "hover style" in both PC and touch device just
	            // by listening to `mouseover` to add "hover style" and listening to `mouseout`
	            // to remove "hover style" on an element, without any additional code for
	            // compatibility. (`mouseout` will not be triggered in `touchend`, so "hover
	            // style" will remain for user view)

	            // click event should always be triggered no matter whether
	            // there is gestrue event. System click can not be prevented.
	            if (+new Date() - this._lastTouchMoment < TOUCH_CLICK_DELAY) {
	                domHandlers.click.call(this, event);
	            }

	            setTouchTimer(this);
	        },

	        pointerdown: function (event) {
	            domHandlers.mousedown.call(this, event);

	            // if (useMSGuesture(this, event)) {
	            //     this._msGesture.addPointer(event.pointerId);
	            // }
	        },

	        pointermove: function (event) {
	            // FIXME
	            // pointermove is so sensitive that it always triggered when
	            // tap(click) on touch screen, which affect some judgement in
	            // upper application. So, we dont support mousemove on MS touch
	            // device yet.
	            if (!isPointerFromTouch(event)) {
	                domHandlers.mousemove.call(this, event);
	            }
	        },

	        pointerup: function (event) {
	            domHandlers.mouseup.call(this, event);
	        },

	        pointerout: function (event) {
	            // pointerout will be triggered when tap on touch screen
	            // (IE11+/Edge on MS Surface) after click event triggered,
	            // which is inconsistent with the mousout behavior we defined
	            // in touchend. So we unify them.
	            // (check domHandlers.touchend for detailed explanation)
	            if (!isPointerFromTouch(event)) {
	                domHandlers.mouseout.call(this, event);
	            }
	        }
	    };

	    function isPointerFromTouch(event) {
	        var pointerType = event.pointerType;
	        return pointerType === 'pen' || pointerType === 'touch';
	    }

	    // function useMSGuesture(handlerProxy, event) {
	    //     return isPointerFromTouch(event) && !!handlerProxy._msGesture;
	    // }

	    // Common handlers
	    zrUtil.each(['click', 'mousedown', 'mouseup', 'mousewheel', 'dblclick', 'contextmenu'], function (name) {
	        domHandlers[name] = function (event) {
	            event = normalizeEvent(this.dom, event);
	            this.trigger(name, event);
	        };
	    });

	    /**
	     * 为控制类实例初始化dom 事件处理函数
	     *
	     * @inner
	     * @param {module:zrender/Handler} instance 控制类实例
	     */
	    function initDomHandler(instance) {
	        zrUtil.each(touchHandlerNames, function (name) {
	            instance._handlers[name] = zrUtil.bind(domHandlers[name], instance);
	        });

	        zrUtil.each(pointerHandlerNames, function (name) {
	            instance._handlers[name] = zrUtil.bind(domHandlers[name], instance);
	        });

	        zrUtil.each(mouseHandlerNames, function (name) {
	            instance._handlers[name] = makeMouseHandler(domHandlers[name], instance);
	        });

	        function makeMouseHandler(fn, instance) {
	            return function () {
	                if (instance._touching) {
	                    return;
	                }
	                return fn.apply(instance, arguments);
	            };
	        }
	    }


	    function HandlerDomProxy(dom) {
	        Eventful.call(this);

	        this.dom = dom;

	        /**
	         * @private
	         * @type {boolean}
	         */
	        this._touching = false;

	        /**
	         * @private
	         * @type {number}
	         */
	        this._touchTimer;

	        /**
	         * @private
	         * @type {module:zrender/core/GestureMgr}
	         */
	        this._gestureMgr = new GestureMgr();

	        this._handlers = {};

	        initDomHandler(this);

	        if (env.pointerEventsSupported) { // Only IE11+/Edge
	            // 1. On devices that both enable touch and mouse (e.g., MS Surface and lenovo X240),
	            // IE11+/Edge do not trigger touch event, but trigger pointer event and mouse event
	            // at the same time.
	            // 2. On MS Surface, it probablely only trigger mousedown but no mouseup when tap on
	            // screen, which do not occurs in pointer event.
	            // So we use pointer event to both detect touch gesture and mouse behavior.
	            mountHandlers(pointerHandlerNames, this);

	            // FIXME
	            // Note: MS Gesture require CSS touch-action set. But touch-action is not reliable,
	            // which does not prevent defuault behavior occasionally (which may cause view port
	            // zoomed in but use can not zoom it back). And event.preventDefault() does not work.
	            // So we have to not to use MSGesture and not to support touchmove and pinch on MS
	            // touch screen. And we only support click behavior on MS touch screen now.

	            // MS Gesture Event is only supported on IE11+/Edge and on Windows 8+.
	            // We dont support touch on IE on win7.
	            // See <https://msdn.microsoft.com/en-us/library/dn433243(v=vs.85).aspx>
	            // if (typeof MSGesture === 'function') {
	            //     (this._msGesture = new MSGesture()).target = dom; // jshint ignore:line
	            //     dom.addEventListener('MSGestureChange', onMSGestureChange);
	            // }
	        }
	        else {
	            if (env.touchEventsSupported) {
	                mountHandlers(touchHandlerNames, this);
	                // Handler of 'mouseout' event is needed in touch mode, which will be mounted below.
	                // addEventListener(root, 'mouseout', this._mouseoutHandler);
	            }

	            // 1. Considering some devices that both enable touch and mouse event (like on MS Surface
	            // and lenovo X240, @see #2350), we make mouse event be always listened, otherwise
	            // mouse event can not be handle in those devices.
	            // 2. On MS Surface, Chrome will trigger both touch event and mouse event. How to prevent
	            // mouseevent after touch event triggered, see `setTouchTimer`.
	            mountHandlers(mouseHandlerNames, this);
	        }

	        function mountHandlers(handlerNames, instance) {
	            zrUtil.each(handlerNames, function (name) {
	                addEventListener(dom, eventNameFix(name), instance._handlers[name]);
	            }, instance);
	        }
	    }

	    var handlerDomProxyProto = HandlerDomProxy.prototype;
	    handlerDomProxyProto.dispose = function () {
	        var handlerNames = mouseHandlerNames.concat(touchHandlerNames);

	        for (var i = 0; i < handlerNames.length; i++) {
	            var name = handlerNames[i];
	            removeEventListener(this.dom, eventNameFix(name), this._handlers[name]);
	        }
	    };

	    handlerDomProxyProto.setCursor = function (cursorStyle) {
	        this.dom.style.cursor = cursorStyle || 'default';
	    };

	    zrUtil.mixin(HandlerDomProxy, Eventful);

	    module.exports = HandlerDomProxy;


/***/ },
/* 91 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	/**
	 * Only implements needed gestures for mobile.
	 */


	    var eventUtil = __webpack_require__(88);

	    var GestureMgr = function () {

	        /**
	         * @private
	         * @type {Array.<Object>}
	         */
	        this._track = [];
	    };

	    GestureMgr.prototype = {

	        constructor: GestureMgr,

	        recognize: function (event, target, root) {
	            this._doTrack(event, target, root);
	            return this._recognize(event);
	        },

	        clear: function () {
	            this._track.length = 0;
	            return this;
	        },

	        _doTrack: function (event, target, root) {
	            var touches = event.touches;

	            if (!touches) {
	                return;
	            }

	            var trackItem = {
	                points: [],
	                touches: [],
	                target: target,
	                event: event
	            };

	            for (var i = 0, len = touches.length; i < len; i++) {
	                var touch = touches[i];
	                var pos = eventUtil.clientToLocal(root, touch, {});
	                trackItem.points.push([pos.zrX, pos.zrY]);
	                trackItem.touches.push(touch);
	            }

	            this._track.push(trackItem);
	        },

	        _recognize: function (event) {
	            for (var eventName in recognizers) {
	                if (recognizers.hasOwnProperty(eventName)) {
	                    var gestureInfo = recognizers[eventName](this._track, event);
	                    if (gestureInfo) {
	                        return gestureInfo;
	                    }
	                }
	            }
	        }
	    };

	    function dist(pointPair) {
	        var dx = pointPair[1][0] - pointPair[0][0];
	        var dy = pointPair[1][1] - pointPair[0][1];

	        return Math.sqrt(dx * dx + dy * dy);
	    }

	    function center(pointPair) {
	        return [
	            (pointPair[0][0] + pointPair[1][0]) / 2,
	            (pointPair[0][1] + pointPair[1][1]) / 2
	        ];
	    }

	    var recognizers = {

	        pinch: function (track, event) {
	            var trackLen = track.length;

	            if (!trackLen) {
	                return;
	            }

	            var pinchEnd = (track[trackLen - 1] || {}).points;
	            var pinchPre = (track[trackLen - 2] || {}).points || pinchEnd;

	            if (pinchPre
	                && pinchPre.length > 1
	                && pinchEnd
	                && pinchEnd.length > 1
	            ) {
	                var pinchScale = dist(pinchEnd) / dist(pinchPre);
	                !isFinite(pinchScale) && (pinchScale = 1);

	                event.pinchScale = pinchScale;

	                var pinchCenter = center(pinchEnd);
	                event.pinchX = pinchCenter[0];
	                event.pinchY = pinchCenter[1];

	                return {
	                    type: 'pinch',
	                    target: track[0].target,
	                    event: event
	                };
	            }
	        }

	        // Only pinch currently.
	    };

	    module.exports = GestureMgr;



/***/ },
/* 92 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	/**
	 * Default canvas painter
	 * @module zrender/Painter
	 * @author Kener (@Kener-林峰, kener.linfeng@gmail.com)
	 *         errorrik (errorrik@gmail.com)
	 *         pissang (https://www.github.com/pissang)
	 */
	 

	    var config = __webpack_require__(34);
	    var util = __webpack_require__(4);
	    var log = __webpack_require__(33);
	    var BoundingRect = __webpack_require__(9);
	    var timsort = __webpack_require__(86);

	    var Layer = __webpack_require__(93);

	    var requestAnimationFrame = __webpack_require__(89);

	    // PENDIGN
	    // Layer exceeds MAX_PROGRESSIVE_LAYER_NUMBER may have some problem when flush directly second time.
	    //
	    // Maximum progressive layer. When exceeding this number. All elements will be drawed in the last layer.
	    var MAX_PROGRESSIVE_LAYER_NUMBER = 5;

	    function parseInt10(val) {
	        return parseInt(val, 10);
	    }

	    function isLayerValid(layer) {
	        if (!layer) {
	            return false;
	        }

	        if (layer.__builtin__) {
	            return true;
	        }

	        if (typeof(layer.resize) !== 'function'
	            || typeof(layer.refresh) !== 'function'
	        ) {
	            return false;
	        }

	        return true;
	    }

	    function preProcessLayer(layer) {
	        layer.__unusedCount++;
	    }

	    function postProcessLayer(layer) {
	        if (layer.__unusedCount == 1) {
	            layer.clear();
	        }
	    }

	    var tmpRect = new BoundingRect(0, 0, 0, 0);
	    var viewRect = new BoundingRect(0, 0, 0, 0);
	    function isDisplayableCulled(el, width, height) {
	        tmpRect.copy(el.getBoundingRect());
	        if (el.transform) {
	            tmpRect.applyTransform(el.transform);
	        }
	        viewRect.width = width;
	        viewRect.height = height;
	        return !tmpRect.intersect(viewRect);
	    }

	    function isClipPathChanged(clipPaths, prevClipPaths) {
	        if (clipPaths == prevClipPaths) { // Can both be null or undefined
	            return false;
	        }

	        if (!clipPaths || !prevClipPaths || (clipPaths.length !== prevClipPaths.length)) {
	            return true;
	        }
	        for (var i = 0; i < clipPaths.length; i++) {
	            if (clipPaths[i] !== prevClipPaths[i]) {
	                return true;
	            }
	        }
	    }

	    function doClip(clipPaths, ctx) {
	        for (var i = 0; i < clipPaths.length; i++) {
	            var clipPath = clipPaths[i];

	            clipPath.setTransform(ctx);
	            ctx.beginPath();
	            clipPath.buildPath(ctx, clipPath.shape);
	            ctx.clip();
	            // Transform back
	            clipPath.restoreTransform(ctx);
	        }
	    }

	    function createRoot(width, height) {
	        var domRoot = document.createElement('div');

	        // domRoot.onselectstart = returnFalse; // 避免页面选中的尴尬
	        domRoot.style.cssText = [
	            'position:relative',
	            'overflow:hidden',
	            'width:' + width + 'px',
	            'height:' + height + 'px',
	            'padding:0',
	            'margin:0',
	            'border-width:0'
	        ].join(';') + ';';

	        return domRoot;
	    }

	    /**
	     * @alias module:zrender/Painter
	     * @constructor
	     * @param {HTMLElement} root 绘图容器
	     * @param {module:zrender/Storage} storage
	     * @param {Ojbect} opts
	     */
	    var Painter = function (root, storage, opts) {
	        // In node environment using node-canvas
	        var singleCanvas = !root.nodeName // In node ?
	            || root.nodeName.toUpperCase() === 'CANVAS';

	        this._opts = opts = util.extend({}, opts || {});

	        /**
	         * @type {number}
	         */
	        this.dpr = opts.devicePixelRatio || config.devicePixelRatio;
	        /**
	         * @type {boolean}
	         * @private
	         */
	        this._singleCanvas = singleCanvas;
	        /**
	         * 绘图容器
	         * @type {HTMLElement}
	         */
	        this.root = root;

	        var rootStyle = root.style;

	        if (rootStyle) {
	            rootStyle['-webkit-tap-highlight-color'] = 'transparent';
	            rootStyle['-webkit-user-select'] =
	            rootStyle['user-select'] =
	            rootStyle['-webkit-touch-callout'] = 'none';

	            root.innerHTML = '';
	        }

	        /**
	         * @type {module:zrender/Storage}
	         */
	        this.storage = storage;

	        /**
	         * @type {Array.<number>}
	         * @private
	         */
	        var zlevelList = this._zlevelList = [];

	        /**
	         * @type {Object.<string, module:zrender/Layer>}
	         * @private
	         */
	        var layers = this._layers = {};

	        /**
	         * @type {Object.<string, Object>}
	         * @type {private}
	         */
	        this._layerConfig = {};

	        if (!singleCanvas) {
	            this._width = this._getSize(0);
	            this._height = this._getSize(1);

	            var domRoot = this._domRoot = createRoot(
	                this._width, this._height
	            );
	            root.appendChild(domRoot);
	        }
	        else {
	            if (opts.width != null) {
	                root.width = opts.width;
	            }
	            if (opts.height != null) {
	                root.height = opts.height;
	            }
	            // Use canvas width and height directly
	            var width = root.width;
	            var height = root.height;
	            this._width = width;
	            this._height = height;

	            // Create layer if only one given canvas
	            // Device pixel ratio is fixed to 1 because given canvas has its specified width and height
	            var mainLayer = new Layer(root, this, 1);
	            mainLayer.initContext();
	            // FIXME Use canvas width and height
	            // mainLayer.resize(width, height);
	            layers[0] = mainLayer;
	            zlevelList.push(0);

	            this._domRoot = root;
	        }

	        // Layers for progressive rendering
	        this._progressiveLayers = [];

	        /**
	         * @type {module:zrender/Layer}
	         * @private
	         */
	        this._hoverlayer;

	        this._hoverElements = [];
	    };

	    Painter.prototype = {

	        constructor: Painter,

	        /**
	         * If painter use a single canvas
	         * @return {boolean}
	         */
	        isSingleCanvas: function () {
	            return this._singleCanvas;
	        },
	        /**
	         * @return {HTMLDivElement}
	         */
	        getViewportRoot: function () {
	            return this._domRoot;
	        },

	        /**
	         * 刷新
	         * @param {boolean} [paintAll=false] 强制绘制所有displayable
	         */
	        refresh: function (paintAll) {

	            var list = this.storage.getDisplayList(true);

	            var zlevelList = this._zlevelList;

	            this._paintList(list, paintAll);

	            // Paint custum layers
	            for (var i = 0; i < zlevelList.length; i++) {
	                var z = zlevelList[i];
	                var layer = this._layers[z];
	                if (!layer.__builtin__ && layer.refresh) {
	                    layer.refresh();
	                }
	            }

	            this.refreshHover();

	            if (this._progressiveLayers.length) {
	                this._startProgessive();
	            }

	            return this;
	        },

	        addHover: function (el, hoverStyle) {
	            if (el.__hoverMir) {
	                return;
	            }
	            var elMirror = new el.constructor({
	                style: el.style,
	                shape: el.shape
	            });
	            elMirror.__from = el;
	            el.__hoverMir = elMirror;
	            elMirror.setStyle(hoverStyle);
	            this._hoverElements.push(elMirror);
	        },

	        removeHover: function (el) {
	            var elMirror = el.__hoverMir;
	            var hoverElements = this._hoverElements;
	            var idx = util.indexOf(hoverElements, elMirror);
	            if (idx >= 0) {
	                hoverElements.splice(idx, 1);
	            }
	            el.__hoverMir = null;
	        },

	        clearHover: function (el) {
	            var hoverElements = this._hoverElements;
	            for (var i = 0; i < hoverElements.length; i++) {
	                var from = hoverElements[i].__from;
	                if (from) {
	                    from.__hoverMir = null;
	                }
	            }
	            hoverElements.length = 0;
	        },

	        refreshHover: function () {
	            var hoverElements = this._hoverElements;
	            var len = hoverElements.length;
	            var hoverLayer = this._hoverlayer;
	            hoverLayer && hoverLayer.clear();

	            if (!len) {
	                return;
	            }
	            timsort(hoverElements, this.storage.displayableSortFunc);

	            // Use a extream large zlevel
	            // FIXME?
	            if (!hoverLayer) {
	                hoverLayer = this._hoverlayer = this.getLayer(1e5);
	            }

	            var scope = {};
	            hoverLayer.ctx.save();
	            for (var i = 0; i < len;) {
	                var el = hoverElements[i];
	                var originalEl = el.__from;
	                // Original el is removed
	                // PENDING
	                if (!(originalEl && originalEl.__zr)) {
	                    hoverElements.splice(i, 1);
	                    originalEl.__hoverMir = null;
	                    len--;
	                    continue;
	                }
	                i++;

	                // Use transform
	                // FIXME style and shape ?
	                if (!originalEl.invisible) {
	                    el.transform = originalEl.transform;
	                    el.invTransform = originalEl.invTransform;
	                    el.__clipPaths = originalEl.__clipPaths;
	                    // el.
	                    this._doPaintEl(el, hoverLayer, true, scope);
	                }
	            }
	            hoverLayer.ctx.restore();
	        },

	        _startProgessive: function () {
	            var self = this;

	            if (!self._furtherProgressive) {
	                return;
	            }

	            // Use a token to stop progress steps triggered by
	            // previous zr.refresh calling.
	            var token = self._progressiveToken = +new Date();

	            self._progress++;
	            requestAnimationFrame(step);

	            function step() {
	                // In case refreshed or disposed
	                if (token === self._progressiveToken && self.storage) {

	                    self._doPaintList(self.storage.getDisplayList());

	                    if (self._furtherProgressive) {
	                        self._progress++;
	                        requestAnimationFrame(step);
	                    }
	                    else {
	                        self._progressiveToken = -1;
	                    }
	                }
	            }
	        },

	        _clearProgressive: function () {
	            this._progressiveToken = -1;
	            this._progress = 0;
	            util.each(this._progressiveLayers, function (layer) {
	                layer.__dirty && layer.clear();
	            });
	        },

	        _paintList: function (list, paintAll) {

	            if (paintAll == null) {
	                paintAll = false;
	            }

	            this._updateLayerStatus(list);

	            this._clearProgressive();

	            this.eachBuiltinLayer(preProcessLayer);

	            this._doPaintList(list, paintAll);

	            this.eachBuiltinLayer(postProcessLayer);
	        },

	        _doPaintList: function (list, paintAll) {
	            var currentLayer;
	            var currentZLevel;
	            var ctx;

	            // var invTransform = [];
	            var scope;

	            var progressiveLayerIdx = 0;
	            var currentProgressiveLayer;

	            var width = this._width;
	            var height = this._height;
	            var layerProgress;
	            var frame = this._progress;
	            function flushProgressiveLayer(layer) {
	                var dpr = ctx.dpr || 1;
	                ctx.save();
	                ctx.globalAlpha = 1;
	                ctx.shadowBlur = 0;
	                // Avoid layer don't clear in next progressive frame
	                currentLayer.__dirty = true;
	                ctx.setTransform(1, 0, 0, 1, 0, 0);
	                ctx.drawImage(layer.dom, 0, 0, width * dpr, height * dpr);
	                ctx.restore();
	            }

	            for (var i = 0, l = list.length; i < l; i++) {
	                var el = list[i];
	                var elZLevel = this._singleCanvas ? 0 : el.zlevel;

	                var elFrame = el.__frame;

	                // Flush at current context
	                // PENDING
	                if (elFrame < 0 && currentProgressiveLayer) {
	                    flushProgressiveLayer(currentProgressiveLayer);
	                    currentProgressiveLayer = null;
	                }

	                // Change draw layer
	                if (currentZLevel !== elZLevel) {
	                    if (ctx) {
	                        ctx.restore();
	                    }

	                    // Reset scope
	                    scope = {};

	                    // Only 0 zlevel if only has one canvas
	                    currentZLevel = elZLevel;
	                    currentLayer = this.getLayer(currentZLevel);

	                    if (!currentLayer.__builtin__) {
	                        log(
	                            'ZLevel ' + currentZLevel
	                            + ' has been used by unkown layer ' + currentLayer.id
	                        );
	                    }

	                    ctx = currentLayer.ctx;
	                    ctx.save();

	                    // Reset the count
	                    currentLayer.__unusedCount = 0;

	                    if (currentLayer.__dirty || paintAll) {
	                        currentLayer.clear();
	                    }
	                }

	                if (!(currentLayer.__dirty || paintAll)) {
	                    continue;
	                }

	                if (elFrame >= 0) {
	                    // Progressive layer changed
	                    if (!currentProgressiveLayer) {
	                        currentProgressiveLayer = this._progressiveLayers[
	                            Math.min(progressiveLayerIdx++, MAX_PROGRESSIVE_LAYER_NUMBER - 1)
	                        ];

	                        currentProgressiveLayer.ctx.save();
	                        currentProgressiveLayer.renderScope = {};

	                        if (currentProgressiveLayer
	                            && (currentProgressiveLayer.__progress > currentProgressiveLayer.__maxProgress)
	                        ) {
	                            // flushProgressiveLayer(currentProgressiveLayer);
	                            // Quick jump all progressive elements
	                            // All progressive element are not dirty, jump over and flush directly
	                            i = currentProgressiveLayer.__nextIdxNotProg - 1;
	                            // currentProgressiveLayer = null;
	                            continue;
	                        }

	                        layerProgress = currentProgressiveLayer.__progress;

	                        if (!currentProgressiveLayer.__dirty) {
	                            // Keep rendering
	                            frame = layerProgress;
	                        }

	                        currentProgressiveLayer.__progress = frame + 1;
	                    }

	                    if (elFrame === frame) {
	                        this._doPaintEl(el, currentProgressiveLayer, true, currentProgressiveLayer.renderScope);
	                    }
	                }
	                else {
	                    this._doPaintEl(el, currentLayer, paintAll, scope);
	                }

	                el.__dirty = false;
	            }

	            if (currentProgressiveLayer) {
	                flushProgressiveLayer(currentProgressiveLayer);
	            }

	            // Restore the lastLayer ctx
	            ctx && ctx.restore();
	            // If still has clipping state
	            // if (scope.prevElClipPaths) {
	            //     ctx.restore();
	            // }

	            this._furtherProgressive = false;
	            util.each(this._progressiveLayers, function (layer) {
	                if (layer.__maxProgress >= layer.__progress) {
	                    this._furtherProgressive = true;
	                }
	            }, this);
	        },

	        _doPaintEl: function (el, currentLayer, forcePaint, scope) {
	            var ctx = currentLayer.ctx;
	            var m = el.transform;
	            if (
	                (currentLayer.__dirty || forcePaint)
	                // Ignore invisible element
	                && !el.invisible
	                // Ignore transparent element
	                && el.style.opacity !== 0
	                // Ignore scale 0 element, in some environment like node-canvas
	                // Draw a scale 0 element can cause all following draw wrong
	                // And setTransform with scale 0 will cause set back transform failed.
	                && !(m && !m[0] && !m[3])
	                // Ignore culled element
	                && !(el.culling && isDisplayableCulled(el, this._width, this._height))
	            ) {

	                var clipPaths = el.__clipPaths;

	                // Optimize when clipping on group with several elements
	                if (scope.prevClipLayer !== currentLayer
	                    || isClipPathChanged(clipPaths, scope.prevElClipPaths)
	                ) {
	                    // If has previous clipping state, restore from it
	                    if (scope.prevElClipPaths) {
	                        scope.prevClipLayer.ctx.restore();
	                        scope.prevClipLayer = scope.prevElClipPaths = null;

	                        // Reset prevEl since context has been restored
	                        scope.prevEl = null;
	                    }
	                    // New clipping state
	                    if (clipPaths) {
	                        ctx.save();
	                        doClip(clipPaths, ctx);
	                        scope.prevClipLayer = currentLayer;
	                        scope.prevElClipPaths = clipPaths;
	                    }
	                }
	                el.beforeBrush && el.beforeBrush(ctx);

	                el.brush(ctx, scope.prevEl || null);
	                scope.prevEl = el;

	                el.afterBrush && el.afterBrush(ctx);
	            }
	        },

	        /**
	         * 获取 zlevel 所在层，如果不存在则会创建一个新的层
	         * @param {number} zlevel
	         * @return {module:zrender/Layer}
	         */
	        getLayer: function (zlevel) {
	            if (this._singleCanvas) {
	                return this._layers[0];
	            }

	            var layer = this._layers[zlevel];
	            if (!layer) {
	                // Create a new layer
	                layer = new Layer('zr_' + zlevel, this, this.dpr);
	                layer.__builtin__ = true;

	                if (this._layerConfig[zlevel]) {
	                    util.merge(layer, this._layerConfig[zlevel], true);
	                }

	                this.insertLayer(zlevel, layer);

	                // Context is created after dom inserted to document
	                // Or excanvas will get 0px clientWidth and clientHeight
	                layer.initContext();
	            }

	            return layer;
	        },

	        insertLayer: function (zlevel, layer) {

	            var layersMap = this._layers;
	            var zlevelList = this._zlevelList;
	            var len = zlevelList.length;
	            var prevLayer = null;
	            var i = -1;
	            var domRoot = this._domRoot;

	            if (layersMap[zlevel]) {
	                log('ZLevel ' + zlevel + ' has been used already');
	                return;
	            }
	            // Check if is a valid layer
	            if (!isLayerValid(layer)) {
	                log('Layer of zlevel ' + zlevel + ' is not valid');
	                return;
	            }

	            if (len > 0 && zlevel > zlevelList[0]) {
	                for (i = 0; i < len - 1; i++) {
	                    if (
	                        zlevelList[i] < zlevel
	                        && zlevelList[i + 1] > zlevel
	                    ) {
	                        break;
	                    }
	                }
	                prevLayer = layersMap[zlevelList[i]];
	            }
	            zlevelList.splice(i + 1, 0, zlevel);

	            layersMap[zlevel] = layer;

	            // Vitual layer will not directly show on the screen.
	            // (It can be a WebGL layer and assigned to a ZImage element)
	            // But it still under management of zrender.
	            if (!layer.virtual) {
	                if (prevLayer) {
	                    var prevDom = prevLayer.dom;
	                    if (prevDom.nextSibling) {
	                        domRoot.insertBefore(
	                            layer.dom,
	                            prevDom.nextSibling
	                        );
	                    }
	                    else {
	                        domRoot.appendChild(layer.dom);
	                    }
	                }
	                else {
	                    if (domRoot.firstChild) {
	                        domRoot.insertBefore(layer.dom, domRoot.firstChild);
	                    }
	                    else {
	                        domRoot.appendChild(layer.dom);
	                    }
	                }
	            }
	        },

	        // Iterate each layer
	        eachLayer: function (cb, context) {
	            var zlevelList = this._zlevelList;
	            var z;
	            var i;
	            for (i = 0; i < zlevelList.length; i++) {
	                z = zlevelList[i];
	                cb.call(context, this._layers[z], z);
	            }
	        },

	        // Iterate each buildin layer
	        eachBuiltinLayer: function (cb, context) {
	            var zlevelList = this._zlevelList;
	            var layer;
	            var z;
	            var i;
	            for (i = 0; i < zlevelList.length; i++) {
	                z = zlevelList[i];
	                layer = this._layers[z];
	                if (layer.__builtin__) {
	                    cb.call(context, layer, z);
	                }
	            }
	        },

	        // Iterate each other layer except buildin layer
	        eachOtherLayer: function (cb, context) {
	            var zlevelList = this._zlevelList;
	            var layer;
	            var z;
	            var i;
	            for (i = 0; i < zlevelList.length; i++) {
	                z = zlevelList[i];
	                layer = this._layers[z];
	                if (!layer.__builtin__) {
	                    cb.call(context, layer, z);
	                }
	            }
	        },

	        /**
	         * 获取所有已创建的层
	         * @param {Array.<module:zrender/Layer>} [prevLayer]
	         */
	        getLayers: function () {
	            return this._layers;
	        },

	        _updateLayerStatus: function (list) {

	            var layers = this._layers;
	            var progressiveLayers = this._progressiveLayers;

	            var elCountsLastFrame = {};
	            var progressiveElCountsLastFrame = {};

	            this.eachBuiltinLayer(function (layer, z) {
	                elCountsLastFrame[z] = layer.elCount;
	                layer.elCount = 0;
	                layer.__dirty = false;
	            });

	            util.each(progressiveLayers, function (layer, idx) {
	                progressiveElCountsLastFrame[idx] = layer.elCount;
	                layer.elCount = 0;
	                layer.__dirty = false;
	            });

	            var progressiveLayerCount = 0;
	            var currentProgressiveLayer;
	            var lastProgressiveKey;
	            var frameCount = 0;
	            for (var i = 0, l = list.length; i < l; i++) {
	                var el = list[i];
	                var zlevel = this._singleCanvas ? 0 : el.zlevel;
	                var layer = layers[zlevel];
	                var elProgress = el.progressive;
	                if (layer) {
	                    layer.elCount++;
	                    layer.__dirty = layer.__dirty || el.__dirty;
	                }

	                /////// Update progressive
	                if (elProgress >= 0) {
	                    // Fix wrong progressive sequence problem.
	                    if (lastProgressiveKey !== elProgress) {
	                        lastProgressiveKey = elProgress;
	                        frameCount++;
	                    }
	                    var elFrame = el.__frame = frameCount - 1;
	                    if (!currentProgressiveLayer) {
	                        var idx = Math.min(progressiveLayerCount, MAX_PROGRESSIVE_LAYER_NUMBER - 1);
	                        currentProgressiveLayer = progressiveLayers[idx];
	                        if (!currentProgressiveLayer) {
	                            currentProgressiveLayer = progressiveLayers[idx] = new Layer(
	                                'progressive', this, this.dpr
	                            );
	                            currentProgressiveLayer.initContext();
	                        }
	                        currentProgressiveLayer.__maxProgress = 0;
	                    }
	                    currentProgressiveLayer.__dirty = currentProgressiveLayer.__dirty || el.__dirty;
	                    currentProgressiveLayer.elCount++;

	                    currentProgressiveLayer.__maxProgress = Math.max(
	                        currentProgressiveLayer.__maxProgress, elFrame
	                    );

	                    if (currentProgressiveLayer.__maxProgress >= currentProgressiveLayer.__progress) {
	                        // Should keep rendering this  layer because progressive rendering is not finished yet
	                        layer.__dirty = true;
	                    }
	                }
	                else {
	                    el.__frame = -1;

	                    if (currentProgressiveLayer) {
	                        currentProgressiveLayer.__nextIdxNotProg = i;
	                        progressiveLayerCount++;
	                        currentProgressiveLayer = null;
	                    }
	                }
	            }

	            if (currentProgressiveLayer) {
	                progressiveLayerCount++;
	                currentProgressiveLayer.__nextIdxNotProg = i;
	            }

	            // 层中的元素数量有发生变化
	            this.eachBuiltinLayer(function (layer, z) {
	                if (elCountsLastFrame[z] !== layer.elCount) {
	                    layer.__dirty = true;
	                }
	            });

	            progressiveLayers.length = Math.min(progressiveLayerCount, MAX_PROGRESSIVE_LAYER_NUMBER);
	            util.each(progressiveLayers, function (layer, idx) {
	                if (progressiveElCountsLastFrame[idx] !== layer.elCount) {
	                    el.__dirty = true;
	                }
	                if (layer.__dirty) {
	                    layer.__progress = 0;
	                }
	            });
	        },

	        /**
	         * 清除hover层外所有内容
	         */
	        clear: function () {
	            this.eachBuiltinLayer(this._clearLayer);
	            return this;
	        },

	        _clearLayer: function (layer) {
	            layer.clear();
	        },

	        /**
	         * 修改指定zlevel的绘制参数
	         *
	         * @param {string} zlevel
	         * @param {Object} config 配置对象
	         * @param {string} [config.clearColor=0] 每次清空画布的颜色
	         * @param {string} [config.motionBlur=false] 是否开启动态模糊
	         * @param {number} [config.lastFrameAlpha=0.7]
	         *                 在开启动态模糊的时候使用，与上一帧混合的alpha值，值越大尾迹越明显
	         */
	        configLayer: function (zlevel, config) {
	            if (config) {
	                var layerConfig = this._layerConfig;
	                if (!layerConfig[zlevel]) {
	                    layerConfig[zlevel] = config;
	                }
	                else {
	                    util.merge(layerConfig[zlevel], config, true);
	                }

	                var layer = this._layers[zlevel];

	                if (layer) {
	                    util.merge(layer, layerConfig[zlevel], true);
	                }
	            }
	        },

	        /**
	         * 删除指定层
	         * @param {number} zlevel 层所在的zlevel
	         */
	        delLayer: function (zlevel) {
	            var layers = this._layers;
	            var zlevelList = this._zlevelList;
	            var layer = layers[zlevel];
	            if (!layer) {
	                return;
	            }
	            layer.dom.parentNode.removeChild(layer.dom);
	            delete layers[zlevel];

	            zlevelList.splice(util.indexOf(zlevelList, zlevel), 1);
	        },

	        /**
	         * 区域大小变化后重绘
	         */
	        resize: function (width, height) {
	            var domRoot = this._domRoot;
	            // FIXME Why ?
	            domRoot.style.display = 'none';

	            // Save input w/h
	            var opts = this._opts;
	            width != null && (opts.width = width);
	            height != null && (opts.height = height);

	            width = this._getSize(0);
	            height = this._getSize(1);

	            domRoot.style.display = '';

	            // 优化没有实际改变的resize
	            if (this._width != width || height != this._height) {
	                domRoot.style.width = width + 'px';
	                domRoot.style.height = height + 'px';

	                for (var id in this._layers) {
	                    if (this._layers.hasOwnProperty(id)) {
	                        this._layers[id].resize(width, height);
	                    }
	                }
	                util.each(this._progressiveLayers, function (layer) {
	                    layer.resize(width, height);
	                });

	                this.refresh(true);
	            }

	            this._width = width;
	            this._height = height;

	            return this;
	        },

	        /**
	         * 清除单独的一个层
	         * @param {number} zlevel
	         */
	        clearLayer: function (zlevel) {
	            var layer = this._layers[zlevel];
	            if (layer) {
	                layer.clear();
	            }
	        },

	        /**
	         * 释放
	         */
	        dispose: function () {
	            this.root.innerHTML = '';

	            this.root =
	            this.storage =

	            this._domRoot =
	            this._layers = null;
	        },

	        /**
	         * Get canvas which has all thing rendered
	         * @param {Object} opts
	         * @param {string} [opts.backgroundColor]
	         */
	        getRenderedCanvas: function (opts) {
	            opts = opts || {};
	            if (this._singleCanvas) {
	                return this._layers[0].dom;
	            }

	            var imageLayer = new Layer('image', this, opts.pixelRatio || this.dpr);
	            imageLayer.initContext();

	            imageLayer.clearColor = opts.backgroundColor;
	            imageLayer.clear();

	            var displayList = this.storage.getDisplayList(true);

	            var scope = {};
	            var zlevel;

	            var self = this;
	            function findAndDrawOtherLayer(smaller, larger) {
	                var zlevelList = self._zlevelList;
	                if (smaller == null) {
	                    smaller = -Infinity;
	                }
	                var intermediateLayer;
	                for (var i = 0; i < zlevelList.length; i++) {
	                    var z = zlevelList[i];
	                    var layer = self._layers[z];
	                    if (!layer.__builtin__ && z > smaller && z < larger) {
	                        intermediateLayer = layer;
	                        break;
	                    }
	                }
	                if (intermediateLayer && intermediateLayer.renderToCanvas) {
	                    imageLayer.ctx.save();
	                    intermediateLayer.renderToCanvas(imageLayer.ctx);
	                    imageLayer.ctx.restore();
	                }
	            }
	            for (var i = 0; i < displayList.length; i++) {
	                var el = displayList[i];

	                if (el.zlevel !== zlevel) {
	                    findAndDrawOtherLayer(zlevel, el.zlevel);
	                    zlevel = el.zlevel;
	                }
	                this._doPaintEl(el, imageLayer, true, scope);
	            }

	            findAndDrawOtherLayer(zlevel, Infinity);

	            return imageLayer.dom;
	        },
	        /**
	         * 获取绘图区域宽度
	         */
	        getWidth: function () {
	            return this._width;
	        },

	        /**
	         * 获取绘图区域高度
	         */
	        getHeight: function () {
	            return this._height;
	        },

	        _getSize: function (whIdx) {
	            var opts = this._opts;
	            var wh = ['width', 'height'][whIdx];
	            var cwh = ['clientWidth', 'clientHeight'][whIdx];
	            var plt = ['paddingLeft', 'paddingTop'][whIdx];
	            var prb = ['paddingRight', 'paddingBottom'][whIdx];

	            if (opts[wh] != null && opts[wh] !== 'auto') {
	                return parseFloat(opts[wh]);
	            }

	            var root = this.root;
	            var stl = document.defaultView.getComputedStyle(root);

	            return (
	                (root[cwh] || parseInt10(stl[wh]) || parseInt10(root.style[wh]))
	                - (parseInt10(stl[plt]) || 0)
	                - (parseInt10(stl[prb]) || 0)
	            ) | 0;
	        },

	        pathToImage: function (path, dpr) {
	            dpr = dpr || this.dpr;

	            var canvas = document.createElement('canvas');
	            var ctx = canvas.getContext('2d');
	            var rect = path.getBoundingRect();
	            var style = path.style;
	            var shadowBlurSize = style.shadowBlur;
	            var shadowOffsetX = style.shadowOffsetX;
	            var shadowOffsetY = style.shadowOffsetY;
	            var lineWidth = style.hasStroke() ? style.lineWidth : 0;

	            var leftMargin = Math.max(lineWidth / 2, -shadowOffsetX + shadowBlurSize);
	            var rightMargin = Math.max(lineWidth / 2, shadowOffsetX + shadowBlurSize);
	            var topMargin = Math.max(lineWidth / 2, -shadowOffsetY + shadowBlurSize);
	            var bottomMargin = Math.max(lineWidth / 2, shadowOffsetY + shadowBlurSize);
	            var width = rect.width + leftMargin + rightMargin;
	            var height = rect.height + topMargin + bottomMargin;

	            canvas.width = width * dpr;
	            canvas.height = height * dpr;

	            ctx.scale(dpr, dpr);
	            ctx.clearRect(0, 0, width, height);
	            ctx.dpr = dpr;

	            var pathTransform = {
	                position: path.position,
	                rotation: path.rotation,
	                scale: path.scale
	            };
	            path.position = [leftMargin - rect.x, topMargin - rect.y];
	            path.rotation = 0;
	            path.scale = [1, 1];
	            path.updateTransform();
	            if (path) {
	                path.brush(ctx);
	            }

	            var ImageShape = __webpack_require__(49);
	            var imgShape = new ImageShape({
	                style: {
	                    x: 0,
	                    y: 0,
	                    image: canvas
	                }
	            });

	            if (pathTransform.position != null) {
	                imgShape.position = path.position = pathTransform.position;
	            }

	            if (pathTransform.rotation != null) {
	                imgShape.rotation = path.rotation = pathTransform.rotation;
	            }

	            if (pathTransform.scale != null) {
	                imgShape.scale = path.scale = pathTransform.scale;
	            }

	            return imgShape;
	        }
	    };

	    module.exports = Painter;



/***/ },
/* 93 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @module zrender/Layer
	 * @author pissang(https://www.github.com/pissang)
	 */


	    var util = __webpack_require__(4);
	    var config = __webpack_require__(34);
	    var Style = __webpack_require__(22);
	    var Pattern = __webpack_require__(46);

	    function returnFalse() {
	        return false;
	    }

	    /**
	     * 创建dom
	     *
	     * @inner
	     * @param {string} id dom id 待用
	     * @param {string} type dom type，such as canvas, div etc.
	     * @param {Painter} painter painter instance
	     * @param {number} number
	     */
	    function createDom(id, type, painter, dpr) {
	        var newDom = document.createElement(type);
	        var width = painter.getWidth();
	        var height = painter.getHeight();

	        var newDomStyle = newDom.style;
	        // 没append呢，请原谅我这样写，清晰~
	        newDomStyle.position = 'absolute';
	        newDomStyle.left = 0;
	        newDomStyle.top = 0;
	        newDomStyle.width = width + 'px';
	        newDomStyle.height = height + 'px';
	        newDom.width = width * dpr;
	        newDom.height = height * dpr;

	        // id不作为索引用，避免可能造成的重名，定义为私有属性
	        newDom.setAttribute('data-zr-dom-id', id);
	        return newDom;
	    }

	    /**
	     * @alias module:zrender/Layer
	     * @constructor
	     * @extends module:zrender/mixin/Transformable
	     * @param {string} id
	     * @param {module:zrender/Painter} painter
	     * @param {number} [dpr]
	     */
	    var Layer = function(id, painter, dpr) {
	        var dom;
	        dpr = dpr || config.devicePixelRatio;
	        if (typeof id === 'string') {
	            dom = createDom(id, 'canvas', painter, dpr);
	        }
	        // Not using isDom because in node it will return false
	        else if (util.isObject(id)) {
	            dom = id;
	            id = dom.id;
	        }
	        this.id = id;
	        this.dom = dom;

	        var domStyle = dom.style;
	        if (domStyle) { // Not in node
	            dom.onselectstart = returnFalse; // 避免页面选中的尴尬
	            domStyle['-webkit-user-select'] = 'none';
	            domStyle['user-select'] = 'none';
	            domStyle['-webkit-touch-callout'] = 'none';
	            domStyle['-webkit-tap-highlight-color'] = 'rgba(0,0,0,0)';
	            domStyle['padding'] = 0;
	            domStyle['margin'] = 0;
	            domStyle['border-width'] = 0;
	        }

	        this.domBack = null;
	        this.ctxBack = null;

	        this.painter = painter;

	        this.config = null;

	        // Configs
	        /**
	         * 每次清空画布的颜色
	         * @type {string}
	         * @default 0
	         */
	        this.clearColor = 0;
	        /**
	         * 是否开启动态模糊
	         * @type {boolean}
	         * @default false
	         */
	        this.motionBlur = false;
	        /**
	         * 在开启动态模糊的时候使用，与上一帧混合的alpha值，值越大尾迹越明显
	         * @type {number}
	         * @default 0.7
	         */
	        this.lastFrameAlpha = 0.7;

	        /**
	         * Layer dpr
	         * @type {number}
	         */
	        this.dpr = dpr;
	    };

	    Layer.prototype = {

	        constructor: Layer,

	        elCount: 0,

	        __dirty: true,

	        initContext: function () {
	            this.ctx = this.dom.getContext('2d');

	            this.ctx.dpr = this.dpr;
	        },

	        createBackBuffer: function () {
	            var dpr = this.dpr;

	            this.domBack = createDom('back-' + this.id, 'canvas', this.painter, dpr);
	            this.ctxBack = this.domBack.getContext('2d');

	            if (dpr != 1) {
	                this.ctxBack.scale(dpr, dpr);
	            }
	        },

	        /**
	         * @param  {number} width
	         * @param  {number} height
	         */
	        resize: function (width, height) {
	            var dpr = this.dpr;

	            var dom = this.dom;
	            var domStyle = dom.style;
	            var domBack = this.domBack;

	            domStyle.width = width + 'px';
	            domStyle.height = height + 'px';

	            dom.width = width * dpr;
	            dom.height = height * dpr;

	            if (domBack) {
	                domBack.width = width * dpr;
	                domBack.height = height * dpr;

	                if (dpr != 1) {
	                    this.ctxBack.scale(dpr, dpr);
	                }
	            }
	        },

	        /**
	         * 清空该层画布
	         * @param {boolean} clearAll Clear all with out motion blur
	         */
	        clear: function (clearAll) {
	            var dom = this.dom;
	            var ctx = this.ctx;
	            var width = dom.width;
	            var height = dom.height;

	            var clearColor = this.clearColor;
	            var haveMotionBLur = this.motionBlur && !clearAll;
	            var lastFrameAlpha = this.lastFrameAlpha;

	            var dpr = this.dpr;

	            if (haveMotionBLur) {
	                if (!this.domBack) {
	                    this.createBackBuffer();
	                }

	                this.ctxBack.globalCompositeOperation = 'copy';
	                this.ctxBack.drawImage(
	                    dom, 0, 0,
	                    width / dpr,
	                    height / dpr
	                );
	            }

	            ctx.clearRect(0, 0, width, height);
	            if (clearColor) {
	                var clearColorGradientOrPattern;
	                // Gradient
	                if (clearColor.colorStops) {
	                    // Cache canvas gradient
	                    clearColorGradientOrPattern = clearColor.__canvasGradient || Style.getGradient(ctx, clearColor, {
	                        x: 0,
	                        y: 0,
	                        width: width,
	                        height: height
	                    });

	                    clearColor.__canvasGradient = clearColorGradientOrPattern;
	                }
	                // Pattern
	                else if (clearColor.image) {
	                    clearColorGradientOrPattern = Pattern.prototype.getCanvasPattern.call(clearColor, ctx);
	                }
	                ctx.save();
	                ctx.fillStyle = clearColorGradientOrPattern || clearColor;
	                ctx.fillRect(0, 0, width, height);
	                ctx.restore();
	            }

	            if (haveMotionBLur) {
	                var domBack = this.domBack;
	                ctx.save();
	                ctx.globalAlpha = lastFrameAlpha;
	                ctx.drawImage(domBack, 0, 0, width, height);
	                ctx.restore();
	            }
	        }
	    };

	    module.exports = Layer;


/***/ },
/* 94 */
/***/ function(module, exports, __webpack_require__) {

	
	    var Gradient = __webpack_require__(66);
	    module.exports = function (ecModel) {
	        function encodeColor(seriesModel) {
	            var colorAccessPath = (seriesModel.visualColorAccessPath || 'itemStyle.normal.color').split('.');
	            var data = seriesModel.getData();
	            var color = seriesModel.get(colorAccessPath) // Set in itemStyle
	                || seriesModel.getColorFromPalette(seriesModel.get('name'));  // Default color

	            // FIXME Set color function or use the platte color
	            data.setVisual('color', color);

	            // Only visible series has each data be visual encoded
	            if (!ecModel.isSeriesFiltered(seriesModel)) {
	                if (typeof color === 'function' && !(color instanceof Gradient)) {
	                    data.each(function (idx) {
	                        data.setItemVisual(
	                            idx, 'color', color(seriesModel.getDataParams(idx))
	                        );
	                    });
	                }

	                // itemStyle in each data item
	                data.each(function (idx) {
	                    var itemModel = data.getItemModel(idx);
	                    var color = itemModel.get(colorAccessPath, true);
	                    if (color != null) {
	                        data.setItemVisual(idx, 'color', color);
	                    }
	                });
	            }
	        }
	        ecModel.eachRawSeries(encodeColor);
	    };


/***/ },
/* 95 */
/***/ function(module, exports, __webpack_require__) {

	// Compatitable with 2.0


	    var zrUtil = __webpack_require__(4);
	    var compatStyle = __webpack_require__(96);

	    function get(opt, path) {
	        path = path.split(',');
	        var obj = opt;
	        for (var i = 0; i < path.length; i++) {
	            obj = obj && obj[path[i]];
	            if (obj == null) {
	                break;
	            }
	        }
	        return obj;
	    }

	    function set(opt, path, val, overwrite) {
	        path = path.split(',');
	        var obj = opt;
	        var key;
	        for (var i = 0; i < path.length - 1; i++) {
	            key = path[i];
	            if (obj[key] == null) {
	                obj[key] = {};
	            }
	            obj = obj[key];
	        }
	        if (overwrite || obj[path[i]] == null) {
	            obj[path[i]] = val;
	        }
	    }

	    function compatLayoutProperties(option) {
	        each(LAYOUT_PROPERTIES, function (prop) {
	            if (prop[0] in option && !(prop[1] in option)) {
	                option[prop[1]] = option[prop[0]];
	            }
	        });
	    }

	    var LAYOUT_PROPERTIES = [
	        ['x', 'left'], ['y', 'top'], ['x2', 'right'], ['y2', 'bottom']
	    ];

	    var COMPATITABLE_COMPONENTS = [
	        'grid', 'geo', 'parallel', 'legend', 'toolbox', 'title', 'visualMap', 'dataZoom', 'timeline'
	    ];

	    var COMPATITABLE_SERIES = [
	        'bar', 'boxplot', 'candlestick', 'chord', 'effectScatter',
	        'funnel', 'gauge', 'lines', 'graph', 'heatmap', 'line', 'map', 'parallel',
	        'pie', 'radar', 'sankey', 'scatter', 'treemap'
	    ];

	    var each = zrUtil.each;

	    module.exports = function (option) {
	        each(option.series, function (seriesOpt) {
	            if (!zrUtil.isObject(seriesOpt)) {
	                return;
	            }

	            var seriesType = seriesOpt.type;

	            compatStyle(seriesOpt);

	            if (seriesType === 'pie' || seriesType === 'gauge') {
	                if (seriesOpt.clockWise != null) {
	                    seriesOpt.clockwise = seriesOpt.clockWise;
	                }
	            }
	            if (seriesType === 'gauge') {
	                var pointerColor = get(seriesOpt, 'pointer.color');
	                pointerColor != null
	                    && set(seriesOpt, 'itemStyle.normal.color', pointerColor);
	            }

	            for (var i = 0; i < COMPATITABLE_SERIES.length; i++) {
	                if (COMPATITABLE_SERIES[i] === seriesOpt.type) {
	                    compatLayoutProperties(seriesOpt);
	                    break;
	                }
	            }
	        });

	        // dataRange has changed to visualMap
	        if (option.dataRange) {
	            option.visualMap = option.dataRange;
	        }

	        each(COMPATITABLE_COMPONENTS, function (componentName) {
	            var options = option[componentName];
	            if (options) {
	                if (!zrUtil.isArray(options)) {
	                    options = [options];
	                }
	                each(options, function (option) {
	                    compatLayoutProperties(option);
	                });
	            }
	        });
	    };


/***/ },
/* 96 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);

	    var POSSIBLE_STYLES = [
	        'areaStyle', 'lineStyle', 'nodeStyle', 'linkStyle',
	        'chordStyle', 'label', 'labelLine'
	    ];

	    function compatItemStyle(opt) {
	        var itemStyleOpt = opt && opt.itemStyle;
	        if (itemStyleOpt) {
	            zrUtil.each(POSSIBLE_STYLES, function (styleName) {
	                var normalItemStyleOpt = itemStyleOpt.normal;
	                var emphasisItemStyleOpt = itemStyleOpt.emphasis;
	                if (normalItemStyleOpt && normalItemStyleOpt[styleName]) {
	                    opt[styleName] = opt[styleName] || {};
	                    if (!opt[styleName].normal) {
	                        opt[styleName].normal = normalItemStyleOpt[styleName];
	                    }
	                    else {
	                        zrUtil.merge(opt[styleName].normal, normalItemStyleOpt[styleName]);
	                    }
	                    normalItemStyleOpt[styleName] = null;
	                }
	                if (emphasisItemStyleOpt && emphasisItemStyleOpt[styleName]) {
	                    opt[styleName] = opt[styleName] || {};
	                    if (!opt[styleName].emphasis) {
	                        opt[styleName].emphasis = emphasisItemStyleOpt[styleName];
	                    }
	                    else {
	                        zrUtil.merge(opt[styleName].emphasis, emphasisItemStyleOpt[styleName]);
	                    }
	                    emphasisItemStyleOpt[styleName] = null;
	                }
	            });
	        }
	    }

	    module.exports = function (seriesOpt) {
	        if (!seriesOpt) {
	            return;
	        }
	        compatItemStyle(seriesOpt);
	        compatItemStyle(seriesOpt.markPoint);
	        compatItemStyle(seriesOpt.markLine);
	        var data = seriesOpt.data;
	        if (data) {
	            for (var i = 0; i < data.length; i++) {
	                compatItemStyle(data[i]);
	            }
	            // mark point data
	            var markPoint = seriesOpt.markPoint;
	            if (markPoint && markPoint.data) {
	                var mpData = markPoint.data;
	                for (var i = 0; i < mpData.length; i++) {
	                    compatItemStyle(mpData[i]);
	                }
	            }
	            // mark line data
	            var markLine = seriesOpt.markLine;
	            if (markLine && markLine.data) {
	                var mlData = markLine.data;
	                for (var i = 0; i < mlData.length; i++) {
	                    if (zrUtil.isArray(mlData[i])) {
	                        compatItemStyle(mlData[i][0]);
	                        compatItemStyle(mlData[i][1]);
	                    }
	                    else {
	                        compatItemStyle(mlData[i]);
	                    }
	                }
	            }
	        }
	    };


/***/ },
/* 97 */
/***/ function(module, exports, __webpack_require__) {

	

	    var graphic = __webpack_require__(18);
	    var zrUtil = __webpack_require__(4);
	    var PI = Math.PI;
	    /**
	     * @param {module:echarts/ExtensionAPI} api
	     * @param {Object} [opts]
	     * @param {string} [opts.text]
	     * @param {string} [opts.color]
	     * @param {string} [opts.textColor]
	     * @return {module:zrender/Element}
	     */
	    module.exports = function (api, opts) {
	        opts = opts || {};
	        zrUtil.defaults(opts, {
	            text: 'loading',
	            color: '#c23531',
	            textColor: '#000',
	            maskColor: 'rgba(255, 255, 255, 0.8)',
	            zlevel: 0
	        });
	        var mask = new graphic.Rect({
	            style: {
	                fill: opts.maskColor
	            },
	            zlevel: opts.zlevel,
	            z: 10000
	        });
	        var arc = new graphic.Arc({
	            shape: {
	                startAngle: -PI / 2,
	                endAngle: -PI / 2 + 0.1,
	                r: 10
	            },
	            style: {
	                stroke: opts.color,
	                lineCap: 'round',
	                lineWidth: 5
	            },
	            zlevel: opts.zlevel,
	            z: 10001
	        });
	        var labelRect = new graphic.Rect({
	            style: {
	                fill: 'none',
	                text: opts.text,
	                textPosition: 'right',
	                textDistance: 10,
	                textFill: opts.textColor
	            },
	            zlevel: opts.zlevel,
	            z: 10001
	        });

	        arc.animateShape(true)
	            .when(1000, {
	                endAngle: PI * 3 / 2
	            })
	            .start('circularInOut');
	        arc.animateShape(true)
	            .when(1000, {
	                startAngle: PI * 3 / 2
	            })
	            .delay(300)
	            .start('circularInOut');

	        var group = new graphic.Group();
	        group.add(arc);
	        group.add(labelRect);
	        group.add(mask);
	        // Inject resize
	        group.resize = function () {
	            var cx = api.getWidth() / 2;
	            var cy = api.getHeight() / 2;
	            arc.setShape({
	                cx: cx,
	                cy: cy
	            });
	            var r = arc.shape.r;
	            labelRect.setShape({
	                x: cx - r,
	                y: cy - r,
	                width: r * 2,
	                height: r * 2
	            });

	            mask.setShape({
	                x: 0,
	                y: 0,
	                width: api.getWidth(),
	                height: api.getHeight()
	            });
	        };
	        group.resize();
	        return group;
	    };


/***/ },
/* 98 */
/***/ function(module, exports, __webpack_require__) {

	/* WEBPACK VAR INJECTION */(function(global) {/**
	 * List for data storage
	 * @module echarts/data/List
	 */


	    var UNDEFINED = 'undefined';
	    var globalObj = typeof window === 'undefined' ? global : window;
	    var Float64Array = typeof globalObj.Float64Array === UNDEFINED
	        ? Array : globalObj.Float64Array;
	    var Int32Array = typeof globalObj.Int32Array === UNDEFINED
	        ? Array : globalObj.Int32Array;

	    var dataCtors = {
	        'float': Float64Array,
	        'int': Int32Array,
	        // Ordinal data type can be string or int
	        'ordinal': Array,
	        'number': Array,
	        'time': Array
	    };

	    var Model = __webpack_require__(12);
	    var DataDiffer = __webpack_require__(99);

	    var zrUtil = __webpack_require__(4);
	    var modelUtil = __webpack_require__(5);
	    var isObject = zrUtil.isObject;

	    var TRANSFERABLE_PROPERTIES = [
	        'stackedOn', 'hasItemOption', '_nameList', '_idList', '_rawData'
	    ];

	    function transferProperties(a, b) {
	        zrUtil.each(TRANSFERABLE_PROPERTIES.concat(b.__wrappedMethods || []), function (propName) {
	            if (b.hasOwnProperty(propName)) {
	                a[propName] = b[propName];
	            }
	        });

	        a.__wrappedMethods = b.__wrappedMethods;
	    }

	    function DefaultDataProvider(dataArray) {
	        this._array = dataArray || [];
	    }

	    DefaultDataProvider.prototype.pure = false;

	    DefaultDataProvider.prototype.count = function () {
	        return this._array.length;
	    };
	    DefaultDataProvider.prototype.getItem = function (idx) {
	        return this._array[idx];
	    };

	    /**
	     * @constructor
	     * @alias module:echarts/data/List
	     *
	     * @param {Array.<string|Object>} dimensions
	     *      For example, ['someDimName', {name: 'someDimName', type: 'someDimType'}, ...].
	     *      Dimensions should be concrete names like x, y, z, lng, lat, angle, radius
	     * @param {module:echarts/model/Model} hostModel
	     */
	    var List = function (dimensions, hostModel) {

	        dimensions = dimensions || ['x', 'y'];

	        var dimensionInfos = {};
	        var dimensionNames = [];
	        for (var i = 0; i < dimensions.length; i++) {
	            var dimensionName;
	            var dimensionInfo = {};
	            if (typeof dimensions[i] === 'string') {
	                dimensionName = dimensions[i];
	                dimensionInfo = {
	                    name: dimensionName,
	                    coordDim: dimensionName,
	                    coordDimIndex: 0,
	                    stackable: false,
	                    // Type can be 'float', 'int', 'number'
	                    // Default is number, Precision of float may not enough
	                    type: 'number'
	                };
	            }
	            else {
	                dimensionInfo = dimensions[i];
	                dimensionName = dimensionInfo.name;
	                dimensionInfo.type = dimensionInfo.type || 'number';
	                if (!dimensionInfo.coordDim) {
	                    dimensionInfo.coordDim = dimensionName;
	                    dimensionInfo.coordDimIndex = 0;
	                }
	            }
	            dimensionInfo.otherDims = dimensionInfo.otherDims || {};
	            dimensionNames.push(dimensionName);
	            dimensionInfos[dimensionName] = dimensionInfo;
	        }

	        /**
	         * @readOnly
	         * @type {Array.<string>}
	         */
	        this.dimensions = dimensionNames;

	        /**
	         * Infomation of each data dimension, like data type.
	         * @type {Object}
	         */
	        this._dimensionInfos = dimensionInfos;

	        /**
	         * @type {module:echarts/model/Model}
	         */
	        this.hostModel = hostModel;

	        /**
	         * @type {module:echarts/model/Model}
	         */
	        this.dataType;

	        /**
	         * Indices stores the indices of data subset after filtered.
	         * This data subset will be used in chart.
	         * @type {Array.<number>}
	         * @readOnly
	         */
	        this.indices = [];

	        /**
	         * Data storage
	         * @type {Object.<key, TypedArray|Array>}
	         * @private
	         */
	        this._storage = {};

	        /**
	         * @type {Array.<string>}
	         */
	        this._nameList = [];
	        /**
	         * @type {Array.<string>}
	         */
	        this._idList = [];

	        /**
	         * Models of data option is stored sparse for optimizing memory cost
	         * @type {Array.<module:echarts/model/Model>}
	         * @private
	         */
	        this._optionModels = [];

	        /**
	         * @param {module:echarts/data/List}
	         */
	        this.stackedOn = null;

	        /**
	         * Global visual properties after visual coding
	         * @type {Object}
	         * @private
	         */
	        this._visual = {};

	        /**
	         * Globel layout properties.
	         * @type {Object}
	         * @private
	         */
	        this._layout = {};

	        /**
	         * Item visual properties after visual coding
	         * @type {Array.<Object>}
	         * @private
	         */
	        this._itemVisuals = [];

	        /**
	         * Item layout properties after layout
	         * @type {Array.<Object>}
	         * @private
	         */
	        this._itemLayouts = [];

	        /**
	         * Graphic elemnents
	         * @type {Array.<module:zrender/Element>}
	         * @private
	         */
	        this._graphicEls = [];

	        /**
	         * @type {Array.<Array|Object>}
	         * @private
	         */
	        this._rawData;

	        /**
	         * @type {Object}
	         * @private
	         */
	        this._extent;
	    };

	    var listProto = List.prototype;

	    listProto.type = 'list';

	    /**
	     * If each data item has it's own option
	     * @type {boolean}
	     */
	    listProto.hasItemOption = true;

	    /**
	     * Get dimension name
	     * @param {string|number} dim
	     *        Dimension can be concrete names like x, y, z, lng, lat, angle, radius
	     *        Or a ordinal number. For example getDimensionInfo(0) will return 'x' or 'lng' or 'radius'
	     * @return {string} Concrete dim name.
	     */
	    listProto.getDimension = function (dim) {
	        if (!isNaN(dim)) {
	            dim = this.dimensions[dim] || dim;
	        }
	        return dim;
	    };

	    /**
	     * Get type and stackable info of particular dimension
	     * @param {string|number} dim
	     *        Dimension can be concrete names like x, y, z, lng, lat, angle, radius
	     *        Or a ordinal number. For example getDimensionInfo(0) will return 'x' or 'lng' or 'radius'
	     */
	    listProto.getDimensionInfo = function (dim) {
	        return zrUtil.clone(this._dimensionInfos[this.getDimension(dim)]);
	    };

	    /**
	     * Initialize from data
	     * @param {Array.<Object|number|Array>} data
	     * @param {Array.<string>} [nameList]
	     * @param {Function} [dimValueGetter] (dataItem, dimName, dataIndex, dimIndex) => number
	     */
	    listProto.initData = function (data, nameList, dimValueGetter) {
	        data = data || [];

	        var isDataArray = zrUtil.isArray(data);
	        if (isDataArray) {
	            data = new DefaultDataProvider(data);
	        }
	        if (true) {
	            if (!isDataArray && (typeof data.getItem != 'function' || typeof data.count != 'function')) {
	                throw new Error('Inavlid data provider.');
	            }
	        }

	        this._rawData = data;

	        // Clear
	        var storage = this._storage = {};
	        var indices = this.indices = [];

	        var dimensions = this.dimensions;
	        var dimensionInfoMap = this._dimensionInfos;

	        var size = data.count();

	        var idList = [];
	        var nameRepeatCount = {};
	        var nameDimIdx;

	        nameList = nameList || [];

	        // Init storage
	        for (var i = 0; i < dimensions.length; i++) {
	            var dimInfo = dimensionInfoMap[dimensions[i]];
	            dimInfo.otherDims.itemName === 0 && (nameDimIdx = i);
	            var DataCtor = dataCtors[dimInfo.type];
	            storage[dimensions[i]] = new DataCtor(size);
	        }

	        var self = this;
	        if (!dimValueGetter) {
	            self.hasItemOption = false;
	        }
	        // Default dim value getter
	        dimValueGetter = dimValueGetter || function (dataItem, dimName, dataIndex, dimIndex) {
	            var value = modelUtil.getDataItemValue(dataItem);
	            // If any dataItem is like { value: 10 }
	            if (modelUtil.isDataItemOption(dataItem)) {
	                self.hasItemOption = true;
	            }
	            return modelUtil.converDataValue(
	                (value instanceof Array)
	                    ? value[dimIndex]
	                    // If value is a single number or something else not array.
	                    : value,
	                dimensionInfoMap[dimName]
	            );
	        };

	        for (var i = 0; i < size; i++) {
	            // NOTICE: Try not to write things into dataItem
	            var dataItem = data.getItem(i);
	            // Each data item is value
	            // [1, 2]
	            // 2
	            // Bar chart, line chart which uses category axis
	            // only gives the 'y' value. 'x' value is the indices of cateogry
	            // Use a tempValue to normalize the value to be a (x, y) value

	            // Store the data by dimensions
	            for (var k = 0; k < dimensions.length; k++) {
	                var dim = dimensions[k];
	                var dimStorage = storage[dim];
	                // PENDING NULL is empty or zero
	                dimStorage[i] = dimValueGetter(dataItem, dim, i, k);
	            }

	            indices.push(i);
	        }

	        // Use the name in option and create id
	        for (var i = 0; i < size; i++) {
	            var dataItem = data.getItem(i);
	            if (!nameList[i] && dataItem) {
	                if (dataItem.name != null) {
	                    nameList[i] = dataItem.name;
	                }
	                else if (nameDimIdx != null) {
	                    nameList[i] = storage[dimensions[nameDimIdx]][i];
	                }
	            }
	            var name = nameList[i] || '';
	            // Try using the id in option
	            var id = dataItem && dataItem.id;

	            if (!id && name) {
	                // Use name as id and add counter to avoid same name
	                nameRepeatCount[name] = nameRepeatCount[name] || 0;
	                id = name;
	                if (nameRepeatCount[name] > 0) {
	                    id += '__ec__' + nameRepeatCount[name];
	                }
	                nameRepeatCount[name]++;
	            }
	            id && (idList[i] = id);
	        }

	        this._nameList = nameList;
	        this._idList = idList;
	    };

	    /**
	     * @return {number}
	     */
	    listProto.count = function () {
	        return this.indices.length;
	    };

	    /**
	     * Get value. Return NaN if idx is out of range.
	     * @param {string} dim Dim must be concrete name.
	     * @param {number} idx
	     * @param {boolean} stack
	     * @return {number}
	     */
	    listProto.get = function (dim, idx, stack) {
	        var storage = this._storage;
	        var dataIndex = this.indices[idx];

	        // If value not exists
	        if (dataIndex == null || !storage[dim]) {
	            return NaN;
	        }

	        var value = storage[dim][dataIndex];
	        // FIXME ordinal data type is not stackable
	        if (stack) {
	            var dimensionInfo = this._dimensionInfos[dim];
	            if (dimensionInfo && dimensionInfo.stackable) {
	                var stackedOn = this.stackedOn;
	                while (stackedOn) {
	                    // Get no stacked data of stacked on
	                    var stackedValue = stackedOn.get(dim, idx);
	                    // Considering positive stack, negative stack and empty data
	                    if ((value >= 0 && stackedValue > 0)  // Positive stack
	                        || (value <= 0 && stackedValue < 0) // Negative stack
	                    ) {
	                        value += stackedValue;
	                    }
	                    stackedOn = stackedOn.stackedOn;
	                }
	            }
	        }
	        return value;
	    };

	    /**
	     * Get value for multi dimensions.
	     * @param {Array.<string>} [dimensions] If ignored, using all dimensions.
	     * @param {number} idx
	     * @param {boolean} stack
	     * @return {number}
	     */
	    listProto.getValues = function (dimensions, idx, stack) {
	        var values = [];

	        if (!zrUtil.isArray(dimensions)) {
	            stack = idx;
	            idx = dimensions;
	            dimensions = this.dimensions;
	        }

	        for (var i = 0, len = dimensions.length; i < len; i++) {
	            values.push(this.get(dimensions[i], idx, stack));
	        }

	        return values;
	    };

	    /**
	     * If value is NaN. Inlcuding '-'
	     * @param {string} dim
	     * @param {number} idx
	     * @return {number}
	     */
	    listProto.hasValue = function (idx) {
	        var dimensions = this.dimensions;
	        var dimensionInfos = this._dimensionInfos;
	        for (var i = 0, len = dimensions.length; i < len; i++) {
	            if (
	                // Ordinal type can be string or number
	                dimensionInfos[dimensions[i]].type !== 'ordinal'
	                && isNaN(this.get(dimensions[i], idx))
	            ) {
	                return false;
	            }
	        }
	        return true;
	    };

	    /**
	     * Get extent of data in one dimension
	     * @param {string} dim
	     * @param {boolean} stack
	     * @param {Function} filter
	     */
	    listProto.getDataExtent = function (dim, stack, filter) {
	        dim = this.getDimension(dim);
	        var dimData = this._storage[dim];
	        var dimInfo = this.getDimensionInfo(dim);
	        stack = (dimInfo && dimInfo.stackable) && stack;
	        var dimExtent = (this._extent || (this._extent = {}))[dim + (!!stack)];
	        var value;
	        if (dimExtent) {
	            return dimExtent;
	        }
	        // var dimInfo = this._dimensionInfos[dim];
	        if (dimData) {
	            var min = Infinity;
	            var max = -Infinity;
	            // var isOrdinal = dimInfo.type === 'ordinal';
	            for (var i = 0, len = this.count(); i < len; i++) {
	                value = this.get(dim, i, stack);
	                // FIXME
	                // if (isOrdinal && typeof value === 'string') {
	                //     value = zrUtil.indexOf(dimData, value);
	                // }
	                if (!filter || filter(value, dim, i)) {
	                    value < min && (min = value);
	                    value > max && (max = value);
	                }
	            }
	            return (this._extent[dim + !!stack] = [min, max]);
	        }
	        else {
	            return [Infinity, -Infinity];
	        }
	    };

	    /**
	     * Get sum of data in one dimension
	     * @param {string} dim
	     * @param {boolean} stack
	     */
	    listProto.getSum = function (dim, stack) {
	        var dimData = this._storage[dim];
	        var sum = 0;
	        if (dimData) {
	            for (var i = 0, len = this.count(); i < len; i++) {
	                var value = this.get(dim, i, stack);
	                if (!isNaN(value)) {
	                    sum += value;
	                }
	            }
	        }
	        return sum;
	    };

	    /**
	     * Retreive the index with given value
	     * @param {number} idx
	     * @param {number} value
	     * @return {number}
	     */
	    // FIXME Precision of float value
	    listProto.indexOf = function (dim, value) {
	        var storage = this._storage;
	        var dimData = storage[dim];
	        var indices = this.indices;

	        if (dimData) {
	            for (var i = 0, len = indices.length; i < len; i++) {
	                var rawIndex = indices[i];
	                if (dimData[rawIndex] === value) {
	                    return i;
	                }
	            }
	        }
	        return -1;
	    };

	    /**
	     * Retreive the index with given name
	     * @param {number} idx
	     * @param {number} name
	     * @return {number}
	     */
	    listProto.indexOfName = function (name) {
	        var indices = this.indices;
	        var nameList = this._nameList;

	        for (var i = 0, len = indices.length; i < len; i++) {
	            var rawIndex = indices[i];
	            if (nameList[rawIndex] === name) {
	                return i;
	            }
	        }

	        return -1;
	    };

	    /**
	     * Retreive the index with given raw data index
	     * @param {number} idx
	     * @param {number} name
	     * @return {number}
	     */
	    listProto.indexOfRawIndex = function (rawIndex) {
	        // Indices are ascending
	        var indices = this.indices;

	        // If rawIndex === dataIndex
	        var rawDataIndex = indices[rawIndex];
	        if (rawDataIndex != null && rawDataIndex === rawIndex) {
	            return rawIndex;
	        }

	        var left = 0;
	        var right = indices.length - 1;
	        while (left <= right) {
	            var mid = (left + right) / 2 | 0;
	            if (indices[mid] < rawIndex) {
	                left = mid + 1;
	            }
	            else if (indices[mid] > rawIndex) {
	                right = mid - 1;
	            }
	            else {
	                return mid;
	            }
	        }
	        return -1;
	    };

	    /**
	     * Retreive the index of nearest value
	     * @param {string} dim
	     * @param {number} value
	     * @param {boolean} stack If given value is after stacked
	     * @param {number} [maxDistance=Infinity]
	     * @return {Array.<number>} Considere multiple points has the same value.
	     */
	    listProto.indicesOfNearest = function (dim, value, stack, maxDistance) {
	        var storage = this._storage;
	        var dimData = storage[dim];
	        var nearestIndices = [];

	        if (!dimData) {
	            return nearestIndices;
	        }

	        if (maxDistance == null) {
	            maxDistance = Infinity;
	        }

	        var minDist = Number.MAX_VALUE;
	        var minDiff = -1;
	        for (var i = 0, len = this.count(); i < len; i++) {
	            var diff = value - this.get(dim, i, stack);
	            var dist = Math.abs(diff);
	            if (diff <= maxDistance && dist <= minDist) {
	                // For the case of two data are same on xAxis, which has sequence data.
	                // Show the nearest index
	                // https://github.com/ecomfe/echarts/issues/2869
	                if (dist < minDist || (diff >= 0 && minDiff < 0)) {
	                    minDist = dist;
	                    minDiff = diff;
	                    nearestIndices.length = 0;
	                }
	                nearestIndices.push(i);
	            }
	        }
	        return nearestIndices;
	    };

	    /**
	     * Get raw data index
	     * @param {number} idx
	     * @return {number}
	     */
	    listProto.getRawIndex = function (idx) {
	        var rawIdx = this.indices[idx];
	        return rawIdx == null ? -1 : rawIdx;
	    };

	    /**
	     * Get raw data item
	     * @param {number} idx
	     * @return {number}
	     */
	    listProto.getRawDataItem = function (idx) {
	        return this._rawData.getItem(this.getRawIndex(idx));
	    };

	    /**
	     * @param {number} idx
	     * @param {boolean} [notDefaultIdx=false]
	     * @return {string}
	     */
	    listProto.getName = function (idx) {
	        return this._nameList[this.indices[idx]] || '';
	    };

	    /**
	     * @param {number} idx
	     * @param {boolean} [notDefaultIdx=false]
	     * @return {string}
	     */
	    listProto.getId = function (idx) {
	        return this._idList[this.indices[idx]] || (this.getRawIndex(idx) + '');
	    };


	    function normalizeDimensions(dimensions) {
	        if (!zrUtil.isArray(dimensions)) {
	            dimensions = [dimensions];
	        }
	        return dimensions;
	    }

	    /**
	     * Data iteration
	     * @param {string|Array.<string>}
	     * @param {Function} cb
	     * @param {boolean} [stack=false]
	     * @param {*} [context=this]
	     *
	     * @example
	     *  list.each('x', function (x, idx) {});
	     *  list.each(['x', 'y'], function (x, y, idx) {});
	     *  list.each(function (idx) {})
	     */
	    listProto.each = function (dims, cb, stack, context) {
	        if (typeof dims === 'function') {
	            context = stack;
	            stack = cb;
	            cb = dims;
	            dims = [];
	        }

	        dims = zrUtil.map(normalizeDimensions(dims), this.getDimension, this);

	        var value = [];
	        var dimSize = dims.length;
	        var indices = this.indices;

	        context = context || this;

	        for (var i = 0; i < indices.length; i++) {
	            // Simple optimization
	            switch (dimSize) {
	                case 0:
	                    cb.call(context, i);
	                    break;
	                case 1:
	                    cb.call(context, this.get(dims[0], i, stack), i);
	                    break;
	                case 2:
	                    cb.call(context, this.get(dims[0], i, stack), this.get(dims[1], i, stack), i);
	                    break;
	                default:
	                    for (var k = 0; k < dimSize; k++) {
	                        value[k] = this.get(dims[k], i, stack);
	                    }
	                    // Index
	                    value[k] = i;
	                    cb.apply(context, value);
	            }
	        }
	    };

	    /**
	     * Data filter
	     * @param {string|Array.<string>}
	     * @param {Function} cb
	     * @param {boolean} [stack=false]
	     * @param {*} [context=this]
	     */
	    listProto.filterSelf = function (dimensions, cb, stack, context) {
	        if (typeof dimensions === 'function') {
	            context = stack;
	            stack = cb;
	            cb = dimensions;
	            dimensions = [];
	        }

	        dimensions = zrUtil.map(
	            normalizeDimensions(dimensions), this.getDimension, this
	        );

	        var newIndices = [];
	        var value = [];
	        var dimSize = dimensions.length;
	        var indices = this.indices;

	        context = context || this;

	        for (var i = 0; i < indices.length; i++) {
	            var keep;
	            // Simple optimization
	            if (!dimSize) {
	                keep = cb.call(context, i);
	            }
	            else if (dimSize === 1) {
	                keep = cb.call(
	                    context, this.get(dimensions[0], i, stack), i
	                );
	            }
	            else {
	                for (var k = 0; k < dimSize; k++) {
	                    value[k] = this.get(dimensions[k], i, stack);
	                }
	                value[k] = i;
	                keep = cb.apply(context, value);
	            }
	            if (keep) {
	                newIndices.push(indices[i]);
	            }
	        }

	        this.indices = newIndices;

	        // Reset data extent
	        this._extent = {};

	        return this;
	    };

	    /**
	     * Data mapping to a plain array
	     * @param {string|Array.<string>} [dimensions]
	     * @param {Function} cb
	     * @param {boolean} [stack=false]
	     * @param {*} [context=this]
	     * @return {Array}
	     */
	    listProto.mapArray = function (dimensions, cb, stack, context) {
	        if (typeof dimensions === 'function') {
	            context = stack;
	            stack = cb;
	            cb = dimensions;
	            dimensions = [];
	        }

	        var result = [];
	        this.each(dimensions, function () {
	            result.push(cb && cb.apply(this, arguments));
	        }, stack, context);
	        return result;
	    };

	    function cloneListForMapAndSample(original, excludeDimensions) {
	        var allDimensions = original.dimensions;
	        var list = new List(
	            zrUtil.map(allDimensions, original.getDimensionInfo, original),
	            original.hostModel
	        );
	        // FIXME If needs stackedOn, value may already been stacked
	        transferProperties(list, original);

	        var storage = list._storage = {};
	        var originalStorage = original._storage;
	        // Init storage
	        for (var i = 0; i < allDimensions.length; i++) {
	            var dim = allDimensions[i];
	            var dimStore = originalStorage[dim];
	            if (zrUtil.indexOf(excludeDimensions, dim) >= 0) {
	                storage[dim] = new dimStore.constructor(
	                    originalStorage[dim].length
	                );
	            }
	            else {
	                // Direct reference for other dimensions
	                storage[dim] = originalStorage[dim];
	            }
	        }
	        return list;
	    }

	    /**
	     * Data mapping to a new List with given dimensions
	     * @param {string|Array.<string>} dimensions
	     * @param {Function} cb
	     * @param {boolean} [stack=false]
	     * @param {*} [context=this]
	     * @return {Array}
	     */
	    listProto.map = function (dimensions, cb, stack, context) {
	        dimensions = zrUtil.map(
	            normalizeDimensions(dimensions), this.getDimension, this
	        );

	        var list = cloneListForMapAndSample(this, dimensions);
	        // Following properties are all immutable.
	        // So we can reference to the same value
	        var indices = list.indices = this.indices;

	        var storage = list._storage;

	        var tmpRetValue = [];
	        this.each(dimensions, function () {
	            var idx = arguments[arguments.length - 1];
	            var retValue = cb && cb.apply(this, arguments);
	            if (retValue != null) {
	                // a number
	                if (typeof retValue === 'number') {
	                    tmpRetValue[0] = retValue;
	                    retValue = tmpRetValue;
	                }
	                for (var i = 0; i < retValue.length; i++) {
	                    var dim = dimensions[i];
	                    var dimStore = storage[dim];
	                    var rawIdx = indices[idx];
	                    if (dimStore) {
	                        dimStore[rawIdx] = retValue[i];
	                    }
	                }
	            }
	        }, stack, context);

	        return list;
	    };

	    /**
	     * Large data down sampling on given dimension
	     * @param {string} dimension
	     * @param {number} rate
	     * @param {Function} sampleValue
	     * @param {Function} sampleIndex Sample index for name and id
	     */
	    listProto.downSample = function (dimension, rate, sampleValue, sampleIndex) {
	        var list = cloneListForMapAndSample(this, [dimension]);
	        var storage = this._storage;
	        var targetStorage = list._storage;

	        var originalIndices = this.indices;
	        var indices = list.indices = [];

	        var frameValues = [];
	        var frameIndices = [];
	        var frameSize = Math.floor(1 / rate);

	        var dimStore = targetStorage[dimension];
	        var len = this.count();
	        // Copy data from original data
	        for (var i = 0; i < storage[dimension].length; i++) {
	            targetStorage[dimension][i] = storage[dimension][i];
	        }
	        for (var i = 0; i < len; i += frameSize) {
	            // Last frame
	            if (frameSize > len - i) {
	                frameSize = len - i;
	                frameValues.length = frameSize;
	            }
	            for (var k = 0; k < frameSize; k++) {
	                var idx = originalIndices[i + k];
	                frameValues[k] = dimStore[idx];
	                frameIndices[k] = idx;
	            }
	            var value = sampleValue(frameValues);
	            var idx = frameIndices[sampleIndex(frameValues, value) || 0];
	            // Only write value on the filtered data
	            dimStore[idx] = value;
	            indices.push(idx);
	        }

	        return list;
	    };

	    /**
	     * Get model of one data item.
	     *
	     * @param {number} idx
	     */
	    // FIXME Model proxy ?
	    listProto.getItemModel = function (idx) {
	        var hostModel = this.hostModel;
	        idx = this.indices[idx];
	        return new Model(this._rawData.getItem(idx), hostModel, hostModel && hostModel.ecModel);
	    };

	    /**
	     * Create a data differ
	     * @param {module:echarts/data/List} otherList
	     * @return {module:echarts/data/DataDiffer}
	     */
	    listProto.diff = function (otherList) {
	        var idList = this._idList;
	        var otherIdList = otherList && otherList._idList;
	        var val;
	        // Use prefix to avoid index to be the same as otherIdList[idx],
	        // which will cause weird udpate animation.
	        var prefix = 'e\0\0';

	        return new DataDiffer(
	            otherList ? otherList.indices : [],
	            this.indices,
	            function (idx) {
	                return (val = otherIdList[idx]) != null ? val : prefix + idx;
	            },
	            function (idx) {
	                return (val = idList[idx]) != null ? val : prefix + idx;
	            }
	        );
	    };
	    /**
	     * Get visual property.
	     * @param {string} key
	     */
	    listProto.getVisual = function (key) {
	        var visual = this._visual;
	        return visual && visual[key];
	    };

	    /**
	     * Set visual property
	     * @param {string|Object} key
	     * @param {*} [value]
	     *
	     * @example
	     *  setVisual('color', color);
	     *  setVisual({
	     *      'color': color
	     *  });
	     */
	    listProto.setVisual = function (key, val) {
	        if (isObject(key)) {
	            for (var name in key) {
	                if (key.hasOwnProperty(name)) {
	                    this.setVisual(name, key[name]);
	                }
	            }
	            return;
	        }
	        this._visual = this._visual || {};
	        this._visual[key] = val;
	    };

	    /**
	     * Set layout property.
	     * @param {string} key
	     * @param {*} [val]
	     */
	    listProto.setLayout = function (key, val) {
	        if (isObject(key)) {
	            for (var name in key) {
	                if (key.hasOwnProperty(name)) {
	                    this.setLayout(name, key[name]);
	                }
	            }
	            return;
	        }
	        this._layout[key] = val;
	    };

	    /**
	     * Get layout property.
	     * @param  {string} key.
	     * @return {*}
	     */
	    listProto.getLayout = function (key) {
	        return this._layout[key];
	    };

	    /**
	     * Get layout of single data item
	     * @param {number} idx
	     */
	    listProto.getItemLayout = function (idx) {
	        return this._itemLayouts[idx];
	    };

	    /**
	     * Set layout of single data item
	     * @param {number} idx
	     * @param {Object} layout
	     * @param {boolean=} [merge=false]
	     */
	    listProto.setItemLayout = function (idx, layout, merge) {
	        this._itemLayouts[idx] = merge
	            ? zrUtil.extend(this._itemLayouts[idx] || {}, layout)
	            : layout;
	    };

	    /**
	     * Clear all layout of single data item
	     */
	    listProto.clearItemLayouts = function () {
	        this._itemLayouts.length = 0;
	    };

	    /**
	     * Get visual property of single data item
	     * @param {number} idx
	     * @param {string} key
	     * @param {boolean} [ignoreParent=false]
	     */
	    listProto.getItemVisual = function (idx, key, ignoreParent) {
	        var itemVisual = this._itemVisuals[idx];
	        var val = itemVisual && itemVisual[key];
	        if (val == null && !ignoreParent) {
	            // Use global visual property
	            return this.getVisual(key);
	        }
	        return val;
	    };

	    /**
	     * Set visual property of single data item
	     *
	     * @param {number} idx
	     * @param {string|Object} key
	     * @param {*} [value]
	     *
	     * @example
	     *  setItemVisual(0, 'color', color);
	     *  setItemVisual(0, {
	     *      'color': color
	     *  });
	     */
	    listProto.setItemVisual = function (idx, key, value) {
	        var itemVisual = this._itemVisuals[idx] || {};
	        this._itemVisuals[idx] = itemVisual;

	        if (isObject(key)) {
	            for (var name in key) {
	                if (key.hasOwnProperty(name)) {
	                    itemVisual[name] = key[name];
	                }
	            }
	            return;
	        }
	        itemVisual[key] = value;
	    };

	    /**
	     * Clear itemVisuals and list visual.
	     */
	    listProto.clearAllVisual = function () {
	        this._visual = {};
	        this._itemVisuals = [];
	    };

	    var setItemDataAndSeriesIndex = function (child) {
	        child.seriesIndex = this.seriesIndex;
	        child.dataIndex = this.dataIndex;
	        child.dataType = this.dataType;
	    };
	    /**
	     * Set graphic element relative to data. It can be set as null
	     * @param {number} idx
	     * @param {module:zrender/Element} [el]
	     */
	    listProto.setItemGraphicEl = function (idx, el) {
	        var hostModel = this.hostModel;

	        if (el) {
	            // Add data index and series index for indexing the data by element
	            // Useful in tooltip
	            el.dataIndex = idx;
	            el.dataType = this.dataType;
	            el.seriesIndex = hostModel && hostModel.seriesIndex;
	            if (el.type === 'group') {
	                el.traverse(setItemDataAndSeriesIndex, el);
	            }
	        }

	        this._graphicEls[idx] = el;
	    };

	    /**
	     * @param {number} idx
	     * @return {module:zrender/Element}
	     */
	    listProto.getItemGraphicEl = function (idx) {
	        return this._graphicEls[idx];
	    };

	    /**
	     * @param {Function} cb
	     * @param {*} context
	     */
	    listProto.eachItemGraphicEl = function (cb, context) {
	        zrUtil.each(this._graphicEls, function (el, idx) {
	            if (el) {
	                cb && cb.call(context, el, idx);
	            }
	        });
	    };

	    /**
	     * Shallow clone a new list except visual and layout properties, and graph elements.
	     * New list only change the indices.
	     */
	    listProto.cloneShallow = function () {
	        var dimensionInfoList = zrUtil.map(this.dimensions, this.getDimensionInfo, this);
	        var list = new List(dimensionInfoList, this.hostModel);

	        // FIXME
	        list._storage = this._storage;

	        transferProperties(list, this);


	        // Clone will not change the data extent and indices
	        list.indices = this.indices.slice();

	        if (this._extent) {
	            list._extent = zrUtil.extend({}, this._extent);
	        }

	        return list;
	    };

	    /**
	     * Wrap some method to add more feature
	     * @param {string} methodName
	     * @param {Function} injectFunction
	     */
	    listProto.wrapMethod = function (methodName, injectFunction) {
	        var originalMethod = this[methodName];
	        if (typeof originalMethod !== 'function') {
	            return;
	        }
	        this.__wrappedMethods = this.__wrappedMethods || [];
	        this.__wrappedMethods.push(methodName);
	        this[methodName] = function () {
	            var res = originalMethod.apply(this, arguments);
	            return injectFunction.apply(this, [res].concat(zrUtil.slice(arguments)));
	        };
	    };

	    // Methods that create a new list based on this list should be listed here.
	    // Notice that those method should `RETURN` the new list.
	    listProto.TRANSFERABLE_METHODS = ['cloneShallow', 'downSample', 'map'];
	    // Methods that change indices of this list should be listed here.
	    listProto.CHANGABLE_METHODS = ['filterSelf'];

	    module.exports = List;

	/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))

/***/ },
/* 99 */
/***/ function(module, exports) {

	'use strict';


	    function defaultKeyGetter(item) {
	        return item;
	    }

	    function DataDiffer(oldArr, newArr, oldKeyGetter, newKeyGetter) {
	        this._old = oldArr;
	        this._new = newArr;

	        this._oldKeyGetter = oldKeyGetter || defaultKeyGetter;
	        this._newKeyGetter = newKeyGetter || defaultKeyGetter;
	    }

	    DataDiffer.prototype = {

	        constructor: DataDiffer,

	        /**
	         * Callback function when add a data
	         */
	        add: function (func) {
	            this._add = func;
	            return this;
	        },

	        /**
	         * Callback function when update a data
	         */
	        update: function (func) {
	            this._update = func;
	            return this;
	        },

	        /**
	         * Callback function when remove a data
	         */
	        remove: function (func) {
	            this._remove = func;
	            return this;
	        },

	        execute: function () {
	            var oldArr = this._old;
	            var newArr = this._new;
	            var oldKeyGetter = this._oldKeyGetter;
	            var newKeyGetter = this._newKeyGetter;

	            var oldDataIndexMap = {};
	            var newDataIndexMap = {};
	            var oldDataKeyArr = [];
	            var newDataKeyArr = [];
	            var i;

	            initIndexMap(oldArr, oldDataIndexMap, oldDataKeyArr, oldKeyGetter);
	            initIndexMap(newArr, newDataIndexMap, newDataKeyArr, newKeyGetter);

	            // Travel by inverted order to make sure order consistency
	            // when duplicate keys exists (consider newDataIndex.pop() below).
	            // For performance consideration, these code below do not look neat.
	            for (i = 0; i < oldArr.length; i++) {
	                var key = oldDataKeyArr[i];
	                var idx = newDataIndexMap[key];

	                // idx can never be empty array here. see 'set null' logic below.
	                if (idx != null) {
	                    // Consider there is duplicate key (for example, use dataItem.name as key).
	                    // We should make sure every item in newArr and oldArr can be visited.
	                    var len = idx.length;
	                    if (len) {
	                        len === 1 && (newDataIndexMap[key] = null);
	                        idx = idx.unshift();
	                    }
	                    else {
	                        newDataIndexMap[key] = null;
	                    }
	                    this._update && this._update(idx, i);
	                }
	                else {
	                    this._remove && this._remove(i);
	                }
	            }

	            for (var i = 0; i < newDataKeyArr.length; i++) {
	                var key = newDataKeyArr[i];
	                if (newDataIndexMap.hasOwnProperty(key)) {
	                    var idx = newDataIndexMap[key];
	                    if (idx == null) {
	                        continue;
	                    }
	                    // idx can never be empty array here. see 'set null' logic above.
	                    if (!idx.length) {
	                        this._add && this._add(idx);
	                    }
	                    else {
	                        for (var j = 0, len = idx.length; j < len; j++) {
	                            this._add && this._add(idx[j]);
	                        }
	                    }
	                }
	            }
	        }
	    };

	    function initIndexMap(arr, map, keyArr, keyGetter) {
	        for (var i = 0; i < arr.length; i++) {
	            // Add prefix to avoid conflict with Object.prototype.
	            var key = '_ec_' + keyGetter(arr[i], i);
	            var existence = map[key];
	            if (existence == null) {
	                keyArr.push(key);
	                map[key] = i;
	            }
	            else {
	                if (!existence.length) {
	                    map[key] = existence = [existence];
	                }
	                existence.push(i);
	            }
	        }
	    }

	    module.exports = DataDiffer;


/***/ },
/* 100 */
/***/ function(module, exports, __webpack_require__) {

	

	    var numberUtil = __webpack_require__(7);
	    var linearMap = numberUtil.linearMap;
	    var zrUtil = __webpack_require__(4);
	    var axisHelper = __webpack_require__(101);

	    function fixExtentWithBands(extent, nTick) {
	        var size = extent[1] - extent[0];
	        var len = nTick;
	        var margin = size / len / 2;
	        extent[0] += margin;
	        extent[1] -= margin;
	    }

	    var normalizedExtent = [0, 1];
	    /**
	     * @name module:echarts/coord/CartesianAxis
	     * @constructor
	     */
	    var Axis = function (dim, scale, extent) {

	        /**
	         * Axis dimension. Such as 'x', 'y', 'z', 'angle', 'radius'
	         * @type {string}
	         */
	        this.dim = dim;

	        /**
	         * Axis scale
	         * @type {module:echarts/coord/scale/*}
	         */
	        this.scale = scale;

	        /**
	         * @type {Array.<number>}
	         * @private
	         */
	        this._extent = extent || [0, 0];

	        /**
	         * @type {boolean}
	         */
	        this.inverse = false;

	        /**
	         * Usually true when axis has a ordinal scale
	         * @type {boolean}
	         */
	        this.onBand = false;

	        /**
	         * @private
	         * @type {number}
	         */
	        this._labelInterval;
	    };

	    Axis.prototype = {

	        constructor: Axis,

	        /**
	         * If axis extent contain given coord
	         * @param {number} coord
	         * @return {boolean}
	         */
	        contain: function (coord) {
	            var extent = this._extent;
	            var min = Math.min(extent[0], extent[1]);
	            var max = Math.max(extent[0], extent[1]);
	            return coord >= min && coord <= max;
	        },

	        /**
	         * If axis extent contain given data
	         * @param {number} data
	         * @return {boolean}
	         */
	        containData: function (data) {
	            return this.contain(this.dataToCoord(data));
	        },

	        /**
	         * Get coord extent.
	         * @return {Array.<number>}
	         */
	        getExtent: function () {
	            return this._extent.slice();
	        },

	        /**
	         * Get precision used for formatting
	         * @param {Array.<number>} [dataExtent]
	         * @return {number}
	         */
	        getPixelPrecision: function (dataExtent) {
	            return numberUtil.getPixelPrecision(
	                dataExtent || this.scale.getExtent(),
	                this._extent
	            );
	        },

	        /**
	         * Set coord extent
	         * @param {number} start
	         * @param {number} end
	         */
	        setExtent: function (start, end) {
	            var extent = this._extent;
	            extent[0] = start;
	            extent[1] = end;
	        },

	        /**
	         * Convert data to coord. Data is the rank if it has a ordinal scale
	         * @param {number} data
	         * @param  {boolean} clamp
	         * @return {number}
	         */
	        dataToCoord: function (data, clamp) {
	            var extent = this._extent;
	            var scale = this.scale;
	            data = scale.normalize(data);

	            if (this.onBand && scale.type === 'ordinal') {
	                extent = extent.slice();
	                fixExtentWithBands(extent, scale.count());
	            }

	            return linearMap(data, normalizedExtent, extent, clamp);
	        },

	        /**
	         * Convert coord to data. Data is the rank if it has a ordinal scale
	         * @param {number} coord
	         * @param  {boolean} clamp
	         * @return {number}
	         */
	        coordToData: function (coord, clamp) {
	            var extent = this._extent;
	            var scale = this.scale;

	            if (this.onBand && scale.type === 'ordinal') {
	                extent = extent.slice();
	                fixExtentWithBands(extent, scale.count());
	            }

	            var t = linearMap(coord, extent, normalizedExtent, clamp);

	            return this.scale.scale(t);
	        },

	        /**
	         * Convert pixel point to data in axis
	         * @param {Array.<number>} point
	         * @param  {boolean} clamp
	         * @return {number} data
	         */
	        pointToData: function (point, clamp) {
	            // Should be implemented in derived class if necessary.
	        },

	        /**
	         * @return {Array.<number>}
	         */
	        getTicksCoords: function (alignWithLabel) {
	            if (this.onBand && !alignWithLabel) {
	                var bands = this.getBands();
	                var coords = [];
	                for (var i = 0; i < bands.length; i++) {
	                    coords.push(bands[i][0]);
	                }
	                if (bands[i - 1]) {
	                    coords.push(bands[i - 1][1]);
	                }
	                return coords;
	            }
	            else {
	                return zrUtil.map(this.scale.getTicks(), this.dataToCoord, this);
	            }
	        },

	        /**
	         * Coords of labels are on the ticks or on the middle of bands
	         * @return {Array.<number>}
	         */
	        getLabelsCoords: function () {
	            return zrUtil.map(this.scale.getTicks(), this.dataToCoord, this);
	        },

	        /**
	         * Get bands.
	         *
	         * If axis has labels [1, 2, 3, 4]. Bands on the axis are
	         * |---1---|---2---|---3---|---4---|.
	         *
	         * @return {Array}
	         */
	         // FIXME Situation when labels is on ticks
	        getBands: function () {
	            var extent = this.getExtent();
	            var bands = [];
	            var len = this.scale.count();
	            var start = extent[0];
	            var end = extent[1];
	            var span = end - start;

	            for (var i = 0; i < len; i++) {
	                bands.push([
	                    span * i / len + start,
	                    span * (i + 1) / len + start
	                ]);
	            }
	            return bands;
	        },

	        /**
	         * Get width of band
	         * @return {number}
	         */
	        getBandWidth: function () {
	            var axisExtent = this._extent;
	            var dataExtent = this.scale.getExtent();

	            var len = dataExtent[1] - dataExtent[0] + (this.onBand ? 1 : 0);
	            // Fix #2728, avoid NaN when only one data.
	            len === 0 && (len = 1);

	            var size = Math.abs(axisExtent[1] - axisExtent[0]);

	            return Math.abs(size) / len;
	        },

	        /**
	         * Get interval of the axis label.
	         * @return {number}
	         */
	        getLabelInterval: function () {
	            var labelInterval = this._labelInterval;
	            if (!labelInterval) {
	                var axisModel = this.model;
	                var labelModel = axisModel.getModel('axisLabel');
	                var interval = labelModel.get('interval');
	                if (!(this.type === 'category' && interval === 'auto')) {
	                    labelInterval = interval === 'auto' ? 0 : interval;
	                }
	                else if (this.isHorizontal){
	                    labelInterval = axisHelper.getAxisLabelInterval(
	                        zrUtil.map(this.scale.getTicks(), this.dataToCoord, this),
	                        axisModel.getFormattedLabels(),
	                        labelModel.getModel('textStyle').getFont(),
	                        this.isHorizontal()
	                    );
	                }
	                this._labelInterval = labelInterval;
	            }
	            return labelInterval;
	        }

	    };

	    module.exports = Axis;


/***/ },
/* 101 */
/***/ function(module, exports, __webpack_require__) {

	

	    var OrdinalScale = __webpack_require__(102);
	    var IntervalScale = __webpack_require__(104);
	    __webpack_require__(106);
	    __webpack_require__(107);
	    var Scale = __webpack_require__(103);

	    var numberUtil = __webpack_require__(7);
	    var zrUtil = __webpack_require__(4);
	    var textContain = __webpack_require__(8);
	    var axisHelper = {};

	    /**
	     * Get axis scale extent before niced.
	     * Item of returned array can only be number (including Infinity and NaN).
	     */
	    axisHelper.getScaleExtent = function (scale, model) {
	        var scaleType = scale.type;

	        var min = model.getMin();
	        var max = model.getMax();
	        var fixMin = min != null;
	        var fixMax = max != null;
	        var originalExtent = scale.getExtent();

	        var axisDataLen;
	        var boundaryGap;
	        var span;
	        if (scaleType === 'ordinal') {
	            axisDataLen = (model.get('data') || []).length;
	        }
	        else {
	            boundaryGap = model.get('boundaryGap');
	            if (!zrUtil.isArray(boundaryGap)) {
	                boundaryGap = [boundaryGap || 0, boundaryGap || 0];
	            }
	            if (typeof boundaryGap[0] === 'boolean') {
	                if (true) {
	                    console.warn('Boolean type for boundaryGap is only '
	                        + 'allowed for ordinal axis. Please use string in '
	                        + 'percentage instead, e.g., "20%". Currently, '
	                        + 'boundaryGap is set to be 0.');
	                }
	                boundaryGap = [0, 0];
	            }
	            boundaryGap[0] = numberUtil.parsePercent(boundaryGap[0], 1);
	            boundaryGap[1] = numberUtil.parsePercent(boundaryGap[1], 1);
	            span = (originalExtent[1] - originalExtent[0])
	                || Math.abs(originalExtent[0]);
	        }

	        // Notice: When min/max is not set (that is, when there are null/undefined,
	        // which is the most common case), these cases should be ensured:
	        // (1) For 'ordinal', show all axis.data.
	        // (2) For others:
	        //      + `boundaryGap` is applied (if min/max set, boundaryGap is
	        //      disabled).
	        //      + If `needCrossZero`, min/max should be zero, otherwise, min/max should
	        //      be the result that originalExtent enlarged by boundaryGap.
	        // (3) If no data, it should be ensured that `scale.setBlank` is set.

	        // FIXME
	        // (1) When min/max is 'dataMin' or 'dataMax', should boundaryGap be able to used?
	        // (2) When `needCrossZero` and all data is positive/negative, should it be ensured
	        // that the results processed by boundaryGap are positive/negative?

	        if (min == null) {
	            min = scaleType === 'ordinal'
	                ? (axisDataLen ? 0 : NaN)
	                : originalExtent[0] - boundaryGap[0] * span;
	        }
	        if (max == null) {
	            max = scaleType === 'ordinal'
	                ? (axisDataLen ? axisDataLen - 1 : NaN)
	                : originalExtent[1] + boundaryGap[1] * span;
	        }

	        if (min === 'dataMin') {
	            min = originalExtent[0];
	        }
	        if (max === 'dataMax') {
	            max = originalExtent[1];
	        }

	        (min == null || !isFinite(min)) && (min = NaN);
	        (max == null || !isFinite(max)) && (max = NaN);

	        scale.setBlank(zrUtil.eqNaN(min) || zrUtil.eqNaN(max));

	        // Evaluate if axis needs cross zero
	        if (model.getNeedCrossZero()) {
	            // Axis is over zero and min is not set
	            if (min > 0 && max > 0 && !fixMin) {
	                min = 0;
	            }
	            // Axis is under zero and max is not set
	            if (min < 0 && max < 0 && !fixMax) {
	                max = 0;
	            }
	        }

	        return [min, max];
	    };

	    axisHelper.niceScaleExtent = function (scale, model) {
	        var extent = axisHelper.getScaleExtent(scale, model);
	        var fixMin = model.getMin() != null;
	        var fixMax = model.getMax() != null;
	        var splitNumber = model.get('splitNumber');

	        if (scale.type === 'log') {
	            scale.base = model.get('logBase');
	        }

	        scale.setExtent(extent[0], extent[1]);
	        scale.niceExtent({
	            splitNumber: splitNumber,
	            fixMin: fixMin,
	            fixMax: fixMax,
	            minInterval: scale.type === 'interval' ? model.get('minInterval') : null
	        });

	        // If some one specified the min, max. And the default calculated interval
	        // is not good enough. He can specify the interval. It is often appeared
	        // in angle axis with angle 0 - 360. Interval calculated in interval scale is hard
	        // to be 60.
	        // FIXME
	        var interval = model.get('interval');
	        if (interval != null) {
	            scale.setInterval && scale.setInterval(interval);
	        }
	    };

	    /**
	     * @param {module:echarts/model/Model} model
	     * @param {string} [axisType] Default retrieve from model.type
	     * @return {module:echarts/scale/*}
	     */
	    axisHelper.createScaleByModel = function(model, axisType) {
	        axisType = axisType || model.get('type');
	        if (axisType) {
	            switch (axisType) {
	                // Buildin scale
	                case 'category':
	                    return new OrdinalScale(
	                        model.getCategories(), [Infinity, -Infinity]
	                    );
	                case 'value':
	                    return new IntervalScale();
	                // Extended scale, like time and log
	                default:
	                    return (Scale.getClass(axisType) || IntervalScale).create(model);
	            }
	        }
	    };

	    /**
	     * Check if the axis corss 0
	     */
	    axisHelper.ifAxisCrossZero = function (axis) {
	        var dataExtent = axis.scale.getExtent();
	        var min = dataExtent[0];
	        var max = dataExtent[1];
	        return !((min > 0 && max > 0) || (min < 0 && max < 0));
	    };

	    /**
	     * @param {Array.<number>} tickCoords In axis self coordinate.
	     * @param {Array.<string>} labels
	     * @param {string} font
	     * @param {boolean} isAxisHorizontal
	     * @return {number}
	     */
	    axisHelper.getAxisLabelInterval = function (tickCoords, labels, font, isAxisHorizontal) {
	        // FIXME
	        // 不同角的axis和label，不只是horizontal和vertical.

	        var textSpaceTakenRect;
	        var autoLabelInterval = 0;
	        var accumulatedLabelInterval = 0;

	        var step = 1;
	        if (labels.length > 40) {
	            // Simple optimization for large amount of labels
	            step = Math.floor(labels.length / 40);
	        }

	        for (var i = 0; i < tickCoords.length; i += step) {
	            var tickCoord = tickCoords[i];
	            var rect = textContain.getBoundingRect(
	                labels[i], font, 'center', 'top'
	            );
	            rect[isAxisHorizontal ? 'x' : 'y'] += tickCoord;
	            // FIXME Magic number 1.5
	            rect[isAxisHorizontal ? 'width' : 'height'] *= 1.3;
	            if (!textSpaceTakenRect) {
	                textSpaceTakenRect = rect.clone();
	            }
	            // There is no space for current label;
	            else if (textSpaceTakenRect.intersect(rect)) {
	                accumulatedLabelInterval++;
	                autoLabelInterval = Math.max(autoLabelInterval, accumulatedLabelInterval);
	            }
	            else {
	                textSpaceTakenRect.union(rect);
	                // Reset
	                accumulatedLabelInterval = 0;
	            }
	        }
	        if (autoLabelInterval === 0 && step > 1) {
	            return step;
	        }
	        return (autoLabelInterval + 1) * step - 1;
	    };

	    /**
	     * @param {Object} axis
	     * @param {Function} labelFormatter
	     * @return {Array.<string>}
	     */
	    axisHelper.getFormattedLabels = function (axis, labelFormatter) {
	        var scale = axis.scale;
	        var labels = scale.getTicksLabels();
	        var ticks = scale.getTicks();
	        if (typeof labelFormatter === 'string') {
	            labelFormatter = (function (tpl) {
	                return function (val) {
	                    return tpl.replace('{value}', val != null ? val : '');
	                };
	            })(labelFormatter);
	            // Consider empty array
	            return zrUtil.map(labels, labelFormatter);
	        }
	        else if (typeof labelFormatter === 'function') {
	            return zrUtil.map(ticks, function (tick, idx) {
	                return labelFormatter(
	                    axisHelper.getAxisRawValue(axis, tick),
	                    idx
	                );
	            }, this);
	        }
	        else {
	            return labels;
	        }
	    };

	    axisHelper.getAxisRawValue = function (axis, value) {
	        // In category axis with data zoom, tick is not the original
	        // index of axis.data. So tick should not be exposed to user
	        // in category axis.
	        return axis.type === 'category' ? axis.scale.getLabel(value) : value;
	    };

	    module.exports = axisHelper;


/***/ },
/* 102 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * Linear continuous scale
	 * @module echarts/coord/scale/Ordinal
	 *
	 * http://en.wikipedia.org/wiki/Level_of_measurement
	 */

	// FIXME only one data


	    var zrUtil = __webpack_require__(4);
	    var Scale = __webpack_require__(103);

	    var scaleProto = Scale.prototype;

	    var OrdinalScale = Scale.extend({

	        type: 'ordinal',

	        init: function (data, extent) {
	            this._data = data;
	            this._extent = extent || [0, data.length - 1];
	        },

	        parse: function (val) {
	            return typeof val === 'string'
	                ? zrUtil.indexOf(this._data, val)
	                // val might be float.
	                : Math.round(val);
	        },

	        contain: function (rank) {
	            rank = this.parse(rank);
	            return scaleProto.contain.call(this, rank)
	                && this._data[rank] != null;
	        },

	        /**
	         * Normalize given rank or name to linear [0, 1]
	         * @param {number|string} [val]
	         * @return {number}
	         */
	        normalize: function (val) {
	            return scaleProto.normalize.call(this, this.parse(val));
	        },

	        scale: function (val) {
	            return Math.round(scaleProto.scale.call(this, val));
	        },

	        /**
	         * @return {Array}
	         */
	        getTicks: function () {
	            var ticks = [];
	            var extent = this._extent;
	            var rank = extent[0];

	            while (rank <= extent[1]) {
	                ticks.push(rank);
	                rank++;
	            }

	            return ticks;
	        },

	        /**
	         * Get item on rank n
	         * @param {number} n
	         * @return {string}
	         */
	        getLabel: function (n) {
	            return this._data[n];
	        },

	        /**
	         * @return {number}
	         */
	        count: function () {
	            return this._extent[1] - this._extent[0] + 1;
	        },

	        /**
	         * @override
	         */
	        unionExtentFromData: function (data, dim) {
	            this.unionExtent(data.getDataExtent(dim, false));
	        },

	        niceTicks: zrUtil.noop,
	        niceExtent: zrUtil.noop
	    });

	    /**
	     * @return {module:echarts/scale/Time}
	     */
	    OrdinalScale.create = function () {
	        return new OrdinalScale();
	    };

	    module.exports = OrdinalScale;


/***/ },
/* 103 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * // Scale class management
	 * @module echarts/scale/Scale
	 */


	    var clazzUtil = __webpack_require__(13);

	    /**
	     * @param {Object} [setting]
	     */
	    function Scale(setting) {
	        this._setting = setting || {};

	        /**
	         * Extent
	         * @type {Array.<number>}
	         * @protected
	         */
	        this._extent = [Infinity, -Infinity];

	        /**
	         * Step is calculated in adjustExtent
	         * @type {Array.<number>}
	         * @protected
	         */
	        this._interval = 0;

	        this.init && this.init.apply(this, arguments);
	    }

	    var scaleProto = Scale.prototype;

	    /**
	     * Parse input val to valid inner number.
	     * @param {*} val
	     * @return {number}
	     */
	    scaleProto.parse = function (val) {
	        // Notice: This would be a trap here, If the implementation
	        // of this method depends on extent, and this method is used
	        // before extent set (like in dataZoom), it would be wrong.
	        // Nevertheless, parse does not depend on extent generally.
	        return val;
	    };

	    scaleProto.getSetting = function (name) {
	        return this._setting[name];
	    };

	    scaleProto.contain = function (val) {
	        var extent = this._extent;
	        return val >= extent[0] && val <= extent[1];
	    };

	    /**
	     * Normalize value to linear [0, 1], return 0.5 if extent span is 0
	     * @param {number} val
	     * @return {number}
	     */
	    scaleProto.normalize = function (val) {
	        var extent = this._extent;
	        if (extent[1] === extent[0]) {
	            return 0.5;
	        }
	        return (val - extent[0]) / (extent[1] - extent[0]);
	    };

	    /**
	     * Scale normalized value
	     * @param {number} val
	     * @return {number}
	     */
	    scaleProto.scale = function (val) {
	        var extent = this._extent;
	        return val * (extent[1] - extent[0]) + extent[0];
	    };

	    /**
	     * Set extent from data
	     * @param {Array.<number>} other
	     */
	    scaleProto.unionExtent = function (other) {
	        var extent = this._extent;
	        other[0] < extent[0] && (extent[0] = other[0]);
	        other[1] > extent[1] && (extent[1] = other[1]);
	        // not setExtent because in log axis it may transformed to power
	        // this.setExtent(extent[0], extent[1]);
	    };

	    /**
	     * Set extent from data
	     * @param {module:echarts/data/List} data
	     * @param {string} dim
	     */
	    scaleProto.unionExtentFromData = function (data, dim) {
	        this.unionExtent(data.getDataExtent(dim, true));
	    };

	    /**
	     * Get extent
	     * @return {Array.<number>}
	     */
	    scaleProto.getExtent = function () {
	        return this._extent.slice();
	    };

	    /**
	     * Set extent
	     * @param {number} start
	     * @param {number} end
	     */
	    scaleProto.setExtent = function (start, end) {
	        var thisExtent = this._extent;
	        if (!isNaN(start)) {
	            thisExtent[0] = start;
	        }
	        if (!isNaN(end)) {
	            thisExtent[1] = end;
	        }
	    };

	    /**
	     * @return {Array.<string>}
	     */
	    scaleProto.getTicksLabels = function () {
	        var labels = [];
	        var ticks = this.getTicks();
	        for (var i = 0; i < ticks.length; i++) {
	            labels.push(this.getLabel(ticks[i]));
	        }
	        return labels;
	    };

	    /**
	     * When axis extent depends on data and no data exists,
	     * axis ticks should not be drawn, which is named 'blank'.
	     */
	    scaleProto.isBlank = function () {
	        return this._isBlank;
	    },

	    /**
	     * When axis extent depends on data and no data exists,
	     * axis ticks should not be drawn, which is named 'blank'.
	     */
	    scaleProto.setBlank = function (isBlank) {
	        this._isBlank = isBlank;
	    };


	    clazzUtil.enableClassExtend(Scale);
	    clazzUtil.enableClassManagement(Scale, {
	        registerWhenExtend: true
	    });

	    module.exports = Scale;


/***/ },
/* 104 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * Interval scale
	 * @module echarts/scale/Interval
	 */



	    var numberUtil = __webpack_require__(7);
	    var formatUtil = __webpack_require__(6);
	    var Scale = __webpack_require__(103);
	    var helper = __webpack_require__(105);

	    var roundNumber = numberUtil.round;

	    /**
	     * @alias module:echarts/coord/scale/Interval
	     * @constructor
	     */
	    var IntervalScale = Scale.extend({

	        type: 'interval',

	        _interval: 0,

	        _intervalPrecision: 2,

	        setExtent: function (start, end) {
	            var thisExtent = this._extent;
	            //start,end may be a Number like '25',so...
	            if (!isNaN(start)) {
	                thisExtent[0] = parseFloat(start);
	            }
	            if (!isNaN(end)) {
	                thisExtent[1] = parseFloat(end);
	            }
	        },

	        unionExtent: function (other) {
	            var extent = this._extent;
	            other[0] < extent[0] && (extent[0] = other[0]);
	            other[1] > extent[1] && (extent[1] = other[1]);

	            // unionExtent may called by it's sub classes
	            IntervalScale.prototype.setExtent.call(this, extent[0], extent[1]);
	        },
	        /**
	         * Get interval
	         */
	        getInterval: function () {
	            return this._interval;
	        },

	        /**
	         * Set interval
	         */
	        setInterval: function (interval) {
	            this._interval = interval;
	            // Dropped auto calculated niceExtent and use user setted extent
	            // We assume user wan't to set both interval, min, max to get a better result
	            this._niceExtent = this._extent.slice();

	            this._intervalPrecision = helper.getIntervalPrecision(interval);
	        },

	        /**
	         * @return {Array.<number>}
	         */
	        getTicks: function () {
	            return helper.intervalScaleGetTicks(
	                this._interval, this._extent, this._niceExtent, this._intervalPrecision
	            );
	        },

	        /**
	         * @return {Array.<string>}
	         */
	        getTicksLabels: function () {
	            var labels = [];
	            var ticks = this.getTicks();
	            for (var i = 0; i < ticks.length; i++) {
	                labels.push(this.getLabel(ticks[i]));
	            }
	            return labels;
	        },

	        /**
	         * @param {number} data
	         * @param {Object} [opt]
	         * @param {number|string} [opt.precision] If 'auto', use nice presision.
	         * @param {boolean} [opt.pad] returns 1.50 but not 1.5 if precision is 2.
	         * @return {string}
	         */
	        getLabel: function (data, opt) {
	            if (data == null) {
	                return '';
	            }

	            var precision = opt && opt.precision;

	            if (precision == null) {
	                precision = numberUtil.getPrecisionSafe(data) || 0;
	            }
	            else if (precision === 'auto') {
	                // Should be more precise then tick.
	                precision = this._intervalPrecision;
	            }

	            // (1) If `precision` is set, 12.005 should be display as '12.00500'.
	            // (2) Use roundNumber (toFixed) to avoid scientific notation like '3.5e-7'.
	            data = roundNumber(data, precision, true);

	            return formatUtil.addCommas(data);
	        },

	        /**
	         * Update interval and extent of intervals for nice ticks
	         *
	         * @param {number} [splitNumber = 5] Desired number of ticks
	         * @param {number} [minInterval]
	         */
	        niceTicks: function (splitNumber, minInterval) {
	            splitNumber = splitNumber || 5;
	            var extent = this._extent;
	            var span = extent[1] - extent[0];
	            if (!isFinite(span)) {
	                return;
	            }
	            // User may set axis min 0 and data are all negative
	            // FIXME If it needs to reverse ?
	            if (span < 0) {
	                span = -span;
	                extent.reverse();
	            }

	            var result = helper.intervalScaleNiceTicks(extent, splitNumber, minInterval);

	            this._intervalPrecision = result.intervalPrecision;
	            this._interval = result.interval;
	            this._niceExtent = result.niceTickExtent;
	        },

	        /**
	         * Nice extent.
	         * @param {Object} opt
	         * @param {number} [opt.splitNumber = 5] Given approx tick number
	         * @param {boolean} [opt.fixMin=false]
	         * @param {boolean} [opt.fixMax=false]
	         * @param {boolean} [opt.minInterval=false]
	         */
	        niceExtent: function (opt) {
	            var extent = this._extent;
	            // If extent start and end are same, expand them
	            if (extent[0] === extent[1]) {
	                if (extent[0] !== 0) {
	                    // Expand extent
	                    var expandSize = extent[0];
	                    // In the fowllowing case
	                    //      Axis has been fixed max 100
	                    //      Plus data are all 100 and axis extent are [100, 100].
	                    // Extend to the both side will cause expanded max is larger than fixed max.
	                    // So only expand to the smaller side.
	                    if (!opt.fixMax) {
	                        extent[1] += expandSize / 2;
	                        extent[0] -= expandSize / 2;
	                    }
	                    else {
	                        extent[0] -= expandSize / 2;
	                    }
	                }
	                else {
	                    extent[1] = 1;
	                }
	            }
	            var span = extent[1] - extent[0];
	            // If there are no data and extent are [Infinity, -Infinity]
	            if (!isFinite(span)) {
	                extent[0] = 0;
	                extent[1] = 1;
	            }

	            this.niceTicks(opt.splitNumber, opt.minInterval);

	            // var extent = this._extent;
	            var interval = this._interval;

	            if (!opt.fixMin) {
	                extent[0] = roundNumber(Math.floor(extent[0] / interval) * interval);
	            }
	            if (!opt.fixMax) {
	                extent[1] = roundNumber(Math.ceil(extent[1] / interval) * interval);
	            }
	        }
	    });

	    /**
	     * @return {module:echarts/scale/Time}
	     */
	    IntervalScale.create = function () {
	        return new IntervalScale();
	    };

	    module.exports = IntervalScale;



/***/ },
/* 105 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * For testable.
	 */


	    var numberUtil = __webpack_require__(7);

	    var roundNumber = numberUtil.round;

	    var helper = {};

	    /**
	     * @param {Array.<number>} extent Both extent[0] and extent[1] should be valid number.
	     *                                Should be extent[0] < extent[1].
	     * @param {number} splitNumber splitNumber should be >= 1.
	     * @param {number} [minInterval]
	     * @return {Object} {interval, intervalPrecision, niceTickExtent}
	     */
	    helper.intervalScaleNiceTicks = function (extent, splitNumber, minInterval) {
	        var result = {};
	        var span = extent[1] - extent[0];

	        var interval = result.interval = numberUtil.nice(span / splitNumber, true);
	        if (minInterval != null && interval < minInterval) {
	            interval = result.interval = minInterval;
	        }
	        // Tow more digital for tick.
	        var precision = result.intervalPrecision = helper.getIntervalPrecision(interval);
	        // Niced extent inside original extent
	        var niceTickExtent = result.niceTickExtent = [
	            roundNumber(Math.ceil(extent[0] / interval) * interval, precision),
	            roundNumber(Math.floor(extent[1] / interval) * interval, precision)
	        ];

	        helper.fixExtent(niceTickExtent, extent);

	        return result;
	    };

	    /**
	     * @param {number} interval
	     * @return {number} interval precision
	     */
	    helper.getIntervalPrecision = function (interval) {
	        // Tow more digital for tick.
	        return numberUtil.getPrecisionSafe(interval) + 2;
	    };

	    function clamp(niceTickExtent, idx, extent) {
	        niceTickExtent[idx] = Math.max(Math.min(niceTickExtent[idx], extent[1]), extent[0]);
	    }

	    // In some cases (e.g., splitNumber is 1), niceTickExtent may be out of extent.
	    helper.fixExtent = function (niceTickExtent, extent) {
	        !isFinite(niceTickExtent[0]) && (niceTickExtent[0] = extent[0]);
	        !isFinite(niceTickExtent[1]) && (niceTickExtent[1] = extent[1]);
	        clamp(niceTickExtent, 0, extent);
	        clamp(niceTickExtent, 1, extent);
	        if (niceTickExtent[0] > niceTickExtent[1]) {
	            niceTickExtent[0] = niceTickExtent[1];
	        }
	    };

	    helper.intervalScaleGetTicks = function (interval, extent, niceTickExtent, intervalPrecision) {
	        var ticks = [];

	        // If interval is 0, return [];
	        if (!interval) {
	            return ticks;
	        }

	        // Consider this case: using dataZoom toolbox, zoom and zoom.
	        var safeLimit = 10000;

	        if (extent[0] < niceTickExtent[0]) {
	            ticks.push(extent[0]);
	        }
	        var tick = niceTickExtent[0];

	        while (tick <= niceTickExtent[1]) {
	            ticks.push(tick);
	            // Avoid rounding error
	            tick = roundNumber(tick + interval, intervalPrecision);
	            if (tick === ticks[ticks.length - 1]) {
	                // Consider out of safe float point, e.g.,
	                // -3711126.9907707 + 2e-10 === -3711126.9907707
	                break;
	            }
	            if (ticks.length > safeLimit) {
	                return [];
	            }
	        }
	        // Consider this case: the last item of ticks is smaller
	        // than niceTickExtent[1] and niceTickExtent[1] === extent[1].
	        if (extent[1] > (ticks.length ? ticks[ticks.length - 1] : niceTickExtent[1])) {
	            ticks.push(extent[1]);
	        }

	        return ticks;
	    };

	    module.exports = helper;


/***/ },
/* 106 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * Interval scale
	 * @module echarts/coord/scale/Time
	 */



	    // [About UTC and local time zone]:
	    // In most cases, `number.parseDate` will treat input data string as local time
	    // (except time zone is specified in time string). And `format.formateTime` returns
	    // local time by default. option.useUTC is false by default. This design have
	    // concidered these common case:
	    // (1) Time that is persistent in server is in UTC, but it is needed to be diplayed
	    // in local time by default.
	    // (2) By default, the input data string (e.g., '2011-01-02') should be displayed
	    // as its original time, without any time difference.

	    var zrUtil = __webpack_require__(4);
	    var numberUtil = __webpack_require__(7);
	    var formatUtil = __webpack_require__(6);
	    var scaleHelper = __webpack_require__(105);

	    var IntervalScale = __webpack_require__(104);

	    var intervalScaleProto = IntervalScale.prototype;

	    var mathCeil = Math.ceil;
	    var mathFloor = Math.floor;
	    var ONE_SECOND = 1000;
	    var ONE_MINUTE = ONE_SECOND * 60;
	    var ONE_HOUR = ONE_MINUTE * 60;
	    var ONE_DAY = ONE_HOUR * 24;

	    // FIXME 公用？
	    var bisect = function (a, x, lo, hi) {
	        while (lo < hi) {
	            var mid = lo + hi >>> 1;
	            if (a[mid][2] < x) {
	                lo = mid + 1;
	            }
	            else {
	                hi  = mid;
	            }
	        }
	        return lo;
	    };

	    /**
	     * @alias module:echarts/coord/scale/Time
	     * @constructor
	     */
	    var TimeScale = IntervalScale.extend({
	        type: 'time',

	        /**
	         * @override
	         */
	        getLabel: function (val) {
	            var stepLvl = this._stepLvl;

	            var date = new Date(val);

	            return formatUtil.formatTime(stepLvl[0], date, this.getSetting('useUTC'));
	        },

	        /**
	         * @override
	         */
	        niceExtent: function (opt) {
	            var extent = this._extent;
	            // If extent start and end are same, expand them
	            if (extent[0] === extent[1]) {
	                // Expand extent
	                extent[0] -= ONE_DAY;
	                extent[1] += ONE_DAY;
	            }
	            // If there are no data and extent are [Infinity, -Infinity]
	            if (extent[1] === -Infinity && extent[0] === Infinity) {
	                var d = new Date();
	                extent[1] = new Date(d.getFullYear(), d.getMonth(), d.getDate());
	                extent[0] = extent[1] - ONE_DAY;
	            }

	            this.niceTicks(opt.splitNumber);

	            // var extent = this._extent;
	            var interval = this._interval;

	            if (!opt.fixMin) {
	                extent[0] = numberUtil.round(mathFloor(extent[0] / interval) * interval);
	            }
	            if (!opt.fixMax) {
	                extent[1] = numberUtil.round(mathCeil(extent[1] / interval) * interval);
	            }
	        },

	        /**
	         * @override
	         */
	        niceTicks: function (approxTickNum) {
	            var timezoneOffset = this.getSetting('useUTC')
	                ? 0 : numberUtil.getTimezoneOffset() * 60 * 1000;
	            approxTickNum = approxTickNum || 10;

	            var extent = this._extent;
	            var span = extent[1] - extent[0];
	            var approxInterval = span / approxTickNum;
	            var scaleLevelsLen = scaleLevels.length;
	            var idx = bisect(scaleLevels, approxInterval, 0, scaleLevelsLen);

	            var level = scaleLevels[Math.min(idx, scaleLevelsLen - 1)];
	            var interval = level[2];
	            // Same with interval scale if span is much larger than 1 year
	            if (level[0] === 'year') {
	                var yearSpan = span / interval;

	                // From "Nice Numbers for Graph Labels" of Graphic Gems
	                // var niceYearSpan = numberUtil.nice(yearSpan, false);
	                var yearStep = numberUtil.nice(yearSpan / approxTickNum, true);

	                interval *= yearStep;
	            }

	            var niceExtent = [
	                Math.round(mathCeil((extent[0] - timezoneOffset) / interval) * interval + timezoneOffset),
	                Math.round(mathFloor((extent[1] - timezoneOffset)/ interval) * interval + timezoneOffset)
	            ];

	            scaleHelper.fixExtent(niceExtent, extent);

	            this._stepLvl = level;
	            // Interval will be used in getTicks
	            this._interval = interval;
	            this._niceExtent = niceExtent;
	        },

	        parse: function (val) {
	            // val might be float.
	            return +numberUtil.parseDate(val);
	        }
	    });

	    zrUtil.each(['contain', 'normalize'], function (methodName) {
	        TimeScale.prototype[methodName] = function (val) {
	            return intervalScaleProto[methodName].call(this, this.parse(val));
	        };
	    });

	    // Steps from d3
	    var scaleLevels = [
	        // Format       step    interval
	        ['hh:mm:ss',    1,      ONE_SECOND],           // 1s
	        ['hh:mm:ss',    5,      ONE_SECOND * 5],       // 5s
	        ['hh:mm:ss',    10,     ONE_SECOND * 10],      // 10s
	        ['hh:mm:ss',    15,     ONE_SECOND * 15],      // 15s
	        ['hh:mm:ss',    30,     ONE_SECOND * 30],      // 30s
	        ['hh:mm\nMM-dd',1,      ONE_MINUTE],          // 1m
	        ['hh:mm\nMM-dd',5,      ONE_MINUTE * 5],      // 5m
	        ['hh:mm\nMM-dd',10,     ONE_MINUTE * 10],     // 10m
	        ['hh:mm\nMM-dd',15,     ONE_MINUTE * 15],     // 15m
	        ['hh:mm\nMM-dd',30,     ONE_MINUTE * 30],     // 30m
	        ['hh:mm\nMM-dd',1,      ONE_HOUR],        // 1h
	        ['hh:mm\nMM-dd',2,      ONE_HOUR * 2],    // 2h
	        ['hh:mm\nMM-dd',6,      ONE_HOUR * 6],    // 6h
	        ['hh:mm\nMM-dd',12,     ONE_HOUR * 12],   // 12h
	        ['MM-dd\nyyyy', 1,      ONE_DAY],   // 1d
	        ['week',        7,      ONE_DAY * 7],        // 7d
	        ['month',       1,      ONE_DAY * 31],       // 1M
	        ['quarter',     3,      ONE_DAY * 380 / 4],  // 3M
	        ['half-year',   6,      ONE_DAY * 380 / 2],  // 6M
	        ['year',        1,      ONE_DAY * 380]       // 1Y
	    ];

	    /**
	     * @param {module:echarts/model/Model}
	     * @return {module:echarts/scale/Time}
	     */
	    TimeScale.create = function (model) {
	        return new TimeScale({useUTC: model.ecModel.get('useUTC')});
	    };

	    module.exports = TimeScale;


/***/ },
/* 107 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * Log scale
	 * @module echarts/scale/Log
	 */


	    var zrUtil = __webpack_require__(4);
	    var Scale = __webpack_require__(103);
	    var numberUtil = __webpack_require__(7);

	    // Use some method of IntervalScale
	    var IntervalScale = __webpack_require__(104);

	    var scaleProto = Scale.prototype;
	    var intervalScaleProto = IntervalScale.prototype;

	    var getPrecisionSafe = numberUtil.getPrecisionSafe;
	    var roundingErrorFix = numberUtil.round;

	    var mathFloor = Math.floor;
	    var mathCeil = Math.ceil;
	    var mathPow = Math.pow;

	    var mathLog = Math.log;

	    var LogScale = Scale.extend({

	        type: 'log',

	        base: 10,

	        $constructor: function () {
	            Scale.apply(this, arguments);
	            this._originalScale = new IntervalScale();
	        },

	        /**
	         * @return {Array.<number>}
	         */
	        getTicks: function () {
	            var originalScale = this._originalScale;
	            var extent = this._extent;
	            var originalExtent = originalScale.getExtent();

	            return zrUtil.map(intervalScaleProto.getTicks.call(this), function (val) {
	                var powVal = numberUtil.round(mathPow(this.base, val));

	                // Fix #4158
	                powVal = (val === extent[0] && originalScale.__fixMin)
	                    ? fixRoundingError(powVal, originalExtent[0])
	                    : powVal;
	                powVal = (val === extent[1] && originalScale.__fixMax)
	                    ? fixRoundingError(powVal, originalExtent[1])
	                    : powVal;

	                return powVal;
	            }, this);
	        },

	        /**
	         * @param {number} val
	         * @return {string}
	         */
	        getLabel: intervalScaleProto.getLabel,

	        /**
	         * @param  {number} val
	         * @return {number}
	         */
	        scale: function (val) {
	            val = scaleProto.scale.call(this, val);
	            return mathPow(this.base, val);
	        },

	        /**
	         * @param {number} start
	         * @param {number} end
	         */
	        setExtent: function (start, end) {
	            var base = this.base;
	            start = mathLog(start) / mathLog(base);
	            end = mathLog(end) / mathLog(base);
	            intervalScaleProto.setExtent.call(this, start, end);
	        },

	        /**
	         * @return {number} end
	         */
	        getExtent: function () {
	            var base = this.base;
	            var extent = scaleProto.getExtent.call(this);
	            extent[0] = mathPow(base, extent[0]);
	            extent[1] = mathPow(base, extent[1]);

	            // Fix #4158
	            var originalScale = this._originalScale;
	            var originalExtent = originalScale.getExtent();
	            originalScale.__fixMin && (extent[0] = fixRoundingError(extent[0], originalExtent[0]));
	            originalScale.__fixMax && (extent[1] = fixRoundingError(extent[1], originalExtent[1]));

	            return extent;
	        },

	        /**
	         * @param  {Array.<number>} extent
	         */
	        unionExtent: function (extent) {
	            this._originalScale.unionExtent(extent);

	            var base = this.base;
	            extent[0] = mathLog(extent[0]) / mathLog(base);
	            extent[1] = mathLog(extent[1]) / mathLog(base);
	            scaleProto.unionExtent.call(this, extent);
	        },

	        /**
	         * @override
	         */
	        unionExtentFromData: function (data, dim) {
	            this.unionExtent(data.getDataExtent(dim, true, function (val) {
	                return val > 0;
	            }));
	        },

	        /**
	         * Update interval and extent of intervals for nice ticks
	         * @param  {number} [approxTickNum = 10] Given approx tick number
	         */
	        niceTicks: function (approxTickNum) {
	            approxTickNum = approxTickNum || 10;
	            var extent = this._extent;
	            var span = extent[1] - extent[0];
	            if (span === Infinity || span <= 0) {
	                return;
	            }

	            var interval = numberUtil.quantity(span);
	            var err = approxTickNum / span * interval;

	            // Filter ticks to get closer to the desired count.
	            if (err <= 0.5) {
	                interval *= 10;
	            }

	            // Interval should be integer
	            while (!isNaN(interval) && Math.abs(interval) < 1 && Math.abs(interval) > 0) {
	                interval *= 10;
	            }

	            var niceExtent = [
	                numberUtil.round(mathCeil(extent[0] / interval) * interval),
	                numberUtil.round(mathFloor(extent[1] / interval) * interval)
	            ];

	            this._interval = interval;
	            this._niceExtent = niceExtent;
	        },

	        /**
	         * Nice extent.
	         * @override
	         */
	        niceExtent: function (opt) {
	            intervalScaleProto.niceExtent.call(this, opt);

	            var originalScale = this._originalScale;
	            originalScale.__fixMin = opt.fixMin;
	            originalScale.__fixMax = opt.fixMax;
	        }

	    });

	    zrUtil.each(['contain', 'normalize'], function (methodName) {
	        LogScale.prototype[methodName] = function (val) {
	            val = mathLog(val) / mathLog(this.base);
	            return scaleProto[methodName].call(this, val);
	        };
	    });

	    LogScale.create = function () {
	        return new LogScale();
	    };

	    function fixRoundingError(val, originalVal) {
	        return roundingErrorFix(val, getPrecisionSafe(originalVal));
	    }

	    module.exports = LogScale;


/***/ },
/* 108 */
/***/ function(module, exports, __webpack_require__) {

	

	    var createListFromArray = __webpack_require__(109);
	    var symbolUtil = __webpack_require__(111);
	    var axisHelper = __webpack_require__(101);
	    var axisModelCommonMixin = __webpack_require__(112);
	    var Model = __webpack_require__(12);
	    var util = __webpack_require__(4);

	    module.exports = {
	        /**
	         * Create a muti dimension List structure from seriesModel.
	         * @param  {module:echarts/model/Model} seriesModel
	         * @return {module:echarts/data/List} list
	         */
	        createList: function (seriesModel) {
	            var data = seriesModel.get('data');
	            return createListFromArray(data, seriesModel, seriesModel.ecModel);
	        },

	        /**
	         * @see {module:echarts/data/helper/completeDimensions}
	         */
	        completeDimensions: __webpack_require__(110),

	        /**
	         * Create a symbol element with given symbol configuration: shape, x, y, width, height, color
	         * @see http://echarts.baidu.com/option.html#series-scatter.symbol
	         * @param {string} symbolDesc
	         * @param {number} x
	         * @param {number} y
	         * @param {number} w
	         * @param {number} h
	         * @param {string} color
	         */
	        createSymbol: symbolUtil.createSymbol,

	        /**
	         * Create scale
	         * @param {Array.<number>} dataExtent
	         * @param {Object|module:echarts/Model} option
	         */
	        createScale: function (dataExtent, option) {
	            var axisModel = option;
	            if (!(option instanceof Model)) {
	                axisModel = new Model(option);
	                util.mixin(axisModel, axisModelCommonMixin);
	            }

	            var scale = axisHelper.createScaleByModel(axisModel);
	            scale.setExtent(dataExtent[0], dataExtent[1]);

	            axisHelper.niceScaleExtent(scale, axisModel);
	            return scale;
	        },

	        /**
	         * Mixin common methods to axis model,
	         *
	         * Inlcude methods
	         * `getFormattedLabels() => Array.<string>`
	         * `getCategories() => Array.<string>`
	         * `getMin(origin: boolean) => number`
	         * `getMax(origin: boolean) => number`
	         * `getNeedCrossZero() => boolean`
	         * `setRange(start: number, end: number)`
	         * `resetRange()`
	         */
	        mixinAxisModelCommonMethods: function (Model) {
	            util.mixin(Model, axisModelCommonMixin);
	        }
	    };


/***/ },
/* 109 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var List = __webpack_require__(98);
	    var completeDimensions = __webpack_require__(110);
	    var zrUtil = __webpack_require__(4);
	    var modelUtil = __webpack_require__(5);
	    var CoordinateSystem = __webpack_require__(76);
	    var getDataItemValue = modelUtil.getDataItemValue;
	    var converDataValue = modelUtil.converDataValue;

	    function firstDataNotNull(data) {
	        var i = 0;
	        while (i < data.length && data[i] == null) {
	            i++;
	        }
	        return data[i];
	    }
	    function ifNeedCompleteOrdinalData(data) {
	        var sampleItem = firstDataNotNull(data);
	        return sampleItem != null
	            && !zrUtil.isArray(getDataItemValue(sampleItem));
	    }

	    /**
	     * Helper function to create a list from option data
	     */
	    function createListFromArray(data, seriesModel, ecModel) {
	        // If data is undefined
	        data = data || [];

	        if (true) {
	            if (!zrUtil.isArray(data)) {
	                throw new Error('Invalid data.');
	            }
	        }

	        var coordSysName = seriesModel.get('coordinateSystem');
	        var creator = creators[coordSysName];
	        var registeredCoordSys = CoordinateSystem.get(coordSysName);
	        var completeDimOpt = {
	            encodeDef: seriesModel.get('encode'),
	            dimsDef: seriesModel.get('dimensions')
	        };

	        // FIXME
	        var axesInfo = creator && creator(data, seriesModel, ecModel, completeDimOpt);
	        var dimensions = axesInfo && axesInfo.dimensions;
	        if (!dimensions) {
	            // Get dimensions from registered coordinate system
	            dimensions = (registeredCoordSys && (
	                registeredCoordSys.getDimensionsInfo
	                    ? registeredCoordSys.getDimensionsInfo()
	                    : registeredCoordSys.dimensions.slice()
	            )) || ['x', 'y'];
	            dimensions = completeDimensions(dimensions, data, completeDimOpt);
	        }

	        var categoryIndex = axesInfo ? axesInfo.categoryIndex : -1;

	        var list = new List(dimensions, seriesModel);

	        var nameList = createNameList(axesInfo, data);

	        var categories = {};
	        var dimValueGetter = (categoryIndex >= 0 && ifNeedCompleteOrdinalData(data))
	            ? function (itemOpt, dimName, dataIndex, dimIndex) {
	                // If any dataItem is like { value: 10 }
	                if (modelUtil.isDataItemOption(itemOpt)) {
	                    list.hasItemOption = true;
	                }

	                // Use dataIndex as ordinal value in categoryAxis
	                return dimIndex === categoryIndex
	                    ? dataIndex
	                    : converDataValue(getDataItemValue(itemOpt), dimensions[dimIndex]);
	            }
	            : function (itemOpt, dimName, dataIndex, dimIndex) {
	                var value = getDataItemValue(itemOpt);
	                var val = converDataValue(value && value[dimIndex], dimensions[dimIndex]);
	                // If any dataItem is like { value: 10 }
	                if (modelUtil.isDataItemOption(itemOpt)) {
	                    list.hasItemOption = true;
	                }

	                var categoryAxesModels = axesInfo && axesInfo.categoryAxesModels;
	                if (categoryAxesModels && categoryAxesModels[dimName]) {
	                    // If given value is a category string
	                    if (typeof val === 'string') {
	                        // Lazy get categories
	                        categories[dimName] = categories[dimName]
	                            || categoryAxesModels[dimName].getCategories();
	                        val = zrUtil.indexOf(categories[dimName], val);
	                        if (val < 0 && !isNaN(val)) {
	                            // In case some one write '1', '2' istead of 1, 2
	                            val = +val;
	                        }
	                    }
	                }
	                return val;
	            };

	        list.hasItemOption = false;
	        list.initData(data, nameList, dimValueGetter);

	        return list;
	    }

	    function isStackable(axisType) {
	        return axisType !== 'category' && axisType !== 'time';
	    }

	    function getDimTypeByAxis(axisType) {
	        return axisType === 'category'
	            ? 'ordinal'
	            : axisType === 'time'
	            ? 'time'
	            : 'float';
	    }

	    /**
	     * Creaters for each coord system.
	     */
	    var creators = {

	        cartesian2d: function (data, seriesModel, ecModel, completeDimOpt) {

	            var axesModels = zrUtil.map(['xAxis', 'yAxis'], function (name) {
	                return ecModel.queryComponents({
	                    mainType: name,
	                    index: seriesModel.get(name + 'Index'),
	                    id: seriesModel.get(name + 'Id')
	                })[0];
	            });
	            var xAxisModel = axesModels[0];
	            var yAxisModel = axesModels[1];

	            if (true) {
	                if (!xAxisModel) {
	                    throw new Error('xAxis "' + zrUtil.retrieve(
	                        seriesModel.get('xAxisIndex'),
	                        seriesModel.get('xAxisId'),
	                        0
	                    ) + '" not found');
	                }
	                if (!yAxisModel) {
	                    throw new Error('yAxis "' + zrUtil.retrieve(
	                        seriesModel.get('xAxisIndex'),
	                        seriesModel.get('yAxisId'),
	                        0
	                    ) + '" not found');
	                }
	            }

	            var xAxisType = xAxisModel.get('type');
	            var yAxisType = yAxisModel.get('type');

	            var dimensions = [
	                {
	                    name: 'x',
	                    type: getDimTypeByAxis(xAxisType),
	                    stackable: isStackable(xAxisType)
	                },
	                {
	                    name: 'y',
	                    // If two category axes
	                    type: getDimTypeByAxis(yAxisType),
	                    stackable: isStackable(yAxisType)
	                }
	            ];

	            var isXAxisCateogry = xAxisType === 'category';
	            var isYAxisCategory = yAxisType === 'category';

	            dimensions = completeDimensions(dimensions, data, completeDimOpt);

	            var categoryAxesModels = {};
	            if (isXAxisCateogry) {
	                categoryAxesModels.x = xAxisModel;
	            }
	            if (isYAxisCategory) {
	                categoryAxesModels.y = yAxisModel;
	            }
	            return {
	                dimensions: dimensions,
	                categoryIndex: isXAxisCateogry ? 0 : (isYAxisCategory ? 1 : -1),
	                categoryAxesModels: categoryAxesModels
	            };
	        },

	        singleAxis: function (data, seriesModel, ecModel, completeDimOpt) {

	            var singleAxisModel = ecModel.queryComponents({
	                mainType: 'singleAxis',
	                index: seriesModel.get('singleAxisIndex'),
	                id: seriesModel.get('singleAxisId')
	            })[0];

	            if (true) {
	                if (!singleAxisModel) {
	                    throw new Error('singleAxis should be specified.');
	                }
	            }

	            var singleAxisType = singleAxisModel.get('type');
	            var isCategory = singleAxisType === 'category';

	            var dimensions = [{
	                name: 'single',
	                type: getDimTypeByAxis(singleAxisType),
	                stackable: isStackable(singleAxisType)
	            }];

	            dimensions = completeDimensions(dimensions, data, completeDimOpt);

	            var categoryAxesModels = {};
	            if (isCategory) {
	                categoryAxesModels.single = singleAxisModel;
	            }

	            return {
	                dimensions: dimensions,
	                categoryIndex: isCategory ? 0 : -1,
	                categoryAxesModels: categoryAxesModels
	            };
	        },

	        polar: function (data, seriesModel, ecModel, completeDimOpt) {
	            var polarModel = ecModel.queryComponents({
	                mainType: 'polar',
	                index: seriesModel.get('polarIndex'),
	                id: seriesModel.get('polarId')
	            })[0];

	            var angleAxisModel = polarModel.findAxisModel('angleAxis');
	            var radiusAxisModel = polarModel.findAxisModel('radiusAxis');

	            if (true) {
	                if (!angleAxisModel) {
	                    throw new Error('angleAxis option not found');
	                }
	                if (!radiusAxisModel) {
	                    throw new Error('radiusAxis option not found');
	                }
	            }

	            var radiusAxisType = radiusAxisModel.get('type');
	            var angleAxisType = angleAxisModel.get('type');

	            var dimensions = [
	                {
	                    name: 'radius',
	                    type: getDimTypeByAxis(radiusAxisType),
	                    stackable: isStackable(radiusAxisType)
	                },
	                {
	                    name: 'angle',
	                    type: getDimTypeByAxis(angleAxisType),
	                    stackable: isStackable(angleAxisType)
	                }
	            ];
	            var isAngleAxisCateogry = angleAxisType === 'category';
	            var isRadiusAxisCateogry = radiusAxisType === 'category';

	            dimensions = completeDimensions(dimensions, data, completeDimOpt);

	            var categoryAxesModels = {};
	            if (isRadiusAxisCateogry) {
	                categoryAxesModels.radius = radiusAxisModel;
	            }
	            if (isAngleAxisCateogry) {
	                categoryAxesModels.angle = angleAxisModel;
	            }
	            return {
	                dimensions: dimensions,
	                categoryIndex: isAngleAxisCateogry ? 1 : (isRadiusAxisCateogry ? 0 : -1),
	                categoryAxesModels: categoryAxesModels
	            };
	        },

	        geo: function (data, seriesModel, ecModel, completeDimOpt) {
	            // TODO Region
	            // 多个散点图系列在同一个地区的时候
	            return {
	                dimensions: completeDimensions([
	                    {name: 'lng'},
	                    {name: 'lat'}
	                ], data, completeDimOpt)
	            };
	        }
	    };

	    function createNameList(result, data) {
	        var nameList = [];

	        var categoryDim = result && result.dimensions[result.categoryIndex];
	        var categoryAxisModel;
	        if (categoryDim) {
	            categoryAxisModel = result.categoryAxesModels[categoryDim.name];
	        }

	        if (categoryAxisModel) {
	            // FIXME Two category axis
	            var categories = categoryAxisModel.getCategories();
	            if (categories) {
	                var dataLen = data.length;
	                // Ordered data is given explicitly like
	                // [[3, 0.2], [1, 0.3], [2, 0.15]]
	                // or given scatter data,
	                // pick the category
	                if (zrUtil.isArray(data[0]) && data[0].length > 1) {
	                    nameList = [];
	                    for (var i = 0; i < dataLen; i++) {
	                        nameList[i] = categories[data[i][result.categoryIndex || 0]];
	                    }
	                }
	                else {
	                    nameList = categories.slice(0);
	                }
	            }
	        }

	        return nameList;
	    }

	    module.exports = createListFromArray;



/***/ },
/* 110 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * Complete dimensions by data (guess dimension).
	 */


	    var zrUtil = __webpack_require__(4);
	    var modelUtil = __webpack_require__(5);
	    var each = zrUtil.each;
	    var isString = zrUtil.isString;
	    var defaults = zrUtil.defaults;
	    var normalizeToArray = modelUtil.normalizeToArray;

	    var OTHER_DIMS = {tooltip: 1, label: 1, itemName: 1};

	    /**
	     * Complete the dimensions array, by user defined `dimension` and `encode`,
	     * and guessing from the data structure.
	     * If no 'value' dimension specified, the first no-named dimension will be
	     * named as 'value'.
	     *
	     * @param {Array.<string>} sysDims Necessary dimensions, like ['x', 'y'], which
	     *      provides not only dim template, but also default order.
	     *      `name` of each item provides default coord name.
	     *      [{dimsDef: []}, ...] can be specified to give names.
	     * @param {Array} data Data list. [[1, 2, 3], [2, 3, 4]].
	     * @param {Object} [opt]
	     * @param {Array.<Object|string>} [opt.dimsDef] option.series.dimensions User defined dimensions
	     *      For example: ['asdf', {name, type}, ...].
	     * @param {Object} [opt.encodeDef] option.series.encode {x: 2, y: [3, 1], tooltip: [1, 2], label: 3}
	     * @param {string} [opt.extraPrefix] Prefix of name when filling the left dimensions.
	     * @param {string} [opt.extraFromZero] If specified, extra dim names will be:
	     *                      extraPrefix + 0, extraPrefix + extraBaseIndex + 1 ...
	     *                      If not specified, extra dim names will be:
	     *                      extraPrefix, extraPrefix + 0, extraPrefix + 1 ...
	     * @param {number} [opt.dimCount] If not specified, guess by the first data item.
	     * @return {Array.<Object>} [{
	     *      name: string mandatory,
	     *      coordDim: string mandatory,
	     *      coordDimIndex: number mandatory,
	     *      type: string optional,
	     *      tooltipName: string optional,
	     *      otherDims: {
	     *          tooltip: number optional,
	     *          label: number optional
	     *      },
	     *      isExtraCoord: boolean true or undefined.
	     *      other props ...
	     * }]
	     */
	    function completeDimensions(sysDims, data, opt) {
	        data = data || [];
	        opt = opt || {};
	        sysDims = (sysDims || []).slice();
	        var dimsDef = (opt.dimsDef || []).slice();
	        var encodeDef = zrUtil.createHashMap(opt.encodeDef);
	        var dataDimNameMap = zrUtil.createHashMap();
	        var coordDimNameMap = zrUtil.createHashMap();
	        // var valueCandidate;
	        var result = [];

	        var dimCount = opt.dimCount;
	        if (dimCount == null) {
	            var value0 = retrieveValue(data[0]);
	            dimCount = Math.max(
	                zrUtil.isArray(value0) && value0.length || 1,
	                sysDims.length,
	                dimsDef.length
	            );
	            each(sysDims, function (sysDimItem) {
	                var sysDimItemDimsDef = sysDimItem.dimsDef;
	                sysDimItemDimsDef && (dimCount = Math.max(dimCount, sysDimItemDimsDef.length));
	            });
	        }

	        // Apply user defined dims (`name` and `type`) and init result.
	        for (var i = 0; i < dimCount; i++) {
	            var dimDefItem = isString(dimsDef[i]) ? {name: dimsDef[i]} : (dimsDef[i] || {});
	            var userDimName = dimDefItem.name;
	            var resultItem = result[i] = {otherDims: {}};
	            // Name will be applied later for avoiding duplication.
	            if (userDimName != null && dataDimNameMap.get(userDimName) == null) {
	                // Only if `series.dimensions` is defined in option, tooltipName
	                // will be set, and dimension will be diplayed vertically in
	                // tooltip by default.
	                resultItem.name = resultItem.tooltipName = userDimName;
	                dataDimNameMap.set(userDimName, i);
	            }
	            dimDefItem.type != null && (resultItem.type = dimDefItem.type);
	        }

	        // Set `coordDim` and `coordDimIndex` by `encodeDef` and normalize `encodeDef`.
	        encodeDef.each(function (dataDims, coordDim) {
	            dataDims = encodeDef.set(coordDim, normalizeToArray(dataDims).slice());
	            each(dataDims, function (resultDimIdx, coordDimIndex) {
	                // The input resultDimIdx can be dim name or index.
	                isString(resultDimIdx) && (resultDimIdx = dataDimNameMap.get(resultDimIdx));
	                if (resultDimIdx != null && resultDimIdx < dimCount) {
	                    dataDims[coordDimIndex] = resultDimIdx;
	                    applyDim(result[resultDimIdx], coordDim, coordDimIndex);
	                }
	            });
	        });

	        // Apply templetes and default order from `sysDims`.
	        var availDimIdx = 0;
	        each(sysDims, function (sysDimItem, sysDimIndex) {
	            var coordDim;
	            var sysDimItem;
	            var sysDimItemDimsDef;
	            var sysDimItemOtherDims;
	            if (isString(sysDimItem)) {
	                coordDim = sysDimItem;
	                sysDimItem = {};
	            }
	            else {
	                coordDim = sysDimItem.name;
	                sysDimItem = zrUtil.clone(sysDimItem);
	                // `coordDimIndex` should not be set directly.
	                sysDimItemDimsDef = sysDimItem.dimsDef;
	                sysDimItemOtherDims = sysDimItem.otherDims;
	                sysDimItem.name = sysDimItem.coordDim = sysDimItem.coordDimIndex
	                    = sysDimItem.dimsDef = sysDimItem.otherDims = null;
	            }

	            var dataDims = normalizeToArray(encodeDef.get(coordDim));
	            // dimensions provides default dim sequences.
	            if (!dataDims.length) {
	                for (var i = 0; i < (sysDimItemDimsDef && sysDimItemDimsDef.length || 1); i++) {
	                    while (availDimIdx < result.length && result[availDimIdx].coordDim != null) {
	                        availDimIdx++;
	                    }
	                    availDimIdx < result.length && dataDims.push(availDimIdx++);
	                }
	            }
	            // Apply templates.
	            each(dataDims, function (resultDimIdx, coordDimIndex) {
	                var resultItem = result[resultDimIdx];
	                applyDim(defaults(resultItem, sysDimItem), coordDim, coordDimIndex);
	                if (resultItem.name == null && sysDimItemDimsDef) {
	                    resultItem.name = resultItem.tooltipName = sysDimItemDimsDef[coordDimIndex];
	                }
	                sysDimItemOtherDims && defaults(resultItem.otherDims, sysDimItemOtherDims);
	            });
	        });

	        // Make sure the first extra dim is 'value'.
	        var extra = opt.extraPrefix || 'value';

	        // Set dim `name` and other `coordDim` and other props.
	        for (var resultDimIdx = 0; resultDimIdx < dimCount; resultDimIdx++) {
	            var resultItem = result[resultDimIdx] = result[resultDimIdx] || {};
	            var coordDim = resultItem.coordDim;

	            coordDim == null && (
	                resultItem.coordDim = genName(extra, coordDimNameMap, opt.extraFromZero),
	                resultItem.coordDimIndex = 0,
	                resultItem.isExtraCoord = true
	            );

	            resultItem.name == null && (resultItem.name = genName(
	                resultItem.coordDim,
	                dataDimNameMap
	            ));

	            resultItem.type == null && guessOrdinal(data, resultDimIdx)
	                && (resultItem.type = 'ordinal');
	        }

	        return result;

	        function applyDim(resultItem, coordDim, coordDimIndex) {
	            if (OTHER_DIMS[coordDim]) {
	                resultItem.otherDims[coordDim] = coordDimIndex;
	            }
	            else {
	                resultItem.coordDim = coordDim;
	                resultItem.coordDimIndex = coordDimIndex;
	                coordDimNameMap.set(coordDim, true);
	            }
	        }

	        function genName(name, map, fromZero) {
	            if (fromZero || map.get(name) != null) {
	                var i = 0;
	                while (map.get(name + i) != null) {
	                    i++;
	                }
	                name += i;
	            }
	            map.set(name, true);
	            return name;
	        }
	    }

	    // The rule should not be complex, otherwise user might not
	    // be able to known where the data is wrong.
	    var guessOrdinal = completeDimensions.guessOrdinal = function (data, dimIndex) {
	        for (var i = 0, len = data.length; i < len; i++) {
	            var value = retrieveValue(data[i]);

	            if (!zrUtil.isArray(value)) {
	                return false;
	            }

	            var value = value[dimIndex];
	            // Consider usage convenience, '1', '2' will be treated as "number".
	            if (value != null && isFinite(value)) {
	                return false;
	            }
	            else if (isString(value) && value !== '-') {
	                return true;
	            }
	        }
	        return false;
	    };

	    function retrieveValue(o) {
	        return zrUtil.isArray(o) ? o : zrUtil.isObject(o) ? o.value: o;
	    }

	    module.exports = completeDimensions;



/***/ },
/* 111 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	// Symbol factory


	    var graphic = __webpack_require__(18);
	    var BoundingRect = __webpack_require__(9);

	    /**
	     * Triangle shape
	     * @inner
	     */
	    var Triangle = graphic.extendShape({
	        type: 'triangle',
	        shape: {
	            cx: 0,
	            cy: 0,
	            width: 0,
	            height: 0
	        },
	        buildPath: function (path, shape) {
	            var cx = shape.cx;
	            var cy = shape.cy;
	            var width = shape.width / 2;
	            var height = shape.height / 2;
	            path.moveTo(cx, cy - height);
	            path.lineTo(cx + width, cy + height);
	            path.lineTo(cx - width, cy + height);
	            path.closePath();
	        }
	    });
	    /**
	     * Diamond shape
	     * @inner
	     */
	    var Diamond = graphic.extendShape({
	        type: 'diamond',
	        shape: {
	            cx: 0,
	            cy: 0,
	            width: 0,
	            height: 0
	        },
	        buildPath: function (path, shape) {
	            var cx = shape.cx;
	            var cy = shape.cy;
	            var width = shape.width / 2;
	            var height = shape.height / 2;
	            path.moveTo(cx, cy - height);
	            path.lineTo(cx + width, cy);
	            path.lineTo(cx, cy + height);
	            path.lineTo(cx - width, cy);
	            path.closePath();
	        }
	    });

	    /**
	     * Pin shape
	     * @inner
	     */
	    var Pin = graphic.extendShape({
	        type: 'pin',
	        shape: {
	            // x, y on the cusp
	            x: 0,
	            y: 0,
	            width: 0,
	            height: 0
	        },

	        buildPath: function (path, shape) {
	            var x = shape.x;
	            var y = shape.y;
	            var w = shape.width / 5 * 3;
	            // Height must be larger than width
	            var h = Math.max(w, shape.height);
	            var r = w / 2;

	            // Dist on y with tangent point and circle center
	            var dy = r * r / (h - r);
	            var cy = y - h + r + dy;
	            var angle = Math.asin(dy / r);
	            // Dist on x with tangent point and circle center
	            var dx = Math.cos(angle) * r;

	            var tanX = Math.sin(angle);
	            var tanY = Math.cos(angle);

	            path.arc(
	                x, cy, r,
	                Math.PI - angle,
	                Math.PI * 2 + angle
	            );

	            var cpLen = r * 0.6;
	            var cpLen2 = r * 0.7;
	            path.bezierCurveTo(
	                x + dx - tanX * cpLen, cy + dy + tanY * cpLen,
	                x, y - cpLen2,
	                x, y
	            );
	            path.bezierCurveTo(
	                x, y - cpLen2,
	                x - dx + tanX * cpLen, cy + dy + tanY * cpLen,
	                x - dx, cy + dy
	            );
	            path.closePath();
	        }
	    });

	    /**
	     * Arrow shape
	     * @inner
	     */
	    var Arrow = graphic.extendShape({

	        type: 'arrow',

	        shape: {
	            x: 0,
	            y: 0,
	            width: 0,
	            height: 0
	        },

	        buildPath: function (ctx, shape) {
	            var height = shape.height;
	            var width = shape.width;
	            var x = shape.x;
	            var y = shape.y;
	            var dx = width / 3 * 2;
	            ctx.moveTo(x, y);
	            ctx.lineTo(x + dx, y + height);
	            ctx.lineTo(x, y + height / 4 * 3);
	            ctx.lineTo(x - dx, y + height);
	            ctx.lineTo(x, y);
	            ctx.closePath();
	        }
	    });

	    /**
	     * Map of path contructors
	     * @type {Object.<string, module:zrender/graphic/Path>}
	     */
	    var symbolCtors = {
	        line: graphic.Line,

	        rect: graphic.Rect,

	        roundRect: graphic.Rect,

	        square: graphic.Rect,

	        circle: graphic.Circle,

	        diamond: Diamond,

	        pin: Pin,

	        arrow: Arrow,

	        triangle: Triangle
	    };

	    var symbolShapeMakers = {

	        line: function (x, y, w, h, shape) {
	            // FIXME
	            shape.x1 = x;
	            shape.y1 = y + h / 2;
	            shape.x2 = x + w;
	            shape.y2 = y + h / 2;
	        },

	        rect: function (x, y, w, h, shape) {
	            shape.x = x;
	            shape.y = y;
	            shape.width = w;
	            shape.height = h;
	        },

	        roundRect: function (x, y, w, h, shape) {
	            shape.x = x;
	            shape.y = y;
	            shape.width = w;
	            shape.height = h;
	            shape.r = Math.min(w, h) / 4;
	        },

	        square: function (x, y, w, h, shape) {
	            var size = Math.min(w, h);
	            shape.x = x;
	            shape.y = y;
	            shape.width = size;
	            shape.height = size;
	        },

	        circle: function (x, y, w, h, shape) {
	            // Put circle in the center of square
	            shape.cx = x + w / 2;
	            shape.cy = y + h / 2;
	            shape.r = Math.min(w, h) / 2;
	        },

	        diamond: function (x, y, w, h, shape) {
	            shape.cx = x + w / 2;
	            shape.cy = y + h / 2;
	            shape.width = w;
	            shape.height = h;
	        },

	        pin: function (x, y, w, h, shape) {
	            shape.x = x + w / 2;
	            shape.y = y + h / 2;
	            shape.width = w;
	            shape.height = h;
	        },

	        arrow: function (x, y, w, h, shape) {
	            shape.x = x + w / 2;
	            shape.y = y + h / 2;
	            shape.width = w;
	            shape.height = h;
	        },

	        triangle: function (x, y, w, h, shape) {
	            shape.cx = x + w / 2;
	            shape.cy = y + h / 2;
	            shape.width = w;
	            shape.height = h;
	        }
	    };

	    var symbolBuildProxies = {};
	    for (var name in symbolCtors) {
	        if (symbolCtors.hasOwnProperty(name)) {
	            symbolBuildProxies[name] = new symbolCtors[name]();
	        }
	    }

	    var Symbol = graphic.extendShape({

	        type: 'symbol',

	        shape: {
	            symbolType: '',
	            x: 0,
	            y: 0,
	            width: 0,
	            height: 0
	        },

	        beforeBrush: function () {
	            var style = this.style;
	            var shape = this.shape;
	            // FIXME
	            if (shape.symbolType === 'pin' && style.textPosition === 'inside') {
	                style.textPosition = ['50%', '40%'];
	                style.textAlign = 'center';
	                style.textVerticalAlign = 'middle';
	            }
	        },

	        buildPath: function (ctx, shape, inBundle) {
	            var symbolType = shape.symbolType;
	            var proxySymbol = symbolBuildProxies[symbolType];
	            if (shape.symbolType !== 'none') {
	                if (!proxySymbol) {
	                    // Default rect
	                    symbolType = 'rect';
	                    proxySymbol = symbolBuildProxies[symbolType];
	                }
	                symbolShapeMakers[symbolType](
	                    shape.x, shape.y, shape.width, shape.height, proxySymbol.shape
	                );
	                proxySymbol.buildPath(ctx, proxySymbol.shape, inBundle);
	            }
	        }
	    });

	    // Provide setColor helper method to avoid determine if set the fill or stroke outside
	    var symbolPathSetColor = function (color) {
	        if (this.type !== 'image') {
	            var symbolStyle = this.style;
	            var symbolShape = this.shape;
	            if (symbolShape && symbolShape.symbolType === 'line') {
	                symbolStyle.stroke = color;
	            }
	            else if (this.__isEmptyBrush) {
	                symbolStyle.stroke = color;
	                symbolStyle.fill = '#fff';
	            }
	            else {
	                // FIXME 判断图形默认是填充还是描边，使用 onlyStroke ?
	                symbolStyle.fill && (symbolStyle.fill = color);
	                symbolStyle.stroke && (symbolStyle.stroke = color);
	            }
	            this.dirty(false);
	        }
	    };

	    var symbolUtil = {
	        /**
	         * Create a symbol element with given symbol configuration: shape, x, y, width, height, color
	         * @param {string} symbolType
	         * @param {number} x
	         * @param {number} y
	         * @param {number} w
	         * @param {number} h
	         * @param {string} color
	         */
	        createSymbol: function (symbolType, x, y, w, h, color) {
	            // TODO Support image object, DynamicImage.

	            var isEmpty = symbolType.indexOf('empty') === 0;
	            if (isEmpty) {
	                symbolType = symbolType.substr(5, 1).toLowerCase() + symbolType.substr(6);
	            }
	            var symbolPath;

	            if (symbolType.indexOf('image://') === 0) {
	                symbolPath = new graphic.Image({
	                    style: {
	                        image: symbolType.slice(8),
	                        x: x,
	                        y: y,
	                        width: w,
	                        height: h
	                    }
	                });
	            }
	            else if (symbolType.indexOf('path://') === 0) {
	                symbolPath = graphic.makePath(symbolType.slice(7), {}, new BoundingRect(x, y, w, h));
	            }
	            else {
	                symbolPath = new Symbol({
	                    shape: {
	                        symbolType: symbolType,
	                        x: x,
	                        y: y,
	                        width: w,
	                        height: h
	                    }
	                });
	            }

	            symbolPath.__isEmptyBrush = isEmpty;

	            symbolPath.setColor = symbolPathSetColor;

	            symbolPath.setColor(color);

	            return symbolPath;
	        }
	    };

	    module.exports = symbolUtil;


/***/ },
/* 112 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);
	    var axisHelper = __webpack_require__(101);

	    function getName(obj) {
	        if (zrUtil.isObject(obj) && obj.value != null) {
	            return obj.value;
	        }
	        else {
	            return obj + '';
	        }
	    }

	    module.exports = {

	        /**
	         * Format labels
	         * @return {Array.<string>}
	         */
	        getFormattedLabels: function () {
	            return axisHelper.getFormattedLabels(
	                this.axis,
	                this.get('axisLabel.formatter')
	            );
	        },

	        /**
	         * Get categories
	         */
	        getCategories: function () {
	            return this.get('type') === 'category'
	                && zrUtil.map(this.get('data'), getName);
	        },

	        /**
	         * @param {boolean} origin
	         * @return {number|string} min value or 'dataMin' or null/undefined (means auto) or NaN
	         */
	        getMin: function (origin) {
	            var option = this.option;
	            var min = (!origin && option.rangeStart != null)
	                ? option.rangeStart : option.min;

	            if (this.axis && min != null && min !== 'dataMin' && !zrUtil.eqNaN(min)) {
	                min = this.axis.scale.parse(min);
	            }
	            return min;
	        },

	        /**
	         * @param {boolean} origin
	         * @return {number|string} max value or 'dataMax' or null/undefined (means auto) or NaN
	         */
	        getMax: function (origin) {
	            var option = this.option;
	            var max = (!origin && option.rangeEnd != null)
	                ? option.rangeEnd : option.max;

	            if (this.axis && max != null && max !== 'dataMax' && !zrUtil.eqNaN(max)) {
	                max = this.axis.scale.parse(max);
	            }
	            return max;
	        },

	        /**
	         * @return {boolean}
	         */
	        getNeedCrossZero: function () {
	            var option = this.option;
	            return (option.rangeStart != null || option.rangeEnd != null)
	                ? false : !option.scale;
	        },

	        /**
	         * Should be implemented by each axis model if necessary.
	         * @return {module:echarts/model/Component} coordinate system model
	         */
	        getCoordSysModel: zrUtil.noop,

	        /**
	         * @param {number} rangeStart Can only be finite number or null/undefined or NaN.
	         * @param {number} rangeEnd Can only be finite number or null/undefined or NaN.
	         */
	        setRange: function (rangeStart, rangeEnd) {
	            this.option.rangeStart = rangeStart;
	            this.option.rangeEnd = rangeEnd;
	        },

	        /**
	         * Reset range
	         */
	        resetRange: function () {
	            // rangeStart and rangeEnd is readonly.
	            this.option.rangeStart = this.option.rangeEnd = null;
	        }
	    };


/***/ },
/* 113 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);
	    var echarts = __webpack_require__(1);
	    var PRIORITY = echarts.PRIORITY;

	    __webpack_require__(114);
	    __webpack_require__(115);

	    echarts.registerVisual(zrUtil.curry(
	        __webpack_require__(121), 'line', 'circle', 'line'
	    ));
	    echarts.registerLayout(zrUtil.curry(
	        __webpack_require__(122), 'line'
	    ));

	    // Down sample after filter
	    echarts.registerProcessor(PRIORITY.PROCESSOR.STATISTIC, zrUtil.curry(
	        __webpack_require__(123), 'line'
	    ));

	    // In case developer forget to include grid component
	    __webpack_require__(124);


/***/ },
/* 114 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var createListFromArray = __webpack_require__(109);
	    var SeriesModel = __webpack_require__(78);

	    module.exports = SeriesModel.extend({

	        type: 'series.line',

	        dependencies: ['grid', 'polar'],

	        getInitialData: function (option, ecModel) {
	            if (true) {
	                var coordSys = option.coordinateSystem;
	                if (coordSys !== 'polar' && coordSys !== 'cartesian2d') {
	                    throw new Error('Line not support coordinateSystem besides cartesian and polar');
	                }
	            }
	            return createListFromArray(option.data, this, ecModel);
	        },

	        defaultOption: {
	            zlevel: 0,                  // 一级层叠
	            z: 2,                       // 二级层叠
	            coordinateSystem: 'cartesian2d',
	            legendHoverLink: true,

	            hoverAnimation: true,
	            // stack: null
	            // xAxisIndex: 0,
	            // yAxisIndex: 0,

	            // polarIndex: 0,

	            // If clip the overflow value
	            clipOverflow: true,
	            // cursor: null,

	            label: {
	                normal: {
	                    position: 'top'
	                }
	            },
	            // itemStyle: {
	            //     normal: {},
	            //     emphasis: {}
	            // },
	            lineStyle: {
	                normal: {
	                    width: 2,
	                    type: 'solid'
	                }
	            },
	            // areaStyle: {},
	            // false, 'start', 'end', 'middle'
	            step: false,

	            // Disabled if step is true
	            smooth: false,
	            smoothMonotone: null,
	            // 拐点图形类型
	            symbol: 'emptyCircle',
	            // 拐点图形大小
	            symbolSize: 4,
	            // 拐点图形旋转控制
	            symbolRotate: null,

	            // 是否显示 symbol, 只有在 tooltip hover 的时候显示
	            showSymbol: true,
	            // 标志图形默认只有主轴显示（随主轴标签间隔隐藏策略）
	            showAllSymbol: false,

	            // 是否连接断点
	            connectNulls: false,

	            // 数据过滤，'average', 'max', 'min', 'sum'
	            sampling: 'none',

	            animationEasing: 'linear',

	            // Disable progressive
	            progressive: 0,
	            hoverLayerThreshold: Infinity
	        }
	    });


/***/ },
/* 115 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	// FIXME step not support polar


	    var zrUtil = __webpack_require__(4);
	    var SymbolDraw = __webpack_require__(116);
	    var Symbol = __webpack_require__(117);
	    var lineAnimationDiff = __webpack_require__(119);
	    var graphic = __webpack_require__(18);
	    var modelUtil = __webpack_require__(5);
	    var polyHelper = __webpack_require__(120);
	    var ChartView = __webpack_require__(80);

	    function isPointsSame(points1, points2) {
	        if (points1.length !== points2.length) {
	            return;
	        }
	        for (var i = 0; i < points1.length; i++) {
	            var p1 = points1[i];
	            var p2 = points2[i];
	            if (p1[0] !== p2[0] || p1[1] !== p2[1]) {
	                return;
	            }
	        }
	        return true;
	    }

	    function getSmooth(smooth) {
	        return typeof (smooth) === 'number' ? smooth : (smooth ? 0.3 : 0);
	    }

	    function getAxisExtentWithGap(axis) {
	        var extent = axis.getGlobalExtent();
	        if (axis.onBand) {
	            // Remove extra 1px to avoid line miter in clipped edge
	            var halfBandWidth = axis.getBandWidth() / 2 - 1;
	            var dir = extent[1] > extent[0] ? 1 : -1;
	            extent[0] += dir * halfBandWidth;
	            extent[1] -= dir * halfBandWidth;
	        }
	        return extent;
	    }

	    function sign(val) {
	        return val >= 0 ? 1 : -1;
	    }
	    /**
	     * @param {module:echarts/coord/cartesian/Cartesian2D|module:echarts/coord/polar/Polar} coordSys
	     * @param {module:echarts/data/List} data
	     * @param {Array.<Array.<number>>} points
	     * @private
	     */
	    function getStackedOnPoints(coordSys, data) {
	        var baseAxis = coordSys.getBaseAxis();
	        var valueAxis = coordSys.getOtherAxis(baseAxis);
	        var valueStart = baseAxis.onZero
	            ? 0 : valueAxis.scale.getExtent()[0];

	        var valueDim = valueAxis.dim;

	        var baseDataOffset = valueDim === 'x' || valueDim === 'radius' ? 1 : 0;

	        return data.mapArray([valueDim], function (val, idx) {
	            var stackedOnSameSign;
	            var stackedOn = data.stackedOn;
	            // Find first stacked value with same sign
	            while (stackedOn &&
	                sign(stackedOn.get(valueDim, idx)) === sign(val)
	            ) {
	                stackedOnSameSign = stackedOn;
	                break;
	            }
	            var stackedData = [];
	            stackedData[baseDataOffset] = data.get(baseAxis.dim, idx);
	            stackedData[1 - baseDataOffset] = stackedOnSameSign
	                ? stackedOnSameSign.get(valueDim, idx, true) : valueStart;

	            return coordSys.dataToPoint(stackedData);
	        }, true);
	    }

	    function createGridClipShape(cartesian, hasAnimation, seriesModel) {
	        var xExtent = getAxisExtentWithGap(cartesian.getAxis('x'));
	        var yExtent = getAxisExtentWithGap(cartesian.getAxis('y'));
	        var isHorizontal = cartesian.getBaseAxis().isHorizontal();

	        var x = Math.min(xExtent[0], xExtent[1]);
	        var y = Math.min(yExtent[0], yExtent[1]);
	        var width = Math.max(xExtent[0], xExtent[1]) - x;
	        var height = Math.max(yExtent[0], yExtent[1]) - y;
	        var lineWidth = seriesModel.get('lineStyle.normal.width') || 2;
	        // Expand clip shape to avoid clipping when line value exceeds axis
	        var expandSize = seriesModel.get('clipOverflow') ? lineWidth / 2 : Math.max(width, height);
	        if (isHorizontal) {
	            y -= expandSize;
	            height += expandSize * 2;
	        }
	        else {
	            x -= expandSize;
	            width += expandSize * 2;
	        }

	        var clipPath = new graphic.Rect({
	            shape: {
	                x: x,
	                y: y,
	                width: width,
	                height: height
	            }
	        });

	        if (hasAnimation) {
	            clipPath.shape[isHorizontal ? 'width' : 'height'] = 0;
	            graphic.initProps(clipPath, {
	                shape: {
	                    width: width,
	                    height: height
	                }
	            }, seriesModel);
	        }

	        return clipPath;
	    }

	    function createPolarClipShape(polar, hasAnimation, seriesModel) {
	        var angleAxis = polar.getAngleAxis();
	        var radiusAxis = polar.getRadiusAxis();

	        var radiusExtent = radiusAxis.getExtent();
	        var angleExtent = angleAxis.getExtent();

	        var RADIAN = Math.PI / 180;

	        var clipPath = new graphic.Sector({
	            shape: {
	                cx: polar.cx,
	                cy: polar.cy,
	                r0: radiusExtent[0],
	                r: radiusExtent[1],
	                startAngle: -angleExtent[0] * RADIAN,
	                endAngle: -angleExtent[1] * RADIAN,
	                clockwise: angleAxis.inverse
	            }
	        });

	        if (hasAnimation) {
	            clipPath.shape.endAngle = -angleExtent[0] * RADIAN;
	            graphic.initProps(clipPath, {
	                shape: {
	                    endAngle: -angleExtent[1] * RADIAN
	                }
	            }, seriesModel);
	        }

	        return clipPath;
	    }

	    function createClipShape(coordSys, hasAnimation, seriesModel) {
	        return coordSys.type === 'polar'
	            ? createPolarClipShape(coordSys, hasAnimation, seriesModel)
	            : createGridClipShape(coordSys, hasAnimation, seriesModel);
	    }

	    function turnPointsIntoStep(points, coordSys, stepTurnAt) {
	        var baseAxis = coordSys.getBaseAxis();
	        var baseIndex = baseAxis.dim === 'x' || baseAxis.dim === 'radius' ? 0 : 1;

	        var stepPoints = [];
	        for (var i = 0; i < points.length - 1; i++) {
	            var nextPt = points[i + 1];
	            var pt = points[i];
	            stepPoints.push(pt);

	            var stepPt = [];
	            switch (stepTurnAt) {
	                case 'end':
	                    stepPt[baseIndex] = nextPt[baseIndex];
	                    stepPt[1 - baseIndex] = pt[1 - baseIndex];
	                    // default is start
	                    stepPoints.push(stepPt);
	                    break;
	                case 'middle':
	                    // default is start
	                    var middle = (pt[baseIndex] + nextPt[baseIndex]) / 2;
	                    var stepPt2 = [];
	                    stepPt[baseIndex] = stepPt2[baseIndex] = middle;
	                    stepPt[1 - baseIndex] = pt[1 - baseIndex];
	                    stepPt2[1 - baseIndex] = nextPt[1 - baseIndex];
	                    stepPoints.push(stepPt);
	                    stepPoints.push(stepPt2);
	                    break;
	                default:
	                    stepPt[baseIndex] = pt[baseIndex];
	                    stepPt[1 - baseIndex] = nextPt[1 - baseIndex];
	                    // default is start
	                    stepPoints.push(stepPt);
	            }
	        }
	        // Last points
	        points[i] && stepPoints.push(points[i]);
	        return stepPoints;
	    }

	    function getVisualGradient(data, coordSys) {
	        var visualMetaList = data.getVisual('visualMeta');
	        if (!visualMetaList || !visualMetaList.length || !data.count()) {
	            // When data.count() is 0, gradient range can not be calculated.
	            return;
	        }

	        var visualMeta;
	        for (var i = visualMetaList.length - 1; i >= 0; i--) {
	            // Can only be x or y
	            if (visualMetaList[i].dimension < 2) {
	                visualMeta = visualMetaList[i];
	                break;
	            }
	        }
	        if (!visualMeta || coordSys.type !== 'cartesian2d') {
	            if (true) {
	                console.warn('Visual map on line style only support x or y dimension.');
	            }
	            return;
	        }

	        // If the area to be rendered is bigger than area defined by LinearGradient,
	        // the canvas spec prescribes that the color of the first stop and the last
	        // stop should be used. But if two stops are added at offset 0, in effect
	        // browsers use the color of the second stop to render area outside
	        // LinearGradient. So we can only infinitesimally extend area defined in
	        // LinearGradient to render `outerColors`.

	        var dimension = visualMeta.dimension;
	        var dimName = data.dimensions[dimension];
	        var axis = coordSys.getAxis(dimName);

	        // dataToCoor mapping may not be linear, but must be monotonic.
	        var colorStops = zrUtil.map(visualMeta.stops, function (stop) {
	            return {
	                coord: axis.toGlobalCoord(axis.dataToCoord(stop.value)),
	                color: stop.color
	            };
	        });
	        var stopLen = colorStops.length;
	        var outerColors = visualMeta.outerColors.slice();

	        if (stopLen && colorStops[0].coord > colorStops[stopLen - 1].coord) {
	            colorStops.reverse();
	            outerColors.reverse();
	        }

	        var tinyExtent = 10; // Arbitrary value: 10px
	        var minCoord = colorStops[0].coord - tinyExtent;
	        var maxCoord = colorStops[stopLen - 1].coord + tinyExtent;
	        var coordSpan = maxCoord - minCoord;

	        if (coordSpan < 1e-3) {
	            return 'transparent';
	        }

	        zrUtil.each(colorStops, function (stop) {
	            stop.offset = (stop.coord - minCoord) / coordSpan;
	        });
	        colorStops.push({
	            offset: stopLen ? colorStops[stopLen - 1].offset : 0.5,
	            color: outerColors[1] || 'transparent'
	        });
	        colorStops.unshift({ // notice colorStops.length have been changed.
	            offset: stopLen ? colorStops[0].offset : 0.5,
	            color: outerColors[0] || 'transparent'
	        });

	        // zrUtil.each(colorStops, function (colorStop) {
	        //     // Make sure each offset has rounded px to avoid not sharp edge
	        //     colorStop.offset = (Math.round(colorStop.offset * (end - start) + start) - start) / (end - start);
	        // });

	        var gradient = new graphic.LinearGradient(0, 0, 0, 0, colorStops, true);
	        gradient[dimName] = minCoord;
	        gradient[dimName + '2'] = maxCoord;

	        return gradient;
	    }

	    module.exports = ChartView.extend({

	        type: 'line',

	        init: function () {
	            var lineGroup = new graphic.Group();

	            var symbolDraw = new SymbolDraw();
	            this.group.add(symbolDraw.group);

	            this._symbolDraw = symbolDraw;
	            this._lineGroup = lineGroup;
	        },

	        render: function (seriesModel, ecModel, api) {
	            var coordSys = seriesModel.coordinateSystem;
	            var group = this.group;
	            var data = seriesModel.getData();
	            var lineStyleModel = seriesModel.getModel('lineStyle.normal');
	            var areaStyleModel = seriesModel.getModel('areaStyle.normal');

	            var points = data.mapArray(data.getItemLayout, true);

	            var isCoordSysPolar = coordSys.type === 'polar';
	            var prevCoordSys = this._coordSys;

	            var symbolDraw = this._symbolDraw;
	            var polyline = this._polyline;
	            var polygon = this._polygon;

	            var lineGroup = this._lineGroup;

	            var hasAnimation = seriesModel.get('animation');

	            var isAreaChart = !areaStyleModel.isEmpty();
	            var stackedOnPoints = getStackedOnPoints(coordSys, data);

	            var showSymbol = seriesModel.get('showSymbol');

	            var isSymbolIgnore = showSymbol && !isCoordSysPolar && !seriesModel.get('showAllSymbol')
	                && this._getSymbolIgnoreFunc(data, coordSys);

	            // Remove temporary symbols
	            var oldData = this._data;
	            oldData && oldData.eachItemGraphicEl(function (el, idx) {
	                if (el.__temp) {
	                    group.remove(el);
	                    oldData.setItemGraphicEl(idx, null);
	                }
	            });

	            // Remove previous created symbols if showSymbol changed to false
	            if (!showSymbol) {
	                symbolDraw.remove();
	            }

	            group.add(lineGroup);

	            // FIXME step not support polar
	            var step = !isCoordSysPolar && seriesModel.get('step');
	            // Initialization animation or coordinate system changed
	            if (
	                !(polyline && prevCoordSys.type === coordSys.type && step === this._step)
	            ) {
	                showSymbol && symbolDraw.updateData(data, isSymbolIgnore);

	                if (step) {
	                    // TODO If stacked series is not step
	                    points = turnPointsIntoStep(points, coordSys, step);
	                    stackedOnPoints = turnPointsIntoStep(stackedOnPoints, coordSys, step);
	                }

	                polyline = this._newPolyline(points, coordSys, hasAnimation);
	                if (isAreaChart) {
	                    polygon = this._newPolygon(
	                        points, stackedOnPoints,
	                        coordSys, hasAnimation
	                    );
	                }
	                lineGroup.setClipPath(createClipShape(coordSys, true, seriesModel));
	            }
	            else {
	                if (isAreaChart && !polygon) {
	                    // If areaStyle is added
	                    polygon = this._newPolygon(
	                        points, stackedOnPoints,
	                        coordSys, hasAnimation
	                    );
	                }
	                else if (polygon && !isAreaChart) {
	                    // If areaStyle is removed
	                    lineGroup.remove(polygon);
	                    polygon = this._polygon = null;
	                }

	                // Update clipPath
	                lineGroup.setClipPath(createClipShape(coordSys, false, seriesModel));

	                // Always update, or it is wrong in the case turning on legend
	                // because points are not changed
	                showSymbol && symbolDraw.updateData(data, isSymbolIgnore);

	                // Stop symbol animation and sync with line points
	                // FIXME performance?
	                data.eachItemGraphicEl(function (el) {
	                    el.stopAnimation(true);
	                });

	                // In the case data zoom triggerred refreshing frequently
	                // Data may not change if line has a category axis. So it should animate nothing
	                if (!isPointsSame(this._stackedOnPoints, stackedOnPoints)
	                    || !isPointsSame(this._points, points)
	                ) {
	                    if (hasAnimation) {
	                        this._updateAnimation(
	                            data, stackedOnPoints, coordSys, api, step
	                        );
	                    }
	                    else {
	                        // Not do it in update with animation
	                        if (step) {
	                            // TODO If stacked series is not step
	                            points = turnPointsIntoStep(points, coordSys, step);
	                            stackedOnPoints = turnPointsIntoStep(stackedOnPoints, coordSys, step);
	                        }

	                        polyline.setShape({
	                            points: points
	                        });
	                        polygon && polygon.setShape({
	                            points: points,
	                            stackedOnPoints: stackedOnPoints
	                        });
	                    }
	                }
	            }

	            var visualColor = getVisualGradient(data, coordSys) || data.getVisual('color');

	            polyline.useStyle(zrUtil.defaults(
	                // Use color in lineStyle first
	                lineStyleModel.getLineStyle(),
	                {
	                    fill: 'none',
	                    stroke: visualColor,
	                    lineJoin: 'bevel'
	                }
	            ));

	            var smooth = seriesModel.get('smooth');
	            smooth = getSmooth(seriesModel.get('smooth'));
	            polyline.setShape({
	                smooth: smooth,
	                smoothMonotone: seriesModel.get('smoothMonotone'),
	                connectNulls: seriesModel.get('connectNulls')
	            });

	            if (polygon) {
	                var stackedOn = data.stackedOn;
	                var stackedOnSmooth = 0;

	                polygon.useStyle(zrUtil.defaults(
	                    areaStyleModel.getAreaStyle(),
	                    {
	                        fill: visualColor,
	                        opacity: 0.7,
	                        lineJoin: 'bevel'
	                    }
	                ));

	                if (stackedOn) {
	                    var stackedOnSeries = stackedOn.hostModel;
	                    stackedOnSmooth = getSmooth(stackedOnSeries.get('smooth'));
	                }

	                polygon.setShape({
	                    smooth: smooth,
	                    stackedOnSmooth: stackedOnSmooth,
	                    smoothMonotone: seriesModel.get('smoothMonotone'),
	                    connectNulls: seriesModel.get('connectNulls')
	                });
	            }

	            this._data = data;
	            // Save the coordinate system for transition animation when data changed
	            this._coordSys = coordSys;
	            this._stackedOnPoints = stackedOnPoints;
	            this._points = points;
	            this._step = step;
	        },

	        dispose: function () {},

	        highlight: function (seriesModel, ecModel, api, payload) {
	            var data = seriesModel.getData();
	            var dataIndex = modelUtil.queryDataIndex(data, payload);

	            if (!(dataIndex instanceof Array) && dataIndex != null && dataIndex >= 0) {
	                var symbol = data.getItemGraphicEl(dataIndex);
	                if (!symbol) {
	                    // Create a temporary symbol if it is not exists
	                    var pt = data.getItemLayout(dataIndex);
	                    if (!pt) {
	                        // Null data
	                        return;
	                    }
	                    symbol = new Symbol(data, dataIndex);
	                    symbol.position = pt;
	                    symbol.setZ(
	                        seriesModel.get('zlevel'),
	                        seriesModel.get('z')
	                    );
	                    symbol.ignore = isNaN(pt[0]) || isNaN(pt[1]);
	                    symbol.__temp = true;
	                    data.setItemGraphicEl(dataIndex, symbol);

	                    // Stop scale animation
	                    symbol.stopSymbolAnimation(true);

	                    this.group.add(symbol);
	                }
	                symbol.highlight();
	            }
	            else {
	                // Highlight whole series
	                ChartView.prototype.highlight.call(
	                    this, seriesModel, ecModel, api, payload
	                );
	            }
	        },

	        downplay: function (seriesModel, ecModel, api, payload) {
	            var data = seriesModel.getData();
	            var dataIndex = modelUtil.queryDataIndex(data, payload);
	            if (dataIndex != null && dataIndex >= 0) {
	                var symbol = data.getItemGraphicEl(dataIndex);
	                if (symbol) {
	                    if (symbol.__temp) {
	                        data.setItemGraphicEl(dataIndex, null);
	                        this.group.remove(symbol);
	                    }
	                    else {
	                        symbol.downplay();
	                    }
	                }
	            }
	            else {
	                // FIXME
	                // can not downplay completely.
	                // Downplay whole series
	                ChartView.prototype.downplay.call(
	                    this, seriesModel, ecModel, api, payload
	                );
	            }
	        },

	        /**
	         * @param {module:zrender/container/Group} group
	         * @param {Array.<Array.<number>>} points
	         * @private
	         */
	        _newPolyline: function (points) {
	            var polyline = this._polyline;
	            // Remove previous created polyline
	            if (polyline) {
	                this._lineGroup.remove(polyline);
	            }

	            polyline = new polyHelper.Polyline({
	                shape: {
	                    points: points
	                },
	                silent: true,
	                z2: 10
	            });

	            this._lineGroup.add(polyline);

	            this._polyline = polyline;

	            return polyline;
	        },

	        /**
	         * @param {module:zrender/container/Group} group
	         * @param {Array.<Array.<number>>} stackedOnPoints
	         * @param {Array.<Array.<number>>} points
	         * @private
	         */
	        _newPolygon: function (points, stackedOnPoints) {
	            var polygon = this._polygon;
	            // Remove previous created polygon
	            if (polygon) {
	                this._lineGroup.remove(polygon);
	            }

	            polygon = new polyHelper.Polygon({
	                shape: {
	                    points: points,
	                    stackedOnPoints: stackedOnPoints
	                },
	                silent: true
	            });

	            this._lineGroup.add(polygon);

	            this._polygon = polygon;
	            return polygon;
	        },
	        /**
	         * @private
	         */
	        _getSymbolIgnoreFunc: function (data, coordSys) {
	            var categoryAxis = coordSys.getAxesByScale('ordinal')[0];
	            // `getLabelInterval` is provided by echarts/component/axis
	            if (categoryAxis && categoryAxis.isLabelIgnored) {
	                return zrUtil.bind(categoryAxis.isLabelIgnored, categoryAxis);
	            }
	        },

	        /**
	         * @private
	         */
	        // FIXME Two value axis
	        _updateAnimation: function (data, stackedOnPoints, coordSys, api, step) {
	            var polyline = this._polyline;
	            var polygon = this._polygon;
	            var seriesModel = data.hostModel;

	            var diff = lineAnimationDiff(
	                this._data, data,
	                this._stackedOnPoints, stackedOnPoints,
	                this._coordSys, coordSys
	            );

	            var current = diff.current;
	            var stackedOnCurrent = diff.stackedOnCurrent;
	            var next = diff.next;
	            var stackedOnNext = diff.stackedOnNext;
	            if (step) {
	                // TODO If stacked series is not step
	                current = turnPointsIntoStep(diff.current, coordSys, step);
	                stackedOnCurrent = turnPointsIntoStep(diff.stackedOnCurrent, coordSys, step);
	                next = turnPointsIntoStep(diff.next, coordSys, step);
	                stackedOnNext = turnPointsIntoStep(diff.stackedOnNext, coordSys, step);
	            }
	            // `diff.current` is subset of `current` (which should be ensured by
	            // turnPointsIntoStep), so points in `__points` can be updated when
	            // points in `current` are update during animation.
	            polyline.shape.__points = diff.current;
	            polyline.shape.points = current;

	            graphic.updateProps(polyline, {
	                shape: {
	                    points: next
	                }
	            }, seriesModel);

	            if (polygon) {
	                polygon.setShape({
	                    points: current,
	                    stackedOnPoints: stackedOnCurrent
	                });
	                graphic.updateProps(polygon, {
	                    shape: {
	                        points: next,
	                        stackedOnPoints: stackedOnNext
	                    }
	                }, seriesModel);
	            }

	            var updatedDataInfo = [];
	            var diffStatus = diff.status;

	            for (var i = 0; i < diffStatus.length; i++) {
	                var cmd = diffStatus[i].cmd;
	                if (cmd === '=') {
	                    var el = data.getItemGraphicEl(diffStatus[i].idx1);
	                    if (el) {
	                        updatedDataInfo.push({
	                            el: el,
	                            ptIdx: i    // Index of points
	                        });
	                    }
	                }
	            }

	            if (polyline.animators && polyline.animators.length) {
	                polyline.animators[0].during(function () {
	                    for (var i = 0; i < updatedDataInfo.length; i++) {
	                        var el = updatedDataInfo[i].el;
	                        el.attr('position', polyline.shape.__points[updatedDataInfo[i].ptIdx]);
	                    }
	                });
	            }
	        },

	        remove: function (ecModel) {
	            var group = this.group;
	            var oldData = this._data;
	            this._lineGroup.removeAll();
	            this._symbolDraw.remove(true);
	            // Remove temporary created elements when highlighting
	            oldData && oldData.eachItemGraphicEl(function (el, idx) {
	                if (el.__temp) {
	                    group.remove(el);
	                    oldData.setItemGraphicEl(idx, null);
	                }
	            });

	            this._polyline =
	            this._polygon =
	            this._coordSys =
	            this._points =
	            this._stackedOnPoints =
	            this._data = null;
	        }
	    });


/***/ },
/* 116 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @module echarts/chart/helper/SymbolDraw
	 */


	    var graphic = __webpack_require__(18);
	    var Symbol = __webpack_require__(117);

	    /**
	     * @constructor
	     * @alias module:echarts/chart/helper/SymbolDraw
	     * @param {module:zrender/graphic/Group} [symbolCtor]
	     */
	    function SymbolDraw(symbolCtor) {
	        this.group = new graphic.Group();

	        this._symbolCtor = symbolCtor || Symbol;
	    }

	    var symbolDrawProto = SymbolDraw.prototype;

	    function symbolNeedsDraw(data, idx, isIgnore) {
	        var point = data.getItemLayout(idx);
	        // Is an object
	        // if (point && point.hasOwnProperty('point')) {
	        //     point = point.point;
	        // }
	        return point && !isNaN(point[0]) && !isNaN(point[1]) && !(isIgnore && isIgnore(idx))
	                    && data.getItemVisual(idx, 'symbol') !== 'none';
	    }
	    /**
	     * Update symbols draw by new data
	     * @param {module:echarts/data/List} data
	     * @param {Array.<boolean>} [isIgnore]
	     */
	    symbolDrawProto.updateData = function (data, isIgnore) {
	        var group = this.group;
	        var seriesModel = data.hostModel;
	        var oldData = this._data;

	        var SymbolCtor = this._symbolCtor;

	        var seriesScope = {
	            itemStyle: seriesModel.getModel('itemStyle.normal').getItemStyle(['color']),
	            hoverItemStyle: seriesModel.getModel('itemStyle.emphasis').getItemStyle(),
	            symbolRotate: seriesModel.get('symbolRotate'),
	            symbolOffset: seriesModel.get('symbolOffset'),
	            hoverAnimation: seriesModel.get('hoverAnimation'),

	            labelModel: seriesModel.getModel('label.normal'),
	            hoverLabelModel: seriesModel.getModel('label.emphasis'),
	            cursorStyle: seriesModel.get('cursor')
	        };

	        data.diff(oldData)
	            .add(function (newIdx) {
	                var point = data.getItemLayout(newIdx);
	                if (symbolNeedsDraw(data, newIdx, isIgnore)) {
	                    var symbolEl = new SymbolCtor(data, newIdx, seriesScope);
	                    symbolEl.attr('position', point);
	                    data.setItemGraphicEl(newIdx, symbolEl);
	                    group.add(symbolEl);
	                }
	            })
	            .update(function (newIdx, oldIdx) {
	                var symbolEl = oldData.getItemGraphicEl(oldIdx);
	                var point = data.getItemLayout(newIdx);
	                if (!symbolNeedsDraw(data, newIdx, isIgnore)) {
	                    group.remove(symbolEl);
	                    return;
	                }
	                if (!symbolEl) {
	                    symbolEl = new SymbolCtor(data, newIdx);
	                    symbolEl.attr('position', point);
	                }
	                else {
	                    symbolEl.updateData(data, newIdx, seriesScope);
	                    graphic.updateProps(symbolEl, {
	                        position: point
	                    }, seriesModel);
	                }

	                // Add back
	                group.add(symbolEl);

	                data.setItemGraphicEl(newIdx, symbolEl);
	            })
	            .remove(function (oldIdx) {
	                var el = oldData.getItemGraphicEl(oldIdx);
	                el && el.fadeOut(function () {
	                    group.remove(el);
	                });
	            })
	            .execute();

	        this._data = data;
	    };

	    symbolDrawProto.updateLayout = function () {
	        var data = this._data;
	        if (data) {
	            // Not use animation
	            data.eachItemGraphicEl(function (el, idx) {
	                var point = data.getItemLayout(idx);
	                el.attr('position', point);
	            });
	        }
	    };

	    symbolDrawProto.remove = function (enableAnimation) {
	        var group = this.group;
	        var data = this._data;
	        if (data) {
	            if (enableAnimation) {
	                data.eachItemGraphicEl(function (el) {
	                    el.fadeOut(function () {
	                        group.remove(el);
	                    });
	                });
	            }
	            else {
	                group.removeAll();
	            }
	        }
	    };

	    module.exports = SymbolDraw;


/***/ },
/* 117 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @module echarts/chart/helper/Symbol
	 */


	    var zrUtil = __webpack_require__(4);
	    var symbolUtil = __webpack_require__(111);
	    var graphic = __webpack_require__(18);
	    var numberUtil = __webpack_require__(7);
	    var labelHelper = __webpack_require__(118);

	    function getSymbolSize(data, idx) {
	        var symbolSize = data.getItemVisual(idx, 'symbolSize');
	        return symbolSize instanceof Array
	            ? symbolSize.slice()
	            : [+symbolSize, +symbolSize];
	    }

	    function getScale(symbolSize) {
	        return [symbolSize[0] / 2, symbolSize[1] / 2];
	    }

	    /**
	     * @constructor
	     * @alias {module:echarts/chart/helper/Symbol}
	     * @param {module:echarts/data/List} data
	     * @param {number} idx
	     * @extends {module:zrender/graphic/Group}
	     */
	    function Symbol(data, idx, seriesScope) {
	        graphic.Group.call(this);

	        this.updateData(data, idx, seriesScope);
	    }

	    var symbolProto = Symbol.prototype;

	    function driftSymbol(dx, dy) {
	        this.parent.drift(dx, dy);
	    }

	    symbolProto._createSymbol = function (symbolType, data, idx, symbolSize) {
	        // Remove paths created before
	        this.removeAll();

	        var seriesModel = data.hostModel;
	        var color = data.getItemVisual(idx, 'color');

	        // var symbolPath = symbolUtil.createSymbol(
	        //     symbolType, -0.5, -0.5, 1, 1, color
	        // );
	        // If width/height are set too small (e.g., set to 1) on ios10
	        // and macOS Sierra, a circle stroke become a rect, no matter what
	        // the scale is set. So we set width/height as 2. See #4150.
	        var symbolPath = symbolUtil.createSymbol(
	            symbolType, -1, -1, 2, 2, color
	        );

	        symbolPath.attr({
	            z2: 100,
	            culling: true,
	            scale: [0, 0]
	        });
	        // Rewrite drift method
	        symbolPath.drift = driftSymbol;

	        graphic.initProps(symbolPath, {
	            scale: getScale(symbolSize)
	        }, seriesModel, idx);
	        this._symbolType = symbolType;

	        this.add(symbolPath);
	    };

	    /**
	     * Stop animation
	     * @param {boolean} toLastFrame
	     */
	    symbolProto.stopSymbolAnimation = function (toLastFrame) {
	        this.childAt(0).stopAnimation(toLastFrame);
	    };

	    /**
	     * Get symbol path element
	     */
	    symbolProto.getSymbolPath = function () {
	        return this.childAt(0);
	    };

	    /**
	     * Get scale(aka, current symbol size).
	     * Including the change caused by animation
	     */
	    symbolProto.getScale = function () {
	        return this.childAt(0).scale;
	    };

	    /**
	     * Highlight symbol
	     */
	    symbolProto.highlight = function () {
	        this.childAt(0).trigger('emphasis');
	    };

	    /**
	     * Downplay symbol
	     */
	    symbolProto.downplay = function () {
	        this.childAt(0).trigger('normal');
	    };

	    /**
	     * @param {number} zlevel
	     * @param {number} z
	     */
	    symbolProto.setZ = function (zlevel, z) {
	        var symbolPath = this.childAt(0);
	        symbolPath.zlevel = zlevel;
	        symbolPath.z = z;
	    };

	    symbolProto.setDraggable = function (draggable) {
	        var symbolPath = this.childAt(0);
	        symbolPath.draggable = draggable;
	        symbolPath.cursor = draggable ? 'move' : 'pointer';
	    };

	    /**
	     * Update symbol properties
	     * @param  {module:echarts/data/List} data
	     * @param  {number} idx
	     */
	    symbolProto.updateData = function (data, idx, seriesScope) {
	        this.silent = false;

	        var symbolType = data.getItemVisual(idx, 'symbol') || 'circle';
	        var seriesModel = data.hostModel;
	        var symbolSize = getSymbolSize(data, idx);

	        if (symbolType !== this._symbolType) {
	            this._createSymbol(symbolType, data, idx, symbolSize);
	        }
	        else {
	            var symbolPath = this.childAt(0);
	            symbolPath.silent = false;
	            graphic.updateProps(symbolPath, {
	                scale: getScale(symbolSize)
	            }, seriesModel, idx);
	        }
	        this._updateCommon(data, idx, symbolSize, seriesScope);
	        this._seriesModel = seriesModel;
	    };

	    // Update common properties
	    var normalStyleAccessPath = ['itemStyle', 'normal'];
	    var emphasisStyleAccessPath = ['itemStyle', 'emphasis'];
	    var normalLabelAccessPath = ['label', 'normal'];
	    var emphasisLabelAccessPath = ['label', 'emphasis'];

	    symbolProto._updateCommon = function (data, idx, symbolSize, seriesScope) {
	        var symbolPath = this.childAt(0);
	        var seriesModel = data.hostModel;
	        var color = data.getItemVisual(idx, 'color');

	        // Reset style
	        if (symbolPath.type !== 'image') {
	            symbolPath.useStyle({
	                strokeNoScale: true
	            });
	        }

	        seriesScope = seriesScope || null;

	        var itemStyle = seriesScope && seriesScope.itemStyle;
	        var hoverItemStyle = seriesScope && seriesScope.hoverItemStyle;
	        var symbolRotate = seriesScope && seriesScope.symbolRotate;
	        var symbolOffset = seriesScope && seriesScope.symbolOffset;
	        var labelModel = seriesScope && seriesScope.labelModel;
	        var hoverLabelModel = seriesScope && seriesScope.hoverLabelModel;
	        var hoverAnimation = seriesScope && seriesScope.hoverAnimation;
	        var cursorStyle = seriesScope && seriesScope.cursorStyle;

	        if (!seriesScope || data.hasItemOption) {
	            var itemModel = data.getItemModel(idx);

	            // Color must be excluded.
	            // Because symbol provide setColor individually to set fill and stroke
	            itemStyle = itemModel.getModel(normalStyleAccessPath).getItemStyle(['color']);
	            hoverItemStyle = itemModel.getModel(emphasisStyleAccessPath).getItemStyle();

	            symbolRotate = itemModel.getShallow('symbolRotate');
	            symbolOffset = itemModel.getShallow('symbolOffset');

	            labelModel = itemModel.getModel(normalLabelAccessPath);
	            hoverLabelModel = itemModel.getModel(emphasisLabelAccessPath);
	            hoverAnimation = itemModel.getShallow('hoverAnimation');
	            cursorStyle = itemModel.getShallow('cursor');
	        }
	        else {
	            hoverItemStyle = zrUtil.extend({}, hoverItemStyle);
	        }

	        var elStyle = symbolPath.style;

	        symbolPath.attr('rotation', (symbolRotate || 0) * Math.PI / 180 || 0);

	        if (symbolOffset) {
	            symbolPath.attr('position', [
	                numberUtil.parsePercent(symbolOffset[0], symbolSize[0]),
	                numberUtil.parsePercent(symbolOffset[1], symbolSize[1])
	            ]);
	        }

	        cursorStyle && symbolPath.attr('cursor', cursorStyle);

	        // PENDING setColor before setStyle!!!
	        symbolPath.setColor(color);

	        symbolPath.setStyle(itemStyle);

	        var opacity = data.getItemVisual(idx, 'opacity');
	        if (opacity != null) {
	            elStyle.opacity = opacity;
	        }

	        var valueDim = labelHelper.findLabelValueDim(data);
	        labelHelper.setTextToStyle(
	            data, idx, valueDim, elStyle, seriesModel, labelModel, color
	        );
	        labelHelper.setTextToStyle(
	            data, idx, valueDim, hoverItemStyle, seriesModel, hoverLabelModel, color
	        );

	        symbolPath.off('mouseover')
	            .off('mouseout')
	            .off('emphasis')
	            .off('normal');

	        symbolPath.hoverStyle = hoverItemStyle;

	        graphic.setHoverStyle(symbolPath);

	        var scale = getScale(symbolSize);

	        if (hoverAnimation && seriesModel.isAnimationEnabled()) {
	            var onEmphasis = function() {
	                var ratio = scale[1] / scale[0];
	                this.animateTo({
	                    scale: [
	                        Math.max(scale[0] * 1.1, scale[0] + 3),
	                        Math.max(scale[1] * 1.1, scale[1] + 3 * ratio)
	                    ]
	                }, 400, 'elasticOut');
	            };
	            var onNormal = function() {
	                this.animateTo({
	                    scale: scale
	                }, 400, 'elasticOut');
	            };
	            symbolPath.on('mouseover', onEmphasis)
	                .on('mouseout', onNormal)
	                .on('emphasis', onEmphasis)
	                .on('normal', onNormal);
	        }
	    };

	    symbolProto.fadeOut = function (cb) {
	        var symbolPath = this.childAt(0);
	        // Avoid mistaken hover when fading out
	        this.silent = symbolPath.silent = true;
	        // Not show text when animating
	        symbolPath.style.text = '';
	        graphic.updateProps(symbolPath, {
	            scale: [0, 0]
	        }, this._seriesModel, this.dataIndex, cb);
	    };

	    zrUtil.inherits(Symbol, graphic.Group);

	    module.exports = Symbol;


/***/ },
/* 118 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @module echarts/chart/helper/Symbol
	 */


	    var graphic = __webpack_require__(18);
	    var zrUtil = __webpack_require__(4);
	    var modelUtil = __webpack_require__(5);

	    var helper = {};

	    helper.findLabelValueDim = function (data) {
	        var valueDim;
	        var labelDims = modelUtil.otherDimToDataDim(data, 'label');

	        if (labelDims.length) {
	            valueDim = labelDims[0];
	        }
	        else {
	            // Get last value dim
	            var dimensions = data.dimensions.slice();
	            var dataType;
	            while (dimensions.length && (
	                valueDim = dimensions.pop(),
	                dataType = data.getDimensionInfo(valueDim).type,
	                dataType === 'ordinal' || dataType === 'time'
	            )) {} // jshint ignore:line
	        }

	        return valueDim;
	    };

	    helper.setTextToStyle = function (
	        data, dataIndex, valueDim, elStyle, seriesModel, labelModel, color
	    ) {
	        if (valueDim != null && labelModel.getShallow('show')) {
	            graphic.setText(elStyle, labelModel, color);
	            elStyle.text = zrUtil.retrieve(
	                seriesModel.getFormattedLabel(dataIndex, 'normal'),
	                data.get(valueDim, dataIndex)
	            );
	        }
	        else {
	            elStyle.text = '';
	        }
	    };

	    module.exports = helper;


/***/ },
/* 119 */
/***/ function(module, exports) {

	

	    // var arrayDiff = require('zrender/lib/core/arrayDiff');
	    // 'zrender/core/arrayDiff' has been used before, but it did
	    // not do well in performance when roam with fixed dataZoom window.

	    function sign(val) {
	        return val >= 0 ? 1 : -1;
	    }

	    function getStackedOnPoint(coordSys, data, idx) {
	        var baseAxis = coordSys.getBaseAxis();
	        var valueAxis = coordSys.getOtherAxis(baseAxis);
	        var valueStart = baseAxis.onZero
	            ? 0 : valueAxis.scale.getExtent()[0];

	        var valueDim = valueAxis.dim;
	        var baseDataOffset = valueDim === 'x' || valueDim === 'radius' ? 1 : 0;

	        var stackedOnSameSign;
	        var stackedOn = data.stackedOn;
	        var val = data.get(valueDim, idx);
	        // Find first stacked value with same sign
	        while (stackedOn &&
	            sign(stackedOn.get(valueDim, idx)) === sign(val)
	        ) {
	            stackedOnSameSign = stackedOn;
	            break;
	        }
	        var stackedData = [];
	        stackedData[baseDataOffset] = data.get(baseAxis.dim, idx);
	        stackedData[1 - baseDataOffset] = stackedOnSameSign
	            ? stackedOnSameSign.get(valueDim, idx, true) : valueStart;

	        return coordSys.dataToPoint(stackedData);
	    }

	    // function convertToIntId(newIdList, oldIdList) {
	    //     // Generate int id instead of string id.
	    //     // Compare string maybe slow in score function of arrDiff

	    //     // Assume id in idList are all unique
	    //     var idIndicesMap = {};
	    //     var idx = 0;
	    //     for (var i = 0; i < newIdList.length; i++) {
	    //         idIndicesMap[newIdList[i]] = idx;
	    //         newIdList[i] = idx++;
	    //     }
	    //     for (var i = 0; i < oldIdList.length; i++) {
	    //         var oldId = oldIdList[i];
	    //         // Same with newIdList
	    //         if (idIndicesMap[oldId]) {
	    //             oldIdList[i] = idIndicesMap[oldId];
	    //         }
	    //         else {
	    //             oldIdList[i] = idx++;
	    //         }
	    //     }
	    // }

	    function diffData(oldData, newData) {
	        var diffResult = [];

	        newData.diff(oldData)
	            .add(function (idx) {
	                diffResult.push({cmd: '+', idx: idx});
	            })
	            .update(function (newIdx, oldIdx) {
	                diffResult.push({cmd: '=', idx: oldIdx, idx1: newIdx});
	            })
	            .remove(function (idx) {
	                diffResult.push({cmd: '-', idx: idx});
	            })
	            .execute();

	        return diffResult;
	    }

	    module.exports = function (
	        oldData, newData,
	        oldStackedOnPoints, newStackedOnPoints,
	        oldCoordSys, newCoordSys
	    ) {
	        var diff = diffData(oldData, newData);

	        // var newIdList = newData.mapArray(newData.getId);
	        // var oldIdList = oldData.mapArray(oldData.getId);

	        // convertToIntId(newIdList, oldIdList);

	        // // FIXME One data ?
	        // diff = arrayDiff(oldIdList, newIdList);

	        var currPoints = [];
	        var nextPoints = [];
	        // Points for stacking base line
	        var currStackedPoints = [];
	        var nextStackedPoints = [];

	        var status = [];
	        var sortedIndices = [];
	        var rawIndices = [];
	        var dims = newCoordSys.dimensions;
	        for (var i = 0; i < diff.length; i++) {
	            var diffItem = diff[i];
	            var pointAdded = true;

	            // FIXME, animation is not so perfect when dataZoom window moves fast
	            // Which is in case remvoing or add more than one data in the tail or head
	            switch (diffItem.cmd) {
	                case '=':
	                    var currentPt = oldData.getItemLayout(diffItem.idx);
	                    var nextPt = newData.getItemLayout(diffItem.idx1);
	                    // If previous data is NaN, use next point directly
	                    if (isNaN(currentPt[0]) || isNaN(currentPt[1])) {
	                        currentPt = nextPt.slice();
	                    }
	                    currPoints.push(currentPt);
	                    nextPoints.push(nextPt);

	                    currStackedPoints.push(oldStackedOnPoints[diffItem.idx]);
	                    nextStackedPoints.push(newStackedOnPoints[diffItem.idx1]);

	                    rawIndices.push(newData.getRawIndex(diffItem.idx1));
	                    break;
	                case '+':
	                    var idx = diffItem.idx;
	                    currPoints.push(
	                        oldCoordSys.dataToPoint([
	                            newData.get(dims[0], idx, true), newData.get(dims[1], idx, true)
	                        ])
	                    );

	                    nextPoints.push(newData.getItemLayout(idx).slice());

	                    currStackedPoints.push(
	                        getStackedOnPoint(oldCoordSys, newData, idx)
	                    );
	                    nextStackedPoints.push(newStackedOnPoints[idx]);

	                    rawIndices.push(newData.getRawIndex(idx));
	                    break;
	                case '-':
	                    var idx = diffItem.idx;
	                    var rawIndex = oldData.getRawIndex(idx);
	                    // Data is replaced. In the case of dynamic data queue
	                    // FIXME FIXME FIXME
	                    if (rawIndex !== idx) {
	                        currPoints.push(oldData.getItemLayout(idx));
	                        nextPoints.push(newCoordSys.dataToPoint([
	                            oldData.get(dims[0], idx, true), oldData.get(dims[1], idx, true)
	                        ]));

	                        currStackedPoints.push(oldStackedOnPoints[idx]);
	                        nextStackedPoints.push(
	                            getStackedOnPoint(
	                                newCoordSys, oldData, idx
	                            )
	                        );

	                        rawIndices.push(rawIndex);
	                    }
	                    else {
	                        pointAdded = false;
	                    }
	            }

	            // Original indices
	            if (pointAdded) {
	                status.push(diffItem);
	                sortedIndices.push(sortedIndices.length);
	            }
	        }

	        // Diff result may be crossed if all items are changed
	        // Sort by data index
	        sortedIndices.sort(function (a, b) {
	            return rawIndices[a] - rawIndices[b];
	        });

	        var sortedCurrPoints = [];
	        var sortedNextPoints = [];

	        var sortedCurrStackedPoints = [];
	        var sortedNextStackedPoints = [];

	        var sortedStatus = [];
	        for (var i = 0; i < sortedIndices.length; i++) {
	            var idx = sortedIndices[i];
	            sortedCurrPoints[i] = currPoints[idx];
	            sortedNextPoints[i] = nextPoints[idx];

	            sortedCurrStackedPoints[i] = currStackedPoints[idx];
	            sortedNextStackedPoints[i] = nextStackedPoints[idx];

	            sortedStatus[i] = status[idx];
	        }

	        return {
	            current: sortedCurrPoints,
	            next: sortedNextPoints,

	            stackedOnCurrent: sortedCurrStackedPoints,
	            stackedOnNext: sortedNextStackedPoints,

	            status: sortedStatus
	        };
	    };


/***/ },
/* 120 */
/***/ function(module, exports, __webpack_require__) {

	// Poly path support NaN point


	    var Path = __webpack_require__(20);
	    var vec2 = __webpack_require__(10);

	    var vec2Min = vec2.min;
	    var vec2Max = vec2.max;

	    var scaleAndAdd = vec2.scaleAndAdd;
	    var v2Copy = vec2.copy;

	    // Temporary variable
	    var v = [];
	    var cp0 = [];
	    var cp1 = [];

	    function isPointNull(p) {
	        return isNaN(p[0]) || isNaN(p[1]);
	    }

	    function drawSegment(
	        ctx, points, start, segLen, allLen,
	        dir, smoothMin, smoothMax, smooth, smoothMonotone, connectNulls
	    ) {
	        var prevIdx = 0;
	        var idx = start;
	        for (var k = 0; k < segLen; k++) {
	            var p = points[idx];
	            if (idx >= allLen || idx < 0) {
	                break;
	            }
	            if (isPointNull(p)) {
	                if (connectNulls) {
	                    idx += dir;
	                    continue;
	                }
	                break;
	            }

	            if (idx === start) {
	                ctx[dir > 0 ? 'moveTo' : 'lineTo'](p[0], p[1]);
	                v2Copy(cp0, p);
	            }
	            else {
	                if (smooth > 0) {
	                    var nextIdx = idx + dir;
	                    var nextP = points[nextIdx];
	                    if (connectNulls) {
	                        // Find next point not null
	                        while (nextP && isPointNull(points[nextIdx])) {
	                            nextIdx += dir;
	                            nextP = points[nextIdx];
	                        }
	                    }

	                    var ratioNextSeg = 0.5;
	                    var prevP = points[prevIdx];
	                    var nextP = points[nextIdx];
	                    // Last point
	                    if (!nextP || isPointNull(nextP)) {
	                        v2Copy(cp1, p);
	                    }
	                    else {
	                        // If next data is null in not connect case
	                        if (isPointNull(nextP) && !connectNulls) {
	                            nextP = p;
	                        }

	                        vec2.sub(v, nextP, prevP);

	                        var lenPrevSeg;
	                        var lenNextSeg;
	                        if (smoothMonotone === 'x' || smoothMonotone === 'y') {
	                            var dim = smoothMonotone === 'x' ? 0 : 1;
	                            lenPrevSeg = Math.abs(p[dim] - prevP[dim]);
	                            lenNextSeg = Math.abs(p[dim] - nextP[dim]);
	                        }
	                        else {
	                            lenPrevSeg = vec2.dist(p, prevP);
	                            lenNextSeg = vec2.dist(p, nextP);
	                        }

	                        // Use ratio of seg length
	                        ratioNextSeg = lenNextSeg / (lenNextSeg + lenPrevSeg);

	                        scaleAndAdd(cp1, p, v, -smooth * (1 - ratioNextSeg));
	                    }
	                    // Smooth constraint
	                    vec2Min(cp0, cp0, smoothMax);
	                    vec2Max(cp0, cp0, smoothMin);
	                    vec2Min(cp1, cp1, smoothMax);
	                    vec2Max(cp1, cp1, smoothMin);

	                    ctx.bezierCurveTo(
	                        cp0[0], cp0[1],
	                        cp1[0], cp1[1],
	                        p[0], p[1]
	                    );
	                    // cp0 of next segment
	                    scaleAndAdd(cp0, p, v, smooth * ratioNextSeg);
	                }
	                else {
	                    ctx.lineTo(p[0], p[1]);
	                }
	            }

	            prevIdx = idx;
	            idx += dir;
	        }

	        return k;
	    }

	    function getBoundingBox(points, smoothConstraint) {
	        var ptMin = [Infinity, Infinity];
	        var ptMax = [-Infinity, -Infinity];
	        if (smoothConstraint) {
	            for (var i = 0; i < points.length; i++) {
	                var pt = points[i];
	                if (pt[0] < ptMin[0]) { ptMin[0] = pt[0]; }
	                if (pt[1] < ptMin[1]) { ptMin[1] = pt[1]; }
	                if (pt[0] > ptMax[0]) { ptMax[0] = pt[0]; }
	                if (pt[1] > ptMax[1]) { ptMax[1] = pt[1]; }
	            }
	        }
	        return {
	            min: smoothConstraint ? ptMin : ptMax,
	            max: smoothConstraint ? ptMax : ptMin
	        };
	    }

	    module.exports = {

	        Polyline: Path.extend({

	            type: 'ec-polyline',

	            shape: {
	                points: [],

	                smooth: 0,

	                smoothConstraint: true,

	                smoothMonotone: null,

	                connectNulls: false
	            },

	            style: {
	                fill: null,

	                stroke: '#000'
	            },

	            buildPath: function (ctx, shape) {
	                var points = shape.points;

	                var i = 0;
	                var len = points.length;

	                var result = getBoundingBox(points, shape.smoothConstraint);

	                if (shape.connectNulls) {
	                    // Must remove first and last null values avoid draw error in polygon
	                    for (; len > 0; len--) {
	                        if (!isPointNull(points[len - 1])) {
	                            break;
	                        }
	                    }
	                    for (; i < len; i++) {
	                        if (!isPointNull(points[i])) {
	                            break;
	                        }
	                    }
	                }
	                while (i < len) {
	                    i += drawSegment(
	                        ctx, points, i, len, len,
	                        1, result.min, result.max, shape.smooth,
	                        shape.smoothMonotone, shape.connectNulls
	                    ) + 1;
	                }
	            }
	        }),

	        Polygon: Path.extend({

	            type: 'ec-polygon',

	            shape: {
	                points: [],

	                // Offset between stacked base points and points
	                stackedOnPoints: [],

	                smooth: 0,

	                stackedOnSmooth: 0,

	                smoothConstraint: true,

	                smoothMonotone: null,

	                connectNulls: false
	            },

	            buildPath: function (ctx, shape) {
	                var points = shape.points;
	                var stackedOnPoints = shape.stackedOnPoints;

	                var i = 0;
	                var len = points.length;
	                var smoothMonotone = shape.smoothMonotone;
	                var bbox = getBoundingBox(points, shape.smoothConstraint);
	                var stackedOnBBox = getBoundingBox(stackedOnPoints, shape.smoothConstraint);

	                if (shape.connectNulls) {
	                    // Must remove first and last null values avoid draw error in polygon
	                    for (; len > 0; len--) {
	                        if (!isPointNull(points[len - 1])) {
	                            break;
	                        }
	                    }
	                    for (; i < len; i++) {
	                        if (!isPointNull(points[i])) {
	                            break;
	                        }
	                    }
	                }
	                while (i < len) {
	                    var k = drawSegment(
	                        ctx, points, i, len, len,
	                        1, bbox.min, bbox.max, shape.smooth,
	                        smoothMonotone, shape.connectNulls
	                    );
	                    drawSegment(
	                        ctx, stackedOnPoints, i + k - 1, k, len,
	                        -1, stackedOnBBox.min, stackedOnBBox.max, shape.stackedOnSmooth,
	                        smoothMonotone, shape.connectNulls
	                    );
	                    i += k + 1;

	                    ctx.closePath();
	                }
	            }
	        })
	    };


/***/ },
/* 121 */
/***/ function(module, exports) {

	

	    module.exports = function (seriesType, defaultSymbolType, legendSymbol, ecModel, api) {

	        // Encoding visual for all series include which is filtered for legend drawing
	        ecModel.eachRawSeriesByType(seriesType, function (seriesModel) {
	            var data = seriesModel.getData();

	            var symbolType = seriesModel.get('symbol') || defaultSymbolType;
	            var symbolSize = seriesModel.get('symbolSize');

	            data.setVisual({
	                legendSymbol: legendSymbol || symbolType,
	                symbol: symbolType,
	                symbolSize: symbolSize
	            });

	            // Only visible series has each data be visual encoded
	            if (!ecModel.isSeriesFiltered(seriesModel)) {
	                if (typeof symbolSize === 'function') {
	                    data.each(function (idx) {
	                        var rawValue = seriesModel.getRawValue(idx);
	                        // FIXME
	                        var params = seriesModel.getDataParams(idx);
	                        data.setItemVisual(idx, 'symbolSize', symbolSize(rawValue, params));
	                    });
	                }
	                data.each(function (idx) {
	                    var itemModel = data.getItemModel(idx);
	                    var itemSymbolType = itemModel.getShallow('symbol', true);
	                    var itemSymbolSize = itemModel.getShallow('symbolSize', true);
	                    // If has item symbol
	                    if (itemSymbolType != null) {
	                        data.setItemVisual(idx, 'symbol', itemSymbolType);
	                    }
	                    if (itemSymbolSize != null) {
	                        // PENDING Transform symbolSize ?
	                        data.setItemVisual(idx, 'symbolSize', itemSymbolSize);
	                    }
	                });
	            }
	        });
	    };


/***/ },
/* 122 */
/***/ function(module, exports) {

	

	    module.exports = function (seriesType, ecModel) {
	        ecModel.eachSeriesByType(seriesType, function (seriesModel) {
	            var data = seriesModel.getData();
	            var coordSys = seriesModel.coordinateSystem;

	            if (!coordSys) {
	                return;
	            }

	            var dims = [];
	            var coordDims = coordSys.dimensions;
	            for (var i = 0; i < coordDims.length; i++) {
	                dims.push(seriesModel.coordDimToDataDim(coordSys.dimensions[i])[0]);
	            }

	            if (dims.length === 1) {
	                data.each(dims[0], function (x, idx) {
	                    // Also {Array.<number>}, not undefined to avoid if...else... statement
	                    data.setItemLayout(idx, isNaN(x) ? [NaN, NaN] : coordSys.dataToPoint(x));
	                });
	            }
	            else if (dims.length === 2) {
	                data.each(dims, function (x, y, idx) {
	                    // Also {Array.<number>}, not undefined to avoid if...else... statement
	                    data.setItemLayout(
	                        idx, (isNaN(x) || isNaN(y)) ? [NaN, NaN] : coordSys.dataToPoint([x, y])
	                    );
	                }, true);
	            }
	        });
	    };



/***/ },
/* 123 */
/***/ function(module, exports) {

	
	    var samplers = {
	        average: function (frame) {
	            var sum = 0;
	            var count = 0;
	            for (var i = 0; i < frame.length; i++) {
	                if (!isNaN(frame[i])) {
	                    sum += frame[i];
	                    count++;
	                }
	            }
	            // Return NaN if count is 0
	            return count === 0 ? NaN : sum / count;
	        },
	        sum: function (frame) {
	            var sum = 0;
	            for (var i = 0; i < frame.length; i++) {
	                // Ignore NaN
	                sum += frame[i] || 0;
	            }
	            return sum;
	        },
	        max: function (frame) {
	            var max = -Infinity;
	            for (var i = 0; i < frame.length; i++) {
	                frame[i] > max && (max = frame[i]);
	            }
	            return max;
	        },
	        min: function (frame) {
	            var min = Infinity;
	            for (var i = 0; i < frame.length; i++) {
	                frame[i] < min && (min = frame[i]);
	            }
	            return min;
	        },
	        // TODO
	        // Median
	        nearest: function (frame) {
	            return frame[0];
	        }
	    };

	    var indexSampler = function (frame, value) {
	        return Math.round(frame.length / 2);
	    };
	    module.exports = function (seriesType, ecModel, api) {
	        ecModel.eachSeriesByType(seriesType, function (seriesModel) {
	            var data = seriesModel.getData();
	            var sampling = seriesModel.get('sampling');
	            var coordSys = seriesModel.coordinateSystem;
	            // Only cartesian2d support down sampling
	            if (coordSys.type === 'cartesian2d' && sampling) {
	                var baseAxis = coordSys.getBaseAxis();
	                var valueAxis = coordSys.getOtherAxis(baseAxis);
	                var extent = baseAxis.getExtent();
	                // Coordinste system has been resized
	                var size = extent[1] - extent[0];
	                var rate = Math.round(data.count() / size);
	                if (rate > 1) {
	                    var sampler;
	                    if (typeof sampling === 'string') {
	                        sampler = samplers[sampling];
	                    }
	                    else if (typeof sampling === 'function') {
	                        sampler = sampling;
	                    }
	                    if (sampler) {
	                        data = data.downSample(
	                            valueAxis.dim, 1 / rate, sampler, indexSampler
	                        );
	                        seriesModel.setData(data);
	                    }
	                }
	            }
	        }, this);
	    };


/***/ },
/* 124 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var graphic = __webpack_require__(18);
	    var zrUtil = __webpack_require__(4);
	    var echarts = __webpack_require__(1);

	    __webpack_require__(125);

	    __webpack_require__(133);

	    // Grid view
	    echarts.extendComponentView({

	        type: 'grid',

	        render: function (gridModel, ecModel) {
	            this.group.removeAll();
	            if (gridModel.get('show')) {
	                this.group.add(new graphic.Rect({
	                    shape: gridModel.coordinateSystem.getRect(),
	                    style: zrUtil.defaults({
	                        fill: gridModel.get('backgroundColor')
	                    }, gridModel.getItemStyle()),
	                    silent: true,
	                    z2: -1
	                }));
	            }
	        }

	    });

	    echarts.registerPreprocessor(function (option) {
	        // Only create grid when need
	        if (option.xAxis && option.yAxis && !option.grid) {
	            option.grid = {};
	        }
	    });


/***/ },
/* 125 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * Grid is a region which contains at most 4 cartesian systems
	 *
	 * TODO Default cartesian
	 */
	var factory = exports;

	    var layout = __webpack_require__(71);
	    var axisHelper = __webpack_require__(101);

	    var zrUtil = __webpack_require__(4);
	    var Cartesian2D = __webpack_require__(126);
	    var Axis2D = __webpack_require__(128);

	    var each = zrUtil.each;

	    var ifAxisCrossZero = axisHelper.ifAxisCrossZero;
	    var niceScaleExtent = axisHelper.niceScaleExtent;

	    // 依赖 GridModel, AxisModel 做预处理
	    __webpack_require__(129);

	    /**
	     * Check if the axis is used in the specified grid
	     * @inner
	     */
	    function isAxisUsedInTheGrid(axisModel, gridModel, ecModel) {
	        return axisModel.getCoordSysModel() === gridModel;
	    }

	    function getLabelUnionRect(axis) {
	        var axisModel = axis.model;
	        var labels = axisModel.getFormattedLabels();
	        var textStyleModel = axisModel.getModel('axisLabel.textStyle');
	        var rect;
	        var step = 1;
	        var labelCount = labels.length;
	        if (labelCount > 40) {
	            // Simple optimization for large amount of labels
	            step = Math.ceil(labelCount / 40);
	        }
	        for (var i = 0; i < labelCount; i += step) {
	            if (!axis.isLabelIgnored(i)) {
	                var singleRect = textStyleModel.getTextRect(labels[i]);
	                // FIXME consider label rotate
	                rect ? rect.union(singleRect) : (rect = singleRect);
	            }
	        }
	        return rect;
	    }

	    function Grid(gridModel, ecModel, api) {
	        /**
	         * @type {Object.<string, module:echarts/coord/cartesian/Cartesian2D>}
	         * @private
	         */
	        this._coordsMap = {};

	        /**
	         * @type {Array.<module:echarts/coord/cartesian/Cartesian>}
	         * @private
	         */
	        this._coordsList = [];

	        /**
	         * @type {Object.<string, module:echarts/coord/cartesian/Axis2D>}
	         * @private
	         */
	        this._axesMap = {};

	        /**
	         * @type {Array.<module:echarts/coord/cartesian/Axis2D>}
	         * @private
	         */
	        this._axesList = [];

	        this._initCartesian(gridModel, ecModel, api);

	        this.model = gridModel;
	    }

	    var gridProto = Grid.prototype;

	    gridProto.type = 'grid';

	    gridProto.axisPointerEnabled = true;

	    gridProto.getRect = function () {
	        return this._rect;
	    };

	    gridProto.update = function (ecModel, api) {

	        var axesMap = this._axesMap;

	        this._updateScale(ecModel, this.model);

	        function ifAxisCanNotOnZero(otherAxisDim) {
	            var axes = axesMap[otherAxisDim];
	            for (var idx in axes) {
	                if (axes.hasOwnProperty(idx)) {
	                    var axis = axes[idx];
	                    if (axis && (
	                        axis.type === 'category' || axis.type === 'time' || !ifAxisCrossZero(axis)
	                    )) {
	                        return true;
	                    }
	                }
	            }
	            return false;
	        }

	        each(axesMap.x, function (xAxis) {
	            niceScaleExtent(xAxis.scale, xAxis.model);
	        });
	        each(axesMap.y, function (yAxis) {
	            niceScaleExtent(yAxis.scale, yAxis.model);
	        });
	        // Fix configuration
	        each(axesMap.x, function (xAxis) {
	            // onZero can not be enabled in these two situations
	            // 1. When any other axis is a category axis
	            // 2. When any other axis not across 0 point
	            if (ifAxisCanNotOnZero('y')) {
	                xAxis.onZero = false;
	            }
	        });
	        each(axesMap.y, function (yAxis) {
	            if (ifAxisCanNotOnZero('x')) {
	                yAxis.onZero = false;
	            }
	        });

	        // Resize again if containLabel is enabled
	        // FIXME It may cause getting wrong grid size in data processing stage
	        this.resize(this.model, api);
	    };

	    /**
	     * Resize the grid
	     * @param {module:echarts/coord/cartesian/GridModel} gridModel
	     * @param {module:echarts/ExtensionAPI} api
	     */
	    gridProto.resize = function (gridModel, api, ignoreContainLabel) {

	        var gridRect = layout.getLayoutRect(
	            gridModel.getBoxLayoutParams(), {
	                width: api.getWidth(),
	                height: api.getHeight()
	            });

	        this._rect = gridRect;

	        var axesList = this._axesList;

	        adjustAxes();

	        // Minus label size
	        if (!ignoreContainLabel && gridModel.get('containLabel')) {
	            each(axesList, function (axis) {
	                if (!axis.model.get('axisLabel.inside')) {
	                    var labelUnionRect = getLabelUnionRect(axis);
	                    if (labelUnionRect) {
	                        var dim = axis.isHorizontal() ? 'height' : 'width';
	                        var margin = axis.model.get('axisLabel.margin');
	                        gridRect[dim] -= labelUnionRect[dim] + margin;
	                        if (axis.position === 'top') {
	                            gridRect.y += labelUnionRect.height + margin;
	                        }
	                        else if (axis.position === 'left')  {
	                            gridRect.x += labelUnionRect.width + margin;
	                        }
	                    }
	                }
	            });

	            adjustAxes();
	        }

	        function adjustAxes() {
	            each(axesList, function (axis) {
	                var isHorizontal = axis.isHorizontal();
	                var extent = isHorizontal ? [0, gridRect.width] : [0, gridRect.height];
	                var idx = axis.inverse ? 1 : 0;
	                axis.setExtent(extent[idx], extent[1 - idx]);
	                updateAxisTransfrom(axis, isHorizontal ? gridRect.x : gridRect.y);
	            });
	        }
	    };

	    /**
	     * @param {string} axisType
	     * @param {ndumber} [axisIndex]
	     */
	    gridProto.getAxis = function (axisType, axisIndex) {
	        var axesMapOnDim = this._axesMap[axisType];
	        if (axesMapOnDim != null) {
	            if (axisIndex == null) {
	                // Find first axis
	                for (var name in axesMapOnDim) {
	                    if (axesMapOnDim.hasOwnProperty(name)) {
	                        return axesMapOnDim[name];
	                    }
	                }
	            }
	            return axesMapOnDim[axisIndex];
	        }
	    };

	    /**
	     * @return {Array.<module:echarts/coord/Axis>}
	     */
	    gridProto.getAxes = function () {
	        return this._axesList.slice();
	    };

	    /**
	     * Usage:
	     *      grid.getCartesian(xAxisIndex, yAxisIndex);
	     *      grid.getCartesian(xAxisIndex);
	     *      grid.getCartesian(null, yAxisIndex);
	     *      grid.getCartesian({xAxisIndex: ..., yAxisIndex: ...});
	     *
	     * @param {number|Object} [xAxisIndex]
	     * @param {number} [yAxisIndex]
	     */
	    gridProto.getCartesian = function (xAxisIndex, yAxisIndex) {
	        if (xAxisIndex != null && yAxisIndex != null) {
	            var key = 'x' + xAxisIndex + 'y' + yAxisIndex;
	            return this._coordsMap[key];
	        }

	        if (zrUtil.isObject(xAxisIndex)) {
	            yAxisIndex = xAxisIndex.yAxisIndex;
	            xAxisIndex = xAxisIndex.xAxisIndex;
	        }
	        // When only xAxisIndex or yAxisIndex given, find its first cartesian.
	        for (var i = 0, coordList = this._coordsList; i < coordList.length; i++) {
	            if (coordList[i].getAxis('x').index === xAxisIndex
	                || coordList[i].getAxis('y').index === yAxisIndex
	            ) {
	                return coordList[i];
	            }
	        }
	    };

	    gridProto.getCartesians = function () {
	        return this._coordsList.slice();
	    };

	    /**
	     * @implements
	     * see {module:echarts/CoodinateSystem}
	     */
	    gridProto.convertToPixel = function (ecModel, finder, value) {
	        var target = this._findConvertTarget(ecModel, finder);

	        return target.cartesian
	            ? target.cartesian.dataToPoint(value)
	            : target.axis
	            ? target.axis.toGlobalCoord(target.axis.dataToCoord(value))
	            : null;
	    };

	    /**
	     * @implements
	     * see {module:echarts/CoodinateSystem}
	     */
	    gridProto.convertFromPixel = function (ecModel, finder, value) {
	        var target = this._findConvertTarget(ecModel, finder);

	        return target.cartesian
	            ? target.cartesian.pointToData(value)
	            : target.axis
	            ? target.axis.coordToData(target.axis.toLocalCoord(value))
	            : null;
	    };

	    /**
	     * @inner
	     */
	    gridProto._findConvertTarget = function (ecModel, finder) {
	        var seriesModel = finder.seriesModel;
	        var xAxisModel = finder.xAxisModel
	            || (seriesModel && seriesModel.getReferringComponents('xAxis')[0]);
	        var yAxisModel = finder.yAxisModel
	            || (seriesModel && seriesModel.getReferringComponents('yAxis')[0]);
	        var gridModel = finder.gridModel;
	        var coordsList = this._coordsList;
	        var cartesian;
	        var axis;

	        if (seriesModel) {
	            cartesian = seriesModel.coordinateSystem;
	            zrUtil.indexOf(coordsList, cartesian) < 0 && (cartesian = null);
	        }
	        else if (xAxisModel && yAxisModel) {
	            cartesian = this.getCartesian(xAxisModel.componentIndex, yAxisModel.componentIndex);
	        }
	        else if (xAxisModel) {
	            axis = this.getAxis('x', xAxisModel.componentIndex);
	        }
	        else if (yAxisModel) {
	            axis = this.getAxis('y', yAxisModel.componentIndex);
	        }
	        // Lowest priority.
	        else if (gridModel) {
	            var grid = gridModel.coordinateSystem;
	            if (grid === this) {
	                cartesian = this._coordsList[0];
	            }
	        }

	        return {cartesian: cartesian, axis: axis};
	    };

	    /**
	     * @implements
	     * see {module:echarts/CoodinateSystem}
	     */
	    gridProto.containPoint = function (point) {
	        var coord = this._coordsList[0];
	        if (coord) {
	            return coord.containPoint(point);
	        }
	    };

	    /**
	     * Initialize cartesian coordinate systems
	     * @private
	     */
	    gridProto._initCartesian = function (gridModel, ecModel, api) {
	        var axisPositionUsed = {
	            left: false,
	            right: false,
	            top: false,
	            bottom: false
	        };

	        var axesMap = {
	            x: {},
	            y: {}
	        };
	        var axesCount = {
	            x: 0,
	            y: 0
	        };

	        /// Create axis
	        ecModel.eachComponent('xAxis', createAxisCreator('x'), this);
	        ecModel.eachComponent('yAxis', createAxisCreator('y'), this);

	        if (!axesCount.x || !axesCount.y) {
	            // Roll back when there no either x or y axis
	            this._axesMap = {};
	            this._axesList = [];
	            return;
	        }

	        this._axesMap = axesMap;

	        /// Create cartesian2d
	        each(axesMap.x, function (xAxis, xAxisIndex) {
	            each(axesMap.y, function (yAxis, yAxisIndex) {
	                var key = 'x' + xAxisIndex + 'y' + yAxisIndex;
	                var cartesian = new Cartesian2D(key);

	                cartesian.grid = this;
	                cartesian.model = gridModel;

	                this._coordsMap[key] = cartesian;
	                this._coordsList.push(cartesian);

	                cartesian.addAxis(xAxis);
	                cartesian.addAxis(yAxis);
	            }, this);
	        }, this);

	        function createAxisCreator(axisType) {
	            return function (axisModel, idx) {
	                if (!isAxisUsedInTheGrid(axisModel, gridModel, ecModel)) {
	                    return;
	                }

	                var axisPosition = axisModel.get('position');
	                if (axisType === 'x') {
	                    // Fix position
	                    if (axisPosition !== 'top' && axisPosition !== 'bottom') {
	                        // Default bottom of X
	                        axisPosition = 'bottom';
	                        if (axisPositionUsed[axisPosition]) {
	                            axisPosition = axisPosition === 'top' ? 'bottom' : 'top';
	                        }
	                    }
	                }
	                else {
	                    // Fix position
	                    if (axisPosition !== 'left' && axisPosition !== 'right') {
	                        // Default left of Y
	                        axisPosition = 'left';
	                        if (axisPositionUsed[axisPosition]) {
	                            axisPosition = axisPosition === 'left' ? 'right' : 'left';
	                        }
	                    }
	                }
	                axisPositionUsed[axisPosition] = true;

	                var axis = new Axis2D(
	                    axisType, axisHelper.createScaleByModel(axisModel),
	                    [0, 0],
	                    axisModel.get('type'),
	                    axisPosition
	                );

	                var isCategory = axis.type === 'category';
	                axis.onBand = isCategory && axisModel.get('boundaryGap');
	                axis.inverse = axisModel.get('inverse');

	                axis.onZero = axisModel.get('axisLine.onZero');

	                // Inject axis into axisModel
	                axisModel.axis = axis;

	                // Inject axisModel into axis
	                axis.model = axisModel;

	                // Inject grid info axis
	                axis.grid = this;

	                // Index of axis, can be used as key
	                axis.index = idx;

	                this._axesList.push(axis);

	                axesMap[axisType][idx] = axis;
	                axesCount[axisType]++;
	            };
	        }
	    };

	    /**
	     * Update cartesian properties from series
	     * @param  {module:echarts/model/Option} option
	     * @private
	     */
	    gridProto._updateScale = function (ecModel, gridModel) {
	        // Reset scale
	        zrUtil.each(this._axesList, function (axis) {
	            axis.scale.setExtent(Infinity, -Infinity);
	        });
	        ecModel.eachSeries(function (seriesModel) {
	            if (isCartesian2D(seriesModel)) {
	                var axesModels = findAxesModels(seriesModel, ecModel);
	                var xAxisModel = axesModels[0];
	                var yAxisModel = axesModels[1];

	                if (!isAxisUsedInTheGrid(xAxisModel, gridModel, ecModel)
	                    || !isAxisUsedInTheGrid(yAxisModel, gridModel, ecModel)
	                 ) {
	                    return;
	                }

	                var cartesian = this.getCartesian(
	                    xAxisModel.componentIndex, yAxisModel.componentIndex
	                );
	                var data = seriesModel.getData();
	                var xAxis = cartesian.getAxis('x');
	                var yAxis = cartesian.getAxis('y');

	                if (data.type === 'list') {
	                    unionExtent(data, xAxis, seriesModel);
	                    unionExtent(data, yAxis, seriesModel);
	                }
	            }
	        }, this);

	        function unionExtent(data, axis, seriesModel) {
	            each(seriesModel.coordDimToDataDim(axis.dim), function (dim) {
	                axis.scale.unionExtentFromData(data, dim);
	            });
	        }
	    };

	    /**
	     * @param {string} [dim] 'x' or 'y' or 'auto' or null/undefined
	     * @return {Object} {baseAxes: [], otherAxes: []}
	     */
	    gridProto.getTooltipAxes = function (dim) {
	        var baseAxes = [];
	        var otherAxes = [];

	        each(this.getCartesians(), function (cartesian) {
	            var baseAxis = (dim != null && dim !== 'auto')
	                ? cartesian.getAxis(dim) : cartesian.getBaseAxis();
	            var otherAxis = cartesian.getOtherAxis(baseAxis);
	            zrUtil.indexOf(baseAxes, baseAxis) < 0 && baseAxes.push(baseAxis);
	            zrUtil.indexOf(otherAxes, otherAxis) < 0 && otherAxes.push(otherAxis);
	        });

	        return {baseAxes: baseAxes, otherAxes: otherAxes};
	    };

	    /**
	     * @inner
	     */
	    function updateAxisTransfrom(axis, coordBase) {
	        var axisExtent = axis.getExtent();
	        var axisExtentSum = axisExtent[0] + axisExtent[1];

	        // Fast transform
	        axis.toGlobalCoord = axis.dim === 'x'
	            ? function (coord) {
	                return coord + coordBase;
	            }
	            : function (coord) {
	                return axisExtentSum - coord + coordBase;
	            };
	        axis.toLocalCoord = axis.dim === 'x'
	            ? function (coord) {
	                return coord - coordBase;
	            }
	            : function (coord) {
	                return axisExtentSum - coord + coordBase;
	            };
	    }

	    var axesTypes = ['xAxis', 'yAxis'];
	    /**
	     * @inner
	     */
	    function findAxesModels(seriesModel, ecModel) {
	        return zrUtil.map(axesTypes, function (axisType) {
	            var axisModel = seriesModel.getReferringComponents(axisType)[0];

	            if (true) {
	                if (!axisModel) {
	                    throw new Error(axisType + ' "' + zrUtil.retrieve(
	                        seriesModel.get(axisType + 'Index'),
	                        seriesModel.get(axisType + 'Id'),
	                        0
	                    ) + '" not found');
	                }
	            }
	            return axisModel;
	        });
	    }

	    /**
	     * @inner
	     */
	    function isCartesian2D(seriesModel) {
	        return seriesModel.get('coordinateSystem') === 'cartesian2d';
	    }

	    Grid.create = function (ecModel, api) {
	        var grids = [];
	        ecModel.eachComponent('grid', function (gridModel, idx) {
	            var grid = new Grid(gridModel, ecModel, api);
	            grid.name = 'grid_' + idx;
	            // dataSampling requires axis extent, so resize
	            // should be performed in create stage.
	            grid.resize(gridModel, api, true);

	            gridModel.coordinateSystem = grid;

	            grids.push(grid);
	        });

	        // Inject the coordinateSystems into seriesModel
	        ecModel.eachSeries(function (seriesModel) {
	            if (!isCartesian2D(seriesModel)) {
	                return;
	            }

	            var axesModels = findAxesModels(seriesModel, ecModel);
	            var xAxisModel = axesModels[0];
	            var yAxisModel = axesModels[1];

	            var gridModel = xAxisModel.getCoordSysModel();

	            if (true) {
	                if (!gridModel) {
	                    throw new Error(
	                        'Grid "' + zrUtil.retrieve(
	                            xAxisModel.get('gridIndex'),
	                            xAxisModel.get('gridId'),
	                            0
	                        ) + '" not found'
	                    );
	                }
	                if (xAxisModel.getCoordSysModel() !== yAxisModel.getCoordSysModel()) {
	                    throw new Error('xAxis and yAxis must use the same grid');
	                }
	            }

	            var grid = gridModel.coordinateSystem;

	            seriesModel.coordinateSystem = grid.getCartesian(
	                xAxisModel.componentIndex, yAxisModel.componentIndex
	            );
	        });

	        return grids;
	    };

	    // For deciding which dimensions to use when creating list data
	    Grid.dimensions = Grid.prototype.dimensions = Cartesian2D.prototype.dimensions;

	    __webpack_require__(76).register('cartesian2d', Grid);

	    module.exports = Grid;


/***/ },
/* 126 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var zrUtil = __webpack_require__(4);
	    var Cartesian = __webpack_require__(127);

	    function Cartesian2D(name) {

	        Cartesian.call(this, name);
	    }

	    Cartesian2D.prototype = {

	        constructor: Cartesian2D,

	        type: 'cartesian2d',

	        /**
	         * @type {Array.<string>}
	         * @readOnly
	         */
	        dimensions: ['x', 'y'],

	        /**
	         * Base axis will be used on stacking.
	         *
	         * @return {module:echarts/coord/cartesian/Axis2D}
	         */
	        getBaseAxis: function () {
	            return this.getAxesByScale('ordinal')[0]
	                || this.getAxesByScale('time')[0]
	                || this.getAxis('x');
	        },

	        /**
	         * If contain point
	         * @param {Array.<number>} point
	         * @return {boolean}
	         */
	        containPoint: function (point) {
	            var axisX = this.getAxis('x');
	            var axisY = this.getAxis('y');
	            return axisX.contain(axisX.toLocalCoord(point[0]))
	                && axisY.contain(axisY.toLocalCoord(point[1]));
	        },

	        /**
	         * If contain data
	         * @param {Array.<number>} data
	         * @return {boolean}
	         */
	        containData: function (data) {
	            return this.getAxis('x').containData(data[0])
	                && this.getAxis('y').containData(data[1]);
	        },

	        /**
	         * Convert series data to an array of points
	         * @param {module:echarts/data/List} data
	         * @param {boolean} stack
	         * @return {Array}
	         *  Return array of points. For example:
	         *  `[[10, 10], [20, 20], [30, 30]]`
	         */
	        dataToPoints: function (data, stack) {
	            return data.mapArray(['x', 'y'], function (x, y) {
	                return this.dataToPoint([x, y]);
	            }, stack, this);
	        },

	        /**
	         * @param {Array.<number>} data
	         * @param {boolean} [clamp=false]
	         * @return {Array.<number>}
	         */
	        dataToPoint: function (data, clamp) {
	            var xAxis = this.getAxis('x');
	            var yAxis = this.getAxis('y');
	            return [
	                xAxis.toGlobalCoord(xAxis.dataToCoord(data[0], clamp)),
	                yAxis.toGlobalCoord(yAxis.dataToCoord(data[1], clamp))
	            ];
	        },

	        /**
	         * @param {Array.<number>} point
	         * @param {boolean} [clamp=false]
	         * @return {Array.<number>}
	         */
	        pointToData: function (point, clamp) {
	            var xAxis = this.getAxis('x');
	            var yAxis = this.getAxis('y');
	            return [
	                xAxis.coordToData(xAxis.toLocalCoord(point[0]), clamp),
	                yAxis.coordToData(yAxis.toLocalCoord(point[1]), clamp)
	            ];
	        },

	        /**
	         * Get other axis
	         * @param {module:echarts/coord/cartesian/Axis2D} axis
	         */
	        getOtherAxis: function (axis) {
	            return this.getAxis(axis.dim === 'x' ? 'y' : 'x');
	        }

	    };

	    zrUtil.inherits(Cartesian2D, Cartesian);

	    module.exports = Cartesian2D;


/***/ },
/* 127 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	/**
	 * Cartesian coordinate system
	 * @module  echarts/coord/Cartesian
	 *
	 */


	    var zrUtil = __webpack_require__(4);

	    function dimAxisMapper(dim) {
	        return this._axes[dim];
	    }

	    /**
	     * @alias module:echarts/coord/Cartesian
	     * @constructor
	     */
	    var Cartesian = function (name) {
	        this._axes = {};

	        this._dimList = [];

	        /**
	         * @type {string}
	         */
	        this.name = name || '';
	    };

	    Cartesian.prototype = {

	        constructor: Cartesian,

	        type: 'cartesian',

	        /**
	         * Get axis
	         * @param  {number|string} dim
	         * @return {module:echarts/coord/Cartesian~Axis}
	         */
	        getAxis: function (dim) {
	            return this._axes[dim];
	        },

	        /**
	         * Get axes list
	         * @return {Array.<module:echarts/coord/Cartesian~Axis>}
	         */
	        getAxes: function () {
	            return zrUtil.map(this._dimList, dimAxisMapper, this);
	        },

	        /**
	         * Get axes list by given scale type
	         */
	        getAxesByScale: function (scaleType) {
	            scaleType = scaleType.toLowerCase();
	            return zrUtil.filter(
	                this.getAxes(),
	                function (axis) {
	                    return axis.scale.type === scaleType;
	                }
	            );
	        },

	        /**
	         * Add axis
	         * @param {module:echarts/coord/Cartesian.Axis}
	         */
	        addAxis: function (axis) {
	            var dim = axis.dim;

	            this._axes[dim] = axis;

	            this._dimList.push(dim);
	        },

	        /**
	         * Convert data to coord in nd space
	         * @param {Array.<number>|Object.<string, number>} val
	         * @return {Array.<number>|Object.<string, number>}
	         */
	        dataToCoord: function (val) {
	            return this._dataCoordConvert(val, 'dataToCoord');
	        },

	        /**
	         * Convert coord in nd space to data
	         * @param  {Array.<number>|Object.<string, number>} val
	         * @return {Array.<number>|Object.<string, number>}
	         */
	        coordToData: function (val) {
	            return this._dataCoordConvert(val, 'coordToData');
	        },

	        _dataCoordConvert: function (input, method) {
	            var dimList = this._dimList;

	            var output = input instanceof Array ? [] : {};

	            for (var i = 0; i < dimList.length; i++) {
	                var dim = dimList[i];
	                var axis = this._axes[dim];

	                output[dim] = axis[method](input[dim]);
	            }

	            return output;
	        }
	    };

	    module.exports = Cartesian;


/***/ },
/* 128 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);
	    var Axis = __webpack_require__(100);

	    /**
	     * Extend axis 2d
	     * @constructor module:echarts/coord/cartesian/Axis2D
	     * @extends {module:echarts/coord/cartesian/Axis}
	     * @param {string} dim
	     * @param {*} scale
	     * @param {Array.<number>} coordExtent
	     * @param {string} axisType
	     * @param {string} position
	     */
	    var Axis2D = function (dim, scale, coordExtent, axisType, position) {
	        Axis.call(this, dim, scale, coordExtent);
	        /**
	         * Axis type
	         *  - 'category'
	         *  - 'value'
	         *  - 'time'
	         *  - 'log'
	         * @type {string}
	         */
	        this.type = axisType || 'value';

	        /**
	         * Axis position
	         *  - 'top'
	         *  - 'bottom'
	         *  - 'left'
	         *  - 'right'
	         */
	        this.position = position || 'bottom';
	    };

	    Axis2D.prototype = {

	        constructor: Axis2D,

	        /**
	         * Index of axis, can be used as key
	         */
	        index: 0,
	        /**
	         * If axis is on the zero position of the other axis
	         * @type {boolean}
	         */
	        onZero: false,

	        /**
	         * Axis model
	         * @param {module:echarts/coord/cartesian/AxisModel}
	         */
	        model: null,

	        isHorizontal: function () {
	            var position = this.position;
	            return position === 'top' || position === 'bottom';
	        },

	        /**
	         * Each item cooresponds to this.getExtent(), which
	         * means globalExtent[0] may greater than globalExtent[1],
	         * unless `asc` is input.
	         *
	         * @param {boolean} [asc]
	         * @return {Array.<number>}
	         */
	        getGlobalExtent: function (asc) {
	            var ret = this.getExtent();
	            ret[0] = this.toGlobalCoord(ret[0]);
	            ret[1] = this.toGlobalCoord(ret[1]);
	            asc && ret[0] > ret[1] && ret.reverse();
	            return ret;
	        },

	        getOtherAxis: function () {
	            this.grid.getOtherAxis();
	        },

	        /**
	         * If label is ignored.
	         * Automatically used when axis is category and label can not be all shown
	         * @param  {number}  idx
	         * @return {boolean}
	         */
	        isLabelIgnored: function (idx) {
	            if (this.type === 'category') {
	                var labelInterval = this.getLabelInterval();
	                return ((typeof labelInterval === 'function')
	                    && !labelInterval(idx, this.scale.getLabel(idx)))
	                    || idx % (labelInterval + 1);
	            }
	        },

	        /**
	         * @override
	         */
	        pointToData: function (point, clamp) {
	            return this.coordToData(this.toLocalCoord(point[this.dim === 'x' ? 0 : 1]), clamp);
	        },

	        /**
	         * Transform global coord to local coord,
	         * i.e. var localCoord = axis.toLocalCoord(80);
	         * designate by module:echarts/coord/cartesian/Grid.
	         * @type {Function}
	         */
	        toLocalCoord: null,

	        /**
	         * Transform global coord to local coord,
	         * i.e. var globalCoord = axis.toLocalCoord(40);
	         * designate by module:echarts/coord/cartesian/Grid.
	         * @type {Function}
	         */
	        toGlobalCoord: null

	    };
	    zrUtil.inherits(Axis2D, Axis);

	    module.exports = Axis2D;


/***/ },
/* 129 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	// Grid 是在有直角坐标系的时候必须要存在的
	// 所以这里也要被 Cartesian2D 依赖


	    __webpack_require__(130);

	    var ComponentModel = __webpack_require__(69);

	    module.exports = ComponentModel.extend({

	        type: 'grid',

	        dependencies: ['xAxis', 'yAxis'],

	        layoutMode: 'box',

	        /**
	         * @type {module:echarts/coord/cartesian/Grid}
	         */
	        coordinateSystem: null,

	        defaultOption: {
	            show: false,
	            zlevel: 0,
	            z: 0,
	            left: '10%',
	            top: 60,
	            right: '10%',
	            bottom: 60,
	            // If grid size contain label
	            containLabel: false,
	            // width: {totalWidth} - left - right,
	            // height: {totalHeight} - top - bottom,
	            backgroundColor: 'rgba(0,0,0,0)',
	            borderWidth: 1,
	            borderColor: '#ccc'
	        }
	    });


/***/ },
/* 130 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var ComponentModel = __webpack_require__(69);
	    var zrUtil = __webpack_require__(4);
	    var axisModelCreator = __webpack_require__(131);

	    var AxisModel = ComponentModel.extend({

	        type: 'cartesian2dAxis',

	        /**
	         * @type {module:echarts/coord/cartesian/Axis2D}
	         */
	        axis: null,

	        /**
	         * @override
	         */
	        init: function () {
	            AxisModel.superApply(this, 'init', arguments);
	            this.resetRange();
	        },

	        /**
	         * @override
	         */
	        mergeOption: function () {
	            AxisModel.superApply(this, 'mergeOption', arguments);
	            this.resetRange();
	        },

	        /**
	         * @override
	         */
	        restoreData: function () {
	            AxisModel.superApply(this, 'restoreData', arguments);
	            this.resetRange();
	        },

	        /**
	         * @override
	         * @return {module:echarts/model/Component}
	         */
	        getCoordSysModel: function () {
	            return this.ecModel.queryComponents({
	                mainType: 'grid',
	                index: this.option.gridIndex,
	                id: this.option.gridId
	            })[0];
	        }

	    });

	    function getAxisType(axisDim, option) {
	        // Default axis with data is category axis
	        return option.type || (option.data ? 'category' : 'value');
	    }

	    zrUtil.merge(AxisModel.prototype, __webpack_require__(112));

	    var extraOption = {
	        // gridIndex: 0,
	        // gridId: '',

	        // Offset is for multiple axis on the same position
	        offset: 0
	    };

	    axisModelCreator('x', AxisModel, getAxisType, extraOption);
	    axisModelCreator('y', AxisModel, getAxisType, extraOption);

	    module.exports = AxisModel;


/***/ },
/* 131 */
/***/ function(module, exports, __webpack_require__) {

	

	    var axisDefault = __webpack_require__(132);
	    var zrUtil = __webpack_require__(4);
	    var ComponentModel = __webpack_require__(69);
	    var layout = __webpack_require__(71);

	    // FIXME axisType is fixed ?
	    var AXIS_TYPES = ['value', 'category', 'time', 'log'];

	    /**
	     * Generate sub axis model class
	     * @param {string} axisName 'x' 'y' 'radius' 'angle' 'parallel'
	     * @param {module:echarts/model/Component} BaseAxisModelClass
	     * @param {Function} axisTypeDefaulter
	     * @param {Object} [extraDefaultOption]
	     */
	    module.exports = function (axisName, BaseAxisModelClass, axisTypeDefaulter, extraDefaultOption) {

	        zrUtil.each(AXIS_TYPES, function (axisType) {

	            BaseAxisModelClass.extend({

	                type: axisName + 'Axis.' + axisType,

	                mergeDefaultAndTheme: function (option, ecModel) {
	                    var layoutMode = this.layoutMode;
	                    var inputPositionParams = layoutMode
	                        ? layout.getLayoutParams(option) : {};

	                    var themeModel = ecModel.getTheme();
	                    zrUtil.merge(option, themeModel.get(axisType + 'Axis'));
	                    zrUtil.merge(option, this.getDefaultOption());

	                    option.type = axisTypeDefaulter(axisName, option);

	                    if (layoutMode) {
	                        layout.mergeLayoutParam(option, inputPositionParams, layoutMode);
	                    }
	                },

	                defaultOption: zrUtil.mergeAll(
	                    [
	                        {},
	                        axisDefault[axisType + 'Axis'],
	                        extraDefaultOption
	                    ],
	                    true
	                )
	            });
	        });

	        ComponentModel.registerSubTypeDefaulter(
	            axisName + 'Axis',
	            zrUtil.curry(axisTypeDefaulter, axisName)
	        );
	    };


/***/ },
/* 132 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);

	    var defaultOption = {
	        show: true,
	        zlevel: 0,                  // 一级层叠
	        z: 0,                       // 二级层叠
	        // 反向坐标轴
	        inverse: false,

	        // 坐标轴名字，默认为空
	        name: '',
	        // 坐标轴名字位置，支持'start' | 'middle' | 'end'
	        nameLocation: 'end',
	        // 坐标轴名字旋转，degree。
	        nameRotate: null, // Adapt to axis rotate, when nameLocation is 'middle'.
	        nameTruncate: {
	            maxWidth: null,
	            ellipsis: '...',
	            placeholder: '.'
	        },
	        // 坐标轴文字样式，默认取全局样式
	        nameTextStyle: {},
	        // 文字与轴线距离
	        nameGap: 15,

	        silent: false, // Default false to support tooltip.
	        triggerEvent: false, // Default false to avoid legacy user event listener fail.

	        tooltip: {
	            show: false
	        },

	        axisPointer: {},

	        // 坐标轴线
	        axisLine: {
	            // 默认显示，属性show控制显示与否
	            show: true,
	            onZero: true,
	            // 属性lineStyle控制线条样式
	            lineStyle: {
	                color: '#333',
	                width: 1,
	                type: 'solid'
	            }
	        },
	        // 坐标轴小标记
	        axisTick: {
	            // 属性show控制显示与否，默认显示
	            show: true,
	            // 控制小标记是否在grid里
	            inside: false,
	            // 属性length控制线长
	            length: 5,
	            // 属性lineStyle控制线条样式
	            lineStyle: {
	                width: 1
	            }
	        },
	        // 坐标轴文本标签，详见axis.axisLabel
	        axisLabel: {
	            show: true,
	            // 控制文本标签是否在grid里
	            inside: false,
	            rotate: 0,
	            showMinLabel: null, // true | false | null (auto)
	            showMaxLabel: null, // true | false | null (auto)
	            margin: 8,
	            // formatter: null,
	            // 其余属性默认使用全局文本样式，详见TEXTSTYLE
	            textStyle: {
	                fontSize: 12
	            }
	        },
	        // 分隔线
	        splitLine: {
	            // 默认显示，属性show控制显示与否
	            show: true,
	            // 属性lineStyle（详见lineStyle）控制线条样式
	            lineStyle: {
	                color: ['#ccc'],
	                width: 1,
	                type: 'solid'
	            }
	        },
	        // 分隔区域
	        splitArea: {
	            // 默认不显示，属性show控制显示与否
	            show: false,
	            // 属性areaStyle（详见areaStyle）控制区域样式
	            areaStyle: {
	                color: ['rgba(250,250,250,0.3)','rgba(200,200,200,0.3)']
	            }
	        }
	    };

	    var categoryAxis = zrUtil.merge({
	        // 类目起始和结束两端空白策略
	        boundaryGap: true,
	        // splitArea: {
	            // show: false
	        // },
	        splitLine: {
	            show: false
	        },
	        // 坐标轴小标记
	        axisTick: {
	            // If tick is align with label when boundaryGap is true
	            alignWithLabel: false,
	            interval: 'auto'
	        },
	        // 坐标轴文本标签，详见axis.axisLabel
	        axisLabel: {
	            interval: 'auto'
	        }
	    }, defaultOption);

	    var valueAxis = zrUtil.merge({
	        // 数值起始和结束两端空白策略
	        boundaryGap: [0, 0],
	        // 最小值, 设置成 'dataMin' 则从数据中计算最小值
	        // min: null,
	        // 最大值，设置成 'dataMax' 则从数据中计算最大值
	        // max: null,
	        // Readonly prop, specifies start value of the range when using data zoom.
	        // rangeStart: null
	        // Readonly prop, specifies end value of the range when using data zoom.
	        // rangeEnd: null
	        // 脱离0值比例，放大聚焦到最终_min，_max区间
	        // scale: false,
	        // 分割段数，默认为5
	        splitNumber: 5
	        // Minimum interval
	        // minInterval: null
	    }, defaultOption);

	    // FIXME
	    var timeAxis = zrUtil.defaults({
	        scale: true,
	        min: 'dataMin',
	        max: 'dataMax'
	    }, valueAxis);

	    var logAxis = zrUtil.defaults({
	        scale: true,
	        logBase: 10
	    }, valueAxis);

	    module.exports = {
	        categoryAxis: categoryAxis,
	        valueAxis: valueAxis,
	        timeAxis: timeAxis,
	        logAxis: logAxis
	    };


/***/ },
/* 133 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	// TODO boundaryGap


	    __webpack_require__(130);

	    __webpack_require__(134);


/***/ },
/* 134 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);
	    var graphic = __webpack_require__(18);
	    var AxisBuilder = __webpack_require__(135);
	    var AxisView = __webpack_require__(136);
	    var cartesianAxisHelper = __webpack_require__(138);
	    var ifIgnoreOnTick = AxisBuilder.ifIgnoreOnTick;
	    var getInterval = AxisBuilder.getInterval;

	    var axisBuilderAttrs = [
	        'axisLine', 'axisLabel', 'axisTick', 'axisName'
	    ];
	    var selfBuilderAttrs = [
	        'splitArea', 'splitLine'
	    ];

	    // function getAlignWithLabel(model, axisModel) {
	    //     var alignWithLabel = model.get('alignWithLabel');
	    //     if (alignWithLabel === 'auto') {
	    //         alignWithLabel = axisModel.get('axisTick.alignWithLabel');
	    //     }
	    //     return alignWithLabel;
	    // }

	    var CartesianAxisView = AxisView.extend({

	        type: 'cartesianAxis',

	        axisPointerClass: 'CartesianAxisPointer',

	        /**
	         * @override
	         */
	        render: function (axisModel, ecModel, api, payload) {

	            this.group.removeAll();

	            var oldAxisGroup = this._axisGroup;
	            this._axisGroup = new graphic.Group();

	            this.group.add(this._axisGroup);

	            if (!axisModel.get('show')) {
	                return;
	            }

	            var gridModel = axisModel.getCoordSysModel();

	            var layout = cartesianAxisHelper.layout(gridModel, axisModel);

	            var axisBuilder = new AxisBuilder(axisModel, layout);

	            zrUtil.each(axisBuilderAttrs, axisBuilder.add, axisBuilder);

	            this._axisGroup.add(axisBuilder.getGroup());

	            zrUtil.each(selfBuilderAttrs, function (name) {
	                if (axisModel.get(name + '.show')) {
	                    this['_' + name](axisModel, gridModel, layout.labelInterval);
	                }
	            }, this);

	            graphic.groupTransition(oldAxisGroup, this._axisGroup, axisModel);

	            CartesianAxisView.superCall(this, 'render', axisModel, ecModel, api, payload);
	        },

	        /**
	         * @param {module:echarts/coord/cartesian/AxisModel} axisModel
	         * @param {module:echarts/coord/cartesian/GridModel} gridModel
	         * @param {number|Function} labelInterval
	         * @private
	         */
	        _splitLine: function (axisModel, gridModel, labelInterval) {
	            var axis = axisModel.axis;

	            if (axis.scale.isBlank()) {
	                return;
	            }

	            var splitLineModel = axisModel.getModel('splitLine');
	            var lineStyleModel = splitLineModel.getModel('lineStyle');
	            var lineColors = lineStyleModel.get('color');

	            var lineInterval = getInterval(splitLineModel, labelInterval);

	            lineColors = zrUtil.isArray(lineColors) ? lineColors : [lineColors];

	            var gridRect = gridModel.coordinateSystem.getRect();
	            var isHorizontal = axis.isHorizontal();

	            var lineCount = 0;

	            var ticksCoords = axis.getTicksCoords(
	                // splitLineModel.get('alignWithLabel')
	            );
	            var ticks = axis.scale.getTicks();

	            var p1 = [];
	            var p2 = [];
	            // Simple optimization
	            // Batching the lines if color are the same
	            var lineStyle = lineStyleModel.getLineStyle();
	            for (var i = 0; i < ticksCoords.length; i++) {
	                if (ifIgnoreOnTick(axis, i, lineInterval)) {
	                    continue;
	                }

	                var tickCoord = axis.toGlobalCoord(ticksCoords[i]);

	                if (isHorizontal) {
	                    p1[0] = tickCoord;
	                    p1[1] = gridRect.y;
	                    p2[0] = tickCoord;
	                    p2[1] = gridRect.y + gridRect.height;
	                }
	                else {
	                    p1[0] = gridRect.x;
	                    p1[1] = tickCoord;
	                    p2[0] = gridRect.x + gridRect.width;
	                    p2[1] = tickCoord;
	                }

	                var colorIndex = (lineCount++) % lineColors.length;
	                this._axisGroup.add(new graphic.Line(graphic.subPixelOptimizeLine({
	                    anid: 'line_' + ticks[i],

	                    shape: {
	                        x1: p1[0],
	                        y1: p1[1],
	                        x2: p2[0],
	                        y2: p2[1]
	                    },
	                    style: zrUtil.defaults({
	                        stroke: lineColors[colorIndex]
	                    }, lineStyle),
	                    silent: true
	                })));
	            }
	        },

	        /**
	         * @param {module:echarts/coord/cartesian/AxisModel} axisModel
	         * @param {module:echarts/coord/cartesian/GridModel} gridModel
	         * @param {number|Function} labelInterval
	         * @private
	         */
	        _splitArea: function (axisModel, gridModel, labelInterval) {
	            var axis = axisModel.axis;

	            if (axis.scale.isBlank()) {
	                return;
	            }

	            var splitAreaModel = axisModel.getModel('splitArea');
	            var areaStyleModel = splitAreaModel.getModel('areaStyle');
	            var areaColors = areaStyleModel.get('color');

	            var gridRect = gridModel.coordinateSystem.getRect();

	            var ticksCoords = axis.getTicksCoords(
	                // splitAreaModel.get('alignWithLabel')
	            );
	            var ticks = axis.scale.getTicks();

	            var prevX = axis.toGlobalCoord(ticksCoords[0]);
	            var prevY = axis.toGlobalCoord(ticksCoords[0]);

	            var count = 0;

	            var areaInterval = getInterval(splitAreaModel, labelInterval);

	            var areaStyle = areaStyleModel.getAreaStyle();
	            areaColors = zrUtil.isArray(areaColors) ? areaColors : [areaColors];

	            for (var i = 1; i < ticksCoords.length; i++) {
	                if (ifIgnoreOnTick(axis, i, areaInterval)) {
	                    continue;
	                }

	                var tickCoord = axis.toGlobalCoord(ticksCoords[i]);

	                var x;
	                var y;
	                var width;
	                var height;
	                if (axis.isHorizontal()) {
	                    x = prevX;
	                    y = gridRect.y;
	                    width = tickCoord - x;
	                    height = gridRect.height;
	                }
	                else {
	                    x = gridRect.x;
	                    y = prevY;
	                    width = gridRect.width;
	                    height = tickCoord - y;
	                }

	                var colorIndex = (count++) % areaColors.length;
	                this._axisGroup.add(new graphic.Rect({
	                    anid: 'area_' + ticks[i],

	                    shape: {
	                        x: x,
	                        y: y,
	                        width: width,
	                        height: height
	                    },
	                    style: zrUtil.defaults({
	                        fill: areaColors[colorIndex]
	                    }, areaStyle),
	                    silent: true
	                }));

	                prevX = x + width;
	                prevY = y + height;
	            }
	        }
	    });

	    CartesianAxisView.extend({
	        type: 'xAxis'
	    });
	    CartesianAxisView.extend({
	        type: 'yAxis'
	    });



/***/ },
/* 135 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);
	    var formatUtil = __webpack_require__(6);
	    var graphic = __webpack_require__(18);
	    var Model = __webpack_require__(12);
	    var numberUtil = __webpack_require__(7);
	    var remRadian = numberUtil.remRadian;
	    var isRadianAroundZero = numberUtil.isRadianAroundZero;
	    var vec2 = __webpack_require__(10);
	    var matrix = __webpack_require__(11);
	    var v2ApplyTransform = vec2.applyTransform;
	    var retrieve = zrUtil.retrieve;

	    var PI = Math.PI;

	    function makeAxisEventDataBase(axisModel) {
	        var eventData = {
	            componentType: axisModel.mainType
	        };
	        eventData[axisModel.mainType + 'Index'] = axisModel.componentIndex;
	        return eventData;
	    }

	    /**
	     * A final axis is translated and rotated from a "standard axis".
	     * So opt.position and opt.rotation is required.
	     *
	     * A standard axis is and axis from [0, 0] to [0, axisExtent[1]],
	     * for example: (0, 0) ------------> (0, 50)
	     *
	     * nameDirection or tickDirection or labelDirection is 1 means tick
	     * or label is below the standard axis, whereas is -1 means above
	     * the standard axis. labelOffset means offset between label and axis,
	     * which is useful when 'onZero', where axisLabel is in the grid and
	     * label in outside grid.
	     *
	     * Tips: like always,
	     * positive rotation represents anticlockwise, and negative rotation
	     * represents clockwise.
	     * The direction of position coordinate is the same as the direction
	     * of screen coordinate.
	     *
	     * Do not need to consider axis 'inverse', which is auto processed by
	     * axis extent.
	     *
	     * @param {module:zrender/container/Group} group
	     * @param {Object} axisModel
	     * @param {Object} opt Standard axis parameters.
	     * @param {Array.<number>} opt.position [x, y]
	     * @param {number} opt.rotation by radian
	     * @param {number} [opt.nameDirection=1] 1 or -1 Used when nameLocation is 'middle'.
	     * @param {number} [opt.tickDirection=1] 1 or -1
	     * @param {number} [opt.labelDirection=1] 1 or -1
	     * @param {number} [opt.labelOffset=0] Usefull when onZero.
	     * @param {string} [opt.axisLabelShow] default get from axisModel.
	     * @param {string} [opt.axisName] default get from axisModel.
	     * @param {number} [opt.axisNameAvailableWidth]
	     * @param {number} [opt.labelRotate] by degree, default get from axisModel.
	     * @param {number} [opt.labelInterval] Default label interval when label
	     *                                     interval from model is null or 'auto'.
	     * @param {number} [opt.strokeContainThreshold] Default label interval when label
	     * @param {number} [opt.nameTruncateMaxWidth]
	     */
	    var AxisBuilder = function (axisModel, opt) {

	        /**
	         * @readOnly
	         */
	        this.opt = opt;

	        /**
	         * @readOnly
	         */
	        this.axisModel = axisModel;

	        // Default value
	        zrUtil.defaults(
	            opt,
	            {
	                labelOffset: 0,
	                nameDirection: 1,
	                tickDirection: 1,
	                labelDirection: 1,
	                silent: true
	            }
	        );

	        /**
	         * @readOnly
	         */
	        this.group = new graphic.Group();

	        // FIXME Not use a seperate text group?
	        var dumbGroup = new graphic.Group({
	            position: opt.position.slice(),
	            rotation: opt.rotation
	        });

	        // this.group.add(dumbGroup);
	        // this._dumbGroup = dumbGroup;

	        dumbGroup.updateTransform();
	        this._transform = dumbGroup.transform;

	        this._dumbGroup = dumbGroup;
	    };

	    AxisBuilder.prototype = {

	        constructor: AxisBuilder,

	        hasBuilder: function (name) {
	            return !!builders[name];
	        },

	        add: function (name) {
	            builders[name].call(this);
	        },

	        getGroup: function () {
	            return this.group;
	        }

	    };

	    var builders = {

	        /**
	         * @private
	         */
	        axisLine: function () {
	            var opt = this.opt;
	            var axisModel = this.axisModel;

	            if (!axisModel.get('axisLine.show')) {
	                return;
	            }

	            var extent = this.axisModel.axis.getExtent();

	            var matrix = this._transform;
	            var pt1 = [extent[0], 0];
	            var pt2 = [extent[1], 0];
	            if (matrix) {
	                v2ApplyTransform(pt1, pt1, matrix);
	                v2ApplyTransform(pt2, pt2, matrix);
	            }

	            this.group.add(new graphic.Line(graphic.subPixelOptimizeLine({

	                // Id for animation
	                anid: 'line',

	                shape: {
	                    x1: pt1[0],
	                    y1: pt1[1],
	                    x2: pt2[0],
	                    y2: pt2[1]
	                },
	                style: zrUtil.extend(
	                    {lineCap: 'round'},
	                    axisModel.getModel('axisLine.lineStyle').getLineStyle()
	                ),
	                strokeContainThreshold: opt.strokeContainThreshold || 5,
	                silent: true,
	                z2: 1
	            })));
	        },

	        /**
	         * @private
	         */
	        axisTick: function () {
	            var axisModel = this.axisModel;
	            var axis = axisModel.axis;

	            if (!axisModel.get('axisTick.show') || axis.scale.isBlank()) {
	                return;
	            }

	            var tickModel = axisModel.getModel('axisTick');
	            var opt = this.opt;

	            var lineStyleModel = tickModel.getModel('lineStyle');
	            var tickLen = tickModel.get('length');

	            var tickInterval = getInterval(tickModel, opt.labelInterval);
	            var ticksCoords = axis.getTicksCoords(tickModel.get('alignWithLabel'));
	            var ticks = axis.scale.getTicks();

	            var pt1 = [];
	            var pt2 = [];
	            var matrix = this._transform;

	            for (var i = 0; i < ticksCoords.length; i++) {
	                // Only ordinal scale support tick interval
	                if (ifIgnoreOnTick(axis, i, tickInterval)) {
	                     continue;
	                }

	                var tickCoord = ticksCoords[i];

	                pt1[0] = tickCoord;
	                pt1[1] = 0;
	                pt2[0] = tickCoord;
	                pt2[1] = opt.tickDirection * tickLen;

	                if (matrix) {
	                    v2ApplyTransform(pt1, pt1, matrix);
	                    v2ApplyTransform(pt2, pt2, matrix);
	                }
	                // Tick line, Not use group transform to have better line draw
	                this.group.add(new graphic.Line(graphic.subPixelOptimizeLine({

	                    // Id for animation
	                    anid: 'tick_' + ticks[i],

	                    shape: {
	                        x1: pt1[0],
	                        y1: pt1[1],
	                        x2: pt2[0],
	                        y2: pt2[1]
	                    },
	                    style: zrUtil.defaults(
	                        lineStyleModel.getLineStyle(),
	                        {
	                            stroke: axisModel.get('axisLine.lineStyle.color')
	                        }
	                    ),
	                    z2: 2,
	                    silent: true
	                })));
	            }
	        },

	        /**
	         * @param {module:echarts/coord/cartesian/AxisModel} axisModel
	         * @param {module:echarts/coord/cartesian/GridModel} gridModel
	         * @private
	         */
	        axisLabel: function () {
	            var opt = this.opt;
	            var axisModel = this.axisModel;
	            var axis = axisModel.axis;
	            var show = retrieve(opt.axisLabelShow, axisModel.get('axisLabel.show'));

	            if (!show || axis.scale.isBlank()) {
	                return;
	            }

	            var labelModel = axisModel.getModel('axisLabel');
	            var textStyleModel = labelModel.getModel('textStyle');
	            var labelMargin = labelModel.get('margin');
	            var ticks = axis.scale.getTicks();
	            var labels = axisModel.getFormattedLabels();

	            // Special label rotate.
	            var labelRotation = (
	                retrieve(opt.labelRotate, labelModel.get('rotate')) || 0
	            ) * PI / 180;

	            var labelLayout = innerTextLayout(opt.rotation, labelRotation, opt.labelDirection);
	            var categoryData = axisModel.get('data');

	            var textEls = [];
	            var silent = isSilent(axisModel);
	            var triggerEvent = axisModel.get('triggerEvent');

	            zrUtil.each(ticks, function (tickVal, index) {
	                if (ifIgnoreOnTick(axis, index, opt.labelInterval)) {
	                     return;
	                }

	                var itemTextStyleModel = textStyleModel;
	                if (categoryData && categoryData[tickVal] && categoryData[tickVal].textStyle) {
	                    itemTextStyleModel = new Model(
	                        categoryData[tickVal].textStyle, textStyleModel, axisModel.ecModel
	                    );
	                }
	                var textColor = itemTextStyleModel.getTextColor()
	                    || axisModel.get('axisLine.lineStyle.color');

	                var tickCoord = axis.dataToCoord(tickVal);
	                var pos = [
	                    tickCoord,
	                    opt.labelOffset + opt.labelDirection * labelMargin
	                ];
	                var labelStr = axis.scale.getLabel(tickVal);

	                var textEl = new graphic.Text({

	                    // Id for animation
	                    anid: 'label_' + tickVal,

	                    style: {
	                        text: labels[index],
	                        textAlign: itemTextStyleModel.get('align', true) || labelLayout.textAlign,
	                        textVerticalAlign: itemTextStyleModel.get('baseline', true) || labelLayout.textVerticalAlign,
	                        textFont: itemTextStyleModel.getFont(),
	                        fill: typeof textColor === 'function'
	                            ? textColor(
	                                // (1) In category axis with data zoom, tick is not the original
	                                // index of axis.data. So tick should not be exposed to user
	                                // in category axis.
	                                // (2) Compatible with previous version, which always returns labelStr.
	                                // But in interval scale labelStr is like '223,445', which maked
	                                // user repalce ','. So we modify it to return original val but remain
	                                // it as 'string' to avoid error in replacing.
	                                axis.type === 'category' ? labelStr : axis.type === 'value' ? tickVal + '' : tickVal,
	                                index
	                            )
	                            : textColor
	                    },
	                    position: pos,
	                    rotation: labelLayout.rotation,
	                    silent: silent,
	                    z2: 10
	                });

	                // Pack data for mouse event
	                if (triggerEvent) {
	                    textEl.eventData = makeAxisEventDataBase(axisModel);
	                    textEl.eventData.targetType = 'axisLabel';
	                    textEl.eventData.value = labelStr;
	                }

	                // FIXME
	                this._dumbGroup.add(textEl);
	                textEl.updateTransform();

	                textEls.push(textEl);
	                this.group.add(textEl);

	                textEl.decomposeTransform();

	            }, this);

	            fixMinMaxLabelShow(axisModel, textEls);
	        },

	        /**
	         * @private
	         */
	        axisName: function () {
	            var opt = this.opt;
	            var axisModel = this.axisModel;
	            var name = retrieve(opt.axisName, axisModel.get('name'));

	            if (!name) {
	                return;
	            }

	            var nameLocation = axisModel.get('nameLocation');
	            var nameDirection = opt.nameDirection;
	            var textStyleModel = axisModel.getModel('nameTextStyle');
	            var gap = axisModel.get('nameGap') || 0;

	            var extent = this.axisModel.axis.getExtent();
	            var gapSignal = extent[0] > extent[1] ? -1 : 1;
	            var pos = [
	                nameLocation === 'start'
	                    ? extent[0] - gapSignal * gap
	                    : nameLocation === 'end'
	                    ? extent[1] + gapSignal * gap
	                    : (extent[0] + extent[1]) / 2, // 'middle'
	                // Reuse labelOffset.
	                nameLocation === 'middle' ? opt.labelOffset + nameDirection * gap : 0
	            ];

	            var labelLayout;

	            var nameRotation = axisModel.get('nameRotate');
	            if (nameRotation != null) {
	                nameRotation = nameRotation * PI / 180; // To radian.
	            }

	            var axisNameAvailableWidth;

	            if (nameLocation === 'middle') {
	                labelLayout = innerTextLayout(
	                    opt.rotation,
	                    nameRotation != null ? nameRotation : opt.rotation, // Adapt to axis.
	                    nameDirection
	                );
	            }
	            else {
	                labelLayout = endTextLayout(
	                    opt, nameLocation, nameRotation || 0, extent
	                );

	                axisNameAvailableWidth = opt.axisNameAvailableWidth;
	                if (axisNameAvailableWidth != null) {
	                    axisNameAvailableWidth = Math.abs(
	                        axisNameAvailableWidth / Math.sin(labelLayout.rotation)
	                    );
	                    !isFinite(axisNameAvailableWidth) && (axisNameAvailableWidth = null);
	                }
	            }

	            var textFont = textStyleModel.getFont();

	            var truncateOpt = axisModel.get('nameTruncate', true) || {};
	            var ellipsis = truncateOpt.ellipsis;
	            var maxWidth = retrieve(
	                opt.nameTruncateMaxWidth, truncateOpt.maxWidth, axisNameAvailableWidth
	            );
	            var truncatedText = (ellipsis != null && maxWidth != null)
	                ? formatUtil.truncateText(
	                    name, maxWidth, textFont, ellipsis,
	                    {minChar: 2, placeholder: truncateOpt.placeholder}
	                )
	                : name;

	            var tooltipOpt = axisModel.get('tooltip', true);

	            var mainType = axisModel.mainType;
	            var formatterParams = {
	                componentType: mainType,
	                name: name,
	                $vars: ['name']
	            };
	            formatterParams[mainType + 'Index'] = axisModel.componentIndex;

	            var textEl = new graphic.Text({

	                // Id for animation
	                anid: 'name',

	                __fullText: name,
	                __truncatedText: truncatedText,

	                style: {
	                    text: truncatedText,
	                    textFont: textFont,
	                    fill: textStyleModel.getTextColor()
	                        || axisModel.get('axisLine.lineStyle.color'),
	                    textAlign: labelLayout.textAlign,
	                    textVerticalAlign: labelLayout.textVerticalAlign
	                },
	                position: pos,
	                rotation: labelLayout.rotation,
	                silent: isSilent(axisModel),
	                z2: 1,
	                tooltip: (tooltipOpt && tooltipOpt.show)
	                    ? zrUtil.extend({
	                        content: name,
	                        formatter: function () {
	                            return name;
	                        },
	                        formatterParams: formatterParams
	                    }, tooltipOpt)
	                    : null
	            });

	            if (axisModel.get('triggerEvent')) {
	                textEl.eventData = makeAxisEventDataBase(axisModel);
	                textEl.eventData.targetType = 'axisName';
	                textEl.eventData.name = name;
	            }

	            // FIXME
	            this._dumbGroup.add(textEl);
	            textEl.updateTransform();

	            this.group.add(textEl);

	            textEl.decomposeTransform();
	        }

	    };

	    /**
	     * @public
	     * @static
	     * @param {Object} opt
	     * @param {number} axisRotation in radian
	     * @param {number} textRotation in radian
	     * @param {number} direction
	     * @return {Object} {
	     *  rotation, // according to axis
	     *  textAlign,
	     *  textVerticalAlign
	     * }
	     */
	    var innerTextLayout = AxisBuilder.innerTextLayout = function (axisRotation, textRotation, direction) {
	        var rotationDiff = remRadian(textRotation - axisRotation);
	        var textAlign;
	        var textVerticalAlign;

	        if (isRadianAroundZero(rotationDiff)) { // Label is parallel with axis line.
	            textVerticalAlign = direction > 0 ? 'top' : 'bottom';
	            textAlign = 'center';
	        }
	        else if (isRadianAroundZero(rotationDiff - PI)) { // Label is inverse parallel with axis line.
	            textVerticalAlign = direction > 0 ? 'bottom' : 'top';
	            textAlign = 'center';
	        }
	        else {
	            textVerticalAlign = 'middle';

	            if (rotationDiff > 0 && rotationDiff < PI) {
	                textAlign = direction > 0 ? 'right' : 'left';
	            }
	            else {
	                textAlign = direction > 0 ? 'left' : 'right';
	            }
	        }

	        return {
	            rotation: rotationDiff,
	            textAlign: textAlign,
	            textVerticalAlign: textVerticalAlign
	        };
	    };

	    function endTextLayout(opt, textPosition, textRotate, extent) {
	        var rotationDiff = remRadian(textRotate - opt.rotation);
	        var textAlign;
	        var textVerticalAlign;
	        var inverse = extent[0] > extent[1];
	        var onLeft = (textPosition === 'start' && !inverse)
	            || (textPosition !== 'start' && inverse);

	        if (isRadianAroundZero(rotationDiff - PI / 2)) {
	            textVerticalAlign = onLeft ? 'bottom' : 'top';
	            textAlign = 'center';
	        }
	        else if (isRadianAroundZero(rotationDiff - PI * 1.5)) {
	            textVerticalAlign = onLeft ? 'top' : 'bottom';
	            textAlign = 'center';
	        }
	        else {
	            textVerticalAlign = 'middle';
	            if (rotationDiff < PI * 1.5 && rotationDiff > PI / 2) {
	                textAlign = onLeft ? 'left' : 'right';
	            }
	            else {
	                textAlign = onLeft ? 'right' : 'left';
	            }
	        }

	        return {
	            rotation: rotationDiff,
	            textAlign: textAlign,
	            textVerticalAlign: textVerticalAlign
	        };
	    }

	    function isSilent(axisModel) {
	        var tooltipOpt = axisModel.get('tooltip');
	        return axisModel.get('silent')
	            // Consider mouse cursor, add these restrictions.
	            || !(
	                axisModel.get('triggerEvent') || (tooltipOpt && tooltipOpt.show)
	            );
	    }

	    function fixMinMaxLabelShow(axisModel, textEls) {
	        // If min or max are user set, we need to check
	        // If the tick on min(max) are overlap on their neighbour tick
	        // If they are overlapped, we need to hide the min(max) tick label
	        var showMinLabel = axisModel.get('axisLabel.showMinLabel');
	        var showMaxLabel = axisModel.get('axisLabel.showMaxLabel');
	        var firstLabel = textEls[0];
	        var nextLabel = textEls[1];
	        var lastLabel = textEls[textEls.length - 1];
	        var prevLabel = textEls[textEls.length - 2];

	        if (showMinLabel === false) {
	            firstLabel.ignore = true;
	        }
	        else if (axisModel.getMin() != null && isTwoLabelOverlapped(firstLabel, nextLabel)) {
	            showMinLabel ? (nextLabel.ignore = true) : (firstLabel.ignore = true);
	        }

	        if (showMaxLabel === false) {
	            lastLabel.ignore = true;
	        }
	        else if (axisModel.getMax() != null && isTwoLabelOverlapped(prevLabel, lastLabel)) {
	            showMaxLabel ? (prevLabel.ignore = true) : (lastLabel.ignore = true);
	        }
	    }

	    function isTwoLabelOverlapped(current, next, labelLayout) {
	        // current and next has the same rotation.
	        var firstRect = current && current.getBoundingRect().clone();
	        var nextRect = next && next.getBoundingRect().clone();

	        if (!firstRect || !nextRect) {
	            return;
	        }

	        // When checking intersect of two rotated labels, we use mRotationBack
	        // to avoid that boundingRect is enlarge when using `boundingRect.applyTransform`.
	        var mRotationBack = matrix.identity([]);
	        matrix.rotate(mRotationBack, mRotationBack, -current.rotation);

	        firstRect.applyTransform(matrix.mul([], mRotationBack, current.getLocalTransform()));
	        nextRect.applyTransform(matrix.mul([], mRotationBack, next.getLocalTransform()));

	        return firstRect.intersect(nextRect);
	    }


	    /**
	     * @static
	     */
	    var ifIgnoreOnTick = AxisBuilder.ifIgnoreOnTick = function (axis, i, interval) {
	        var rawTick;
	        var scale = axis.scale;
	        return scale.type === 'ordinal'
	            && (
	                typeof interval === 'function'
	                    ? (
	                        rawTick = scale.getTicks()[i],
	                        !interval(rawTick, scale.getLabel(rawTick))
	                    )
	                    : i % (interval + 1)
	            );
	    };

	    /**
	     * @static
	     */
	    var getInterval = AxisBuilder.getInterval = function (model, labelInterval) {
	        var interval = model.get('interval');
	        if (interval == null || interval == 'auto') {
	            interval = labelInterval;
	        }
	        return interval;
	    };

	    module.exports = AxisBuilder;



/***/ },
/* 136 */
/***/ function(module, exports, __webpack_require__) {

	

	    var axisPointerModelHelper = __webpack_require__(137);

	    /**
	     * Base class of AxisView.
	     */
	    var AxisView = __webpack_require__(1).extendComponentView({

	        type: 'axis',

	        /**
	         * @private
	         */
	        _axisPointer: null,

	        /**
	         * @protected
	         * @type {string}
	         */
	        axisPointerClass: null,

	        /**
	         * @override
	         */
	        render: function (axisModel, ecModel, api, payload) {
	            // FIXME
	            // This process should proformed after coordinate systems updated
	            // (axis scale updated), and should be performed each time update.
	            // So put it here temporarily, although it is not appropriate to
	            // put a model-writing procedure in `view`.
	            this.axisPointerClass && axisPointerModelHelper.fixValue(axisModel);

	            AxisView.superApply(this, 'render', arguments);

	            updateAxisPointer(this, axisModel, ecModel, api, payload, true);
	        },

	        /**
	         * Action handler.
	         * @public
	         * @param {module:echarts/coord/cartesian/AxisModel} axisModel
	         * @param {module:echarts/model/Global} ecModel
	         * @param {module:echarts/ExtensionAPI} api
	         * @param {Object} payload
	         */
	        updateAxisPointer: function (axisModel, ecModel, api, payload, force) {
	            updateAxisPointer(this, axisModel, ecModel, api, payload, false);
	        },

	        /**
	         * @override
	         */
	        remove: function (ecModel, api) {
	            var axisPointer = this._axisPointer;
	            axisPointer && axisPointer.remove(api);
	            AxisView.superApply(this, 'remove', arguments);
	        },

	        /**
	         * @override
	         */
	        dispose: function (ecModel, api) {
	            disposeAxisPointer(this, api);
	            AxisView.superApply(this, 'dispose', arguments);
	        }

	    });

	    function updateAxisPointer(axisView, axisModel, ecModel, api, payload, forceRender) {
	        var Clazz = AxisView.getAxisPointerClass(axisView.axisPointerClass);
	        if (!Clazz) {
	            return;
	        }
	        var axisPointerModel = axisPointerModelHelper.getAxisPointerModel(axisModel);
	        axisPointerModel
	            ? (axisView._axisPointer || (axisView._axisPointer = new Clazz()))
	                .render(axisModel, axisPointerModel, api, forceRender)
	            : disposeAxisPointer(axisView, api);
	    }

	    function disposeAxisPointer(axisView, ecModel, api) {
	        var axisPointer = axisView._axisPointer;
	        axisPointer && axisPointer.dispose(ecModel, api);
	        axisView._axisPointer = null;
	    }

	    var axisPointerClazz = [];

	    AxisView.registerAxisPointerClass = function (type, clazz) {
	        if (true) {
	            if (axisPointerClazz[type]) {
	                throw new Error('axisPointer ' + type + ' exists');
	            }
	        }
	        axisPointerClazz[type] = clazz;
	    };

	    AxisView.getAxisPointerClass = function (type) {
	        return type && axisPointerClazz[type];
	    };

	    module.exports = AxisView;


/***/ },
/* 137 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);
	    var Model = __webpack_require__(12);
	    var each = zrUtil.each;
	    var curry = zrUtil.curry;

	    var helper = {};

	    // Build axisPointerModel, mergin tooltip.axisPointer model for each axis.
	    // allAxesInfo should be updated when setOption performed.
	    helper.collect = function (ecModel, api) {
	        var result = {
	            /**
	             * key: makeKey(axis.model)
	             * value: {
	             *      axis,
	             *      coordSys,
	             *      axisPointerModel,
	             *      triggerTooltip,
	             *      involveSeries,
	             *      snap,
	             *      seriesModels,
	             *      seriesDataCount
	             * }
	             */
	            axesInfo: {},
	            seriesInvolved: false,
	            /**
	             * key: makeKey(coordSys.model)
	             * value: Object: key makeKey(axis.model), value: axisInfo
	             */
	            coordSysAxesInfo: {},
	            coordSysMap: {}
	        };

	        collectAxesInfo(result, ecModel, api);

	        // Check seriesInvolved for performance, in case too many series in some chart.
	        result.seriesInvolved && collectSeriesInfo(result, ecModel);

	        return result;
	    };

	    function collectAxesInfo(result, ecModel, api) {
	        var globalTooltipModel = ecModel.getComponent('tooltip');
	        var globalAxisPointerModel = ecModel.getComponent('axisPointer');
	        // links can only be set on global.
	        var linksOption = globalAxisPointerModel.get('link', true) || [];
	        var linkGroups = [];

	        // Collect axes info.
	        each(api.getCoordinateSystems(), function (coordSys) {
	            // Some coordinate system do not support axes, like geo.
	            if (!coordSys.axisPointerEnabled) {
	                return;
	            }

	            var coordSysKey = makeKey(coordSys.model);
	            var axesInfoInCoordSys = result.coordSysAxesInfo[coordSysKey] = {};
	            result.coordSysMap[coordSysKey] = coordSys;

	            // Set tooltip (like 'cross') is a convienent way to show axisPointer
	            // for user. So we enable seting tooltip on coordSys model.
	            var coordSysModel = coordSys.model;
	            var baseTooltipModel = coordSysModel.getModel('tooltip', globalTooltipModel);

	            each(coordSys.getAxes(), curry(saveTooltipAxisInfo, false, null));

	            // If axis tooltip used, choose tooltip axis for each coordSys.
	            // Notice this case: coordSys is `grid` but not `cartesian2D` here.
	            if (coordSys.getTooltipAxes
	                && globalTooltipModel
	                // If tooltip.showContent is set as false, tooltip will not
	                // show but axisPointer will show as normal.
	                && baseTooltipModel.get('show')
	            ) {
	                // Compatible with previous logic. But series.tooltip.trigger: 'axis'
	                // or series.data[n].tooltip.trigger: 'axis' are not support any more.
	                var triggerAxis = baseTooltipModel.get('trigger') === 'axis';
	                var cross = baseTooltipModel.get('axisPointer.type') === 'cross';
	                var tooltipAxes = coordSys.getTooltipAxes(baseTooltipModel.get('axisPointer.axis'));
	                if (triggerAxis || cross) {
	                    each(tooltipAxes.baseAxes, curry(
	                        saveTooltipAxisInfo, cross ? 'cross' : true, triggerAxis
	                    ));
	                }
	                if (cross) {
	                    each(tooltipAxes.otherAxes, curry(saveTooltipAxisInfo, 'cross', false));
	                }
	            }

	            // fromTooltip: true | false | 'cross'
	            // triggerTooltip: true | false | null
	            function saveTooltipAxisInfo(fromTooltip, triggerTooltip, axis) {
	                var axisPointerModel = axis.model.getModel('axisPointer', globalAxisPointerModel);

	                var axisPointerShow = axisPointerModel.get('show');
	                if (!axisPointerShow || (
	                    axisPointerShow === 'auto'
	                    && !fromTooltip
	                    && !isHandleTrigger(axisPointerModel)
	                )) {
	                    return;
	                }

	                if (triggerTooltip == null) {
	                    triggerTooltip = axisPointerModel.get('triggerTooltip');
	                }

	                axisPointerModel = fromTooltip
	                    ? makeAxisPointerModel(
	                        axis, baseTooltipModel, globalAxisPointerModel, ecModel,
	                        fromTooltip, triggerTooltip
	                    )
	                    : axisPointerModel;

	                var snap = axisPointerModel.get('snap');
	                var key = makeKey(axis.model);
	                var involveSeries = triggerTooltip || snap || axis.type === 'category';

	                // If result.axesInfo[key] exist, override it (tooltip has higher priority).
	                var axisInfo = result.axesInfo[key] = {
	                    key: key,
	                    axis: axis,
	                    coordSys: coordSys,
	                    axisPointerModel: axisPointerModel,
	                    triggerTooltip: triggerTooltip,
	                    involveSeries: involveSeries,
	                    snap: snap,
	                    useHandle: isHandleTrigger(axisPointerModel),
	                    seriesModels: []
	                };
	                axesInfoInCoordSys[key] = axisInfo;
	                result.seriesInvolved |= involveSeries;

	                var groupIndex = getLinkGroupIndex(linksOption, axis);
	                if (groupIndex != null) {
	                    var linkGroup = linkGroups[groupIndex] || (linkGroups[groupIndex] = {axesInfo: {}});
	                    linkGroup.axesInfo[key] = axisInfo;
	                    linkGroup.mapper = linksOption[groupIndex].mapper;
	                    axisInfo.linkGroup = linkGroup;
	                }
	            }
	        });
	    }

	    function makeAxisPointerModel(
	        axis, baseTooltipModel, globalAxisPointerModel, ecModel, fromTooltip, triggerTooltip
	    ) {
	        var tooltipAxisPointerModel = baseTooltipModel.getModel('axisPointer');
	        var volatileOption = {};

	        each(
	            [
	                'type', 'snap', 'lineStyle', 'shadowStyle', 'label',
	                'animation', 'animationDurationUpdate', 'animationEasingUpdate', 'z'
	            ],
	            function (field) {
	                volatileOption[field] = zrUtil.clone(tooltipAxisPointerModel.get(field));
	            }
	        );

	        // category axis do not auto snap, otherwise some tick that do not
	        // has value can not be hovered. value/time/log axis default snap if
	        // triggered from tooltip and trigger tooltip.
	        volatileOption.snap = axis.type !== 'category' && !!triggerTooltip;

	        // Compatibel with previous behavior, tooltip axis do not show label by default.
	        // Only these properties can be overrided from tooltip to axisPointer.
	        if (tooltipAxisPointerModel.get('type') === 'cross') {
	            volatileOption.type = 'line';
	        }
	        var labelOption = volatileOption.label || (volatileOption.label = {});
	        // Follow the convention, do not show label when triggered by tooltip by default.
	        labelOption.show == null && (labelOption.show = false);

	        if (fromTooltip === 'cross') {
	            // When 'cross', both axes show labels.
	            labelOption.show = true;
	            // If triggerTooltip, this is a base axis, which should better not use cross style
	            // (cross style is dashed by default)
	            if (!triggerTooltip) {
	                var crossStyle = volatileOption.lineStyle = tooltipAxisPointerModel.get('crossStyle');
	                crossStyle && zrUtil.defaults(
	                    labelOption.textStyle || (labelOption.textStyle = {}),
	                    crossStyle.textStyle
	                );
	            }
	        }

	        return axis.model.getModel(
	            'axisPointer',
	            new Model(volatileOption, globalAxisPointerModel, ecModel)
	        );
	    }

	    function collectSeriesInfo(result, ecModel) {
	        // Prepare data for axis trigger
	        ecModel.eachSeries(function (seriesModel) {

	            // Notice this case: this coordSys is `cartesian2D` but not `grid`.
	            var coordSys = seriesModel.coordinateSystem;
	            var seriesTooltipTrigger = seriesModel.get('tooltip.trigger', true);
	            var seriesTooltipShow = seriesModel.get('tooltip.show', true);
	            if (!coordSys
	                || seriesTooltipTrigger === 'none'
	                || seriesTooltipTrigger === false
	                || seriesTooltipTrigger === 'item'
	                || seriesTooltipShow === false
	                || seriesModel.get('axisPointer.show', true) === false
	            ) {
	                return;
	            }

	            each(result.coordSysAxesInfo[makeKey(coordSys.model)], function (axisInfo) {
	                var axis = axisInfo.axis;
	                if (coordSys.getAxis(axis.dim) === axis) {
	                    axisInfo.seriesModels.push(seriesModel);
	                    axisInfo.seriesDataCount == null && (axisInfo.seriesDataCount = 0);
	                    axisInfo.seriesDataCount += seriesModel.getData().count();
	                }
	            });

	        }, this);
	    }

	    /**
	     * For example:
	     * {
	     *     axisPointer: {
	     *         links: [{
	     *             xAxisIndex: [2, 4],
	     *             yAxisIndex: 'all'
	     *         }, {
	     *             xAxisId: ['a5', 'a7'],
	     *             xAxisName: 'xxx'
	     *         }]
	     *     }
	     * }
	     */
	    function getLinkGroupIndex(linksOption, axis) {
	        var axisModel = axis.model;
	        var dim = axis.dim;
	        for (var i = 0; i < linksOption.length; i++) {
	            var linkOption = linksOption[i] || {};
	            if (checkPropInLink(linkOption[dim + 'AxisId'], axisModel.id)
	                || checkPropInLink(linkOption[dim + 'AxisIndex'], axisModel.componentIndex)
	                || checkPropInLink(linkOption[dim + 'AxisName'], axisModel.name)
	            ) {
	                return i;
	            }
	        }
	    }

	    function checkPropInLink(linkPropValue, axisPropValue) {
	        return linkPropValue === 'all'
	            || (zrUtil.isArray(linkPropValue) && zrUtil.indexOf(linkPropValue, axisPropValue) >= 0)
	            || linkPropValue === axisPropValue;
	    }

	    helper.fixValue = function (axisModel) {
	        var axisInfo = helper.getAxisInfo(axisModel);
	        if (!axisInfo) {
	            return;
	        }

	        var axisPointerModel = axisInfo.axisPointerModel;
	        var scale = axisInfo.axis.scale;
	        var option = axisPointerModel.option;
	        var status = axisPointerModel.get('status');
	        var value = axisPointerModel.get('value');

	        // Parse init value for category and time axis.
	        if (value != null) {
	            value = scale.parse(value);
	        }

	        var useHandle = isHandleTrigger(axisPointerModel);
	        // If `handle` used, `axisPointer` will always be displayed, so value
	        // and status should be initialized.
	        if (status == null) {
	            option.status = useHandle ? 'show' : 'hide';
	        }

	        var extent = scale.getExtent().slice();
	        extent[0] > extent[1] && extent.reverse();

	        if (// Pick a value on axis when initializing.
	            value == null
	            // If both `handle` and `dataZoom` are used, value may be out of axis extent,
	            // where we should re-pick a value to keep `handle` displaying normally.
	            || value > extent[1]
	        ) {
	            // Make handle displayed on the end of the axis when init, which looks better.
	            value = extent[1];
	        }
	        if (value < extent[0]) {
	            value = extent[0];
	        }

	        option.value = value;

	        if (useHandle) {
	            option.status = axisInfo.axis.scale.isBlank() ? 'hide' : 'show';
	        }
	    };

	    helper.getAxisInfo = function (axisModel) {
	        var coordSysAxesInfo = (axisModel.ecModel.getComponent('axisPointer') || {}).coordSysAxesInfo;
	        return coordSysAxesInfo && coordSysAxesInfo.axesInfo[makeKey(axisModel)];
	    };

	    helper.getAxisPointerModel = function (axisModel) {
	        var axisInfo = helper.getAxisInfo(axisModel);
	        return axisInfo && axisInfo.axisPointerModel;
	    };

	    function isHandleTrigger(axisPointerModel) {
	        return !!axisPointerModel.get('handle.show');
	    }

	    /**
	     * @param {module:echarts/model/Model} model
	     * @return {string} unique key
	     */
	    var makeKey = helper.makeKey = function (model) {
	        return model.type + '||' + model.id;
	    };

	    module.exports = helper;



/***/ },
/* 138 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);

	    var helper = {};

	    /**
	     * @param {Object} opt {labelInside}
	     * @return {Object} {
	     *  position, rotation, labelDirection, labelOffset,
	     *  tickDirection, labelRotate, labelInterval, z2
	     * }
	     */
	    helper.layout = function (gridModel, axisModel, opt) {
	        opt = opt || {};
	        var grid = gridModel.coordinateSystem;
	        var axis = axisModel.axis;
	        var layout = {};

	        var rawAxisPosition = axis.position;
	        var axisPosition = axis.onZero ? 'onZero' : rawAxisPosition;
	        var axisDim = axis.dim;

	        // [left, right, top, bottom]
	        var rect = grid.getRect();
	        var rectBound = [rect.x, rect.x + rect.width, rect.y, rect.y + rect.height];

	        var axisOffset = axisModel.get('offset') || 0;

	        var posMap = {
	            x: { top: rectBound[2] - axisOffset, bottom: rectBound[3] + axisOffset },
	            y: { left: rectBound[0] - axisOffset, right: rectBound[1] + axisOffset }
	        };

	        posMap.x.onZero = Math.max(Math.min(getZero('y'), posMap.x.bottom), posMap.x.top);
	        posMap.y.onZero = Math.max(Math.min(getZero('x'), posMap.y.right), posMap.y.left);

	        function getZero(dim, val) {
	            var theAxis = grid.getAxis(dim);
	            return theAxis.toGlobalCoord(theAxis.dataToCoord(0));
	        }

	        // Axis position
	        layout.position = [
	            axisDim === 'y' ? posMap.y[axisPosition] : rectBound[0],
	            axisDim === 'x' ? posMap.x[axisPosition] : rectBound[3]
	        ];

	        // Axis rotation
	        layout.rotation = Math.PI / 2 * (axisDim === 'x' ? 0 : 1);

	        // Tick and label direction, x y is axisDim
	        var dirMap = {top: -1, bottom: 1, left: -1, right: 1};

	        layout.labelDirection = layout.tickDirection = layout.nameDirection = dirMap[rawAxisPosition];
	        layout.labelOffset = axis.onZero ? posMap[axisDim][rawAxisPosition] - posMap[axisDim].onZero : 0;

	        if (axisModel.get('axisTick.inside')) {
	            layout.tickDirection = -layout.tickDirection;
	        }
	        if (zrUtil.retrieve(opt.labelInside, axisModel.get('axisLabel.inside'))) {
	            layout.labelDirection = -layout.labelDirection;
	        }

	        // Special label rotation
	        var labelRotate = axisModel.get('axisLabel.rotate');
	        layout.labelRotate = axisPosition === 'top' ? -labelRotate : labelRotate;

	        // label interval when auto mode.
	        layout.labelInterval = axis.getLabelInterval();

	        // Over splitLine and splitArea
	        layout.z2 = 1;

	        return layout;
	    };

	    module.exports = helper;



/***/ },
/* 139 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);

	    __webpack_require__(125);

	    __webpack_require__(140);
	    __webpack_require__(142);

	    var barLayoutGrid = __webpack_require__(145);
	    var echarts = __webpack_require__(1);

	    echarts.registerLayout(zrUtil.curry(barLayoutGrid, 'bar'));

	    // Visual coding for legend
	    echarts.registerVisual(function (ecModel) {
	        ecModel.eachSeriesByType('bar', function (seriesModel) {
	            var data = seriesModel.getData();
	            data.setVisual('legendSymbol', 'roundRect');
	        });
	    });

	    // In case developer forget to include grid component
	    __webpack_require__(124);


/***/ },
/* 140 */
/***/ function(module, exports, __webpack_require__) {

	

	    module.exports = __webpack_require__(141).extend({

	        type: 'series.bar',

	        dependencies: ['grid', 'polar'],

	        brushSelector: 'rect'
	    });


/***/ },
/* 141 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var SeriesModel = __webpack_require__(78);
	    var createListFromArray = __webpack_require__(109);

	    module.exports = SeriesModel.extend({

	        type: 'series.__base_bar__',

	        getInitialData: function (option, ecModel) {
	            return createListFromArray(option.data, this, ecModel);
	        },

	        getMarkerPosition: function (value) {
	            var coordSys = this.coordinateSystem;
	            if (coordSys) {
	                // PENDING if clamp ?
	                var pt = coordSys.dataToPoint(value, true);
	                var data = this.getData();
	                var offset = data.getLayout('offset');
	                var size = data.getLayout('size');
	                var offsetIndex = coordSys.getBaseAxis().isHorizontal() ? 0 : 1;
	                pt[offsetIndex] += offset + size / 2;
	                return pt;
	            }
	            return [NaN, NaN];
	        },

	        defaultOption: {
	            zlevel: 0,                  // 一级层叠
	            z: 2,                       // 二级层叠
	            coordinateSystem: 'cartesian2d',
	            legendHoverLink: true,
	            // stack: null

	            // Cartesian coordinate system
	            // xAxisIndex: 0,
	            // yAxisIndex: 0,

	            // 最小高度改为0
	            barMinHeight: 0,
	            // 最小角度为0，仅对极坐标系下的柱状图有效
	            barMinAngle: 0,
	            // cursor: null,

	            // barMaxWidth: null,
	            // 默认自适应
	            // barWidth: null,
	            // 柱间距离，默认为柱形宽度的30%，可设固定值
	            // barGap: '30%',
	            // 类目间柱形距离，默认为类目间距的20%，可设固定值
	            // barCategoryGap: '20%',
	            // label: {
	            //     normal: {
	            //         show: false
	            //     }
	            // },
	            itemStyle: {
	                normal: {
	                    // color: '各异'
	                },
	                emphasis: {}
	            }
	        }
	    });


/***/ },
/* 142 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var zrUtil = __webpack_require__(4);
	    var graphic = __webpack_require__(18);
	    var helper = __webpack_require__(143);

	    var BAR_BORDER_WIDTH_QUERY = ['itemStyle', 'normal', 'barBorderWidth'];

	    // FIXME
	    // Just for compatible with ec2.
	    zrUtil.extend(__webpack_require__(12).prototype, __webpack_require__(144));

	    var BarView = __webpack_require__(1).extendChartView({

	        type: 'bar',

	        render: function (seriesModel, ecModel, api) {
	            var coordinateSystemType = seriesModel.get('coordinateSystem');

	            if (coordinateSystemType === 'cartesian2d'
	                || coordinateSystemType === 'polar'
	            ) {
	                this._render(seriesModel, ecModel, api);
	            }
	            else if (true) {
	                console.warn('Only cartesian2d and polar supported for bar.');
	            }

	            return this.group;
	        },

	        dispose: zrUtil.noop,

	        _render: function (seriesModel, ecModel, api) {
	            var group = this.group;
	            var data = seriesModel.getData();
	            var oldData = this._data;

	            var coord = seriesModel.coordinateSystem;
	            var baseAxis = coord.getBaseAxis();
	            var isHorizontalOrRadial;

	            if (coord.type === 'cartesian2d') {
	                isHorizontalOrRadial = baseAxis.isHorizontal();
	            }
	            else if (coord.type === 'polar') {
	                isHorizontalOrRadial = baseAxis.dim === 'angle';
	            }

	            var animationModel = seriesModel.isAnimationEnabled() ? seriesModel : null;

	            data.diff(oldData)
	                .add(function (dataIndex) {
	                    if (!data.hasValue(dataIndex)) {
	                        return;
	                    }

	                    var itemModel = data.getItemModel(dataIndex);
	                    var layout = getLayout[coord.type](data, dataIndex, itemModel);
	                    var el = elementCreator[coord.type](
	                        data, dataIndex, itemModel, layout, isHorizontalOrRadial, animationModel
	                    );
	                    data.setItemGraphicEl(dataIndex, el);
	                    group.add(el);

	                    updateStyle(
	                        el, data, dataIndex, itemModel, layout,
	                        seriesModel, isHorizontalOrRadial, coord.type === 'polar'
	                    );
	                })
	                .update(function (newIndex, oldIndex) {
	                    var el = oldData.getItemGraphicEl(oldIndex);

	                    if (!data.hasValue(newIndex)) {
	                        group.remove(el);
	                        return;
	                    }

	                    var itemModel = data.getItemModel(newIndex);
	                    var layout = getLayout[coord.type](data, newIndex, itemModel);

	                    if (el) {
	                        graphic.updateProps(el, {shape: layout}, animationModel, newIndex);
	                    }
	                    else {
	                        el = elementCreator[coord.type](
	                            data, newIndex, itemModel, layout, isHorizontalOrRadial, animationModel, true
	                        );
	                    }

	                    data.setItemGraphicEl(newIndex, el);
	                    // Add back
	                    group.add(el);

	                    updateStyle(
	                        el, data, newIndex, itemModel, layout,
	                        seriesModel, isHorizontalOrRadial, coord.type === 'polar'
	                    );
	                })
	                .remove(function (dataIndex) {
	                    var el = oldData.getItemGraphicEl(dataIndex);
	                    if (coord.type === 'cartesian2d') {
	                        el && removeRect(dataIndex, animationModel, el);
	                    }
	                    else {
	                        el && removeSector(dataIndex, animationModel, el);
	                    }
	                })
	                .execute();

	            this._data = data;
	        },

	        remove: function (ecModel, api) {
	            var group = this.group;
	            var data = this._data;
	            if (ecModel.get('animation')) {
	                if (data) {
	                    data.eachItemGraphicEl(function (el) {
	                        if (el.type === 'sector') {
	                            removeSector(el.dataIndex, ecModel, el);
	                        }
	                        else {
	                            removeRect(el.dataIndex, ecModel, el);
	                        }
	                    });
	                }
	            }
	            else {
	                group.removeAll();
	            }
	        }
	    });

	    var elementCreator = {

	        cartesian2d: function (
	            data, dataIndex, itemModel, layout, isHorizontal,
	            animationModel, isUpdate
	        ) {
	            var rect = new graphic.Rect({shape: zrUtil.extend({}, layout)});

	            // Animation
	            if (animationModel) {
	                var rectShape = rect.shape;
	                var animateProperty = isHorizontal ? 'height' : 'width';
	                var animateTarget = {};
	                rectShape[animateProperty] = 0;
	                animateTarget[animateProperty] = layout[animateProperty];
	                graphic[isUpdate ? 'updateProps' : 'initProps'](rect, {
	                    shape: animateTarget
	                }, animationModel, dataIndex);
	            }

	            return rect;
	        },

	        polar: function (
	            data, dataIndex, itemModel, layout, isRadial,
	            animationModel, isUpdate
	        ) {
	            var sector = new graphic.Sector({shape: zrUtil.extend({}, layout)});

	            // Animation
	            if (animationModel) {
	                var sectorShape = sector.shape;
	                var animateProperty = isRadial ? 'r' : 'endAngle';
	                var animateTarget = {};
	                sectorShape[animateProperty] = isRadial ? 0 : layout.startAngle;
	                animateTarget[animateProperty] = layout[animateProperty];
	                graphic[isUpdate ? 'updateProps' : 'initProps'](sector, {
	                    shape: animateTarget
	                }, animationModel, dataIndex);
	            }

	            return sector;
	        }
	    };

	    function removeRect(dataIndex, animationModel, el) {
	        // Not show text when animating
	        el.style.text = '';
	        graphic.updateProps(el, {
	            shape: {
	                width: 0
	            }
	        }, animationModel, dataIndex, function () {
	            el.parent && el.parent.remove(el);
	        });
	    }

	    function removeSector(dataIndex, animationModel, el) {
	        // Not show text when animating
	        el.style.text = '';
	        graphic.updateProps(el, {
	            shape: {
	                r: el.shape.r0
	            }
	        }, animationModel, dataIndex, function () {
	            el.parent && el.parent.remove(el);
	        });
	    }

	    var getLayout = {
	        cartesian2d: function (data, dataIndex, itemModel) {
	            var layout = data.getItemLayout(dataIndex);
	            var fixedLineWidth = getLineWidth(itemModel, layout);

	            // fix layout with lineWidth
	            var signX = layout.width > 0 ? 1 : -1;
	            var signY = layout.height > 0 ? 1 : -1;
	            return {
	                x: layout.x + signX * fixedLineWidth / 2,
	                y: layout.y + signY * fixedLineWidth / 2,
	                width: layout.width - signX * fixedLineWidth,
	                height: layout.height - signY * fixedLineWidth
	            };
	        },

	        polar: function (data, dataIndex, itemModel) {
	            var layout = data.getItemLayout(dataIndex);
	            return {
	                cx: layout.cx,
	                cy: layout.cy,
	                r0: layout.r0,
	                r: layout.r,
	                startAngle: layout.startAngle,
	                endAngle: layout.endAngle
	            };
	        }
	    };

	    function updateStyle(
	        el, data, dataIndex, itemModel, layout, seriesModel, isHorizontal, isPolar
	    ) {
	        var color = data.getItemVisual(dataIndex, 'color');
	        var opacity = data.getItemVisual(dataIndex, 'opacity');
	        var itemStyleModel = itemModel.getModel('itemStyle.normal');
	        var hoverStyle = itemModel.getModel('itemStyle.emphasis').getBarItemStyle();

	        if (!isPolar) {
	            el.setShape('r', itemStyleModel.get('barBorderRadius') || 0);
	        }

	        el.useStyle(zrUtil.defaults(
	            {
	                fill: color,
	                opacity: opacity
	            },
	            itemStyleModel.getBarItemStyle()
	        ));

	        var cursorStyle = itemModel.getShallow('cursor');
	        cursorStyle && el.attr('cursor', cursorStyle);

	        var labelPositionOutside = isHorizontal
	            ? (layout.height > 0 ? 'bottom' : 'top')
	            : (layout.width > 0 ? 'left' : 'right');

	        if (!isPolar) {
	            helper.setLabel(
	                el.style, hoverStyle, itemModel, color,
	                seriesModel, dataIndex, labelPositionOutside
	            );
	        }

	        graphic.setHoverStyle(el, hoverStyle);
	    }

	    // In case width or height are too small.
	    function getLineWidth(itemModel, rawLayout) {
	        var lineWidth = itemModel.get(BAR_BORDER_WIDTH_QUERY) || 0;
	        return Math.min(lineWidth, Math.abs(rawLayout.width), Math.abs(rawLayout.height));
	    }

	    module.exports = BarView;


/***/ },
/* 143 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);
	    var graphic = __webpack_require__(18);

	    var helper = {};

	    helper.setLabel = function (
	        normalStyle, hoverStyle, itemModel, color, seriesModel, dataIndex, labelPositionOutside
	    ) {
	        var labelModel = itemModel.getModel('label.normal');
	        var hoverLabelModel = itemModel.getModel('label.emphasis');

	        if (labelModel.get('show')) {
	            setLabel(
	                normalStyle, labelModel, color,
	                zrUtil.retrieve(
	                    seriesModel.getFormattedLabel(dataIndex, 'normal'),
	                    seriesModel.getRawValue(dataIndex)
	                ),
	                labelPositionOutside
	            );
	        }
	        else {
	            normalStyle.text = '';
	        }

	        if (hoverLabelModel.get('show')) {
	            setLabel(
	                hoverStyle, hoverLabelModel, color,
	                zrUtil.retrieve(
	                    seriesModel.getFormattedLabel(dataIndex, 'emphasis'),
	                    seriesModel.getRawValue(dataIndex)
	                ),
	                labelPositionOutside
	            );
	        }
	        else {
	            hoverStyle.text = '';
	        }
	    };

	    function setLabel(style, model, color, labelText, labelPositionOutside) {
	        graphic.setText(style, model, color);
	        style.text = labelText;
	        if (style.textPosition === 'outside') {
	            style.textPosition = labelPositionOutside;
	        }
	    }

	    module.exports = helper;


/***/ },
/* 144 */
/***/ function(module, exports, __webpack_require__) {

	


	    var getBarItemStyle = __webpack_require__(15)(
	        [
	            ['fill', 'color'],
	            ['stroke', 'borderColor'],
	            ['lineWidth', 'borderWidth'],
	            // Compatitable with 2
	            ['stroke', 'barBorderColor'],
	            ['lineWidth', 'barBorderWidth'],
	            ['opacity'],
	            ['shadowBlur'],
	            ['shadowOffsetX'],
	            ['shadowOffsetY'],
	            ['shadowColor']
	        ]
	    );
	    module.exports = {
	        getBarItemStyle: function (excludes) {
	            var style = getBarItemStyle.call(this, excludes);
	            if (this.getBorderLineDash) {
	                var lineDash = this.getBorderLineDash();
	                lineDash && (style.lineDash = lineDash);
	            }
	            return style;
	        }
	    };


/***/ },
/* 145 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var zrUtil = __webpack_require__(4);
	    var numberUtil = __webpack_require__(7);
	    var parsePercent = numberUtil.parsePercent;

	    var STACK_PREFIX = '__ec_stack_';

	    function getSeriesStackId(seriesModel) {
	        return seriesModel.get('stack') || STACK_PREFIX + seriesModel.seriesIndex;
	    }

	    function getAxisKey(axis) {
	        return axis.dim + axis.index;
	    }

	    /**
	     * @param {Object} opt
	     * @param {module:echarts/coord/Axis} opt.axis Only support category axis currently.
	     * @param {number} opt.count Positive interger.
	     * @param {number} [opt.barWidth]
	     * @param {number} [opt.barMaxWidth]
	     * @param {number} [opt.barGap]
	     * @param {number} [opt.barCategoryGap]
	     * @return {Object} {width, offset, offsetCenter} If axis.type is not 'category', return undefined.
	     */
	    function getLayoutOnAxis(opt, api) {
	        var params = [];
	        var baseAxis = opt.axis;
	        var axisKey = 'axis0';

	        if (baseAxis.type !== 'category') {
	            return;
	        }
	        var bandWidth = baseAxis.getBandWidth();

	        for (var i = 0; i < opt.count || 0; i++) {
	            params.push(zrUtil.defaults({
	                bandWidth: bandWidth,
	                axisKey: axisKey,
	                stackId: STACK_PREFIX + i
	            }, opt));
	        }
	        var widthAndOffsets = doCalBarWidthAndOffset(params, api);

	        var result = [];
	        for (var i = 0; i < opt.count; i++) {
	            var item = widthAndOffsets[axisKey][STACK_PREFIX + i];
	            item.offsetCenter = item.offset + item.width / 2;
	            result.push(item);
	        }

	        return result;
	    }

	    function calBarWidthAndOffset(barSeries, api) {
	        var seriesInfoList = zrUtil.map(barSeries, function (seriesModel) {
	            var data = seriesModel.getData();
	            var cartesian = seriesModel.coordinateSystem;
	            var baseAxis = cartesian.getBaseAxis();
	            var axisExtent = baseAxis.getExtent();
	            var bandWidth = baseAxis.type === 'category'
	                ? baseAxis.getBandWidth()
	                : (Math.abs(axisExtent[1] - axisExtent[0]) / data.count());

	            var barWidth = parsePercent(
	                seriesModel.get('barWidth'), bandWidth
	            );
	            var barMaxWidth = parsePercent(
	                seriesModel.get('barMaxWidth'), bandWidth
	            );
	            var barGap = seriesModel.get('barGap');
	            var barCategoryGap = seriesModel.get('barCategoryGap');

	            return {
	                bandWidth: bandWidth,
	                barWidth: barWidth,
	                barMaxWidth: barMaxWidth,
	                barGap: barGap,
	                barCategoryGap: barCategoryGap,
	                axisKey: getAxisKey(baseAxis),
	                stackId: getSeriesStackId(seriesModel)
	            };
	        });

	        return doCalBarWidthAndOffset(seriesInfoList, api);
	    }

	    function doCalBarWidthAndOffset(seriesInfoList, api) {
	        // Columns info on each category axis. Key is cartesian name
	        var columnsMap = {};

	        zrUtil.each(seriesInfoList, function (seriesInfo, idx) {
	            var axisKey = seriesInfo.axisKey;
	            var bandWidth = seriesInfo.bandWidth;
	            var columnsOnAxis = columnsMap[axisKey] || {
	                bandWidth: bandWidth,
	                remainedWidth: bandWidth,
	                autoWidthCount: 0,
	                categoryGap: '20%',
	                gap: '30%',
	                stacks: {}
	            };
	            var stacks = columnsOnAxis.stacks;
	            columnsMap[axisKey] = columnsOnAxis;

	            var stackId = seriesInfo.stackId;

	            if (!stacks[stackId]) {
	                columnsOnAxis.autoWidthCount++;
	            }
	            stacks[stackId] = stacks[stackId] || {
	                width: 0,
	                maxWidth: 0
	            };

	            // Caution: In a single coordinate system, these barGrid attributes
	            // will be shared by series. Consider that they have default values,
	            // only the attributes set on the last series will work.
	            // Do not change this fact unless there will be a break change.

	            // TODO
	            var barWidth = seriesInfo.barWidth;
	            if (barWidth && !stacks[stackId].width) {
	                barWidth = Math.min(columnsOnAxis.remainedWidth, barWidth);
	                stacks[stackId].width = barWidth;
	                columnsOnAxis.remainedWidth -= barWidth;
	            }

	            var barMaxWidth = seriesInfo.barMaxWidth;
	            barMaxWidth && (stacks[stackId].maxWidth = barMaxWidth);
	            var barGap = seriesInfo.barGap;
	            (barGap != null) && (columnsOnAxis.gap = barGap);
	            var barCategoryGap = seriesInfo.barCategoryGap;
	            (barCategoryGap != null) && (columnsOnAxis.categoryGap = barCategoryGap);
	        });

	        var result = {};

	        zrUtil.each(columnsMap, function (columnsOnAxis, coordSysName) {

	            result[coordSysName] = {};

	            var stacks = columnsOnAxis.stacks;
	            var bandWidth = columnsOnAxis.bandWidth;
	            var categoryGap = parsePercent(columnsOnAxis.categoryGap, bandWidth);
	            var barGapPercent = parsePercent(columnsOnAxis.gap, 1);

	            var remainedWidth = columnsOnAxis.remainedWidth;
	            var autoWidthCount = columnsOnAxis.autoWidthCount;
	            var autoWidth = (remainedWidth - categoryGap)
	                / (autoWidthCount + (autoWidthCount - 1) * barGapPercent);
	            autoWidth = Math.max(autoWidth, 0);

	            // Find if any auto calculated bar exceeded maxBarWidth
	            zrUtil.each(stacks, function (column, stack) {
	                var maxWidth = column.maxWidth;
	                if (maxWidth && maxWidth < autoWidth) {
	                    maxWidth = Math.min(maxWidth, remainedWidth);
	                    if (column.width) {
	                        maxWidth = Math.min(maxWidth, column.width);
	                    }
	                    remainedWidth -= maxWidth;
	                    column.width = maxWidth;
	                    autoWidthCount--;
	                }
	            });

	            // Recalculate width again
	            autoWidth = (remainedWidth - categoryGap)
	                / (autoWidthCount + (autoWidthCount - 1) * barGapPercent);
	            autoWidth = Math.max(autoWidth, 0);

	            var widthSum = 0;
	            var lastColumn;
	            zrUtil.each(stacks, function (column, idx) {
	                if (!column.width) {
	                    column.width = autoWidth;
	                }
	                lastColumn = column;
	                widthSum += column.width * (1 + barGapPercent);
	            });
	            if (lastColumn) {
	                widthSum -= lastColumn.width * barGapPercent;
	            }

	            var offset = -widthSum / 2;
	            zrUtil.each(stacks, function (column, stackId) {
	                result[coordSysName][stackId] = result[coordSysName][stackId] || {
	                    offset: offset,
	                    width: column.width
	                };

	                offset += column.width * (1 + barGapPercent);
	            });
	        });

	        return result;
	    }

	    /**
	     * @param {string} seriesType
	     * @param {module:echarts/model/Global} ecModel
	     * @param {module:echarts/ExtensionAPI} api
	     */
	    function barLayoutGrid(seriesType, ecModel, api) {

	        var barWidthAndOffset = calBarWidthAndOffset(
	            zrUtil.filter(
	                ecModel.getSeriesByType(seriesType),
	                function (seriesModel) {
	                    return !ecModel.isSeriesFiltered(seriesModel)
	                        && seriesModel.coordinateSystem
	                        && seriesModel.coordinateSystem.type === 'cartesian2d';
	                }
	            )
	        );

	        var lastStackCoords = {};
	        var lastStackCoordsOrigin = {};

	        ecModel.eachSeriesByType(seriesType, function (seriesModel) {

	            // Check series coordinate, do layout for cartesian2d only
	            if (seriesModel.coordinateSystem.type !== 'cartesian2d') {
	                return;
	            }

	            var data = seriesModel.getData();
	            var cartesian = seriesModel.coordinateSystem;
	            var baseAxis = cartesian.getBaseAxis();

	            var stackId = getSeriesStackId(seriesModel);
	            var columnLayoutInfo = barWidthAndOffset[getAxisKey(baseAxis)][stackId];
	            var columnOffset = columnLayoutInfo.offset;
	            var columnWidth = columnLayoutInfo.width;
	            var valueAxis = cartesian.getOtherAxis(baseAxis);

	            var barMinHeight = seriesModel.get('barMinHeight') || 0;

	            var valueAxisStart = baseAxis.onZero
	                ? valueAxis.toGlobalCoord(valueAxis.dataToCoord(0))
	                : valueAxis.getGlobalExtent()[0];

	            var coords = cartesian.dataToPoints(data, true);
	            lastStackCoords[stackId] = lastStackCoords[stackId] || [];
	            lastStackCoordsOrigin[stackId] = lastStackCoordsOrigin[stackId] || []; // Fix #4243

	            data.setLayout({
	                offset: columnOffset,
	                size: columnWidth
	            });

	            data.each(valueAxis.dim, function (value, idx) {
	                if (isNaN(value)) {
	                    return;
	                }

	                if (!lastStackCoords[stackId][idx]) {
	                    lastStackCoords[stackId][idx] = {
	                        p: valueAxisStart, // Positive stack
	                        n: valueAxisStart  // Negative stack
	                    };
	                    lastStackCoordsOrigin[stackId][idx] = {
	                        p: valueAxisStart, // Positive stack
	                        n: valueAxisStart  // Negative stack
	                    };
	                }
	                var sign = value >= 0 ? 'p' : 'n';
	                var coord = coords[idx];
	                var lastCoord = lastStackCoords[stackId][idx][sign];
	                var lastCoordOrigin = lastStackCoordsOrigin[stackId][idx][sign];
	                var x;
	                var y;
	                var width;
	                var height;

	                if (valueAxis.isHorizontal()) {
	                    x = lastCoord;
	                    y = coord[1] + columnOffset;
	                    width = coord[0] - lastCoordOrigin;
	                    height = columnWidth;

	                    lastStackCoordsOrigin[stackId][idx][sign] += width;
	                    if (Math.abs(width) < barMinHeight) {
	                        width = (width < 0 ? -1 : 1) * barMinHeight;
	                    }
	                    lastStackCoords[stackId][idx][sign] += width;
	                }
	                else {
	                    x = coord[0] + columnOffset;
	                    y = lastCoord;
	                    width = columnWidth;
	                    height = coord[1] - lastCoordOrigin;

	                    lastStackCoordsOrigin[stackId][idx][sign] += height;
	                    if (Math.abs(height) < barMinHeight) {
	                        // Include zero to has a positive bar
	                        height = (height <= 0 ? -1 : 1) * barMinHeight;
	                    }
	                    lastStackCoords[stackId][idx][sign] += height;
	                }

	                data.setItemLayout(idx, {
	                    x: x,
	                    y: y,
	                    width: width,
	                    height: height
	                });
	            }, true);

	        }, this);
	    }

	    barLayoutGrid.getLayoutOnAxis = getLayoutOnAxis;

	    module.exports = barLayoutGrid;


/***/ },
/* 146 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);
	    var echarts = __webpack_require__(1);

	    __webpack_require__(147);
	    __webpack_require__(149);

	    __webpack_require__(150)('pie', [{
	        type: 'pieToggleSelect',
	        event: 'pieselectchanged',
	        method: 'toggleSelected'
	    }, {
	        type: 'pieSelect',
	        event: 'pieselected',
	        method: 'select'
	    }, {
	        type: 'pieUnSelect',
	        event: 'pieunselected',
	        method: 'unSelect'
	    }]);

	    echarts.registerVisual(zrUtil.curry(__webpack_require__(151), 'pie'));

	    echarts.registerLayout(zrUtil.curry(
	        __webpack_require__(152), 'pie'
	    ));

	    echarts.registerProcessor(zrUtil.curry(__webpack_require__(154), 'pie'));


/***/ },
/* 147 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var List = __webpack_require__(98);
	    var zrUtil = __webpack_require__(4);
	    var modelUtil = __webpack_require__(5);
	    var numberUtil = __webpack_require__(7);
	    var completeDimensions = __webpack_require__(110);

	    var dataSelectableMixin = __webpack_require__(148);

	    var PieSeries = __webpack_require__(1).extendSeriesModel({

	        type: 'series.pie',

	        // Overwrite
	        init: function (option) {
	            PieSeries.superApply(this, 'init', arguments);

	            // Enable legend selection for each data item
	            // Use a function instead of direct access because data reference may changed
	            this.legendDataProvider = function () {
	                return this.getRawData();
	            };

	            this.updateSelectedMap(option.data);

	            this._defaultLabelLine(option);
	        },

	        // Overwrite
	        mergeOption: function (newOption) {
	            PieSeries.superCall(this, 'mergeOption', newOption);
	            this.updateSelectedMap(this.option.data);
	        },

	        getInitialData: function (option, ecModel) {
	            var dimensions = completeDimensions(['value'], option.data);
	            var list = new List(dimensions, this);
	            list.initData(option.data);
	            return list;
	        },

	        // Overwrite
	        getDataParams: function (dataIndex) {
	            var data = this.getData();
	            var params = PieSeries.superCall(this, 'getDataParams', dataIndex);
	            // FIXME toFixed?

	            var valueList = [];
	            data.each('value', function (value) {
	                valueList.push(value);
	            });

	            params.percent = numberUtil.getPercentWithPrecision(
	                valueList,
	                dataIndex,
	                data.hostModel.get('percentPrecision')
	            );

	            params.$vars.push('percent');
	            return params;
	        },

	        _defaultLabelLine: function (option) {
	            // Extend labelLine emphasis
	            modelUtil.defaultEmphasis(option.labelLine, ['show']);

	            var labelLineNormalOpt = option.labelLine.normal;
	            var labelLineEmphasisOpt = option.labelLine.emphasis;
	            // Not show label line if `label.normal.show = false`
	            labelLineNormalOpt.show = labelLineNormalOpt.show
	                && option.label.normal.show;
	            labelLineEmphasisOpt.show = labelLineEmphasisOpt.show
	                && option.label.emphasis.show;
	        },

	        defaultOption: {
	            zlevel: 0,
	            z: 2,
	            legendHoverLink: true,

	            hoverAnimation: true,
	            // 默认全局居中
	            center: ['50%', '50%'],
	            radius: [0, '75%'],
	            // 默认顺时针
	            clockwise: true,
	            startAngle: 90,
	            // 最小角度改为0
	            minAngle: 0,
	            // 选中是扇区偏移量
	            selectedOffset: 10,

	            // If use strategy to avoid label overlapping
	            avoidLabelOverlap: true,
	            // 选择模式，默认关闭，可选single，multiple
	            // selectedMode: false,
	            // 南丁格尔玫瑰图模式，'radius'（半径） | 'area'（面积）
	            // roseType: null,

	            percentPrecision: 2,

	            // If still show when all data zero.
	            stillShowZeroSum: true,

	            // cursor: null,

	            label: {
	                normal: {
	                    // If rotate around circle
	                    rotate: false,
	                    show: true,
	                    // 'outer', 'inside', 'center'
	                    position: 'outer'
	                    // formatter: 标签文本格式器，同Tooltip.formatter，不支持异步回调
	                    // textStyle: null      // 默认使用全局文本样式，详见TEXTSTYLE
	                    // distance: 当position为inner时有效，为label位置到圆心的距离与圆半径(环状图为内外半径和)的比例系数
	                },
	                emphasis: {}
	            },
	            // Enabled when label.normal.position is 'outer'
	            labelLine: {
	                normal: {
	                    show: true,
	                    // 引导线两段中的第一段长度
	                    length: 15,
	                    // 引导线两段中的第二段长度
	                    length2: 15,
	                    smooth: false,
	                    lineStyle: {
	                        // color: 各异,
	                        width: 1,
	                        type: 'solid'
	                    }
	                }
	            },
	            itemStyle: {
	                normal: {
	                    borderWidth: 1
	                },
	                emphasis: {}
	            },

	            // Animation type canbe expansion, scale
	            animationType: 'expansion',

	            animationEasing: 'cubicOut',

	            data: []
	        }
	    });

	    zrUtil.mixin(PieSeries, dataSelectableMixin);

	    module.exports = PieSeries;


/***/ },
/* 148 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * Data selectable mixin for chart series.
	 * To eanble data select, option of series must have `selectedMode`.
	 * And each data item will use `selected` to toggle itself selected status
	 *
	 * @module echarts/chart/helper/DataSelectable
	 */


	    var zrUtil = __webpack_require__(4);

	    module.exports = {

	        updateSelectedMap: function (targetList) {
	            this._selectTargetMap = zrUtil.reduce(targetList || [], function (targetMap, target) {
	                targetMap.set(target.name, target);
	                return targetMap;
	            }, zrUtil.createHashMap());
	        },
	        /**
	         * @param {string} name
	         */
	        // PENGING If selectedMode is null ?
	        select: function (name) {
	            var targetMap = this._selectTargetMap;
	            var target = targetMap.get(name);
	            var selectedMode = this.get('selectedMode');
	            if (selectedMode === 'single') {
	                targetMap.each(function (target) {
	                    target.selected = false;
	                });
	            }
	            target && (target.selected = true);
	        },

	        /**
	         * @param {string} name
	         */
	        unSelect: function (name) {
	            var target = this._selectTargetMap.get(name);
	            // var selectedMode = this.get('selectedMode');
	            // selectedMode !== 'single' && target && (target.selected = false);
	            target && (target.selected = false);
	        },

	        /**
	         * @param {string} name
	         */
	        toggleSelected: function (name) {
	            var target = this._selectTargetMap.get(name);
	            if (target != null) {
	                this[target.selected ? 'unSelect' : 'select'](name);
	                return target.selected;
	            }
	        },

	        /**
	         * @param {string} name
	         */
	        isSelected: function (name) {
	            var target = this._selectTargetMap.get(name);
	            return target && target.selected;
	        }
	    };


/***/ },
/* 149 */
/***/ function(module, exports, __webpack_require__) {

	

	    var graphic = __webpack_require__(18);
	    var zrUtil = __webpack_require__(4);

	    /**
	     * @param {module:echarts/model/Series} seriesModel
	     * @param {boolean} hasAnimation
	     * @inner
	     */
	    function updateDataSelected(uid, seriesModel, hasAnimation, api) {
	        var data = seriesModel.getData();
	        var dataIndex = this.dataIndex;
	        var name = data.getName(dataIndex);
	        var selectedOffset = seriesModel.get('selectedOffset');

	        api.dispatchAction({
	            type: 'pieToggleSelect',
	            from: uid,
	            name: name,
	            seriesId: seriesModel.id
	        });

	        data.each(function (idx) {
	            toggleItemSelected(
	                data.getItemGraphicEl(idx),
	                data.getItemLayout(idx),
	                seriesModel.isSelected(data.getName(idx)),
	                selectedOffset,
	                hasAnimation
	            );
	        });
	    }

	    /**
	     * @param {module:zrender/graphic/Sector} el
	     * @param {Object} layout
	     * @param {boolean} isSelected
	     * @param {number} selectedOffset
	     * @param {boolean} hasAnimation
	     * @inner
	     */
	    function toggleItemSelected(el, layout, isSelected, selectedOffset, hasAnimation) {
	        var midAngle = (layout.startAngle + layout.endAngle) / 2;

	        var dx = Math.cos(midAngle);
	        var dy = Math.sin(midAngle);

	        var offset = isSelected ? selectedOffset : 0;
	        var position = [dx * offset, dy * offset];

	        hasAnimation
	            // animateTo will stop revious animation like update transition
	            ? el.animate()
	                .when(200, {
	                    position: position
	                })
	                .start('bounceOut')
	            : el.attr('position', position);
	    }

	    /**
	     * Piece of pie including Sector, Label, LabelLine
	     * @constructor
	     * @extends {module:zrender/graphic/Group}
	     */
	    function PiePiece(data, idx) {

	        graphic.Group.call(this);

	        var sector = new graphic.Sector({
	            z2: 2
	        });
	        var polyline = new graphic.Polyline();
	        var text = new graphic.Text();
	        this.add(sector);
	        this.add(polyline);
	        this.add(text);

	        this.updateData(data, idx, true);

	        // Hover to change label and labelLine
	        function onEmphasis() {
	            polyline.ignore = polyline.hoverIgnore;
	            text.ignore = text.hoverIgnore;
	        }
	        function onNormal() {
	            polyline.ignore = polyline.normalIgnore;
	            text.ignore = text.normalIgnore;
	        }
	        this.on('emphasis', onEmphasis)
	            .on('normal', onNormal)
	            .on('mouseover', onEmphasis)
	            .on('mouseout', onNormal);
	    }

	    var piePieceProto = PiePiece.prototype;

	    function getLabelStyle(data, idx, state, labelModel, labelPosition) {
	        var textStyleModel = labelModel.getModel('textStyle');
	        var isLabelInside = labelPosition === 'inside' || labelPosition === 'inner';
	        return {
	            fill: textStyleModel.getTextColor()
	                || (isLabelInside ? '#fff' : data.getItemVisual(idx, 'color')),
	            opacity: data.getItemVisual(idx, 'opacity'),
	            textFont: textStyleModel.getFont(),
	            text: zrUtil.retrieve(
	                data.hostModel.getFormattedLabel(idx, state), data.getName(idx)
	            )
	        };
	    }

	    piePieceProto.updateData = function (data, idx, firstCreate) {

	        var sector = this.childAt(0);

	        var seriesModel = data.hostModel;
	        var itemModel = data.getItemModel(idx);
	        var layout = data.getItemLayout(idx);
	        var sectorShape = zrUtil.extend({}, layout);
	        sectorShape.label = null;

	        if (firstCreate) {
	            sector.setShape(sectorShape);

	            var animationType = seriesModel.getShallow('animationType');
	            if (animationType === 'scale') {
	                sector.shape.r = layout.r0;
	                graphic.initProps(sector, {
	                    shape: {
	                        r: layout.r
	                    }
	                }, seriesModel, idx);
	            }
	            // Expansion
	            else {
	                sector.shape.endAngle = layout.startAngle;
	                graphic.updateProps(sector, {
	                    shape: {
	                        endAngle: layout.endAngle
	                    }
	                }, seriesModel, idx);
	            }

	        }
	        else {
	            graphic.updateProps(sector, {
	                shape: sectorShape
	            }, seriesModel, idx);
	        }

	        // Update common style
	        var itemStyleModel = itemModel.getModel('itemStyle');
	        var visualColor = data.getItemVisual(idx, 'color');

	        sector.useStyle(
	            zrUtil.defaults(
	                {
	                    lineJoin: 'bevel',
	                    fill: visualColor
	                },
	                itemStyleModel.getModel('normal').getItemStyle()
	            )
	        );
	        sector.hoverStyle = itemStyleModel.getModel('emphasis').getItemStyle();

	        var cursorStyle = itemModel.getShallow('cursor');
	        cursorStyle && sector.attr('cursor', cursorStyle);

	        // Toggle selected
	        toggleItemSelected(
	            this,
	            data.getItemLayout(idx),
	            itemModel.get('selected'),
	            seriesModel.get('selectedOffset'),
	            seriesModel.get('animation')
	        );

	        function onEmphasis() {
	            // Sector may has animation of updating data. Force to move to the last frame
	            // Or it may stopped on the wrong shape
	            sector.stopAnimation(true);
	            sector.animateTo({
	                shape: {
	                    r: layout.r + 10
	                }
	            }, 300, 'elasticOut');
	        }
	        function onNormal() {
	            sector.stopAnimation(true);
	            sector.animateTo({
	                shape: {
	                    r: layout.r
	                }
	            }, 300, 'elasticOut');
	        }
	        sector.off('mouseover').off('mouseout').off('emphasis').off('normal');
	        if (itemModel.get('hoverAnimation') && seriesModel.isAnimationEnabled()) {
	            sector
	                .on('mouseover', onEmphasis)
	                .on('mouseout', onNormal)
	                .on('emphasis', onEmphasis)
	                .on('normal', onNormal);
	        }

	        this._updateLabel(data, idx);

	        graphic.setHoverStyle(this);
	    };

	    piePieceProto._updateLabel = function (data, idx) {

	        var labelLine = this.childAt(1);
	        var labelText = this.childAt(2);

	        var seriesModel = data.hostModel;
	        var itemModel = data.getItemModel(idx);
	        var layout = data.getItemLayout(idx);
	        var labelLayout = layout.label;
	        var visualColor = data.getItemVisual(idx, 'color');

	        graphic.updateProps(labelLine, {
	            shape: {
	                points: labelLayout.linePoints || [
	                    [labelLayout.x, labelLayout.y], [labelLayout.x, labelLayout.y], [labelLayout.x, labelLayout.y]
	                ]
	            }
	        }, seriesModel, idx);

	        graphic.updateProps(labelText, {
	            style: {
	                x: labelLayout.x,
	                y: labelLayout.y
	            }
	        }, seriesModel, idx);
	        labelText.attr({
	            style: {
	                textVerticalAlign: labelLayout.verticalAlign,
	                textAlign: labelLayout.textAlign,
	                textFont: labelLayout.font
	            },
	            rotation: labelLayout.rotation,
	            origin: [labelLayout.x, labelLayout.y],
	            z2: 10
	        });

	        var labelModel = itemModel.getModel('label.normal');
	        var labelHoverModel = itemModel.getModel('label.emphasis');
	        var labelLineModel = itemModel.getModel('labelLine.normal');
	        var labelLineHoverModel = itemModel.getModel('labelLine.emphasis');
	        var labelPosition = labelModel.get('position') || labelHoverModel.get('position');

	        labelText.setStyle(getLabelStyle(data, idx, 'normal', labelModel, labelPosition));

	        labelText.ignore = labelText.normalIgnore = !labelModel.get('show');
	        labelText.hoverIgnore = !labelHoverModel.get('show');

	        labelLine.ignore = labelLine.normalIgnore = !labelLineModel.get('show');
	        labelLine.hoverIgnore = !labelLineHoverModel.get('show');

	        // Default use item visual color
	        labelLine.setStyle({
	            stroke: visualColor,
	            opacity: data.getItemVisual(idx, 'opacity')
	        });
	        labelLine.setStyle(labelLineModel.getModel('lineStyle').getLineStyle());

	        labelText.hoverStyle = getLabelStyle(data, idx, 'emphasis', labelHoverModel, labelPosition);
	        labelLine.hoverStyle = labelLineHoverModel.getModel('lineStyle').getLineStyle();

	        var smooth = labelLineModel.get('smooth');
	        if (smooth && smooth === true) {
	            smooth = 0.4;
	        }
	        labelLine.setShape({
	            smooth: smooth
	        });
	    };

	    zrUtil.inherits(PiePiece, graphic.Group);


	    // Pie view
	    var Pie = __webpack_require__(80).extend({

	        type: 'pie',

	        init: function () {
	            var sectorGroup = new graphic.Group();
	            this._sectorGroup = sectorGroup;
	        },

	        render: function (seriesModel, ecModel, api, payload) {
	            if (payload && (payload.from === this.uid)) {
	                return;
	            }

	            var data = seriesModel.getData();
	            var oldData = this._data;
	            var group = this.group;

	            var hasAnimation = ecModel.get('animation');
	            var isFirstRender = !oldData;
	            var animationType = seriesModel.get('animationType');

	            var onSectorClick = zrUtil.curry(
	                updateDataSelected, this.uid, seriesModel, hasAnimation, api
	            );

	            var selectedMode = seriesModel.get('selectedMode');

	            data.diff(oldData)
	                .add(function (idx) {
	                    var piePiece = new PiePiece(data, idx);
	                    // Default expansion animation
	                    if (isFirstRender && animationType !== 'scale') {
	                        piePiece.eachChild(function (child) {
	                            child.stopAnimation(true);
	                        });
	                    }

	                    selectedMode && piePiece.on('click', onSectorClick);

	                    data.setItemGraphicEl(idx, piePiece);

	                    group.add(piePiece);
	                })
	                .update(function (newIdx, oldIdx) {
	                    var piePiece = oldData.getItemGraphicEl(oldIdx);

	                    piePiece.updateData(data, newIdx);

	                    piePiece.off('click');
	                    selectedMode && piePiece.on('click', onSectorClick);
	                    group.add(piePiece);
	                    data.setItemGraphicEl(newIdx, piePiece);
	                })
	                .remove(function (idx) {
	                    var piePiece = oldData.getItemGraphicEl(idx);
	                    group.remove(piePiece);
	                })
	                .execute();

	            if (
	                hasAnimation && isFirstRender && data.count() > 0
	                // Default expansion animation
	                && animationType !== 'scale'
	            ) {
	                var shape = data.getItemLayout(0);
	                var r = Math.max(api.getWidth(), api.getHeight()) / 2;

	                var removeClipPath = zrUtil.bind(group.removeClipPath, group);
	                group.setClipPath(this._createClipPath(
	                    shape.cx, shape.cy, r, shape.startAngle, shape.clockwise, removeClipPath, seriesModel
	                ));
	            }

	            this._data = data;
	        },

	        dispose: function () {},

	        _createClipPath: function (
	            cx, cy, r, startAngle, clockwise, cb, seriesModel
	        ) {
	            var clipPath = new graphic.Sector({
	                shape: {
	                    cx: cx,
	                    cy: cy,
	                    r0: 0,
	                    r: r,
	                    startAngle: startAngle,
	                    endAngle: startAngle,
	                    clockwise: clockwise
	                }
	            });

	            graphic.initProps(clipPath, {
	                shape: {
	                    endAngle: startAngle + (clockwise ? 1 : -1) * Math.PI * 2
	                }
	            }, seriesModel, cb);

	            return clipPath;
	        },

	        /**
	         * @implement
	         */
	        containPoint: function (point, seriesModel) {
	            var data = seriesModel.getData();
	            var itemLayout = data.getItemLayout(0);
	            if (itemLayout) {
	                var dx = point[0] - itemLayout.cx;
	                var dy = point[1] - itemLayout.cy;
	                var radius = Math.sqrt(dx * dx + dy * dy);
	                return radius <= itemLayout.r && radius >= itemLayout.r0;
	            }
	        }

	    });

	    module.exports = Pie;


/***/ },
/* 150 */
/***/ function(module, exports, __webpack_require__) {

	
	    var echarts = __webpack_require__(1);
	    var zrUtil = __webpack_require__(4);
	    module.exports = function (seriesType, actionInfos) {
	        zrUtil.each(actionInfos, function (actionInfo) {
	            actionInfo.update = 'updateView';
	            /**
	             * @payload
	             * @property {string} seriesName
	             * @property {string} name
	             */
	            echarts.registerAction(actionInfo, function (payload, ecModel) {
	                var selected = {};
	                ecModel.eachComponent(
	                    {mainType: 'series', subType: seriesType, query: payload},
	                    function (seriesModel) {
	                        if (seriesModel[actionInfo.method]) {
	                            seriesModel[actionInfo.method](payload.name);
	                        }
	                        var data = seriesModel.getData();
	                        // Create selected map
	                        data.each(function (idx) {
	                            var name = data.getName(idx);
	                            selected[name] = seriesModel.isSelected(name) || false;
	                        });
	                    }
	                );
	                return {
	                    name: payload.name,
	                    selected: selected
	                };
	            });
	        });
	    };


/***/ },
/* 151 */
/***/ function(module, exports) {

	// Pick color from palette for each data item.
	// Applicable for charts that require applying color palette
	// in data level (like pie, funnel, chord).


	    module.exports = function (seriesType, ecModel) {
	        // Pie and funnel may use diferrent scope
	        var paletteScope = {};
	        ecModel.eachRawSeriesByType(seriesType, function (seriesModel) {
	            var dataAll = seriesModel.getRawData();
	            var idxMap = {};
	            if (!ecModel.isSeriesFiltered(seriesModel)) {
	                var data = seriesModel.getData();
	                data.each(function (idx) {
	                    var rawIdx = data.getRawIndex(idx);
	                    idxMap[rawIdx] = idx;
	                });
	                dataAll.each(function (rawIdx) {
	                    var filteredIdx = idxMap[rawIdx];

	                    // If series.itemStyle.normal.color is a function. itemVisual may be encoded
	                    var singleDataColor = filteredIdx != null
	                        && data.getItemVisual(filteredIdx, 'color', true);

	                    if (!singleDataColor) {
	                        // FIXME Performance
	                        var itemModel = dataAll.getItemModel(rawIdx);
	                        var color = itemModel.get('itemStyle.normal.color')
	                            || seriesModel.getColorFromPalette(dataAll.getName(rawIdx), paletteScope);
	                        // Legend may use the visual info in data before processed
	                        dataAll.setItemVisual(rawIdx, 'color', color);

	                        // Data is not filtered
	                        if (filteredIdx != null) {
	                            data.setItemVisual(filteredIdx, 'color', color);
	                        }
	                    }
	                    else {
	                        // Set data all color for legend
	                        dataAll.setItemVisual(rawIdx, 'color', singleDataColor);
	                    }
	                });
	            }
	        });
	    };


/***/ },
/* 152 */
/***/ function(module, exports, __webpack_require__) {

	

	    var numberUtil = __webpack_require__(7);
	    var parsePercent = numberUtil.parsePercent;
	    var labelLayout = __webpack_require__(153);
	    var zrUtil = __webpack_require__(4);

	    var PI2 = Math.PI * 2;
	    var RADIAN = Math.PI / 180;

	    module.exports = function (seriesType, ecModel, api, payload) {
	        ecModel.eachSeriesByType(seriesType, function (seriesModel) {
	            var center = seriesModel.get('center');
	            var radius = seriesModel.get('radius');

	            if (!zrUtil.isArray(radius)) {
	                radius = [0, radius];
	            }
	            if (!zrUtil.isArray(center)) {
	                center = [center, center];
	            }

	            var width = api.getWidth();
	            var height = api.getHeight();
	            var size = Math.min(width, height);
	            var cx = parsePercent(center[0], width);
	            var cy = parsePercent(center[1], height);
	            var r0 = parsePercent(radius[0], size / 2);
	            var r = parsePercent(radius[1], size / 2);

	            var data = seriesModel.getData();

	            var startAngle = -seriesModel.get('startAngle') * RADIAN;

	            var minAngle = seriesModel.get('minAngle') * RADIAN;

	            var validDataCount = 0;
	            data.each('value', function (value) {
	                !isNaN(value) && validDataCount++;
	            });

	            var sum = data.getSum('value');
	            // Sum may be 0
	            var unitRadian = Math.PI / (sum || validDataCount) * 2;

	            var clockwise = seriesModel.get('clockwise');

	            var roseType = seriesModel.get('roseType');
	            var stillShowZeroSum = seriesModel.get('stillShowZeroSum');

	            // [0...max]
	            var extent = data.getDataExtent('value');
	            extent[0] = 0;

	            // In the case some sector angle is smaller than minAngle
	            var restAngle = PI2;
	            var valueSumLargerThanMinAngle = 0;

	            var currentAngle = startAngle;
	            var dir = clockwise ? 1 : -1;

	            data.each('value', function (value, idx) {
	                var angle;
	                if (isNaN(value)) {
	                    data.setItemLayout(idx, {
	                        angle: NaN,
	                        startAngle: NaN,
	                        endAngle: NaN,
	                        clockwise: clockwise,
	                        cx: cx,
	                        cy: cy,
	                        r0: r0,
	                        r: roseType
	                            ? NaN
	                            : r
	                    });
	                    return;
	                }

	                // FIXME 兼容 2.0 但是 roseType 是 area 的时候才是这样？
	                if (roseType !== 'area') {
	                    angle = (sum === 0 && stillShowZeroSum)
	                        ? unitRadian : (value * unitRadian);
	                }
	                else {
	                    angle = PI2 / validDataCount;
	                }

	                if (angle < minAngle) {
	                    angle = minAngle;
	                    restAngle -= minAngle;
	                }
	                else {
	                    valueSumLargerThanMinAngle += value;
	                }

	                var endAngle = currentAngle + dir * angle;
	                data.setItemLayout(idx, {
	                    angle: angle,
	                    startAngle: currentAngle,
	                    endAngle: endAngle,
	                    clockwise: clockwise,
	                    cx: cx,
	                    cy: cy,
	                    r0: r0,
	                    r: roseType
	                        ? numberUtil.linearMap(value, extent, [r0, r])
	                        : r
	                });

	                currentAngle = endAngle;
	            }, true);

	            // Some sector is constrained by minAngle
	            // Rest sectors needs recalculate angle
	            if (restAngle < PI2 && validDataCount) {
	                // Average the angle if rest angle is not enough after all angles is
	                // Constrained by minAngle
	                if (restAngle <= 1e-3) {
	                    var angle = PI2 / validDataCount;
	                    data.each('value', function (value, idx) {
	                        if (!isNaN(value)) {
	                            var layout = data.getItemLayout(idx);
	                            layout.angle = angle;
	                            layout.startAngle = startAngle + dir * idx * angle;
	                            layout.endAngle = startAngle + dir * (idx + 1) * angle;
	                        }
	                    });
	                }
	                else {
	                    unitRadian = restAngle / valueSumLargerThanMinAngle;
	                    currentAngle = startAngle;
	                    data.each('value', function (value, idx) {
	                        if (!isNaN(value)) {
	                            var layout = data.getItemLayout(idx);
	                            var angle = layout.angle === minAngle
	                                ? minAngle : value * unitRadian;
	                            layout.startAngle = currentAngle;
	                            layout.endAngle = currentAngle + dir * angle;
	                            currentAngle += dir * angle;
	                        }
	                    });
	                }
	            }

	            labelLayout(seriesModel, r, width, height);
	        });
	    };


/***/ },
/* 153 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	// FIXME emphasis label position is not same with normal label position


	    var textContain = __webpack_require__(8);

	    function adjustSingleSide(list, cx, cy, r, dir, viewWidth, viewHeight) {
	        list.sort(function (a, b) {
	            return a.y - b.y;
	        });

	        // 压
	        function shiftDown(start, end, delta, dir) {
	            for (var j = start; j < end; j++) {
	                list[j].y += delta;
	                if (j > start
	                    && j + 1 < end
	                    && list[j + 1].y > list[j].y + list[j].height
	                ) {
	                    shiftUp(j, delta / 2);
	                    return;
	                }
	            }

	            shiftUp(end - 1, delta / 2);
	        }

	        // 弹
	        function shiftUp(end, delta) {
	            for (var j = end; j >= 0; j--) {
	                list[j].y -= delta;
	                if (j > 0
	                    && list[j].y > list[j - 1].y + list[j - 1].height
	                ) {
	                    break;
	                }
	            }
	        }

	        function changeX(list, isDownList, cx, cy, r, dir) {
	            var lastDeltaX = dir > 0
	                ? isDownList                // 右侧
	                    ? Number.MAX_VALUE      // 下
	                    : 0                     // 上
	                : isDownList                // 左侧
	                    ? Number.MAX_VALUE      // 下
	                    : 0;                    // 上

	            for (var i = 0, l = list.length; i < l; i++) {
	                // Not change x for center label
	                if (list[i].position === 'center') {
	                    continue;
	                }
	                var deltaY = Math.abs(list[i].y - cy);
	                var length = list[i].len;
	                var length2 = list[i].len2;
	                var deltaX = (deltaY < r + length)
	                    ? Math.sqrt(
	                          (r + length + length2) * (r + length + length2)
	                          - deltaY * deltaY
	                      )
	                    : Math.abs(list[i].x - cx);
	                if (isDownList && deltaX >= lastDeltaX) {
	                    // 右下，左下
	                    deltaX = lastDeltaX - 10;
	                }
	                if (!isDownList && deltaX <= lastDeltaX) {
	                    // 右上，左上
	                    deltaX = lastDeltaX + 10;
	                }

	                list[i].x = cx + deltaX * dir;
	                lastDeltaX = deltaX;
	            }
	        }

	        var lastY = 0;
	        var delta;
	        var len = list.length;
	        var upList = [];
	        var downList = [];
	        for (var i = 0; i < len; i++) {
	            delta = list[i].y - lastY;
	            if (delta < 0) {
	                shiftDown(i, len, -delta, dir);
	            }
	            lastY = list[i].y + list[i].height;
	        }
	        if (viewHeight - lastY < 0) {
	            shiftUp(len - 1, lastY - viewHeight);
	        }
	        for (var i = 0; i < len; i++) {
	            if (list[i].y >= cy) {
	                downList.push(list[i]);
	            }
	            else {
	                upList.push(list[i]);
	            }
	        }
	        changeX(upList, false, cx, cy, r, dir);
	        changeX(downList, true, cx, cy, r, dir);
	    }

	    function avoidOverlap(labelLayoutList, cx, cy, r, viewWidth, viewHeight) {
	        var leftList = [];
	        var rightList = [];
	        for (var i = 0; i < labelLayoutList.length; i++) {
	            if (labelLayoutList[i].x < cx) {
	                leftList.push(labelLayoutList[i]);
	            }
	            else {
	                rightList.push(labelLayoutList[i]);
	            }
	        }

	        adjustSingleSide(rightList, cx, cy, r, 1, viewWidth, viewHeight);
	        adjustSingleSide(leftList, cx, cy, r, -1, viewWidth, viewHeight);

	        for (var i = 0; i < labelLayoutList.length; i++) {
	            var linePoints = labelLayoutList[i].linePoints;
	            if (linePoints) {
	                var dist = linePoints[1][0] - linePoints[2][0];
	                if (labelLayoutList[i].x < cx) {
	                    linePoints[2][0] = labelLayoutList[i].x + 3;
	                }
	                else {
	                    linePoints[2][0] = labelLayoutList[i].x - 3;
	                }
	                linePoints[1][1] = linePoints[2][1] = labelLayoutList[i].y;
	                linePoints[1][0] = linePoints[2][0] + dist;
	            }
	        }
	    }

	    module.exports = function (seriesModel, r, viewWidth, viewHeight) {
	        var data = seriesModel.getData();
	        var labelLayoutList = [];
	        var cx;
	        var cy;
	        var hasLabelRotate = false;

	        data.each(function (idx) {
	            var layout = data.getItemLayout(idx);

	            var itemModel = data.getItemModel(idx);
	            var labelModel = itemModel.getModel('label.normal');
	            // Use position in normal or emphasis
	            var labelPosition = labelModel.get('position') || itemModel.get('label.emphasis.position');

	            var labelLineModel = itemModel.getModel('labelLine.normal');
	            var labelLineLen = labelLineModel.get('length');
	            var labelLineLen2 = labelLineModel.get('length2');

	            var midAngle = (layout.startAngle + layout.endAngle) / 2;
	            var dx = Math.cos(midAngle);
	            var dy = Math.sin(midAngle);

	            var textX;
	            var textY;
	            var linePoints;
	            var textAlign;

	            cx = layout.cx;
	            cy = layout.cy;

	            var isLabelInside = labelPosition === 'inside' || labelPosition === 'inner';
	            if (labelPosition === 'center') {
	                textX = layout.cx;
	                textY = layout.cy;
	                textAlign = 'center';
	            }
	            else {
	                var x1 = (isLabelInside ? (layout.r + layout.r0) / 2 * dx : layout.r * dx) + cx;
	                var y1 = (isLabelInside ? (layout.r + layout.r0) / 2 * dy : layout.r * dy) + cy;

	                textX = x1 + dx * 3;
	                textY = y1 + dy * 3;

	                if (!isLabelInside) {
	                    // For roseType
	                    var x2 = x1 + dx * (labelLineLen + r - layout.r);
	                    var y2 = y1 + dy * (labelLineLen + r - layout.r);
	                    var x3 = x2 + ((dx < 0 ? -1 : 1) * labelLineLen2);
	                    var y3 = y2;

	                    textX = x3 + (dx < 0 ? -5 : 5);
	                    textY = y3;
	                    linePoints = [[x1, y1], [x2, y2], [x3, y3]];
	                }

	                textAlign = isLabelInside ? 'center' : (dx > 0 ? 'left' : 'right');
	            }
	            var font = labelModel.getModel('textStyle').getFont();

	            var labelRotate = labelModel.get('rotate')
	                ? (dx < 0 ? -midAngle + Math.PI : -midAngle) : 0;
	            var text = seriesModel.getFormattedLabel(idx, 'normal')
	                        || data.getName(idx);
	            var textRect = textContain.getBoundingRect(
	                text, font, textAlign, 'top'
	            );
	            hasLabelRotate = !!labelRotate;
	            layout.label = {
	                x: textX,
	                y: textY,
	                position: labelPosition,
	                height: textRect.height,
	                len: labelLineLen,
	                len2: labelLineLen2,
	                linePoints: linePoints,
	                textAlign: textAlign,
	                verticalAlign: 'middle',
	                font: font,
	                rotation: labelRotate
	            };

	            // Not layout the inside label
	            if (!isLabelInside) {
	                labelLayoutList.push(layout.label);
	            }
	        });
	        if (!hasLabelRotate && seriesModel.get('avoidLabelOverlap')) {
	            avoidOverlap(labelLayoutList, cx, cy, r, viewWidth, viewHeight);
	        }
	    };


/***/ },
/* 154 */
/***/ function(module, exports) {

	
	    module.exports = function (seriesType, ecModel) {
	        var legendModels = ecModel.findComponents({
	            mainType: 'legend'
	        });
	        if (!legendModels || !legendModels.length) {
	            return;
	        }
	        ecModel.eachSeriesByType(seriesType, function (series) {
	            var data = series.getData();
	            data.filterSelf(function (idx) {
	                var name = data.getName(idx);
	                // If in any legend component the status is not selected.
	                for (var i = 0; i < legendModels.length; i++) {
	                    if (!legendModels[i].isSelected(name)) {
	                        return false;
	                    }
	                }
	                return true;
	            }, this);
	        }, this);
	    };


/***/ },
/* 155 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);
	    var echarts = __webpack_require__(1);

	    __webpack_require__(156);
	    __webpack_require__(157);

	    echarts.registerVisual(zrUtil.curry(
	        __webpack_require__(121), 'scatter', 'circle', null
	    ));
	    echarts.registerLayout(zrUtil.curry(
	        __webpack_require__(122), 'scatter'
	    ));

	    // In case developer forget to include grid component
	    __webpack_require__(124);


/***/ },
/* 156 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var createListFromArray = __webpack_require__(109);
	    var SeriesModel = __webpack_require__(78);

	    module.exports = SeriesModel.extend({

	        type: 'series.scatter',

	        dependencies: ['grid', 'polar', 'geo', 'singleAxis', 'calendar'],

	        getInitialData: function (option, ecModel) {
	            return createListFromArray(option.data, this, ecModel);
	        },

	        brushSelector: 'point',

	        defaultOption: {
	            coordinateSystem: 'cartesian2d',
	            zlevel: 0,
	            z: 2,
	            legendHoverLink: true,

	            hoverAnimation: true,
	            // Cartesian coordinate system
	            // xAxisIndex: 0,
	            // yAxisIndex: 0,

	            // Polar coordinate system
	            // polarIndex: 0,

	            // Geo coordinate system
	            // geoIndex: 0,

	            // symbol: null,        // 图形类型
	            symbolSize: 10,          // 图形大小，半宽（半径）参数，当图形为方向或菱形则总宽度为symbolSize * 2
	            // symbolRotate: null,  // 图形旋转控制

	            large: false,
	            // Available when large is true
	            largeThreshold: 2000,
	            // cursor: null,

	            // label: {
	                // normal: {
	                    // show: false
	                    // distance: 5,
	                    // formatter: 标签文本格式器，同Tooltip.formatter，不支持异步回调
	                    // position: 默认自适应，水平布局为'top'，垂直布局为'right'，可选为
	                    //           'inside'|'left'|'right'|'top'|'bottom'
	                    // textStyle: null      // 默认使用全局文本样式，详见TEXTSTYLE
	            //     }
	            // },
	            itemStyle: {
	                normal: {
	                    opacity: 0.8
	                    // color: 各异
	                }
	            }
	        }

	    });


/***/ },
/* 157 */
/***/ function(module, exports, __webpack_require__) {

	

	    var SymbolDraw = __webpack_require__(116);
	    var LargeSymbolDraw = __webpack_require__(158);

	    __webpack_require__(1).extendChartView({

	        type: 'scatter',

	        init: function () {
	            this._normalSymbolDraw = new SymbolDraw();
	            this._largeSymbolDraw = new LargeSymbolDraw();
	        },

	        render: function (seriesModel, ecModel, api) {
	            var data = seriesModel.getData();
	            var largeSymbolDraw = this._largeSymbolDraw;
	            var normalSymbolDraw = this._normalSymbolDraw;
	            var group = this.group;

	            var symbolDraw = seriesModel.get('large') && data.count() > seriesModel.get('largeThreshold')
	                ? largeSymbolDraw : normalSymbolDraw;

	            this._symbolDraw = symbolDraw;
	            symbolDraw.updateData(data);
	            group.add(symbolDraw.group);

	            group.remove(
	                symbolDraw === largeSymbolDraw
	                ? normalSymbolDraw.group : largeSymbolDraw.group
	            );
	        },

	        updateLayout: function (seriesModel) {
	            this._symbolDraw.updateLayout(seriesModel);
	        },

	        remove: function (ecModel, api) {
	            this._symbolDraw && this._symbolDraw.remove(api, true);
	        },

	        dispose: function () {}
	    });


/***/ },
/* 158 */
/***/ function(module, exports, __webpack_require__) {

	// TODO Batch by color



	    var graphic = __webpack_require__(18);
	    var symbolUtil = __webpack_require__(111);

	    var LargeSymbolPath = graphic.extendShape({

	        shape: {
	            points: null,
	            sizes: null
	        },

	        symbolProxy: null,

	        buildPath: function (path, shape) {
	            var points = shape.points;
	            var sizes = shape.sizes;

	            var symbolProxy = this.symbolProxy;
	            var symbolProxyShape = symbolProxy.shape;
	            for (var i = 0; i < points.length; i++) {
	                var pt = points[i];

	                if (isNaN(pt[0]) || isNaN(pt[1])) {
	                    continue;
	                }

	                var size = sizes[i];
	                if (size[0] < 4) {
	                    // Optimize for small symbol
	                    path.rect(
	                        pt[0] - size[0] / 2, pt[1] - size[1] / 2,
	                        size[0], size[1]
	                    );
	                }
	                else {
	                    symbolProxyShape.x = pt[0] - size[0] / 2;
	                    symbolProxyShape.y = pt[1] - size[1] / 2;
	                    symbolProxyShape.width = size[0];
	                    symbolProxyShape.height = size[1];

	                    symbolProxy.buildPath(path, symbolProxyShape, true);
	                }
	            }
	        },

	        findDataIndex: function (x, y) {
	            var shape = this.shape;
	            var points = shape.points;
	            var sizes = shape.sizes;

	            // Not consider transform
	            // Treat each element as a rect
	            // top down traverse
	            for (var i = points.length - 1; i >= 0; i--) {
	                var pt = points[i];
	                var size = sizes[i];
	                var x0 = pt[0] - size[0] / 2;
	                var y0 = pt[1] - size[1] / 2;
	                if (x >= x0 && y >= y0 && x <= x0 + size[0] && y <= y0 + size[1]) {
	                    // i is dataIndex
	                    return i;
	                }
	            }

	            return -1;
	        }
	    });

	    function LargeSymbolDraw() {
	        this.group = new graphic.Group();

	        this._symbolEl = new LargeSymbolPath({
	            // rectHover: true,
	            // cursor: 'default'
	        });
	    }

	    var largeSymbolProto = LargeSymbolDraw.prototype;

	    /**
	     * Update symbols draw by new data
	     * @param {module:echarts/data/List} data
	     */
	    largeSymbolProto.updateData = function (data) {
	        this.group.removeAll();

	        var symbolEl = this._symbolEl;

	        var seriesModel = data.hostModel;

	        symbolEl.setShape({
	            points: data.mapArray(data.getItemLayout),
	            sizes: data.mapArray(
	                function (idx) {
	                    var size = data.getItemVisual(idx, 'symbolSize');
	                    if (!(size instanceof Array)) {
	                        size = [size, size];
	                    }
	                    return size;
	                }
	            )
	        });

	        // Create symbolProxy to build path for each data
	        symbolEl.symbolProxy = symbolUtil.createSymbol(
	            data.getVisual('symbol'), 0, 0, 0, 0
	        );
	        // Use symbolProxy setColor method
	        symbolEl.setColor = symbolEl.symbolProxy.setColor;

	        symbolEl.useStyle(
	            seriesModel.getModel('itemStyle.normal').getItemStyle(['color'])
	        );

	        var visualColor = data.getVisual('color');
	        if (visualColor) {
	            symbolEl.setColor(visualColor);
	        }

	        // Enable tooltip
	        // PENDING May have performance issue when path is extremely large
	        symbolEl.seriesIndex = seriesModel.seriesIndex;
	        symbolEl.on('mousemove', function (e) {
	            symbolEl.dataIndex = null;
	            var dataIndex = symbolEl.findDataIndex(e.offsetX, e.offsetY);
	            if (dataIndex >= 0) {
	                // Provide dataIndex for tooltip
	                symbolEl.dataIndex = dataIndex;
	            }
	        });

	        // Add back
	        this.group.add(symbolEl);
	    };

	    largeSymbolProto.updateLayout = function (seriesModel) {
	        var data = seriesModel.getData();
	        this._symbolEl.setShape({
	            points: data.mapArray(data.getItemLayout)
	        });
	    };

	    largeSymbolProto.remove = function () {
	        this.group.removeAll();
	    };

	    module.exports = LargeSymbolDraw;


/***/ },
/* 159 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);
	    var echarts = __webpack_require__(1);

	    // Must use radar component
	    __webpack_require__(160);

	    __webpack_require__(165);
	    __webpack_require__(166);

	    echarts.registerVisual(zrUtil.curry(__webpack_require__(151), 'radar'));
	    echarts.registerVisual(zrUtil.curry(
	        __webpack_require__(121), 'radar', 'circle', null
	    ));
	    echarts.registerLayout(__webpack_require__(167));

	    echarts.registerProcessor(
	        zrUtil.curry(__webpack_require__(154), 'radar')
	    );

	    echarts.registerPreprocessor(__webpack_require__(168));


/***/ },
/* 160 */
/***/ function(module, exports, __webpack_require__) {

	

	    __webpack_require__(161);
	    __webpack_require__(163);

	    __webpack_require__(164);


/***/ },
/* 161 */
/***/ function(module, exports, __webpack_require__) {

	// TODO clockwise


	    var zrUtil = __webpack_require__(4);
	    var IndicatorAxis = __webpack_require__(162);
	    var IntervalScale = __webpack_require__(104);
	    var numberUtil = __webpack_require__(7);
	    var axisHelper = __webpack_require__(101);

	    function Radar(radarModel, ecModel, api) {

	        this._model = radarModel;
	        /**
	         * Radar dimensions
	         * @type {Array.<string>}
	         */
	        this.dimensions = [];

	        this._indicatorAxes = zrUtil.map(radarModel.getIndicatorModels(), function (indicatorModel, idx) {
	            var dim = 'indicator_' + idx;
	            var indicatorAxis = new IndicatorAxis(dim, new IntervalScale());
	            indicatorAxis.name = indicatorModel.get('name');
	            // Inject model and axis
	            indicatorAxis.model = indicatorModel;
	            indicatorModel.axis = indicatorAxis;
	            this.dimensions.push(dim);
	            return indicatorAxis;
	        }, this);

	        this.resize(radarModel, api);

	        /**
	         * @type {number}
	         * @readOnly
	         */
	        this.cx;
	        /**
	         * @type {number}
	         * @readOnly
	         */
	        this.cy;
	        /**
	         * @type {number}
	         * @readOnly
	         */
	        this.r;
	        /**
	         * @type {number}
	         * @readOnly
	         */
	        this.startAngle;
	    }

	    Radar.prototype.getIndicatorAxes = function () {
	        return this._indicatorAxes;
	    };

	    Radar.prototype.dataToPoint = function (value, indicatorIndex) {
	        var indicatorAxis = this._indicatorAxes[indicatorIndex];

	        return this.coordToPoint(indicatorAxis.dataToCoord(value), indicatorIndex);
	    };

	    Radar.prototype.coordToPoint = function (coord, indicatorIndex) {
	        var indicatorAxis = this._indicatorAxes[indicatorIndex];
	        var angle = indicatorAxis.angle;
	        var x = this.cx + coord * Math.cos(angle);
	        var y = this.cy - coord * Math.sin(angle);
	        return [x, y];
	    };

	    Radar.prototype.pointToData = function (pt) {
	        var dx = pt[0] - this.cx;
	        var dy = pt[1] - this.cy;
	        var radius = Math.sqrt(dx * dx + dy * dy);
	        dx /= radius;
	        dy /= radius;

	        var radian = Math.atan2(-dy, dx);

	        // Find the closest angle
	        // FIXME index can calculated directly
	        var minRadianDiff = Infinity;
	        var closestAxis;
	        var closestAxisIdx = -1;
	        for (var i = 0; i < this._indicatorAxes.length; i++) {
	            var indicatorAxis = this._indicatorAxes[i];
	            var diff = Math.abs(radian - indicatorAxis.angle);
	            if (diff < minRadianDiff) {
	                closestAxis = indicatorAxis;
	                closestAxisIdx = i;
	                minRadianDiff = diff;
	            }
	        }

	        return [closestAxisIdx, +(closestAxis && closestAxis.coodToData(radius))];
	    };

	    Radar.prototype.resize = function (radarModel, api) {
	        var center = radarModel.get('center');
	        var viewWidth = api.getWidth();
	        var viewHeight = api.getHeight();
	        var viewSize = Math.min(viewWidth, viewHeight) / 2;
	        this.cx = numberUtil.parsePercent(center[0], viewWidth);
	        this.cy = numberUtil.parsePercent(center[1], viewHeight);

	        this.startAngle = radarModel.get('startAngle') * Math.PI / 180;

	        this.r = numberUtil.parsePercent(radarModel.get('radius'), viewSize);

	        zrUtil.each(this._indicatorAxes, function (indicatorAxis, idx) {
	            indicatorAxis.setExtent(0, this.r);
	            var angle = (this.startAngle + idx * Math.PI * 2 / this._indicatorAxes.length);
	            // Normalize to [-PI, PI]
	            angle = Math.atan2(Math.sin(angle), Math.cos(angle));
	            indicatorAxis.angle = angle;
	        }, this);
	    };

	    Radar.prototype.update = function (ecModel, api) {
	        var indicatorAxes = this._indicatorAxes;
	        var radarModel = this._model;
	        zrUtil.each(indicatorAxes, function (indicatorAxis) {
	            indicatorAxis.scale.setExtent(Infinity, -Infinity);
	        });
	        ecModel.eachSeriesByType('radar', function (radarSeries, idx) {
	            if (radarSeries.get('coordinateSystem') !== 'radar'
	                || ecModel.getComponent('radar', radarSeries.get('radarIndex')) !== radarModel
	            ) {
	                return;
	            }
	            var data = radarSeries.getData();
	            zrUtil.each(indicatorAxes, function (indicatorAxis) {
	                indicatorAxis.scale.unionExtentFromData(data, indicatorAxis.dim);
	            });
	        }, this);

	        var splitNumber = radarModel.get('splitNumber');

	        function increaseInterval(interval) {
	            var exp10 = Math.pow(10, Math.floor(Math.log(interval) / Math.LN10));
	            // Increase interval
	            var f = interval / exp10;
	            if (f === 2) {
	                f = 5;
	            }
	            else { // f is 2 or 5
	                f *= 2;
	            }
	            return f * exp10;
	        }
	        // Force all the axis fixing the maxSplitNumber.
	        zrUtil.each(indicatorAxes, function (indicatorAxis, idx) {
	            var rawExtent = axisHelper.getScaleExtent(indicatorAxis.scale, indicatorAxis.model);
	            axisHelper.niceScaleExtent(indicatorAxis.scale, indicatorAxis.model);

	            var axisModel = indicatorAxis.model;
	            var scale = indicatorAxis.scale;
	            var fixedMin = axisModel.getMin();
	            var fixedMax = axisModel.getMax();
	            var interval = scale.getInterval();

	            if (fixedMin != null && fixedMax != null) {
	                // User set min, max, divide to get new interval
	                scale.setExtent(+fixedMin, +fixedMax);
	                scale.setInterval(
	                    (fixedMax - fixedMin) / splitNumber
	                );
	            }
	            else if (fixedMin != null) {
	                var max;
	                // User set min, expand extent on the other side
	                do {
	                    max = fixedMin + interval * splitNumber;
	                    scale.setExtent(+fixedMin, max);
	                    // Interval must been set after extent
	                    // FIXME
	                    scale.setInterval(interval);

	                    interval = increaseInterval(interval);
	                } while (max < rawExtent[1] && isFinite(max) && isFinite(rawExtent[1]));
	            }
	            else if (fixedMax != null) {
	                var min;
	                // User set min, expand extent on the other side
	                do {
	                    min = fixedMax - interval * splitNumber;
	                    scale.setExtent(min, +fixedMax);
	                    scale.setInterval(interval);
	                    interval = increaseInterval(interval);
	                } while (min > rawExtent[0] && isFinite(min) && isFinite(rawExtent[0]));
	            }
	            else {
	                var nicedSplitNumber = scale.getTicks().length - 1;
	                if (nicedSplitNumber > splitNumber) {
	                    interval = increaseInterval(interval);
	                }
	                // PENDING
	                var center = Math.round((rawExtent[0] + rawExtent[1]) / 2 / interval) * interval;
	                var halfSplitNumber = Math.round(splitNumber / 2);
	                scale.setExtent(
	                    numberUtil.round(center - halfSplitNumber * interval),
	                    numberUtil.round(center + (splitNumber - halfSplitNumber) * interval)
	                );
	                scale.setInterval(interval);
	            }
	        });
	    };

	    /**
	     * Radar dimensions is based on the data
	     * @type {Array}
	     */
	    Radar.dimensions = [];

	    Radar.create = function (ecModel, api) {
	        var radarList = [];
	        ecModel.eachComponent('radar', function (radarModel) {
	            var radar = new Radar(radarModel, ecModel, api);
	            radarList.push(radar);
	            radarModel.coordinateSystem = radar;
	        });
	        ecModel.eachSeriesByType('radar', function (radarSeries) {
	            if (radarSeries.get('coordinateSystem') === 'radar') {
	                // Inject coordinate system
	                radarSeries.coordinateSystem = radarList[radarSeries.get('radarIndex') || 0];
	            }
	        });
	        return radarList;
	    };

	    __webpack_require__(76).register('radar', Radar);
	    module.exports = Radar;


/***/ },
/* 162 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);
	    var Axis = __webpack_require__(100);

	    function IndicatorAxis(dim, scale, radiusExtent) {
	        Axis.call(this, dim, scale, radiusExtent);

	        /**
	         * Axis type
	         *  - 'category'
	         *  - 'value'
	         *  - 'time'
	         *  - 'log'
	         * @type {string}
	         */
	        this.type = 'value';

	        this.angle = 0;

	        /**
	         * Indicator name
	         * @type {string}
	         */
	        this.name = '';
	        /**
	         * @type {module:echarts/model/Model}
	         */
	        this.model;
	    }

	    zrUtil.inherits(IndicatorAxis, Axis);

	    module.exports = IndicatorAxis;


/***/ },
/* 163 */
/***/ function(module, exports, __webpack_require__) {

	


	    var axisDefault = __webpack_require__(132);
	    var valueAxisDefault = axisDefault.valueAxis;
	    var Model = __webpack_require__(12);
	    var zrUtil = __webpack_require__(4);

	    var axisModelCommonMixin = __webpack_require__(112);

	    function defaultsShow(opt, show) {
	        return zrUtil.defaults({
	            show: show
	        }, opt);
	    }

	    var RadarModel = __webpack_require__(1).extendComponentModel({

	        type: 'radar',

	        optionUpdated: function () {
	            var boundaryGap = this.get('boundaryGap');
	            var splitNumber = this.get('splitNumber');
	            var scale = this.get('scale');
	            var axisLine = this.get('axisLine');
	            var axisTick = this.get('axisTick');
	            var axisLabel = this.get('axisLabel');
	            var nameTextStyle = this.get('name.textStyle');
	            var showName = this.get('name.show');
	            var nameFormatter = this.get('name.formatter');
	            var nameGap = this.get('nameGap');
	            var triggerEvent = this.get('triggerEvent');

	            var indicatorModels = zrUtil.map(this.get('indicator') || [], function (indicatorOpt) {
	                // PENDING
	                if (indicatorOpt.max != null && indicatorOpt.max > 0 && !indicatorOpt.min) {
	                    indicatorOpt.min = 0;
	                }
	                else if (indicatorOpt.min != null && indicatorOpt.min < 0 && !indicatorOpt.max) {
	                    indicatorOpt.max = 0;
	                }
	                // Use same configuration
	                indicatorOpt = zrUtil.merge(zrUtil.clone(indicatorOpt), {
	                    boundaryGap: boundaryGap,
	                    splitNumber: splitNumber,
	                    scale: scale,
	                    axisLine: axisLine,
	                    axisTick: axisTick,
	                    axisLabel: axisLabel,
	                    // Competitable with 2 and use text
	                    name: indicatorOpt.text,
	                    nameLocation: 'end',
	                    nameGap: nameGap,
	                    // min: 0,
	                    nameTextStyle: nameTextStyle,
	                    triggerEvent: triggerEvent
	                }, false);
	                if (!showName) {
	                    indicatorOpt.name = '';
	                }
	                if (typeof nameFormatter === 'string') {
	                    var indName = indicatorOpt.name;
	                    indicatorOpt.name = nameFormatter.replace('{value}', indName != null ? indName : '');
	                }
	                else if (typeof nameFormatter === 'function') {
	                    indicatorOpt.name = nameFormatter(
	                        indicatorOpt.name, indicatorOpt
	                    );
	                }
	                var model = zrUtil.extend(
	                    new Model(indicatorOpt, null, this.ecModel),
	                    axisModelCommonMixin
	                );

	                // For triggerEvent.
	                model.mainType = 'radar';
	                model.componentIndex = this.componentIndex;

	                return model;
	            }, this);

	            this.getIndicatorModels = function () {
	                return indicatorModels;
	            };
	        },

	        defaultOption: {

	            zlevel: 0,

	            z: 0,

	            center: ['50%', '50%'],

	            radius: '75%',

	            startAngle: 90,

	            name: {
	                show: true
	                // formatter: null
	                // textStyle: {}
	            },

	            boundaryGap: [0, 0],

	            splitNumber: 5,

	            nameGap: 15,

	            scale: false,

	            // Polygon or circle
	            shape: 'polygon',

	            axisLine: zrUtil.merge(
	                {
	                    lineStyle: {
	                        color: '#bbb'
	                    }
	                },
	                valueAxisDefault.axisLine
	            ),
	            axisLabel: defaultsShow(valueAxisDefault.axisLabel, false),
	            axisTick: defaultsShow(valueAxisDefault.axisTick, false),
	            splitLine: defaultsShow(valueAxisDefault.splitLine, true),
	            splitArea: defaultsShow(valueAxisDefault.splitArea, true),

	            // {text, min, max}
	            indicator: []
	        }
	    });

	    module.exports = RadarModel;


/***/ },
/* 164 */
/***/ function(module, exports, __webpack_require__) {

	

	    var AxisBuilder = __webpack_require__(135);
	    var zrUtil = __webpack_require__(4);
	    var graphic = __webpack_require__(18);

	    var axisBuilderAttrs = [
	        'axisLine', 'axisLabel', 'axisTick', 'axisName'
	    ];

	    module.exports = __webpack_require__(1).extendComponentView({

	        type: 'radar',

	        render: function (radarModel, ecModel, api) {
	            var group = this.group;
	            group.removeAll();

	            this._buildAxes(radarModel);
	            this._buildSplitLineAndArea(radarModel);
	        },

	        _buildAxes: function (radarModel) {
	            var radar = radarModel.coordinateSystem;
	            var indicatorAxes = radar.getIndicatorAxes();
	            var axisBuilders = zrUtil.map(indicatorAxes, function (indicatorAxis) {
	                var axisBuilder = new AxisBuilder(indicatorAxis.model, {
	                    position: [radar.cx, radar.cy],
	                    rotation: indicatorAxis.angle,
	                    labelDirection: -1,
	                    tickDirection: -1,
	                    nameDirection: 1
	                });
	                return axisBuilder;
	            });

	            zrUtil.each(axisBuilders, function (axisBuilder) {
	                zrUtil.each(axisBuilderAttrs, axisBuilder.add, axisBuilder);
	                this.group.add(axisBuilder.getGroup());
	            }, this);
	        },

	        _buildSplitLineAndArea: function (radarModel) {
	            var radar = radarModel.coordinateSystem;
	            var indicatorAxes = radar.getIndicatorAxes();
	            if (!indicatorAxes.length) {
	                return;
	            }
	            var shape = radarModel.get('shape');
	            var splitLineModel = radarModel.getModel('splitLine');
	            var splitAreaModel = radarModel.getModel('splitArea');
	            var lineStyleModel = splitLineModel.getModel('lineStyle');
	            var areaStyleModel = splitAreaModel.getModel('areaStyle');

	            var showSplitLine = splitLineModel.get('show');
	            var showSplitArea = splitAreaModel.get('show');
	            var splitLineColors = lineStyleModel.get('color');
	            var splitAreaColors = areaStyleModel.get('color');

	            splitLineColors = zrUtil.isArray(splitLineColors) ? splitLineColors : [splitLineColors];
	            splitAreaColors = zrUtil.isArray(splitAreaColors) ? splitAreaColors : [splitAreaColors];

	            var splitLines = [];
	            var splitAreas = [];

	            function getColorIndex(areaOrLine, areaOrLineColorList, idx) {
	                var colorIndex = idx % areaOrLineColorList.length;
	                areaOrLine[colorIndex] = areaOrLine[colorIndex] || [];
	                return colorIndex;
	            }

	            if (shape === 'circle') {
	                var ticksRadius = indicatorAxes[0].getTicksCoords();
	                var cx = radar.cx;
	                var cy = radar.cy;
	                for (var i = 0; i < ticksRadius.length; i++) {
	                    if (showSplitLine) {
	                        var colorIndex = getColorIndex(splitLines, splitLineColors, i);
	                        splitLines[colorIndex].push(new graphic.Circle({
	                            shape: {
	                                cx: cx,
	                                cy: cy,
	                                r: ticksRadius[i]
	                            }
	                        }));
	                    }
	                    if (showSplitArea && i < ticksRadius.length - 1) {
	                        var colorIndex = getColorIndex(splitAreas, splitAreaColors, i);
	                        splitAreas[colorIndex].push(new graphic.Ring({
	                            shape: {
	                                cx: cx,
	                                cy: cy,
	                                r0: ticksRadius[i],
	                                r: ticksRadius[i + 1]
	                            }
	                        }));
	                    }
	                }
	            }
	            // Polyyon
	            else {
	                var realSplitNumber;
	                var axesTicksPoints = zrUtil.map(indicatorAxes, function (indicatorAxis, idx) {
	                    var ticksCoords = indicatorAxis.getTicksCoords();
	                    realSplitNumber = realSplitNumber == null
	                        ? ticksCoords.length - 1
	                        : Math.min(ticksCoords.length - 1, realSplitNumber);
	                    return zrUtil.map(ticksCoords, function (tickCoord) {
	                        return radar.coordToPoint(tickCoord, idx);
	                    });
	                });

	                var prevPoints = [];
	                for (var i = 0; i <= realSplitNumber; i++) {
	                    var points = [];
	                    for (var j = 0; j < indicatorAxes.length; j++) {
	                        points.push(axesTicksPoints[j][i]);
	                    }
	                    // Close
	                    if (points[0]) {
	                        points.push(points[0].slice());
	                    }
	                    else {
	                        if (true) {
	                            console.error('Can\'t draw value axis ' + i);
	                        }
	                    }

	                    if (showSplitLine) {
	                        var colorIndex = getColorIndex(splitLines, splitLineColors, i);
	                        splitLines[colorIndex].push(new graphic.Polyline({
	                            shape: {
	                                points: points
	                            }
	                        }));
	                    }
	                    if (showSplitArea && prevPoints) {
	                        var colorIndex = getColorIndex(splitAreas, splitAreaColors, i - 1);
	                        splitAreas[colorIndex].push(new graphic.Polygon({
	                            shape: {
	                                points: points.concat(prevPoints)
	                            }
	                        }));
	                    }
	                    prevPoints = points.slice().reverse();
	                }
	            }

	            var lineStyle = lineStyleModel.getLineStyle();
	            var areaStyle = areaStyleModel.getAreaStyle();
	            // Add splitArea before splitLine
	            zrUtil.each(splitAreas, function (splitAreas, idx) {
	                this.group.add(graphic.mergePath(
	                    splitAreas, {
	                        style: zrUtil.defaults({
	                            stroke: 'none',
	                            fill: splitAreaColors[idx % splitAreaColors.length]
	                        }, areaStyle),
	                        silent: true
	                    }
	                ));
	            }, this);

	            zrUtil.each(splitLines, function (splitLines, idx) {
	                this.group.add(graphic.mergePath(
	                    splitLines, {
	                        style: zrUtil.defaults({
	                            fill: 'none',
	                            stroke: splitLineColors[idx % splitLineColors.length]
	                        }, lineStyle),
	                        silent: true
	                    }
	                ));
	            }, this);

	        }
	    });


/***/ },
/* 165 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var SeriesModel = __webpack_require__(78);
	    var List = __webpack_require__(98);
	    var completeDimensions = __webpack_require__(110);
	    var zrUtil = __webpack_require__(4);
	    var encodeHTML = __webpack_require__(6).encodeHTML;

	    var RadarSeries = SeriesModel.extend({

	        type: 'series.radar',

	        dependencies: ['radar'],


	        // Overwrite
	        init: function (option) {
	            RadarSeries.superApply(this, 'init', arguments);

	            // Enable legend selection for each data item
	            // Use a function instead of direct access because data reference may changed
	            this.legendDataProvider = function () {
	                return this.getRawData();
	            };
	        },

	        getInitialData: function (option, ecModel) {
	            var data = option.data || [];
	            var dimensions = completeDimensions(
	                [], data, {extraPrefix: 'indicator_', extraFromZero: true}
	            );
	            var list = new List(dimensions, this);
	            list.initData(data);
	            return list;
	        },

	        formatTooltip: function (dataIndex) {
	            var value = this.getRawValue(dataIndex);
	            var coordSys = this.coordinateSystem;
	            var indicatorAxes = coordSys.getIndicatorAxes();
	            var name = this.getData().getName(dataIndex);
	            return encodeHTML(name === '' ? this.name : name) + '<br/>'
	                + zrUtil.map(indicatorAxes, function (axis, idx) {
	                    return encodeHTML(axis.name + ' : ' + value[idx]);
	                }).join('<br />');
	        },

	        defaultOption: {
	            zlevel: 0,
	            z: 2,
	            coordinateSystem: 'radar',
	            legendHoverLink: true,
	            radarIndex: 0,
	            lineStyle: {
	                normal: {
	                    width: 2,
	                    type: 'solid'
	                }
	            },
	            label: {
	                normal: {
	                    position: 'top'
	                }
	            },
	            // areaStyle: {
	            // },
	            // itemStyle: {}
	            symbol: 'emptyCircle',
	            symbolSize: 4
	            // symbolRotate: null
	        }
	    });

	    module.exports = RadarSeries;


/***/ },
/* 166 */
/***/ function(module, exports, __webpack_require__) {

	

	    var graphic = __webpack_require__(18);
	    var zrUtil = __webpack_require__(4);
	    var symbolUtil = __webpack_require__(111);

	    function normalizeSymbolSize(symbolSize) {
	        if (!zrUtil.isArray(symbolSize)) {
	            symbolSize = [+symbolSize, +symbolSize];
	        }
	        return symbolSize;
	    }
	    module.exports = __webpack_require__(1).extendChartView({
	        type: 'radar',

	        render: function (seriesModel, ecModel, api) {
	            var polar = seriesModel.coordinateSystem;
	            var group = this.group;

	            var data = seriesModel.getData();
	            var oldData = this._data;

	            function createSymbol(data, idx) {
	                var symbolType = data.getItemVisual(idx, 'symbol') || 'circle';
	                var color = data.getItemVisual(idx, 'color');
	                if (symbolType === 'none') {
	                    return;
	                }
	                var symbolPath = symbolUtil.createSymbol(
	                    symbolType, -0.5, -0.5, 1, 1, color
	                );
	                symbolPath.attr({
	                    style: {
	                        strokeNoScale: true
	                    },
	                    z2: 100,
	                    scale: normalizeSymbolSize(data.getItemVisual(idx, 'symbolSize'))
	                });
	                return symbolPath;
	            }

	            function updateSymbols(oldPoints, newPoints, symbolGroup, data, idx, isInit) {
	                // Simply rerender all
	                symbolGroup.removeAll();
	                for (var i = 0; i < newPoints.length - 1; i++) {
	                    var symbolPath = createSymbol(data, idx);
	                    if (symbolPath) {
	                        symbolPath.__dimIdx = i;
	                        if (oldPoints[i]) {
	                            symbolPath.attr('position', oldPoints[i]);
	                            graphic[isInit ? 'initProps' : 'updateProps'](
	                                symbolPath, {
	                                    position: newPoints[i]
	                                }, seriesModel, idx
	                            );
	                        }
	                        else {
	                            symbolPath.attr('position', newPoints[i]);
	                        }
	                        symbolGroup.add(symbolPath);
	                    }
	                }
	            }

	            function getInitialPoints(points) {
	                return zrUtil.map(points, function (pt) {
	                    return [polar.cx, polar.cy];
	                });
	            }
	            data.diff(oldData)
	                .add(function (idx) {
	                    var points = data.getItemLayout(idx);
	                    if (!points) {
	                        return;
	                    }
	                    var polygon = new graphic.Polygon();
	                    var polyline = new graphic.Polyline();
	                    var target = {
	                        shape: {
	                            points: points
	                        }
	                    };
	                    polygon.shape.points = getInitialPoints(points);
	                    polyline.shape.points = getInitialPoints(points);
	                    graphic.initProps(polygon, target, seriesModel, idx);
	                    graphic.initProps(polyline, target, seriesModel, idx);

	                    var itemGroup = new graphic.Group();
	                    var symbolGroup = new graphic.Group();
	                    itemGroup.add(polyline);
	                    itemGroup.add(polygon);
	                    itemGroup.add(symbolGroup);

	                    updateSymbols(
	                        polyline.shape.points, points, symbolGroup, data, idx, true
	                    );

	                    data.setItemGraphicEl(idx, itemGroup);
	                })
	                .update(function (newIdx, oldIdx) {
	                    var itemGroup = oldData.getItemGraphicEl(oldIdx);
	                    var polyline = itemGroup.childAt(0);
	                    var polygon = itemGroup.childAt(1);
	                    var symbolGroup = itemGroup.childAt(2);
	                    var target = {
	                        shape: {
	                            points: data.getItemLayout(newIdx)
	                        }
	                    };
	                    if (!target.shape.points) {
	                        return;
	                    }
	                    updateSymbols(
	                        polyline.shape.points, target.shape.points, symbolGroup, data, newIdx, false
	                    );

	                    graphic.updateProps(polyline, target, seriesModel);
	                    graphic.updateProps(polygon, target, seriesModel);

	                    data.setItemGraphicEl(newIdx, itemGroup);
	                })
	                .remove(function (idx) {
	                    group.remove(oldData.getItemGraphicEl(idx));
	                })
	                .execute();

	            data.eachItemGraphicEl(function (itemGroup, idx) {
	                var itemModel = data.getItemModel(idx);
	                var polyline = itemGroup.childAt(0);
	                var polygon = itemGroup.childAt(1);
	                var symbolGroup = itemGroup.childAt(2);
	                var color = data.getItemVisual(idx, 'color');

	                group.add(itemGroup);

	                polyline.useStyle(
	                    zrUtil.defaults(
	                        itemModel.getModel('lineStyle.normal').getLineStyle(),
	                        {
	                            fill: 'none',
	                            stroke: color
	                        }
	                    )
	                );
	                polyline.hoverStyle = itemModel.getModel('lineStyle.emphasis').getLineStyle();

	                var areaStyleModel = itemModel.getModel('areaStyle.normal');
	                var hoverAreaStyleModel = itemModel.getModel('areaStyle.emphasis');
	                var polygonIgnore = areaStyleModel.isEmpty() && areaStyleModel.parentModel.isEmpty();
	                var hoverPolygonIgnore = hoverAreaStyleModel.isEmpty() && hoverAreaStyleModel.parentModel.isEmpty();

	                hoverPolygonIgnore = hoverPolygonIgnore && polygonIgnore;
	                polygon.ignore = polygonIgnore;

	                polygon.useStyle(
	                    zrUtil.defaults(
	                        areaStyleModel.getAreaStyle(),
	                        {
	                            fill: color,
	                            opacity: 0.7
	                        }
	                    )
	                );
	                polygon.hoverStyle = hoverAreaStyleModel.getAreaStyle();

	                var itemStyle = itemModel.getModel('itemStyle.normal').getItemStyle(['color']);
	                var itemHoverStyle = itemModel.getModel('itemStyle.emphasis').getItemStyle();
	                var labelModel = itemModel.getModel('label.normal');
	                var labelHoverModel = itemModel.getModel('label.emphasis');
	                symbolGroup.eachChild(function (symbolPath) {
	                    symbolPath.setStyle(itemStyle);
	                    symbolPath.hoverStyle = zrUtil.clone(itemHoverStyle);

	                    var defaultText = data.get(data.dimensions[symbolPath.__dimIdx], idx);
	                    graphic.setText(symbolPath.style, labelModel, color);
	                    symbolPath.setStyle({
	                        text: labelModel.get('show') ? zrUtil.retrieve(
	                            seriesModel.getFormattedLabel(
	                                idx, 'normal', null, symbolPath.__dimIdx
	                            ),
	                            defaultText
	                        ) : ''
	                    });

	                    graphic.setText(symbolPath.hoverStyle, labelHoverModel, color);
	                    symbolPath.hoverStyle.text = labelHoverModel.get('show') ? zrUtil.retrieve(
	                        seriesModel.getFormattedLabel(
	                            idx, 'emphasis', null, symbolPath.__dimIdx
	                        ),
	                        defaultText
	                    ) : '';
	                });

	                function onEmphasis() {
	                    polygon.attr('ignore', hoverPolygonIgnore);
	                }

	                function onNormal() {
	                    polygon.attr('ignore', polygonIgnore);
	                }

	                itemGroup.off('mouseover').off('mouseout').off('normal').off('emphasis');
	                itemGroup.on('emphasis', onEmphasis)
	                    .on('mouseover', onEmphasis)
	                    .on('normal', onNormal)
	                    .on('mouseout', onNormal);

	                graphic.setHoverStyle(itemGroup);
	            });

	            this._data = data;
	        },

	        remove: function () {
	            this.group.removeAll();
	            this._data = null;
	        },

	        dispose: function () {}
	    });


/***/ },
/* 167 */
/***/ function(module, exports) {

	

	    module.exports = function (ecModel) {
	        ecModel.eachSeriesByType('radar', function (seriesModel) {
	            var data = seriesModel.getData();
	            var points = [];
	            var coordSys = seriesModel.coordinateSystem;
	            if (!coordSys) {
	                return;
	            }

	            function pointsConverter(val, idx) {
	                points[idx] = points[idx] || [];
	                points[idx][i] = coordSys.dataToPoint(val, i);
	            }
	            for (var i = 0; i < coordSys.getIndicatorAxes().length; i++) {
	                var dim = data.dimensions[i];
	                data.each(dim, pointsConverter);
	            }

	            data.each(function (idx) {
	                // Close polygon
	                points[idx][0] && points[idx].push(points[idx][0].slice());
	                data.setItemLayout(idx, points[idx]);
	            });
	        });
	    };


/***/ },
/* 168 */
/***/ function(module, exports, __webpack_require__) {

	// Backward compat for radar chart in 2


	    var zrUtil = __webpack_require__(4);

	    module.exports = function (option) {
	        var polarOptArr = option.polar;
	        if (polarOptArr) {
	            if (!zrUtil.isArray(polarOptArr)) {
	                polarOptArr = [polarOptArr];
	            }
	            var polarNotRadar = [];
	            zrUtil.each(polarOptArr, function (polarOpt, idx) {
	                if (polarOpt.indicator) {
	                    if (polarOpt.type && !polarOpt.shape) {
	                        polarOpt.shape = polarOpt.type;
	                    }
	                    option.radar = option.radar || [];
	                    if (!zrUtil.isArray(option.radar)) {
	                        option.radar = [option.radar];
	                    }
	                    option.radar.push(polarOpt);
	                }
	                else {
	                    polarNotRadar.push(polarOpt);
	                }
	            });
	            option.polar = polarNotRadar;
	        }
	        zrUtil.each(option.series, function (seriesOpt) {
	            if (seriesOpt.type === 'radar' && seriesOpt.polarIndex) {
	                seriesOpt.radarIndex = seriesOpt.polarIndex;
	            }
	        });
	    };


/***/ },
/* 169 */
/***/ function(module, exports, __webpack_require__) {

	

	    var echarts = __webpack_require__(1);
	    var PRIORITY = echarts.PRIORITY;

	    __webpack_require__(170);

	    __webpack_require__(181);

	    __webpack_require__(187);

	    __webpack_require__(171);

	    echarts.registerLayout(__webpack_require__(189));

	    echarts.registerVisual(__webpack_require__(190));

	    echarts.registerProcessor(PRIORITY.PROCESSOR.STATISTIC, __webpack_require__(191));

	    echarts.registerPreprocessor(__webpack_require__(192));

	    __webpack_require__(150)('map', [{
	        type: 'mapToggleSelect',
	        event: 'mapselectchanged',
	        method: 'toggleSelected'
	    }, {
	        type: 'mapSelect',
	        event: 'mapselected',
	        method: 'select'
	    }, {
	        type: 'mapUnSelect',
	        event: 'mapunselected',
	        method: 'unSelect'
	    }]);


/***/ },
/* 170 */
/***/ function(module, exports, __webpack_require__) {

	

	    var List = __webpack_require__(98);
	    var SeriesModel = __webpack_require__(78);
	    var zrUtil = __webpack_require__(4);
	    var completeDimensions = __webpack_require__(110);

	    var formatUtil = __webpack_require__(6);
	    var encodeHTML = formatUtil.encodeHTML;
	    var addCommas = formatUtil.addCommas;

	    var dataSelectableMixin = __webpack_require__(148);

	    var geoCreator = __webpack_require__(171);

	    var MapSeries = SeriesModel.extend({

	        type: 'series.map',

	        dependencies: ['geo'],

	        layoutMode: 'box',

	        /**
	         * Only first map series of same mapType will drawMap
	         * @type {boolean}
	         */
	        needsDrawMap: false,

	        /**
	         * Group of all map series with same mapType
	         * @type {boolean}
	         */
	        seriesGroup: [],

	        init: function (option) {

	            option = this._fillOption(option, this.getMapType());
	            this.option = option;

	            MapSeries.superApply(this, 'init', arguments);

	            this.updateSelectedMap(option.data);
	        },

	        getInitialData: function (option) {
	            var dimensions = completeDimensions(['value'], option.data || []);

	            var list = new List(dimensions, this);

	            list.initData(option.data);

	            return list;
	        },

	        mergeOption: function (newOption) {
	            if (newOption.data) {
	                newOption = this._fillOption(newOption, this.getMapType());
	            }

	            MapSeries.superCall(this, 'mergeOption', newOption);

	            this.updateSelectedMap(this.option.data);
	        },

	        /**
	         * If no host geo model, return null, which means using a
	         * inner exclusive geo model.
	         */
	        getHostGeoModel: function () {
	            var geoIndex = this.option.geoIndex;
	            return geoIndex != null
	                ? this.dependentModels.geo[geoIndex]
	                : null;
	        },

	        getMapType: function () {
	            return (this.getHostGeoModel() || this).option.map;
	        },

	        _fillOption: function (option, mapName) {
	            // Shallow clone
	            option = zrUtil.extend({}, option);

	            option.data = geoCreator.getFilledRegions(option.data, mapName);

	            return option;
	        },

	        getRawValue: function (dataIndex) {
	            // Use value stored in data instead because it is calculated from multiple series
	            // FIXME Provide all value of multiple series ?
	            return this.getData().get('value', dataIndex);
	        },

	        /**
	         * Get model of region
	         * @param  {string} name
	         * @return {module:echarts/model/Model}
	         */
	        getRegionModel: function (regionName) {
	            var data = this.getData();
	            return data.getItemModel(data.indexOfName(regionName));
	        },

	        /**
	         * Map tooltip formatter
	         *
	         * @param {number} dataIndex
	         */
	        formatTooltip: function (dataIndex) {
	            // FIXME orignalData and data is a bit confusing
	            var data = this.getData();
	            var formattedValue = addCommas(this.getRawValue(dataIndex));
	            var name = data.getName(dataIndex);

	            var seriesGroup = this.seriesGroup;
	            var seriesNames = [];
	            for (var i = 0; i < seriesGroup.length; i++) {
	                var otherIndex = seriesGroup[i].originalData.indexOfName(name);
	                if (!isNaN(seriesGroup[i].originalData.get('value', otherIndex))) {
	                    seriesNames.push(
	                        encodeHTML(seriesGroup[i].name)
	                    );
	                }
	            }

	            return seriesNames.join(', ') + '<br />'
	                + encodeHTML(name + ' : ' + formattedValue);
	        },

	        /**
	         * @implement
	         */
	        getTooltipPosition: function (dataIndex) {
	            if (dataIndex != null) {
	                var name = this.getData().getName(dataIndex);
	                var geo = this.coordinateSystem;
	                var region = geo.getRegion(name);

	                return region && geo.dataToPoint(region.center);
	            }
	        },

	        setZoom: function (zoom) {
	            this.option.zoom = zoom;
	        },

	        setCenter: function (center) {
	            this.option.center = center;
	        },

	        defaultOption: {
	            // 一级层叠
	            zlevel: 0,
	            // 二级层叠
	            z: 2,

	            coordinateSystem: 'geo',

	            // map should be explicitly specified since ec3.
	            map: '',

	            // If `geoIndex` is not specified, a exclusive geo will be
	            // created. Otherwise use the specified geo component, and
	            // `map` and `mapType` are ignored.
	            // geoIndex: 0,

	            // 'center' | 'left' | 'right' | 'x%' | {number}
	            left: 'center',
	            // 'center' | 'top' | 'bottom' | 'x%' | {number}
	            top: 'center',
	            // right
	            // bottom
	            // width:
	            // height

	            // Aspect is width / height. Inited to be geoJson bbox aspect
	            // This parameter is used for scale this aspect
	            aspectScale: 0.75,

	            ///// Layout with center and size
	            // If you wan't to put map in a fixed size box with right aspect ratio
	            // This two properties may more conveninet
	            // layoutCenter: [50%, 50%]
	            // layoutSize: 100


	            // 数值合并方式，默认加和，可选为：
	            // 'sum' | 'average' | 'max' | 'min'
	            // mapValueCalculation: 'sum',
	            // 地图数值计算结果小数精度
	            // mapValuePrecision: 0,


	            // 显示图例颜色标识（系列标识的小圆点），图例开启时有效
	            showLegendSymbol: true,
	            // 选择模式，默认关闭，可选single，multiple
	            // selectedMode: false,
	            dataRangeHoverLink: true,
	            // 是否开启缩放及漫游模式
	            // roam: false,

	            // Define left-top, right-bottom coords to control view
	            // For example, [ [180, 90], [-180, -90] ],
	            // higher priority than center and zoom
	            boundingCoords: null,

	            // Default on center of map
	            center: null,

	            zoom: 1,

	            scaleLimit: null,

	            label: {
	                normal: {
	                    show: false,
	                    textStyle: {
	                        color: '#000'
	                    }
	                },
	                emphasis: {
	                    show: true,
	                    textStyle: {
	                        color: 'rgb(100,0,0)'
	                    }
	                }
	            },
	            // scaleLimit: null,
	            itemStyle: {
	                normal: {
	                    // color: 各异,
	                    borderWidth: 0.5,
	                    borderColor: '#444',
	                    areaColor: '#eee'
	                },
	                // 也是选中样式
	                emphasis: {
	                    areaColor: 'rgba(255,215,0,0.8)'
	                }
	            }
	        }

	    });

	    zrUtil.mixin(MapSeries, dataSelectableMixin);

	    module.exports = MapSeries;


/***/ },
/* 171 */
/***/ function(module, exports, __webpack_require__) {

	

	    var Geo = __webpack_require__(172);

	    var layout = __webpack_require__(71);
	    var zrUtil = __webpack_require__(4);
	    var numberUtil = __webpack_require__(7);

	    var mapDataStores = {};

	    /**
	     * Resize method bound to the geo
	     * @param {module:echarts/coord/geo/GeoModel|module:echarts/chart/map/MapModel} geoModel
	     * @param {module:echarts/ExtensionAPI} api
	     */
	    function resizeGeo (geoModel, api) {

	        var boundingCoords = geoModel.get('boundingCoords');
	        if (boundingCoords != null) {
	            var leftTop = boundingCoords[0];
	            var rightBottom = boundingCoords[1];
	            if (isNaN(leftTop[0]) || isNaN(leftTop[1]) || isNaN(rightBottom[0]) || isNaN(rightBottom[1])) {
	                if (true) {
	                    console.error('Invalid boundingCoords');
	                }
	            }
	            else {
	                this.setBoundingRect(leftTop[0], leftTop[1], rightBottom[0] - leftTop[0], rightBottom[1] - leftTop[1]);
	            }
	        }

	        var rect = this.getBoundingRect();

	        var boxLayoutOption;

	        var center = geoModel.get('layoutCenter');
	        var size = geoModel.get('layoutSize');

	        var viewWidth = api.getWidth();
	        var viewHeight = api.getHeight();

	        var aspectScale = geoModel.get('aspectScale') || 0.75;
	        var aspect = rect.width / rect.height * aspectScale;

	        var useCenterAndSize = false;

	        if (center && size) {
	            center = [
	                numberUtil.parsePercent(center[0], viewWidth),
	                numberUtil.parsePercent(center[1], viewHeight)
	            ];
	            size = numberUtil.parsePercent(size, Math.min(viewWidth, viewHeight));

	            if (!isNaN(center[0]) && !isNaN(center[1]) && !isNaN(size)) {
	                useCenterAndSize = true;
	            }
	            else {
	                if (true) {
	                    console.warn('Given layoutCenter or layoutSize data are invalid. Use left/top/width/height instead.');
	                }
	            }
	        }

	        var viewRect;
	        if (useCenterAndSize) {
	            var viewRect = {};
	            if (aspect > 1) {
	                // Width is same with size
	                viewRect.width = size;
	                viewRect.height = size / aspect;
	            }
	            else {
	                viewRect.height = size;
	                viewRect.width = size * aspect;
	            }
	            viewRect.y = center[1] - viewRect.height / 2;
	            viewRect.x = center[0] - viewRect.width / 2;
	        }
	        else {
	            // Use left/top/width/height
	            boxLayoutOption = geoModel.getBoxLayoutParams();

	            // 0.75 rate
	            boxLayoutOption.aspect = aspect;

	            viewRect = layout.getLayoutRect(boxLayoutOption, {
	                width: viewWidth,
	                height: viewHeight
	            });
	        }

	        this.setViewRect(viewRect.x, viewRect.y, viewRect.width, viewRect.height);

	        this.setCenter(geoModel.get('center'));
	        this.setZoom(geoModel.get('zoom'));
	    }

	    /**
	     * @param {module:echarts/coord/Geo} geo
	     * @param {module:echarts/model/Model} model
	     * @inner
	     */
	    function setGeoCoords(geo, model) {
	        zrUtil.each(model.get('geoCoord'), function (geoCoord, name) {
	            geo.addGeoCoord(name, geoCoord);
	        });
	    }

	    if (true) {
	        var mapNotExistsError = function (name) {
	            console.error('Map ' + name + ' not exists. You can download map file on http://echarts.baidu.com/download-map.html');
	        };
	    }

	    var geoCreator = {

	        // For deciding which dimensions to use when creating list data
	        dimensions: Geo.prototype.dimensions,

	        create: function (ecModel, api) {
	            var geoList = [];

	            // FIXME Create each time may be slow
	            ecModel.eachComponent('geo', function (geoModel, idx) {
	                var name = geoModel.get('map');
	                var mapData = mapDataStores[name];
	                if (true) {
	                    if (!mapData) {
	                        mapNotExistsError(name);
	                    }
	                }
	                var geo = new Geo(
	                    name + idx, name,
	                    mapData && mapData.geoJson, mapData && mapData.specialAreas,
	                    geoModel.get('nameMap')
	                );
	                geo.zoomLimit = geoModel.get('scaleLimit');
	                geoList.push(geo);

	                setGeoCoords(geo, geoModel);

	                geoModel.coordinateSystem = geo;
	                geo.model = geoModel;

	                // Inject resize method
	                geo.resize = resizeGeo;

	                geo.resize(geoModel, api);
	            });

	            ecModel.eachSeries(function (seriesModel) {
	                var coordSys = seriesModel.get('coordinateSystem');
	                if (coordSys === 'geo') {
	                    var geoIndex = seriesModel.get('geoIndex') || 0;
	                    seriesModel.coordinateSystem = geoList[geoIndex];
	                }
	            });

	            // If has map series
	            var mapModelGroupBySeries = {};

	            ecModel.eachSeriesByType('map', function (seriesModel) {
	                if (!seriesModel.getHostGeoModel()) {
	                    var mapType = seriesModel.getMapType();
	                    mapModelGroupBySeries[mapType] = mapModelGroupBySeries[mapType] || [];
	                    mapModelGroupBySeries[mapType].push(seriesModel);
	                }
	            });

	            zrUtil.each(mapModelGroupBySeries, function (mapSeries, mapType) {
	                var mapData = mapDataStores[mapType];
	                if (true) {
	                    if (!mapData) {
	                        mapNotExistsError(mapSeries[0].get('map'));
	                    }
	                }

	                var nameMapList = zrUtil.map(mapSeries, function (singleMapSeries) {
	                    return singleMapSeries.get('nameMap');
	                });
	                var geo = new Geo(
	                    mapType, mapType,
	                    mapData && mapData.geoJson, mapData && mapData.specialAreas,
	                    zrUtil.mergeAll(nameMapList)
	                );
	                geo.zoomLimit = zrUtil.retrieve.apply(null, zrUtil.map(mapSeries, function (singleMapSeries) {
	                    return singleMapSeries.get('scaleLimit');
	                }));
	                geoList.push(geo);

	                // Inject resize method
	                geo.resize = resizeGeo;

	                geo.resize(mapSeries[0], api);

	                zrUtil.each(mapSeries, function (singleMapSeries) {
	                    singleMapSeries.coordinateSystem = geo;

	                    setGeoCoords(geo, singleMapSeries);
	                });
	            });

	            return geoList;
	        },

	        /**
	         * @param {string} mapName
	         * @param {Object|string} geoJson
	         * @param {Object} [specialAreas]
	         *
	         * @example
	         *     $.get('USA.json', function (geoJson) {
	         *         echarts.registerMap('USA', geoJson);
	         *         // Or
	         *         echarts.registerMap('USA', {
	         *             geoJson: geoJson,
	         *             specialAreas: {}
	         *         })
	         *     });
	         */
	        registerMap: function (mapName, geoJson, specialAreas) {
	            if (geoJson.geoJson && !geoJson.features) {
	                specialAreas = geoJson.specialAreas;
	                geoJson = geoJson.geoJson;
	            }
	            if (typeof geoJson === 'string') {
	                geoJson = (typeof JSON !== 'undefined' && JSON.parse)
	                    ? JSON.parse(geoJson) : (new Function('return (' + geoJson + ');'))();
	            }
	            mapDataStores[mapName] = {
	                geoJson: geoJson,
	                specialAreas: specialAreas
	            };
	        },

	        /**
	         * @param {string} mapName
	         * @return {Object}
	         */
	        getMap: function (mapName) {
	            return mapDataStores[mapName];
	        },

	        /**
	         * Fill given regions array
	         * @param  {Array.<Object>} originRegionArr
	         * @param  {string} mapName
	         * @return {Array}
	         */
	        getFilledRegions: function (originRegionArr, mapName) {
	            // Not use the original
	            var regionsArr = (originRegionArr || []).slice();

	            var map = geoCreator.getMap(mapName);
	            var geoJson = map && map.geoJson;
	            if (!geoJson) {
	                if (true) {
	                    mapNotExistsError(mapName);
	                }
	                return originRegionArr;
	            }

	            var dataNameMap = zrUtil.createHashMap();
	            var features = geoJson.features;
	            for (var i = 0; i < regionsArr.length; i++) {
	                dataNameMap.set(regionsArr[i].name, regionsArr[i]);
	            }

	            for (var i = 0; i < features.length; i++) {
	                var name = features[i].properties.name;
	                if (!dataNameMap.get(name)) {
	                    regionsArr.push({
	                        name: name
	                    });
	                }
	            }
	            return regionsArr;
	        }
	    };

	    // Inject methods into echarts
	    var echarts = __webpack_require__(1);

	    echarts.registerMap = geoCreator.registerMap;

	    echarts.getMap = geoCreator.getMap;

	    echarts.parseGeoJSON = __webpack_require__(173);

	    // TODO
	    echarts.loadMap = function () {};

	    echarts.registerCoordinateSystem('geo', geoCreator);

	    module.exports = geoCreator;


/***/ },
/* 172 */
/***/ function(module, exports, __webpack_require__) {

	

	    var parseGeoJson = __webpack_require__(173);

	    var zrUtil = __webpack_require__(4);

	    var BoundingRect = __webpack_require__(9);

	    var View = __webpack_require__(176);


	    // Geo fix functions
	    var geoFixFuncs = [
	        __webpack_require__(177),
	        __webpack_require__(178),
	        __webpack_require__(179),
	        __webpack_require__(180)
	    ];

	    /**
	     * [Geo description]
	     * @param {string} name Geo name
	     * @param {string} map Map type
	     * @param {Object} geoJson
	     * @param {Object} [specialAreas]
	     *        Specify the positioned areas by left, top, width, height
	     * @param {Object.<string, string>} [nameMap]
	     *        Specify name alias
	     */
	    function Geo(name, map, geoJson, specialAreas, nameMap) {

	        View.call(this, name);

	        /**
	         * Map type
	         * @type {string}
	         */
	        this.map = map;

	        this._nameCoordMap = zrUtil.createHashMap();

	        this.loadGeoJson(geoJson, specialAreas, nameMap);
	    }

	    Geo.prototype = {

	        constructor: Geo,

	        type: 'geo',

	        /**
	         * @param {Array.<string>}
	         * @readOnly
	         */
	        dimensions: ['lng', 'lat'],

	        /**
	         * If contain given lng,lat coord
	         * @param {Array.<number>}
	         * @readOnly
	         */
	        containCoord: function (coord) {
	            var regions = this.regions;
	            for (var i = 0; i < regions.length; i++) {
	                if (regions[i].contain(coord)) {
	                    return true;
	                }
	            }
	            return false;
	        },
	        /**
	         * @param {Object} geoJson
	         * @param {Object} [specialAreas]
	         *        Specify the positioned areas by left, top, width, height
	         * @param {Object.<string, string>} [nameMap]
	         *        Specify name alias
	         */
	        loadGeoJson: function (geoJson, specialAreas, nameMap) {
	            // https://jsperf.com/try-catch-performance-overhead
	            try {
	                this.regions = geoJson ? parseGeoJson(geoJson) : [];
	            }
	            catch (e) {
	                throw 'Invalid geoJson format\n' + e.message;
	            }
	            specialAreas = specialAreas || {};
	            nameMap = nameMap || {};
	            var regions = this.regions;
	            var regionsMap = zrUtil.createHashMap();
	            for (var i = 0; i < regions.length; i++) {
	                var regionName = regions[i].name;
	                // Try use the alias in nameMap
	                regionName = nameMap.hasOwnProperty(regionName) ? nameMap[regionName] : regionName;
	                regions[i].name = regionName;

	                regionsMap.set(regionName, regions[i]);
	                // Add geoJson
	                this.addGeoCoord(regionName, regions[i].center);

	                // Some area like Alaska in USA map needs to be tansformed
	                // to look better
	                var specialArea = specialAreas[regionName];
	                if (specialArea) {
	                    regions[i].transformTo(
	                        specialArea.left, specialArea.top, specialArea.width, specialArea.height
	                    );
	                }
	            }

	            this._regionsMap = regionsMap;

	            this._rect = null;

	            zrUtil.each(geoFixFuncs, function (fixFunc) {
	                fixFunc(this);
	            }, this);
	        },

	        // Overwrite
	        transformTo: function (x, y, width, height) {
	            var rect = this.getBoundingRect();

	            rect = rect.clone();
	            // Longitute is inverted
	            rect.y = -rect.y - rect.height;

	            var viewTransform = this._viewTransform;

	            viewTransform.transform = rect.calculateTransform(
	                new BoundingRect(x, y, width, height)
	            );

	            viewTransform.decomposeTransform();

	            var scale = viewTransform.scale;
	            scale[1] = -scale[1];

	            viewTransform.updateTransform();

	            this._updateTransform();
	        },

	        /**
	         * @param {string} name
	         * @return {module:echarts/coord/geo/Region}
	         */
	        getRegion: function (name) {
	            return this._regionsMap.get(name);
	        },

	        getRegionByCoord: function (coord) {
	            var regions = this.regions;
	            for (var i = 0; i < regions.length; i++) {
	                if (regions[i].contain(coord)) {
	                    return regions[i];
	                }
	            }
	        },

	        /**
	         * Add geoCoord for indexing by name
	         * @param {string} name
	         * @param {Array.<number>} geoCoord
	         */
	        addGeoCoord: function (name, geoCoord) {
	            this._nameCoordMap.set(name, geoCoord);
	        },

	        /**
	         * Get geoCoord by name
	         * @param {string} name
	         * @return {Array.<number>}
	         */
	        getGeoCoord: function (name) {
	            return this._nameCoordMap.get(name);
	        },

	        // Overwrite
	        getBoundingRect: function () {
	            if (this._rect) {
	                return this._rect;
	            }
	            var rect;

	            var regions = this.regions;
	            for (var i = 0; i < regions.length; i++) {
	                var regionRect = regions[i].getBoundingRect();
	                rect = rect || regionRect.clone();
	                rect.union(regionRect);
	            }
	            // FIXME Always return new ?
	            return (this._rect = rect || new BoundingRect(0, 0, 0, 0));
	        },

	        /**
	         * Convert series data to a list of points
	         * @param {module:echarts/data/List} data
	         * @param {boolean} stack
	         * @return {Array}
	         *  Return list of points. For example:
	         *  `[[10, 10], [20, 20], [30, 30]]`
	         */
	        dataToPoints: function (data) {
	            var item = [];
	            return data.mapArray(['lng', 'lat'], function (lon, lat) {
	                item[0] = lon;
	                item[1] = lat;
	                return this.dataToPoint(item);
	            }, this);
	        },

	        /**
	         * @param {string|Array.<number>} data
	         * @return {Array.<number>}
	         */
	        dataToPoint: function (data) {
	            if (typeof data === 'string') {
	                // Map area name to geoCoord
	                data = this.getGeoCoord(data);
	            }
	            if (data) {
	                return View.prototype.dataToPoint.call(this, data);
	            }
	        },

	        /**
	         * @inheritDoc
	         */
	        convertToPixel: zrUtil.curry(doConvert, 'dataToPoint'),

	        /**
	         * @inheritDoc
	         */
	        convertFromPixel: zrUtil.curry(doConvert, 'pointToData')

	    };

	    zrUtil.mixin(Geo, View);

	    function doConvert(methodName, ecModel, finder, value) {
	        var geoModel = finder.geoModel;
	        var seriesModel = finder.seriesModel;

	        var coordSys = geoModel
	            ? geoModel.coordinateSystem
	            : seriesModel
	            ? (
	                seriesModel.coordinateSystem // For map.
	                || (seriesModel.getReferringComponents('geo')[0] || {}).coordinateSystem
	            )
	            : null;

	        return coordSys === this ? coordSys[methodName](value) : null;
	    }

	    module.exports = Geo;


/***/ },
/* 173 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * Parse and decode geo json
	 * @module echarts/coord/geo/parseGeoJson
	 */


	    var zrUtil = __webpack_require__(4);

	    var Region = __webpack_require__(174);

	    function decode(json) {
	        if (!json.UTF8Encoding) {
	            return json;
	        }
	        var encodeScale = json.UTF8Scale;
	        if (encodeScale == null) {
	            encodeScale = 1024;
	        }

	        var features = json.features;

	        for (var f = 0; f < features.length; f++) {
	            var feature = features[f];
	            var geometry = feature.geometry;
	            var coordinates = geometry.coordinates;
	            var encodeOffsets = geometry.encodeOffsets;

	            for (var c = 0; c < coordinates.length; c++) {
	                var coordinate = coordinates[c];

	                if (geometry.type === 'Polygon') {
	                    coordinates[c] = decodePolygon(
	                        coordinate,
	                        encodeOffsets[c],
	                        encodeScale
	                    );
	                }
	                else if (geometry.type === 'MultiPolygon') {
	                    for (var c2 = 0; c2 < coordinate.length; c2++) {
	                        var polygon = coordinate[c2];
	                        coordinate[c2] = decodePolygon(
	                            polygon,
	                            encodeOffsets[c][c2],
	                            encodeScale
	                        );
	                    }
	                }
	            }
	        }
	        // Has been decoded
	        json.UTF8Encoding = false;
	        return json;
	    }

	    function decodePolygon(coordinate, encodeOffsets, encodeScale) {
	        var result = [];
	        var prevX = encodeOffsets[0];
	        var prevY = encodeOffsets[1];

	        for (var i = 0; i < coordinate.length; i += 2) {
	            var x = coordinate.charCodeAt(i) - 64;
	            var y = coordinate.charCodeAt(i + 1) - 64;
	            // ZigZag decoding
	            x = (x >> 1) ^ (-(x & 1));
	            y = (y >> 1) ^ (-(y & 1));
	            // Delta deocding
	            x += prevX;
	            y += prevY;

	            prevX = x;
	            prevY = y;
	            // Dequantize
	            result.push([x / encodeScale, y / encodeScale]);
	        }

	        return result;
	    }

	    /**
	     * @alias module:echarts/coord/geo/parseGeoJson
	     * @param {Object} geoJson
	     * @return {module:zrender/container/Group}
	     */
	    module.exports = function (geoJson) {

	        decode(geoJson);

	        return zrUtil.map(zrUtil.filter(geoJson.features, function (featureObj) {
	            // Output of mapshaper may have geometry null
	            return featureObj.geometry
	                && featureObj.properties
	                && featureObj.geometry.coordinates.length > 0;
	        }), function (featureObj) {
	            var properties = featureObj.properties;
	            var geo = featureObj.geometry;

	            var coordinates = geo.coordinates;

	            var geometries = [];
	            if (geo.type === 'Polygon') {
	                geometries.push({
	                    type: 'polygon',
	                    // According to the GeoJSON specification.
	                    // First must be exterior, and the rest are all interior(holes).
	                    exterior: coordinates[0],
	                    interiors: coordinates.slice(1)
	                });
	            }
	            if (geo.type === 'MultiPolygon') {
	                zrUtil.each(coordinates, function (item) {
	                    if (item[0]) {
	                        geometries.push({
	                            type: 'polygon',
	                            exterior: item[0],
	                            interiors: item.slice(1)
	                        });
	                    }
	                });
	            }

	            var region = new Region(
	                properties.name,
	                geometries,
	                properties.cp
	            );
	            region.properties = properties;
	            return region;
	        });
	    };


/***/ },
/* 174 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @module echarts/coord/geo/Region
	 */


	    var polygonContain = __webpack_require__(175);

	    var BoundingRect = __webpack_require__(9);

	    var bbox = __webpack_require__(38);
	    var vec2 = __webpack_require__(10);

	    /**
	     * @param {string} name
	     * @param {Array} geometries
	     * @param {Array.<number>} cp
	     */
	    function Region(name, geometries, cp) {

	        /**
	         * @type {string}
	         * @readOnly
	         */
	        this.name = name;

	        /**
	         * @type {Array.<Array>}
	         * @readOnly
	         */
	        this.geometries = geometries;

	        if (!cp) {
	            var rect = this.getBoundingRect();
	            cp = [
	                rect.x + rect.width / 2,
	                rect.y + rect.height / 2
	            ];
	        }
	        else {
	            cp = [cp[0], cp[1]];
	        }
	        /**
	         * @type {Array.<number>}
	         */
	        this.center = cp;
	    }

	    Region.prototype = {

	        constructor: Region,

	        properties: null,

	        /**
	         * @return {module:zrender/core/BoundingRect}
	         */
	        getBoundingRect: function () {
	            var rect = this._rect;
	            if (rect) {
	                return rect;
	            }

	            var MAX_NUMBER = Number.MAX_VALUE;
	            var min = [MAX_NUMBER, MAX_NUMBER];
	            var max = [-MAX_NUMBER, -MAX_NUMBER];
	            var min2 = [];
	            var max2 = [];
	            var geometries = this.geometries;
	            for (var i = 0; i < geometries.length; i++) {
	                // Only support polygon
	                if (geometries[i].type !== 'polygon') {
	                    continue;
	                }
	                // Doesn't consider hole
	                var exterior = geometries[i].exterior;
	                bbox.fromPoints(exterior, min2, max2);
	                vec2.min(min, min, min2);
	                vec2.max(max, max, max2);
	            }
	            // No data
	            if (i === 0) {
	                min[0] = min[1] = max[0] = max[1] = 0;
	            }

	            return (this._rect = new BoundingRect(
	                min[0], min[1], max[0] - min[0], max[1] - min[1]
	            ));
	        },

	        /**
	         * @param {<Array.<number>} coord
	         * @return {boolean}
	         */
	        contain: function (coord) {
	            var rect = this.getBoundingRect();
	            var geometries = this.geometries;
	            if (!rect.contain(coord[0], coord[1])) {
	                return false;
	            }
	            loopGeo: for (var i = 0, len = geometries.length; i < len; i++) {
	                // Only support polygon.
	                if (geometries[i].type !== 'polygon') {
	                    continue;
	                }
	                var exterior = geometries[i].exterior;
	                var interiors = geometries[i].interiors;
	                if (polygonContain.contain(exterior, coord[0], coord[1])) {
	                    // Not in the region if point is in the hole.
	                    for (var k = 0; k < (interiors ? interiors.length : 0); k++) {
	                        if (polygonContain.contain(interiors[k])) {
	                            continue loopGeo;
	                        }
	                    }
	                    return true;
	                }
	            }
	            return false;
	        },

	        transformTo: function (x, y, width, height) {
	            var rect = this.getBoundingRect();
	            var aspect = rect.width / rect.height;
	            if (!width) {
	                width = aspect * height;
	            }
	            else if (!height) {
	                height = width / aspect ;
	            }
	            var target = new BoundingRect(x, y, width, height);
	            var transform = rect.calculateTransform(target);
	            var geometries = this.geometries;
	            for (var i = 0; i < geometries.length; i++) {
	                // Only support polygon.
	                if (geometries[i].type !== 'polygon') {
	                    continue;
	                }
	                var exterior = geometries[i].exterior;
	                var interiors = geometries[i].interiors;
	                for (var p = 0; p < exterior.length; p++) {
	                    vec2.applyTransform(exterior[p], exterior[p], transform);
	                }
	                for (var h = 0; h < (interiors ? interiors.length : 0); h++) {
	                    for (var p = 0; p < interiors[h].length; p++) {
	                        vec2.applyTransform(interiors[h][p], interiors[h][p], transform);
	                    }
	                }
	            }
	            rect = this._rect;
	            rect.copy(target);
	            // Update center
	            this.center = [
	                rect.x + rect.width / 2,
	                rect.y + rect.height / 2
	            ];
	        }
	    };

	    module.exports = Region;


/***/ },
/* 175 */
/***/ function(module, exports, __webpack_require__) {

	

	    var windingLine = __webpack_require__(45);

	    var EPSILON = 1e-8;

	    function isAroundEqual(a, b) {
	        return Math.abs(a - b) < EPSILON;
	    }

	    function contain(points, x, y) {
	        var w = 0;
	        var p = points[0];

	        if (!p) {
	            return false;
	        }

	        for (var i = 1; i < points.length; i++) {
	            var p2 = points[i];
	            w += windingLine(p[0], p[1], p2[0], p2[1], x, y);
	            p = p2;
	        }

	        // Close polygon
	        var p0 = points[0];
	        if (!isAroundEqual(p[0], p0[0]) || !isAroundEqual(p[1], p0[1])) {
	            w += windingLine(p[0], p[1], p0[0], p0[1], x, y);
	        }

	        return w !== 0;
	    }


	    module.exports = {
	        contain: contain
	    };


/***/ },
/* 176 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * Simple view coordinate system
	 * Mapping given x, y to transformd view x, y
	 */


	    var vector = __webpack_require__(10);
	    var matrix = __webpack_require__(11);

	    var Transformable = __webpack_require__(26);
	    var zrUtil = __webpack_require__(4);

	    var BoundingRect = __webpack_require__(9);

	    var v2ApplyTransform = vector.applyTransform;

	    // Dummy transform node
	    function TransformDummy() {
	        Transformable.call(this);
	    }
	    zrUtil.mixin(TransformDummy, Transformable);

	    function View(name) {
	        /**
	         * @type {string}
	         */
	        this.name = name;

	        /**
	         * @type {Object}
	         */
	        this.zoomLimit;

	        Transformable.call(this);

	        this._roamTransform = new TransformDummy();

	        this._viewTransform = new TransformDummy();

	        this._center;
	        this._zoom;
	    }

	    View.prototype = {

	        constructor: View,

	        type: 'view',

	        /**
	         * @param {Array.<string>}
	         * @readOnly
	         */
	        dimensions: ['x', 'y'],

	        /**
	         * Set bounding rect
	         * @param {number} x
	         * @param {number} y
	         * @param {number} width
	         * @param {number} height
	         */

	        // PENDING to getRect
	        setBoundingRect: function (x, y, width, height) {
	            this._rect = new BoundingRect(x, y, width, height);
	            return this._rect;
	        },

	        /**
	         * @return {module:zrender/core/BoundingRect}
	         */
	        // PENDING to getRect
	        getBoundingRect: function () {
	            return this._rect;
	        },

	        /**
	         * @param {number} x
	         * @param {number} y
	         * @param {number} width
	         * @param {number} height
	         */
	        setViewRect: function (x, y, width, height) {
	            this.transformTo(x, y, width, height);
	            this._viewRect = new BoundingRect(x, y, width, height);
	        },

	        /**
	         * Transformed to particular position and size
	         * @param {number} x
	         * @param {number} y
	         * @param {number} width
	         * @param {number} height
	         */
	        transformTo: function (x, y, width, height) {
	            var rect = this.getBoundingRect();
	            var viewTransform = this._viewTransform;

	            viewTransform.transform = rect.calculateTransform(
	                new BoundingRect(x, y, width, height)
	            );

	            viewTransform.decomposeTransform();

	            this._updateTransform();
	        },

	        /**
	         * Set center of view
	         * @param {Array.<number>} [centerCoord]
	         */
	        setCenter: function (centerCoord) {
	            if (!centerCoord) {
	                return;
	            }
	            this._center = centerCoord;

	            this._updateCenterAndZoom();
	        },

	        /**
	         * @param {number} zoom
	         */
	        setZoom: function (zoom) {
	            zoom = zoom || 1;

	            var zoomLimit = this.zoomLimit;
	            if (zoomLimit) {
	                if (zoomLimit.max != null) {
	                    zoom = Math.min(zoomLimit.max, zoom);
	                }
	                if (zoomLimit.min != null) {
	                    zoom = Math.max(zoomLimit.min, zoom);
	                }
	            }
	            this._zoom = zoom;

	            this._updateCenterAndZoom();
	        },

	        /**
	         * Get default center without roam
	         */
	        getDefaultCenter: function () {
	            // Rect before any transform
	            var rawRect = this.getBoundingRect();
	            var cx = rawRect.x + rawRect.width / 2;
	            var cy = rawRect.y + rawRect.height / 2;

	            return [cx, cy];
	        },

	        getCenter: function () {
	            return this._center || this.getDefaultCenter();
	        },

	        getZoom: function () {
	            return this._zoom || 1;
	        },

	        /**
	         * @return {Array.<number}
	         */
	        getRoamTransform: function () {
	            return this._roamTransform;
	        },

	        _updateCenterAndZoom: function () {
	            // Must update after view transform updated
	            var viewTransformMatrix = this._viewTransform.getLocalTransform();
	            var roamTransform = this._roamTransform;
	            var defaultCenter = this.getDefaultCenter();
	            var center = this.getCenter();
	            var zoom = this.getZoom();

	            center = vector.applyTransform([], center, viewTransformMatrix);
	            defaultCenter = vector.applyTransform([], defaultCenter, viewTransformMatrix);

	            roamTransform.origin = center;
	            roamTransform.position = [
	                defaultCenter[0] - center[0],
	                defaultCenter[1] - center[1]
	            ];
	            roamTransform.scale = [zoom, zoom];

	            this._updateTransform();
	        },

	        /**
	         * Update transform from roam and mapLocation
	         * @private
	         */
	        _updateTransform: function () {
	            var roamTransform = this._roamTransform;
	            var viewTransform = this._viewTransform;

	            viewTransform.parent = roamTransform;
	            roamTransform.updateTransform();
	            viewTransform.updateTransform();

	            viewTransform.transform
	                && matrix.copy(this.transform || (this.transform = []), viewTransform.transform);

	            if (this.transform) {
	                this.invTransform = this.invTransform || [];
	                matrix.invert(this.invTransform, this.transform);
	            }
	            else {
	                this.invTransform = null;
	            }
	            this.decomposeTransform();
	        },

	        /**
	         * @return {module:zrender/core/BoundingRect}
	         */
	        getViewRect: function () {
	            return this._viewRect;
	        },

	        /**
	         * Get view rect after roam transform
	         * @return {module:zrender/core/BoundingRect}
	         */
	        getViewRectAfterRoam: function () {
	            var rect = this.getBoundingRect().clone();
	            rect.applyTransform(this.transform);
	            return rect;
	        },

	        /**
	         * Convert a single (lon, lat) data item to (x, y) point.
	         * @param {Array.<number>} data
	         * @return {Array.<number>}
	         */
	        dataToPoint: function (data) {
	            var transform = this.transform;
	            return transform
	                ? v2ApplyTransform([], data, transform)
	                : [data[0], data[1]];
	        },

	        /**
	         * Convert a (x, y) point to (lon, lat) data
	         * @param {Array.<number>} point
	         * @return {Array.<number>}
	         */
	        pointToData: function (point) {
	            var invTransform = this.invTransform;
	            return invTransform
	                ? v2ApplyTransform([], point, invTransform)
	                : [point[0], point[1]];
	        },

	        /**
	         * @implements
	         * see {module:echarts/CoodinateSystem}
	         */
	        convertToPixel: zrUtil.curry(doConvert, 'dataToPoint'),

	        /**
	         * @implements
	         * see {module:echarts/CoodinateSystem}
	         */
	        convertFromPixel: zrUtil.curry(doConvert, 'pointToData'),

	        /**
	         * @implements
	         * see {module:echarts/CoodinateSystem}
	         */
	        containPoint: function (point) {
	            return this.getViewRectAfterRoam().contain(point[0], point[1]);
	        }

	        /**
	         * @return {number}
	         */
	        // getScalarScale: function () {
	        //     // Use determinant square root of transform to mutiply scalar
	        //     var m = this.transform;
	        //     var det = Math.sqrt(Math.abs(m[0] * m[3] - m[2] * m[1]));
	        //     return det;
	        // }
	    };

	    zrUtil.mixin(View, Transformable);

	    function doConvert(methodName, ecModel, finder, value) {
	        var seriesModel = finder.seriesModel;
	        var coordSys = seriesModel ? seriesModel.coordinateSystem : null; // e.g., graph.
	        return coordSys === this ? coordSys[methodName](value) : null;
	    }

	    module.exports = View;


/***/ },
/* 177 */
/***/ function(module, exports, __webpack_require__) {

	// Fix for 南海诸岛


	    var Region = __webpack_require__(174);
	    var zrUtil = __webpack_require__(4);

	    var geoCoord = [126, 25];

	    var points = [
	        [[0,3.5],[7,11.2],[15,11.9],[30,7],[42,0.7],[52,0.7],
	         [56,7.7],[59,0.7],[64,0.7],[64,0],[5,0],[0,3.5]],
	        [[13,16.1],[19,14.7],[16,21.7],[11,23.1],[13,16.1]],
	        [[12,32.2],[14,38.5],[15,38.5],[13,32.2],[12,32.2]],
	        [[16,47.6],[12,53.2],[13,53.2],[18,47.6],[16,47.6]],
	        [[6,64.4],[8,70],[9,70],[8,64.4],[6,64.4]],
	        [[23,82.6],[29,79.8],[30,79.8],[25,82.6],[23,82.6]],
	        [[37,70.7],[43,62.3],[44,62.3],[39,70.7],[37,70.7]],
	        [[48,51.1],[51,45.5],[53,45.5],[50,51.1],[48,51.1]],
	        [[51,35],[51,28.7],[53,28.7],[53,35],[51,35]],
	        [[52,22.4],[55,17.5],[56,17.5],[53,22.4],[52,22.4]],
	        [[58,12.6],[62,7],[63,7],[60,12.6],[58,12.6]],
	        [[0,3.5],[0,93.1],[64,93.1],[64,0],[63,0],[63,92.4],
	         [1,92.4],[1,3.5],[0,3.5]]
	    ];
	    for (var i = 0; i < points.length; i++) {
	        for (var k = 0; k < points[i].length; k++) {
	            points[i][k][0] /= 10.5;
	            points[i][k][1] /= -10.5 / 0.75;

	            points[i][k][0] += geoCoord[0];
	            points[i][k][1] += geoCoord[1];
	        }
	    }
	    module.exports = function (geo) {
	        if (geo.map === 'china') {
	            geo.regions.push(new Region(
	                '南海诸岛',
	                zrUtil.map(points, function (exterior) {
	                    return {
	                        type: 'polygon',
	                        exterior: exterior
	                    };
	                }), geoCoord
	            ));
	        }
	    };


/***/ },
/* 178 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);

	    var coordsOffsetMap = {
	        '南海诸岛' : [32, 80],
	        // 全国
	        '广东': [0, -10],
	        '香港': [10, 5],
	        '澳门': [-10, 10],
	        //'北京': [-10, 0],
	        '天津': [5, 5]
	    };

	    module.exports = function (geo) {
	        zrUtil.each(geo.regions, function (region) {
	            var coordFix = coordsOffsetMap[region.name];
	            if (coordFix) {
	                var cp = region.center;
	                cp[0] += coordFix[0] / 10.5;
	                cp[1] += -coordFix[1] / (10.5 / 0.75);
	            }
	        });
	    };


/***/ },
/* 179 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);

	    var geoCoordMap = {
	        'Russia': [100, 60],
	        'United States': [-99, 38],
	        'United States of America': [-99, 38]
	    };

	    module.exports = function (geo) {
	        zrUtil.each(geo.regions, function (region) {
	            var geoCoord = geoCoordMap[region.name];
	            if (geoCoord) {
	                var cp = region.center;
	                cp[0] = geoCoord[0];
	                cp[1] = geoCoord[1];
	            }
	        });
	    };


/***/ },
/* 180 */
/***/ function(module, exports, __webpack_require__) {

	// Fix for 钓鱼岛


	    var Region = __webpack_require__(174);
	    var zrUtil = __webpack_require__(4);

	    var geoCoord = [126, 25];

	    var points = [
	        [
	            [123.45165252685547, 25.73527164402261],
	            [123.49731445312499, 25.73527164402261],
	            [123.49731445312499, 25.750734064600884],
	            [123.45165252685547, 25.750734064600884],
	            [123.45165252685547, 25.73527164402261]
	        ]
	    ];
	    module.exports = function (geo) {
	        if (geo.map === 'china') {
	            for (var i = 0, len = geo.regions.length; i < len; ++i) {
	                if (geo.regions[i].name === '台湾') {
	                    geo.regions[i].geometries.push({
	                        type: 'polygon',
	                        exterior: points[0]
	                    });
	                }
	            }
	        }
	    };



/***/ },
/* 181 */
/***/ function(module, exports, __webpack_require__) {

	

	    // var zrUtil = require('zrender/lib/core/util');
	    var graphic = __webpack_require__(18);

	    var MapDraw = __webpack_require__(182);

	    __webpack_require__(1).extendChartView({

	        type: 'map',

	        render: function (mapModel, ecModel, api, payload) {
	            // Not render if it is an toggleSelect action from self
	            if (payload && payload.type === 'mapToggleSelect'
	                && payload.from === this.uid
	            ) {
	                return;
	            }

	            var group = this.group;
	            group.removeAll();

	            if (mapModel.getHostGeoModel()) {
	                return;
	            }

	            // Not update map if it is an roam action from self
	            if (!(payload && payload.type === 'geoRoam'
	                    && payload.componentType === 'series'
	                    && payload.seriesId === mapModel.id
	                )
	            ) {
	                if (mapModel.needsDrawMap) {
	                    var mapDraw = this._mapDraw || new MapDraw(api, true);
	                    group.add(mapDraw.group);

	                    mapDraw.draw(mapModel, ecModel, api, this, payload);

	                    this._mapDraw = mapDraw;
	                }
	                else {
	                    // Remove drawed map
	                    this._mapDraw && this._mapDraw.remove();
	                    this._mapDraw = null;
	                }
	            }
	            else {
	                var mapDraw = this._mapDraw;
	                mapDraw && group.add(mapDraw.group);
	            }

	            mapModel.get('showLegendSymbol') && ecModel.getComponent('legend')
	                && this._renderSymbols(mapModel, ecModel, api);
	        },

	        remove: function () {
	            this._mapDraw && this._mapDraw.remove();
	            this._mapDraw = null;
	            this.group.removeAll();
	        },

	        dispose: function () {
	            this._mapDraw && this._mapDraw.remove();
	            this._mapDraw = null;
	        },

	        _renderSymbols: function (mapModel, ecModel, api) {
	            var originalData = mapModel.originalData;
	            var group = this.group;

	            originalData.each('value', function (value, idx) {
	                if (isNaN(value)) {
	                    return;
	                }

	                var layout = originalData.getItemLayout(idx);

	                if (!layout || !layout.point) {
	                    // Not exists in map
	                    return;
	                }

	                var point = layout.point;
	                var offset = layout.offset;

	                var circle = new graphic.Circle({
	                    style: {
	                        // Because the special of map draw.
	                        // Which needs statistic of multiple series and draw on one map.
	                        // And each series also need a symbol with legend color
	                        //
	                        // Layout and visual are put one the different data
	                        fill: mapModel.getData().getVisual('color')
	                    },
	                    shape: {
	                        cx: point[0] + offset * 9,
	                        cy: point[1],
	                        r: 3
	                    },
	                    silent: true,
	                    z2: 10
	                });

	                // First data on the same region
	                if (!offset) {
	                    var fullData = mapModel.mainSeries.getData();
	                    var name = originalData.getName(idx);
	                    var labelText = name;
	                    var fullIndex = fullData.indexOfName(name);

	                    var itemModel = originalData.getItemModel(idx);
	                    var labelModel = itemModel.getModel('label.normal');
	                    var hoverLabelModel = itemModel.getModel('label.emphasis');

	                    var textStyleModel = labelModel.getModel('textStyle');
	                    var hoverTextStyleModel = hoverLabelModel.getModel('textStyle');

	                    var polygonGroups = fullData.getItemGraphicEl(fullIndex);
	                    circle.setStyle({
	                        textPosition: 'bottom'
	                    });

	                    var onEmphasis = function () {
	                        circle.setStyle({
	                            text: hoverLabelModel.get('show') ? labelText : '',
	                            textFill: hoverTextStyleModel.getTextColor(),
	                            textFont: hoverTextStyleModel.getFont()
	                        });
	                    };

	                    var onNormal = function () {
	                        circle.setStyle({
	                            text: labelModel.get('show') ? labelText : '',
	                            textFill: textStyleModel.getTextColor(),
	                            textFont: textStyleModel.getFont()
	                        });
	                    };

	                    polygonGroups.on('mouseover', onEmphasis)
	                        .on('mouseout', onNormal)
	                        .on('emphasis', onEmphasis)
	                        .on('normal', onNormal);

	                    onNormal();
	                }

	                group.add(circle);
	            });
	        }
	    });


/***/ },
/* 182 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @module echarts/component/helper/MapDraw
	 */


	    var RoamController = __webpack_require__(183);
	    var roamHelper = __webpack_require__(185);
	    var cursorHelper = __webpack_require__(186);
	    var graphic = __webpack_require__(18);
	    var zrUtil = __webpack_require__(4);

	    function getFixedItemStyle(model, scale) {
	        var itemStyle = model.getItemStyle();
	        var areaColor = model.get('areaColor');

	        // If user want the color not to be changed when hover,
	        // they should both set areaColor and color to be null.
	        if (areaColor != null) {
	            itemStyle.fill = areaColor;
	        }

	        return itemStyle;
	    }

	    function updateMapSelectHandler(mapDraw, mapOrGeoModel, group, api, fromView) {
	        group.off('click');
	        group.off('mousedown');

	        if (mapOrGeoModel.get('selectedMode')) {

	            group.on('mousedown', function () {
	                mapDraw._mouseDownFlag = true;
	            });

	            group.on('click', function (e) {
	                if (!mapDraw._mouseDownFlag) {
	                    return;
	                }
	                mapDraw._mouseDownFlag = false;

	                var el = e.target;
	                while (!el.__regions) {
	                    el = el.parent;
	                }
	                if (!el) {
	                    return;
	                }

	                var action = {
	                    type: (mapOrGeoModel.mainType === 'geo' ? 'geo' : 'map') + 'ToggleSelect',
	                    batch: zrUtil.map(el.__regions, function (region) {
	                        return {
	                            name: region.name,
	                            from: fromView.uid
	                        };
	                    })
	                };
	                action[mapOrGeoModel.mainType + 'Id'] = mapOrGeoModel.id;

	                api.dispatchAction(action);

	                updateMapSelected(mapOrGeoModel, group);
	            });
	        }
	    }

	    function updateMapSelected(mapOrGeoModel, group) {
	        // FIXME
	        group.eachChild(function (otherRegionEl) {
	            zrUtil.each(otherRegionEl.__regions, function (region) {
	                otherRegionEl.trigger(mapOrGeoModel.isSelected(region.name) ? 'emphasis' : 'normal');
	            });
	        });
	    }

	    /**
	     * @alias module:echarts/component/helper/MapDraw
	     * @param {module:echarts/ExtensionAPI} api
	     * @param {boolean} updateGroup
	     */
	    function MapDraw(api, updateGroup) {

	        var group = new graphic.Group();

	        /**
	         * @type {module:echarts/component/helper/RoamController}
	         * @private
	         */
	        this._controller = new RoamController(api.getZr());

	        /**
	         * @type {Object} {target, zoom, zoomLimit}
	         * @private
	         */
	        this._controllerHost = {target: updateGroup ? group : null};

	        /**
	         * @type {module:zrender/container/Group}
	         * @readOnly
	         */
	        this.group = group;

	        /**
	         * @type {boolean}
	         * @private
	         */
	        this._updateGroup = updateGroup;

	        /**
	         * This flag is used to make sure that only one among
	         * `pan`, `zoom`, `click` can occurs, otherwise 'selected'
	         * action may be triggered when `pan`, which is unexpected.
	         * @type {booelan}
	         */
	        this._mouseDownFlag;
	    }

	    MapDraw.prototype = {

	        constructor: MapDraw,

	        draw: function (mapOrGeoModel, ecModel, api, fromView, payload) {

	            var isGeo = mapOrGeoModel.mainType === 'geo';

	            // map series has data, geo model that controlled by map series
	            // has no data, otherwise data exists.
	            var data = mapOrGeoModel.getData && mapOrGeoModel.getData();
	            isGeo && ecModel.eachComponent({mainType: 'series', subType: 'map'}, function (mapSeries) {
	                if (!data && mapSeries.getHostGeoModel() === mapOrGeoModel) {
	                    data = mapSeries.getData();
	                }
	            });

	            var geo = mapOrGeoModel.coordinateSystem;

	            var group = this.group;

	            var scale = geo.scale;
	            var groupNewProp = {
	                position: geo.position,
	                scale: scale
	            };

	            // No animation when first draw or in action
	            if (!group.childAt(0) || payload) {
	                group.attr(groupNewProp);
	            }
	            else {
	                graphic.updateProps(group, groupNewProp, mapOrGeoModel);
	            }

	            group.removeAll();

	            var itemStyleAccessPath = ['itemStyle', 'normal'];
	            var hoverItemStyleAccessPath = ['itemStyle', 'emphasis'];
	            var labelAccessPath = ['label', 'normal'];
	            var hoverLabelAccessPath = ['label', 'emphasis'];
	            var nameMap = zrUtil.createHashMap();

	            zrUtil.each(geo.regions, function (region) {

	                // Consider in GeoJson properties.name may be duplicated, for example,
	                // there is multiple region named "United Kindom" or "France" (so many
	                // colonies). And it is not appropriate to merge them in geo, which
	                // will make them share the same label and bring trouble in label
	                // location calculation.
	                var regionGroup = nameMap.get(region.name)
	                    || nameMap.set(region.name, new graphic.Group());

	                var compoundPath = new graphic.CompoundPath({
	                    shape: {
	                        paths: []
	                    }
	                });
	                regionGroup.add(compoundPath);

	                var regionModel = mapOrGeoModel.getRegionModel(region.name) || mapOrGeoModel;

	                var itemStyleModel = regionModel.getModel(itemStyleAccessPath);
	                var hoverItemStyleModel = regionModel.getModel(hoverItemStyleAccessPath);
	                var itemStyle = getFixedItemStyle(itemStyleModel, scale);
	                var hoverItemStyle = getFixedItemStyle(hoverItemStyleModel, scale);

	                var labelModel = regionModel.getModel(labelAccessPath);
	                var hoverLabelModel = regionModel.getModel(hoverLabelAccessPath);

	                var dataIdx;
	                // Use the itemStyle in data if has data
	                if (data) {
	                    dataIdx = data.indexOfName(region.name);
	                    // Only visual color of each item will be used. It can be encoded by dataRange
	                    // But visual color of series is used in symbol drawing
	                    //
	                    // Visual color for each series is for the symbol draw
	                    var visualColor = data.getItemVisual(dataIdx, 'color', true);
	                    if (visualColor) {
	                        itemStyle.fill = visualColor;
	                    }
	                }

	                var textStyleModel = labelModel.getModel('textStyle');
	                var hoverTextStyleModel = hoverLabelModel.getModel('textStyle');

	                zrUtil.each(region.geometries, function (geometry) {
	                    if (geometry.type !== 'polygon') {
	                        return;
	                    }
	                    compoundPath.shape.paths.push(new graphic.Polygon({
	                        shape: {
	                            points: geometry.exterior
	                        }
	                    }));

	                    for (var i = 0; i < (geometry.interiors ? geometry.interiors.length : 0); i++) {
	                        compoundPath.shape.paths.push(new graphic.Polygon({
	                            shape: {
	                                points: geometry.interiors[i]
	                            }
	                        }));
	                    }
	                });

	                compoundPath.setStyle(itemStyle);
	                compoundPath.style.strokeNoScale = true;
	                compoundPath.culling = true;
	                // Label
	                var showLabel = labelModel.get('show');
	                var hoverShowLabel = hoverLabelModel.get('show');

	                var isDataNaN = data && isNaN(data.get('value', dataIdx));
	                var itemLayout = data && data.getItemLayout(dataIdx);
	                // In the following cases label will be drawn
	                // 1. In map series and data value is NaN
	                // 2. In geo component
	                // 4. Region has no series legendSymbol, which will be add a showLabel flag in mapSymbolLayout
	                if (
	                    (isGeo || isDataNaN && (showLabel || hoverShowLabel))
	                 || (itemLayout && itemLayout.showLabel)
	                 ) {
	                    var query = data ? dataIdx : region.name;
	                    var formattedStr = mapOrGeoModel.getFormattedLabel(query, 'normal');
	                    var hoverFormattedStr = mapOrGeoModel.getFormattedLabel(query, 'emphasis');
	                    var text = new graphic.Text({
	                        style: {
	                            text: showLabel ? (formattedStr || region.name) : '',
	                            fill: textStyleModel.getTextColor(),
	                            textFont: textStyleModel.getFont(),
	                            textAlign: 'center',
	                            textVerticalAlign: 'middle'
	                        },
	                        hoverStyle: {
	                            text: hoverShowLabel ? (hoverFormattedStr || region.name) : '',
	                            fill: hoverTextStyleModel.getTextColor(),
	                            textFont: hoverTextStyleModel.getFont()
	                        },
	                        position: region.center.slice(),
	                        scale: [1 / scale[0], 1 / scale[1]],
	                        z2: 10,
	                        silent: true
	                    });

	                    regionGroup.add(text);
	                }

	                // setItemGraphicEl, setHoverStyle after all polygons and labels
	                // are added to the rigionGroup
	                if (data) {
	                    data.setItemGraphicEl(dataIdx, regionGroup);
	                }
	                else {
	                    var regionModel = mapOrGeoModel.getRegionModel(region.name);
	                    // Package custom mouse event for geo component
	                    compoundPath.eventData = {
	                        componentType: 'geo',
	                        geoIndex: mapOrGeoModel.componentIndex,
	                        name: region.name,
	                        region: (regionModel && regionModel.option) || {}
	                    };
	                }

	                var groupRegions = regionGroup.__regions || (regionGroup.__regions = []);
	                groupRegions.push(region);

	                graphic.setHoverStyle(
	                    regionGroup,
	                    hoverItemStyle,
	                    {hoverSilentOnTouch: !!mapOrGeoModel.get('selectedMode')}
	                );

	                group.add(regionGroup);
	            });

	            this._updateController(mapOrGeoModel, ecModel, api);

	            updateMapSelectHandler(this, mapOrGeoModel, group, api, fromView);

	            updateMapSelected(mapOrGeoModel, group);
	        },

	        remove: function () {
	            this.group.removeAll();
	            this._controller.dispose();
	            this._controllerHost = {};
	        },

	        _updateController: function (mapOrGeoModel, ecModel, api) {
	            var geo = mapOrGeoModel.coordinateSystem;
	            var controller = this._controller;
	            var controllerHost = this._controllerHost;

	            controllerHost.zoomLimit = mapOrGeoModel.get('scaleLimit');
	            controllerHost.zoom = geo.getZoom();

	            // roamType is will be set default true if it is null
	            controller.enable(mapOrGeoModel.get('roam') || false);
	            var mainType = mapOrGeoModel.mainType;

	            function makeActionBase() {
	                var action = {
	                    type: 'geoRoam',
	                    componentType: mainType
	                };
	                action[mainType + 'Id'] = mapOrGeoModel.id;
	                return action;
	            }

	            controller.off('pan').on('pan', function (dx, dy) {
	                this._mouseDownFlag = false;

	                roamHelper.updateViewOnPan(controllerHost, dx, dy);

	                api.dispatchAction(zrUtil.extend(makeActionBase(), {
	                    dx: dx,
	                    dy: dy
	                }));
	            }, this);

	            controller.off('zoom').on('zoom', function (zoom, mouseX, mouseY) {
	                this._mouseDownFlag = false;

	                roamHelper.updateViewOnZoom(controllerHost, zoom, mouseX, mouseY);

	                api.dispatchAction(zrUtil.extend(makeActionBase(), {
	                    zoom: zoom,
	                    originX: mouseX,
	                    originY: mouseY
	                }));

	                if (this._updateGroup) {
	                    var group = this.group;
	                    var scale = group.scale;
	                    group.traverse(function (el) {
	                        if (el.type === 'text') {
	                            el.attr('scale', [1 / scale[0], 1 / scale[1]]);
	                        }
	                    });
	                }
	            }, this);

	            controller.setPointerChecker(function (e, x, y) {
	                return geo.getViewRectAfterRoam().contain(x, y)
	                    && !cursorHelper.onIrrelevantElement(e, api, mapOrGeoModel);
	            });
	        }
	    };

	    module.exports = MapDraw;


/***/ },
/* 183 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @module echarts/component/helper/RoamController
	 */


	    var Eventful = __webpack_require__(25);
	    var zrUtil = __webpack_require__(4);
	    var eventTool = __webpack_require__(88);
	    var interactionMutex = __webpack_require__(184);

	    /**
	     * @alias module:echarts/component/helper/RoamController
	     * @constructor
	     * @mixin {module:zrender/mixin/Eventful}
	     *
	     * @param {module:zrender/zrender~ZRender} zr
	     */
	    function RoamController(zr) {

	        /**
	         * @type {Function}
	         */
	        this.pointerChecker;

	        /**
	         * @type {module:zrender}
	         */
	        this._zr = zr;

	        /**
	         * @type {Object}
	         */
	        this._opt = {};

	        // Avoid two roamController bind the same handler
	        var bind = zrUtil.bind;
	        var mousedownHandler = bind(mousedown, this);
	        var mousemoveHandler = bind(mousemove, this);
	        var mouseupHandler = bind(mouseup, this);
	        var mousewheelHandler = bind(mousewheel, this);
	        var pinchHandler = bind(pinch, this);

	        Eventful.call(this);

	        /**
	         * @param {Function} pointerChecker
	         *                   input: x, y
	         *                   output: boolean
	         */
	        this.setPointerChecker = function (pointerChecker) {
	            this.pointerChecker = pointerChecker;
	        };

	        /**
	         * Notice: only enable needed types. For example, if 'zoom'
	         * is not needed, 'zoom' should not be enabled, otherwise
	         * default mousewheel behaviour (scroll page) will be disabled.
	         *
	         * @param  {boolean|string} [controlType=true] Specify the control type,
	         *                          which can be null/undefined or true/false
	         *                          or 'pan/move' or 'zoom'/'scale'
	         * @param {Object} [opt]
	         * @param {Object} [opt.zoomOnMouseWheel=true]
	         * @param {Object} [opt.moveOnMouseMove=true]
	         * @param {Object} [opt.preventDefaultMouseMove=true] When pan.
	         */
	        this.enable = function (controlType, opt) {

	            // Disable previous first
	            this.disable();

	            this._opt = zrUtil.defaults(zrUtil.clone(opt) || {}, {
	                zoomOnMouseWheel: true,
	                moveOnMouseMove: true,
	                preventDefaultMouseMove: true
	            });

	            if (controlType == null) {
	                controlType = true;
	            }

	            if (controlType === true || (controlType === 'move' || controlType === 'pan')) {
	                zr.on('mousedown', mousedownHandler);
	                zr.on('mousemove', mousemoveHandler);
	                zr.on('mouseup', mouseupHandler);
	            }
	            if (controlType === true || (controlType === 'scale' || controlType === 'zoom')) {
	                zr.on('mousewheel', mousewheelHandler);
	                zr.on('pinch', pinchHandler);
	            }
	        };

	        this.disable = function () {
	            zr.off('mousedown', mousedownHandler);
	            zr.off('mousemove', mousemoveHandler);
	            zr.off('mouseup', mouseupHandler);
	            zr.off('mousewheel', mousewheelHandler);
	            zr.off('pinch', pinchHandler);
	        };

	        this.dispose = this.disable;

	        this.isDragging = function () {
	            return this._dragging;
	        };

	        this.isPinching = function () {
	            return this._pinching;
	        };
	    }

	    zrUtil.mixin(RoamController, Eventful);


	    function mousedown(e) {
	        if (e.target && e.target.draggable) {
	            return;
	        }

	        var x = e.offsetX;
	        var y = e.offsetY;

	        // Only check on mosedown, but not mousemove.
	        // Mouse can be out of target when mouse moving.
	        if (this.pointerChecker && this.pointerChecker(e, x, y)) {
	            this._x = x;
	            this._y = y;
	            this._dragging = true;
	        }
	    }

	    function mousemove(e) {
	        if (!checkKeyBinding(this, 'moveOnMouseMove', e) || !this._dragging) {
	            return;
	        }

	        if (e.gestureEvent === 'pinch') {
	            return;
	        }

	        if (interactionMutex.isTaken(this._zr, 'globalPan')) {
	            return;
	        }

	        var x = e.offsetX;
	        var y = e.offsetY;

	        var oldX = this._x;
	        var oldY = this._y;

	        var dx = x - oldX;
	        var dy = y - oldY;

	        this._x = x;
	        this._y = y;

	        this._opt.preventDefaultMouseMove && eventTool.stop(e.event);

	        this.trigger('pan', dx, dy, oldX, oldY, x, y);
	    }

	    function mouseup(e) {
	        this._dragging = false;
	    }

	    function mousewheel(e) {
	        // wheelDelta maybe -0 in chrome mac.
	        if (!checkKeyBinding(this, 'zoomOnMouseWheel', e) || e.wheelDelta === 0) {
	            return;
	        }

	        // Convenience:
	        // Mac and VM Windows on Mac: scroll up: zoom out.
	        // Windows: scroll up: zoom in.
	        var zoomDelta = e.wheelDelta > 0 ? 1.1 : 1 / 1.1;
	        zoom.call(this, e, zoomDelta, e.offsetX, e.offsetY);
	    }

	    function pinch(e) {
	        if (interactionMutex.isTaken(this._zr, 'globalPan')) {
	            return;
	        }
	        var zoomDelta = e.pinchScale > 1 ? 1.1 : 1 / 1.1;
	        zoom.call(this, e, zoomDelta, e.pinchX, e.pinchY);
	    }

	    function zoom(e, zoomDelta, zoomX, zoomY) {
	        if (this.pointerChecker && this.pointerChecker(e, zoomX, zoomY)) {
	            // When mouse is out of roamController rect,
	            // default befavoius should not be be disabled, otherwise
	            // page sliding is disabled, contrary to expectation.
	            eventTool.stop(e.event);

	            this.trigger('zoom', zoomDelta, zoomX, zoomY);
	        }
	    }

	    function checkKeyBinding(roamController, prop, e) {
	        var setting = roamController._opt[prop];
	        return setting
	            && (!zrUtil.isString(setting) || e.event[setting + 'Key']);
	    }

	    module.exports = RoamController;


/***/ },
/* 184 */
/***/ function(module, exports, __webpack_require__) {

	

	    var ATTR = '\0_ec_interaction_mutex';

	    var interactionMutex = {

	        take: function (zr, resourceKey, userKey) {
	            var store = getStore(zr);
	            store[resourceKey] = userKey;
	        },

	        release: function (zr, resourceKey, userKey) {
	            var store = getStore(zr);
	            var uKey = store[resourceKey];

	            if (uKey === userKey) {
	                store[resourceKey] = null;
	            }
	        },

	        isTaken: function (zr, resourceKey) {
	            return !!getStore(zr)[resourceKey];
	        }
	    };

	    function getStore(zr) {
	        return zr[ATTR] || (zr[ATTR] = {});
	    }

	    /**
	     * payload: {
	     *     type: 'takeGlobalCursor',
	     *     key: 'dataZoomSelect', or 'brush', or ...,
	     *         If no userKey, release global cursor.
	     * }
	     */
	    __webpack_require__(1).registerAction(
	        {type: 'takeGlobalCursor', event: 'globalCursorTaken', update: 'update'},
	        function () {}
	    );

	    module.exports = interactionMutex;


/***/ },
/* 185 */
/***/ function(module, exports) {

	

	    var helper = {};

	    /**
	     * For geo and graph.
	     *
	     * @param {Object} controllerHost
	     * @param {module:zrender/Element} controllerHost.target
	     */
	    helper.updateViewOnPan = function (controllerHost, dx, dy) {
	        var target = controllerHost.target;
	        var pos = target.position;
	        pos[0] += dx;
	        pos[1] += dy;
	        target.dirty();
	    };

	    /**
	     * For geo and graph.
	     *
	     * @param {Object} controllerHost
	     * @param {module:zrender/Element} controllerHost.target
	     * @param {number} controllerHost.zoom
	     * @param {number} controllerHost.zoomLimit like: {min: 1, max: 2}
	     */
	    helper.updateViewOnZoom = function (controllerHost, zoomDelta, zoomX, zoomY) {
	        var target = controllerHost.target;
	        var zoomLimit = controllerHost.zoomLimit;
	        var pos = target.position;
	        var scale = target.scale;

	        var newZoom = controllerHost.zoom = controllerHost.zoom || 1;
	        newZoom *= zoomDelta;
	        if (zoomLimit) {
	            var zoomMin = zoomLimit.min || 0;
	            var zoomMax = zoomLimit.max || Infinity;
	            newZoom = Math.max(
	                Math.min(zoomMax, newZoom),
	                zoomMin
	            );
	        }
	        var zoomScale = newZoom / controllerHost.zoom;
	        controllerHost.zoom = newZoom;
	        // Keep the mouse center when scaling
	        pos[0] -= (zoomX - pos[0]) * (zoomScale - 1);
	        pos[1] -= (zoomY - pos[1]) * (zoomScale - 1);
	        scale[0] *= zoomScale;
	        scale[1] *= zoomScale;

	        target.dirty();
	    };

	    module.exports = helper;


/***/ },
/* 186 */
/***/ function(module, exports) {

	

	    var helper = {};

	    var IRRELEVANT_EXCLUDES = {'axisPointer': 1, 'tooltip': 1, 'brush': 1};

	    /**
	     * Avoid that: mouse click on a elements that is over geo or graph,
	     * but roam is triggered.
	     */
	    helper.onIrrelevantElement = function (e, api, targetCoordSysModel) {
	        var model = api.getComponentByElement(e.topTarget);
	        // If model is axisModel, it works only if it is injected with coordinateSystem.
	        var coordSys = model && model.coordinateSystem;
	        return model
	            && model !== targetCoordSysModel
	            && !IRRELEVANT_EXCLUDES[model.mainType]
	            && (coordSys && coordSys.model !== targetCoordSysModel);
	    };

	    module.exports = helper;


/***/ },
/* 187 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);
	    var roamHelper = __webpack_require__(188);

	    var echarts = __webpack_require__(1);

	    /**
	     * @payload
	     * @property {string} [componentType=series]
	     * @property {number} [dx]
	     * @property {number} [dy]
	     * @property {number} [zoom]
	     * @property {number} [originX]
	     * @property {number} [originY]
	     */
	    echarts.registerAction({
	        type: 'geoRoam',
	        event: 'geoRoam',
	        update: 'updateLayout'
	    }, function (payload, ecModel) {
	        var componentType = payload.componentType || 'series';

	        ecModel.eachComponent(
	            { mainType: componentType, query: payload },
	            function (componentModel) {
	                var geo = componentModel.coordinateSystem;
	                if (geo.type !== 'geo') {
	                    return;
	                }

	                var res = roamHelper.updateCenterAndZoom(
	                    geo, payload, componentModel.get('scaleLimit')
	                );

	                componentModel.setCenter
	                    && componentModel.setCenter(res.center);

	                componentModel.setZoom
	                    && componentModel.setZoom(res.zoom);

	                // All map series with same `map` use the same geo coordinate system
	                // So the center and zoom must be in sync. Include the series not selected by legend
	                if (componentType === 'series') {
	                    zrUtil.each(componentModel.seriesGroup, function (seriesModel) {
	                        seriesModel.setCenter(res.center);
	                        seriesModel.setZoom(res.zoom);
	                    });
	                }
	            }
	        );
	    });


/***/ },
/* 188 */
/***/ function(module, exports) {

	

	    var roamHelper = {};

	    /**
	     * @param {module:echarts/coord/View} view
	     * @param {Object} payload
	     * @param {Object} [zoomLimit]
	     */
	    roamHelper.updateCenterAndZoom = function (
	        view, payload, zoomLimit
	    ) {
	        var previousZoom = view.getZoom();
	        var center = view.getCenter();
	        var zoom = payload.zoom;

	        var point = view.dataToPoint(center);

	        if (payload.dx != null && payload.dy != null) {
	            point[0] -= payload.dx;
	            point[1] -= payload.dy;

	            var center = view.pointToData(point);
	            view.setCenter(center);
	        }
	        if (zoom != null) {
	            if (zoomLimit) {
	                var zoomMin = zoomLimit.min || 0;
	                var zoomMax = zoomLimit.max || Infinity;
	                zoom = Math.max(
	                    Math.min(previousZoom * zoom, zoomMax),
	                    zoomMin
	                ) / previousZoom;
	            }

	            // Zoom on given point(originX, originY)
	            view.scale[0] *= zoom;
	            view.scale[1] *= zoom;
	            var position = view.position;
	            var fixX = (payload.originX - position[0]) * (zoom - 1);
	            var fixY = (payload.originY - position[1]) * (zoom - 1);

	            position[0] -= fixX;
	            position[1] -= fixY;

	            view.updateTransform();
	            // Get the new center
	            var center = view.pointToData(point);
	            view.setCenter(center);
	            view.setZoom(zoom * previousZoom);
	        }

	        return {
	            center: view.getCenter(),
	            zoom: view.getZoom()
	        };
	    };

	    module.exports = roamHelper;


/***/ },
/* 189 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);

	    module.exports = function (ecModel) {

	        var processedMapType = {};

	        ecModel.eachSeriesByType('map', function (mapSeries) {
	            var mapType = mapSeries.getMapType();
	            if (mapSeries.getHostGeoModel() || processedMapType[mapType]) {
	                return;
	            }

	            var mapSymbolOffsets = {};

	            zrUtil.each(mapSeries.seriesGroup, function (subMapSeries) {
	                var geo = subMapSeries.coordinateSystem;
	                var data = subMapSeries.originalData;
	                if (subMapSeries.get('showLegendSymbol') && ecModel.getComponent('legend')) {
	                    data.each('value', function (value, idx) {
	                        var name = data.getName(idx);
	                        var region = geo.getRegion(name);

	                        // If input series.data is [11, 22, '-'/null/undefined, 44],
	                        // it will be filled with NaN: [11, 22, NaN, 44] and NaN will
	                        // not be drawn. So here must validate if value is NaN.
	                        if (!region || isNaN(value)) {
	                            return;
	                        }

	                        var offset = mapSymbolOffsets[name] || 0;

	                        var point = geo.dataToPoint(region.center);

	                        mapSymbolOffsets[name] = offset + 1;

	                        data.setItemLayout(idx, {
	                            point: point,
	                            offset: offset
	                        });
	                    });
	                }
	            });

	            // Show label of those region not has legendSymbol(which is offset 0)
	            var data = mapSeries.getData();
	            data.each(function (idx) {
	                var name = data.getName(idx);
	                var layout = data.getItemLayout(idx) || {};
	                layout.showLabel = !mapSymbolOffsets[name];
	                data.setItemLayout(idx, layout);
	            });

	            processedMapType[mapType] = true;
	        });
	    };


/***/ },
/* 190 */
/***/ function(module, exports) {

	
	    module.exports = function (ecModel) {
	        ecModel.eachSeriesByType('map', function (seriesModel) {
	            var colorList = seriesModel.get('color');
	            var itemStyleModel = seriesModel.getModel('itemStyle.normal');

	            var areaColor = itemStyleModel.get('areaColor');
	            var color = itemStyleModel.get('color')
	                || colorList[seriesModel.seriesIndex % colorList.length];

	            seriesModel.getData().setVisual({
	                'areaColor': areaColor,
	                'color': color
	            });
	        });
	    };


/***/ },
/* 191 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);

	    // FIXME 公用？
	    /**
	     * @param {Array.<module:echarts/data/List>} datas
	     * @param {string} statisticType 'average' 'sum'
	     * @inner
	     */
	    function dataStatistics(datas, statisticType) {
	        var dataNameMap = {};
	        var dims = ['value'];

	        zrUtil.each(datas, function (data) {
	            data.each(dims, function (value, idx) {
	                // Add prefix to avoid conflict with Object.prototype.
	                var mapKey = 'ec-' + data.getName(idx);
	                dataNameMap[mapKey] = dataNameMap[mapKey] || [];
	                if (!isNaN(value)) {
	                    dataNameMap[mapKey].push(value);
	                }
	            });
	        });

	        return datas[0].map(dims, function (value, idx) {
	            var mapKey = 'ec-' + datas[0].getName(idx);
	            var sum = 0;
	            var min = Infinity;
	            var max = -Infinity;
	            var len = dataNameMap[mapKey].length;
	            for (var i = 0; i < len; i++) {
	                min = Math.min(min, dataNameMap[mapKey][i]);
	                max = Math.max(max, dataNameMap[mapKey][i]);
	                sum += dataNameMap[mapKey][i];
	            }
	            var result;
	            if (statisticType === 'min') {
	                result = min;
	            }
	            else if (statisticType === 'max') {
	                result = max;
	            }
	            else if (statisticType === 'average') {
	                result = sum / len;
	            }
	            else {
	                result = sum;
	            }
	            return len === 0 ? NaN : result;
	        });
	    }

	    module.exports = function (ecModel) {
	        var seriesGroups = {};
	        ecModel.eachSeriesByType('map', function (seriesModel) {
	            var hostGeoModel = seriesModel.getHostGeoModel();
	            var key = hostGeoModel ? 'o' + hostGeoModel.id : 'i' + seriesModel.getMapType();
	            (seriesGroups[key] = seriesGroups[key] || []).push(seriesModel);
	        });

	        zrUtil.each(seriesGroups, function (seriesList, key) {
	            var data = dataStatistics(
	                zrUtil.map(seriesList, function (seriesModel) {
	                    return seriesModel.getData();
	                }),
	                seriesList[0].get('mapValueCalculation')
	            );

	            for (var i = 0; i < seriesList.length; i++) {
	                seriesList[i].originalData = seriesList[i].getData();
	            }

	            // FIXME Put where?
	            for (var i = 0; i < seriesList.length; i++) {
	                seriesList[i].seriesGroup = seriesList;
	                seriesList[i].needsDrawMap = i === 0 && !seriesList[i].getHostGeoModel();

	                seriesList[i].setData(data.cloneShallow());
	                seriesList[i].mainSeries = seriesList[0];
	            }
	        });
	    };


/***/ },
/* 192 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);

	    module.exports = function (option) {
	        // Save geoCoord
	        var mapSeries = [];
	        zrUtil.each(option.series, function (seriesOpt) {
	            if (seriesOpt.type === 'map') {
	                mapSeries.push(seriesOpt);
	            }
	        });

	        zrUtil.each(mapSeries, function (seriesOpt) {
	            seriesOpt.map = seriesOpt.map || seriesOpt.mapType;
	            // Put x, y, width, height, x2, y2 in the top level
	            zrUtil.defaults(seriesOpt, seriesOpt.mapLocation);
	        });
	    };


/***/ },
/* 193 */
/***/ function(module, exports, __webpack_require__) {

	

	    var echarts = __webpack_require__(1);

	    __webpack_require__(194);
	    __webpack_require__(198);
	    __webpack_require__(201);

	    echarts.registerVisual(__webpack_require__(202));

	    echarts.registerLayout(__webpack_require__(204));


/***/ },
/* 194 */
/***/ function(module, exports, __webpack_require__) {

	

	    var SeriesModel = __webpack_require__(78);
	    var Tree = __webpack_require__(195);
	    var zrUtil = __webpack_require__(4);
	    var Model = __webpack_require__(12);
	    var formatUtil = __webpack_require__(6);
	    var helper = __webpack_require__(197);
	    var encodeHTML = formatUtil.encodeHTML;
	    var addCommas = formatUtil.addCommas;


	    module.exports = SeriesModel.extend({

	        type: 'series.treemap',

	        layoutMode: 'box',

	        dependencies: ['grid', 'polar'],

	        /**
	         * @type {module:echarts/data/Tree~Node}
	         */
	        _viewRoot: null,

	        defaultOption: {
	            // Disable progressive rendering
	            progressive: 0,
	            hoverLayerThreshold: Infinity,
	            // center: ['50%', '50%'],          // not supported in ec3.
	            // size: ['80%', '80%'],            // deprecated, compatible with ec2.
	            left: 'center',
	            top: 'middle',
	            right: null,
	            bottom: null,
	            width: '80%',
	            height: '80%',
	            sort: true,                         // Can be null or false or true
	                                                // (order by desc default, asc not supported yet (strange effect))
	            clipWindow: 'origin',               // Size of clipped window when zooming. 'origin' or 'fullscreen'
	            squareRatio: 0.5 * (1 + Math.sqrt(5)), // golden ratio
	            leafDepth: null,                    // Nodes on depth from root are regarded as leaves.
	                                                // Count from zero (zero represents only view root).
	            drillDownIcon: '▶',                 // Use html character temporarily because it is complicated
	                                                // to align specialized icon. ▷▶❒❐▼✚

	            zoomToNodeRatio: 0.32 * 0.32,       // Be effective when using zoomToNode. Specify the proportion of the
	                                                // target node area in the view area.
	            roam: true,                         // true, false, 'scale' or 'zoom', 'move'.
	            nodeClick: 'zoomToNode',            // Leaf node click behaviour: 'zoomToNode', 'link', false.
	                                                // If leafDepth is set and clicking a node which has children but
	                                                // be on left depth, the behaviour would be changing root. Otherwise
	                                                // use behavious defined above.
	            animation: true,
	            animationDurationUpdate: 900,
	            animationEasing: 'quinticInOut',
	            breadcrumb: {
	                show: true,
	                height: 22,
	                left: 'center',
	                top: 'bottom',
	                // right
	                // bottom
	                emptyItemWidth: 25,             // Width of empty node.
	                itemStyle: {
	                    normal: {
	                        color: 'rgba(0,0,0,0.7)', //'#5793f3',
	                        borderColor: 'rgba(255,255,255,0.7)',
	                        borderWidth: 1,
	                        shadowColor: 'rgba(150,150,150,1)',
	                        shadowBlur: 3,
	                        shadowOffsetX: 0,
	                        shadowOffsetY: 0,
	                        textStyle: {
	                            color: '#fff'
	                        }
	                    },
	                    emphasis: {
	                        textStyle: {}
	                    }
	                }
	            },
	            label: {
	                normal: {
	                    show: true,
	                    position: 'inside', // Can be [5, '5%'] or position stirng like 'insideTopLeft', ...
	                    // formatter: null,
	                    textStyle: {
	                        color: '#fff',
	                        ellipsis: true
	                        // align
	                        // baseline
	                    }
	                }
	            },
	            upperLabel: {                   // Label when node is parent.
	                normal: {
	                    show: false,
	                    position: [0, '50%'],
	                    height: 20,
	                    // formatter: null,
	                    textStyle: {
	                        color: '#fff',
	                        ellipsis: true,
	                        // align: null,
	                        baseline: 'middle'
	                    }
	                },
	                emphasis: {
	                    show: true,
	                    position: [0, '50%'],
	                    textStyle: {
	                        color: '#fff',
	                        ellipsis: true,
	                        baseline: 'middle'
	                    }
	                }
	            },
	            itemStyle: {
	                normal: {
	                    color: null,            // Can be 'none' if not necessary.
	                    colorAlpha: null,       // Can be 'none' if not necessary.
	                    colorSaturation: null,  // Can be 'none' if not necessary.
	                    borderWidth: 0,
	                    gapWidth: 0,
	                    borderColor: '#fff',
	                    borderColorSaturation: null // If specified, borderColor will be ineffective, and the
	                                                // border color is evaluated by color of current node and
	                                                // borderColorSaturation.
	                },
	                emphasis: {

	                }
	            },

	            visualDimension: 0,                 // Can be 0, 1, 2, 3.
	            visualMin: null,
	            visualMax: null,

	            color: [],                  // + treemapSeries.color should not be modified. Please only modified
	                                        // level[n].color (if necessary).
	                                        // + Specify color list of each level. level[0].color would be global
	                                        // color list if not specified. (see method `setDefault`).
	                                        // + But set as a empty array to forbid fetch color from global palette
	                                        // when using nodeModel.get('color'), otherwise nodes on deep level
	                                        // will always has color palette set and are not able to inherit color
	                                        // from parent node.
	                                        // + TreemapSeries.color can not be set as 'none', otherwise effect
	                                        // legend color fetching (see seriesColor.js).
	            colorAlpha: null,           // Array. Specify color alpha range of each level, like [0.2, 0.8]
	            colorSaturation: null,      // Array. Specify color saturation of each level, like [0.2, 0.5]
	            colorMappingBy: 'index',    // 'value' or 'index' or 'id'.
	            visibleMin: 10,             // If area less than this threshold (unit: pixel^2), node will not
	                                        // be rendered. Only works when sort is 'asc' or 'desc'.
	            childrenVisibleMin: null,   // If area of a node less than this threshold (unit: pixel^2),
	                                        // grandchildren will not show.
	                                        // Why grandchildren? If not grandchildren but children,
	                                        // some siblings show children and some not,
	                                        // the appearance may be mess and not consistent,
	            levels: []                  // Each item: {
	                                        //     visibleMin, itemStyle, visualDimension, label
	                                        // }
	            // data: {
	            //      value: [],
	            //      children: [],
	            //      link: 'http://xxx.xxx.xxx',
	            //      target: 'blank' or 'self'
	            // }
	        },

	        /**
	         * @override
	         */
	        getInitialData: function (option, ecModel) {
	            // Create a virtual root.
	            var root = {name: option.name, children: option.data};

	            completeTreeValue(root);

	            var levels = option.levels || [];

	            levels = option.levels = setDefault(levels, ecModel);

	            // Make sure always a new tree is created when setOption,
	            // in TreemapView, we check whether oldTree === newTree
	            // to choose mappings approach among old shapes and new shapes.
	            return Tree.createTree(root, this, levels).data;
	        },

	        optionUpdated: function () {
	            this.resetViewRoot();
	        },

	        /**
	         * @override
	         * @param {number} dataIndex
	         * @param {boolean} [mutipleSeries=false]
	         */
	        formatTooltip: function (dataIndex) {
	            var data = this.getData();
	            var value = this.getRawValue(dataIndex);
	            var formattedValue = zrUtil.isArray(value)
	                ? addCommas(value[0]) : addCommas(value);
	            var name = data.getName(dataIndex);

	            return encodeHTML(name + ': ' + formattedValue);
	        },

	        /**
	         * Add tree path to tooltip param
	         *
	         * @override
	         * @param {number} dataIndex
	         * @return {Object}
	         */
	        getDataParams: function (dataIndex) {
	            var params = SeriesModel.prototype.getDataParams.apply(this, arguments);

	            var node = this.getData().tree.getNodeByDataIndex(dataIndex);
	            params.treePathInfo = helper.wrapTreePathInfo(node, this);

	            return params;
	        },

	        /**
	         * @public
	         * @param {Object} layoutInfo {
	         *                                x: containerGroup x
	         *                                y: containerGroup y
	         *                                width: containerGroup width
	         *                                height: containerGroup height
	         *                            }
	         */
	        setLayoutInfo: function (layoutInfo) {
	            /**
	             * @readOnly
	             * @type {Object}
	             */
	            this.layoutInfo = this.layoutInfo || {};
	            zrUtil.extend(this.layoutInfo, layoutInfo);
	        },

	        /**
	         * @param  {string} id
	         * @return {number} index
	         */
	        mapIdToIndex: function (id) {
	            // A feature is implemented:
	            // index is monotone increasing with the sequence of
	            // input id at the first time.
	            // This feature can make sure that each data item and its
	            // mapped color have the same index between data list and
	            // color list at the beginning, which is useful for user
	            // to adjust data-color mapping.

	            /**
	             * @private
	             * @type {Object}
	             */
	            var idIndexMap = this._idIndexMap;

	            if (!idIndexMap) {
	                idIndexMap = this._idIndexMap = zrUtil.createHashMap();
	                /**
	                 * @private
	                 * @type {number}
	                 */
	                this._idIndexMapCount = 0;
	            }

	            var index = idIndexMap.get(id);
	            if (index == null) {
	                idIndexMap.set(id, index = this._idIndexMapCount++);
	            }

	            return index;
	        },

	        getViewRoot: function () {
	            return this._viewRoot;
	        },

	        /**
	         * @param {module:echarts/data/Tree~Node} [viewRoot]
	         */
	        resetViewRoot: function (viewRoot) {
	            viewRoot
	                ? (this._viewRoot = viewRoot)
	                : (viewRoot = this._viewRoot);

	            var root = this.getData().tree.root;

	            if (!viewRoot
	                || (viewRoot !== root && !root.contains(viewRoot))
	            ) {
	                this._viewRoot = root;
	            }
	        }
	    });

	    /**
	     * @param {Object} dataNode
	     */
	    function completeTreeValue(dataNode) {
	        // Postorder travel tree.
	        // If value of none-leaf node is not set,
	        // calculate it by suming up the value of all children.
	        var sum = 0;

	        zrUtil.each(dataNode.children, function (child) {

	            completeTreeValue(child);

	            var childValue = child.value;
	            zrUtil.isArray(childValue) && (childValue = childValue[0]);

	            sum += childValue;
	        });

	        var thisValue = dataNode.value;
	        if (zrUtil.isArray(thisValue)) {
	            thisValue = thisValue[0];
	        }

	        if (thisValue == null || isNaN(thisValue)) {
	            thisValue = sum;
	        }
	        // Value should not less than 0.
	        if (thisValue < 0) {
	            thisValue = 0;
	        }

	        zrUtil.isArray(dataNode.value)
	            ? (dataNode.value[0] = thisValue)
	            : (dataNode.value = thisValue);
	    }

	    /**
	     * set default to level configuration
	     */
	    function setDefault(levels, ecModel) {
	        var globalColorList = ecModel.get('color');

	        if (!globalColorList) {
	            return;
	        }

	        levels = levels || [];
	        var hasColorDefine;
	        zrUtil.each(levels, function (levelDefine) {
	            var model = new Model(levelDefine);
	            var modelColor = model.get('color');

	            if (model.get('itemStyle.normal.color')
	                || (modelColor && modelColor !== 'none')
	            ) {
	                hasColorDefine = true;
	            }
	        });

	        if (!hasColorDefine) {
	            var level0 = levels[0] || (levels[0] = {});
	            level0.color = globalColorList.slice();
	        }

	        return levels;
	    }



/***/ },
/* 195 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * Tree data structure
	 *
	 * @module echarts/data/Tree
	 */


	    var zrUtil = __webpack_require__(4);
	    var Model = __webpack_require__(12);
	    var List = __webpack_require__(98);
	    var linkList = __webpack_require__(196);
	    var completeDimensions = __webpack_require__(110);

	    /**
	     * @constructor module:echarts/data/Tree~TreeNode
	     * @param {string} name
	     * @param {module:echarts/data/Tree} hostTree
	     */
	    var TreeNode = function (name, hostTree) {
	        /**
	         * @type {string}
	         */
	        this.name = name || '';

	        /**
	         * Depth of node
	         *
	         * @type {number}
	         * @readOnly
	         */
	        this.depth = 0;

	        /**
	         * Height of the subtree rooted at this node.
	         * @type {number}
	         * @readOnly
	         */
	        this.height = 0;

	        /**
	         * @type {module:echarts/data/Tree~TreeNode}
	         * @readOnly
	         */
	        this.parentNode = null;

	        /**
	         * Reference to list item.
	         * Do not persistent dataIndex outside,
	         * besause it may be changed by list.
	         * If dataIndex -1,
	         * this node is logical deleted (filtered) in list.
	         *
	         * @type {Object}
	         * @readOnly
	         */
	        this.dataIndex = -1;

	        /**
	         * @type {Array.<module:echarts/data/Tree~TreeNode>}
	         * @readOnly
	         */
	        this.children = [];

	        /**
	         * @type {Array.<module:echarts/data/Tree~TreeNode>}
	         * @pubilc
	         */
	        this.viewChildren = [];

	        /**
	         * @type {moduel:echarts/data/Tree}
	         * @readOnly
	         */
	        this.hostTree = hostTree;
	    };

	    TreeNode.prototype = {

	        constructor: TreeNode,

	        /**
	         * The node is removed.
	         * @return {boolean} is removed.
	         */
	        isRemoved: function () {
	            return this.dataIndex < 0;
	        },

	        /**
	         * Travel this subtree (include this node).
	         * Usage:
	         *    node.eachNode(function () { ... }); // preorder
	         *    node.eachNode('preorder', function () { ... }); // preorder
	         *    node.eachNode('postorder', function () { ... }); // postorder
	         *    node.eachNode(
	         *        {order: 'postorder', attr: 'viewChildren'},
	         *        function () { ... }
	         *    ); // postorder
	         *
	         * @param {(Object|string)} options If string, means order.
	         * @param {string=} options.order 'preorder' or 'postorder'
	         * @param {string=} options.attr 'children' or 'viewChildren'
	         * @param {Function} cb If in preorder and return false,
	         *                      its subtree will not be visited.
	         * @param {Object} [context]
	         */
	        eachNode: function (options, cb, context) {
	            if (typeof options === 'function') {
	                context = cb;
	                cb = options;
	                options = null;
	            }

	            options = options || {};
	            if (zrUtil.isString(options)) {
	                options = {order: options};
	            }

	            var order = options.order || 'preorder';
	            var children = this[options.attr || 'children'];

	            var suppressVisitSub;
	            order === 'preorder' && (suppressVisitSub = cb.call(context, this));

	            for (var i = 0; !suppressVisitSub && i < children.length; i++) {
	                children[i].eachNode(options, cb, context);
	            }

	            order === 'postorder' && cb.call(context, this);
	        },

	        /**
	         * Update depth and height of this subtree.
	         *
	         * @param  {number} depth
	         */
	        updateDepthAndHeight: function (depth) {
	            var height = 0;
	            this.depth = depth;
	            for (var i = 0; i < this.children.length; i++) {
	                var child = this.children[i];
	                child.updateDepthAndHeight(depth + 1);
	                if (child.height > height) {
	                    height = child.height;
	                }
	            }
	            this.height = height + 1;
	        },

	        /**
	         * @param  {string} id
	         * @return {module:echarts/data/Tree~TreeNode}
	         */
	        getNodeById: function (id) {
	            if (this.getId() === id) {
	                return this;
	            }
	            for (var i = 0, children = this.children, len = children.length; i < len; i++) {
	                var res = children[i].getNodeById(id);
	                if (res) {
	                    return res;
	                }
	            }
	        },

	        /**
	         * @param {module:echarts/data/Tree~TreeNode} node
	         * @return {boolean}
	         */
	        contains: function (node) {
	            if (node === this) {
	                return true;
	            }
	            for (var i = 0, children = this.children, len = children.length; i < len; i++) {
	                var res = children[i].contains(node);
	                if (res) {
	                    return res;
	                }
	            }
	        },

	        /**
	         * @param {boolean} includeSelf Default false.
	         * @return {Array.<module:echarts/data/Tree~TreeNode>} order: [root, child, grandchild, ...]
	         */
	        getAncestors: function (includeSelf) {
	            var ancestors = [];
	            var node = includeSelf ? this : this.parentNode;
	            while (node) {
	                ancestors.push(node);
	                node = node.parentNode;
	            }
	            ancestors.reverse();
	            return ancestors;
	        },

	        /**
	         * @param {string|Array=} [dimension='value'] Default 'value'. can be 0, 1, 2, 3
	         * @return {number} Value.
	         */
	        getValue: function (dimension) {
	            var data = this.hostTree.data;
	            return data.get(data.getDimension(dimension || 'value'), this.dataIndex);
	        },

	        /**
	         * @param {Object} layout
	         * @param {boolean=} [merge=false]
	         */
	        setLayout: function (layout, merge) {
	            this.dataIndex >= 0
	                && this.hostTree.data.setItemLayout(this.dataIndex, layout, merge);
	        },

	        /**
	         * @return {Object} layout
	         */
	        getLayout: function () {
	            return this.hostTree.data.getItemLayout(this.dataIndex);
	        },

	        /**
	         * @param {string} [path]
	         * @return {module:echarts/model/Model}
	         */
	        getModel: function (path) {
	            if (this.dataIndex < 0) {
	                return;
	            }
	            var hostTree = this.hostTree;
	            var itemModel = hostTree.data.getItemModel(this.dataIndex);
	            var levelModel = this.getLevelModel();

	            return itemModel.getModel(path, (levelModel || hostTree.hostModel).getModel(path));
	        },

	        /**
	         * @return {module:echarts/model/Model}
	         */
	        getLevelModel: function () {
	            return (this.hostTree.levelModels || [])[this.depth];
	        },

	        /**
	         * @example
	         *  setItemVisual('color', color);
	         *  setItemVisual({
	         *      'color': color
	         *  });
	         */
	        setVisual: function (key, value) {
	            this.dataIndex >= 0
	                && this.hostTree.data.setItemVisual(this.dataIndex, key, value);
	        },

	        /**
	         * Get item visual
	         */
	        getVisual: function (key, ignoreParent) {
	            return this.hostTree.data.getItemVisual(this.dataIndex, key, ignoreParent);
	        },

	        /**
	         * @public
	         * @return {number}
	         */
	        getRawIndex: function () {
	            return this.hostTree.data.getRawIndex(this.dataIndex);
	        },

	        /**
	         * @public
	         * @return {string}
	         */
	        getId: function () {
	            return this.hostTree.data.getId(this.dataIndex);
	        }
	    };

	    /**
	     * @constructor
	     * @alias module:echarts/data/Tree
	     * @param {module:echarts/model/Model} hostModel
	     * @param {Array.<Object>} levelOptions
	     */
	    function Tree(hostModel, levelOptions) {
	        /**
	         * @type {module:echarts/data/Tree~TreeNode}
	         * @readOnly
	         */
	        this.root;

	        /**
	         * @type {module:echarts/data/List}
	         * @readOnly
	         */
	        this.data;

	        /**
	         * Index of each item is the same as the raw index of coresponding list item.
	         * @private
	         * @type {Array.<module:echarts/data/Tree~TreeNode}
	         */
	        this._nodes = [];

	        /**
	         * @private
	         * @readOnly
	         * @type {module:echarts/model/Model}
	         */
	        this.hostModel = hostModel;

	        /**
	         * @private
	         * @readOnly
	         * @type {Array.<module:echarts/model/Model}
	         */
	        this.levelModels = zrUtil.map(levelOptions || [], function (levelDefine) {
	            return new Model(levelDefine, hostModel, hostModel.ecModel);
	        });
	    }

	    Tree.prototype = {

	        constructor: Tree,

	        type: 'tree',

	        /**
	         * Travel this subtree (include this node).
	         * Usage:
	         *    node.eachNode(function () { ... }); // preorder
	         *    node.eachNode('preorder', function () { ... }); // preorder
	         *    node.eachNode('postorder', function () { ... }); // postorder
	         *    node.eachNode(
	         *        {order: 'postorder', attr: 'viewChildren'},
	         *        function () { ... }
	         *    ); // postorder
	         *
	         * @param {(Object|string)} options If string, means order.
	         * @param {string=} options.order 'preorder' or 'postorder'
	         * @param {string=} options.attr 'children' or 'viewChildren'
	         * @param {Function} cb
	         * @param {Object}   [context]
	         */
	        eachNode: function(options, cb, context) {
	            this.root.eachNode(options, cb, context);
	        },

	        /**
	         * @param {number} dataIndex
	         * @return {module:echarts/data/Tree~TreeNode}
	         */
	        getNodeByDataIndex: function (dataIndex) {
	            var rawIndex = this.data.getRawIndex(dataIndex);
	            return this._nodes[rawIndex];
	        },

	        /**
	         * @param {string} name
	         * @return {module:echarts/data/Tree~TreeNode}
	         */
	        getNodeByName: function (name) {
	            return this.root.getNodeByName(name);
	        },

	        /**
	         * Update item available by list,
	         * when list has been performed options like 'filterSelf' or 'map'.
	         */
	        update: function () {
	            var data = this.data;
	            var nodes = this._nodes;

	            for (var i = 0, len = nodes.length; i < len; i++) {
	                nodes[i].dataIndex = -1;
	            }

	            for (var i = 0, len = data.count(); i < len; i++) {
	                nodes[data.getRawIndex(i)].dataIndex = i;
	            }
	        },

	        /**
	         * Clear all layouts
	         */
	        clearLayouts: function () {
	            this.data.clearItemLayouts();
	        }
	    };

	    /**
	     * data node format:
	     * {
	     *     name: ...
	     *     value: ...
	     *     children: [
	     *         {
	     *             name: ...
	     *             value: ...
	     *             children: ...
	     *         },
	     *         ...
	     *     ]
	     * }
	     *
	     * @static
	     * @param {Objec} dataRoot Root node.
	     * @param {module:echarts/model/Model} hostModel
	     * @param {Array.<Object>} levelOptions
	     * @return module:echarts/data/Tree
	     */
	    Tree.createTree = function (dataRoot, hostModel, levelOptions) {

	        var tree = new Tree(hostModel, levelOptions);
	        var listData = [];
	        var dimMax = 1;

	        buildHierarchy(dataRoot);

	        function buildHierarchy(dataNode, parentNode) {
	            var value = dataNode.value;
	            dimMax = Math.max(dimMax, zrUtil.isArray(value) ? value.length : 1);

	            listData.push(dataNode);

	            var node = new TreeNode(dataNode.name, tree);
	            parentNode
	                ? addChild(node, parentNode)
	                : (tree.root = node);

	            tree._nodes.push(node);

	            var children = dataNode.children;
	            if (children) {
	                for (var i = 0; i < children.length; i++) {
	                    buildHierarchy(children[i], node);
	                }
	            }
	        }

	        tree.root.updateDepthAndHeight(0);

	        var dimensions = completeDimensions([{name: 'value'}], listData, {dimCount: dimMax});
	        var list = new List(dimensions, hostModel);
	        list.initData(listData);

	        linkList({
	            mainData: list,
	            struct: tree,
	            structAttr: 'tree'
	        });

	        tree.update();

	        return tree;
	    };

	    /**
	     * It is needed to consider the mess of 'list', 'hostModel' when creating a TreeNote,
	     * so this function is not ready and not necessary to be public.
	     *
	     * @param {(module:echarts/data/Tree~TreeNode|Object)} child
	     */
	    function addChild(child, node) {
	        var children = node.children;
	        if (child.parentNode === node) {
	            return;
	        }

	        children.push(child);
	        child.parentNode = node;
	    }

	    module.exports = Tree;


/***/ },
/* 196 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * Link lists and struct (graph or tree)
	 */


	    var zrUtil = __webpack_require__(4);
	    var each = zrUtil.each;

	    var DATAS = '\0__link_datas';
	    var MAIN_DATA = '\0__link_mainData';

	    // Caution:
	    // In most case, either list or its shallow clones (see list.cloneShallow)
	    // is active in echarts process. So considering heap memory consumption,
	    // we do not clone tree or graph, but share them among list and its shallow clones.
	    // But in some rare case, we have to keep old list (like do animation in chart). So
	    // please take care that both the old list and the new list share the same tree/graph.

	    /**
	     * @param {Object} opt
	     * @param {module:echarts/data/List} opt.mainData
	     * @param {Object} [opt.struct] For example, instance of Graph or Tree.
	     * @param {string} [opt.structAttr] designation: list[structAttr] = struct;
	     * @param {Object} [opt.datas] {dataType: data},
	     *                 like: {node: nodeList, edge: edgeList}.
	     *                 Should contain mainData.
	     * @param {Object} [opt.datasAttr] {dataType: attr},
	     *                 designation: struct[datasAttr[dataType]] = list;
	     */
	    function linkList(opt) {
	        var mainData = opt.mainData;
	        var datas = opt.datas;

	        if (!datas) {
	            datas = {main: mainData};
	            opt.datasAttr = {main: 'data'};
	        }
	        opt.datas = opt.mainData = null;

	        linkAll(mainData, datas, opt);

	        // Porxy data original methods.
	        each(datas, function (data) {
	            each(mainData.TRANSFERABLE_METHODS, function (methodName) {
	                data.wrapMethod(methodName, zrUtil.curry(transferInjection, opt));
	            });

	        });

	        // Beyond transfer, additional features should be added to `cloneShallow`.
	        mainData.wrapMethod('cloneShallow', zrUtil.curry(cloneShallowInjection, opt));

	        // Only mainData trigger change, because struct.update may trigger
	        // another changable methods, which may bring about dead lock.
	        each(mainData.CHANGABLE_METHODS, function (methodName) {
	            mainData.wrapMethod(methodName, zrUtil.curry(changeInjection, opt));
	        });

	        // Make sure datas contains mainData.
	        zrUtil.assert(datas[mainData.dataType] === mainData);
	    }

	    function transferInjection(opt, res) {
	        if (isMainData(this)) {
	            // Transfer datas to new main data.
	            var datas = zrUtil.extend({}, this[DATAS]);
	            datas[this.dataType] = res;
	            linkAll(res, datas, opt);
	        }
	        else {
	            // Modify the reference in main data to point newData.
	            linkSingle(res, this.dataType, this[MAIN_DATA], opt);
	        }
	        return res;
	    }

	    function changeInjection(opt, res) {
	        opt.struct && opt.struct.update(this);
	        return res;
	    }

	    function cloneShallowInjection(opt, res) {
	        // cloneShallow, which brings about some fragilities, may be inappropriate
	        // to be exposed as an API. So for implementation simplicity we can make
	        // the restriction that cloneShallow of not-mainData should not be invoked
	        // outside, but only be invoked here.
	        each(res[DATAS], function (data, dataType) {
	            data !== res && linkSingle(data.cloneShallow(), dataType, res, opt);
	        });
	        return res;
	    }

	    /**
	     * Supplement method to List.
	     *
	     * @public
	     * @param {string} [dataType] If not specified, return mainData.
	     * @return {module:echarts/data/List}
	     */
	    function getLinkedData(dataType) {
	        var mainData = this[MAIN_DATA];
	        return (dataType == null || mainData == null)
	            ? mainData
	            : mainData[DATAS][dataType];
	    }

	    function isMainData(data) {
	        return data[MAIN_DATA] === data;
	    }

	    function linkAll(mainData, datas, opt) {
	        mainData[DATAS] = {};
	        each(datas, function (data, dataType) {
	            linkSingle(data, dataType, mainData, opt);
	        });
	    }

	    function linkSingle(data, dataType, mainData, opt) {
	        mainData[DATAS][dataType] = data;
	        data[MAIN_DATA] = mainData;
	        data.dataType = dataType;

	        if (opt.struct) {
	            data[opt.structAttr] = opt.struct;
	            opt.struct[opt.datasAttr[dataType]] = data;
	        }

	        // Supplement method.
	        data.getLinkedData = getLinkedData;
	    }

	    module.exports = linkList;


/***/ },
/* 197 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);

	    var helper = {

	        retrieveTargetInfo: function (payload, seriesModel) {
	            if (payload
	                && (
	                    payload.type === 'treemapZoomToNode'
	                    || payload.type === 'treemapRootToNode'
	                )
	            ) {
	                var root = seriesModel.getData().tree.root;
	                var targetNode = payload.targetNode;
	                if (targetNode && root.contains(targetNode)) {
	                    return {node: targetNode};
	                }

	                var targetNodeId = payload.targetNodeId;
	                if (targetNodeId != null && (targetNode = root.getNodeById(targetNodeId))) {
	                    return {node: targetNode};
	                }
	            }
	        },

	        // Not includes the given node at the last item.
	        getPathToRoot: function (node) {
	            var path = [];
	            while (node) {
	                node = node.parentNode;
	                node && path.push(node);
	            }
	            return path.reverse();
	        },

	        aboveViewRoot: function (viewRoot, node) {
	            var viewPath = helper.getPathToRoot(viewRoot);
	            return zrUtil.indexOf(viewPath, node) >= 0;
	        },

	        // From root to the input node (the input node will be included).
	        wrapTreePathInfo: function (node, seriesModel) {
	            var treePathInfo = [];

	            while (node) {
	                var nodeDataIndex = node.dataIndex;
	                treePathInfo.push({
	                    name: node.name,
	                    dataIndex: nodeDataIndex,
	                    value: seriesModel.getRawValue(nodeDataIndex)
	                });
	                node = node.parentNode;
	            }

	            treePathInfo.reverse();

	            return treePathInfo;
	        }
	    };

	    module.exports = helper;


/***/ },
/* 198 */
/***/ function(module, exports, __webpack_require__) {

	 

	    var zrUtil = __webpack_require__(4);
	    var graphic = __webpack_require__(18);
	    var DataDiffer = __webpack_require__(99);
	    var helper = __webpack_require__(197);
	    var Breadcrumb = __webpack_require__(199);
	    var RoamController = __webpack_require__(183);
	    var BoundingRect = __webpack_require__(9);
	    var matrix = __webpack_require__(11);
	    var animationUtil = __webpack_require__(200);
	    var bind = zrUtil.bind;
	    var Group = graphic.Group;
	    var Rect = graphic.Rect;
	    var each = zrUtil.each;

	    var DRAG_THRESHOLD = 3;
	    var PATH_LABEL_NOAMAL = ['label', 'normal'];
	    var PATH_LABEL_EMPHASIS = ['label', 'emphasis'];
	    var PATH_UPPERLABEL_NORMAL = ['upperLabel', 'normal'];
	    var PATH_UPPERLABEL_EMPHASIS = ['upperLabel', 'emphasis'];
	    var Z_BASE = 10; // Should bigger than every z.
	    var Z_BG = 1;
	    var Z_CONTENT = 2;

	    module.exports = __webpack_require__(1).extendChartView({

	        type: 'treemap',

	        /**
	         * @override
	         */
	        init: function (o, api) {

	            /**
	             * @private
	             * @type {module:zrender/container/Group}
	             */
	            this._containerGroup;

	            /**
	             * @private
	             * @type {Object.<string, Array.<module:zrender/container/Group>>}
	             */
	            this._storage = createStorage();

	            /**
	             * @private
	             * @type {module:echarts/data/Tree}
	             */
	            this._oldTree;

	            /**
	             * @private
	             * @type {module:echarts/chart/treemap/Breadcrumb}
	             */
	            this._breadcrumb;

	            /**
	             * @private
	             * @type {module:echarts/component/helper/RoamController}
	             */
	            this._controller;

	            /**
	             * 'ready', 'animating'
	             * @private
	             */
	            this._state = 'ready';

	            /**
	             * @private
	             * @type {boolean}
	             */
	            this._mayClick;
	        },

	        /**
	         * @override
	         */
	        render: function (seriesModel, ecModel, api, payload) {

	            var models = ecModel.findComponents({
	                mainType: 'series', subType: 'treemap', query: payload
	            });
	            if (zrUtil.indexOf(models, seriesModel) < 0) {
	                return;
	            }

	            this.seriesModel = seriesModel;
	            this.api = api;
	            this.ecModel = ecModel;

	            var targetInfo = helper.retrieveTargetInfo(payload, seriesModel);
	            var payloadType = payload && payload.type;
	            var layoutInfo = seriesModel.layoutInfo;
	            var isInit = !this._oldTree;
	            var thisStorage = this._storage;

	            // Mark new root when action is treemapRootToNode.
	            var reRoot = (payloadType === 'treemapRootToNode' && targetInfo && thisStorage)
	                ? {
	                    rootNodeGroup: thisStorage.nodeGroup[targetInfo.node.getRawIndex()],
	                    direction: payload.direction
	                }
	                : null;

	            var containerGroup = this._giveContainerGroup(layoutInfo);

	            var renderResult = this._doRender(containerGroup, seriesModel, reRoot);
	            (
	                !isInit && (
	                    !payloadType
	                    || payloadType === 'treemapZoomToNode'
	                    || payloadType === 'treemapRootToNode'
	                )
	            )
	                ? this._doAnimation(containerGroup, renderResult, seriesModel, reRoot)
	                : renderResult.renderFinally();

	            this._resetController(api);

	            this._renderBreadcrumb(seriesModel, api, targetInfo);
	        },

	        /**
	         * @private
	         */
	        _giveContainerGroup: function (layoutInfo) {
	            var containerGroup = this._containerGroup;
	            if (!containerGroup) {
	                // FIXME
	                // 加一层containerGroup是为了clip，但是现在clip功能并没有实现。
	                containerGroup = this._containerGroup = new Group();
	                this._initEvents(containerGroup);
	                this.group.add(containerGroup);
	            }
	            containerGroup.attr('position', [layoutInfo.x, layoutInfo.y]);

	            return containerGroup;
	        },

	        /**
	         * @private
	         */
	        _doRender: function (containerGroup, seriesModel, reRoot) {
	            var thisTree = seriesModel.getData().tree;
	            var oldTree = this._oldTree;

	            // Clear last shape records.
	            var lastsForAnimation = createStorage();
	            var thisStorage = createStorage();
	            var oldStorage = this._storage;
	            var willInvisibleEls = [];
	            var doRenderNode = zrUtil.curry(
	                renderNode, seriesModel,
	                thisStorage, oldStorage, reRoot,
	                lastsForAnimation, willInvisibleEls
	            );

	            // Notice: when thisTree and oldTree are the same tree (see list.cloneShadow),
	            // the oldTree is actually losted, so we can not find all of the old graphic
	            // elements from tree. So we use this stragegy: make element storage, move
	            // from old storage to new storage, clear old storage.

	            dualTravel(
	                thisTree.root ? [thisTree.root] : [],
	                (oldTree && oldTree.root) ? [oldTree.root] : [],
	                containerGroup,
	                thisTree === oldTree || !oldTree,
	                0
	            );

	            // Process all removing.
	            var willDeleteEls = clearStorage(oldStorage);

	            this._oldTree = thisTree;
	            this._storage = thisStorage;

	            return {
	                lastsForAnimation: lastsForAnimation,
	                willDeleteEls: willDeleteEls,
	                renderFinally: renderFinally
	            };

	            function dualTravel(thisViewChildren, oldViewChildren, parentGroup, sameTree, depth) {
	                // When 'render' is triggered by action,
	                // 'this' and 'old' may be the same tree,
	                // we use rawIndex in that case.
	                if (sameTree) {
	                    oldViewChildren = thisViewChildren;
	                    each(thisViewChildren, function (child, index) {
	                        !child.isRemoved() && processNode(index, index);
	                    });
	                }
	                // Diff hierarchically (diff only in each subtree, but not whole).
	                // because, consistency of view is important.
	                else {
	                    (new DataDiffer(oldViewChildren, thisViewChildren, getKey, getKey))
	                        .add(processNode)
	                        .update(processNode)
	                        .remove(zrUtil.curry(processNode, null))
	                        .execute();
	                }

	                function getKey(node) {
	                    // Identify by name or raw index.
	                    return node.getId();
	                }

	                function processNode(newIndex, oldIndex) {
	                    var thisNode = newIndex != null ? thisViewChildren[newIndex] : null;
	                    var oldNode = oldIndex != null ? oldViewChildren[oldIndex] : null;

	                    var group = doRenderNode(thisNode, oldNode, parentGroup, depth);

	                    group && dualTravel(
	                        thisNode && thisNode.viewChildren || [],
	                        oldNode && oldNode.viewChildren || [],
	                        group,
	                        sameTree,
	                        depth + 1
	                    );
	                }
	            }

	            function clearStorage(storage) {
	                var willDeleteEls = createStorage();
	                storage && each(storage, function (store, storageName) {
	                    var delEls = willDeleteEls[storageName];
	                    each(store, function (el) {
	                        el && (delEls.push(el), el.__tmWillDelete = 1);
	                    });
	                });
	                return willDeleteEls;
	            }

	            function renderFinally() {
	                each(willDeleteEls, function (els) {
	                    each(els, function (el) {
	                        el.parent && el.parent.remove(el);
	                    });
	                });
	                each(willInvisibleEls, function (el) {
	                    el.invisible = true;
	                    // Setting invisible is for optimizing, so no need to set dirty,
	                    // just mark as invisible.
	                    el.dirty();
	                });
	            }
	        },

	        /**
	         * @private
	         */
	        _doAnimation: function (containerGroup, renderResult, seriesModel, reRoot) {
	            if (!seriesModel.get('animation')) {
	                return;
	            }

	            var duration = seriesModel.get('animationDurationUpdate');
	            var easing = seriesModel.get('animationEasing');
	            var animationWrap = animationUtil.createWrap();

	            // Make delete animations.
	            each(renderResult.willDeleteEls, function (store, storageName) {
	                each(store, function (el, rawIndex) {
	                    if (el.invisible) {
	                        return;
	                    }

	                    var parent = el.parent; // Always has parent, and parent is nodeGroup.
	                    var target;

	                    if (reRoot && reRoot.direction === 'drillDown') {
	                        target = parent === reRoot.rootNodeGroup
	                            // This is the content element of view root.
	                            // Only `content` will enter this branch, because
	                            // `background` and `nodeGroup` will not be deleted.
	                            ? {
	                                shape: {
	                                    x: 0,
	                                    y: 0,
	                                    width: parent.__tmNodeWidth,
	                                    height: parent.__tmNodeHeight
	                                },
	                                style: {
	                                    opacity: 0
	                                }
	                            }
	                            // Others.
	                            : {style: {opacity: 0}};
	                    }
	                    else {
	                        var targetX = 0;
	                        var targetY = 0;

	                        if (!parent.__tmWillDelete) {
	                            // Let node animate to right-bottom corner, cooperating with fadeout,
	                            // which is appropriate for user understanding.
	                            // Divided by 2 for reRoot rolling up effect.
	                            targetX = parent.__tmNodeWidth / 2;
	                            targetY = parent.__tmNodeHeight / 2;
	                        }

	                        target = storageName === 'nodeGroup'
	                            ? {position: [targetX, targetY], style: {opacity: 0}}
	                            : {
	                                shape: {x: targetX, y: targetY, width: 0, height: 0},
	                                style: {opacity: 0}
	                            };
	                    }

	                    target && animationWrap.add(el, target, duration, easing);
	                });
	            });

	            // Make other animations
	            each(this._storage, function (store, storageName) {
	                each(store, function (el, rawIndex) {
	                    var last = renderResult.lastsForAnimation[storageName][rawIndex];
	                    var target = {};

	                    if (!last) {
	                        return;
	                    }

	                    if (storageName === 'nodeGroup') {
	                        if (last.old) {
	                            target.position = el.position.slice();
	                            el.attr('position', last.old);
	                        }
	                    }
	                    else {
	                        if (last.old) {
	                            target.shape = zrUtil.extend({}, el.shape);
	                            el.setShape(last.old);
	                        }

	                        if (last.fadein) {
	                            el.setStyle('opacity', 0);
	                            target.style = {opacity: 1};
	                        }
	                        // When animation is stopped for succedent animation starting,
	                        // el.style.opacity might not be 1
	                        else if (el.style.opacity !== 1) {
	                            target.style = {opacity: 1};
	                        }
	                    }

	                    animationWrap.add(el, target, duration, easing);
	                });
	            }, this);

	            this._state = 'animating';

	            animationWrap
	                .done(bind(function () {
	                    this._state = 'ready';
	                    renderResult.renderFinally();
	                }, this))
	                .start();
	        },

	        /**
	         * @private
	         */
	        _resetController: function (api) {
	            var controller = this._controller;

	            // Init controller.
	            if (!controller) {
	                controller = this._controller = new RoamController(api.getZr());
	                controller.enable(this.seriesModel.get('roam'));
	                controller.on('pan', bind(this._onPan, this));
	                controller.on('zoom', bind(this._onZoom, this));
	            }

	            var rect = new BoundingRect(0, 0, api.getWidth(), api.getHeight());
	            controller.setPointerChecker(function (e, x, y) {
	                return rect.contain(x, y);
	            });
	        },

	        /**
	         * @private
	         */
	        _clearController: function () {
	            var controller = this._controller;
	            if (controller) {
	                controller.dispose();
	                controller = null;
	            }
	        },

	        /**
	         * @private
	         */
	        _onPan: function (dx, dy) {
	            this._mayClick = false;

	            if (this._state !== 'animating'
	                && (Math.abs(dx) > DRAG_THRESHOLD || Math.abs(dy) > DRAG_THRESHOLD)
	            ) {
	                // These param must not be cached.
	                var root = this.seriesModel.getData().tree.root;

	                if (!root) {
	                    return;
	                }

	                var rootLayout = root.getLayout();

	                if (!rootLayout) {
	                    return;
	                }

	                this.api.dispatchAction({
	                    type: 'treemapMove',
	                    from: this.uid,
	                    seriesId: this.seriesModel.id,
	                    rootRect: {
	                        x: rootLayout.x + dx, y: rootLayout.y + dy,
	                        width: rootLayout.width, height: rootLayout.height
	                    }
	                });
	            }
	        },

	        /**
	         * @private
	         */
	        _onZoom: function (scale, mouseX, mouseY) {
	            this._mayClick = false;

	            if (this._state !== 'animating') {
	                // These param must not be cached.
	                var root = this.seriesModel.getData().tree.root;

	                if (!root) {
	                    return;
	                }

	                var rootLayout = root.getLayout();

	                if (!rootLayout) {
	                    return;
	                }

	                var rect = new BoundingRect(
	                    rootLayout.x, rootLayout.y, rootLayout.width, rootLayout.height
	                );
	                var layoutInfo = this.seriesModel.layoutInfo;

	                // Transform mouse coord from global to containerGroup.
	                mouseX -= layoutInfo.x;
	                mouseY -= layoutInfo.y;

	                // Scale root bounding rect.
	                var m = matrix.create();
	                matrix.translate(m, m, [-mouseX, -mouseY]);
	                matrix.scale(m, m, [scale, scale]);
	                matrix.translate(m, m, [mouseX, mouseY]);

	                rect.applyTransform(m);

	                this.api.dispatchAction({
	                    type: 'treemapRender',
	                    from: this.uid,
	                    seriesId: this.seriesModel.id,
	                    rootRect: {
	                        x: rect.x, y: rect.y,
	                        width: rect.width, height: rect.height
	                    }
	                });
	            }
	        },

	        /**
	         * @private
	         */
	        _initEvents: function (containerGroup) {
	            // FIXME
	            // 不用click以及silent的原因是，animate时视图设置silent true来避免click生效，
	            // 但是animate中，按下鼠标，animate结束后（silent设回为false）松开鼠标，
	            // 还是会触发click，期望是不触发。

	            // Mousedown occurs when drag start, and mouseup occurs when drag end,
	            // click event should not be triggered in that case.

	            containerGroup.on('mousedown', function (e) {
	                this._state === 'ready' && (this._mayClick = true);
	            }, this);
	            containerGroup.on('mouseup', function (e) {
	                if (this._mayClick) {
	                    this._mayClick = false;
	                    this._state === 'ready' && onClick.call(this, e);
	                }
	            }, this);

	            function onClick(e) {
	                var nodeClick = this.seriesModel.get('nodeClick', true);

	                if (!nodeClick) {
	                    return;
	                }

	                var targetInfo = this.findTarget(e.offsetX, e.offsetY);

	                if (!targetInfo) {
	                    return;
	                }

	                var node = targetInfo.node;
	                if (node.getLayout().isLeafRoot) {
	                    this._rootToNode(targetInfo);
	                }
	                else {
	                    if (nodeClick === 'zoomToNode') {
	                        this._zoomToNode(targetInfo);
	                    }
	                    else if (nodeClick === 'link') {
	                        var itemModel = node.hostTree.data.getItemModel(node.dataIndex);
	                        var link = itemModel.get('link', true);
	                        var linkTarget = itemModel.get('target', true) || 'blank';
	                        link && window.open(link, linkTarget);
	                    }
	                }
	            }
	        },

	        /**
	         * @private
	         */
	        _renderBreadcrumb: function (seriesModel, api, targetInfo) {
	            if (!targetInfo) {
	                targetInfo = seriesModel.get('leafDepth', true) != null
	                    ? {node: seriesModel.getViewRoot()}
	                    // FIXME
	                    // better way?
	                    // Find breadcrumb tail on center of containerGroup.
	                    : this.findTarget(api.getWidth() / 2, api.getHeight() / 2);

	                if (!targetInfo) {
	                    targetInfo = {node: seriesModel.getData().tree.root};
	                }
	            }

	            (this._breadcrumb || (this._breadcrumb = new Breadcrumb(this.group)))
	                .render(seriesModel, api, targetInfo.node, bind(onSelect, this));

	            function onSelect(node) {
	                if (this._state !== 'animating') {
	                    helper.aboveViewRoot(seriesModel.getViewRoot(), node)
	                        ? this._rootToNode({node: node})
	                        : this._zoomToNode({node: node});
	                }
	            }
	        },

	        /**
	         * @override
	         */
	        remove: function () {
	            this._clearController();
	            this._containerGroup && this._containerGroup.removeAll();
	            this._storage = createStorage();
	            this._state = 'ready';
	            this._breadcrumb && this._breadcrumb.remove();
	        },

	        dispose: function () {
	            this._clearController();
	        },

	        /**
	         * @private
	         */
	        _zoomToNode: function (targetInfo) {
	            this.api.dispatchAction({
	                type: 'treemapZoomToNode',
	                from: this.uid,
	                seriesId: this.seriesModel.id,
	                targetNode: targetInfo.node
	            });
	        },

	        /**
	         * @private
	         */
	        _rootToNode: function (targetInfo) {
	            this.api.dispatchAction({
	                type: 'treemapRootToNode',
	                from: this.uid,
	                seriesId: this.seriesModel.id,
	                targetNode: targetInfo.node
	            });
	        },

	        /**
	         * @public
	         * @param {number} x Global coord x.
	         * @param {number} y Global coord y.
	         * @return {Object} info If not found, return undefined;
	         * @return {number} info.node Target node.
	         * @return {number} info.offsetX x refer to target node.
	         * @return {number} info.offsetY y refer to target node.
	         */
	        findTarget: function (x, y) {
	            var targetInfo;
	            var viewRoot = this.seriesModel.getViewRoot();

	            viewRoot.eachNode({attr: 'viewChildren', order: 'preorder'}, function (node) {
	                var bgEl = this._storage.background[node.getRawIndex()];
	                // If invisible, there might be no element.
	                if (bgEl) {
	                    var point = bgEl.transformCoordToLocal(x, y);
	                    var shape = bgEl.shape;

	                    // For performance consideration, dont use 'getBoundingRect'.
	                    if (shape.x <= point[0]
	                        && point[0] <= shape.x + shape.width
	                        && shape.y <= point[1]
	                        && point[1] <= shape.y + shape.height
	                    ) {
	                        targetInfo = {node: node, offsetX: point[0], offsetY: point[1]};
	                    }
	                    else {
	                        return false; // Suppress visit subtree.
	                    }
	                }
	            }, this);

	            return targetInfo;
	        }

	    });

	    /**
	     * @inner
	     */
	    function createStorage() {
	        return {nodeGroup: [], background: [], content: []};
	    }

	    /**
	     * @inner
	     * @return Return undefined means do not travel further.
	     */
	    function renderNode(
	        seriesModel, thisStorage, oldStorage, reRoot,
	        lastsForAnimation, willInvisibleEls,
	        thisNode, oldNode, parentGroup, depth
	    ) {
	        // Whether under viewRoot.
	        if (!thisNode) {
	            // Deleting nodes will be performed finally. This method just find
	            // element from old storage, or create new element, set them to new
	            // storage, and set styles.
	            return;
	        }

	        // -------------------------------------------------------------------
	        // Start of closure variables available in "Procedures in renderNode".

	        var thisLayout = thisNode.getLayout();

	        if (!thisLayout || !thisLayout.isInView) {
	            return;
	        }

	        var thisWidth = thisLayout.width;
	        var thisHeight = thisLayout.height;
	        var borderWidth = thisLayout.borderWidth;
	        var thisInvisible = thisLayout.invisible;

	        var thisRawIndex = thisNode.getRawIndex();
	        var oldRawIndex = oldNode && oldNode.getRawIndex();

	        var thisViewChildren = thisNode.viewChildren;
	        var upperHeight = thisLayout.upperHeight;
	        var isParent = thisViewChildren && thisViewChildren.length;
	        var itemStyleEmphasisModel = thisNode.getModel('itemStyle.emphasis');

	        // End of closure ariables available in "Procedures in renderNode".
	        // -----------------------------------------------------------------

	        // Node group
	        var group = giveGraphic('nodeGroup', Group);

	        if (!group) {
	            return;
	        }

	        parentGroup.add(group);
	        // x,y are not set when el is above view root.
	        group.attr('position', [thisLayout.x || 0, thisLayout.y || 0]);
	        group.__tmNodeWidth = thisWidth;
	        group.__tmNodeHeight = thisHeight;

	        if (thisLayout.isAboveViewRoot) {
	            return group;
	        }

	        // Background
	        var bg = giveGraphic('background', Rect, depth, Z_BG);
	        bg && renderBackground(group, bg, isParent && thisLayout.upperHeight);

	        // No children, render content.
	        if (!isParent) {
	            var content = giveGraphic('content', Rect, depth, Z_CONTENT);
	            content && renderContent(group, content);
	        }

	        return group;

	        // ----------------------------
	        // | Procedures in renderNode |
	        // ----------------------------

	        function renderBackground(group, bg, useUpperLabel) {
	            // For tooltip.
	            bg.dataIndex = thisNode.dataIndex;
	            bg.seriesIndex = seriesModel.seriesIndex;

	            bg.setShape({x: 0, y: 0, width: thisWidth, height: thisHeight});
	            var visualBorderColor = thisNode.getVisual('borderColor', true);
	            var emphasisBorderColor = itemStyleEmphasisModel.get('borderColor');

	            updateStyle(bg, function () {
	                var normalStyle = {fill: visualBorderColor};
	                var emphasisStyle = {fill: emphasisBorderColor};

	                if (useUpperLabel) {
	                    var upperLabelWidth = thisWidth - 2 * borderWidth;

	                    prepareText(
	                        normalStyle, emphasisStyle, visualBorderColor, upperLabelWidth, upperHeight,
	                        {x: borderWidth, y: 0, width: upperLabelWidth, height: upperHeight}
	                    );
	                }
	                // For old bg.
	                else {
	                    normalStyle.text = emphasisStyle.text = '';
	                }

	                bg.setStyle(normalStyle);
	                graphic.setHoverStyle(bg, emphasisStyle);
	            });

	            group.add(bg);
	        }

	        function renderContent(group, content) {
	            // For tooltip.
	            content.dataIndex = thisNode.dataIndex;
	            content.seriesIndex = seriesModel.seriesIndex;

	            var contentWidth = Math.max(thisWidth - 2 * borderWidth, 0);
	            var contentHeight = Math.max(thisHeight - 2 * borderWidth, 0);

	            content.culling = true;
	            content.setShape({
	                x: borderWidth,
	                y: borderWidth,
	                width: contentWidth,
	                height: contentHeight
	            });

	            var visualColor = thisNode.getVisual('color', true);
	            updateStyle(content, function () {
	                var normalStyle = {fill: visualColor};
	                var emphasisStyle = itemStyleEmphasisModel.getItemStyle();

	                prepareText(normalStyle, emphasisStyle, visualColor, contentWidth, contentHeight);

	                content.setStyle(normalStyle);
	                graphic.setHoverStyle(content, emphasisStyle);
	            });

	            group.add(content);
	        }

	        function updateStyle(element, cb) {
	            if (!thisInvisible) {
	                // If invisible, do not set visual, otherwise the element will
	                // change immediately before animation. We think it is OK to
	                // remain its origin color when moving out of the view window.
	                cb();

	                if (!element.__tmWillVisible) {
	                    element.invisible = false;
	                }
	            }
	            else {
	                // Delay invisible setting utill animation finished,
	                // avoid element vanish suddenly before animation.
	                !element.invisible && willInvisibleEls.push(element);
	            }
	        }

	        function prepareText(normalStyle, emphasisStyle, visualColor, width, height, upperLabelRect) {
	            var nodeModel = thisNode.getModel();
	            var text = zrUtil.retrieve(
	                seriesModel.getFormattedLabel(
	                    thisNode.dataIndex, 'normal', null, null, upperLabelRect ? 'upperLabel' : 'label'
	                ),
	                nodeModel.get('name')
	            );
	            if (!upperLabelRect && thisLayout.isLeafRoot) {
	                var iconChar = seriesModel.get('drillDownIcon', true);
	                text = iconChar ? iconChar + ' ' + text : text;
	            }

	            setText(
	                text, normalStyle, nodeModel, upperLabelRect ? PATH_UPPERLABEL_NORMAL : PATH_LABEL_NOAMAL,
	                visualColor, width, height, upperLabelRect
	            );
	            setText(
	                text, emphasisStyle, nodeModel, upperLabelRect ? PATH_UPPERLABEL_EMPHASIS : PATH_LABEL_EMPHASIS,
	                visualColor, width, height, upperLabelRect
	            );
	        }

	        function setText(text, style, nodeModel, labelPath, visualColor, width, height, upperLabelRect) {
	            var labelModel = nodeModel.getModel(labelPath);
	            var labelTextStyleModel = labelModel.getModel('textStyle');

	            graphic.setText(style, labelModel, visualColor);

	            // text.align and text.baseline is not included by graphic.setText,
	            // because in most cases the two attributes are not exposed to user,
	            // except in treemap.
	            style.textAlign = labelTextStyleModel.get('align');
	            style.textVerticalAlign = labelTextStyleModel.get('baseline');
	            upperLabelRect && (style.textPositionRect = zrUtil.clone(upperLabelRect));

	            var textRect = labelTextStyleModel.getTextRect(text);
	            if (!labelModel.getShallow('show') || textRect.height > height) {
	                style.text = '';
	            }
	            else if (textRect.width > width) {
	                style.text = labelTextStyleModel.get('ellipsis')
	                    ? labelTextStyleModel.truncateText(
	                        text, width, null, {minChar: 2}
	                    )
	                    : '';
	            }
	            else {
	                style.text = text;
	            }
	        }

	        function giveGraphic(storageName, Ctor, depth, z) {
	            var element = oldRawIndex != null && oldStorage[storageName][oldRawIndex];
	            var lasts = lastsForAnimation[storageName];

	            if (element) {
	                // Remove from oldStorage
	                oldStorage[storageName][oldRawIndex] = null;
	                prepareAnimationWhenHasOld(lasts, element, storageName);
	            }
	            // If invisible and no old element, do not create new element (for optimizing).
	            else if (!thisInvisible) {
	                element = new Ctor({z: calculateZ(depth, z)});
	                element.__tmDepth = depth;
	                element.__tmStorageName = storageName;
	                prepareAnimationWhenNoOld(lasts, element, storageName);
	            }

	            // Set to thisStorage
	            return (thisStorage[storageName][thisRawIndex] = element);
	        }

	        function prepareAnimationWhenHasOld(lasts, element, storageName) {
	            var lastCfg = lasts[thisRawIndex] = {};
	            lastCfg.old = storageName === 'nodeGroup'
	                ? element.position.slice()
	                : zrUtil.extend({}, element.shape);
	        }

	        // If a element is new, we need to find the animation start point carefully,
	        // otherwise it will looks strange when 'zoomToNode'.
	        function prepareAnimationWhenNoOld(lasts, element, storageName) {
	            var lastCfg = lasts[thisRawIndex] = {};
	            var parentNode = thisNode.parentNode;

	            if (parentNode && (!reRoot || reRoot.direction === 'drillDown')) {
	                var parentOldX = 0;
	                var parentOldY = 0;

	                // New nodes appear from right-bottom corner in 'zoomToNode' animation.
	                // For convenience, get old bounding rect from background.
	                var parentOldBg = lastsForAnimation.background[parentNode.getRawIndex()];
	                if (!reRoot && parentOldBg && parentOldBg.old) {
	                    parentOldX = parentOldBg.old.width;
	                    parentOldY = parentOldBg.old.height;
	                }

	                // When no parent old shape found, its parent is new too,
	                // so we can just use {x:0, y:0}.
	                lastCfg.old = storageName === 'nodeGroup'
	                    ? [0, parentOldY]
	                    : {x: parentOldX, y: parentOldY, width: 0, height: 0};
	            }

	            // Fade in, user can be aware that these nodes are new.
	            lastCfg.fadein = storageName !== 'nodeGroup';
	        }
	    }

	    // We can not set all backgroud with the same z, Because the behaviour of
	    // drill down and roll up differ background creation sequence from tree
	    // hierarchy sequence, which cause that lowser background element overlap
	    // upper ones. So we calculate z based on depth.
	    // Moreover, we try to shrink down z interval to [0, 1] to avoid that
	    // treemap with large z overlaps other components.
	    function calculateZ(depth, zInLevel) {
	        var zb = depth * Z_BASE + zInLevel;
	        return (zb - 1) / zb;
	    }



/***/ },
/* 199 */
/***/ function(module, exports, __webpack_require__) {

	 

	    var graphic = __webpack_require__(18);
	    var layout = __webpack_require__(71);
	    var zrUtil = __webpack_require__(4);
	    var helper = __webpack_require__(197);

	    var TEXT_PADDING = 8;
	    var ITEM_GAP = 8;
	    var ARRAY_LENGTH = 5;

	    function Breadcrumb(containerGroup) {
	        /**
	         * @private
	         * @type {module:zrender/container/Group}
	         */
	        this.group = new graphic.Group();

	        containerGroup.add(this.group);
	    }

	    Breadcrumb.prototype = {

	        constructor: Breadcrumb,

	        render: function (seriesModel, api, targetNode, onSelect) {
	            var model = seriesModel.getModel('breadcrumb');
	            var thisGroup = this.group;

	            thisGroup.removeAll();

	            if (!model.get('show') || !targetNode) {
	                return;
	            }

	            var normalStyleModel = model.getModel('itemStyle.normal');
	            // var emphasisStyleModel = model.getModel('itemStyle.emphasis');
	            var textStyleModel = normalStyleModel.getModel('textStyle');

	            var layoutParam = {
	                pos: {
	                    left: model.get('left'),
	                    right: model.get('right'),
	                    top: model.get('top'),
	                    bottom: model.get('bottom')
	                },
	                box: {
	                    width: api.getWidth(),
	                    height: api.getHeight()
	                },
	                emptyItemWidth: model.get('emptyItemWidth'),
	                totalWidth: 0,
	                renderList: []
	            };

	            this._prepare(targetNode, layoutParam, textStyleModel);
	            this._renderContent(seriesModel, layoutParam, normalStyleModel, textStyleModel, onSelect);

	            layout.positionElement(thisGroup, layoutParam.pos, layoutParam.box);
	        },

	        /**
	         * Prepare render list and total width
	         * @private
	         */
	        _prepare: function (targetNode, layoutParam, textStyleModel) {
	            for (var node = targetNode; node; node = node.parentNode) {
	                var text = node.getModel().get('name');
	                var textRect = textStyleModel.getTextRect(text);
	                var itemWidth = Math.max(
	                    textRect.width + TEXT_PADDING * 2,
	                    layoutParam.emptyItemWidth
	                );
	                layoutParam.totalWidth += itemWidth + ITEM_GAP;
	                layoutParam.renderList.push({node: node, text: text, width: itemWidth});
	            }
	        },

	        /**
	         * @private
	         */
	        _renderContent: function (
	            seriesModel, layoutParam, normalStyleModel, textStyleModel, onSelect
	        ) {
	            // Start rendering.
	            var lastX = 0;
	            var emptyItemWidth = layoutParam.emptyItemWidth;
	            var height = seriesModel.get('breadcrumb.height');
	            var availableSize = layout.getAvailableSize(layoutParam.pos, layoutParam.box);
	            var totalWidth = layoutParam.totalWidth;
	            var renderList = layoutParam.renderList;

	            for (var i = renderList.length - 1; i >= 0; i--) {
	                var item = renderList[i];
	                var itemNode = item.node;
	                var itemWidth = item.width;
	                var text = item.text;

	                // Hdie text and shorten width if necessary.
	                if (totalWidth > availableSize.width) {
	                    totalWidth -= itemWidth - emptyItemWidth;
	                    itemWidth = emptyItemWidth;
	                    text = '';
	                }

	                var el = new graphic.Polygon({
	                    shape: {
	                        points: makeItemPoints(
	                            lastX, 0, itemWidth, height,
	                            i === renderList.length - 1, i === 0
	                        )
	                    },
	                    style: zrUtil.defaults(
	                        normalStyleModel.getItemStyle(),
	                        {
	                            lineJoin: 'bevel',
	                            text: text,
	                            textFill: textStyleModel.getTextColor(),
	                            textFont: textStyleModel.getFont()
	                        }
	                    ),
	                    z: 10,
	                    onclick: zrUtil.curry(onSelect, itemNode)
	                });
	                this.group.add(el);

	                packEventData(el, seriesModel, itemNode);

	                lastX += itemWidth + ITEM_GAP;
	            }
	        },

	        /**
	         * @override
	         */
	        remove: function () {
	            this.group.removeAll();
	        }
	    };

	    function makeItemPoints(x, y, itemWidth, itemHeight, head, tail) {
	        var points = [
	            [head ? x : x - ARRAY_LENGTH, y],
	            [x + itemWidth, y],
	            [x + itemWidth, y + itemHeight],
	            [head ? x : x - ARRAY_LENGTH, y + itemHeight]
	        ];
	        !tail && points.splice(2, 0, [x + itemWidth + ARRAY_LENGTH, y + itemHeight / 2]);
	        !head && points.push([x, y + itemHeight / 2]);
	        return points;
	    }

	    // Package custom mouse event.
	    function packEventData(el, seriesModel, itemNode) {
	        el.eventData = {
	            componentType: 'series',
	            componentSubType: 'treemap',
	            seriesIndex: seriesModel.componentIndex,
	            seriesName: seriesModel.name,
	            seriesType: 'treemap',
	            selfType: 'breadcrumb', // Distinguish with click event on treemap node.
	            nodeData: {
	                dataIndex: itemNode && itemNode.dataIndex,
	                name: itemNode && itemNode.name
	            },
	            treePathInfo: itemNode && helper.wrapTreePathInfo(itemNode, seriesModel)
	        };
	    }

	    module.exports = Breadcrumb;


/***/ },
/* 200 */
/***/ function(module, exports, __webpack_require__) {

	 

	    var zrUtil = __webpack_require__(4);

	    /**
	     * @param {number} [time=500] Time in ms
	     * @param {string} [easing='linear']
	     * @param {number} [delay=0]
	     * @param {Function} [callback]
	     *
	     * @example
	     *  // Animate position
	     *  animation
	     *      .createWrap()
	     *      .add(el1, {position: [10, 10]})
	     *      .add(el2, {shape: {width: 500}, style: {fill: 'red'}}, 400)
	     *      .done(function () { // done })
	     *      .start('cubicOut');
	     */
	    function createWrap() {

	        var storage = [];
	        var elExistsMap = {};
	        var doneCallback;

	        return {

	            /**
	             * Caution: a el can only be added once, otherwise 'done'
	             * might not be called. This method checks this (by el.id),
	             * suppresses adding and returns false when existing el found.
	             *
	             * @param {modele:zrender/Element} el
	             * @param {Object} target
	             * @param {number} [time=500]
	             * @param {number} [delay=0]
	             * @param {string} [easing='linear']
	             * @return {boolean} Whether adding succeeded.
	             *
	             * @example
	             *     add(el, target, time, delay, easing);
	             *     add(el, target, time, easing);
	             *     add(el, target, time);
	             *     add(el, target);
	             */
	            add: function (el, target, time, delay, easing) {
	                if (zrUtil.isString(delay)) {
	                    easing = delay;
	                    delay = 0;
	                }

	                if (elExistsMap[el.id]) {
	                    return false;
	                }
	                elExistsMap[el.id] = 1;

	                storage.push(
	                    {el: el, target: target, time: time, delay: delay, easing: easing}
	                );

	                return true;
	            },

	            /**
	             * Only execute when animation finished. Will not execute when any
	             * of 'stop' or 'stopAnimation' called.
	             *
	             * @param {Function} callback
	             */
	            done: function (callback) {
	                doneCallback = callback;
	                return this;
	            },

	            /**
	             * Will stop exist animation firstly.
	             */
	            start: function () {
	                var count = storage.length;

	                for (var i = 0, len = storage.length; i < len; i++) {
	                    var item = storage[i];
	                    item.el.animateTo(item.target, item.time, item.delay, item.easing, done);
	                }

	                return this;

	                function done() {
	                    count--;
	                    if (!count) {
	                        storage.length = 0;
	                        elExistsMap = {};
	                        doneCallback && doneCallback();
	                    }
	                }
	            }
	        };
	    }

	    module.exports = {createWrap: createWrap};


/***/ },
/* 201 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @file Treemap action
	 */


	    var echarts = __webpack_require__(1);
	    var helper = __webpack_require__(197);

	    var noop = function () {};

	    var actionTypes = [
	        'treemapZoomToNode',
	        'treemapRender',
	        'treemapMove'
	    ];

	    for (var i = 0; i < actionTypes.length; i++) {
	        echarts.registerAction({type: actionTypes[i], update: 'updateView'}, noop);
	    }

	    echarts.registerAction(
	        {type: 'treemapRootToNode', update: 'updateView'},
	        function (payload, ecModel) {

	            ecModel.eachComponent(
	                {mainType: 'series', subType: 'treemap', query: payload},
	                handleRootToNode
	            );

	            function handleRootToNode(model, index) {
	                var targetInfo = helper.retrieveTargetInfo(payload, model);

	                if (targetInfo) {
	                    var originViewRoot = model.getViewRoot();
	                    if (originViewRoot) {
	                        payload.direction = helper.aboveViewRoot(originViewRoot, targetInfo.node)
	                            ? 'rollUp' : 'drillDown';
	                    }
	                    model.resetViewRoot(targetInfo.node);
	                }
	            }
	        }
	    );



/***/ },
/* 202 */
/***/ function(module, exports, __webpack_require__) {

	

	    var VisualMapping = __webpack_require__(203);
	    var zrColor = __webpack_require__(31);
	    var zrUtil = __webpack_require__(4);
	    var isArray = zrUtil.isArray;

	    var ITEM_STYLE_NORMAL = 'itemStyle.normal';

	    module.exports = function (ecModel, api, payload) {

	        var condition = {mainType: 'series', subType: 'treemap', query: payload};
	        ecModel.eachComponent(condition, function (seriesModel) {

	            var tree = seriesModel.getData().tree;
	            var root = tree.root;
	            var seriesItemStyleModel = seriesModel.getModel(ITEM_STYLE_NORMAL);

	            if (root.isRemoved()) {
	                return;
	            }

	            var levelItemStyles = zrUtil.map(tree.levelModels, function (levelModel) {
	                return levelModel ? levelModel.get(ITEM_STYLE_NORMAL) : null;
	            });

	            travelTree(
	                root, // Visual should calculate from tree root but not view root.
	                {},
	                levelItemStyles,
	                seriesItemStyleModel,
	                seriesModel.getViewRoot().getAncestors(),
	                seriesModel
	            );
	        });
	    };

	    function travelTree(
	        node, designatedVisual, levelItemStyles, seriesItemStyleModel,
	        viewRootAncestors, seriesModel
	    ) {
	        var nodeModel = node.getModel();
	        var nodeLayout = node.getLayout();

	        // Optimize
	        if (!nodeLayout || nodeLayout.invisible || !nodeLayout.isInView) {
	            return;
	        }

	        var nodeItemStyleModel = node.getModel(ITEM_STYLE_NORMAL);
	        var levelItemStyle = levelItemStyles[node.depth];
	        var visuals = buildVisuals(
	            nodeItemStyleModel, designatedVisual, levelItemStyle, seriesItemStyleModel
	        );

	        // calculate border color
	        var borderColor = nodeItemStyleModel.get('borderColor');
	        var borderColorSaturation = nodeItemStyleModel.get('borderColorSaturation');
	        var thisNodeColor;
	        if (borderColorSaturation != null) {
	            // For performance, do not always execute 'calculateColor'.
	            thisNodeColor = calculateColor(visuals, node);
	            borderColor = calculateBorderColor(borderColorSaturation, thisNodeColor);
	        }
	        node.setVisual('borderColor', borderColor);

	        var viewChildren = node.viewChildren;
	        if (!viewChildren || !viewChildren.length) {
	            thisNodeColor = calculateColor(visuals, node);
	            // Apply visual to this node.
	            node.setVisual('color', thisNodeColor);
	        }
	        else {
	            var mapping = buildVisualMapping(
	                node, nodeModel, nodeLayout, nodeItemStyleModel, visuals, viewChildren
	            );

	            // Designate visual to children.
	            zrUtil.each(viewChildren, function (child, index) {
	                // If higher than viewRoot, only ancestors of viewRoot is needed to visit.
	                if (child.depth >= viewRootAncestors.length
	                    || child === viewRootAncestors[child.depth]
	                ) {
	                    var childVisual = mapVisual(
	                        nodeModel, visuals, child, index, mapping, seriesModel
	                    );
	                    travelTree(
	                        child, childVisual, levelItemStyles, seriesItemStyleModel,
	                        viewRootAncestors, seriesModel
	                    );
	                }
	            });
	        }
	    }

	    function buildVisuals(
	        nodeItemStyleModel, designatedVisual, levelItemStyle, seriesItemStyleModel
	    ) {
	        var visuals = zrUtil.extend({}, designatedVisual);

	        zrUtil.each(['color', 'colorAlpha', 'colorSaturation'], function (visualName) {
	            // Priority: thisNode > thisLevel > parentNodeDesignated > seriesModel
	            var val = nodeItemStyleModel.get(visualName, true); // Ignore parent
	            val == null && levelItemStyle && (val = levelItemStyle[visualName]);
	            val == null && (val = designatedVisual[visualName]);
	            val == null && (val = seriesItemStyleModel.get(visualName));

	            val != null && (visuals[visualName] = val);
	        });

	        return visuals;
	    }

	    function calculateColor(visuals) {
	        var color = getValueVisualDefine(visuals, 'color');

	        if (color) {
	            var colorAlpha = getValueVisualDefine(visuals, 'colorAlpha');
	            var colorSaturation = getValueVisualDefine(visuals, 'colorSaturation');
	            if (colorSaturation) {
	                color = zrColor.modifyHSL(color, null, null, colorSaturation);
	            }
	            if (colorAlpha) {
	                color = zrColor.modifyAlpha(color, colorAlpha);
	            }

	            return color;
	        }
	    }

	    function calculateBorderColor(borderColorSaturation, thisNodeColor) {
	        return thisNodeColor != null
	             ? zrColor.modifyHSL(thisNodeColor, null, null, borderColorSaturation)
	             : null;
	    }

	    function getValueVisualDefine(visuals, name) {
	        var value = visuals[name];
	        if (value != null && value !== 'none') {
	            return value;
	        }
	    }

	    function buildVisualMapping(
	        node, nodeModel, nodeLayout, nodeItemStyleModel, visuals, viewChildren
	    ) {
	        if (!viewChildren || !viewChildren.length) {
	            return;
	        }

	        var rangeVisual = getRangeVisual(nodeModel, 'color')
	            || (
	                visuals.color != null
	                && visuals.color !== 'none'
	                && (
	                    getRangeVisual(nodeModel, 'colorAlpha')
	                    || getRangeVisual(nodeModel, 'colorSaturation')
	                )
	            );

	        if (!rangeVisual) {
	            return;
	        }

	        var visualMin = nodeModel.get('visualMin');
	        var visualMax = nodeModel.get('visualMax');
	        var dataExtent = nodeLayout.dataExtent.slice();
	        visualMin != null && visualMin < dataExtent[0] && (dataExtent[0] = visualMin);
	        visualMax != null && visualMax > dataExtent[1] && (dataExtent[1] = visualMax);

	        var colorMappingBy = nodeModel.get('colorMappingBy');
	        var opt = {
	            type: rangeVisual.name,
	            dataExtent: dataExtent,
	            visual: rangeVisual.range
	        };
	        if (opt.type === 'color'
	            && (colorMappingBy === 'index' || colorMappingBy === 'id')
	        ) {
	            opt.mappingMethod = 'category';
	            opt.loop = true;
	            // categories is ordinal, so do not set opt.categories.
	        }
	        else {
	            opt.mappingMethod = 'linear';
	        }

	        var mapping = new VisualMapping(opt);
	        mapping.__drColorMappingBy = colorMappingBy;

	        return mapping;
	    }

	    // Notice: If we dont have the attribute 'colorRange', but only use
	    // attribute 'color' to represent both concepts of 'colorRange' and 'color',
	    // (It means 'colorRange' when 'color' is Array, means 'color' when not array),
	    // this problem will be encountered:
	    // If a level-1 node dont have children, and its siblings has children,
	    // and colorRange is set on level-1, then the node can not be colored.
	    // So we separate 'colorRange' and 'color' to different attributes.
	    function getRangeVisual(nodeModel, name) {
	        // 'colorRange', 'colorARange', 'colorSRange'.
	        // If not exsits on this node, fetch from levels and series.
	        var range = nodeModel.get(name);
	        return (isArray(range) && range.length) ? {name: name, range: range} : null;
	    }

	    function mapVisual(nodeModel, visuals, child, index, mapping, seriesModel) {
	        var childVisuals = zrUtil.extend({}, visuals);

	        if (mapping) {
	            var mappingType = mapping.type;
	            var colorMappingBy = mappingType === 'color' && mapping.__drColorMappingBy;
	            var value =
	                colorMappingBy === 'index'
	                ? index
	                : colorMappingBy === 'id'
	                ? seriesModel.mapIdToIndex(child.getId())
	                : child.getValue(nodeModel.get('visualDimension'));

	            childVisuals[mappingType] = mapping.mapValueToVisual(value);
	        }

	        return childVisuals;
	    }



/***/ },
/* 203 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @file Visual mapping.
	 */


	    var zrUtil = __webpack_require__(4);
	    var zrColor = __webpack_require__(31);
	    var linearMap = __webpack_require__(7).linearMap;
	    var each = zrUtil.each;
	    var isObject = zrUtil.isObject;

	    var CATEGORY_DEFAULT_VISUAL_INDEX = -1;

	    /**
	     * @param {Object} option
	     * @param {string} [option.type] See visualHandlers.
	     * @param {string} [option.mappingMethod] 'linear' or 'piecewise' or 'category' or 'fixed'
	     * @param {Array.<number>=} [option.dataExtent] [minExtent, maxExtent],
	     *                                              required when mappingMethod is 'linear'
	     * @param {Array.<Object>=} [option.pieceList] [
	     *                                             {value: someValue},
	     *                                             {interval: [min1, max1], visual: {...}},
	     *                                             {interval: [min2, max2]}
	     *                                             ],
	     *                                            required when mappingMethod is 'piecewise'.
	     *                                            Visual for only each piece can be specified.
	     * @param {Array.<string|Object>=} [option.categories] ['cate1', 'cate2']
	     *                                            required when mappingMethod is 'category'.
	     *                                            If no option.categories, categories is set
	     *                                            as [0, 1, 2, ...].
	     * @param {boolean} [option.loop=false] Whether loop mapping when mappingMethod is 'category'.
	     * @param {(Array|Object|*)} [option.visual]  Visual data.
	     *                                            when mappingMethod is 'category',
	     *                                            visual data can be array or object
	     *                                            (like: {cate1: '#222', none: '#fff'})
	     *                                            or primary types (which represents
	     *                                            defualt category visual), otherwise visual
	     *                                            can be array or primary (which will be
	     *                                            normalized to array).
	     *
	     */
	    var VisualMapping = function (option) {
	        var mappingMethod = option.mappingMethod;
	        var visualType = option.type;

	        /**
	         * @readOnly
	         * @type {Object}
	         */
	        var thisOption = this.option = zrUtil.clone(option);

	        /**
	         * @readOnly
	         * @type {string}
	         */
	        this.type = visualType;

	        /**
	         * @readOnly
	         * @type {string}
	         */
	        this.mappingMethod = mappingMethod;

	        /**
	         * @private
	         * @type {Function}
	         */
	        this._normalizeData = normalizers[mappingMethod];

	        var visualHandler = visualHandlers[visualType];

	        /**
	         * @public
	         * @type {Function}
	         */
	        this.applyVisual = visualHandler.applyVisual;

	        /**
	         * @public
	         * @type {Function}
	         */
	        this.getColorMapper = visualHandler.getColorMapper;

	        /**
	         * @private
	         * @type {Function}
	         */
	        this._doMap = visualHandler._doMap[mappingMethod];

	        if (mappingMethod === 'piecewise') {
	            normalizeVisualRange(thisOption);
	            preprocessForPiecewise(thisOption);
	        }
	        else if (mappingMethod === 'category') {
	            thisOption.categories
	                ? preprocessForSpecifiedCategory(thisOption)
	                // categories is ordinal when thisOption.categories not specified,
	                // which need no more preprocess except normalize visual.
	                : normalizeVisualRange(thisOption, true);
	        }
	        else { // mappingMethod === 'linear' or 'fixed'
	            zrUtil.assert(mappingMethod !== 'linear' || thisOption.dataExtent);
	            normalizeVisualRange(thisOption);
	        }
	    };

	    VisualMapping.prototype = {

	        constructor: VisualMapping,

	        mapValueToVisual: function (value) {
	            var normalized = this._normalizeData(value);
	            return this._doMap(normalized, value);
	        },

	        getNormalizer: function () {
	            return zrUtil.bind(this._normalizeData, this);
	        }
	    };

	    var visualHandlers = VisualMapping.visualHandlers = {

	        color: {

	            applyVisual: makeApplyVisual('color'),

	            /**
	             * Create a mapper function
	             * @return {Function}
	             */
	            getColorMapper: function () {
	                var thisOption = this.option;

	                return zrUtil.bind(
	                    thisOption.mappingMethod === 'category'
	                        ? function (value, isNormalized) {
	                            !isNormalized && (value = this._normalizeData(value));
	                            return doMapCategory.call(this, value);
	                        }
	                        : function (value, isNormalized, out) {
	                            // If output rgb array
	                            // which will be much faster and useful in pixel manipulation
	                            var returnRGBArray = !!out;
	                            !isNormalized && (value = this._normalizeData(value));
	                            out = zrColor.fastMapToColor(value, thisOption.parsedVisual, out);
	                            return returnRGBArray ? out : zrColor.stringify(out, 'rgba');
	                        },
	                    this
	                );
	            },

	            _doMap: {
	                linear: function (normalized) {
	                    return zrColor.stringify(
	                        zrColor.fastMapToColor(normalized, this.option.parsedVisual),
	                        'rgba'
	                    );
	                },
	                category: doMapCategory,
	                piecewise: function (normalized, value) {
	                    var result = getSpecifiedVisual.call(this, value);
	                    if (result == null) {
	                        result = zrColor.stringify(
	                            zrColor.fastMapToColor(normalized, this.option.parsedVisual),
	                            'rgba'
	                        );
	                    }
	                    return result;
	                },
	                fixed: doMapFixed
	            }
	        },

	        colorHue: makePartialColorVisualHandler(function (color, value) {
	            return zrColor.modifyHSL(color, value);
	        }),

	        colorSaturation: makePartialColorVisualHandler(function (color, value) {
	            return zrColor.modifyHSL(color, null, value);
	        }),

	        colorLightness: makePartialColorVisualHandler(function (color, value) {
	            return zrColor.modifyHSL(color, null, null, value);
	        }),

	        colorAlpha: makePartialColorVisualHandler(function (color, value) {
	            return zrColor.modifyAlpha(color, value);
	        }),

	        opacity: {
	            applyVisual: makeApplyVisual('opacity'),
	            _doMap: makeDoMap([0, 1])
	        },

	        symbol: {
	            applyVisual: function (value, getter, setter) {
	                var symbolCfg = this.mapValueToVisual(value);
	                if (zrUtil.isString(symbolCfg)) {
	                    setter('symbol', symbolCfg);
	                }
	                else if (isObject(symbolCfg)) {
	                    for (var name in symbolCfg) {
	                        if (symbolCfg.hasOwnProperty(name)) {
	                            setter(name, symbolCfg[name]);
	                        }
	                    }
	                }
	            },
	            _doMap: {
	                linear: doMapToArray,
	                category: doMapCategory,
	                piecewise: function (normalized, value) {
	                    var result = getSpecifiedVisual.call(this, value);
	                    if (result == null) {
	                        result = doMapToArray.call(this, normalized);
	                    }
	                    return result;
	                },
	                fixed: doMapFixed
	            }
	        },

	        symbolSize: {
	            applyVisual: makeApplyVisual('symbolSize'),
	            _doMap: makeDoMap([0, 1])
	        }
	    };


	    function preprocessForPiecewise(thisOption) {
	        var pieceList = thisOption.pieceList;
	        thisOption.hasSpecialVisual = false;

	        zrUtil.each(pieceList, function (piece, index) {
	            piece.originIndex = index;
	            // piece.visual is "result visual value" but not
	            // a visual range, so it does not need to be normalized.
	            if (piece.visual != null) {
	                thisOption.hasSpecialVisual = true;
	            }
	        });
	    }

	    function preprocessForSpecifiedCategory(thisOption) {
	        // Hash categories.
	        var categories = thisOption.categories;
	        var visual = thisOption.visual;

	        var categoryMap = thisOption.categoryMap = {};
	        each(categories, function (cate, index) {
	            categoryMap[cate] = index;
	        });

	        // Process visual map input.
	        if (!zrUtil.isArray(visual)) {
	            var visualArr = [];

	            if (zrUtil.isObject(visual)) {
	                each(visual, function (v, cate) {
	                    var index = categoryMap[cate];
	                    visualArr[index != null ? index : CATEGORY_DEFAULT_VISUAL_INDEX] = v;
	                });
	            }
	            else { // Is primary type, represents default visual.
	                visualArr[CATEGORY_DEFAULT_VISUAL_INDEX] = visual;
	            }

	            visual = setVisualToOption(thisOption, visualArr);
	        }

	        // Remove categories that has no visual,
	        // then we can mapping them to CATEGORY_DEFAULT_VISUAL_INDEX.
	        for (var i = categories.length - 1; i >= 0; i--) {
	            if (visual[i] == null) {
	                delete categoryMap[categories[i]];
	                categories.pop();
	            }
	        }
	    }

	    function normalizeVisualRange(thisOption, isCategory) {
	        var visual = thisOption.visual;
	        var visualArr = [];

	        if (zrUtil.isObject(visual)) {
	            each(visual, function (v) {
	                visualArr.push(v);
	            });
	        }
	        else if (visual != null) {
	            visualArr.push(visual);
	        }

	        var doNotNeedPair = {color: 1, symbol: 1};

	        if (!isCategory
	            && visualArr.length === 1
	            && !doNotNeedPair.hasOwnProperty(thisOption.type)
	        ) {
	            // Do not care visualArr.length === 0, which is illegal.
	            visualArr[1] = visualArr[0];
	        }

	        setVisualToOption(thisOption, visualArr);
	    }

	    function makePartialColorVisualHandler(applyValue) {
	        return {
	            applyVisual: function (value, getter, setter) {
	                value = this.mapValueToVisual(value);
	                // Must not be array value
	                setter('color', applyValue(getter('color'), value));
	            },
	            _doMap: makeDoMap([0, 1])
	        };
	    }

	    function doMapToArray(normalized) {
	        var visual = this.option.visual;
	        return visual[
	            Math.round(linearMap(normalized, [0, 1], [0, visual.length - 1], true))
	        ] || {};
	    }

	    function makeApplyVisual(visualType) {
	        return function (value, getter, setter) {
	            setter(visualType, this.mapValueToVisual(value));
	        };
	    }

	    function doMapCategory(normalized) {
	        var visual = this.option.visual;
	        return visual[
	            (this.option.loop && normalized !== CATEGORY_DEFAULT_VISUAL_INDEX)
	                ? normalized % visual.length
	                : normalized
	        ];
	    }

	    function doMapFixed() {
	        return this.option.visual[0];
	    }

	    function makeDoMap(sourceExtent) {
	        return {
	            linear: function (normalized) {
	                return linearMap(normalized, sourceExtent, this.option.visual, true);
	            },
	            category: doMapCategory,
	            piecewise: function (normalized, value) {
	                var result = getSpecifiedVisual.call(this, value);
	                if (result == null) {
	                    result = linearMap(normalized, sourceExtent, this.option.visual, true);
	                }
	                return result;
	            },
	            fixed: doMapFixed
	        };
	    }

	    function getSpecifiedVisual(value) {
	        var thisOption = this.option;
	        var pieceList = thisOption.pieceList;
	        if (thisOption.hasSpecialVisual) {
	            var pieceIndex = VisualMapping.findPieceIndex(value, pieceList);
	            var piece = pieceList[pieceIndex];
	            if (piece && piece.visual) {
	                return piece.visual[this.type];
	            }
	        }
	    }

	    function setVisualToOption(thisOption, visualArr) {
	        thisOption.visual = visualArr;
	        if (thisOption.type === 'color') {
	            thisOption.parsedVisual = zrUtil.map(visualArr, function (item) {
	                return zrColor.parse(item);
	            });
	        }
	        return visualArr;
	    }


	    /**
	     * Normalizers by mapping methods.
	     */
	    var normalizers = {

	        linear: function (value) {
	            return linearMap(value, this.option.dataExtent, [0, 1], true);
	        },

	        piecewise: function (value) {
	            var pieceList = this.option.pieceList;
	            var pieceIndex = VisualMapping.findPieceIndex(value, pieceList, true);
	            if (pieceIndex != null) {
	                return linearMap(pieceIndex, [0, pieceList.length - 1], [0, 1], true);
	            }
	        },

	        category: function (value) {
	            var index = this.option.categories
	                ? this.option.categoryMap[value]
	                : value; // ordinal
	            return index == null ? CATEGORY_DEFAULT_VISUAL_INDEX : index;
	        },

	        fixed: zrUtil.noop
	    };



	    /**
	     * List available visual types.
	     *
	     * @public
	     * @return {Array.<string>}
	     */
	    VisualMapping.listVisualTypes = function () {
	        var visualTypes = [];
	        zrUtil.each(visualHandlers, function (handler, key) {
	            visualTypes.push(key);
	        });
	        return visualTypes;
	    };

	    /**
	     * @public
	     */
	    VisualMapping.addVisualHandler = function (name, handler) {
	        visualHandlers[name] = handler;
	    };

	    /**
	     * @public
	     */
	    VisualMapping.isValidType = function (visualType) {
	        return visualHandlers.hasOwnProperty(visualType);
	    };

	    /**
	     * Convinent method.
	     * Visual can be Object or Array or primary type.
	     *
	     * @public
	     */
	    VisualMapping.eachVisual = function (visual, callback, context) {
	        if (zrUtil.isObject(visual)) {
	            zrUtil.each(visual, callback, context);
	        }
	        else {
	            callback.call(context, visual);
	        }
	    };

	    VisualMapping.mapVisual = function (visual, callback, context) {
	        var isPrimary;
	        var newVisual = zrUtil.isArray(visual)
	            ? []
	            : zrUtil.isObject(visual)
	            ? {}
	            : (isPrimary = true, null);

	        VisualMapping.eachVisual(visual, function (v, key) {
	            var newVal = callback.call(context, v, key);
	            isPrimary ? (newVisual = newVal) : (newVisual[key] = newVal);
	        });
	        return newVisual;
	    };

	    /**
	     * @public
	     * @param {Object} obj
	     * @return {Oject} new object containers visual values.
	     *                 If no visuals, return null.
	     */
	    VisualMapping.retrieveVisuals = function (obj) {
	        var ret = {};
	        var hasVisual;

	        obj && each(visualHandlers, function (h, visualType) {
	            if (obj.hasOwnProperty(visualType)) {
	                ret[visualType] = obj[visualType];
	                hasVisual = true;
	            }
	        });

	        return hasVisual ? ret : null;
	    };

	    /**
	     * Give order to visual types, considering colorSaturation, colorAlpha depends on color.
	     *
	     * @public
	     * @param {(Object|Array)} visualTypes If Object, like: {color: ..., colorSaturation: ...}
	     *                                     IF Array, like: ['color', 'symbol', 'colorSaturation']
	     * @return {Array.<string>} Sorted visual types.
	     */
	    VisualMapping.prepareVisualTypes = function (visualTypes) {
	        if (isObject(visualTypes)) {
	            var types = [];
	            each(visualTypes, function (item, type) {
	                types.push(type);
	            });
	            visualTypes = types;
	        }
	        else if (zrUtil.isArray(visualTypes)) {
	            visualTypes = visualTypes.slice();
	        }
	        else {
	            return [];
	        }

	        visualTypes.sort(function (type1, type2) {
	            // color should be front of colorSaturation, colorAlpha, ...
	            // symbol and symbolSize do not matter.
	            return (type2 === 'color' && type1 !== 'color' && type1.indexOf('color') === 0)
	                ? 1 : -1;
	        });

	        return visualTypes;
	    };

	    /**
	     * 'color', 'colorSaturation', 'colorAlpha', ... are depends on 'color'.
	     * Other visuals are only depends on themself.
	     *
	     * @public
	     * @param {string} visualType1
	     * @param {string} visualType2
	     * @return {boolean}
	     */
	    VisualMapping.dependsOn = function (visualType1, visualType2) {
	        return visualType2 === 'color'
	            ? !!(visualType1 && visualType1.indexOf(visualType2) === 0)
	            : visualType1 === visualType2;
	    };

	    /**
	     * @param {number} value
	     * @param {Array.<Object>} pieceList [{value: ..., interval: [min, max]}, ...]
	     *                         Always from small to big.
	     * @param {boolean} [findClosestWhenOutside=false]
	     * @return {number} index
	     */
	    VisualMapping.findPieceIndex = function (value, pieceList, findClosestWhenOutside) {
	        var possibleI;
	        var abs = Infinity;

	        // value has the higher priority.
	        for (var i = 0, len = pieceList.length; i < len; i++) {
	            var pieceValue = pieceList[i].value;
	            if (pieceValue != null) {
	                if (pieceValue === value
	                    // FIXME
	                    // It is supposed to compare value according to value type of dimension,
	                    // but currently value type can exactly be string or number.
	                    // Compromise for numeric-like string (like '12'), especially
	                    // in the case that visualMap.categories is ['22', '33'].
	                    || (typeof pieceValue === 'string' && pieceValue === value + '')
	                ) {
	                    return i;
	                }
	                findClosestWhenOutside && updatePossible(pieceValue, i);
	            }
	        }

	        for (var i = 0, len = pieceList.length; i < len; i++) {
	            var piece = pieceList[i];
	            var interval = piece.interval;
	            var close = piece.close;

	            if (interval) {
	                if (interval[0] === -Infinity) {
	                    if (littleThan(close[1], value, interval[1])) {
	                        return i;
	                    }
	                }
	                else if (interval[1] === Infinity) {
	                    if (littleThan(close[0], interval[0], value)) {
	                        return i;
	                    }
	                }
	                else if (
	                    littleThan(close[0], interval[0], value)
	                    && littleThan(close[1], value, interval[1])
	                ) {
	                    return i;
	                }
	                findClosestWhenOutside && updatePossible(interval[0], i);
	                findClosestWhenOutside && updatePossible(interval[1], i);
	            }
	        }

	        if (findClosestWhenOutside) {
	            return value === Infinity
	                ? pieceList.length - 1
	                : value === -Infinity
	                ? 0
	                : possibleI;
	        }

	        function updatePossible(val, index) {
	            var newAbs = Math.abs(val - value);
	            if (newAbs < abs) {
	                abs = newAbs;
	                possibleI = index;
	            }
	        }

	    };

	    function littleThan(close, a, b) {
	        return close ? a <= b : a < b;
	    }

	    module.exports = VisualMapping;



/***/ },
/* 204 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);
	    var numberUtil = __webpack_require__(7);
	    var layout = __webpack_require__(71);
	    var helper = __webpack_require__(197);
	    var BoundingRect = __webpack_require__(9);
	    var helper = __webpack_require__(197);

	    var mathMax = Math.max;
	    var mathMin = Math.min;
	    var parsePercent = numberUtil.parsePercent;
	    var retrieveValue = zrUtil.retrieve;
	    var each = zrUtil.each;

	    var PATH_BORDER_WIDTH = ['itemStyle', 'normal', 'borderWidth'];
	    var PATH_GAP_WIDTH = ['itemStyle', 'normal', 'gapWidth'];
	    var PATH_UPPER_LABEL_SHOW = ['upperLabel', 'normal', 'show'];
	    var PATH_UPPER_LABEL_HEIGHT = ['upperLabel', 'normal', 'height'];

	    /**
	     * @public
	     */
	    function update(ecModel, api, payload) {
	        // Layout result in each node:
	        // {x, y, width, height, area, borderWidth}
	        var condition = {mainType: 'series', subType: 'treemap', query: payload};
	        ecModel.eachComponent(condition, function (seriesModel) {

	            var ecWidth = api.getWidth();
	            var ecHeight = api.getHeight();
	            var seriesOption = seriesModel.option;

	            var layoutInfo = layout.getLayoutRect(
	                seriesModel.getBoxLayoutParams(),
	                {
	                    width: api.getWidth(),
	                    height: api.getHeight()
	                }
	            );

	            var size = seriesOption.size || []; // Compatible with ec2.
	            var containerWidth = parsePercent(
	                retrieveValue(layoutInfo.width, size[0]),
	                ecWidth
	            );
	            var containerHeight = parsePercent(
	                retrieveValue(layoutInfo.height, size[1]),
	                ecHeight
	            );

	            // Fetch payload info.
	            var payloadType = payload && payload.type;
	            var targetInfo = helper.retrieveTargetInfo(payload, seriesModel);
	            var rootRect = (payloadType === 'treemapRender' || payloadType === 'treemapMove')
	                ? payload.rootRect : null;
	            var viewRoot = seriesModel.getViewRoot();
	            var viewAbovePath = helper.getPathToRoot(viewRoot);

	            if (payloadType !== 'treemapMove') {
	                var rootSize = payloadType === 'treemapZoomToNode'
	                    ? estimateRootSize(
	                        seriesModel, targetInfo, viewRoot, containerWidth, containerHeight
	                    )
	                    : rootRect
	                    ? [rootRect.width, rootRect.height]
	                    : [containerWidth, containerHeight];

	                var sort = seriesOption.sort;
	                if (sort && sort !== 'asc' && sort !== 'desc') {
	                    sort = 'desc';
	                }
	                var options = {
	                    squareRatio: seriesOption.squareRatio,
	                    sort: sort,
	                    leafDepth: seriesOption.leafDepth
	                };

	                // layout should be cleared because using updateView but not update.
	                viewRoot.hostTree.clearLayouts();

	                // TODO
	                // optimize: if out of view clip, do not layout.
	                // But take care that if do not render node out of view clip,
	                // how to calculate start po

	                var viewRootLayout = {
	                    x: 0, y: 0,
	                    width: rootSize[0], height: rootSize[1],
	                    area: rootSize[0] * rootSize[1]
	                };
	                viewRoot.setLayout(viewRootLayout);

	                squarify(viewRoot, options, false, 0);
	                // Supplement layout.
	                var viewRootLayout = viewRoot.getLayout();
	                each(viewAbovePath, function (node, index) {
	                    var childValue = (viewAbovePath[index + 1] || viewRoot).getValue();
	                    node.setLayout(zrUtil.extend(
	                        {dataExtent: [childValue, childValue], borderWidth: 0, upperHeight: 0},
	                        viewRootLayout
	                    ));
	                });
	            }

	            var treeRoot = seriesModel.getData().tree.root;

	            treeRoot.setLayout(
	                calculateRootPosition(layoutInfo, rootRect, targetInfo),
	                true
	            );

	            seriesModel.setLayoutInfo(layoutInfo);

	            // FIXME
	            // 现在没有clip功能，暂时取ec高宽。
	            prunning(
	                treeRoot,
	                // Transform to base element coordinate system.
	                new BoundingRect(-layoutInfo.x, -layoutInfo.y, ecWidth, ecHeight),
	                viewAbovePath,
	                viewRoot,
	                0
	            );
	        });
	    }

	    /**
	     * Layout treemap with squarify algorithm.
	     * @see https://graphics.ethz.ch/teaching/scivis_common/Literature/squarifiedTreeMaps.pdf
	     * @see https://github.com/mbostock/d3/blob/master/src/layout/treemap.js
	     *
	     * @protected
	     * @param {module:echarts/data/Tree~TreeNode} node
	     * @param {Object} options
	     * @param {string} options.sort 'asc' or 'desc'
	     * @param {number} options.squareRatio
	     * @param {boolean} hideChildren
	     * @param {number} depth
	     */
	    function squarify(node, options, hideChildren, depth) {
	        var width;
	        var height;

	        if (node.isRemoved()) {
	            return;
	        }

	        var thisLayout = node.getLayout();
	        width = thisLayout.width;
	        height = thisLayout.height;

	        // Considering border and gap
	        var nodeModel = node.getModel();
	        var borderWidth = nodeModel.get(PATH_BORDER_WIDTH);
	        var halfGapWidth = nodeModel.get(PATH_GAP_WIDTH) / 2;
	        var upperLabelHeight = getUpperLabelHeight(nodeModel);
	        var upperHeight = Math.max(borderWidth, upperLabelHeight);
	        var layoutOffset = borderWidth - halfGapWidth;
	        var layoutOffsetUpper = upperHeight - halfGapWidth;
	        var nodeModel = node.getModel();

	        node.setLayout({
	            borderWidth: borderWidth,
	            upperHeight: upperHeight,
	            upperLabelHeight: upperLabelHeight
	        }, true);

	        width = mathMax(width - 2 * layoutOffset, 0);
	        height = mathMax(height - layoutOffset - layoutOffsetUpper, 0);

	        var totalArea = width * height;
	        var viewChildren = initChildren(
	            node, nodeModel, totalArea, options, hideChildren, depth
	        );

	        if (!viewChildren.length) {
	            return;
	        }

	        var rect = {x: layoutOffset, y: layoutOffsetUpper, width: width, height: height};
	        var rowFixedLength = mathMin(width, height);
	        var best = Infinity; // the best row score so far
	        var row = [];
	        row.area = 0;

	        for (var i = 0, len = viewChildren.length; i < len;) {
	            var child = viewChildren[i];

	            row.push(child);
	            row.area += child.getLayout().area;
	            var score = worst(row, rowFixedLength, options.squareRatio);

	            // continue with this orientation
	            if (score <= best) {
	                i++;
	                best = score;
	            }
	            // abort, and try a different orientation
	            else {
	                row.area -= row.pop().getLayout().area;
	                position(row, rowFixedLength, rect, halfGapWidth, false);
	                rowFixedLength = mathMin(rect.width, rect.height);
	                row.length = row.area = 0;
	                best = Infinity;
	            }
	        }

	        if (row.length) {
	            position(row, rowFixedLength, rect, halfGapWidth, true);
	        }

	        if (!hideChildren) {
	            var childrenVisibleMin = nodeModel.get('childrenVisibleMin');
	            if (childrenVisibleMin != null && totalArea < childrenVisibleMin) {
	                hideChildren = true;
	            }
	        }

	        for (var i = 0, len = viewChildren.length; i < len; i++) {
	            squarify(viewChildren[i], options, hideChildren, depth + 1);
	        }
	    }

	    /**
	     * Set area to each child, and calculate data extent for visual coding.
	     */
	    function initChildren(node, nodeModel, totalArea, options, hideChildren, depth) {
	        var viewChildren = node.children || [];
	        var orderBy = options.sort;
	        orderBy !== 'asc' && orderBy !== 'desc' && (orderBy = null);

	        var overLeafDepth = options.leafDepth != null && options.leafDepth <= depth;

	        // leafDepth has higher priority.
	        if (hideChildren && !overLeafDepth) {
	            return (node.viewChildren = []);
	        }

	        // Sort children, order by desc.
	        viewChildren = zrUtil.filter(viewChildren, function (child) {
	            return !child.isRemoved();
	        });

	        sort(viewChildren, orderBy);

	        var info = statistic(nodeModel, viewChildren, orderBy);

	        if (info.sum === 0) {
	            return (node.viewChildren = []);
	        }

	        info.sum = filterByThreshold(nodeModel, totalArea, info.sum, orderBy, viewChildren);

	        if (info.sum === 0) {
	            return (node.viewChildren = []);
	        }

	        // Set area to each child.
	        for (var i = 0, len = viewChildren.length; i < len; i++) {
	            var area = viewChildren[i].getValue() / info.sum * totalArea;
	            // Do not use setLayout({...}, true), because it is needed to clear last layout.
	            viewChildren[i].setLayout({area: area});
	        }

	        if (overLeafDepth) {
	            viewChildren.length && node.setLayout({isLeafRoot: true}, true);
	            viewChildren.length = 0;
	        }

	        node.viewChildren = viewChildren;
	        node.setLayout({dataExtent: info.dataExtent}, true);

	        return viewChildren;
	    }

	    /**
	     * Consider 'visibleMin'. Modify viewChildren and get new sum.
	     */
	    function filterByThreshold(nodeModel, totalArea, sum, orderBy, orderedChildren) {

	        // visibleMin is not supported yet when no option.sort.
	        if (!orderBy) {
	            return sum;
	        }

	        var visibleMin = nodeModel.get('visibleMin');
	        var len = orderedChildren.length;
	        var deletePoint = len;

	        // Always travel from little value to big value.
	        for (var i = len - 1; i >= 0; i--) {
	            var value = orderedChildren[
	                orderBy === 'asc' ? len - i - 1 : i
	            ].getValue();

	            if (value / sum * totalArea < visibleMin) {
	                deletePoint = i;
	                sum -= value;
	            }
	        }

	        orderBy === 'asc'
	            ? orderedChildren.splice(0, len - deletePoint)
	            : orderedChildren.splice(deletePoint, len - deletePoint);

	        return sum;
	    }

	    /**
	     * Sort
	     */
	    function sort(viewChildren, orderBy) {
	        if (orderBy) {
	            viewChildren.sort(function (a, b) {
	                var diff = orderBy === 'asc'
	                    ?  a.getValue() - b.getValue() : b.getValue() - a.getValue();
	                return diff === 0
	                    ? (orderBy === 'asc'
	                        ? a.dataIndex - b.dataIndex : b.dataIndex - a.dataIndex
	                    )
	                    : diff;
	            });
	        }
	        return viewChildren;
	    }

	    /**
	     * Statistic
	     */
	    function statistic(nodeModel, children, orderBy) {
	        // Calculate sum.
	        var sum = 0;
	        for (var i = 0, len = children.length; i < len; i++) {
	            sum += children[i].getValue();
	        }

	        // Statistic data extent for latter visual coding.
	        // Notice: data extent should be calculate based on raw children
	        // but not filtered view children, otherwise visual mapping will not
	        // be stable when zoom (where children is filtered by visibleMin).

	        var dimension = nodeModel.get('visualDimension');
	        var dataExtent;

	        // The same as area dimension.
	        if (!children || !children.length) {
	            dataExtent = [NaN, NaN];
	        }
	        else if (dimension === 'value' && orderBy) {
	            dataExtent = [
	                children[children.length - 1].getValue(),
	                children[0].getValue()
	            ];
	            orderBy === 'asc' && dataExtent.reverse();
	        }
	        // Other dimension.
	        else {
	            var dataExtent = [Infinity, -Infinity];
	            each(children, function (child) {
	                var value = child.getValue(dimension);
	                value < dataExtent[0] && (dataExtent[0] = value);
	                value > dataExtent[1] && (dataExtent[1] = value);
	            });
	        }

	        return {sum: sum, dataExtent: dataExtent};
	    }

	    /**
	     * Computes the score for the specified row,
	     * as the worst aspect ratio.
	     */
	    function worst(row, rowFixedLength, ratio) {
	        var areaMax = 0;
	        var areaMin = Infinity;

	        for (var i = 0, area, len = row.length; i < len; i++) {
	            area = row[i].getLayout().area;
	            if (area) {
	                area < areaMin && (areaMin = area);
	                area > areaMax && (areaMax = area);
	            }
	        }

	        var squareArea = row.area * row.area;
	        var f = rowFixedLength * rowFixedLength * ratio;

	        return squareArea
	            ? mathMax(
	                (f * areaMax) / squareArea,
	                squareArea / (f * areaMin)
	            )
	            : Infinity;
	    }

	    /**
	     * Positions the specified row of nodes. Modifies `rect`.
	     */
	    function position(row, rowFixedLength, rect, halfGapWidth, flush) {
	        // When rowFixedLength === rect.width,
	        // it is horizontal subdivision,
	        // rowFixedLength is the width of the subdivision,
	        // rowOtherLength is the height of the subdivision,
	        // and nodes will be positioned from left to right.

	        // wh[idx0WhenH] means: when horizontal,
	        //      wh[idx0WhenH] => wh[0] => 'width'.
	        //      xy[idx1WhenH] => xy[1] => 'y'.
	        var idx0WhenH = rowFixedLength === rect.width ? 0 : 1;
	        var idx1WhenH = 1 - idx0WhenH;
	        var xy = ['x', 'y'];
	        var wh = ['width', 'height'];

	        var last = rect[xy[idx0WhenH]];
	        var rowOtherLength = rowFixedLength
	            ? row.area / rowFixedLength : 0;

	        if (flush || rowOtherLength > rect[wh[idx1WhenH]]) {
	            rowOtherLength = rect[wh[idx1WhenH]]; // over+underflow
	        }
	        for (var i = 0, rowLen = row.length; i < rowLen; i++) {
	            var node = row[i];
	            var nodeLayout = {};
	            var step = rowOtherLength
	                ? node.getLayout().area / rowOtherLength : 0;

	            var wh1 = nodeLayout[wh[idx1WhenH]] = mathMax(rowOtherLength - 2 * halfGapWidth, 0);

	            // We use Math.max/min to avoid negative width/height when considering gap width.
	            var remain = rect[xy[idx0WhenH]] + rect[wh[idx0WhenH]] - last;
	            var modWH = (i === rowLen - 1 || remain < step) ? remain : step;
	            var wh0 = nodeLayout[wh[idx0WhenH]] = mathMax(modWH - 2 * halfGapWidth, 0);

	            nodeLayout[xy[idx1WhenH]] = rect[xy[idx1WhenH]] + mathMin(halfGapWidth, wh1 / 2);
	            nodeLayout[xy[idx0WhenH]] = last + mathMin(halfGapWidth, wh0 / 2);

	            last += modWH;
	            node.setLayout(nodeLayout, true);
	        }

	        rect[xy[idx1WhenH]] += rowOtherLength;
	        rect[wh[idx1WhenH]] -= rowOtherLength;
	    }

	    // Return [containerWidth, containerHeight] as defualt.
	    function estimateRootSize(seriesModel, targetInfo, viewRoot, containerWidth, containerHeight) {
	        // If targetInfo.node exists, we zoom to the node,
	        // so estimate whold width and heigth by target node.
	        var currNode = (targetInfo || {}).node;
	        var defaultSize = [containerWidth, containerHeight];

	        if (!currNode || currNode === viewRoot) {
	            return defaultSize;
	        }

	        var parent;
	        var viewArea = containerWidth * containerHeight;
	        var area = viewArea * seriesModel.option.zoomToNodeRatio;

	        while (parent = currNode.parentNode) { // jshint ignore:line
	            var sum = 0;
	            var siblings = parent.children;

	            for (var i = 0, len = siblings.length; i < len; i++) {
	                sum += siblings[i].getValue();
	            }
	            var currNodeValue = currNode.getValue();
	            if (currNodeValue === 0) {
	                return defaultSize;
	            }
	            area *= sum / currNodeValue;

	            // Considering border, suppose aspect ratio is 1.
	            var parentModel = parent.getModel();
	            var borderWidth = parentModel.get(PATH_BORDER_WIDTH);
	            var upperHeight = Math.max(borderWidth, getUpperLabelHeight(parentModel, borderWidth));
	            area += 4 * borderWidth * borderWidth
	                + (3 * borderWidth + upperHeight) * Math.pow(area, 0.5);

	            area > numberUtil.MAX_SAFE_INTEGER && (area = numberUtil.MAX_SAFE_INTEGER);

	            currNode = parent;
	        }

	        area < viewArea && (area = viewArea);
	        var scale = Math.pow(area / viewArea, 0.5);

	        return [containerWidth * scale, containerHeight * scale];
	    }

	    // Root postion base on coord of containerGroup
	    function calculateRootPosition(layoutInfo, rootRect, targetInfo) {
	        if (rootRect) {
	            return {x: rootRect.x, y: rootRect.y};
	        }

	        var defaultPosition = {x: 0, y: 0};
	        if (!targetInfo) {
	            return defaultPosition;
	        }

	        // If targetInfo is fetched by 'retrieveTargetInfo',
	        // old tree and new tree are the same tree,
	        // so the node still exists and we can visit it.

	        var targetNode = targetInfo.node;
	        var layout = targetNode.getLayout();

	        if (!layout) {
	            return defaultPosition;
	        }

	        // Transform coord from local to container.
	        var targetCenter = [layout.width / 2, layout.height / 2];
	        var node = targetNode;
	        while (node) {
	            var nodeLayout = node.getLayout();
	            targetCenter[0] += nodeLayout.x;
	            targetCenter[1] += nodeLayout.y;
	            node = node.parentNode;
	        }

	        return {
	            x: layoutInfo.width / 2 - targetCenter[0],
	            y: layoutInfo.height / 2 - targetCenter[1]
	        };
	    }

	    // Mark nodes visible for prunning when visual coding and rendering.
	    // Prunning depends on layout and root position, so we have to do it after layout.
	    function prunning(node, clipRect, viewAbovePath, viewRoot, depth) {
	        var nodeLayout = node.getLayout();
	        var nodeInViewAbovePath = viewAbovePath[depth];
	        var isAboveViewRoot = nodeInViewAbovePath && nodeInViewAbovePath === node;

	        if (
	            (nodeInViewAbovePath && !isAboveViewRoot)
	            || (depth === viewAbovePath.length && node !== viewRoot)
	        ) {
	            return;
	        }

	        node.setLayout({
	            // isInView means: viewRoot sub tree + viewAbovePath
	            isInView: true,
	            // invisible only means: outside view clip so that the node can not
	            // see but still layout for animation preparation but not render.
	            invisible: !isAboveViewRoot && !clipRect.intersect(nodeLayout),
	            isAboveViewRoot: isAboveViewRoot
	        }, true);

	        // Transform to child coordinate.
	        var childClipRect = new BoundingRect(
	            clipRect.x - nodeLayout.x,
	            clipRect.y - nodeLayout.y,
	            clipRect.width,
	            clipRect.height
	        );

	        each(node.viewChildren || [], function (child) {
	            prunning(child, childClipRect, viewAbovePath, viewRoot, depth + 1);
	        });
	    }

	    function getUpperLabelHeight(model) {
	        return model.get(PATH_UPPER_LABEL_SHOW) ? model.get(PATH_UPPER_LABEL_HEIGHT) : 0;
	    }

	    module.exports = update;


/***/ },
/* 205 */
/***/ function(module, exports, __webpack_require__) {

	

	    var echarts = __webpack_require__(1);
	    var zrUtil = __webpack_require__(4);

	    __webpack_require__(206);
	    __webpack_require__(209);

	    __webpack_require__(214);

	    echarts.registerProcessor(__webpack_require__(215));

	    echarts.registerVisual(zrUtil.curry(
	        __webpack_require__(121), 'graph', 'circle', null
	    ));
	    echarts.registerVisual(__webpack_require__(216));
	    echarts.registerVisual(__webpack_require__(217));

	    echarts.registerLayout(__webpack_require__(218));
	    echarts.registerLayout(__webpack_require__(221));
	    echarts.registerLayout(__webpack_require__(223));

	    // Graph view coordinate system
	    echarts.registerCoordinateSystem('graphView', {
	        create: __webpack_require__(225)
	    });


/***/ },
/* 206 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var List = __webpack_require__(98);
	    var zrUtil = __webpack_require__(4);
	    var modelUtil = __webpack_require__(5);
	    var Model = __webpack_require__(12);
	    var formatUtil = __webpack_require__(6);

	    var createGraphFromNodeEdge = __webpack_require__(207);

	    var GraphSeries = __webpack_require__(1).extendSeriesModel({

	        type: 'series.graph',

	        init: function (option) {
	            GraphSeries.superApply(this, 'init', arguments);

	            // Provide data for legend select
	            this.legendDataProvider = function () {
	                return this._categoriesData;
	            };

	            this.fillDataTextStyle(option.edges || option.links);

	            this._updateCategoriesData();
	        },

	        mergeOption: function (option) {
	            GraphSeries.superApply(this, 'mergeOption', arguments);

	            this.fillDataTextStyle(option.edges || option.links);

	            this._updateCategoriesData();
	        },

	        mergeDefaultAndTheme: function (option) {
	            GraphSeries.superApply(this, 'mergeDefaultAndTheme', arguments);
	            modelUtil.defaultEmphasis(option.edgeLabel, modelUtil.LABEL_OPTIONS);
	        },

	        getInitialData: function (option, ecModel) {
	            var edges = option.edges || option.links || [];
	            var nodes = option.data || option.nodes || [];
	            var self = this;

	            if (nodes && edges) {
	                return createGraphFromNodeEdge(nodes, edges, this, true, beforeLink).data;
	            }

	            function beforeLink(nodeData, edgeData) {
	                // Overwrite nodeData.getItemModel to
	                nodeData.wrapMethod('getItemModel', function (model) {
	                    var categoriesModels = self._categoriesModels;
	                    var categoryIdx = model.getShallow('category');
	                    var categoryModel = categoriesModels[categoryIdx];
	                    if (categoryModel) {
	                        categoryModel.parentModel = model.parentModel;
	                        model.parentModel = categoryModel;
	                    }
	                    return model;
	                });

	                var edgeLabelModel = self.getModel('edgeLabel');
	                // For option `edgeLabel` can be found by label.xxx.xxx on item mode.
	                var fakeSeriesModel = new Model(
	                    {label: edgeLabelModel.option},
	                    edgeLabelModel.parentModel,
	                    ecModel
	                );

	                edgeData.wrapMethod('getItemModel', function (model) {
	                    model.customizeGetParent(edgeGetParent);
	                    return model;
	                });

	                function edgeGetParent(path) {
	                    path = this.parsePath(path);
	                    return (path && path[0] === 'label')
	                        ? fakeSeriesModel
	                        : this.parentModel;
	                }
	            }
	        },

	        /**
	         * @return {module:echarts/data/Graph}
	         */
	        getGraph: function () {
	            return this.getData().graph;
	        },

	        /**
	         * @return {module:echarts/data/List}
	         */
	        getEdgeData: function () {
	            return this.getGraph().edgeData;
	        },

	        /**
	         * @return {module:echarts/data/List}
	         */
	        getCategoriesData: function () {
	            return this._categoriesData;
	        },

	        /**
	         * @override
	         */
	        formatTooltip: function (dataIndex, multipleSeries, dataType) {
	            if (dataType === 'edge') {
	                var nodeData = this.getData();
	                var params = this.getDataParams(dataIndex, dataType);
	                var edge = nodeData.graph.getEdgeByIndex(dataIndex);
	                var sourceName = nodeData.getName(edge.node1.dataIndex);
	                var targetName = nodeData.getName(edge.node2.dataIndex);

	                var html = [];
	                sourceName != null && html.push(sourceName);
	                targetName != null && html.push(targetName);
	                html = formatUtil.encodeHTML(html.join(' > '));

	                if (params.value) {
	                    html += ' : ' + formatUtil.encodeHTML(params.value);
	                }
	                return html;
	            }
	            else { // dataType === 'node' or empty
	                return GraphSeries.superApply(this, 'formatTooltip', arguments);
	            }
	        },

	        _updateCategoriesData: function () {
	            var categories = zrUtil.map(this.option.categories || [], function (category) {
	                // Data must has value
	                return category.value != null ? category : zrUtil.extend({
	                    value: 0
	                }, category);
	            });
	            var categoriesData = new List(['value'], this);
	            categoriesData.initData(categories);

	            this._categoriesData = categoriesData;

	            this._categoriesModels = categoriesData.mapArray(function (idx) {
	                return categoriesData.getItemModel(idx, true);
	            });
	        },

	        setZoom: function (zoom) {
	            this.option.zoom = zoom;
	        },

	        setCenter: function (center) {
	            this.option.center = center;
	        },

	        isAnimationEnabled: function () {
	            return GraphSeries.superCall(this, 'isAnimationEnabled')
	                // Not enable animation when do force layout
	                && !(this.get('layout') === 'force' && this.get('force.layoutAnimation'));
	        },

	        defaultOption: {
	            zlevel: 0,
	            z: 2,

	            coordinateSystem: 'view',

	            // Default option for all coordinate systems
	            // xAxisIndex: 0,
	            // yAxisIndex: 0,
	            // polarIndex: 0,
	            // geoIndex: 0,

	            legendHoverLink: true,

	            hoverAnimation: true,

	            layout: null,

	            focusNodeAdjacency: false,

	            // Configuration of circular layout
	            circular: {
	                rotateLabel: false
	            },
	            // Configuration of force directed layout
	            force: {
	                initLayout: null,
	                // Node repulsion. Can be an array to represent range.
	                repulsion: [0, 50],
	                gravity: 0.1,

	                // Edge length. Can be an array to represent range.
	                edgeLength: 30,

	                layoutAnimation: true
	            },

	            left: 'center',
	            top: 'center',
	            // right: null,
	            // bottom: null,
	            // width: '80%',
	            // height: '80%',

	            symbol: 'circle',
	            symbolSize: 10,

	            edgeSymbol: ['none', 'none'],
	            edgeSymbolSize: 10,
	            edgeLabel: {
	                normal: {
	                    position: 'middle'
	                },
	                emphasis: {}
	            },

	            draggable: false,

	            roam: false,

	            // Default on center of graph
	            center: null,

	            zoom: 1,
	            // Symbol size scale ratio in roam
	            nodeScaleRatio: 0.6,
	            // cursor: null,

	            // categories: [],

	            // data: []
	            // Or
	            // nodes: []
	            //
	            // links: []
	            // Or
	            // edges: []

	            label: {
	                normal: {
	                    show: false,
	                    formatter: '{b}'
	                },
	                emphasis: {
	                    show: true
	                }
	            },

	            itemStyle: {
	                normal: {},
	                emphasis: {}
	            },

	            lineStyle: {
	                normal: {
	                    color: '#aaa',
	                    width: 1,
	                    curveness: 0,
	                    opacity: 0.5
	                },
	                emphasis: {}
	            }
	        }
	    });

	    module.exports = GraphSeries;


/***/ },
/* 207 */
/***/ function(module, exports, __webpack_require__) {

	

	    var List = __webpack_require__(98);
	    var Graph = __webpack_require__(208);
	    var linkList = __webpack_require__(196);
	    var completeDimensions = __webpack_require__(110);
	    var CoordinateSystem = __webpack_require__(76);
	    var zrUtil = __webpack_require__(4);
	    var createListFromArray = __webpack_require__(109);

	    module.exports = function (nodes, edges, hostModel, directed, beforeLink) {
	        var graph = new Graph(directed);
	        for (var i = 0; i < nodes.length; i++) {
	            graph.addNode(zrUtil.retrieve(
	                // Id, name, dataIndex
	                nodes[i].id, nodes[i].name, i
	            ), i);
	        }

	        var linkNameList = [];
	        var validEdges = [];
	        var linkCount = 0;
	        for (var i = 0; i < edges.length; i++) {
	            var link = edges[i];
	            var source = link.source;
	            var target = link.target;
	            // addEdge may fail when source or target not exists
	            if (graph.addEdge(source, target, linkCount)) {
	                validEdges.push(link);
	                linkNameList.push(zrUtil.retrieve(link.id, source + ' > ' + target));
	                linkCount++;
	            }
	        }

	        var coordSys = hostModel.get('coordinateSystem');
	        var nodeData;
	        if (coordSys === 'cartesian2d' || coordSys === 'polar') {
	            nodeData = createListFromArray(nodes, hostModel, hostModel.ecModel);
	        }
	        else {
	            // FIXME
	            var coordSysCtor = CoordinateSystem.get(coordSys);
	            // FIXME
	            var dimensionNames = completeDimensions(
	                ((coordSysCtor && coordSysCtor.type !== 'view') ? (coordSysCtor.dimensions || []) : []).concat(['value']),
	                nodes
	            );
	            nodeData = new List(dimensionNames, hostModel);
	            nodeData.initData(nodes);
	        }

	        var edgeData = new List(['value'], hostModel);
	        edgeData.initData(validEdges, linkNameList);

	        beforeLink && beforeLink(nodeData, edgeData);

	        linkList({
	            mainData: nodeData,
	            struct: graph,
	            structAttr: 'graph',
	            datas: {node: nodeData, edge: edgeData},
	            datasAttr: {node: 'data', edge: 'edgeData'}
	        });

	        // Update dataIndex of nodes and edges because invalid edge may be removed
	        graph.update();

	        return graph;
	    };


/***/ },
/* 208 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	/**
	 * Graph data structure
	 *
	 * @module echarts/data/Graph
	 * @author Yi Shen(https://www.github.com/pissang)
	 */


	    var zrUtil = __webpack_require__(4);

	    // id may be function name of Object, add a prefix to avoid this problem.
	    function generateNodeKey (id) {
	        return '_EC_' + id;
	    }
	    /**
	     * @alias module:echarts/data/Graph
	     * @constructor
	     * @param {boolean} directed
	     */
	    var Graph = function(directed) {
	        /**
	         * 是否是有向图
	         * @type {boolean}
	         * @private
	         */
	        this._directed = directed || false;

	        /**
	         * @type {Array.<module:echarts/data/Graph.Node>}
	         * @readOnly
	         */
	        this.nodes = [];

	        /**
	         * @type {Array.<module:echarts/data/Graph.Edge>}
	         * @readOnly
	         */
	        this.edges = [];

	        /**
	         * @type {Object.<string, module:echarts/data/Graph.Node>}
	         * @private
	         */
	        this._nodesMap = {};
	        /**
	         * @type {Object.<string, module:echarts/data/Graph.Edge>}
	         * @private
	         */
	        this._edgesMap = {};

	        /**
	         * @type {module:echarts/data/List}
	         * @readOnly
	         */
	        this.data;

	        /**
	         * @type {module:echarts/data/List}
	         * @readOnly
	         */
	        this.edgeData;
	    };

	    var graphProto = Graph.prototype;
	    /**
	     * @type {string}
	     */
	    graphProto.type = 'graph';

	    /**
	     * If is directed graph
	     * @return {boolean}
	     */
	    graphProto.isDirected = function () {
	        return this._directed;
	    };

	    /**
	     * Add a new node
	     * @param {string} id
	     * @param {number} [dataIndex]
	     */
	    graphProto.addNode = function (id, dataIndex) {
	        id = id || ('' + dataIndex);

	        var nodesMap = this._nodesMap;

	        if (nodesMap[generateNodeKey(id)]) {
	            if (true) {
	                console.error('Graph nodes have duplicate name or id');
	            }
	            return;
	        }

	        var node = new Node(id, dataIndex);
	        node.hostGraph = this;

	        this.nodes.push(node);

	        nodesMap[generateNodeKey(id)] = node;
	        return node;
	    };

	    /**
	     * Get node by data index
	     * @param  {number} dataIndex
	     * @return {module:echarts/data/Graph~Node}
	     */
	    graphProto.getNodeByIndex = function (dataIndex) {
	        var rawIdx = this.data.getRawIndex(dataIndex);
	        return this.nodes[rawIdx];
	    };
	    /**
	     * Get node by id
	     * @param  {string} id
	     * @return {module:echarts/data/Graph.Node}
	     */
	    graphProto.getNodeById = function (id) {
	        return this._nodesMap[generateNodeKey(id)];
	    };

	    /**
	     * Add a new edge
	     * @param {number|string|module:echarts/data/Graph.Node} n1
	     * @param {number|string|module:echarts/data/Graph.Node} n2
	     * @param {number} [dataIndex=-1]
	     * @return {module:echarts/data/Graph.Edge}
	     */
	    graphProto.addEdge = function (n1, n2, dataIndex) {
	        var nodesMap = this._nodesMap;
	        var edgesMap = this._edgesMap;

	        // PNEDING
	        if (typeof n1 === 'number') {
	            n1 = this.nodes[n1];
	        }
	        if (typeof n2 === 'number') {
	            n2 = this.nodes[n2];
	        }

	        if (!(n1 instanceof Node)) {
	            n1 = nodesMap[generateNodeKey(n1)];
	        }
	        if (!(n2 instanceof Node)) {
	            n2 = nodesMap[generateNodeKey(n2)];
	        }
	        if (!n1 || !n2) {
	            return;
	        }

	        var key = n1.id + '-' + n2.id;
	        // PENDING
	        if (edgesMap[key]) {
	            return;
	        }

	        var edge = new Edge(n1, n2, dataIndex);
	        edge.hostGraph = this;

	        if (this._directed) {
	            n1.outEdges.push(edge);
	            n2.inEdges.push(edge);
	        }
	        n1.edges.push(edge);
	        if (n1 !== n2) {
	            n2.edges.push(edge);
	        }

	        this.edges.push(edge);
	        edgesMap[key] = edge;

	        return edge;
	    };

	    /**
	     * Get edge by data index
	     * @param  {number} dataIndex
	     * @return {module:echarts/data/Graph~Node}
	     */
	    graphProto.getEdgeByIndex = function (dataIndex) {
	        var rawIdx = this.edgeData.getRawIndex(dataIndex);
	        return this.edges[rawIdx];
	    };
	    /**
	     * Get edge by two linked nodes
	     * @param  {module:echarts/data/Graph.Node|string} n1
	     * @param  {module:echarts/data/Graph.Node|string} n2
	     * @return {module:echarts/data/Graph.Edge}
	     */
	    graphProto.getEdge = function (n1, n2) {
	        if (n1 instanceof Node) {
	            n1 = n1.id;
	        }
	        if (n2 instanceof Node) {
	            n2 = n2.id;
	        }

	        var edgesMap = this._edgesMap;

	        if (this._directed) {
	            return edgesMap[n1 + '-' + n2];
	        } else {
	            return edgesMap[n1 + '-' + n2]
	                || edgesMap[n2 + '-' + n1];
	        }
	    };

	    /**
	     * Iterate all nodes
	     * @param  {Function} cb
	     * @param  {*} [context]
	     */
	    graphProto.eachNode = function (cb, context) {
	        var nodes = this.nodes;
	        var len = nodes.length;
	        for (var i = 0; i < len; i++) {
	            if (nodes[i].dataIndex >= 0) {
	                cb.call(context, nodes[i], i);
	            }
	        }
	    };

	    /**
	     * Iterate all edges
	     * @param  {Function} cb
	     * @param  {*} [context]
	     */
	    graphProto.eachEdge = function (cb, context) {
	        var edges = this.edges;
	        var len = edges.length;
	        for (var i = 0; i < len; i++) {
	            if (edges[i].dataIndex >= 0
	                && edges[i].node1.dataIndex >= 0
	                && edges[i].node2.dataIndex >= 0
	            ) {
	                cb.call(context, edges[i], i);
	            }
	        }
	    };

	    /**
	     * Breadth first traverse
	     * @param {Function} cb
	     * @param {module:echarts/data/Graph.Node} startNode
	     * @param {string} [direction='none'] 'none'|'in'|'out'
	     * @param {*} [context]
	     */
	    graphProto.breadthFirstTraverse = function (
	        cb, startNode, direction, context
	    ) {
	        if (!(startNode instanceof Node)) {
	            startNode = this._nodesMap[generateNodeKey(startNode)];
	        }
	        if (!startNode) {
	            return;
	        }

	        var edgeType = direction === 'out'
	            ? 'outEdges' : (direction === 'in' ? 'inEdges' : 'edges');

	        for (var i = 0; i < this.nodes.length; i++) {
	            this.nodes[i].__visited = false;
	        }

	        if (cb.call(context, startNode, null)) {
	            return;
	        }

	        var queue = [startNode];
	        while (queue.length) {
	            var currentNode = queue.shift();
	            var edges = currentNode[edgeType];

	            for (var i = 0; i < edges.length; i++) {
	                var e = edges[i];
	                var otherNode = e.node1 === currentNode
	                    ? e.node2 : e.node1;
	                if (!otherNode.__visited) {
	                    if (cb.call(context, otherNode, currentNode)) {
	                        // Stop traversing
	                        return;
	                    }
	                    queue.push(otherNode);
	                    otherNode.__visited = true;
	                }
	            }
	        }
	    };

	    // TODO
	    // graphProto.depthFirstTraverse = function (
	    //     cb, startNode, direction, context
	    // ) {

	    // };

	    // Filter update
	    graphProto.update = function () {
	        var data = this.data;
	        var edgeData = this.edgeData;
	        var nodes = this.nodes;
	        var edges = this.edges;

	        for (var i = 0, len = nodes.length; i < len; i++) {
	            nodes[i].dataIndex = -1;
	        }
	        for (var i = 0, len = data.count(); i < len; i++) {
	            nodes[data.getRawIndex(i)].dataIndex = i;
	        }

	        edgeData.filterSelf(function (idx) {
	            var edge = edges[edgeData.getRawIndex(idx)];
	            return edge.node1.dataIndex >= 0 && edge.node2.dataIndex >= 0;
	        });

	        // Update edge
	        for (var i = 0, len = edges.length; i < len; i++) {
	            edges[i].dataIndex = -1;
	        }
	        for (var i = 0, len = edgeData.count(); i < len; i++) {
	            edges[edgeData.getRawIndex(i)].dataIndex = i;
	        }
	    };

	    /**
	     * @return {module:echarts/data/Graph}
	     */
	    graphProto.clone = function () {
	        var graph = new Graph(this._directed);
	        var nodes = this.nodes;
	        var edges = this.edges;
	        for (var i = 0; i < nodes.length; i++) {
	            graph.addNode(nodes[i].id, nodes[i].dataIndex);
	        }
	        for (var i = 0; i < edges.length; i++) {
	            var e = edges[i];
	            graph.addEdge(e.node1.id, e.node2.id, e.dataIndex);
	        }
	        return graph;
	    };


	    /**
	     * @alias module:echarts/data/Graph.Node
	     */
	    function Node(id, dataIndex) {
	        /**
	        * @type {string}
	        */
	        this.id = id == null ? '' : id;

	        /**
	        * @type {Array.<module:echarts/data/Graph.Edge>}
	        */
	        this.inEdges = [];
	        /**
	        * @type {Array.<module:echarts/data/Graph.Edge>}
	        */
	        this.outEdges = [];
	        /**
	        * @type {Array.<module:echarts/data/Graph.Edge>}
	        */
	        this.edges = [];
	        /**
	         * @type {module:echarts/data/Graph}
	         */
	        this.hostGraph;

	        /**
	         * @type {number}
	         */
	        this.dataIndex = dataIndex == null ? -1 : dataIndex;
	    }

	    Node.prototype = {

	        constructor: Node,

	        /**
	         * @return {number}
	         */
	        degree: function () {
	            return this.edges.length;
	        },

	        /**
	         * @return {number}
	         */
	        inDegree: function () {
	            return this.inEdges.length;
	        },

	        /**
	        * @return {number}
	        */
	        outDegree: function () {
	            return this.outEdges.length;
	        },

	        /**
	         * @param {string} [path]
	         * @return {module:echarts/model/Model}
	         */
	        getModel: function (path) {
	            if (this.dataIndex < 0) {
	                return;
	            }
	            var graph = this.hostGraph;
	            var itemModel = graph.data.getItemModel(this.dataIndex);

	            return itemModel.getModel(path);
	        }
	    };

	    /**
	     * 图边
	     * @alias module:echarts/data/Graph.Edge
	     * @param {module:echarts/data/Graph.Node} n1
	     * @param {module:echarts/data/Graph.Node} n2
	     * @param {number} [dataIndex=-1]
	     */
	    function Edge(n1, n2, dataIndex) {

	        /**
	         * 节点1，如果是有向图则为源节点
	         * @type {module:echarts/data/Graph.Node}
	         */
	        this.node1 = n1;

	        /**
	         * 节点2，如果是有向图则为目标节点
	         * @type {module:echarts/data/Graph.Node}
	         */
	        this.node2 = n2;

	        this.dataIndex = dataIndex == null ? -1 : dataIndex;
	    }

	    /**
	     * @param {string} [path]
	     * @return {module:echarts/model/Model}
	     */
	     Edge.prototype.getModel = function (path) {
	        if (this.dataIndex < 0) {
	            return;
	        }
	        var graph = this.hostGraph;
	        var itemModel = graph.edgeData.getItemModel(this.dataIndex);

	        return itemModel.getModel(path);
	    };

	    var createGraphDataProxyMixin = function (hostName, dataName) {
	        return {
	            /**
	             * @param {string=} [dimension='value'] Default 'value'. can be 'a', 'b', 'c', 'd', 'e'.
	             * @return {number}
	             */
	            getValue: function (dimension) {
	                var data = this[hostName][dataName];
	                return data.get(data.getDimension(dimension || 'value'), this.dataIndex);
	            },

	            /**
	             * @param {Object|string} key
	             * @param {*} [value]
	             */
	            setVisual: function (key, value) {
	                this.dataIndex >= 0
	                    && this[hostName][dataName].setItemVisual(this.dataIndex, key, value);
	            },

	            /**
	             * @param {string} key
	             * @return {boolean}
	             */
	            getVisual: function (key, ignoreParent) {
	                return this[hostName][dataName].getItemVisual(this.dataIndex, key, ignoreParent);
	            },

	            /**
	             * @param {Object} layout
	             * @return {boolean} [merge=false]
	             */
	            setLayout: function (layout, merge) {
	                this.dataIndex >= 0
	                    && this[hostName][dataName].setItemLayout(this.dataIndex, layout, merge);
	            },

	            /**
	             * @return {Object}
	             */
	            getLayout: function () {
	                return this[hostName][dataName].getItemLayout(this.dataIndex);
	            },

	            /**
	             * @return {module:zrender/Element}
	             */
	            getGraphicEl: function () {
	                return this[hostName][dataName].getItemGraphicEl(this.dataIndex);
	            },

	            /**
	             * @return {number}
	             */
	            getRawIndex: function () {
	                return this[hostName][dataName].getRawIndex(this.dataIndex);
	            }
	        };
	    };

	    zrUtil.mixin(Node, createGraphDataProxyMixin('hostGraph', 'data'));
	    zrUtil.mixin(Edge, createGraphDataProxyMixin('hostGraph', 'edgeData'));

	    Graph.Node = Node;
	    Graph.Edge = Edge;

	    module.exports = Graph;


/***/ },
/* 209 */
/***/ function(module, exports, __webpack_require__) {

	


	    var SymbolDraw = __webpack_require__(116);
	    var LineDraw = __webpack_require__(210);
	    var RoamController = __webpack_require__(183);
	    var roamHelper = __webpack_require__(185);
	    var cursorHelper = __webpack_require__(186);

	    var graphic = __webpack_require__(18);
	    var adjustEdge = __webpack_require__(213);
	    var zrUtil = __webpack_require__(4);

	    var nodeOpacityPath = ['itemStyle', 'normal', 'opacity'];
	    var lineOpacityPath = ['lineStyle', 'normal', 'opacity'];

	    function getItemOpacity(item, opacityPath) {
	        return item.getVisual('opacity') || item.getModel().get(opacityPath);
	    }

	    __webpack_require__(1).extendChartView({

	        type: 'graph',

	        init: function (ecModel, api) {
	            var symbolDraw = new SymbolDraw();
	            var lineDraw = new LineDraw();
	            var group = this.group;

	            this._controller = new RoamController(api.getZr());
	            this._controllerHost = {target: group};

	            group.add(symbolDraw.group);
	            group.add(lineDraw.group);

	            this._symbolDraw = symbolDraw;
	            this._lineDraw = lineDraw;

	            this._firstRender = true;
	        },

	        render: function (seriesModel, ecModel, api) {
	            var coordSys = seriesModel.coordinateSystem;

	            this._model = seriesModel;
	            this._nodeScaleRatio = seriesModel.get('nodeScaleRatio');

	            var symbolDraw = this._symbolDraw;
	            var lineDraw = this._lineDraw;

	            var group = this.group;

	            if (coordSys.type === 'view') {
	                var groupNewProp = {
	                    position: coordSys.position,
	                    scale: coordSys.scale
	                };
	                if (this._firstRender) {
	                    group.attr(groupNewProp);
	                }
	                else {
	                    graphic.updateProps(group, groupNewProp, seriesModel);
	                }
	            }
	            // Fix edge contact point with node
	            adjustEdge(seriesModel.getGraph(), this._getNodeGlobalScale(seriesModel));

	            var data = seriesModel.getData();
	            symbolDraw.updateData(data);

	            var edgeData = seriesModel.getEdgeData();
	            lineDraw.updateData(edgeData);

	            this._updateNodeAndLinkScale();

	            this._updateController(seriesModel, ecModel, api);

	            clearTimeout(this._layoutTimeout);
	            var forceLayout = seriesModel.forceLayout;
	            var layoutAnimation = seriesModel.get('force.layoutAnimation');
	            if (forceLayout) {
	                this._startForceLayoutIteration(forceLayout, layoutAnimation);
	            }
	            data.eachItemGraphicEl(function (el, idx) {
	                var itemModel = data.getItemModel(idx);
	                // Update draggable
	                el.off('drag').off('dragend');
	                var draggable = data.getItemModel(idx).get('draggable');
	                if (draggable) {
	                    el.on('drag', function () {
	                        if (forceLayout) {
	                            forceLayout.warmUp();
	                            !this._layouting
	                                && this._startForceLayoutIteration(forceLayout, layoutAnimation);
	                            forceLayout.setFixed(idx);
	                            // Write position back to layout
	                            data.setItemLayout(idx, el.position);
	                        }
	                    }, this).on('dragend', function () {
	                        if (forceLayout) {
	                            forceLayout.setUnfixed(idx);
	                        }
	                    }, this);
	                }
	                el.setDraggable(draggable && forceLayout);

	                el.off('mouseover', el.__focusNodeAdjacency);
	                el.off('mouseout', el.__unfocusNodeAdjacency);

	                if (itemModel.get('focusNodeAdjacency')) {
	                    el.on('mouseover', el.__focusNodeAdjacency = function () {
	                        api.dispatchAction({
	                            type: 'focusNodeAdjacency',
	                            seriesId: seriesModel.id,
	                            dataIndex: el.dataIndex
	                        });
	                    });
	                    el.on('mouseout', el.__unfocusNodeAdjacency = function () {
	                        api.dispatchAction({
	                            type: 'unfocusNodeAdjacency',
	                            seriesId: seriesModel.id
	                        });
	                    });
	                }

	            }, this);

	            var circularRotateLabel = seriesModel.get('layout') === 'circular' && seriesModel.get('circular.rotateLabel');
	            var cx = data.getLayout('cx');
	            var cy = data.getLayout('cy');
	            data.eachItemGraphicEl(function (el, idx) {
	                var symbolPath = el.getSymbolPath();
	                if (circularRotateLabel) {
	                    var pos = data.getItemLayout(idx);
	                    var rad = Math.atan2(pos[1] - cy, pos[0] - cx);
	                    if (rad < 0) {
	                        rad = Math.PI * 2 + rad;
	                    }
	                    var isLeft = pos[0] < cx;
	                    if (isLeft) {
	                        rad = rad - Math.PI;
	                    }
	                    var textPosition = isLeft ? 'left' : 'right';
	                    symbolPath.setStyle({
	                        textRotation: rad,
	                        textPosition: textPosition
	                    });
	                    symbolPath.hoverStyle && (symbolPath.hoverStyle.textPosition = textPosition);
	                }
	                else {
	                    symbolPath.setStyle({
	                        textRotation: 0
	                    });
	                }
	            });

	            this._firstRender = false;
	        },

	        dispose: function () {
	            this._controller && this._controller.dispose();
	            this._controllerHost = {};
	        },

	        focusNodeAdjacency: function (seriesModel, ecModel, api, payload) {
	            var data = this._model.getData();
	            var dataIndex = payload.dataIndex;
	            var el = data.getItemGraphicEl(dataIndex);

	            if (!el) {
	                return;
	            }

	            var graph = data.graph;
	            var dataType = el.dataType;

	            function fadeOutItem(item, opacityPath) {
	                var opacity = getItemOpacity(item, opacityPath);
	                var el = item.getGraphicEl();
	                if (opacity == null) {
	                    opacity = 1;
	                }

	                el.traverse(function (child) {
	                    child.trigger('normal');
	                    if (child.type !== 'group') {
	                        child.setStyle('opacity', opacity * 0.1);
	                    }
	                });
	            }

	            function fadeInItem(item, opacityPath) {
	                var opacity = getItemOpacity(item, opacityPath);
	                var el = item.getGraphicEl();

	                el.traverse(function (child) {
	                    child.trigger('emphasis');
	                    if (child.type !== 'group') {
	                        child.setStyle('opacity', opacity);
	                    }
	                });
	            }
	            if (dataIndex !== null && dataType !== 'edge') {
	                graph.eachNode(function (node) {
	                    fadeOutItem(node, nodeOpacityPath);
	                });
	                graph.eachEdge(function (edge) {
	                    fadeOutItem(edge, lineOpacityPath);
	                });

	                var node = graph.getNodeByIndex(dataIndex);
	                fadeInItem(node, nodeOpacityPath);
	                zrUtil.each(node.edges, function (edge) {
	                    if (edge.dataIndex < 0) {
	                        return;
	                    }
	                    fadeInItem(edge, lineOpacityPath);
	                    fadeInItem(edge.node1, nodeOpacityPath);
	                    fadeInItem(edge.node2, nodeOpacityPath);
	                });
	            }
	        },

	        unfocusNodeAdjacency: function (seriesModel, ecModel, api, payload) {
	            var graph = this._model.getData().graph;
	            graph.eachNode(function (node) {
	                var opacity = getItemOpacity(node, nodeOpacityPath);
	                node.getGraphicEl().traverse(function (child) {
	                    child.trigger('normal');
	                    if (child.type !== 'group') {
	                        child.setStyle('opacity', opacity);
	                    }
	                });
	            });
	            graph.eachEdge(function (edge) {
	                var opacity = getItemOpacity(edge, lineOpacityPath);
	                edge.getGraphicEl().traverse(function (child) {
	                    child.trigger('normal');
	                    if (child.type !== 'group') {
	                        child.setStyle('opacity', opacity);
	                    }
	                });
	            });
	        },

	        _startForceLayoutIteration: function (forceLayout, layoutAnimation) {
	            var self = this;
	            (function step() {
	                forceLayout.step(function (stopped) {
	                    self.updateLayout(self._model);
	                    (self._layouting = !stopped) && (
	                        layoutAnimation
	                            ? (self._layoutTimeout = setTimeout(step, 16))
	                            : step()
	                    );
	                });
	            })();
	        },

	        _updateController: function (seriesModel, ecModel, api) {
	            var controller = this._controller;
	            var controllerHost = this._controllerHost;
	            var group = this.group;

	            controller.setPointerChecker(function (e, x, y) {
	                var rect = group.getBoundingRect();
	                rect.applyTransform(group.transform);
	                return rect.contain(x, y)
	                    && !cursorHelper.onIrrelevantElement(e, api, seriesModel);
	            });

	            if (seriesModel.coordinateSystem.type !== 'view') {
	                controller.disable();
	                return;
	            }
	            controller.enable(seriesModel.get('roam'));
	            controllerHost.zoomLimit = seriesModel.get('scaleLimit');
	            controllerHost.zoom = seriesModel.coordinateSystem.getZoom();

	            controller
	                .off('pan')
	                .off('zoom')
	                .on('pan', function (dx, dy) {
	                    roamHelper.updateViewOnPan(controllerHost, dx, dy);
	                    api.dispatchAction({
	                        seriesId: seriesModel.id,
	                        type: 'graphRoam',
	                        dx: dx,
	                        dy: dy
	                    });
	                })
	                .on('zoom', function (zoom, mouseX, mouseY) {
	                    roamHelper.updateViewOnZoom(controllerHost, zoom, mouseX, mouseY);
	                    api.dispatchAction({
	                        seriesId: seriesModel.id,
	                        type: 'graphRoam',
	                        zoom:  zoom,
	                        originX: mouseX,
	                        originY: mouseY
	                    });
	                    this._updateNodeAndLinkScale();
	                    adjustEdge(seriesModel.getGraph(), this._getNodeGlobalScale(seriesModel));
	                    this._lineDraw.updateLayout();
	                }, this);
	        },

	        _updateNodeAndLinkScale: function () {
	            var seriesModel = this._model;
	            var data = seriesModel.getData();

	            var nodeScale = this._getNodeGlobalScale(seriesModel);
	            var invScale = [nodeScale, nodeScale];

	            data.eachItemGraphicEl(function (el, idx) {
	                el.attr('scale', invScale);
	            });
	        },

	        _getNodeGlobalScale: function (seriesModel) {
	            var coordSys = seriesModel.coordinateSystem;
	            if (coordSys.type !== 'view') {
	                return 1;
	            }

	            var nodeScaleRatio = this._nodeScaleRatio;

	            var groupScale = coordSys.scale;
	            var groupZoom = (groupScale && groupScale[0]) || 1;
	            // Scale node when zoom changes
	            var roamZoom = coordSys.getZoom();
	            var nodeScale = (roamZoom - 1) * nodeScaleRatio + 1;

	            return nodeScale / groupZoom;
	        },

	        updateLayout: function (seriesModel) {
	            adjustEdge(seriesModel.getGraph(), this._getNodeGlobalScale(seriesModel));

	            this._symbolDraw.updateLayout();
	            this._lineDraw.updateLayout();
	        },

	        remove: function (ecModel, api) {
	            this._symbolDraw && this._symbolDraw.remove();
	            this._lineDraw && this._lineDraw.remove();
	        }
	    });


/***/ },
/* 210 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @module echarts/chart/helper/LineDraw
	 */


	    var graphic = __webpack_require__(18);
	    var LineGroup = __webpack_require__(211);


	    function isPointNaN(pt) {
	        return isNaN(pt[0]) || isNaN(pt[1]);
	    }
	    function lineNeedsDraw(pts) {
	        return !isPointNaN(pts[0]) && !isPointNaN(pts[1]);
	    }
	    /**
	     * @alias module:echarts/component/marker/LineDraw
	     * @constructor
	     */
	    function LineDraw(ctor) {
	        this._ctor = ctor || LineGroup;
	        this.group = new graphic.Group();
	    }

	    var lineDrawProto = LineDraw.prototype;

	    /**
	     * @param {module:echarts/data/List} lineData
	     */
	    lineDrawProto.updateData = function (lineData) {

	        var oldLineData = this._lineData;
	        var group = this.group;
	        var LineCtor = this._ctor;

	        var hostModel = lineData.hostModel;

	        var seriesScope = {
	            lineStyle: hostModel.getModel('lineStyle.normal').getLineStyle(),
	            hoverLineStyle: hostModel.getModel('lineStyle.emphasis').getLineStyle(),
	            labelModel: hostModel.getModel('label.normal'),
	            hoverLabelModel: hostModel.getModel('label.emphasis')
	        };

	        lineData.diff(oldLineData)
	            .add(function (idx) {
	                if (!lineNeedsDraw(lineData.getItemLayout(idx))) {
	                    return;
	                }
	                var lineGroup = new LineCtor(lineData, idx, seriesScope);

	                lineData.setItemGraphicEl(idx, lineGroup);

	                group.add(lineGroup);
	            })
	            .update(function (newIdx, oldIdx) {
	                var lineGroup = oldLineData.getItemGraphicEl(oldIdx);
	                if (!lineNeedsDraw(lineData.getItemLayout(newIdx))) {
	                    group.remove(lineGroup);
	                    return;
	                }

	                if (!lineGroup) {
	                    lineGroup = new LineCtor(lineData, newIdx, seriesScope);
	                }
	                else {
	                    lineGroup.updateData(lineData, newIdx, seriesScope);
	                }

	                lineData.setItemGraphicEl(newIdx, lineGroup);

	                group.add(lineGroup);
	            })
	            .remove(function (idx) {
	                group.remove(oldLineData.getItemGraphicEl(idx));
	            })
	            .execute();

	        this._lineData = lineData;
	    };

	    lineDrawProto.updateLayout = function () {
	        var lineData = this._lineData;
	        lineData.eachItemGraphicEl(function (el, idx) {
	            el.updateLayout(lineData, idx);
	        }, this);
	    };

	    lineDrawProto.remove = function () {
	        this.group.removeAll();
	    };

	    module.exports = LineDraw;


/***/ },
/* 211 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @module echarts/chart/helper/Line
	 */


	    var symbolUtil = __webpack_require__(111);
	    var vector = __webpack_require__(10);
	    // var matrix = require('zrender/lib/core/matrix');
	    var LinePath = __webpack_require__(212);
	    var graphic = __webpack_require__(18);
	    var zrUtil = __webpack_require__(4);
	    var numberUtil = __webpack_require__(7);

	    var SYMBOL_CATEGORIES = ['fromSymbol', 'toSymbol'];
	    function makeSymbolTypeKey(symbolCategory) {
	        return '_' + symbolCategory + 'Type';
	    }
	    /**
	     * @inner
	     */
	    function createSymbol(name, lineData, idx) {
	        var color = lineData.getItemVisual(idx, 'color');
	        var symbolType = lineData.getItemVisual(idx, name);
	        var symbolSize = lineData.getItemVisual(idx, name + 'Size');

	        if (!symbolType || symbolType === 'none') {
	            return;
	        }

	        if (!zrUtil.isArray(symbolSize)) {
	            symbolSize = [symbolSize, symbolSize];
	        }
	        var symbolPath = symbolUtil.createSymbol(
	            symbolType, -symbolSize[0] / 2, -symbolSize[1] / 2,
	            symbolSize[0], symbolSize[1], color
	        );

	        symbolPath.name = name;

	        return symbolPath;
	    }

	    function createLine(points) {
	        var line = new LinePath({
	            name: 'line'
	        });
	        setLinePoints(line.shape, points);
	        return line;
	    }

	    function setLinePoints(targetShape, points) {
	        var p1 = points[0];
	        var p2 = points[1];
	        var cp1 = points[2];
	        targetShape.x1 = p1[0];
	        targetShape.y1 = p1[1];
	        targetShape.x2 = p2[0];
	        targetShape.y2 = p2[1];
	        targetShape.percent = 1;

	        if (cp1) {
	            targetShape.cpx1 = cp1[0];
	            targetShape.cpy1 = cp1[1];
	        }
	        else {
	            targetShape.cpx1 = NaN;
	            targetShape.cpy1 = NaN;
	        }
	    }

	    function updateSymbolAndLabelBeforeLineUpdate () {
	        var lineGroup = this;
	        var symbolFrom = lineGroup.childOfName('fromSymbol');
	        var symbolTo = lineGroup.childOfName('toSymbol');
	        var label = lineGroup.childOfName('label');
	        // Quick reject
	        if (!symbolFrom && !symbolTo && label.ignore) {
	            return;
	        }

	        var invScale = 1;
	        var parentNode = this.parent;
	        while (parentNode) {
	            if (parentNode.scale) {
	                invScale /= parentNode.scale[0];
	            }
	            parentNode = parentNode.parent;
	        }

	        var line = lineGroup.childOfName('line');
	        // If line not changed
	        // FIXME Parent scale changed
	        if (!this.__dirty && !line.__dirty) {
	            return;
	        }

	        var percent = line.shape.percent;
	        var fromPos = line.pointAt(0);
	        var toPos = line.pointAt(percent);

	        var d = vector.sub([], toPos, fromPos);
	        vector.normalize(d, d);

	        if (symbolFrom) {
	            symbolFrom.attr('position', fromPos);
	            var tangent = line.tangentAt(0);
	            symbolFrom.attr('rotation', Math.PI / 2 - Math.atan2(
	                tangent[1], tangent[0]
	            ));
	            symbolFrom.attr('scale', [invScale * percent, invScale * percent]);
	        }
	        if (symbolTo) {
	            symbolTo.attr('position', toPos);
	            var tangent = line.tangentAt(1);
	            symbolTo.attr('rotation', -Math.PI / 2 - Math.atan2(
	                tangent[1], tangent[0]
	            ));
	            symbolTo.attr('scale', [invScale * percent, invScale * percent]);
	        }

	        if (!label.ignore) {
	            label.attr('position', toPos);

	            var textPosition;
	            var textAlign;
	            var textVerticalAlign;

	            var distance = 5 * invScale;
	            // End
	            if (label.__position === 'end') {
	                textPosition = [d[0] * distance + toPos[0], d[1] * distance + toPos[1]];
	                textAlign = d[0] > 0.8 ? 'left' : (d[0] < -0.8 ? 'right' : 'center');
	                textVerticalAlign = d[1] > 0.8 ? 'top' : (d[1] < -0.8 ? 'bottom' : 'middle');
	            }
	            // Middle
	            else if (label.__position === 'middle') {
	                var halfPercent = percent / 2;
	                var tangent = line.tangentAt(halfPercent);
	                var n = [tangent[1], -tangent[0]];
	                var cp = line.pointAt(halfPercent);
	                if (n[1] > 0) {
	                    n[0] = -n[0];
	                    n[1] = -n[1];
	                }
	                textPosition = [cp[0] + n[0] * distance, cp[1] + n[1] * distance];
	                textAlign = 'center';
	                textVerticalAlign = 'bottom';
	                var rotation = -Math.atan2(tangent[1], tangent[0]);
	                if (toPos[0] < fromPos[0]) {
	                    rotation = Math.PI + rotation;
	                }
	                label.attr('rotation', rotation);
	            }
	            // Start
	            else {
	                textPosition = [-d[0] * distance + fromPos[0], -d[1] * distance + fromPos[1]];
	                textAlign = d[0] > 0.8 ? 'right' : (d[0] < -0.8 ? 'left' : 'center');
	                textVerticalAlign = d[1] > 0.8 ? 'bottom' : (d[1] < -0.8 ? 'top' : 'middle');
	            }
	            label.attr({
	                style: {
	                    // Use the user specified text align and baseline first
	                    textVerticalAlign: label.__verticalAlign || textVerticalAlign,
	                    textAlign: label.__textAlign || textAlign
	                },
	                position: textPosition,
	                scale: [invScale, invScale]
	            });
	        }
	    }

	    /**
	     * @constructor
	     * @extends {module:zrender/graphic/Group}
	     * @alias {module:echarts/chart/helper/Line}
	     */
	    function Line(lineData, idx, seriesScope) {
	        graphic.Group.call(this);

	        this._createLine(lineData, idx, seriesScope);
	    }

	    var lineProto = Line.prototype;

	    // Update symbol position and rotation
	    lineProto.beforeUpdate = updateSymbolAndLabelBeforeLineUpdate;

	    lineProto._createLine = function (lineData, idx, seriesScope) {
	        var seriesModel = lineData.hostModel;
	        var linePoints = lineData.getItemLayout(idx);

	        var line = createLine(linePoints);
	        line.shape.percent = 0;
	        graphic.initProps(line, {
	            shape: {
	                percent: 1
	            }
	        }, seriesModel, idx);

	        this.add(line);

	        var label = new graphic.Text({
	            name: 'label'
	        });
	        this.add(label);

	        zrUtil.each(SYMBOL_CATEGORIES, function (symbolCategory) {
	            var symbol = createSymbol(symbolCategory, lineData, idx);
	            // symbols must added after line to make sure
	            // it will be updated after line#update.
	            // Or symbol position and rotation update in line#beforeUpdate will be one frame slow
	            this.add(symbol);
	            this[makeSymbolTypeKey(symbolCategory)] = lineData.getItemVisual(idx, symbolCategory);
	        }, this);

	        this._updateCommonStl(lineData, idx, seriesScope);
	    };

	    lineProto.updateData = function (lineData, idx, seriesScope) {
	        var seriesModel = lineData.hostModel;

	        var line = this.childOfName('line');
	        var linePoints = lineData.getItemLayout(idx);
	        var target = {
	            shape: {}
	        };
	        setLinePoints(target.shape, linePoints);
	        graphic.updateProps(line, target, seriesModel, idx);

	        zrUtil.each(SYMBOL_CATEGORIES, function (symbolCategory) {
	            var symbolType = lineData.getItemVisual(idx, symbolCategory);
	            var key = makeSymbolTypeKey(symbolCategory);
	            // Symbol changed
	            if (this[key] !== symbolType) {
	                this.remove(this.childOfName(symbolCategory));
	                var symbol = createSymbol(symbolCategory, lineData, idx);
	                this.add(symbol);
	            }
	            this[key] = symbolType;
	        }, this);

	        this._updateCommonStl(lineData, idx, seriesScope);
	    };

	    lineProto._updateCommonStl = function (lineData, idx, seriesScope) {
	        var seriesModel = lineData.hostModel;

	        var line = this.childOfName('line');

	        var lineStyle = seriesScope && seriesScope.lineStyle;
	        var hoverLineStyle = seriesScope && seriesScope.hoverLineStyle;
	        var labelModel = seriesScope && seriesScope.labelModel;
	        var hoverLabelModel = seriesScope && seriesScope.hoverLabelModel;

	        // Optimization for large dataset
	        if (!seriesScope || lineData.hasItemOption) {
	            var itemModel = lineData.getItemModel(idx);

	            lineStyle = itemModel.getModel('lineStyle.normal').getLineStyle();
	            hoverLineStyle = itemModel.getModel('lineStyle.emphasis').getLineStyle();

	            labelModel = itemModel.getModel('label.normal');
	            hoverLabelModel = itemModel.getModel('label.emphasis');
	        }

	        var visualColor = lineData.getItemVisual(idx, 'color');
	        var visualOpacity = zrUtil.retrieve(
	            lineData.getItemVisual(idx, 'opacity'),
	            lineStyle.opacity,
	            1
	        );

	        line.useStyle(zrUtil.defaults(
	            {
	                strokeNoScale: true,
	                fill: 'none',
	                stroke: visualColor,
	                opacity: visualOpacity
	            },
	            lineStyle
	        ));
	        line.hoverStyle = hoverLineStyle;

	        // Update symbol
	        zrUtil.each(SYMBOL_CATEGORIES, function (symbolCategory) {
	            var symbol = this.childOfName(symbolCategory);
	            if (symbol) {
	                symbol.setColor(visualColor);
	                symbol.setStyle({
	                    opacity: visualOpacity
	                });
	            }
	        }, this);

	        var showLabel = labelModel.getShallow('show');
	        var hoverShowLabel = hoverLabelModel.getShallow('show');

	        var label = this.childOfName('label');
	        var defaultLabelColor;
	        var defaultText;

	        if (showLabel || hoverShowLabel) {
	            var rawVal = seriesModel.getRawValue(idx);
	            defaultText = rawVal == null
	                ? defaultText = lineData.getName(idx)
	                : isFinite(rawVal)
	                ? numberUtil.round(rawVal)
	                : rawVal;
	            defaultLabelColor = visualColor || '#000';
	        }

	        // label.afterUpdate = lineAfterUpdate;
	        if (showLabel) {
	            var textStyleModel = labelModel.getModel('textStyle');
	            label.setStyle({
	                text: zrUtil.retrieve(
	                    seriesModel.getFormattedLabel(idx, 'normal', lineData.dataType),
	                    defaultText
	                ),
	                textFont: textStyleModel.getFont(),
	                fill: textStyleModel.getTextColor() || defaultLabelColor
	            });

	            label.__textAlign = textStyleModel.get('align');
	            label.__verticalAlign = textStyleModel.get('baseline');
	            label.__position = labelModel.get('position');
	        }
	        else {
	            label.setStyle('text', '');
	        }
	        if (hoverShowLabel) {
	            var textStyleHoverModel = hoverLabelModel.getModel('textStyle');

	            label.hoverStyle = {
	                text: zrUtil.retrieve(
	                    seriesModel.getFormattedLabel(idx, 'emphasis', lineData.dataType),
	                    defaultText
	                ),
	                textFont: textStyleHoverModel.getFont(),
	                fill: textStyleHoverModel.getTextColor() || defaultLabelColor
	            };
	        }
	        else {
	            label.hoverStyle = {
	                text: ''
	            };
	        }

	        label.ignore = !showLabel && !hoverShowLabel;

	        graphic.setHoverStyle(this);
	    };

	    lineProto.updateLayout = function (lineData, idx) {
	        this.setLinePoints(lineData.getItemLayout(idx));
	    };

	    lineProto.setLinePoints = function (points) {
	        var linePath = this.childOfName('line');
	        setLinePoints(linePath.shape, points);
	        linePath.dirty();
	    };

	    zrUtil.inherits(Line, graphic.Group);

	    module.exports = Line;


/***/ },
/* 212 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * Line path for bezier and straight line draw
	 */

	    var graphic = __webpack_require__(18);
	    var vec2 = __webpack_require__(10);

	    var straightLineProto = graphic.Line.prototype;
	    var bezierCurveProto = graphic.BezierCurve.prototype;

	    function isLine(shape) {
	        return isNaN(+shape.cpx1) || isNaN(+shape.cpy1);
	    }

	    module.exports = graphic.extendShape({

	        type: 'ec-line',

	        style: {
	            stroke: '#000',
	            fill: null
	        },

	        shape: {
	            x1: 0,
	            y1: 0,
	            x2: 0,
	            y2: 0,
	            percent: 1,
	            cpx1: null,
	            cpy1: null
	        },

	        buildPath: function (ctx, shape) {
	            (isLine(shape) ? straightLineProto : bezierCurveProto).buildPath(ctx, shape);
	        },

	        pointAt: function (t) {
	            return isLine(this.shape)
	                ? straightLineProto.pointAt.call(this, t)
	                : bezierCurveProto.pointAt.call(this, t);
	        },

	        tangentAt: function (t) {
	            var shape = this.shape;
	            var p = isLine(shape)
	                ? [shape.x2 - shape.x1, shape.y2 - shape.y1]
	                : bezierCurveProto.tangentAt.call(this, t);
	            return vec2.normalize(p, p);
	        }
	    });


/***/ },
/* 213 */
/***/ function(module, exports, __webpack_require__) {

	

	    var curveTool = __webpack_require__(37);
	    var vec2 = __webpack_require__(10);

	    var v1 = [];
	    var v2 = [];
	    var v3 = [];
	    var quadraticAt = curveTool.quadraticAt;
	    var v2DistSquare = vec2.distSquare;
	    var mathAbs = Math.abs;
	    function intersectCurveCircle(curvePoints, center, radius) {
	        var p0 = curvePoints[0];
	        var p1 = curvePoints[1];
	        var p2 = curvePoints[2];

	        var d = Infinity;
	        var t;
	        var radiusSquare = radius * radius;
	        var interval = 0.1;

	        for (var _t = 0.1; _t <= 0.9; _t += 0.1) {
	            v1[0] = quadraticAt(p0[0], p1[0], p2[0], _t);
	            v1[1] = quadraticAt(p0[1], p1[1], p2[1], _t);
	            var diff = mathAbs(v2DistSquare(v1, center) - radiusSquare);
	            if (diff < d) {
	                d = diff;
	                t = _t;
	            }
	        }

	        // Assume the segment is monotone，Find root through Bisection method
	        // At most 32 iteration
	        for (var i = 0; i < 32; i++) {
	            // var prev = t - interval;
	            var next = t + interval;
	            // v1[0] = quadraticAt(p0[0], p1[0], p2[0], prev);
	            // v1[1] = quadraticAt(p0[1], p1[1], p2[1], prev);
	            v2[0] = quadraticAt(p0[0], p1[0], p2[0], t);
	            v2[1] = quadraticAt(p0[1], p1[1], p2[1], t);
	            v3[0] = quadraticAt(p0[0], p1[0], p2[0], next);
	            v3[1] = quadraticAt(p0[1], p1[1], p2[1], next);

	            var diff = v2DistSquare(v2, center) - radiusSquare;
	            if (mathAbs(diff) < 1e-2) {
	                break;
	            }

	            // var prevDiff = v2DistSquare(v1, center) - radiusSquare;
	            var nextDiff = v2DistSquare(v3, center) - radiusSquare;

	            interval /= 2;
	            if (diff < 0) {
	                if (nextDiff >= 0) {
	                    t = t + interval;
	                }
	                else {
	                    t = t - interval;
	                }
	            }
	            else {
	                if (nextDiff >= 0) {
	                    t = t - interval;
	                }
	                else {
	                    t = t + interval;
	                }
	            }
	        }

	        return t;
	    }
	    // Adjust edge to avoid
	    module.exports = function (graph, scale) {
	        var tmp0 = [];
	        var quadraticSubdivide = curveTool.quadraticSubdivide;
	        var pts = [[], [], []];
	        var pts2 = [[], []];
	        var v = [];
	        scale /= 2;

	        function getSymbolSize(node) {
	            var symbolSize = node.getVisual('symbolSize');
	            if (symbolSize instanceof Array) {
	                symbolSize = (symbolSize[0] + symbolSize[1]) / 2;
	            }
	            return symbolSize;
	        }
	        graph.eachEdge(function (edge, idx) {
	            var linePoints = edge.getLayout();
	            var fromSymbol = edge.getVisual('fromSymbol');
	            var toSymbol = edge.getVisual('toSymbol');

	            if (!linePoints.__original) {
	                linePoints.__original = [
	                    vec2.clone(linePoints[0]),
	                    vec2.clone(linePoints[1])
	                ];
	                if (linePoints[2]) {
	                    linePoints.__original.push(vec2.clone(linePoints[2]));
	                }
	            }
	            var originalPoints = linePoints.__original;
	            // Quadratic curve
	            if (linePoints[2] != null) {
	                vec2.copy(pts[0], originalPoints[0]);
	                vec2.copy(pts[1], originalPoints[2]);
	                vec2.copy(pts[2], originalPoints[1]);
	                if (fromSymbol && fromSymbol != 'none') {
	                    var symbolSize = getSymbolSize(edge.node1);

	                    var t = intersectCurveCircle(pts, originalPoints[0], symbolSize * scale);
	                    // Subdivide and get the second
	                    quadraticSubdivide(pts[0][0], pts[1][0], pts[2][0], t, tmp0);
	                    pts[0][0] = tmp0[3];
	                    pts[1][0] = tmp0[4];
	                    quadraticSubdivide(pts[0][1], pts[1][1], pts[2][1], t, tmp0);
	                    pts[0][1] = tmp0[3];
	                    pts[1][1] = tmp0[4];
	                }
	                if (toSymbol && toSymbol != 'none') {
	                    var symbolSize = getSymbolSize(edge.node2);

	                    var t = intersectCurveCircle(pts, originalPoints[1], symbolSize * scale);
	                    // Subdivide and get the first
	                    quadraticSubdivide(pts[0][0], pts[1][0], pts[2][0], t, tmp0);
	                    pts[1][0] = tmp0[1];
	                    pts[2][0] = tmp0[2];
	                    quadraticSubdivide(pts[0][1], pts[1][1], pts[2][1], t, tmp0);
	                    pts[1][1] = tmp0[1];
	                    pts[2][1] = tmp0[2];
	                }
	                // Copy back to layout
	                vec2.copy(linePoints[0], pts[0]);
	                vec2.copy(linePoints[1], pts[2]);
	                vec2.copy(linePoints[2], pts[1]);
	            }
	            // Line
	            else {
	                vec2.copy(pts2[0], originalPoints[0]);
	                vec2.copy(pts2[1], originalPoints[1]);

	                vec2.sub(v, pts2[1], pts2[0]);
	                vec2.normalize(v, v);
	                if (fromSymbol && fromSymbol != 'none') {

	                    var symbolSize = getSymbolSize(edge.node1);

	                    vec2.scaleAndAdd(pts2[0], pts2[0], v, symbolSize * scale);
	                }
	                if (toSymbol && toSymbol != 'none') {
	                    var symbolSize = getSymbolSize(edge.node2);

	                    vec2.scaleAndAdd(pts2[1], pts2[1], v, -symbolSize * scale);
	                }
	                vec2.copy(linePoints[0], pts2[0]);
	                vec2.copy(linePoints[1], pts2[1]);
	            }
	        });
	    };


/***/ },
/* 214 */
/***/ function(module, exports, __webpack_require__) {

	

	    var echarts = __webpack_require__(1);
	    var roamHelper = __webpack_require__(188);

	    var actionInfo = {
	        type: 'graphRoam',
	        event: 'graphRoam',
	        update: 'none'
	    };

	    /**
	     * @payload
	     * @property {string} name Series name
	     * @property {number} [dx]
	     * @property {number} [dy]
	     * @property {number} [zoom]
	     * @property {number} [originX]
	     * @property {number} [originY]
	     */
	    echarts.registerAction(actionInfo, function (payload, ecModel) {
	        ecModel.eachComponent({mainType: 'series', query: payload}, function (seriesModel) {
	            var coordSys = seriesModel.coordinateSystem;

	            var res = roamHelper.updateCenterAndZoom(coordSys, payload);

	            seriesModel.setCenter
	                && seriesModel.setCenter(res.center);

	            seriesModel.setZoom
	                && seriesModel.setZoom(res.zoom);
	        });
	    });


	    /**
	     * @payload
	     * @property {number} [seriesIndex]
	     * @property {string} [seriesId]
	     * @property {string} [seriesName]
	     * @property {number} [dataIndex]
	     */
	    echarts.registerAction({
	        type: 'focusNodeAdjacency',
	        event: 'focusNodeAdjacency',
	        update: 'series.graph:focusNodeAdjacency'
	    }, function () {});

	    /**
	     * @payload
	     * @property {number} [seriesIndex]
	     * @property {string} [seriesId]
	     * @property {string} [seriesName]
	     */
	    echarts.registerAction({
	        type: 'unfocusNodeAdjacency',
	        event: 'unfocusNodeAdjacency',
	        update: 'series.graph:unfocusNodeAdjacency'
	    }, function () {});



/***/ },
/* 215 */
/***/ function(module, exports) {

	

	    module.exports = function (ecModel) {
	        var legendModels = ecModel.findComponents({
	            mainType: 'legend'
	        });
	        if (!legendModels || !legendModels.length) {
	            return;
	        }
	        ecModel.eachSeriesByType('graph', function (graphSeries) {
	            var categoriesData = graphSeries.getCategoriesData();
	            var graph = graphSeries.getGraph();
	            var data = graph.data;

	            var categoryNames = categoriesData.mapArray(categoriesData.getName);

	            data.filterSelf(function (idx) {
	                var model = data.getItemModel(idx);
	                var category = model.getShallow('category');
	                if (category != null) {
	                    if (typeof category === 'number') {
	                        category = categoryNames[category];
	                    }
	                    // If in any legend component the status is not selected.
	                    for (var i = 0; i < legendModels.length; i++) {
	                        if (!legendModels[i].isSelected(category)) {
	                            return false;
	                        }
	                    }
	                }
	                return true;
	            });
	        }, this);
	    };


/***/ },
/* 216 */
/***/ function(module, exports) {

	

	    module.exports = function (ecModel) {

	        var paletteScope = {};
	        ecModel.eachSeriesByType('graph', function (seriesModel) {
	            var categoriesData = seriesModel.getCategoriesData();
	            var data = seriesModel.getData();

	            var categoryNameIdxMap = {};

	            categoriesData.each(function (idx) {
	                var name = categoriesData.getName(idx);
	                // Add prefix to avoid conflict with Object.prototype.
	                categoryNameIdxMap['ec-' + name] = idx;

	                var itemModel = categoriesData.getItemModel(idx);
	                var color = itemModel.get('itemStyle.normal.color')
	                    || seriesModel.getColorFromPalette(name, paletteScope);
	                categoriesData.setItemVisual(idx, 'color', color);
	            });

	            // Assign category color to visual
	            if (categoriesData.count()) {
	                data.each(function (idx) {
	                    var model = data.getItemModel(idx);
	                    var category = model.getShallow('category');
	                    if (category != null) {
	                        if (typeof category === 'string') {
	                            category = categoryNameIdxMap['ec-' + category];
	                        }
	                        if (!data.getItemVisual(idx, 'color', true)) {
	                            data.setItemVisual(
	                                idx, 'color',
	                                categoriesData.getItemVisual(category, 'color')
	                            );
	                        }
	                    }
	                });
	            }
	        });
	    };


/***/ },
/* 217 */
/***/ function(module, exports) {

	

	    function normalize(a) {
	        if (!(a instanceof Array)) {
	            a = [a, a];
	        }
	        return a;
	    }
	    module.exports = function (ecModel) {
	        ecModel.eachSeriesByType('graph', function (seriesModel) {
	            var graph = seriesModel.getGraph();
	            var edgeData = seriesModel.getEdgeData();
	            var symbolType = normalize(seriesModel.get('edgeSymbol'));
	            var symbolSize = normalize(seriesModel.get('edgeSymbolSize'));

	            var colorQuery = 'lineStyle.normal.color'.split('.');
	            var opacityQuery = 'lineStyle.normal.opacity'.split('.');

	            edgeData.setVisual('fromSymbol', symbolType && symbolType[0]);
	            edgeData.setVisual('toSymbol', symbolType && symbolType[1]);
	            edgeData.setVisual('fromSymbolSize', symbolSize && symbolSize[0]);
	            edgeData.setVisual('toSymbolSize', symbolSize && symbolSize[1]);
	            edgeData.setVisual('color', seriesModel.get(colorQuery));
	            edgeData.setVisual('opacity', seriesModel.get(opacityQuery));

	            edgeData.each(function (idx) {
	                var itemModel = edgeData.getItemModel(idx);
	                var edge = graph.getEdgeByIndex(idx);
	                var symbolType = normalize(itemModel.getShallow('symbol', true));
	                var symbolSize = normalize(itemModel.getShallow('symbolSize', true));
	                // Edge visual must after node visual
	                var color = itemModel.get(colorQuery);
	                var opacity = itemModel.get(opacityQuery);
	                switch (color) {
	                    case 'source':
	                        color = edge.node1.getVisual('color');
	                        break;
	                    case 'target':
	                        color = edge.node2.getVisual('color');
	                        break;
	                }

	                symbolType[0] && edge.setVisual('fromSymbol', symbolType[0]);
	                symbolType[1] && edge.setVisual('toSymbol', symbolType[1]);
	                symbolSize[0] && edge.setVisual('fromSymbolSize', symbolSize[0]);
	                symbolSize[1] && edge.setVisual('toSymbolSize', symbolSize[1]);

	                edge.setVisual('color', color);
	                edge.setVisual('opacity', opacity);
	            });
	        });
	    };


/***/ },
/* 218 */
/***/ function(module, exports, __webpack_require__) {

	

	    var simpleLayoutHelper = __webpack_require__(219);
	    var simpleLayoutEdge = __webpack_require__(220);

	    module.exports = function (ecModel, api) {
	        ecModel.eachSeriesByType('graph', function (seriesModel) {
	            var layout = seriesModel.get('layout');
	            var coordSys = seriesModel.coordinateSystem;
	            if (coordSys && coordSys.type !== 'view') {
	                var data = seriesModel.getData();
	                var dimensions = coordSys.dimensions;

	                data.each(dimensions, function () {
	                    var hasValue;
	                    var args = arguments;
	                    var value = [];
	                    for (var i = 0; i < dimensions.length; i++) {
	                        if (!isNaN(args[i])) {
	                            hasValue = true;
	                        }
	                        value.push(args[i]);
	                    }
	                    var idx = args[args.length - 1];

	                    if (hasValue) {
	                        data.setItemLayout(idx, coordSys.dataToPoint(value));
	                    }
	                    else {
	                        // Also {Array.<number>}, not undefined to avoid if...else... statement
	                        data.setItemLayout(idx, [NaN, NaN]);
	                    }
	                });

	                simpleLayoutEdge(data.graph);
	            }
	            else if (!layout || layout === 'none') {
	                simpleLayoutHelper(seriesModel);
	            }
	        });
	    };



/***/ },
/* 219 */
/***/ function(module, exports, __webpack_require__) {

	

	    var simpleLayoutEdge = __webpack_require__(220);

	    module.exports = function (seriesModel) {
	        var coordSys = seriesModel.coordinateSystem;
	        if (coordSys && coordSys.type !== 'view') {
	            return;
	        }
	        var graph = seriesModel.getGraph();

	        graph.eachNode(function (node) {
	            var model = node.getModel();
	            node.setLayout([+model.get('x'), +model.get('y')]);
	        });

	        simpleLayoutEdge(graph);
	    };


/***/ },
/* 220 */
/***/ function(module, exports, __webpack_require__) {

	
	    var vec2 = __webpack_require__(10);
	    module.exports = function (graph) {
	        graph.eachEdge(function (edge) {
	            var curveness = edge.getModel().get('lineStyle.normal.curveness') || 0;
	            var p1 = vec2.clone(edge.node1.getLayout());
	            var p2 = vec2.clone(edge.node2.getLayout());
	            var points = [p1, p2];
	            if (+curveness) {
	                points.push([
	                    (p1[0] + p2[0]) / 2 - (p1[1] - p2[1]) * curveness,
	                    (p1[1] + p2[1]) / 2 - (p2[0] - p1[0]) * curveness
	                ]);
	            }
	            edge.setLayout(points);
	        });
	    };


/***/ },
/* 221 */
/***/ function(module, exports, __webpack_require__) {

	
	    var circularLayoutHelper = __webpack_require__(222);
	    module.exports = function (ecModel) {
	        ecModel.eachSeriesByType('graph', function (seriesModel) {
	            if (seriesModel.get('layout') === 'circular') {
	                circularLayoutHelper(seriesModel);
	            }
	        });
	    };


/***/ },
/* 222 */
/***/ function(module, exports, __webpack_require__) {

	
	    var vec2 = __webpack_require__(10);
	    module.exports = function (seriesModel) {
	        var coordSys = seriesModel.coordinateSystem;
	        if (coordSys && coordSys.type !== 'view') {
	            return;
	        }

	        var rect = coordSys.getBoundingRect();

	        var nodeData = seriesModel.getData();
	        var graph = nodeData.graph;

	        var angle = 0;
	        var sum = nodeData.getSum('value');
	        var unitAngle = Math.PI * 2 / (sum || nodeData.count());

	        var cx = rect.width / 2 + rect.x;
	        var cy = rect.height / 2 + rect.y;

	        var r = Math.min(rect.width, rect.height) / 2;

	        graph.eachNode(function (node) {
	            var value = node.getValue('value');

	            angle += unitAngle * (sum ? value : 1) / 2;

	            node.setLayout([
	                r * Math.cos(angle) + cx,
	                r * Math.sin(angle) + cy
	            ]);

	            angle += unitAngle * (sum ? value : 1) / 2;
	        });

	        nodeData.setLayout({
	            cx: cx,
	            cy: cy
	        });

	        graph.eachEdge(function (edge) {
	            var curveness = edge.getModel().get('lineStyle.normal.curveness') || 0;
	            var p1 = vec2.clone(edge.node1.getLayout());
	            var p2 = vec2.clone(edge.node2.getLayout());
	            var cp1;
	            var x12 = (p1[0] + p2[0]) / 2;
	            var y12 = (p1[1] + p2[1]) / 2;
	            if (+curveness) {
	                curveness *= 3;
	                cp1 = [
	                    cx * curveness + x12 * (1 - curveness),
	                    cy * curveness + y12 * (1 - curveness)
	                ];
	            }
	            edge.setLayout([p1, p2, cp1]);
	        });
	    };


/***/ },
/* 223 */
/***/ function(module, exports, __webpack_require__) {

	

	    var forceHelper = __webpack_require__(224);
	    var numberUtil = __webpack_require__(7);
	    var simpleLayoutHelper = __webpack_require__(219);
	    var circularLayoutHelper = __webpack_require__(222);
	    var vec2 = __webpack_require__(10);
	    var zrUtil = __webpack_require__(4);

	    module.exports = function (ecModel) {
	        ecModel.eachSeriesByType('graph', function (graphSeries) {
	            var coordSys = graphSeries.coordinateSystem;
	            if (coordSys && coordSys.type !== 'view') {
	                return;
	            }
	            if (graphSeries.get('layout') === 'force') {
	                var preservedPoints = graphSeries.preservedPoints || {};
	                var graph = graphSeries.getGraph();
	                var nodeData = graph.data;
	                var edgeData = graph.edgeData;
	                var forceModel = graphSeries.getModel('force');
	                var initLayout = forceModel.get('initLayout');
	                if (graphSeries.preservedPoints) {
	                    nodeData.each(function (idx) {
	                        var id = nodeData.getId(idx);
	                        nodeData.setItemLayout(idx, preservedPoints[id] || [NaN, NaN]);
	                    });
	                }
	                else if (!initLayout || initLayout === 'none') {
	                    simpleLayoutHelper(graphSeries);
	                }
	                else if (initLayout === 'circular') {
	                    circularLayoutHelper(graphSeries);
	                }

	                var nodeDataExtent = nodeData.getDataExtent('value');
	                var edgeDataExtent = edgeData.getDataExtent('value');
	                // var edgeDataExtent = edgeData.getDataExtent('value');
	                var repulsion = forceModel.get('repulsion');
	                var edgeLength = forceModel.get('edgeLength');
	                if (!zrUtil.isArray(repulsion)) {
	                    repulsion = [repulsion, repulsion];
	                }
	                if (!zrUtil.isArray(edgeLength)) {
	                    edgeLength = [edgeLength, edgeLength];
	                }
	                // Larger value has smaller length
	                edgeLength = [edgeLength[1], edgeLength[0]];

	                var nodes = nodeData.mapArray('value', function (value, idx) {
	                    var point = nodeData.getItemLayout(idx);
	                    // var w = numberUtil.linearMap(value, nodeDataExtent, [0, 50]);
	                    var rep = numberUtil.linearMap(value, nodeDataExtent, repulsion);
	                    if (isNaN(rep)) {
	                        rep = (repulsion[0] + repulsion[1]) / 2;
	                    }
	                    return {
	                        w: rep,
	                        rep: rep,
	                        fixed: nodeData.getItemModel(idx).get('fixed'),
	                        p: (!point || isNaN(point[0]) || isNaN(point[1])) ? null : point
	                    };
	                });
	                var edges = edgeData.mapArray('value', function (value, idx) {
	                    var edge = graph.getEdgeByIndex(idx);
	                    var d = numberUtil.linearMap(value, edgeDataExtent, edgeLength);
	                    if (isNaN(d)) {
	                        d = (edgeLength[0] + edgeLength[1]) / 2;
	                    }
	                    return {
	                        n1: nodes[edge.node1.dataIndex],
	                        n2: nodes[edge.node2.dataIndex],
	                        d: d,
	                        curveness: edge.getModel().get('lineStyle.normal.curveness') || 0
	                    };
	                });

	                var coordSys = graphSeries.coordinateSystem;
	                var rect = coordSys.getBoundingRect();
	                var forceInstance = forceHelper(nodes, edges, {
	                    rect: rect,
	                    gravity: forceModel.get('gravity')
	                });
	                var oldStep = forceInstance.step;
	                forceInstance.step = function (cb) {
	                    for (var i = 0, l = nodes.length; i < l; i++) {
	                        if (nodes[i].fixed) {
	                            // Write back to layout instance
	                            vec2.copy(nodes[i].p, graph.getNodeByIndex(i).getLayout());
	                        }
	                    }
	                    oldStep(function (nodes, edges, stopped) {
	                        for (var i = 0, l = nodes.length; i < l; i++) {
	                            if (!nodes[i].fixed) {
	                                graph.getNodeByIndex(i).setLayout(nodes[i].p);
	                            }
	                            preservedPoints[nodeData.getId(i)] = nodes[i].p;
	                        }
	                        for (var i = 0, l = edges.length; i < l; i++) {
	                            var e = edges[i];
	                            var edge = graph.getEdgeByIndex(i);
	                            var p1 = e.n1.p;
	                            var p2 = e.n2.p;
	                            var points = edge.getLayout();
	                            points = points ? points.slice() : [];
	                            points[0] = points[0] || [];
	                            points[1] = points[1] || [];
	                            vec2.copy(points[0], p1);
	                            vec2.copy(points[1], p2);
	                            if (+e.curveness) {
	                                points[2] = [
	                                    (p1[0] + p2[0]) / 2 - (p1[1] - p2[1]) * e.curveness,
	                                    (p1[1] + p2[1]) / 2 - (p2[0] - p1[0]) * e.curveness
	                                ];
	                            }
	                            edge.setLayout(points);
	                        }
	                        // Update layout

	                        cb && cb(stopped);
	                    });
	                };
	                graphSeries.forceLayout = forceInstance;
	                graphSeries.preservedPoints = preservedPoints;

	                // Step to get the layout
	                forceInstance.step();
	            }
	            else {
	                // Remove prev injected forceLayout instance
	                graphSeries.forceLayout = null;
	            }
	        });
	    };


/***/ },
/* 224 */
/***/ function(module, exports, __webpack_require__) {

	

	    var vec2 = __webpack_require__(10);
	    var scaleAndAdd = vec2.scaleAndAdd;

	    // function adjacentNode(n, e) {
	    //     return e.n1 === n ? e.n2 : e.n1;
	    // }

	    module.exports = function (nodes, edges, opts) {
	        var rect = opts.rect;
	        var width = rect.width;
	        var height = rect.height;
	        var center = [rect.x + width / 2, rect.y + height / 2];
	        // var scale = opts.scale || 1;
	        var gravity = opts.gravity == null ? 0.1 : opts.gravity;

	        // for (var i = 0; i < edges.length; i++) {
	        //     var e = edges[i];
	        //     var n1 = e.n1;
	        //     var n2 = e.n2;
	        //     n1.edges = n1.edges || [];
	        //     n2.edges = n2.edges || [];
	        //     n1.edges.push(e);
	        //     n2.edges.push(e);
	        // }
	        // Init position
	        for (var i = 0; i < nodes.length; i++) {
	            var n = nodes[i];
	            if (!n.p) {
	                // Use the position from first adjecent node with defined position
	                // Or use a random position
	                // From d3
	                // if (n.edges) {
	                //     var j = -1;
	                //     while (++j < n.edges.length) {
	                //         var e = n.edges[j];
	                //         var other = adjacentNode(n, e);
	                //         if (other.p) {
	                //             n.p = vec2.clone(other.p);
	                //             break;
	                //         }
	                //     }
	                // }
	                // if (!n.p) {
	                    n.p = vec2.create(
	                        width * (Math.random() - 0.5) + center[0],
	                        height * (Math.random() - 0.5) + center[1]
	                    );
	                // }
	            }
	            n.pp = vec2.clone(n.p);
	            n.edges = null;
	        }

	        // Formula in 'Graph Drawing by Force-directed Placement'
	        // var k = scale * Math.sqrt(width * height / nodes.length);
	        // var k2 = k * k;

	        var friction = 0.6;

	        return {
	            warmUp: function () {
	                friction = 0.5;
	            },

	            setFixed: function (idx) {
	                nodes[idx].fixed = true;
	            },

	            setUnfixed: function (idx) {
	                nodes[idx].fixed = false;
	            },

	            step: function (cb) {
	                var v12 = [];
	                var nLen = nodes.length;
	                for (var i = 0; i < edges.length; i++) {
	                    var e = edges[i];
	                    var n1 = e.n1;
	                    var n2 = e.n2;

	                    vec2.sub(v12, n2.p, n1.p);
	                    var d = vec2.len(v12) - e.d;
	                    var w = n2.w / (n1.w + n2.w);
	                    vec2.normalize(v12, v12);

	                    !n1.fixed && scaleAndAdd(n1.p, n1.p, v12, w * d * friction);
	                    !n2.fixed && scaleAndAdd(n2.p, n2.p, v12, -(1 - w) * d * friction);
	                }
	                // Gravity
	                for (var i = 0; i < nLen; i++) {
	                    var n = nodes[i];
	                    if (!n.fixed) {
	                        vec2.sub(v12, center, n.p);
	                        // var d = vec2.len(v12);
	                        // vec2.scale(v12, v12, 1 / d);
	                        // var gravityFactor = gravity;
	                        vec2.scaleAndAdd(n.p, n.p, v12, gravity * friction);
	                    }
	                }

	                // Repulsive
	                // PENDING
	                for (var i = 0; i < nLen; i++) {
	                    var n1 = nodes[i];
	                    for (var j = i + 1; j < nLen; j++) {
	                        var n2 = nodes[j];
	                        vec2.sub(v12, n2.p, n1.p);
	                        var d = vec2.len(v12);
	                        if (d === 0) {
	                            // Random repulse
	                            vec2.set(v12, Math.random() - 0.5, Math.random() - 0.5);
	                            d = 1;
	                        }
	                        var repFact = (n1.rep + n2.rep) / d / d;
	                        !n1.fixed && scaleAndAdd(n1.pp, n1.pp, v12, repFact);
	                        !n2.fixed && scaleAndAdd(n2.pp, n2.pp, v12, -repFact);
	                    }
	                }
	                var v = [];
	                for (var i = 0; i < nLen; i++) {
	                    var n = nodes[i];
	                    if (!n.fixed) {
	                        vec2.sub(v, n.p, n.pp);
	                        vec2.scaleAndAdd(n.p, n.p, v, friction);
	                        vec2.copy(n.pp, n.p);
	                    }
	                }

	                friction = friction * 0.992;

	                cb && cb(nodes, edges, friction < 0.01);
	            }
	        };
	    };


/***/ },
/* 225 */
/***/ function(module, exports, __webpack_require__) {

	
	    // FIXME Where to create the simple view coordinate system
	    var View = __webpack_require__(176);
	    var layout = __webpack_require__(71);
	    var bbox = __webpack_require__(38);

	    function getViewRect(seriesModel, api, aspect) {
	        var option = seriesModel.getBoxLayoutParams();
	        option.aspect = aspect;
	        return layout.getLayoutRect(option, {
	            width: api.getWidth(),
	            height: api.getHeight()
	        });
	    }

	    module.exports = function (ecModel, api) {
	        var viewList = [];
	        ecModel.eachSeriesByType('graph', function (seriesModel) {
	            var coordSysType = seriesModel.get('coordinateSystem');
	            if (!coordSysType || coordSysType === 'view') {

	                var data = seriesModel.getData();
	                var positions = data.mapArray(function (idx) {
	                    var itemModel = data.getItemModel(idx);
	                    return [+itemModel.get('x'), +itemModel.get('y')];
	                });

	                var min = [];
	                var max = [];

	                bbox.fromPoints(positions, min, max);

	                // If width or height is 0
	                if (max[0] - min[0] === 0) {
	                    max[0] += 1;
	                    min[0] -= 1;
	                }
	                if (max[1] - min[1] === 0) {
	                    max[1] += 1;
	                    min[1] -= 1;
	                }
	                var aspect = (max[0] - min[0]) / (max[1] - min[1]);
	                // FIXME If get view rect after data processed?
	                var viewRect = getViewRect(seriesModel, api, aspect);
	                // Position may be NaN, use view rect instead
	                if (isNaN(aspect)) {
	                    min = [viewRect.x, viewRect.y];
	                    max = [viewRect.x + viewRect.width, viewRect.y + viewRect.height];
	                }

	                var bbWidth = max[0] - min[0];
	                var bbHeight = max[1] - min[1];

	                var viewWidth = viewRect.width;
	                var viewHeight = viewRect.height;

	                var viewCoordSys = seriesModel.coordinateSystem = new View();
	                viewCoordSys.zoomLimit = seriesModel.get('scaleLimit');

	                viewCoordSys.setBoundingRect(
	                    min[0], min[1], bbWidth, bbHeight
	                );
	                viewCoordSys.setViewRect(
	                    viewRect.x, viewRect.y, viewWidth, viewHeight
	                );

	                // Update roam info
	                viewCoordSys.setCenter(seriesModel.get('center'));
	                viewCoordSys.setZoom(seriesModel.get('zoom'));

	                viewList.push(viewCoordSys);
	            }
	        });
	        return viewList;
	    };


/***/ },
/* 226 */
/***/ function(module, exports, __webpack_require__) {

	
	    __webpack_require__(227);
	    __webpack_require__(228);


/***/ },
/* 227 */
/***/ function(module, exports, __webpack_require__) {

	

	    var List = __webpack_require__(98);
	    var SeriesModel = __webpack_require__(78);
	    var zrUtil = __webpack_require__(4);

	    var GaugeSeries = SeriesModel.extend({

	        type: 'series.gauge',

	        getInitialData: function (option, ecModel) {
	            var list = new List(['value'], this);
	            var dataOpt = option.data || [];
	            if (!zrUtil.isArray(dataOpt)) {
	                dataOpt = [dataOpt];
	            }
	            // Only use the first data item
	            list.initData(dataOpt);
	            return list;
	        },

	        defaultOption: {
	            zlevel: 0,
	            z: 2,
	            // 默认全局居中
	            center: ['50%', '50%'],
	            legendHoverLink: true,
	            radius: '75%',
	            startAngle: 225,
	            endAngle: -45,
	            clockwise: true,
	            // 最小值
	            min: 0,
	            // 最大值
	            max: 100,
	            // 分割段数，默认为10
	            splitNumber: 10,
	            // 坐标轴线
	            axisLine: {
	                // 默认显示，属性show控制显示与否
	                show: true,
	                lineStyle: {       // 属性lineStyle控制线条样式
	                    color: [[0.2, '#91c7ae'], [0.8, '#63869e'], [1, '#c23531']],
	                    width: 30
	                }
	            },
	            // 分隔线
	            splitLine: {
	                // 默认显示，属性show控制显示与否
	                show: true,
	                // 属性length控制线长
	                length: 30,
	                // 属性lineStyle（详见lineStyle）控制线条样式
	                lineStyle: {
	                    color: '#eee',
	                    width: 2,
	                    type: 'solid'
	                }
	            },
	            // 坐标轴小标记
	            axisTick: {
	                // 属性show控制显示与否，默认不显示
	                show: true,
	                // 每份split细分多少段
	                splitNumber: 5,
	                // 属性length控制线长
	                length: 8,
	                // 属性lineStyle控制线条样式
	                lineStyle: {
	                    color: '#eee',
	                    width: 1,
	                    type: 'solid'
	                }
	            },
	            axisLabel: {
	                show: true,
	                distance: 5,
	                // formatter: null,
	                textStyle: {       // 其余属性默认使用全局文本样式，详见TEXTSTYLE
	                    color: 'auto'
	                }
	            },
	            pointer: {
	                show: true,
	                length: '80%',
	                width: 8
	            },
	            itemStyle: {
	                normal: {
	                    color: 'auto'
	                }
	            },
	            title: {
	                show: true,
	                // x, y，单位px
	                offsetCenter: [0, '-40%'],
	                // 其余属性默认使用全局文本样式，详见TEXTSTYLE
	                textStyle: {
	                    color: '#333',
	                    fontSize: 15
	                }
	            },
	            detail: {
	                show: true,
	                backgroundColor: 'rgba(0,0,0,0)',
	                borderWidth: 0,
	                borderColor: '#ccc',
	                width: 100,
	                height: 40,
	                // x, y，单位px
	                offsetCenter: [0, '40%'],
	                // formatter: null,
	                // 其余属性默认使用全局文本样式，详见TEXTSTYLE
	                textStyle: {
	                    color: 'auto',
	                    fontSize: 30
	                }
	            }
	        }
	    });

	    module.exports = GaugeSeries;


/***/ },
/* 228 */
/***/ function(module, exports, __webpack_require__) {

	

	    var PointerPath = __webpack_require__(229);

	    var graphic = __webpack_require__(18);
	    var numberUtil = __webpack_require__(7);
	    var parsePercent = numberUtil.parsePercent;

	    function parsePosition(seriesModel, api) {
	        var center = seriesModel.get('center');
	        var width = api.getWidth();
	        var height = api.getHeight();
	        var size = Math.min(width, height);
	        var cx = parsePercent(center[0], api.getWidth());
	        var cy = parsePercent(center[1], api.getHeight());
	        var r = parsePercent(seriesModel.get('radius'), size / 2);

	        return {
	            cx: cx,
	            cy: cy,
	            r: r
	        };
	    }

	    function formatLabel(label, labelFormatter) {
	        if (labelFormatter) {
	            if (typeof labelFormatter === 'string') {
	                label = labelFormatter.replace('{value}', label != null ? label : '');
	            }
	            else if (typeof labelFormatter === 'function') {
	                label = labelFormatter(label);
	            }
	        }

	        return label;
	    }

	    var PI2 = Math.PI * 2;

	    var GaugeView = __webpack_require__(80).extend({

	        type: 'gauge',

	        render: function (seriesModel, ecModel, api) {

	            this.group.removeAll();

	            var colorList = seriesModel.get('axisLine.lineStyle.color');
	            var posInfo = parsePosition(seriesModel, api);

	            this._renderMain(
	                seriesModel, ecModel, api, colorList, posInfo
	            );
	        },

	        dispose: function () {},

	        _renderMain: function (seriesModel, ecModel, api, colorList, posInfo) {
	            var group = this.group;

	            var axisLineModel = seriesModel.getModel('axisLine');
	            var lineStyleModel = axisLineModel.getModel('lineStyle');

	            var clockwise = seriesModel.get('clockwise');
	            var startAngle = -seriesModel.get('startAngle') / 180 * Math.PI;
	            var endAngle = -seriesModel.get('endAngle') / 180 * Math.PI;

	            var angleRangeSpan = (endAngle - startAngle) % PI2;

	            var prevEndAngle = startAngle;
	            var axisLineWidth = lineStyleModel.get('width');

	            for (var i = 0; i < colorList.length; i++) {
	                // Clamp
	                var percent = Math.min(Math.max(colorList[i][0], 0), 1);
	                var endAngle = startAngle + angleRangeSpan * percent;
	                var sector = new graphic.Sector({
	                    shape: {
	                        startAngle: prevEndAngle,
	                        endAngle: endAngle,
	                        cx: posInfo.cx,
	                        cy: posInfo.cy,
	                        clockwise: clockwise,
	                        r0: posInfo.r - axisLineWidth,
	                        r: posInfo.r
	                    },
	                    silent: true
	                });

	                sector.setStyle({
	                    fill: colorList[i][1]
	                });

	                sector.setStyle(lineStyleModel.getLineStyle(
	                    // Because we use sector to simulate arc
	                    // so the properties for stroking are useless
	                    ['color', 'borderWidth', 'borderColor']
	                ));

	                group.add(sector);

	                prevEndAngle = endAngle;
	            }

	            var getColor = function (percent) {
	                // Less than 0
	                if (percent <= 0) {
	                    return colorList[0][1];
	                }
	                for (var i = 0; i < colorList.length; i++) {
	                    if (colorList[i][0] >= percent
	                        && (i === 0 ? 0 : colorList[i - 1][0]) < percent
	                    ) {
	                        return colorList[i][1];
	                    }
	                }
	                // More than 1
	                return colorList[i - 1][1];
	            };

	            if (!clockwise) {
	                var tmp = startAngle;
	                startAngle = endAngle;
	                endAngle = tmp;
	            }

	            this._renderTicks(
	                seriesModel, ecModel, api, getColor, posInfo,
	                startAngle, endAngle, clockwise
	            );

	            this._renderPointer(
	                seriesModel, ecModel, api, getColor, posInfo,
	                startAngle, endAngle, clockwise
	            );

	            this._renderTitle(
	                seriesModel, ecModel, api, getColor, posInfo
	            );
	            this._renderDetail(
	                seriesModel, ecModel, api, getColor, posInfo
	            );
	        },

	        _renderTicks: function (
	            seriesModel, ecModel, api, getColor, posInfo,
	            startAngle, endAngle, clockwise
	        ) {
	            var group = this.group;
	            var cx = posInfo.cx;
	            var cy = posInfo.cy;
	            var r = posInfo.r;

	            var minVal = +seriesModel.get('min');
	            var maxVal = +seriesModel.get('max');

	            var splitLineModel = seriesModel.getModel('splitLine');
	            var tickModel = seriesModel.getModel('axisTick');
	            var labelModel = seriesModel.getModel('axisLabel');

	            var splitNumber = seriesModel.get('splitNumber');
	            var subSplitNumber = tickModel.get('splitNumber');

	            var splitLineLen = parsePercent(
	                splitLineModel.get('length'), r
	            );
	            var tickLen = parsePercent(
	                tickModel.get('length'), r
	            );

	            var angle = startAngle;
	            var step = (endAngle - startAngle) / splitNumber;
	            var subStep = step / subSplitNumber;

	            var splitLineStyle = splitLineModel.getModel('lineStyle').getLineStyle();
	            var tickLineStyle = tickModel.getModel('lineStyle').getLineStyle();
	            var textStyleModel = labelModel.getModel('textStyle');

	            for (var i = 0; i <= splitNumber; i++) {
	                var unitX = Math.cos(angle);
	                var unitY = Math.sin(angle);
	                // Split line
	                if (splitLineModel.get('show')) {
	                    var splitLine = new graphic.Line({
	                        shape: {
	                            x1: unitX * r + cx,
	                            y1: unitY * r + cy,
	                            x2: unitX * (r - splitLineLen) + cx,
	                            y2: unitY * (r - splitLineLen) + cy
	                        },
	                        style: splitLineStyle,
	                        silent: true
	                    });
	                    if (splitLineStyle.stroke === 'auto') {
	                        splitLine.setStyle({
	                            stroke: getColor(i / splitNumber)
	                        });
	                    }

	                    group.add(splitLine);
	                }

	                // Label
	                if (labelModel.get('show')) {
	                    var label = formatLabel(
	                        numberUtil.round(i / splitNumber * (maxVal - minVal) + minVal),
	                        labelModel.get('formatter')
	                    );
	                    var distance = labelModel.get('distance');

	                    var text = new graphic.Text({
	                        style: {
	                            text: label,
	                            x: unitX * (r - splitLineLen - distance) + cx,
	                            y: unitY * (r - splitLineLen - distance) + cy,
	                            fill: textStyleModel.getTextColor(),
	                            textFont: textStyleModel.getFont(),
	                            textVerticalAlign: unitY < -0.4 ? 'top' : (unitY > 0.4 ? 'bottom' : 'middle'),
	                            textAlign: unitX < -0.4 ? 'left' : (unitX > 0.4 ? 'right' : 'center')
	                        },
	                        silent: true
	                    });
	                    if (text.style.fill === 'auto') {
	                        text.setStyle({
	                            fill: getColor(i / splitNumber)
	                        });
	                    }

	                    group.add(text);
	                }

	                // Axis tick
	                if (tickModel.get('show') && i !== splitNumber) {
	                    for (var j = 0; j <= subSplitNumber; j++) {
	                        var unitX = Math.cos(angle);
	                        var unitY = Math.sin(angle);
	                        var tickLine = new graphic.Line({
	                            shape: {
	                                x1: unitX * r + cx,
	                                y1: unitY * r + cy,
	                                x2: unitX * (r - tickLen) + cx,
	                                y2: unitY * (r - tickLen) + cy
	                            },
	                            silent: true,
	                            style: tickLineStyle
	                        });

	                        if (tickLineStyle.stroke === 'auto') {
	                            tickLine.setStyle({
	                                stroke: getColor((i + j / subSplitNumber) / splitNumber)
	                            });
	                        }

	                        group.add(tickLine);
	                        angle += subStep;
	                    }
	                    angle -= subStep;
	                }
	                else {
	                    angle += step;
	                }
	            }
	        },

	        _renderPointer: function (
	            seriesModel, ecModel, api, getColor, posInfo,
	            startAngle, endAngle, clockwise
	        ) {

	            var group = this.group;
	            var oldData = this._data;

	            if (!seriesModel.get('pointer.show')) {
	                // Remove old element
	                oldData && oldData.eachItemGraphicEl(function (el) {
	                    group.remove(el);
	                });
	                return;
	            }

	            var valueExtent = [+seriesModel.get('min'), +seriesModel.get('max')];
	            var angleExtent = [startAngle, endAngle];

	            var data = seriesModel.getData();

	            data.diff(oldData)
	                .add(function (idx) {
	                    var pointer = new PointerPath({
	                        shape: {
	                            angle: startAngle
	                        }
	                    });

	                    graphic.initProps(pointer, {
	                        shape: {
	                            angle: numberUtil.linearMap(data.get('value', idx), valueExtent, angleExtent, true)
	                        }
	                    }, seriesModel);

	                    group.add(pointer);
	                    data.setItemGraphicEl(idx, pointer);
	                })
	                .update(function (newIdx, oldIdx) {
	                    var pointer = oldData.getItemGraphicEl(oldIdx);

	                    graphic.updateProps(pointer, {
	                        shape: {
	                            angle: numberUtil.linearMap(data.get('value', newIdx), valueExtent, angleExtent, true)
	                        }
	                    }, seriesModel);

	                    group.add(pointer);
	                    data.setItemGraphicEl(newIdx, pointer);
	                })
	                .remove(function (idx) {
	                    var pointer = oldData.getItemGraphicEl(idx);
	                    group.remove(pointer);
	                })
	                .execute();

	            data.eachItemGraphicEl(function (pointer, idx) {
	                var itemModel = data.getItemModel(idx);
	                var pointerModel = itemModel.getModel('pointer');

	                pointer.setShape({
	                    x: posInfo.cx,
	                    y: posInfo.cy,
	                    width: parsePercent(
	                        pointerModel.get('width'), posInfo.r
	                    ),
	                    r: parsePercent(pointerModel.get('length'), posInfo.r)
	                });

	                pointer.useStyle(itemModel.getModel('itemStyle.normal').getItemStyle());

	                if (pointer.style.fill === 'auto') {
	                    pointer.setStyle('fill', getColor(
	                        numberUtil.linearMap(data.get('value', idx), valueExtent, [0, 1], true)
	                    ));
	                }

	                graphic.setHoverStyle(
	                    pointer, itemModel.getModel('itemStyle.emphasis').getItemStyle()
	                );
	            });

	            this._data = data;
	        },

	        _renderTitle: function (
	            seriesModel, ecModel, api, getColor, posInfo
	        ) {
	            var titleModel = seriesModel.getModel('title');
	            if (titleModel.get('show')) {
	                var textStyleModel = titleModel.getModel('textStyle');
	                var offsetCenter = titleModel.get('offsetCenter');
	                var x = posInfo.cx + parsePercent(offsetCenter[0], posInfo.r);
	                var y = posInfo.cy + parsePercent(offsetCenter[1], posInfo.r);

	                var text = new graphic.Text({
	                    style: {
	                        x: x,
	                        y: y,
	                        // FIXME First data name ?
	                        text: seriesModel.getData().getName(0),
	                        fill: textStyleModel.getTextColor(),
	                        textFont: textStyleModel.getFont(),
	                        textAlign: 'center',
	                        textVerticalAlign: 'middle'
	                    }
	                });

	                if (text.style.fill === 'auto') {
	                    var minVal = +seriesModel.get('min');
	                    var maxVal = +seriesModel.get('max');
	                    var value = seriesModel.getData().get('value', 0);
	                    text.setStyle('fill', getColor(
	                        numberUtil.linearMap(value, [minVal, maxVal], [0, 1], true)
	                    ));
	                }

	                this.group.add(text);
	            }
	        },

	        _renderDetail: function (
	            seriesModel, ecModel, api, getColor, posInfo
	        ) {
	            var detailModel = seriesModel.getModel('detail');
	            var minVal = +seriesModel.get('min');
	            var maxVal = +seriesModel.get('max');
	            if (detailModel.get('show')) {
	                var textStyleModel = detailModel.getModel('textStyle');
	                var offsetCenter = detailModel.get('offsetCenter');
	                var x = posInfo.cx + parsePercent(offsetCenter[0], posInfo.r);
	                var y = posInfo.cy + parsePercent(offsetCenter[1], posInfo.r);
	                var width = parsePercent(detailModel.get('width'), posInfo.r);
	                var height = parsePercent(detailModel.get('height'), posInfo.r);
	                var value = seriesModel.getData().get('value', 0);
	                var rect = new graphic.Rect({
	                    shape: {
	                        x: x - width / 2,
	                        y: y - height / 2,
	                        width: width,
	                        height: height
	                    },
	                    style: {
	                        text: formatLabel(
	                            // FIXME First data name ?
	                            value, detailModel.get('formatter')
	                        ),
	                        fill: detailModel.get('backgroundColor'),
	                        textFill: textStyleModel.getTextColor(),
	                        textFont: textStyleModel.getFont()
	                    }
	                });
	                if (rect.style.textFill === 'auto') {
	                    rect.setStyle('textFill', getColor(
	                        numberUtil.linearMap(value, [minVal, maxVal], [0, 1], true)
	                    ));
	                }
	                rect.setStyle(detailModel.getItemStyle(['color']));
	                this.group.add(rect);
	            }
	        }
	    });

	    module.exports = GaugeView;


/***/ },
/* 229 */
/***/ function(module, exports, __webpack_require__) {

	

	    module.exports = __webpack_require__(20).extend({

	        type: 'echartsGaugePointer',

	        shape: {
	            angle: 0,

	            width: 10,

	            r: 10,

	            x: 0,

	            y: 0
	        },

	        buildPath: function (ctx, shape) {
	            var mathCos = Math.cos;
	            var mathSin = Math.sin;

	            var r = shape.r;
	            var width = shape.width;
	            var angle = shape.angle;
	            var x = shape.x - mathCos(angle) * width * (width >= r / 3 ? 1 : 2);
	            var y = shape.y - mathSin(angle) * width * (width >= r / 3 ? 1 : 2);

	            angle = shape.angle - Math.PI / 2;
	            ctx.moveTo(x, y);
	            ctx.lineTo(
	                shape.x + mathCos(angle) * width,
	                shape.y + mathSin(angle) * width
	            );
	            ctx.lineTo(
	                shape.x + mathCos(shape.angle) * r,
	                shape.y + mathSin(shape.angle) * r
	            );
	            ctx.lineTo(
	                shape.x - mathCos(angle) * width,
	                shape.y - mathSin(angle) * width
	            );
	            ctx.lineTo(x, y);
	            return;
	        }
	    });


/***/ },
/* 230 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);
	    var echarts = __webpack_require__(1);

	    __webpack_require__(231);
	    __webpack_require__(232);

	    echarts.registerVisual(zrUtil.curry(__webpack_require__(151), 'funnel'));
	    echarts.registerLayout(__webpack_require__(233));

	    echarts.registerProcessor(zrUtil.curry(__webpack_require__(154), 'funnel'));


/***/ },
/* 231 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var List = __webpack_require__(98);
	    var modelUtil = __webpack_require__(5);
	    var completeDimensions = __webpack_require__(110);

	    var FunnelSeries = __webpack_require__(1).extendSeriesModel({

	        type: 'series.funnel',

	        init: function (option) {
	            FunnelSeries.superApply(this, 'init', arguments);

	            // Enable legend selection for each data item
	            // Use a function instead of direct access because data reference may changed
	            this.legendDataProvider = function () {
	                return this.getRawData();
	            };
	            // Extend labelLine emphasis
	            this._defaultLabelLine(option);
	        },

	        getInitialData: function (option, ecModel) {
	            var dimensions = completeDimensions(['value'], option.data);
	            var list = new List(dimensions, this);
	            list.initData(option.data);
	            return list;
	        },

	        _defaultLabelLine: function (option) {
	            // Extend labelLine emphasis
	            modelUtil.defaultEmphasis(option.labelLine, ['show']);

	            var labelLineNormalOpt = option.labelLine.normal;
	            var labelLineEmphasisOpt = option.labelLine.emphasis;
	            // Not show label line if `label.normal.show = false`
	            labelLineNormalOpt.show = labelLineNormalOpt.show
	                && option.label.normal.show;
	            labelLineEmphasisOpt.show = labelLineEmphasisOpt.show
	                && option.label.emphasis.show;
	        },

	        // Overwrite
	        getDataParams: function (dataIndex) {
	            var data = this.getData();
	            var params = FunnelSeries.superCall(this, 'getDataParams', dataIndex);
	            var sum = data.getSum('value');
	            // Percent is 0 if sum is 0
	            params.percent = !sum ? 0 : +(data.get('value', dataIndex) / sum * 100).toFixed(2);

	            params.$vars.push('percent');
	            return params;
	        },

	        defaultOption: {
	            zlevel: 0,                  // 一级层叠
	            z: 2,                       // 二级层叠
	            legendHoverLink: true,
	            left: 80,
	            top: 60,
	            right: 80,
	            bottom: 60,
	            // width: {totalWidth} - left - right,
	            // height: {totalHeight} - top - bottom,

	            // 默认取数据最小最大值
	            // min: 0,
	            // max: 100,
	            minSize: '0%',
	            maxSize: '100%',
	            sort: 'descending', // 'ascending', 'descending'
	            gap: 0,
	            funnelAlign: 'center',
	            label: {
	                normal: {
	                    show: true,
	                    position: 'outer'
	                    // formatter: 标签文本格式器，同Tooltip.formatter，不支持异步回调
	                    // textStyle: null      // 默认使用全局文本样式，详见TEXTSTYLE
	                },
	                emphasis: {
	                    show: true
	                }
	            },
	            labelLine: {
	                normal: {
	                    show: true,
	                    length: 20,
	                    lineStyle: {
	                        // color: 各异,
	                        width: 1,
	                        type: 'solid'
	                    }
	                },
	                emphasis: {}
	            },
	            itemStyle: {
	                normal: {
	                    // color: 各异,
	                    borderColor: '#fff',
	                    borderWidth: 1
	                },
	                emphasis: {
	                    // color: 各异,
	                }
	            }
	        }
	    });

	    module.exports = FunnelSeries;



/***/ },
/* 232 */
/***/ function(module, exports, __webpack_require__) {

	

	    var graphic = __webpack_require__(18);
	    var zrUtil = __webpack_require__(4);

	    /**
	     * Piece of pie including Sector, Label, LabelLine
	     * @constructor
	     * @extends {module:zrender/graphic/Group}
	     */
	    function FunnelPiece(data, idx) {

	        graphic.Group.call(this);

	        var polygon = new graphic.Polygon();
	        var labelLine = new graphic.Polyline();
	        var text = new graphic.Text();
	        this.add(polygon);
	        this.add(labelLine);
	        this.add(text);

	        this.updateData(data, idx, true);

	        // Hover to change label and labelLine
	        function onEmphasis() {
	            labelLine.ignore = labelLine.hoverIgnore;
	            text.ignore = text.hoverIgnore;
	        }
	        function onNormal() {
	            labelLine.ignore = labelLine.normalIgnore;
	            text.ignore = text.normalIgnore;
	        }
	        this.on('emphasis', onEmphasis)
	            .on('normal', onNormal)
	            .on('mouseover', onEmphasis)
	            .on('mouseout', onNormal);
	    }

	    var funnelPieceProto = FunnelPiece.prototype;

	    function getLabelStyle(data, idx, state, labelModel) {
	        var textStyleModel = labelModel.getModel('textStyle');
	        var position = labelModel.get('position');
	        var isLabelInside = position === 'inside' || position === 'inner' || position === 'center';
	        return {
	            fill: textStyleModel.getTextColor()
	                || (isLabelInside ? '#fff' : data.getItemVisual(idx, 'color')),
	            textFont: textStyleModel.getFont(),
	            text: zrUtil.retrieve(
	                data.hostModel.getFormattedLabel(idx, state),
	                data.getName(idx)
	            )
	        };
	    }

	    var opacityAccessPath = ['itemStyle', 'normal', 'opacity'];
	    funnelPieceProto.updateData = function (data, idx, firstCreate) {

	        var polygon = this.childAt(0);

	        var seriesModel = data.hostModel;
	        var itemModel = data.getItemModel(idx);
	        var layout = data.getItemLayout(idx);
	        var opacity = data.getItemModel(idx).get(opacityAccessPath);
	        opacity = opacity == null ? 1 : opacity;

	        // Reset style
	        polygon.useStyle({});

	        if (firstCreate) {
	            polygon.setShape({
	                points: layout.points
	            });
	            polygon.setStyle({ opacity : 0 });
	            graphic.initProps(polygon, {
	                style: {
	                    opacity: opacity
	                }
	            }, seriesModel, idx);
	        }
	        else {
	            graphic.updateProps(polygon, {
	                style: {
	                    opacity: opacity
	                },
	                shape: {
	                    points: layout.points
	                }
	            }, seriesModel, idx);
	        }

	        // Update common style
	        var itemStyleModel = itemModel.getModel('itemStyle');
	        var visualColor = data.getItemVisual(idx, 'color');

	        polygon.setStyle(
	            zrUtil.defaults(
	                {
	                    lineJoin: 'round',
	                    fill: visualColor
	                },
	                itemStyleModel.getModel('normal').getItemStyle(['opacity'])
	            )
	        );
	        polygon.hoverStyle = itemStyleModel.getModel('emphasis').getItemStyle();

	        this._updateLabel(data, idx);

	        graphic.setHoverStyle(this);
	    };

	    funnelPieceProto._updateLabel = function (data, idx) {

	        var labelLine = this.childAt(1);
	        var labelText = this.childAt(2);

	        var seriesModel = data.hostModel;
	        var itemModel = data.getItemModel(idx);
	        var layout = data.getItemLayout(idx);
	        var labelLayout = layout.label;
	        var visualColor = data.getItemVisual(idx, 'color');

	        graphic.updateProps(labelLine, {
	            shape: {
	                points: labelLayout.linePoints || labelLayout.linePoints
	            }
	        }, seriesModel, idx);

	        graphic.updateProps(labelText, {
	            style: {
	                x: labelLayout.x,
	                y: labelLayout.y
	            }
	        }, seriesModel, idx);
	        labelText.attr({
	            style: {
	                textAlign: labelLayout.textAlign,
	                textVerticalAlign: labelLayout.verticalAlign,
	                textFont: labelLayout.font
	            },
	            rotation: labelLayout.rotation,
	            origin: [labelLayout.x, labelLayout.y],
	            z2: 10
	        });

	        var labelModel = itemModel.getModel('label.normal');
	        var labelHoverModel = itemModel.getModel('label.emphasis');
	        var labelLineModel = itemModel.getModel('labelLine.normal');
	        var labelLineHoverModel = itemModel.getModel('labelLine.emphasis');

	        labelText.setStyle(getLabelStyle(data, idx, 'normal', labelModel));

	        labelText.ignore = labelText.normalIgnore = !labelModel.get('show');
	        labelText.hoverIgnore = !labelHoverModel.get('show');

	        labelLine.ignore = labelLine.normalIgnore = !labelLineModel.get('show');
	        labelLine.hoverIgnore = !labelLineHoverModel.get('show');

	        // Default use item visual color
	        labelLine.setStyle({
	            stroke: visualColor
	        });
	        labelLine.setStyle(labelLineModel.getModel('lineStyle').getLineStyle());

	        labelText.hoverStyle = getLabelStyle(data, idx, 'emphasis', labelHoverModel);
	        labelLine.hoverStyle = labelLineHoverModel.getModel('lineStyle').getLineStyle();
	    };

	    zrUtil.inherits(FunnelPiece, graphic.Group);


	    var Funnel = __webpack_require__(80).extend({

	        type: 'funnel',

	        render: function (seriesModel, ecModel, api) {
	            var data = seriesModel.getData();
	            var oldData = this._data;

	            var group = this.group;

	            data.diff(oldData)
	                .add(function (idx) {
	                    var funnelPiece = new FunnelPiece(data, idx);

	                    data.setItemGraphicEl(idx, funnelPiece);

	                    group.add(funnelPiece);
	                })
	                .update(function (newIdx, oldIdx) {
	                    var piePiece = oldData.getItemGraphicEl(oldIdx);

	                    piePiece.updateData(data, newIdx);

	                    group.add(piePiece);
	                    data.setItemGraphicEl(newIdx, piePiece);
	                })
	                .remove(function (idx) {
	                    var piePiece = oldData.getItemGraphicEl(idx);
	                    group.remove(piePiece);
	                })
	                .execute();

	            this._data = data;
	        },

	        remove: function () {
	            this.group.removeAll();
	            this._data = null;
	        },

	        dispose: function () {}
	    });

	    module.exports = Funnel;


/***/ },
/* 233 */
/***/ function(module, exports, __webpack_require__) {

	

	    var layout = __webpack_require__(71);
	    var number = __webpack_require__(7);

	    var parsePercent = number.parsePercent;

	    function getViewRect(seriesModel, api) {
	        return layout.getLayoutRect(
	            seriesModel.getBoxLayoutParams(), {
	                width: api.getWidth(),
	                height: api.getHeight()
	            }
	        );
	    }

	    function getSortedIndices(data, sort) {
	        var valueArr = data.mapArray('value', function (val) {
	            return val;
	        });
	        var indices = [];
	        var isAscending = sort === 'ascending';
	        for (var i = 0, len = data.count(); i < len; i++) {
	            indices[i] = i;
	        }

	        // Add custom sortable function & none sortable opetion by "options.sort"
	        if (typeof sort === 'function') {
	            indices.sort(sort);
	        } else if (sort !== 'none') {
	            indices.sort(function (a, b) {
	                return isAscending ? valueArr[a] - valueArr[b] : valueArr[b] - valueArr[a];
	            });
	        }
	        return indices;
	    }

	    function labelLayout (data) {
	        data.each(function (idx) {
	            var itemModel = data.getItemModel(idx);
	            var labelModel = itemModel.getModel('label.normal');
	            var labelPosition = labelModel.get('position');

	            var labelLineModel = itemModel.getModel('labelLine.normal');

	            var layout = data.getItemLayout(idx);
	            var points = layout.points;

	            var isLabelInside = labelPosition === 'inner'
	                || labelPosition === 'inside' || labelPosition === 'center';

	            var textAlign;
	            var textX;
	            var textY;
	            var linePoints;

	            if (isLabelInside) {
	                textX = (points[0][0] + points[1][0] + points[2][0] + points[3][0]) / 4;
	                textY = (points[0][1] + points[1][1] + points[2][1] + points[3][1]) / 4;
	                textAlign = 'center';
	                linePoints = [
	                    [textX, textY], [textX, textY]
	                ];
	            }
	            else {
	                var x1;
	                var y1;
	                var x2;
	                var labelLineLen = labelLineModel.get('length');
	                if (labelPosition === 'left') {
	                    // Left side
	                    x1 = (points[3][0] + points[0][0]) / 2;
	                    y1 = (points[3][1] + points[0][1]) / 2;
	                    x2 = x1 - labelLineLen;
	                    textX = x2 - 5;
	                    textAlign = 'right';
	                }
	                else {
	                    // Right side
	                    x1 = (points[1][0] + points[2][0]) / 2;
	                    y1 = (points[1][1] + points[2][1]) / 2;
	                    x2 = x1 + labelLineLen;
	                    textX = x2 + 5;
	                    textAlign = 'left';
	                }
	                var y2 = y1;

	                linePoints = [[x1, y1], [x2, y2]];
	                textY = y2;
	            }

	            layout.label = {
	                linePoints: linePoints,
	                x: textX,
	                y: textY,
	                verticalAlign: 'middle',
	                textAlign: textAlign,
	                inside: isLabelInside
	            };
	        });
	    }

	    module.exports = function (ecModel, api, payload) {
	        ecModel.eachSeriesByType('funnel', function (seriesModel) {
	            var data = seriesModel.getData();
	            var sort = seriesModel.get('sort');
	            var viewRect = getViewRect(seriesModel, api);
	            var indices = getSortedIndices(data, sort);

	            var sizeExtent = [
	                parsePercent(seriesModel.get('minSize'), viewRect.width),
	                parsePercent(seriesModel.get('maxSize'), viewRect.width)
	            ];
	            var dataExtent = data.getDataExtent('value');
	            var min = seriesModel.get('min');
	            var max = seriesModel.get('max');
	            if (min == null) {
	                min = Math.min(dataExtent[0], 0);
	            }
	            if (max == null) {
	                max = dataExtent[1];
	            }

	            var funnelAlign = seriesModel.get('funnelAlign');
	            var gap = seriesModel.get('gap');
	            var itemHeight = (viewRect.height - gap * (data.count() - 1)) / data.count();

	            var y = viewRect.y;

	            var getLinePoints = function (idx, offY) {
	                // End point index is data.count() and we assign it 0
	                var val = data.get('value', idx) || 0;
	                var itemWidth = number.linearMap(val, [min, max], sizeExtent, true);
	                var x0;
	                switch (funnelAlign) {
	                    case 'left':
	                        x0 = viewRect.x;
	                        break;
	                    case 'center':
	                        x0 = viewRect.x + (viewRect.width - itemWidth) / 2;
	                        break;
	                    case 'right':
	                        x0 = viewRect.x + viewRect.width - itemWidth;
	                        break;
	                }
	                return [
	                    [x0, offY],
	                    [x0 + itemWidth, offY]
	                ];
	            };

	            if (sort === 'ascending') {
	                // From bottom to top
	                itemHeight = -itemHeight;
	                gap = -gap;
	                y += viewRect.height;
	                indices = indices.reverse();
	            }

	            for (var i = 0; i < indices.length; i++) {
	                var idx = indices[i];
	                var nextIdx = indices[i + 1];
	                var start = getLinePoints(idx, y);
	                var end = getLinePoints(nextIdx, y + itemHeight);

	                y += itemHeight + gap;

	                data.setItemLayout(idx, {
	                    points: start.concat(end.slice().reverse())
	                });
	            }

	            labelLayout(data);
	        });
	    };



/***/ },
/* 234 */
/***/ function(module, exports, __webpack_require__) {

	

	    var echarts = __webpack_require__(1);

	    __webpack_require__(235);

	    __webpack_require__(248);
	    __webpack_require__(249);

	    echarts.registerVisual(__webpack_require__(250));



/***/ },
/* 235 */
/***/ function(module, exports, __webpack_require__) {

	

	    __webpack_require__(236);
	    __webpack_require__(240);
	    __webpack_require__(242);

	    var echarts = __webpack_require__(1);
	    var zrUtil = __webpack_require__(4);
	    var throttle = __webpack_require__(81);

	    var CLICK_THRESHOLD = 5; // > 4

	    // Parallel view
	    echarts.extendComponentView({
	        type: 'parallel',

	        render: function (parallelModel, ecModel, api) {
	            this._model = parallelModel;
	            this._api = api;

	            if (!this._handlers) {
	                this._handlers = {};
	                zrUtil.each(handlers, function (handler, eventName) {
	                    api.getZr().on(eventName, this._handlers[eventName] = zrUtil.bind(handler, this));
	                }, this);
	            }

	            throttle.createOrUpdate(
	                this,
	                '_throttledDispatchExpand',
	                parallelModel.get('axisExpandRate'),
	                'fixRate'
	            );
	        },

	        dispose: function (ecModel, api) {
	            zrUtil.each(this._handlers, function (handler, eventName) {
	                api.getZr().off(eventName, handler);
	            });
	            this._handlers = null;
	        },

	        /**
	         * @param {Object} [opt] If null, cancle the last action triggering for debounce.
	         */
	        _throttledDispatchExpand: function (opt) {
	            this._dispatchExpand(opt);
	        },

	        _dispatchExpand: function (opt) {
	            opt && this._api.dispatchAction(
	                zrUtil.extend({type: 'parallelAxisExpand'}, opt)
	            );
	        }

	    });

	    var handlers = {

	        mousedown: function (e) {
	            if (checkTrigger(this, 'click')) {
	                this._mouseDownPoint = [e.offsetX, e.offsetY];
	            }
	        },

	        mouseup: function (e) {
	            var mouseDownPoint = this._mouseDownPoint;

	            if (checkTrigger(this, 'click') && mouseDownPoint) {
	                var point = [e.offsetX, e.offsetY];
	                var dist = Math.pow(mouseDownPoint[0] - point[0], 2)
	                    + Math.pow(mouseDownPoint[1] - point[1], 2);

	                if (dist > CLICK_THRESHOLD) {
	                    return;
	                }

	                var result = this._model.coordinateSystem.getSlidedAxisExpandWindow(
	                    [e.offsetX, e.offsetY]
	                );

	                result.behavior !== 'none' && this._dispatchExpand({
	                    axisExpandWindow: result.axisExpandWindow
	                });
	            }

	            this._mouseDownPoint = null;
	        },

	        mousemove: function (e) {
	            // Should do nothing when brushing.
	            if (this._mouseDownPoint || !checkTrigger(this, 'mousemove')) {
	                return;
	            }
	            var model = this._model;
	            var result = model.coordinateSystem.getSlidedAxisExpandWindow(
	                [e.offsetX, e.offsetY]
	            );

	            var behavior = result.behavior;
	            behavior === 'jump' && this._throttledDispatchExpand.debounceNextCall(model.get('axisExpandDebounce'));
	            this._throttledDispatchExpand(
	                behavior === 'none'
	                    ? null // Cancle the last trigger, in case that mouse slide out of the area quickly.
	                    : {
	                        axisExpandWindow: result.axisExpandWindow,
	                        // Jumping uses animation, and sliding suppresses animation.
	                        animation: behavior === 'jump'  ? null : false
	                    }
	            );
	        }
	    };

	    function checkTrigger(view, triggerOn) {
	        var model = view._model;
	        return model.get('axisExpandable') && model.get('axisExpandTriggerOn') === triggerOn;
	    }

	    echarts.registerPreprocessor(
	        __webpack_require__(247)
	    );



/***/ },
/* 236 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * Parallel coordinate system creater.
	 */


	    var Parallel = __webpack_require__(237);

	    function create(ecModel, api) {
	        var coordSysList = [];

	        ecModel.eachComponent('parallel', function (parallelModel, idx) {
	            var coordSys = new Parallel(parallelModel, ecModel, api);

	            coordSys.name = 'parallel_' + idx;
	            coordSys.resize(parallelModel, api);

	            parallelModel.coordinateSystem = coordSys;
	            coordSys.model = parallelModel;

	            coordSysList.push(coordSys);
	        });

	        // Inject the coordinateSystems into seriesModel
	        ecModel.eachSeries(function (seriesModel) {
	            if (seriesModel.get('coordinateSystem') === 'parallel') {
	                var parallelModel = ecModel.queryComponents({
	                    mainType: 'parallel',
	                    index: seriesModel.get('parallelIndex'),
	                    id: seriesModel.get('parallelId')
	                })[0];
	                seriesModel.coordinateSystem = parallelModel.coordinateSystem;
	            }
	        });

	        return coordSysList;
	    }

	    __webpack_require__(76).register('parallel', {create: create});



/***/ },
/* 237 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * Parallel Coordinates
	 * <https://en.wikipedia.org/wiki/Parallel_coordinates>
	 */


	    var layoutUtil = __webpack_require__(71);
	    var axisHelper = __webpack_require__(101);
	    var zrUtil = __webpack_require__(4);
	    var ParallelAxis = __webpack_require__(238);
	    var graphic = __webpack_require__(18);
	    var matrix = __webpack_require__(11);
	    var numberUtil = __webpack_require__(7);
	    var sliderMove = __webpack_require__(239);

	    var each = zrUtil.each;
	    var mathMin = Math.min;
	    var mathMax = Math.max;
	    var mathFloor = Math.floor;
	    var mathCeil = Math.ceil;
	    var round = numberUtil.round;

	    var PI = Math.PI;

	    function Parallel(parallelModel, ecModel, api) {

	        /**
	         * key: dimension
	         * @type {Object.<string, module:echarts/coord/parallel/Axis>}
	         * @private
	         */
	        this._axesMap = zrUtil.createHashMap();

	        /**
	         * key: dimension
	         * value: {position: [], rotation, }
	         * @type {Object.<string, Object>}
	         * @private
	         */
	        this._axesLayout = {};

	        /**
	         * Always follow axis order.
	         * @type {Array.<string>}
	         * @readOnly
	         */
	        this.dimensions = parallelModel.dimensions;

	        /**
	         * @type {module:zrender/core/BoundingRect}
	         */
	        this._rect;

	        /**
	         * @type {module:echarts/coord/parallel/ParallelModel}
	         */
	        this._model = parallelModel;

	        this._init(parallelModel, ecModel, api);
	    }

	    Parallel.prototype = {

	        type: 'parallel',

	        constructor: Parallel,

	        /**
	         * Initialize cartesian coordinate systems
	         * @private
	         */
	        _init: function (parallelModel, ecModel, api) {

	            var dimensions = parallelModel.dimensions;
	            var parallelAxisIndex = parallelModel.parallelAxisIndex;

	            each(dimensions, function (dim, idx) {

	                var axisIndex = parallelAxisIndex[idx];
	                var axisModel = ecModel.getComponent('parallelAxis', axisIndex);

	                var axis = this._axesMap.set(dim, new ParallelAxis(
	                    dim,
	                    axisHelper.createScaleByModel(axisModel),
	                    [0, 0],
	                    axisModel.get('type'),
	                    axisIndex
	                ));

	                var isCategory = axis.type === 'category';
	                axis.onBand = isCategory && axisModel.get('boundaryGap');
	                axis.inverse = axisModel.get('inverse');

	                // Injection
	                axisModel.axis = axis;
	                axis.model = axisModel;
	                axis.coordinateSystem = axisModel.coordinateSystem = this;

	            }, this);
	        },

	        /**
	         * Update axis scale after data processed
	         * @param  {module:echarts/model/Global} ecModel
	         * @param  {module:echarts/ExtensionAPI} api
	         */
	        update: function (ecModel, api) {
	            this._updateAxesFromSeries(this._model, ecModel);
	        },

	        /**
	         * @override
	         */
	        containPoint: function (point) {
	            var layoutInfo = this._makeLayoutInfo();
	            var axisBase = layoutInfo.axisBase;
	            var layoutBase = layoutInfo.layoutBase;
	            var pixelDimIndex = layoutInfo.pixelDimIndex;
	            var pAxis = point[1 - pixelDimIndex];
	            var pLayout = point[pixelDimIndex];

	            return pAxis >= axisBase
	                && pAxis <= axisBase + layoutInfo.axisLength
	                && pLayout >= layoutBase
	                && pLayout <= layoutBase + layoutInfo.layoutLength;
	        },

	        /**
	         * Update properties from series
	         * @private
	         */
	        _updateAxesFromSeries: function (parallelModel, ecModel) {
	            ecModel.eachSeries(function (seriesModel) {

	                if (!parallelModel.contains(seriesModel, ecModel)) {
	                    return;
	                }

	                var data = seriesModel.getData();

	                each(this.dimensions, function (dim) {
	                    var axis = this._axesMap.get(dim);
	                    axis.scale.unionExtentFromData(data, dim);
	                    axisHelper.niceScaleExtent(axis.scale, axis.model);
	                }, this);
	            }, this);
	        },

	        /**
	         * Resize the parallel coordinate system.
	         * @param {module:echarts/coord/parallel/ParallelModel} parallelModel
	         * @param {module:echarts/ExtensionAPI} api
	         */
	        resize: function (parallelModel, api) {
	            this._rect = layoutUtil.getLayoutRect(
	                parallelModel.getBoxLayoutParams(),
	                {
	                    width: api.getWidth(),
	                    height: api.getHeight()
	                }
	            );

	            this._layoutAxes();
	        },

	        /**
	         * @return {module:zrender/core/BoundingRect}
	         */
	        getRect: function () {
	            return this._rect;
	        },

	        /**
	         * @private
	         */
	        _makeLayoutInfo: function () {
	            var parallelModel = this._model;
	            var rect = this._rect;
	            var xy = ['x', 'y'];
	            var wh = ['width', 'height'];
	            var layout = parallelModel.get('layout');
	            var pixelDimIndex = layout === 'horizontal' ? 0 : 1;
	            var layoutLength = rect[wh[pixelDimIndex]];
	            var layoutExtent = [0, layoutLength];
	            var axisCount = this.dimensions.length;

	            var axisExpandWidth = restrict(parallelModel.get('axisExpandWidth'), layoutExtent);
	            var axisExpandCount = restrict(parallelModel.get('axisExpandCount') || 0, [0, axisCount]);
	            var axisExpandable = parallelModel.get('axisExpandable')
	                && axisCount > 3
	                && axisCount > axisExpandCount
	                && axisExpandCount > 1
	                && axisExpandWidth > 0
	                && layoutLength > 0;

	            // `axisExpandWindow` is According to the coordinates of [0, axisExpandLength],
	            // for sake of consider the case that axisCollapseWidth is 0 (when screen is narrow),
	            // where collapsed axes should be overlapped.
	            var axisExpandWindow = parallelModel.get('axisExpandWindow');
	            var winSize;
	            if (!axisExpandWindow) {
	                winSize = restrict(axisExpandWidth * (axisExpandCount - 1), layoutExtent);
	                var axisExpandCenter = parallelModel.get('axisExpandCenter') || mathFloor(axisCount / 2);
	                axisExpandWindow = [axisExpandWidth * axisExpandCenter - winSize / 2];
	                axisExpandWindow[1] = axisExpandWindow[0] + winSize;
	            }
	            else {
	                 winSize = restrict(axisExpandWindow[1] - axisExpandWindow[0], layoutExtent);
	                 axisExpandWindow[1] = axisExpandWindow[0] + winSize;
	            }

	            var axisCollapseWidth = (layoutLength - winSize) / (axisCount - axisExpandCount);
	            // Avoid axisCollapseWidth is too small.
	            axisCollapseWidth < 3 && (axisCollapseWidth = 0);

	            // Find the first and last indices > ewin[0] and < ewin[1].
	            var winInnerIndices = [
	                mathFloor(round(axisExpandWindow[0] / axisExpandWidth, 1)) + 1,
	                mathCeil(round(axisExpandWindow[1] / axisExpandWidth, 1)) - 1
	            ];

	            // Pos in ec coordinates.
	            var axisExpandWindow0Pos = axisCollapseWidth / axisExpandWidth * axisExpandWindow[0];

	            return {
	                layout: layout,
	                pixelDimIndex: pixelDimIndex,
	                layoutBase: rect[xy[pixelDimIndex]],
	                layoutLength: layoutLength,
	                axisBase: rect[xy[1 - pixelDimIndex]],
	                axisLength: rect[wh[1 - pixelDimIndex]],
	                axisExpandable: axisExpandable,
	                axisExpandWidth: axisExpandWidth,
	                axisCollapseWidth: axisCollapseWidth,
	                axisExpandWindow: axisExpandWindow,
	                axisCount: axisCount,
	                winInnerIndices: winInnerIndices,
	                axisExpandWindow0Pos: axisExpandWindow0Pos
	            };
	        },

	        /**
	         * @private
	         */
	        _layoutAxes: function () {
	            var rect = this._rect;
	            var axes = this._axesMap;
	            var dimensions = this.dimensions;
	            var layoutInfo = this._makeLayoutInfo();
	            var layout = layoutInfo.layout;

	            axes.each(function (axis) {
	                var axisExtent = [0, layoutInfo.axisLength];
	                var idx = axis.inverse ? 1 : 0;
	                axis.setExtent(axisExtent[idx], axisExtent[1 - idx]);
	            });

	            each(dimensions, function (dim, idx) {
	                var posInfo = (layoutInfo.axisExpandable
	                    ? layoutAxisWithExpand : layoutAxisWithoutExpand
	                )(idx, layoutInfo);

	                var positionTable = {
	                    horizontal: {
	                        x: posInfo.position,
	                        y: layoutInfo.axisLength
	                    },
	                    vertical: {
	                        x: 0,
	                        y: posInfo.position
	                    }
	                };
	                var rotationTable = {
	                    horizontal: PI / 2,
	                    vertical: 0
	                };

	                var position = [
	                    positionTable[layout].x + rect.x,
	                    positionTable[layout].y + rect.y
	                ];

	                var rotation = rotationTable[layout];
	                var transform = matrix.create();
	                matrix.rotate(transform, transform, rotation);
	                matrix.translate(transform, transform, position);

	                // TODO
	                // tick等排布信息。

	                // TODO
	                // 根据axis order 更新 dimensions顺序。

	                this._axesLayout[dim] = {
	                    position: position,
	                    rotation: rotation,
	                    transform: transform,
	                    axisNameAvailableWidth: posInfo.axisNameAvailableWidth,
	                    axisLabelShow: posInfo.axisLabelShow,
	                    nameTruncateMaxWidth: posInfo.nameTruncateMaxWidth,
	                    tickDirection: 1,
	                    labelDirection: 1,
	                    labelInterval: axes.get(dim).getLabelInterval()
	                };
	            }, this);
	        },

	        /**
	         * Get axis by dim.
	         * @param {string} dim
	         * @return {module:echarts/coord/parallel/ParallelAxis} [description]
	         */
	        getAxis: function (dim) {
	            return this._axesMap.get(dim);
	        },

	        /**
	         * Convert a dim value of a single item of series data to Point.
	         * @param {*} value
	         * @param {string} dim
	         * @return {Array}
	         */
	        dataToPoint: function (value, dim) {
	            return this.axisCoordToPoint(
	                this._axesMap.get(dim).dataToCoord(value),
	                dim
	            );
	        },

	        /**
	         * Travel data for one time, get activeState of each data item.
	         * @param {module:echarts/data/List} data
	         * @param {Functio} cb param: {string} activeState 'active' or 'inactive' or 'normal'
	         *                            {number} dataIndex
	         * @param {Object} context
	         */
	        eachActiveState: function (data, callback, context) {
	            var dimensions = this.dimensions;
	            var axesMap = this._axesMap;
	            var hasActiveSet = this.hasAxisBrushed();

	            for (var i = 0, len = data.count(); i < len; i++) {
	                var values = data.getValues(dimensions, i);
	                var activeState;

	                if (!hasActiveSet) {
	                    activeState = 'normal';
	                }
	                else {
	                    activeState = 'active';
	                    for (var j = 0, lenj = dimensions.length; j < lenj; j++) {
	                        var dimName = dimensions[j];
	                        var state = axesMap.get(dimName).model.getActiveState(values[j], j);

	                        if (state === 'inactive') {
	                            activeState = 'inactive';
	                            break;
	                        }
	                    }
	                }

	                callback.call(context, activeState, i);
	            }
	        },

	        /**
	         * Whether has any activeSet.
	         * @return {boolean}
	         */
	        hasAxisBrushed: function () {
	            var dimensions = this.dimensions;
	            var axesMap = this._axesMap;
	            var hasActiveSet = false;

	            for (var j = 0, lenj = dimensions.length; j < lenj; j++) {
	                if (axesMap.get(dimensions[j]).model.getActiveState() !== 'normal') {
	                    hasActiveSet = true;
	                }
	            }

	            return hasActiveSet;
	        },

	        /**
	         * Convert coords of each axis to Point.
	         *  Return point. For example: [10, 20]
	         * @param {Array.<number>} coords
	         * @param {string} dim
	         * @return {Array.<number>}
	         */
	        axisCoordToPoint: function (coord, dim) {
	            var axisLayout = this._axesLayout[dim];
	            return graphic.applyTransform([coord, 0], axisLayout.transform);
	        },

	        /**
	         * Get axis layout.
	         */
	        getAxisLayout: function (dim) {
	            return zrUtil.clone(this._axesLayout[dim]);
	        },

	        /**
	         * @param {Array.<number>} point
	         * @return {Object} {axisExpandWindow, delta, behavior: 'jump' | 'slide' | 'none'}.
	         */
	        getSlidedAxisExpandWindow: function (point) {
	            var layoutInfo = this._makeLayoutInfo();
	            var pixelDimIndex = layoutInfo.pixelDimIndex;
	            var axisExpandWindow = layoutInfo.axisExpandWindow.slice();
	            var winSize = axisExpandWindow[1] - axisExpandWindow[0];
	            var extent = [0, layoutInfo.axisExpandWidth * (layoutInfo.axisCount - 1)];

	            // Out of the area of coordinate system.
	            if (!this.containPoint(point)) {
	                return {behavior: 'none', axisExpandWindow: axisExpandWindow};
	            }

	            // Conver the point from global to expand coordinates.
	            var pointCoord = point[pixelDimIndex] - layoutInfo.layoutBase - layoutInfo.axisExpandWindow0Pos;

	            // For dragging operation convenience, the window should not be
	            // slided when mouse is the center area of the window.
	            var delta;
	            var behavior = 'slide';
	            var axisCollapseWidth = layoutInfo.axisCollapseWidth;
	            var triggerArea = this._model.get('axisExpandSlideTriggerArea');
	            // But consider touch device, jump is necessary.
	            var useJump = triggerArea[0] != null;

	            if (axisCollapseWidth) {
	                if (useJump && axisCollapseWidth && pointCoord < winSize * triggerArea[0]) {
	                    behavior = 'jump';
	                    delta = pointCoord - winSize * triggerArea[2];
	                }
	                else if (useJump && axisCollapseWidth && pointCoord > winSize * (1 - triggerArea[0])) {
	                    behavior = 'jump';
	                    delta = pointCoord - winSize * (1 - triggerArea[2]);
	                }
	                else {
	                    (delta = pointCoord - winSize * triggerArea[1]) >= 0
	                        && (delta = pointCoord - winSize * (1 - triggerArea[1])) <= 0
	                        && (delta = 0);
	                }
	                delta *= layoutInfo.axisExpandWidth / axisCollapseWidth;
	                delta
	                    ? sliderMove(delta, axisExpandWindow, extent, 'all')
	                    // Avoid nonsense triger on mousemove.
	                    : (behavior = 'none');
	            }
	            // When screen is too narrow, make it visible and slidable, although it is hard to interact.
	            else {
	                var winSize = axisExpandWindow[1] - axisExpandWindow[0];
	                var pos = extent[1] * pointCoord / winSize;
	                axisExpandWindow = [mathMax(0, pos - winSize / 2)];
	                axisExpandWindow[1] = mathMin(extent[1], axisExpandWindow[0] + winSize);
	                axisExpandWindow[0] = axisExpandWindow[1] - winSize;
	            }

	            return {
	                axisExpandWindow: axisExpandWindow,
	                behavior: behavior
	            };
	        }
	    };

	    function restrict(len, extent) {
	        return mathMin(mathMax(len, extent[0]), extent[1]);
	    }

	    function layoutAxisWithoutExpand(axisIndex, layoutInfo) {
	        var step = layoutInfo.layoutLength / (layoutInfo.axisCount - 1);
	        return {
	            position: step * axisIndex,
	            axisNameAvailableWidth: step,
	            axisLabelShow: true
	        };
	    }

	    function layoutAxisWithExpand(axisIndex, layoutInfo) {
	        var layoutLength = layoutInfo.layoutLength;
	        var axisExpandWidth = layoutInfo.axisExpandWidth;
	        var axisCount = layoutInfo.axisCount;
	        var axisCollapseWidth = layoutInfo.axisCollapseWidth;
	        var winInnerIndices = layoutInfo.winInnerIndices;

	        var position;
	        var axisNameAvailableWidth = axisCollapseWidth;
	        var axisLabelShow = false;
	        var nameTruncateMaxWidth;

	        if (axisIndex < winInnerIndices[0]) {
	            position = axisIndex * axisCollapseWidth;
	            nameTruncateMaxWidth = axisCollapseWidth;
	        }
	        else if (axisIndex <= winInnerIndices[1]) {
	            position = layoutInfo.axisExpandWindow0Pos
	                + axisIndex * axisExpandWidth - layoutInfo.axisExpandWindow[0];
	            axisNameAvailableWidth = axisExpandWidth;
	            axisLabelShow = true;
	        }
	        else {
	            position = layoutLength - (axisCount - 1 - axisIndex) * axisCollapseWidth;
	            nameTruncateMaxWidth = axisCollapseWidth;
	        }

	        return {
	            position: position,
	            axisNameAvailableWidth: axisNameAvailableWidth,
	            axisLabelShow: axisLabelShow,
	            nameTruncateMaxWidth: nameTruncateMaxWidth
	        };
	    }

	    module.exports = Parallel;


/***/ },
/* 238 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);
	    var Axis = __webpack_require__(100);

	    /**
	     * @constructor module:echarts/coord/parallel/ParallelAxis
	     * @extends {module:echarts/coord/Axis}
	     * @param {string} dim
	     * @param {*} scale
	     * @param {Array.<number>} coordExtent
	     * @param {string} axisType
	     */
	    var ParallelAxis = function (dim, scale, coordExtent, axisType, axisIndex) {

	        Axis.call(this, dim, scale, coordExtent);

	        /**
	         * Axis type
	         *  - 'category'
	         *  - 'value'
	         *  - 'time'
	         *  - 'log'
	         * @type {string}
	         */
	        this.type = axisType || 'value';

	        /**
	         * @type {number}
	         * @readOnly
	         */
	        this.axisIndex = axisIndex;
	    };

	    ParallelAxis.prototype = {

	        constructor: ParallelAxis,

	        /**
	         * Axis model
	         * @param {module:echarts/coord/parallel/AxisModel}
	         */
	        model: null

	    };

	    zrUtil.inherits(ParallelAxis, Axis);

	    module.exports = ParallelAxis;


/***/ },
/* 239 */
/***/ function(module, exports) {

	

	    /**
	     * Calculate slider move result.
	     * Usage:
	     * (1) If both handle0 and handle1 are needed to be moved, set minSpan the same as
	     * maxSpan and the same as `Math.abs(handleEnd[1] - handleEnds[0])`.
	     * (2) If handle0 is forbidden to cross handle1, set minSpan as `0`.
	     *
	     * @param {number} delta Move length.
	     * @param {Array.<number>} handleEnds handleEnds[0] can be bigger then handleEnds[1].
	     *              handleEnds will be modified in this method.
	     * @param {Array.<number>} extent handleEnds is restricted by extent.
	     *              extent[0] should less or equals than extent[1].
	     * @param {number|string} handleIndex Can be 'all', means that both move the two handleEnds,
	     *              where the input minSpan and maxSpan will not work.
	     * @param {number} [minSpan] The range of dataZoom can not be smaller than that.
	     *              If not set, handle0 and cross handle1. If set as a non-negative
	     *              number (including `0`), handles will push each other when reaching
	     *              the minSpan.
	     * @param {number} [maxSpan] The range of dataZoom can not be larger than that.
	     * @return {Array.<number>} The input handleEnds.
	     */
	    module.exports = function (delta, handleEnds, extent, handleIndex, minSpan, maxSpan) {
	        // Normalize firstly.
	        handleEnds[0] = restrict(handleEnds[0], extent);
	        handleEnds[1] = restrict(handleEnds[1], extent);

	        delta = delta || 0;

	        var extentSpan = extent[1] - extent[0];

	        // Notice maxSpan and minSpan can be null/undefined.
	        if (minSpan != null) {
	            minSpan = restrict(minSpan, [0, extentSpan]);
	        }
	        if (maxSpan != null) {
	            maxSpan = Math.max(maxSpan, minSpan != null ? minSpan : 0);
	        }
	        if (handleIndex === 'all') {
	            minSpan = maxSpan = Math.abs(handleEnds[1] - handleEnds[0]);
	            handleIndex = 0;
	        }

	        var originalDistSign = getSpanSign(handleEnds, handleIndex);

	        handleEnds[handleIndex] += delta;

	        // Restrict in extent.
	        var extentMinSpan = minSpan || 0;
	        var realExtent = extent.slice();
	        originalDistSign.sign < 0 ? (realExtent[0] += extentMinSpan) : (realExtent[1] -= extentMinSpan);
	        handleEnds[handleIndex] = restrict(handleEnds[handleIndex], realExtent);

	        // Expand span.
	        var currDistSign = getSpanSign(handleEnds, handleIndex);
	        if (minSpan != null && (
	            currDistSign.sign !== originalDistSign.sign || currDistSign.span < minSpan
	        )) {
	            // If minSpan exists, 'cross' is forbinden.
	            handleEnds[1 - handleIndex] = handleEnds[handleIndex] + originalDistSign.sign * minSpan;
	        }

	        // Shrink span.
	        var currDistSign = getSpanSign(handleEnds, handleIndex);
	        if (maxSpan != null && currDistSign.span > maxSpan) {
	            handleEnds[1 - handleIndex] = handleEnds[handleIndex] + currDistSign.sign * maxSpan;
	        }

	        return handleEnds;
	    };

	    function getSpanSign(handleEnds, handleIndex) {
	        var dist = handleEnds[handleIndex] - handleEnds[1 - handleIndex];
	        // If `handleEnds[0] === handleEnds[1]`, always believe that handleEnd[0]
	        // is at left of handleEnds[1] for non-cross case.
	        return {span: Math.abs(dist), sign: dist > 0 ? -1 : dist < 0 ? 1 : handleIndex ? -1 : 1};
	    }

	    function restrict(value, extend) {
	        return Math.min(extend[1], Math.max(extend[0], value));
	    }


/***/ },
/* 240 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);
	    var Component = __webpack_require__(69);

	    __webpack_require__(241);

	    Component.extend({

	        type: 'parallel',

	        dependencies: ['parallelAxis'],

	        /**
	         * @type {module:echarts/coord/parallel/Parallel}
	         */
	        coordinateSystem: null,

	        /**
	         * Each item like: 'dim0', 'dim1', 'dim2', ...
	         * @type {Array.<string>}
	         * @readOnly
	         */
	        dimensions: null,

	        /**
	         * Coresponding to dimensions.
	         * @type {Array.<number>}
	         * @readOnly
	         */
	        parallelAxisIndex: null,

	        layoutMode: 'box',

	        defaultOption: {
	            zlevel: 0,
	            z: 0,
	            left: 80,
	            top: 60,
	            right: 80,
	            bottom: 60,
	            // width: {totalWidth} - left - right,
	            // height: {totalHeight} - top - bottom,

	            layout: 'horizontal',      // 'horizontal' or 'vertical'

	            // FIXME
	            // naming?
	            axisExpandable: false,
	            axisExpandCenter: null,
	            axisExpandCount: 0,
	            axisExpandWidth: 50,      // FIXME '10%' ?
	            axisExpandRate: 17,
	            axisExpandDebounce: 50,
	            // [out, in, jumpTarget]. In percentage. If use [null, 0.05], null means full.
	            // Do not doc to user until necessary.
	            axisExpandSlideTriggerArea: [-0.15, 0.05, 0.4],
	            axisExpandTriggerOn: 'click', // 'mousemove' or 'click'

	            parallelAxisDefault: null
	        },

	        /**
	         * @override
	         */
	        init: function () {
	            Component.prototype.init.apply(this, arguments);

	            this.mergeOption({});
	        },

	        /**
	         * @override
	         */
	        mergeOption: function (newOption) {
	            var thisOption = this.option;

	            newOption && zrUtil.merge(thisOption, newOption, true);

	            this._initDimensions();
	        },

	        /**
	         * Whether series or axis is in this coordinate system.
	         * @param {module:echarts/model/Series|module:echarts/coord/parallel/AxisModel} model
	         * @param {module:echarts/model/Global} ecModel
	         */
	        contains: function (model, ecModel) {
	            var parallelIndex = model.get('parallelIndex');
	            return parallelIndex != null
	                && ecModel.getComponent('parallel', parallelIndex) === this;
	        },

	        setAxisExpand: function (opt) {
	            zrUtil.each(
	                ['axisExpandable', 'axisExpandCenter', 'axisExpandCount', 'axisExpandWidth', 'axisExpandWindow'],
	                function (name) {
	                    if (opt.hasOwnProperty(name)) {
	                        this.option[name] = opt[name];
	                    }
	                },
	                this
	            );
	        },

	        /**
	         * @private
	         */
	        _initDimensions: function () {
	            var dimensions = this.dimensions = [];
	            var parallelAxisIndex = this.parallelAxisIndex = [];

	            var axisModels = zrUtil.filter(this.dependentModels.parallelAxis, function (axisModel) {
	                // Can not use this.contains here, because
	                // initialization has not been completed yet.
	                return axisModel.get('parallelIndex') === this.componentIndex;
	            });

	            zrUtil.each(axisModels, function (axisModel) {
	                dimensions.push('dim' + axisModel.get('dim'));
	                parallelAxisIndex.push(axisModel.componentIndex);
	            });
	        }

	    });



/***/ },
/* 241 */
/***/ function(module, exports, __webpack_require__) {

	

	    var ComponentModel = __webpack_require__(69);
	    var zrUtil = __webpack_require__(4);
	    var makeStyleMapper = __webpack_require__(15);
	    var axisModelCreator = __webpack_require__(131);
	    var numberUtil = __webpack_require__(7);

	    var AxisModel = ComponentModel.extend({

	        type: 'baseParallelAxis',

	        /**
	         * @type {module:echarts/coord/parallel/Axis}
	         */
	        axis: null,

	        /**
	         * @type {Array.<Array.<number>}
	         * @readOnly
	         */
	        activeIntervals: [],

	        /**
	         * @return {Object}
	         */
	        getAreaSelectStyle: function () {
	            return makeStyleMapper(
	                [
	                    ['fill', 'color'],
	                    ['lineWidth', 'borderWidth'],
	                    ['stroke', 'borderColor'],
	                    ['width', 'width'],
	                    ['opacity', 'opacity']
	                ]
	            ).call(this.getModel('areaSelectStyle'));
	        },

	        /**
	         * The code of this feature is put on AxisModel but not ParallelAxis,
	         * because axisModel can be alive after echarts updating but instance of
	         * ParallelAxis having been disposed. this._activeInterval should be kept
	         * when action dispatched (i.e. legend click).
	         *
	         * @param {Array.<Array<number>>} intervals interval.length === 0
	         *                                          means set all active.
	         * @public
	         */
	        setActiveIntervals: function (intervals) {
	            var activeIntervals = this.activeIntervals = zrUtil.clone(intervals);

	            // Normalize
	            if (activeIntervals) {
	                for (var i = activeIntervals.length - 1; i >= 0; i--) {
	                    numberUtil.asc(activeIntervals[i]);
	                }
	            }
	        },

	        /**
	         * @param {number|string} [value] When attempting to detect 'no activeIntervals set',
	         *                         value can not be input.
	         * @return {string} 'normal': no activeIntervals set,
	         *                  'active',
	         *                  'inactive'.
	         * @public
	         */
	        getActiveState: function (value) {
	            var activeIntervals = this.activeIntervals;

	            if (!activeIntervals.length) {
	                return 'normal';
	            }

	            if (value == null) {
	                return 'inactive';
	            }

	            for (var i = 0, len = activeIntervals.length; i < len; i++) {
	                if (activeIntervals[i][0] <= value && value <= activeIntervals[i][1]) {
	                    return 'active';
	                }
	            }
	            return 'inactive';
	        }

	    });

	    var defaultOption = {

	        type: 'value',

	        /**
	         * @type {Array.<number>}
	         */
	        dim: null, // 0, 1, 2, ...

	        // parallelIndex: null,

	        areaSelectStyle: {
	            width: 20,
	            borderWidth: 1,
	            borderColor: 'rgba(160,197,232)',
	            color: 'rgba(160,197,232)',
	            opacity: 0.3
	        },

	        realtime: true, // Whether realtime update view when select.

	        z: 10
	    };

	    zrUtil.merge(AxisModel.prototype, __webpack_require__(112));

	    function getAxisType(axisName, option) {
	        return option.type || (option.data ? 'category' : 'value');
	    }

	    axisModelCreator('parallel', AxisModel, getAxisType, defaultOption);

	    module.exports = AxisModel;


/***/ },
/* 242 */
/***/ function(module, exports, __webpack_require__) {

	

	    __webpack_require__(236);
	    __webpack_require__(243);
	    __webpack_require__(244);



/***/ },
/* 243 */
/***/ function(module, exports, __webpack_require__) {

	

	    var echarts = __webpack_require__(1);

	    /**
	     * @payload
	     * @property {string} parallelAxisId
	     * @property {Array.<Array.<number>>} intervals
	     */
	    var actionInfo = {
	        type: 'axisAreaSelect',
	        event: 'axisAreaSelected',
	        update: 'updateVisual'
	    };
	    echarts.registerAction(actionInfo, function (payload, ecModel) {
	        ecModel.eachComponent(
	            {mainType: 'parallelAxis', query: payload},
	            function (parallelAxisModel) {
	                parallelAxisModel.axis.model.setActiveIntervals(payload.intervals);
	            }
	        );
	    });

	    /**
	     * @payload
	     */
	    echarts.registerAction('parallelAxisExpand', function (payload, ecModel) {
	        ecModel.eachComponent(
	            {mainType: 'parallel', query: payload},
	            function (parallelModel) {
	                parallelModel.setAxisExpand(payload);
	            }
	        );

	    });


/***/ },
/* 244 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);
	    var AxisBuilder = __webpack_require__(135);
	    var BrushController = __webpack_require__(245);
	    var brushHelper = __webpack_require__(246);
	    var graphic = __webpack_require__(18);

	    var elementList = ['axisLine', 'axisLabel', 'axisTick', 'axisName'];

	    var AxisView = __webpack_require__(1).extendComponentView({

	        type: 'parallelAxis',

	        /**
	         * @override
	         */
	        init: function (ecModel, api) {
	            AxisView.superApply(this, 'init', arguments);

	            /**
	             * @type {module:echarts/component/helper/BrushController}
	             */
	            (this._brushController = new BrushController(api.getZr()))
	                .on('brush', zrUtil.bind(this._onBrush, this));
	        },

	        /**
	         * @override
	         */
	        render: function (axisModel, ecModel, api, payload) {
	            if (fromAxisAreaSelect(axisModel, ecModel, payload)) {
	                return;
	            }

	            this.axisModel = axisModel;
	            this.api = api;

	            this.group.removeAll();

	            var oldAxisGroup = this._axisGroup;
	            this._axisGroup = new graphic.Group();
	            this.group.add(this._axisGroup);

	            if (!axisModel.get('show')) {
	                return;
	            }

	            var coordSysModel = getCoordSysModel(axisModel, ecModel);
	            var coordSys = coordSysModel.coordinateSystem;

	            var areaSelectStyle = axisModel.getAreaSelectStyle();
	            var areaWidth = areaSelectStyle.width;

	            var dim = axisModel.axis.dim;
	            var axisLayout = coordSys.getAxisLayout(dim);

	            var builderOpt = zrUtil.extend(
	                {strokeContainThreshold: areaWidth},
	                axisLayout
	            );

	            var axisBuilder = new AxisBuilder(axisModel, builderOpt);

	            zrUtil.each(elementList, axisBuilder.add, axisBuilder);

	            this._axisGroup.add(axisBuilder.getGroup());

	            this._refreshBrushController(
	                builderOpt, areaSelectStyle, axisModel, coordSysModel, areaWidth, api
	            );

	            var animationModel = (payload && payload.animation === false) ? null : axisModel;
	            graphic.groupTransition(oldAxisGroup, this._axisGroup, animationModel);
	        },

	        /**
	         * @override
	         */
	        updateVisual: function (axisModel, ecModel, api, payload) {
	            this._brushController && this._brushController
	                .updateCovers(getCoverInfoList(axisModel));
	        },

	        _refreshBrushController: function (
	            builderOpt, areaSelectStyle, axisModel, coordSysModel, areaWidth, api
	        ) {
	            // After filtering, axis may change, select area needs to be update.
	            var extent = axisModel.axis.getExtent();
	            var extentLen = extent[1] - extent[0];
	            var extra = Math.min(30, Math.abs(extentLen) * 0.1); // Arbitrary value.

	            // width/height might be negative, which will be
	            // normalized in BoundingRect.
	            var rect = graphic.BoundingRect.create({
	                x: extent[0],
	                y: -areaWidth / 2,
	                width: extentLen,
	                height: areaWidth
	            });
	            rect.x -= extra;
	            rect.width += 2 * extra;

	            this._brushController
	                .mount({
	                    enableGlobalPan: true,
	                    rotation: builderOpt.rotation,
	                    position: builderOpt.position
	                })
	                .setPanels([{
	                    panelId: 'pl',
	                    clipPath: brushHelper.makeRectPanelClipPath(rect),
	                    isTargetByCursor: brushHelper.makeRectIsTargetByCursor(rect, api, coordSysModel),
	                    getLinearBrushOtherExtent: brushHelper.makeLinearBrushOtherExtent(rect, 0)
	                }])
	                .enableBrush({
	                    brushType: 'lineX',
	                    brushStyle: areaSelectStyle,
	                    removeOnClick: true
	                })
	                .updateCovers(getCoverInfoList(axisModel));
	        },

	        _onBrush: function (coverInfoList, opt) {
	            // Do not cache these object, because the mey be changed.
	            var axisModel = this.axisModel;
	            var axis = axisModel.axis;
	            var intervals = zrUtil.map(coverInfoList, function (coverInfo) {
	                return [
	                    axis.coordToData(coverInfo.range[0], true),
	                    axis.coordToData(coverInfo.range[1], true)
	                ];
	            });

	            // If realtime is true, action is not dispatched on drag end, because
	            // the drag end emits the same params with the last drag move event,
	            // and may have some delay when using touch pad.
	            if (!axisModel.option.realtime === opt.isEnd || opt.removeOnClick) { // jshint ignore:line
	                this.api.dispatchAction({
	                    type: 'axisAreaSelect',
	                    parallelAxisId: axisModel.id,
	                    intervals: intervals
	                });
	            }
	        },

	        /**
	         * @override
	         */
	        dispose: function () {
	            this._brushController.dispose();
	        }
	    });

	    function fromAxisAreaSelect(axisModel, ecModel, payload) {
	        return payload
	            && payload.type === 'axisAreaSelect'
	            && ecModel.findComponents(
	                {mainType: 'parallelAxis', query: payload}
	            )[0] === axisModel;
	    }

	    function getCoverInfoList(axisModel) {
	        var axis = axisModel.axis;
	        return zrUtil.map(axisModel.activeIntervals, function (interval) {
	            return {
	                brushType: 'lineX',
	                panelId: 'pl',
	                range: [
	                    axis.dataToCoord(interval[0], true),
	                    axis.dataToCoord(interval[1], true)
	                ]
	            };
	        });
	    }

	    function getCoordSysModel(axisModel, ecModel) {
	        return ecModel.getComponent(
	            'parallel', axisModel.get('parallelIndex')
	        );
	    }

	    module.exports = AxisView;


/***/ },
/* 245 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * Box selection tool.
	 *
	 * @module echarts/component/helper/BrushController
	 */



	    var Eventful = __webpack_require__(25);
	    var zrUtil = __webpack_require__(4);
	    var graphic = __webpack_require__(18);
	    var interactionMutex = __webpack_require__(184);
	    var DataDiffer = __webpack_require__(99);

	    var curry = zrUtil.curry;
	    var each = zrUtil.each;
	    var map = zrUtil.map;
	    var mathMin = Math.min;
	    var mathMax = Math.max;
	    var mathPow = Math.pow;

	    var COVER_Z = 10000;
	    var UNSELECT_THRESHOLD = 6;
	    var MIN_RESIZE_LINE_WIDTH = 6;
	    var MUTEX_RESOURCE_KEY = 'globalPan';

	    var DIRECTION_MAP = {
	        w: [0, 0],
	        e: [0, 1],
	        n: [1, 0],
	        s: [1, 1]
	    };
	    var CURSOR_MAP = {
	        w: 'ew',
	        e: 'ew',
	        n: 'ns',
	        s: 'ns',
	        ne: 'nesw',
	        sw: 'nesw',
	        nw: 'nwse',
	        se: 'nwse'
	    };
	    var DEFAULT_BRUSH_OPT = {
	        brushStyle: {
	            lineWidth: 2,
	            stroke: 'rgba(0,0,0,0.3)',
	            fill: 'rgba(0,0,0,0.1)'
	        },
	        transformable: true,
	        brushMode: 'single',
	        removeOnClick: false
	    };

	    var baseUID = 0;

	    /**
	     * @alias module:echarts/component/helper/BrushController
	     * @constructor
	     * @mixin {module:zrender/mixin/Eventful}
	     * @event module:echarts/component/helper/BrushController#brush
	     *        params:
	     *            areas: Array.<Array>, coord relates to container group,
	     *                                    If no container specified, to global.
	     *            opt {
	     *                isEnd: boolean,
	     *                removeOnClick: boolean
	     *            }
	     *
	     * @param {module:zrender/zrender~ZRender} zr
	     */
	    function BrushController(zr) {

	        if (true) {
	            zrUtil.assert(zr);
	        }

	        Eventful.call(this);

	        /**
	         * @type {module:zrender/zrender~ZRender}
	         * @private
	         */
	        this._zr = zr;

	        /**
	         * @type {module:zrender/container/Group}
	         * @readOnly
	         */
	        this.group = new graphic.Group();

	        /**
	         * Only for drawing (after enabledBrush).
	         *     'line', 'rect', 'polygon' or false
	         *     If passing false/null/undefined, disable brush.
	         *     If passing 'auto', determined by panel.defaultBrushType
	         * @private
	         * @type {string}
	         */
	        this._brushType;

	        /**
	         * Only for drawing (after enabledBrush).
	         *
	         * @private
	         * @type {Object}
	         */
	        this._brushOption;

	        /**
	         * @private
	         * @type {Object}
	         */
	        this._panels;

	        /**
	         * @private
	         * @type {Array.<nubmer>}
	         */
	        this._track = [];

	        /**
	         * @private
	         * @type {boolean}
	         */
	        this._dragging;

	        /**
	         * @private
	         * @type {Array}
	         */
	        this._covers = [];

	        /**
	         * @private
	         * @type {moudule:zrender/container/Group}
	         */
	        this._creatingCover;

	        /**
	         * `true` means global panel
	         * @private
	         * @type {module:zrender/container/Group|boolean}
	         */
	        this._creatingPanel;

	        /**
	         * @private
	         * @type {boolean}
	         */
	        this._enableGlobalPan;

	        /**
	         * @private
	         * @type {boolean}
	         */
	        if (true) {
	            this._mounted;
	        }

	        /**
	         * @private
	         * @type {string}
	         */
	        this._uid = 'brushController_' + baseUID++;

	        /**
	         * @private
	         * @type {Object}
	         */
	        this._handlers = {};
	        each(mouseHandlers, function (handler, eventName) {
	            this._handlers[eventName] = zrUtil.bind(handler, this);
	        }, this);
	    }

	    BrushController.prototype = {

	        constructor: BrushController,

	        /**
	         * If set to null/undefined/false, select disabled.
	         * @param {Object} brushOption
	         * @param {string|boolean} brushOption.brushType 'line', 'rect', 'polygon' or false
	         *                          If passing false/null/undefined, disable brush.
	         *                          If passing 'auto', determined by panel.defaultBrushType.
	         *                              ('auto' can not be used in global panel)
	         * @param {number} [brushOption.brushMode='single'] 'single' or 'multiple'
	         * @param {boolean} [brushOption.transformable=true]
	         * @param {boolean} [brushOption.removeOnClick=false]
	         * @param {Object} [brushOption.brushStyle]
	         * @param {number} [brushOption.brushStyle.width]
	         * @param {number} [brushOption.brushStyle.lineWidth]
	         * @param {string} [brushOption.brushStyle.stroke]
	         * @param {string} [brushOption.brushStyle.fill]
	         * @param {number} [brushOption.z]
	         */
	        enableBrush: function (brushOption) {
	            if (true) {
	                zrUtil.assert(this._mounted);
	            }

	            this._brushType && doDisableBrush(this);
	            brushOption.brushType && doEnableBrush(this, brushOption);

	            return this;
	        },

	        /**
	         * @param {Array.<Object>} panelOpts If not pass, it is global brush.
	         *        Each items: {
	         *            panelId, // mandatory.
	         *            clipPath, // mandatory. function.
	         *            isTargetByCursor, // mandatory. function.
	         *            defaultBrushType, // optional, only used when brushType is 'auto'.
	         *            getLinearBrushOtherExtent, // optional. function.
	         *        }
	         */
	        setPanels: function (panelOpts) {
	            if (panelOpts && panelOpts.length) {
	                var panels = this._panels = {};
	                zrUtil.each(panelOpts, function (panelOpts) {
	                    panels[panelOpts.panelId] = zrUtil.clone(panelOpts);
	                });
	            }
	            else {
	                this._panels = null;
	            }
	            return this;
	        },

	        /**
	         * @param {Object} [opt]
	         * @return {boolean} [opt.enableGlobalPan=false]
	         */
	        mount: function (opt) {
	            opt = opt || {};

	            if (true) {
	                this._mounted = true; // should be at first.
	            }

	            this._enableGlobalPan = opt.enableGlobalPan;

	            var thisGroup = this.group;
	            this._zr.add(thisGroup);

	            thisGroup.attr({
	                position: opt.position || [0, 0],
	                rotation: opt.rotation || 0,
	                scale: opt.scale || [1, 1]
	            });
	            this._transform = thisGroup.getLocalTransform();

	            return this;
	        },

	        eachCover: function (cb, context) {
	            each(this._covers, cb, context);
	        },

	        /**
	         * Update covers.
	         * @param {Array.<Object>} brushOptionList Like:
	         *        [
	         *            {id: 'xx', brushType: 'line', range: [23, 44], brushStyle, transformable},
	         *            {id: 'yy', brushType: 'rect', range: [[23, 44], [23, 54]]},
	         *            ...
	         *        ]
	         *        `brushType` is required in each cover info. (can not be 'auto')
	         *        `id` is not mandatory.
	         *        `brushStyle`, `transformable` is not mandatory, use DEFAULT_BRUSH_OPT by default.
	         *        If brushOptionList is null/undefined, all covers removed.
	         */
	        updateCovers: function (brushOptionList) {
	            if (true) {
	                zrUtil.assert(this._mounted);
	            }

	            brushOptionList = zrUtil.map(brushOptionList, function (brushOption) {
	                return zrUtil.merge(zrUtil.clone(DEFAULT_BRUSH_OPT), brushOption, true);
	            });

	            var tmpIdPrefix = '\0-brush-index-';
	            var oldCovers = this._covers;
	            var newCovers = this._covers = [];
	            var controller = this;
	            var creatingCover = this._creatingCover;

	            (new DataDiffer(oldCovers, brushOptionList, oldGetKey, getKey))
	                .add(addOrUpdate)
	                .update(addOrUpdate)
	                .remove(remove)
	                .execute();

	            return this;

	            function getKey(brushOption, index) {
	                return (brushOption.id != null ? brushOption.id : tmpIdPrefix + index)
	                    + '-' + brushOption.brushType;
	            }

	            function oldGetKey(cover, index) {
	                return getKey(cover.__brushOption, index);
	            }

	            function addOrUpdate(newIndex, oldIndex) {
	                var newBrushOption = brushOptionList[newIndex];
	                // Consider setOption in event listener of brushSelect,
	                // where updating cover when creating should be forbiden.
	                if (oldIndex != null && oldCovers[oldIndex] === creatingCover) {
	                    newCovers[newIndex] = oldCovers[oldIndex];
	                }
	                else {
	                    var cover = newCovers[newIndex] = oldIndex != null
	                        ? (
	                            oldCovers[oldIndex].__brushOption = newBrushOption,
	                            oldCovers[oldIndex]
	                        )
	                        : endCreating(controller, createCover(controller, newBrushOption));
	                    updateCoverAfterCreation(controller, cover);
	                }
	            }

	            function remove(oldIndex) {
	                if (oldCovers[oldIndex] !== creatingCover) {
	                    controller.group.remove(oldCovers[oldIndex]);
	                }
	            }
	        },

	        unmount: function () {
	            if (true) {
	                if (!this._mounted) {
	                    return;
	                }
	            }

	            this.enableBrush(false);

	            // container may 'removeAll' outside.
	            clearCovers(this);
	            this._zr.remove(this.group);

	            if (true) {
	                this._mounted = false; // should be at last.
	            }

	            return this;
	        },

	        dispose: function () {
	            this.unmount();
	            this.off();
	        }
	    };

	    zrUtil.mixin(BrushController, Eventful);

	    function doEnableBrush(controller, brushOption) {
	        var zr = controller._zr;

	        // Consider roam, which takes globalPan too.
	        if (!controller._enableGlobalPan) {
	            interactionMutex.take(zr, MUTEX_RESOURCE_KEY, controller._uid);
	        }

	        each(controller._handlers, function (handler, eventName) {
	            zr.on(eventName, handler);
	        });

	        controller._brushType = brushOption.brushType;
	        controller._brushOption = zrUtil.merge(zrUtil.clone(DEFAULT_BRUSH_OPT), brushOption, true);
	    }

	    function doDisableBrush(controller) {
	        var zr = controller._zr;

	        interactionMutex.release(zr, MUTEX_RESOURCE_KEY, controller._uid);

	        each(controller._handlers, function (handler, eventName) {
	            zr.off(eventName, handler);
	        });

	        controller._brushType = controller._brushOption = null;
	    }

	    function createCover(controller, brushOption) {
	        var cover = coverRenderers[brushOption.brushType].createCover(controller, brushOption);
	        cover.__brushOption = brushOption;
	        updateZ(cover, brushOption);
	        controller.group.add(cover);
	        return cover;
	    }

	    function endCreating(controller, creatingCover) {
	        var coverRenderer = getCoverRenderer(creatingCover);
	        if (coverRenderer.endCreating) {
	            coverRenderer.endCreating(controller, creatingCover);
	            updateZ(creatingCover, creatingCover.__brushOption);
	        }
	        return creatingCover;
	    }

	    function updateCoverShape(controller, cover) {
	        var brushOption = cover.__brushOption;
	        getCoverRenderer(cover).updateCoverShape(
	            controller, cover, brushOption.range, brushOption
	        );
	    }

	    function updateZ(cover, brushOption) {
	        var z = brushOption.z;
	        z == null && (z = COVER_Z);
	        cover.traverse(function (el) {
	            el.z = z;
	            el.z2 = z; // Consider in given container.
	        });
	    }

	    function updateCoverAfterCreation(controller, cover) {
	        getCoverRenderer(cover).updateCommon(controller, cover);
	        updateCoverShape(controller, cover);
	    }

	    function getCoverRenderer(cover) {
	        return coverRenderers[cover.__brushOption.brushType];
	    }

	    // return target panel or `true` (means global panel)
	    function getPanelByPoint(controller, e, localCursorPoint) {
	        var panels = controller._panels;
	        if (!panels) {
	            return true; // Global panel
	        }
	        var panel;
	        var transform = controller._transform;
	        each(panels, function (pn) {
	            pn.isTargetByCursor(e, localCursorPoint, transform) && (panel = pn);
	        });
	        return panel;
	    }

	    // Return a panel or true
	    function getPanelByCover(controller, cover) {
	        var panels = controller._panels;
	        if (!panels) {
	            return true; // Global panel
	        }
	        var panelId = cover.__brushOption.panelId;
	        // User may give cover without coord sys info,
	        // which is then treated as global panel.
	        return panelId != null ? panels[panelId] : true;
	    }

	    function clearCovers(controller) {
	        var covers = controller._covers;
	        var originalLength = covers.length;
	        each(covers, function (cover) {
	            controller.group.remove(cover);
	        }, controller);
	        covers.length = 0;

	        return !!originalLength;
	    }

	    function trigger(controller, opt) {
	        var areas = map(controller._covers, function (cover) {
	            var brushOption = cover.__brushOption;
	            var range = zrUtil.clone(brushOption.range);
	            return {
	                brushType: brushOption.brushType,
	                panelId: brushOption.panelId,
	                range: range
	            };
	        });

	        controller.trigger('brush', areas, {
	            isEnd: !!opt.isEnd,
	            removeOnClick: !!opt.removeOnClick
	        });
	    }

	    function shouldShowCover(controller) {
	        var track = controller._track;

	        if (!track.length) {
	            return false;
	        }

	        var p2 = track[track.length - 1];
	        var p1 = track[0];
	        var dx = p2[0] - p1[0];
	        var dy = p2[1] - p1[1];
	        var dist = mathPow(dx * dx + dy * dy, 0.5);

	        return dist > UNSELECT_THRESHOLD;
	    }

	    function getTrackEnds(track) {
	        var tail = track.length - 1;
	        tail < 0 && (tail = 0);
	        return [track[0], track[tail]];
	    }

	    function createBaseRectCover(doDrift, controller, brushOption, edgeNames) {
	        var cover = new graphic.Group();

	        cover.add(new graphic.Rect({
	            name: 'main',
	            style: makeStyle(brushOption),
	            silent: true,
	            draggable: true,
	            cursor: 'move',
	            drift: curry(doDrift, controller, cover, 'nswe'),
	            ondragend: curry(trigger, controller, {isEnd: true})
	        }));

	        each(
	            edgeNames,
	            function (name) {
	                cover.add(new graphic.Rect({
	                    name: name,
	                    style: {opacity: 0},
	                    draggable: true,
	                    silent: true,
	                    invisible: true,
	                    drift: curry(doDrift, controller, cover, name),
	                    ondragend: curry(trigger, controller, {isEnd: true})
	                }));
	            }
	        );

	        return cover;
	    }

	    function updateBaseRect(controller, cover, localRange, brushOption) {
	        var lineWidth = brushOption.brushStyle.lineWidth || 0;
	        var handleSize = mathMax(lineWidth, MIN_RESIZE_LINE_WIDTH);
	        var x = localRange[0][0];
	        var y = localRange[1][0];
	        var xa = x - lineWidth / 2;
	        var ya = y - lineWidth / 2;
	        var x2 = localRange[0][1];
	        var y2 = localRange[1][1];
	        var x2a = x2 - handleSize + lineWidth / 2;
	        var y2a = y2 - handleSize + lineWidth / 2;
	        var width = x2 - x;
	        var height = y2 - y;
	        var widtha = width + lineWidth;
	        var heighta = height + lineWidth;

	        updateRectShape(controller, cover, 'main', x, y, width, height);

	        if (brushOption.transformable) {
	            updateRectShape(controller, cover, 'w', xa, ya, handleSize, heighta);
	            updateRectShape(controller, cover, 'e', x2a, ya, handleSize, heighta);
	            updateRectShape(controller, cover, 'n', xa, ya, widtha, handleSize);
	            updateRectShape(controller, cover, 's', xa, y2a, widtha, handleSize);

	            updateRectShape(controller, cover, 'nw', xa, ya, handleSize, handleSize);
	            updateRectShape(controller, cover, 'ne', x2a, ya, handleSize, handleSize);
	            updateRectShape(controller, cover, 'sw', xa, y2a, handleSize, handleSize);
	            updateRectShape(controller, cover, 'se', x2a, y2a, handleSize, handleSize);
	        }
	    }

	    function updateCommon(controller, cover) {
	        var brushOption = cover.__brushOption;
	        var transformable = brushOption.transformable;

	        var mainEl = cover.childAt(0);
	        mainEl.useStyle(makeStyle(brushOption));
	        mainEl.attr({
	            silent: !transformable,
	            cursor: transformable ? 'move' : 'default'
	        });

	        each(
	            ['w', 'e', 'n', 's', 'se', 'sw', 'ne', 'nw'],
	            function (name) {
	                var el = cover.childOfName(name);
	                var globalDir = getGlobalDirection(controller, name);

	                el && el.attr({
	                    silent: !transformable,
	                    invisible: !transformable,
	                    cursor: transformable ? CURSOR_MAP[globalDir] + '-resize' : null
	                });
	            }
	        );
	    }

	    function updateRectShape(controller, cover, name, x, y, w, h) {
	        var el = cover.childOfName(name);
	        el && el.setShape(pointsToRect(
	            clipByPanel(controller, cover, [[x, y], [x + w, y + h]])
	        ));
	    }

	    function makeStyle(brushOption) {
	        return zrUtil.defaults({strokeNoScale: true}, brushOption.brushStyle);
	    }

	    function formatRectRange(x, y, x2, y2) {
	        var min = [mathMin(x, x2), mathMin(y, y2)];
	        var max = [mathMax(x, x2), mathMax(y, y2)];

	        return [
	            [min[0], max[0]], // x range
	            [min[1], max[1]] // y range
	        ];
	    }

	    function getTransform(controller) {
	        return graphic.getTransform(controller.group);
	    }

	    function getGlobalDirection(controller, localDirection) {
	        if (localDirection.length > 1) {
	            localDirection = localDirection.split('');
	            var globalDir = [
	                getGlobalDirection(controller, localDirection[0]),
	                getGlobalDirection(controller, localDirection[1])
	            ];
	            (globalDir[0] === 'e' || globalDir[0] === 'w') && globalDir.reverse();
	            return globalDir.join('');
	        }
	        else {
	            var map = {w: 'left', e: 'right', n: 'top', s: 'bottom'};
	            var inverseMap = {left: 'w', right: 'e', top: 'n', bottom: 's'};
	            var globalDir = graphic.transformDirection(
	                map[localDirection], getTransform(controller)
	            );
	            return inverseMap[globalDir];
	        }
	    }

	    function driftRect(toRectRange, fromRectRange, controller, cover, name, dx, dy, e) {
	        var brushOption = cover.__brushOption;
	        var rectRange = toRectRange(brushOption.range);
	        var localDelta = toLocalDelta(controller, dx, dy);

	        each(name.split(''), function (namePart) {
	            var ind = DIRECTION_MAP[namePart];
	            rectRange[ind[0]][ind[1]] += localDelta[ind[0]];
	        });

	        brushOption.range = fromRectRange(formatRectRange(
	            rectRange[0][0], rectRange[1][0], rectRange[0][1], rectRange[1][1]
	        ));

	        updateCoverAfterCreation(controller, cover);
	        trigger(controller, {isEnd: false});
	    }

	    function driftPolygon(controller, cover, dx, dy, e) {
	        var range = cover.__brushOption.range;
	        var localDelta = toLocalDelta(controller, dx, dy);

	        each(range, function (point) {
	            point[0] += localDelta[0];
	            point[1] += localDelta[1];
	        });

	        updateCoverAfterCreation(controller, cover);
	        trigger(controller, {isEnd: false});
	    }

	    function toLocalDelta(controller, dx, dy) {
	        var thisGroup = controller.group;
	        var localD = thisGroup.transformCoordToLocal(dx, dy);
	        var localZero = thisGroup.transformCoordToLocal(0, 0);

	        return [localD[0] - localZero[0], localD[1] - localZero[1]];
	    }

	    function clipByPanel(controller, cover, data) {
	        var panel = getPanelByCover(controller, cover);

	        return (panel && panel !== true)
	            ? panel.clipPath(data, controller._transform)
	            : zrUtil.clone(data);
	    }

	    function pointsToRect(points) {
	        var xmin = mathMin(points[0][0], points[1][0]);
	        var ymin = mathMin(points[0][1], points[1][1]);
	        var xmax = mathMax(points[0][0], points[1][0]);
	        var ymax = mathMax(points[0][1], points[1][1]);

	        return {
	            x: xmin,
	            y: ymin,
	            width: xmax - xmin,
	            height: ymax - ymin
	        };
	    }

	    function resetCursor(controller, e, localCursorPoint) {
	        // Check active
	        if (!controller._brushType) {
	            return;
	        }

	        var zr = controller._zr;
	        var covers = controller._covers;
	        var currPanel = getPanelByPoint(controller, e, localCursorPoint);

	        // Check whether in covers.
	        if (!controller._dragging) {
	            for (var i = 0; i < covers.length; i++) {
	                var brushOption = covers[i].__brushOption;
	                if (currPanel
	                    && (currPanel === true || brushOption.panelId === currPanel.panelId)
	                    && coverRenderers[brushOption.brushType].contain(
	                        covers[i], localCursorPoint[0], localCursorPoint[1]
	                    )
	                ) {
	                    // Use cursor style set on cover.
	                    return;
	                }
	            }
	        }

	        currPanel && zr.setCursorStyle('crosshair');
	    }

	    function preventDefault(e) {
	        var rawE = e.event;
	        rawE.preventDefault && rawE.preventDefault();
	    }

	    function mainShapeContain(cover, x, y) {
	        return cover.childOfName('main').contain(x, y);
	    }

	    function updateCoverByMouse(controller, e, localCursorPoint, isEnd) {
	        var creatingCover = controller._creatingCover;
	        var panel = controller._creatingPanel;
	        var thisBrushOption = controller._brushOption;
	        var eventParams;

	        controller._track.push(localCursorPoint.slice());

	        if (shouldShowCover(controller) || creatingCover) {

	            if (panel && !creatingCover) {
	                thisBrushOption.brushMode === 'single' && clearCovers(controller);
	                var brushOption = zrUtil.clone(thisBrushOption);
	                brushOption.brushType = determineBrushType(brushOption.brushType, panel);
	                brushOption.panelId = panel === true ? null : panel.panelId;
	                creatingCover = controller._creatingCover = createCover(controller, brushOption);
	                controller._covers.push(creatingCover);
	            }

	            if (creatingCover) {
	                var coverRenderer = coverRenderers[determineBrushType(controller._brushType, panel)];
	                var coverBrushOption = creatingCover.__brushOption;

	                coverBrushOption.range = coverRenderer.getCreatingRange(
	                    clipByPanel(controller, creatingCover, controller._track)
	                );

	                if (isEnd) {
	                    endCreating(controller, creatingCover);
	                    coverRenderer.updateCommon(controller, creatingCover);
	                }

	                updateCoverShape(controller, creatingCover);

	                eventParams = {isEnd: isEnd};
	            }
	        }
	        else if (
	            isEnd
	            && thisBrushOption.brushMode === 'single'
	            && thisBrushOption.removeOnClick
	        ) {
	            // Help user to remove covers easily, only by a tiny drag, in 'single' mode.
	            // But a single click do not clear covers, because user may have casual
	            // clicks (for example, click on other component and do not expect covers
	            // disappear).
	            // Only some cover removed, trigger action, but not every click trigger action.
	            if (getPanelByPoint(controller, e, localCursorPoint) && clearCovers(controller)) {
	                eventParams = {isEnd: isEnd, removeOnClick: true};
	            }
	        }

	        return eventParams;
	    }

	    function determineBrushType(brushType, panel) {
	        if (brushType === 'auto') {
	            if (true) {
	                zrUtil.assert(
	                    panel && panel.defaultBrushType,
	                    'MUST have defaultBrushType when brushType is "atuo"'
	                );
	            }
	            return panel.defaultBrushType;
	        }
	        return brushType;
	    }

	    var mouseHandlers = {

	        mousedown: function (e) {
	            if (this._dragging) {
	                // In case some browser do not support globalOut,
	                // and release mose out side the browser.
	                handleDragEnd.call(this, e);
	            }
	            else if (!e.target || !e.target.draggable) {

	                preventDefault(e);

	                var localCursorPoint = this.group.transformCoordToLocal(e.offsetX, e.offsetY);

	                this._creatingCover = null;
	                var panel = this._creatingPanel = getPanelByPoint(this, e, localCursorPoint);

	                if (panel) {
	                    this._dragging = true;
	                    this._track = [localCursorPoint.slice()];
	                }
	            }
	        },

	        mousemove: function (e) {
	            var localCursorPoint = this.group.transformCoordToLocal(e.offsetX, e.offsetY);

	            resetCursor(this, e, localCursorPoint);

	            if (this._dragging) {

	                preventDefault(e);

	                var eventParams = updateCoverByMouse(this, e, localCursorPoint, false);

	                eventParams && trigger(this, eventParams);
	            }
	        },

	        mouseup: handleDragEnd //,

	        // FIXME
	        // in tooltip, globalout should not be triggered.
	        // globalout: handleDragEnd
	    };

	    function handleDragEnd(e) {
	        if (this._dragging) {

	            preventDefault(e);

	            var localCursorPoint = this.group.transformCoordToLocal(e.offsetX, e.offsetY);
	            var eventParams = updateCoverByMouse(this, e, localCursorPoint, true);

	            this._dragging = false;
	            this._track = [];
	            this._creatingCover = null;

	            // trigger event shoule be at final, after procedure will be nested.
	            eventParams && trigger(this, eventParams);
	        }
	    }

	    /**
	     * key: brushType
	     * @type {Object}
	     */
	    var coverRenderers = {

	        lineX: getLineRenderer(0),

	        lineY: getLineRenderer(1),

	        rect: {
	            createCover: function (controller, brushOption) {
	                return createBaseRectCover(
	                    curry(
	                        driftRect,
	                        function (range) {
	                            return range;
	                        },
	                        function (range) {
	                            return range;
	                        }
	                    ),
	                    controller,
	                    brushOption,
	                    ['w', 'e', 'n', 's', 'se', 'sw', 'ne', 'nw']
	                );
	            },
	            getCreatingRange: function (localTrack) {
	                var ends = getTrackEnds(localTrack);
	                return formatRectRange(ends[1][0], ends[1][1], ends[0][0], ends[0][1]);
	            },
	            updateCoverShape: function (controller, cover, localRange, brushOption) {
	                updateBaseRect(controller, cover, localRange, brushOption);
	            },
	            updateCommon: updateCommon,
	            contain: mainShapeContain
	        },

	        polygon: {
	            createCover: function (controller, brushOption) {
	                var cover = new graphic.Group();

	                // Do not use graphic.Polygon because graphic.Polyline do not close the
	                // border of the shape when drawing, which is a better experience for user.
	                cover.add(new graphic.Polyline({
	                    name: 'main',
	                    style: makeStyle(brushOption),
	                    silent: true
	                }));

	                return cover;
	            },
	            getCreatingRange: function (localTrack) {
	                return localTrack;
	            },
	            endCreating: function (controller, cover) {
	                cover.remove(cover.childAt(0));
	                // Use graphic.Polygon close the shape.
	                cover.add(new graphic.Polygon({
	                    name: 'main',
	                    draggable: true,
	                    drift: curry(driftPolygon, controller, cover),
	                    ondragend: curry(trigger, controller, {isEnd: true})
	                }));
	            },
	            updateCoverShape: function (controller, cover, localRange, brushOption) {
	                cover.childAt(0).setShape({
	                    points: clipByPanel(controller, cover, localRange)
	                });
	            },
	            updateCommon: updateCommon,
	            contain: mainShapeContain
	        }
	    };

	    function getLineRenderer(xyIndex) {
	        return {
	            createCover: function (controller, brushOption) {
	                return createBaseRectCover(
	                    curry(
	                        driftRect,
	                        function (range) {
	                            var rectRange = [range, [0, 100]];
	                            xyIndex && rectRange.reverse();
	                            return rectRange;
	                        },
	                        function (rectRange) {
	                            return rectRange[xyIndex];
	                        }
	                    ),
	                    controller,
	                    brushOption,
	                    [['w', 'e'], ['n', 's']][xyIndex]
	                );
	            },
	            getCreatingRange: function (localTrack) {
	                var ends = getTrackEnds(localTrack);
	                var min = mathMin(ends[0][xyIndex], ends[1][xyIndex]);
	                var max = mathMax(ends[0][xyIndex], ends[1][xyIndex]);

	                return [min, max];
	            },
	            updateCoverShape: function (controller, cover, localRange, brushOption) {
	                var otherExtent;
	                // If brushWidth not specified, fit the panel.
	                var panel = getPanelByCover(controller, cover);
	                if (panel !== true && panel.getLinearBrushOtherExtent) {
	                    otherExtent = panel.getLinearBrushOtherExtent(
	                        xyIndex, controller._transform
	                    );
	                }
	                else {
	                    var zr = controller._zr;
	                    otherExtent = [0, [zr.getWidth(), zr.getHeight()][1 - xyIndex]];
	                }
	                var rectRange = [localRange, otherExtent];
	                xyIndex && rectRange.reverse();

	                updateBaseRect(controller, cover, rectRange, brushOption);
	            },
	            updateCommon: updateCommon,
	            contain: mainShapeContain
	        };
	    }

	    module.exports = BrushController;


/***/ },
/* 246 */
/***/ function(module, exports, __webpack_require__) {

	

	    var cursorHelper = __webpack_require__(186);
	    var BoundingRect = __webpack_require__(9);
	    var graphicUtil = __webpack_require__(18);

	    var helper = {};

	    helper.makeRectPanelClipPath = function (rect) {
	        rect = normalizeRect(rect);
	        return function (localPoints, transform) {
	            return graphicUtil.clipPointsByRect(localPoints, rect);
	        };
	    };

	    helper.makeLinearBrushOtherExtent = function (rect, specifiedXYIndex) {
	        rect = normalizeRect(rect);
	        return function (xyIndex) {
	            var idx = specifiedXYIndex != null ? specifiedXYIndex : xyIndex;
	            var brushWidth = idx ? rect.width : rect.height;
	            var base = idx ? rect.x : rect.y;
	            return [base, base + (brushWidth || 0)];
	        };
	    };

	    helper.makeRectIsTargetByCursor = function (rect, api, targetModel) {
	        rect = normalizeRect(rect);
	        return function (e, localCursorPoint, transform) {
	            return rect.contain(localCursorPoint[0], localCursorPoint[1])
	                && !cursorHelper.onIrrelevantElement(e, api, targetModel);
	        };
	    };

	    // Consider width/height is negative.
	    function normalizeRect(rect) {
	        return BoundingRect.create(rect);
	    }

	    module.exports = helper;



/***/ },
/* 247 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);
	    var modelUtil = __webpack_require__(5);

	    module.exports = function (option) {
	        createParallelIfNeeded(option);
	        mergeAxisOptionFromParallel(option);
	    };

	    /**
	     * Create a parallel coordinate if not exists.
	     * @inner
	     */
	    function createParallelIfNeeded(option) {
	        if (option.parallel) {
	            return;
	        }

	        var hasParallelSeries = false;

	        zrUtil.each(option.series, function (seriesOpt) {
	            if (seriesOpt && seriesOpt.type === 'parallel') {
	                hasParallelSeries = true;
	            }
	        });

	        if (hasParallelSeries) {
	            option.parallel = [{}];
	        }
	    }

	    /**
	     * Merge aixs definition from parallel option (if exists) to axis option.
	     * @inner
	     */
	    function mergeAxisOptionFromParallel(option) {
	        var axes = modelUtil.normalizeToArray(option.parallelAxis);

	        zrUtil.each(axes, function (axisOption) {
	            if (!zrUtil.isObject(axisOption)) {
	                return;
	            }

	            var parallelIndex = axisOption.parallelIndex || 0;
	            var parallelOption = modelUtil.normalizeToArray(option.parallel)[parallelIndex];

	            if (parallelOption && parallelOption.parallelAxisDefault) {
	                zrUtil.merge(axisOption, parallelOption.parallelAxisDefault, false);
	            }
	        });
	    }



/***/ },
/* 248 */
/***/ function(module, exports, __webpack_require__) {

	

	    var List = __webpack_require__(98);
	    var zrUtil = __webpack_require__(4);
	    var SeriesModel = __webpack_require__(78);
	    var completeDimensions = __webpack_require__(110);

	    module.exports = SeriesModel.extend({

	        type: 'series.parallel',

	        dependencies: ['parallel'],

	        visualColorAccessPath: 'lineStyle.normal.color',

	        getInitialData: function (option, ecModel) {
	            var parallelModel = ecModel.getComponent(
	                'parallel', this.get('parallelIndex')
	            );
	            var parallelAxisIndices = parallelModel.parallelAxisIndex;

	            var rawData = option.data;
	            var modelDims = parallelModel.dimensions;

	            var dataDims = generateDataDims(modelDims, rawData);

	            var dataDimsInfo = zrUtil.map(dataDims, function (dim, dimIndex) {

	                var modelDimsIndex = zrUtil.indexOf(modelDims, dim);
	                var axisModel = modelDimsIndex >= 0 && ecModel.getComponent(
	                    'parallelAxis', parallelAxisIndices[modelDimsIndex]
	                );

	                if (axisModel && axisModel.get('type') === 'category') {
	                    translateCategoryValue(axisModel, dim, rawData);
	                    return {name: dim, type: 'ordinal'};
	                }
	                else if (modelDimsIndex < 0) {
	                    return completeDimensions.guessOrdinal(rawData, dimIndex)
	                        ? {name: dim, type: 'ordinal'}
	                        : dim;
	                }
	                else {
	                    return dim;
	                }
	            });

	            var list = new List(dataDimsInfo, this);
	            list.initData(rawData);

	            // Anication is forbiden in progressive data mode.
	            if (this.option.progressive) {
	                this.option.animation = false;
	            }

	            return list;
	        },

	        /**
	         * User can get data raw indices on 'axisAreaSelected' event received.
	         *
	         * @public
	         * @param {string} activeState 'active' or 'inactive' or 'normal'
	         * @return {Array.<number>} Raw indices
	         */
	        getRawIndicesByActiveState: function (activeState) {
	            var coordSys = this.coordinateSystem;
	            var data = this.getData();
	            var indices = [];

	            coordSys.eachActiveState(data, function (theActiveState, dataIndex) {
	                if (activeState === theActiveState) {
	                    indices.push(data.getRawIndex(dataIndex));
	                }
	            });

	            return indices;
	        },

	        defaultOption: {
	            zlevel: 0,                  // 一级层叠
	            z: 2,                       // 二级层叠

	            coordinateSystem: 'parallel',
	            parallelIndex: 0,

	            label: {
	                normal: {
	                    show: false
	                },
	                emphasis: {
	                    show: false
	                }
	            },

	            inactiveOpacity: 0.05,
	            activeOpacity: 1,

	            lineStyle: {
	                normal: {
	                    width: 1,
	                    opacity: 0.45,
	                    type: 'solid'
	                }
	            },
	            progressive: false, // 100
	            smooth: false,

	            animationEasing: 'linear'
	        }
	    });

	    function translateCategoryValue(axisModel, dim, rawData) {
	        var axisData = axisModel.get('data');
	        var numberDim = convertDimNameToNumber(dim);

	        if (axisData && axisData.length) {
	            zrUtil.each(rawData, function (dataItem) {
	                if (!dataItem) {
	                    return;
	                }
	                // FIXME
	                // time consuming, should use hash?
	                var index = zrUtil.indexOf(axisData, dataItem[numberDim]);
	                dataItem[numberDim] = index >= 0 ? index : NaN;
	            });
	        }
	        // FIXME
	        // 如果没有设置axis data, 应自动算出，或者提示。
	    }

	    function convertDimNameToNumber(dimName) {
	        return +dimName.replace('dim', '');
	    }

	    function generateDataDims(modelDims, rawData) {
	        // parallelModel.dimension should not be regarded as data
	        // dimensions. Consider dimensions = ['dim4', 'dim2', 'dim6'];

	        // We detect max dim by parallelModel.dimensions and fist
	        // item in rawData arbitrarily.
	        var maxDimNum = 0;
	        zrUtil.each(modelDims, function (dimName) {
	            var numberDim = convertDimNameToNumber(dimName);
	            numberDim > maxDimNum && (maxDimNum = numberDim);
	        });

	        var firstItem = rawData[0];
	        if (firstItem && firstItem.length - 1 > maxDimNum) {
	            maxDimNum = firstItem.length - 1;
	        }

	        var dataDims = [];
	        for (var i = 0; i <= maxDimNum; i++) {
	            dataDims.push('dim' + i);
	        }

	        return dataDims;
	    }


/***/ },
/* 249 */
/***/ function(module, exports, __webpack_require__) {

	

	    var graphic = __webpack_require__(18);
	    var zrUtil = __webpack_require__(4);

	    var SMOOTH = 0.3;

	    var ParallelView = __webpack_require__(80).extend({

	        type: 'parallel',

	        init: function () {

	            /**
	             * @type {module:zrender/container/Group}
	             * @private
	             */
	            this._dataGroup = new graphic.Group();

	            this.group.add(this._dataGroup);

	            /**
	             * @type {module:echarts/data/List}
	             */
	            this._data;
	        },

	        /**
	         * @override
	         */
	        render: function (seriesModel, ecModel, api, payload) {
	            this._renderForNormal(seriesModel, payload);
	            // this[
	            //     seriesModel.option.progressive
	            //         ? '_renderForProgressive'
	            //         : '_renderForNormal'
	            // ](seriesModel);
	        },

	        dispose: function () {},

	        /**
	         * @private
	         */
	        _renderForNormal: function (seriesModel, payload) {
	            var dataGroup = this._dataGroup;
	            var data = seriesModel.getData();
	            var oldData = this._data;
	            var coordSys = seriesModel.coordinateSystem;
	            var dimensions = coordSys.dimensions;
	            var option = seriesModel.option;
	            var smooth = option.smooth ? SMOOTH : null;

	            // Consider switch between progressive and not.
	            // oldData && oldData.__plProgressive && dataGroup.removeAll();

	            data.diff(oldData)
	                .add(add)
	                .update(update)
	                .remove(remove)
	                .execute();

	            // Update style
	            updateElCommon(data, smooth);

	            // First create
	            if (!this._data) {
	                var clipPath = createGridClipShape(
	                    coordSys, seriesModel, function () {
	                        // Callback will be invoked immediately if there is no animation
	                        setTimeout(function () {
	                            dataGroup.removeClipPath();
	                        });
	                    }
	                );
	                dataGroup.setClipPath(clipPath);
	            }

	            this._data = data;

	            function add(newDataIndex) {
	                addEl(data, dataGroup, newDataIndex, dimensions, coordSys, null, smooth);
	            }

	            function update(newDataIndex, oldDataIndex) {
	                var line = oldData.getItemGraphicEl(oldDataIndex);
	                var points = createLinePoints(data, newDataIndex, dimensions, coordSys);
	                data.setItemGraphicEl(newDataIndex, line);
	                var animationModel = (payload && payload.animation === false) ? null : seriesModel;
	                graphic.updateProps(line, {shape: {points: points}}, animationModel, newDataIndex);
	            }

	            function remove(oldDataIndex) {
	                var line = oldData.getItemGraphicEl(oldDataIndex);
	                dataGroup.remove(line);
	            }

	        },

	        /**
	         * @private
	         */
	        // _renderForProgressive: function (seriesModel) {
	        //     var dataGroup = this._dataGroup;
	        //     var data = seriesModel.getData();
	        //     var oldData = this._data;
	        //     var coordSys = seriesModel.coordinateSystem;
	        //     var dimensions = coordSys.dimensions;
	        //     var option = seriesModel.option;
	        //     var progressive = option.progressive;
	        //     var smooth = option.smooth ? SMOOTH : null;

	        //     // In progressive animation is disabled, so use simple data diff,
	        //     // which effects performance less.
	        //     // (Typically performance for data with length 7000+ like:
	        //     // simpleDiff: 60ms, addEl: 184ms,
	        //     // in RMBP 2.4GHz intel i7, OSX 10.9 chrome 50.0.2661.102 (64-bit))
	        //     if (simpleDiff(oldData, data, dimensions)) {
	        //         dataGroup.removeAll();
	        //         data.each(function (dataIndex) {
	        //             addEl(data, dataGroup, dataIndex, dimensions, coordSys);
	        //         });
	        //     }

	        //     updateElCommon(data, progressive, smooth);

	        //     // Consider switch between progressive and not.
	        //     data.__plProgressive = true;
	        //     this._data = data;
	        // },

	        /**
	         * @override
	         */
	        remove: function () {
	            this._dataGroup && this._dataGroup.removeAll();
	            this._data = null;
	        }
	    });

	    function createGridClipShape(coordSys, seriesModel, cb) {
	        var parallelModel = coordSys.model;
	        var rect = coordSys.getRect();
	        var rectEl = new graphic.Rect({
	            shape: {
	                x: rect.x,
	                y: rect.y,
	                width: rect.width,
	                height: rect.height
	            }
	        });

	        var dim = parallelModel.get('layout') === 'horizontal' ? 'width' : 'height';
	        rectEl.setShape(dim, 0);
	        graphic.initProps(rectEl, {
	            shape: {
	                width: rect.width,
	                height: rect.height
	            }
	        }, seriesModel, cb);
	        return rectEl;
	    }

	    function createLinePoints(data, dataIndex, dimensions, coordSys) {
	        var points = [];
	        for (var i = 0; i < dimensions.length; i++) {
	            var dimName = dimensions[i];
	            var value = data.get(dimName, dataIndex);
	            if (!isEmptyValue(value, coordSys.getAxis(dimName).type)) {
	                points.push(coordSys.dataToPoint(value, dimName));
	            }
	        }
	        return points;
	    }

	    function addEl(data, dataGroup, dataIndex, dimensions, coordSys) {
	        var points = createLinePoints(data, dataIndex, dimensions, coordSys);
	        var line = new graphic.Polyline({
	            shape: {points: points},
	            silent: true,
	            z2: 10
	        });
	        dataGroup.add(line);
	        data.setItemGraphicEl(dataIndex, line);
	    }

	    function updateElCommon(data, smooth) {
	        var seriesStyleModel = data.hostModel.getModel('lineStyle.normal');
	        var lineStyle = seriesStyleModel.getLineStyle();
	        data.eachItemGraphicEl(function (line, dataIndex) {
	            if (data.hasItemOption) {
	                var itemModel = data.getItemModel(dataIndex);
	                var lineStyleModel = itemModel.getModel('lineStyle.normal', seriesStyleModel);
	                lineStyle = lineStyleModel.getLineStyle(['color', 'stroke']);
	            }

	            line.useStyle(zrUtil.extend(lineStyle, {
	                fill: null,
	                // lineStyle.color have been set to itemVisual in module:echarts/visual/seriesColor.
	                stroke: data.getItemVisual(dataIndex, 'color'),
	                // lineStyle.opacity have been set to itemVisual in parallelVisual.
	                opacity: data.getItemVisual(dataIndex, 'opacity')
	            }));

	            line.shape.smooth = smooth;
	        });
	    }

	    // function simpleDiff(oldData, newData, dimensions) {
	    //     var oldLen;
	    //     if (!oldData
	    //         || !oldData.__plProgressive
	    //         || (oldLen = oldData.count()) !== newData.count()
	    //     ) {
	    //         return true;
	    //     }

	    //     var dimLen = dimensions.length;
	    //     for (var i = 0; i < oldLen; i++) {
	    //         for (var j = 0; j < dimLen; j++) {
	    //             if (oldData.get(dimensions[j], i) !== newData.get(dimensions[j], i)) {
	    //                 return true;
	    //             }
	    //         }
	    //     }

	    //     return false;
	    // }

	    // FIXME
	    // 公用方法?
	    function isEmptyValue(val, axisType) {
	        return axisType === 'category'
	            ? val == null
	            : (val == null || isNaN(val)); // axisType === 'value'
	    }

	    module.exports = ParallelView;


/***/ },
/* 250 */
/***/ function(module, exports) {

	

	    var opacityAccessPath = ['lineStyle', 'normal', 'opacity'];

	    module.exports = function (ecModel) {

	        ecModel.eachSeriesByType('parallel', function (seriesModel) {

	            var itemStyleModel = seriesModel.getModel('itemStyle.normal');
	            var lineStyleModel = seriesModel.getModel('lineStyle.normal');
	            var globalColors = ecModel.get('color');

	            var color = lineStyleModel.get('color')
	                || itemStyleModel.get('color')
	                || globalColors[seriesModel.seriesIndex % globalColors.length];
	            var inactiveOpacity = seriesModel.get('inactiveOpacity');
	            var activeOpacity = seriesModel.get('activeOpacity');
	            var lineStyle = seriesModel.getModel('lineStyle.normal').getLineStyle();

	            var coordSys = seriesModel.coordinateSystem;
	            var data = seriesModel.getData();

	            var opacityMap = {
	                normal: lineStyle.opacity,
	                active: activeOpacity,
	                inactive: inactiveOpacity
	            };

	            coordSys.eachActiveState(data, function (activeState, dataIndex) {
	                var itemModel = data.getItemModel(dataIndex);
	                var opacity = opacityMap[activeState];
	                if (activeState === 'normal') {
	                    var itemOpacity = itemModel.get(opacityAccessPath, true);
	                    itemOpacity != null && (opacity = itemOpacity);
	                }
	                data.setItemVisual(dataIndex, 'opacity', opacity);
	            });

	            data.setVisual('color', color);
	        });
	    };


/***/ },
/* 251 */
/***/ function(module, exports, __webpack_require__) {

	

	    var echarts = __webpack_require__(1);

	    __webpack_require__(252);
	    __webpack_require__(253);
	    echarts.registerLayout(__webpack_require__(254));
	    echarts.registerVisual(__webpack_require__(256));


/***/ },
/* 252 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @file Get initial data and define sankey view's series model
	 * @author Deqing Li(annong035@gmail.com)
	 */


	    var SeriesModel = __webpack_require__(78);
	    var createGraphFromNodeEdge = __webpack_require__(207);
	    var encodeHTML = __webpack_require__(6).encodeHTML;

	    var SankeySeries = SeriesModel.extend({

	        type: 'series.sankey',

	        layoutInfo: null,

	        /**
	         * Init a graph data structure from data in option series
	         *
	         * @param  {Object} option  the object used to config echarts view
	         * @return {module:echarts/data/List} storage initial data
	         */
	        getInitialData: function (option) {
	            var links = option.edges || option.links;
	            var nodes = option.data || option.nodes;
	            if (nodes && links) {
	                var graph = createGraphFromNodeEdge(nodes, links, this, true);
	                return graph.data;
	            }
	        },

	        /**
	         * Return the graphic data structure
	         *
	         * @return {module:echarts/data/Graph} graphic data structure
	         */
	        getGraph: function () {
	            return this.getData().graph;
	        },

	        /**
	         * Get edge data of graphic data structure
	         *
	         * @return {module:echarts/data/List} data structure of list
	         */
	        getEdgeData: function () {
	            return this.getGraph().edgeData;
	        },

	        /**
	         * @override
	         */
	        formatTooltip: function (dataIndex, multipleSeries, dataType) {
	            // dataType === 'node' or empty do not show tooltip by default
	            if (dataType === 'edge') {
	                var params = this.getDataParams(dataIndex, dataType);
	                var rawDataOpt = params.data;
	                var html = rawDataOpt.source + ' -- ' + rawDataOpt.target;
	                if (params.value) {
	                    html += ' : ' + params.value;
	                }
	                return encodeHTML(html);
	            }

	            return SankeySeries.superCall(this, 'formatTooltip', dataIndex, multipleSeries);
	        },

	        defaultOption: {
	            zlevel: 0,
	            z: 2,

	            coordinateSystem: 'view',

	            layout: null,

	            // the position of the whole view
	            left: '5%',
	            top: '5%',
	            right: '20%',
	            bottom: '5%',

	            // the dx of the node
	            nodeWidth: 20,

	            // the vertical distance between two nodes
	            nodeGap: 8,

	            // the number of iterations to change the position of the node
	            layoutIterations: 32,

	            label: {
	                normal: {
	                    show: true,
	                    position: 'right',
	                    textStyle: {
	                        color: '#000',
	                        fontSize: 12
	                    }
	                },
	                emphasis: {
	                    show: true
	                }
	            },

	            itemStyle: {
	                normal: {
	                    borderWidth: 1,
	                    borderColor: '#333'
	                }
	            },

	            lineStyle: {
	                normal: {
	                    color: '#314656',
	                    opacity: 0.2,
	                    curveness: 0.5
	                },
	                emphasis: {
	                    opacity: 0.6
	                }
	            },

	            animationEasing: 'linear',

	            animationDuration: 1000
	        }

	    });

	    module.exports = SankeySeries;



/***/ },
/* 253 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @file  The file used to draw sankey view
	 * @author  Deqing Li(annong035@gmail.com)
	 */


	    var graphic = __webpack_require__(18);
	    var zrUtil = __webpack_require__(4);

	    var SankeyShape = graphic.extendShape({
	        shape: {
	            x1: 0, y1: 0,
	            x2: 0, y2: 0,
	            cpx1: 0, cpy1: 0,
	            cpx2: 0, cpy2: 0,

	            extent: 0
	        },

	        buildPath: function (ctx, shape) {
	            var halfExtent = shape.extent / 2;
	            ctx.moveTo(shape.x1, shape.y1 - halfExtent);
	            ctx.bezierCurveTo(
	                shape.cpx1, shape.cpy1 - halfExtent,
	                shape.cpx2, shape.cpy2 - halfExtent,
	                shape.x2, shape.y2 - halfExtent
	            );
	            ctx.lineTo(shape.x2, shape.y2 + halfExtent);
	            ctx.bezierCurveTo(
	                shape.cpx2, shape.cpy2 + halfExtent,
	                shape.cpx1, shape.cpy1 + halfExtent,
	                shape.x1, shape.y1 + halfExtent
	            );
	            ctx.closePath();
	        }
	    });

	    module.exports = __webpack_require__(1).extendChartView({

	        type: 'sankey',

	        /**
	         * @private
	         * @type {module:echarts/chart/sankey/SankeySeries}
	         */
	        _model: null,

	        render: function (seriesModel, ecModel, api) {
	            var graph = seriesModel.getGraph();
	            var group = this.group;
	            var layoutInfo = seriesModel.layoutInfo;
	            var nodeData = seriesModel.getData();
	            var edgeData = seriesModel.getData('edge');

	            this._model = seriesModel;

	            group.removeAll();

	            group.position = [layoutInfo.x, layoutInfo.y];

	            // generate a bezire Curve for each edge
	            graph.eachEdge(function (edge) {
	                var curve = new SankeyShape();

	                curve.dataIndex = edge.dataIndex;
	                curve.seriesIndex = seriesModel.seriesIndex;
	                curve.dataType = 'edge';

	                var lineStyleModel = edge.getModel('lineStyle.normal');
	                var curvature = lineStyleModel.get('curveness');
	                var n1Layout = edge.node1.getLayout();
	                var n2Layout = edge.node2.getLayout();
	                var edgeLayout = edge.getLayout();

	                curve.shape.extent = Math.max(1, edgeLayout.dy);

	                var x1 = n1Layout.x + n1Layout.dx;
	                var y1 = n1Layout.y + edgeLayout.sy + edgeLayout.dy / 2;
	                var x2 = n2Layout.x;
	                var y2 = n2Layout.y + edgeLayout.ty + edgeLayout.dy / 2;
	                var cpx1 = x1 * (1 - curvature) + x2 * curvature;
	                var cpy1 = y1;
	                var cpx2 = x1 * curvature + x2 * (1 - curvature);
	                var cpy2 = y2;

	                curve.setShape({
	                    x1: x1,
	                    y1: y1,
	                    x2: x2,
	                    y2: y2,
	                    cpx1: cpx1,
	                    cpy1: cpy1,
	                    cpx2: cpx2,
	                    cpy2: cpy2
	                });

	                curve.setStyle(lineStyleModel.getItemStyle());
	                // Special color, use source node color or target node color
	                switch (curve.style.fill) {
	                    case 'source':
	                        curve.style.fill = edge.node1.getVisual('color');
	                        break;
	                    case 'target':
	                        curve.style.fill = edge.node2.getVisual('color');
	                        break;
	                }

	                graphic.setHoverStyle(curve, edge.getModel('lineStyle.emphasis').getItemStyle());

	                group.add(curve);

	                edgeData.setItemGraphicEl(edge.dataIndex, curve);
	            });

	            // generate a rect  for each node
	            graph.eachNode(function (node) {
	                var layout = node.getLayout();
	                var itemModel = node.getModel();
	                var labelModel = itemModel.getModel('label.normal');
	                var textStyleModel = labelModel.getModel('textStyle');
	                var labelHoverModel = itemModel.getModel('label.emphasis');
	                var textStyleHoverModel = labelHoverModel.getModel('textStyle');

	                var rect = new graphic.Rect({
	                    shape: {
	                        x: layout.x,
	                        y: layout.y,
	                        width: node.getLayout().dx,
	                        height: node.getLayout().dy
	                    },
	                    style: {
	                        // Get formatted label in label.normal option
	                        //  Use node id if it is not specified
	                        text: labelModel.get('show')
	                            ? seriesModel.getFormattedLabel(node.dataIndex, 'normal') || node.id
	                            // Use empty string to hide the label
	                            : '',
	                        textFont: textStyleModel.getFont(),
	                        textFill: textStyleModel.getTextColor(),
	                        textPosition: labelModel.get('position')
	                    }
	                });

	                rect.setStyle(zrUtil.defaults(
	                    {
	                        fill: node.getVisual('color')
	                    },
	                    itemModel.getModel('itemStyle.normal').getItemStyle()
	                ));

	                graphic.setHoverStyle(rect, zrUtil.extend(
	                    node.getModel('itemStyle.emphasis'),
	                    {
	                        text: labelHoverModel.get('show')
	                            ? seriesModel.getFormattedLabel(node.dataIndex, 'emphasis') || node.id
	                            : '',
	                        textFont: textStyleHoverModel.getFont(),
	                        textFill: textStyleHoverModel.getTextColor(),
	                        textPosition: labelHoverModel.get('position')
	                    }
	                ));

	                group.add(rect);

	                nodeData.setItemGraphicEl(node.dataIndex, rect);

	                rect.dataType = 'node';
	            });

	            if (!this._data && seriesModel.get('animation')) {
	                group.setClipPath(createGridClipShape(group.getBoundingRect(), seriesModel, function () {
	                    group.removeClipPath();
	                }));
	            }

	            this._data = seriesModel.getData();
	        },

	        dispose: function () {}
	    });

	    // add animation to the view
	    function createGridClipShape(rect, seriesModel, cb) {
	        var rectEl = new graphic.Rect({
	            shape: {
	                x: rect.x - 10,
	                y: rect.y - 10,
	                width: 0,
	                height: rect.height + 20
	            }
	        });
	        graphic.initProps(rectEl, {
	            shape: {
	                width: rect.width + 20,
	                height: rect.height + 20
	            }
	        }, seriesModel, cb);

	        return rectEl;
	    }



/***/ },
/* 254 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @file The layout algorithm of sankey view
	 * @author  Deqing Li(annong035@gmail.com)
	 */


	    var layout = __webpack_require__(71);
	    var nest = __webpack_require__(255);
	    var zrUtil = __webpack_require__(4);

	    module.exports = function (ecModel, api, payload) {

	        ecModel.eachSeriesByType('sankey', function (seriesModel) {

	            var nodeWidth = seriesModel.get('nodeWidth');
	            var nodeGap = seriesModel.get('nodeGap');

	            var layoutInfo = getViewRect(seriesModel, api);

	            seriesModel.layoutInfo = layoutInfo;

	            var width = layoutInfo.width;
	            var height = layoutInfo.height;

	            var graph = seriesModel.getGraph();

	            var nodes = graph.nodes;
	            var edges = graph.edges;

	            computeNodeValues(nodes);

	            var filteredNodes = zrUtil.filter(nodes, function (node) {
	                return node.getLayout().value === 0;
	            });

	            var iterations = filteredNodes.length !== 0
	                ? 0 : seriesModel.get('layoutIterations');

	            layoutSankey(nodes, edges, nodeWidth, nodeGap, width, height, iterations);
	        });
	    };

	    /**
	     * Get the layout position of the whole view
	     *
	     * @param {module:echarts/model/Series} seriesModel  the model object of sankey series
	     * @param {module:echarts/ExtensionAPI} api  provide the API list that the developer can call
	     * @return {module:zrender/core/BoundingRect}  size of rect to draw the sankey view
	     */
	    function getViewRect(seriesModel, api) {
	        return layout.getLayoutRect(
	            seriesModel.getBoxLayoutParams(), {
	                width: api.getWidth(),
	                height: api.getHeight()
	            }
	        );
	    }

	    function layoutSankey(nodes, edges, nodeWidth, nodeGap, width, height, iterations) {
	        computeNodeBreadths(nodes, nodeWidth, width);
	        computeNodeDepths(nodes, edges, height, nodeGap, iterations);
	        computeEdgeDepths(nodes);
	    }

	    /**
	     * Compute the value of each node by summing the associated edge's value
	     *
	     * @param {module:echarts/data/Graph~Node} nodes  node of sankey view
	     */
	    function computeNodeValues(nodes) {
	        zrUtil.each(nodes, function (node) {
	            var value1 = sum(node.outEdges, getEdgeValue);
	            var value2 = sum(node.inEdges, getEdgeValue);
	            var value = Math.max(value1, value2);
	            node.setLayout({value: value}, true);
	        });
	    }

	    /**
	     * Compute the x-position for each node
	     *
	     * @param {module:echarts/data/Graph~Node} nodes  node of sankey view
	     * @param  {number} nodeWidth  the dx of the node
	     * @param  {number} width  the whole width of the area to draw the view
	     */
	    function computeNodeBreadths(nodes, nodeWidth, width) {
	        var remainNodes = nodes;
	        var nextNode = null;
	        var x = 0;
	        var kx = 0;

	        while (remainNodes.length) {
	            nextNode = [];
	            for (var i = 0, len = remainNodes.length; i < len; i++) {
	                var node = remainNodes[i];
	                node.setLayout({x: x}, true);
	                node.setLayout({dx: nodeWidth}, true);
	                for (var j = 0, lenj = node.outEdges.length; j < lenj; j++) {
	                    nextNode.push(node.outEdges[j].node2);
	                }
	            }
	            remainNodes = nextNode;
	            ++x;
	        }

	        moveSinksRight(nodes, x);
	        kx = (width - nodeWidth) / (x - 1);

	        scaleNodeBreadths(nodes, kx);
	    }

	    /**
	     * All the node without outEgdes are assigned maximum x-position and
	     *     be aligned in the last column.
	     *
	     * @param {module:echarts/data/Graph~Node} nodes  node of sankey view
	     * @param {number} x  value (x-1) use to assign to node without outEdges
	     *     as x-position
	     */
	    function moveSinksRight(nodes, x) {
	        zrUtil.each(nodes, function (node) {
	            if (!node.outEdges.length) {
	                node.setLayout({x: x - 1}, true);
	            }
	        });
	    }

	    /**
	     * Scale node x-position to the width
	     *
	     * @param {module:echarts/data/Graph~Node} nodes  node of sankey view
	     * @param {number} kx   multiple used to scale nodes
	     */
	    function scaleNodeBreadths(nodes, kx) {
	        zrUtil.each(nodes, function (node) {
	            var nodeX = node.getLayout().x * kx;
	            node.setLayout({x: nodeX}, true);
	        });
	    }

	    /**
	     * Using Gauss-Seidel iterations method to compute the node depth(y-position)
	     *
	     * @param {module:echarts/data/Graph~Node} nodes  node of sankey view
	     * @param {module:echarts/data/Graph~Edge} edges  edge of sankey view
	     * @param {number} height  the whole height of the area to draw the view
	     * @param {numbber} nodeGap  the vertical distance between two nodes
	     *     in the same column.
	     * @param {number} iterations  the number of iterations for the algorithm
	     */
	    function computeNodeDepths(nodes, edges, height, nodeGap, iterations) {
	        var nodesByBreadth = nest()
	            .key(function (d) {
	                return d.getLayout().x;
	            })
	            .sortKeys(ascending)
	            .entries(nodes)
	            .map(function (d) {
	                return d.values;
	            });

	        initializeNodeDepth(nodes, nodesByBreadth, edges, height, nodeGap);
	        resolveCollisions(nodesByBreadth, nodeGap, height);

	        for (var alpha = 1; iterations > 0; iterations--) {
	            // 0.99 is a experience parameter, ensure that each iterations of
	            // changes as small as possible.
	            alpha *= 0.99;
	            relaxRightToLeft(nodesByBreadth, alpha);
	            resolveCollisions(nodesByBreadth, nodeGap, height);
	            relaxLeftToRight(nodesByBreadth, alpha);
	            resolveCollisions(nodesByBreadth, nodeGap, height);
	        }
	    }

	    /**
	     * Compute the original y-position for each node
	     *
	     * @param {module:echarts/data/Graph~Node} nodes  node of sankey view
	     * @param {Array.<Array.<module:echarts/data/Graph~Node>>} nodesByBreadth
	     *     group by the array of all sankey nodes based on the nodes x-position.
	     * @param {module:echarts/data/Graph~Edge} edges  edge of sankey view
	     * @param {number} height  the whole height of the area to draw the view
	     * @param {number} nodeGap  the vertical distance between two nodes
	     */
	    function initializeNodeDepth(nodes, nodesByBreadth, edges, height, nodeGap) {
	        var kyArray = [];
	        zrUtil.each(nodesByBreadth, function (nodes) {
	            var n = nodes.length;
	            var sum = 0;
	            zrUtil.each(nodes, function (node) {
	                sum += node.getLayout().value;
	            });
	            var ky = (height - (n - 1) * nodeGap) / sum;
	            kyArray.push(ky);
	        });

	        kyArray.sort(function (a, b) {
	            return a - b;
	        });
	        var ky0 = kyArray[0];

	        zrUtil.each(nodesByBreadth, function (nodes) {
	            zrUtil.each(nodes, function (node, i) {
	                node.setLayout({y: i}, true);
	                var nodeDy = node.getLayout().value * ky0;
	                node.setLayout({dy: nodeDy}, true);
	            });
	        });

	        zrUtil.each(edges, function (edge) {
	            var edgeDy = +edge.getValue() * ky0;
	            edge.setLayout({dy: edgeDy}, true);
	        });
	    }

	    /**
	     * Resolve the collision of initialized depth (y-position)
	     *
	     * @param {Array.<Array.<module:echarts/data/Graph~Node>>} nodesByBreadth
	     *     group by the array of all sankey nodes based on the nodes x-position.
	     * @param {number} nodeGap  the vertical distance between two nodes
	     * @param {number} height  the whole height of the area to draw the view
	     */
	    function resolveCollisions(nodesByBreadth, nodeGap, height) {
	        zrUtil.each(nodesByBreadth, function (nodes) {
	            var node;
	            var dy;
	            var y0 = 0;
	            var n = nodes.length;
	            var i;

	            nodes.sort(ascendingDepth);

	            for (i = 0; i < n; i++) {
	                node = nodes[i];
	                dy = y0 - node.getLayout().y;
	                if (dy > 0) {
	                    var nodeY = node.getLayout().y + dy;
	                    node.setLayout({y: nodeY}, true);
	                }
	                y0 = node.getLayout().y + node.getLayout().dy + nodeGap;
	            }

	            // if the bottommost node goes outside the bounds, push it back up
	            dy = y0 - nodeGap - height;
	            if (dy > 0) {
	                var nodeY = node.getLayout().y - dy;
	                node.setLayout({y: nodeY}, true);
	                y0 = node.getLayout().y;
	                for (i = n - 2; i >= 0; --i) {
	                    node = nodes[i];
	                    dy = node.getLayout().y + node.getLayout().dy + nodeGap - y0;
	                    if (dy > 0) {
	                        nodeY = node.getLayout().y - dy;
	                        node.setLayout({y: nodeY}, true);
	                    }
	                    y0 = node.getLayout().y;
	                }
	            }
	        });
	    }

	    /**
	     * Change the y-position of the nodes, except most the right side nodes
	     *
	     * @param {Array.<Array.<module:echarts/data/Graph~Node>>} nodesByBreadth
	     *     group by the array of all sankey nodes based on the node x-position.
	     * @param {number} alpha  parameter used to adjust the nodes y-position
	     */
	    function relaxRightToLeft(nodesByBreadth, alpha) {
	        zrUtil.each(nodesByBreadth.slice().reverse(), function (nodes) {
	            zrUtil.each(nodes, function (node) {
	                if (node.outEdges.length) {
	                    var y = sum(node.outEdges, weightedTarget) / sum(node.outEdges, getEdgeValue);
	                    var nodeY = node.getLayout().y + (y - center(node)) * alpha;
	                    node.setLayout({y: nodeY}, true);
	                }
	            });
	        });
	    }

	    function weightedTarget(edge) {
	        return center(edge.node2) * edge.getValue();
	    }

	    /**
	     * Change the y-position of the nodes, except most the left side nodes
	     *
	     * @param {Array.<Array.<module:echarts/data/Graph~Node>>} nodesByBreadth
	     *     group by the array of all sankey nodes based on the node x-position.
	     * @param {number} alpha  parameter used to adjust the nodes y-position
	     */
	    function relaxLeftToRight(nodesByBreadth, alpha) {
	        zrUtil.each(nodesByBreadth, function (nodes) {
	            zrUtil.each(nodes, function (node) {
	                if (node.inEdges.length) {
	                    var y = sum(node.inEdges, weightedSource) / sum(node.inEdges, getEdgeValue);
	                    var nodeY = node.getLayout().y + (y - center(node)) * alpha;
	                    node.setLayout({y: nodeY}, true);
	                }
	            });
	        });
	    }

	    function weightedSource(edge) {
	        return center(edge.node1) * edge.getValue();
	    }

	    /**
	     * Compute the depth(y-position) of each edge
	     *
	     * @param {module:echarts/data/Graph~Node} nodes  node of sankey view
	     */
	    function computeEdgeDepths(nodes) {
	        zrUtil.each(nodes, function (node) {
	            node.outEdges.sort(ascendingTargetDepth);
	            node.inEdges.sort(ascendingSourceDepth);
	        });
	        zrUtil.each(nodes, function (node) {
	            var sy = 0;
	            var ty = 0;
	            zrUtil.each(node.outEdges, function (edge) {
	                edge.setLayout({sy: sy}, true);
	                sy += edge.getLayout().dy;
	            });
	            zrUtil.each(node.inEdges, function (edge) {
	                edge.setLayout({ty: ty}, true);
	                ty += edge.getLayout().dy;
	            });
	        });
	    }

	    function ascendingTargetDepth(a, b) {
	        return a.node2.getLayout().y - b.node2.getLayout().y;
	    }

	    function ascendingSourceDepth(a, b) {
	        return a.node1.getLayout().y - b.node1.getLayout().y;
	    }

	    function sum(array, f) {
	        var sum = 0;
	        var len = array.length;
	        var i = -1;
	        while (++i < len) {
	            var value = +f.call(array, array[i], i);
	            if (!isNaN(value)) {
	                sum += value;
	            }
	        }
	        return sum;
	    }

	    function center(node) {
	        return node.getLayout().y + node.getLayout().dy / 2;
	    }

	    function ascendingDepth(a, b) {
	        return a.getLayout().y - b.getLayout().y;
	    }

	    function ascending(a, b) {
	        return a < b ? -1 : a > b ? 1 : a === b ? 0 : NaN;
	    }

	    function getEdgeValue(edge) {
	        return edge.getValue();
	    }



/***/ },
/* 255 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);

	    /**
	     * nest helper used to group by the array.
	     * can specified the keys and sort the keys.
	     */
	    function nest() {

	        var keysFunction = [];
	        var sortKeysFunction = [];

	        /**
	         * map an Array into the mapObject.
	         * @param {Array} array
	         * @param {number} depth
	         */
	        function map(array, depth) {
	            if (depth >= keysFunction.length) {
	                return array;
	            }
	            var i = -1;
	            var n = array.length;
	            var keyFunction = keysFunction[depth++];
	            var mapObject = {};
	            var valuesByKey = {};

	            while (++i < n) {
	                var keyValue = keyFunction(array[i]);
	                var values = valuesByKey[keyValue];

	                if (values) {
	                    values.push(array[i]);
	                }
	                else {
	                    valuesByKey[keyValue] = [array[i]];
	                }
	            }

	            zrUtil.each(valuesByKey, function (value, key) {
	                mapObject[key] = map(value, depth);
	            });

	            return mapObject;
	        }

	        /**
	         * transform the Map Object to multidimensional Array
	         * @param {Object} map
	         * @param {number} depth
	         */
	        function entriesMap(mapObject, depth) {
	            if (depth >= keysFunction.length) {
	                return mapObject;
	            }
	            var array = [];
	            var sortKeyFunction = sortKeysFunction[depth++];

	            zrUtil.each(mapObject, function (value, key) {
	                array.push({
	                    key: key, values: entriesMap(value, depth)
	                });
	            });

	            if (sortKeyFunction) {
	                return array.sort(function (a, b) {
	                    return sortKeyFunction(a.key, b.key);
	                });
	            }
	            else {
	                return array;
	            }
	        }

	        return {
	            /**
	             * specified the key to groupby the arrays.
	             * users can specified one more keys.
	             * @param {Function} d
	             */
	            key: function (d) {
	                keysFunction.push(d);
	                return this;
	            },

	            /**
	             * specified the comparator to sort the keys
	             * @param {Function} order
	             */
	            sortKeys: function (order) {
	                sortKeysFunction[keysFunction.length - 1] = order;
	                return this;
	            },

	            /**
	             * the array to be grouped by.
	             * @param {Array} array
	             */
	            entries: function (array) {
	                return entriesMap(map(array, 0), 0);
	            }
	        };
	    }
	    module.exports = nest;


/***/ },
/* 256 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @file Visual encoding for sankey view
	 * @author  Deqing Li(annong035@gmail.com)
	 */


	    var VisualMapping = __webpack_require__(203);
	    var zrUtil = __webpack_require__(4);

	    module.exports = function (ecModel, payload) {
	        ecModel.eachSeriesByType('sankey', function (seriesModel) {
	            var graph = seriesModel.getGraph();
	            var nodes = graph.nodes;

	            nodes.sort(function (a, b) {
	                return a.getLayout().value - b.getLayout().value;
	            });

	            var minValue = nodes[0].getLayout().value;
	            var maxValue = nodes[nodes.length - 1].getLayout().value;

	            zrUtil.each(nodes, function (node) {
	                var mapping = new VisualMapping({
	                    type: 'color',
	                    mappingMethod: 'linear',
	                    dataExtent: [minValue, maxValue],
	                    visual: seriesModel.get('color')
	                });

	                var mapValueToColor = mapping.mapValueToVisual(node.getLayout().value);
	                node.setVisual('color', mapValueToColor);
	                // If set itemStyle.normal.color
	                var itemModel = node.getModel();
	                var customColor = itemModel.get('itemStyle.normal.color');
	                if (customColor != null) {
	                    node.setVisual('color', customColor);
	                }
	            });

	        });
	    };



/***/ },
/* 257 */
/***/ function(module, exports, __webpack_require__) {

	

	    var echarts = __webpack_require__(1);

	    __webpack_require__(258);
	    __webpack_require__(261);

	    echarts.registerVisual(__webpack_require__(262));
	    echarts.registerLayout(__webpack_require__(263));



/***/ },
/* 258 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var zrUtil = __webpack_require__(4);
	    var SeriesModel = __webpack_require__(78);
	    var whiskerBoxCommon = __webpack_require__(259);

	    var BoxplotSeries = SeriesModel.extend({

	        type: 'series.boxplot',

	        dependencies: ['xAxis', 'yAxis', 'grid'],

	        // TODO
	        // box width represents group size, so dimension should have 'size'.

	        /**
	         * @see <https://en.wikipedia.org/wiki/Box_plot>
	         * The meanings of 'min' and 'max' depend on user,
	         * and echarts do not need to know it.
	         * @readOnly
	         */
	        defaultValueDimensions: ['min', 'Q1', 'median', 'Q3', 'max'],

	        /**
	         * @type {Array.<string>}
	         * @readOnly
	         */
	        dimensions: null,

	        /**
	         * @override
	         */
	        defaultOption: {
	            zlevel: 0,                  // 一级层叠
	            z: 2,                       // 二级层叠
	            coordinateSystem: 'cartesian2d',
	            legendHoverLink: true,

	            hoverAnimation: true,

	            // xAxisIndex: 0,
	            // yAxisIndex: 0,

	            layout: null,               // 'horizontal' or 'vertical'
	            boxWidth: [7, 50],       // [min, max] can be percent of band width.

	            itemStyle: {
	                normal: {
	                    color: '#fff',
	                    borderWidth: 1
	                },
	                emphasis: {
	                    borderWidth: 2,
	                    shadowBlur: 5,
	                    shadowOffsetX: 2,
	                    shadowOffsetY: 2,
	                    shadowColor: 'rgba(0,0,0,0.4)'
	                }
	            },

	            animationEasing: 'elasticOut',
	            animationDuration: 800
	        }
	    });

	    zrUtil.mixin(BoxplotSeries, whiskerBoxCommon.seriesModelMixin, true);

	    module.exports = BoxplotSeries;



/***/ },
/* 259 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var List = __webpack_require__(98);
	    var completeDimensions = __webpack_require__(110);
	    var WhiskerBoxDraw = __webpack_require__(260);
	    var zrUtil = __webpack_require__(4);

	    var seriesModelMixin = {

	        /**
	         * @private
	         * @type {string}
	         */
	        _baseAxisDim: null,

	        /**
	         * @override
	         */
	        getInitialData: function (option, ecModel) {
	            // When both types of xAxis and yAxis are 'value', layout is
	            // needed to be specified by user. Otherwise, layout can be
	            // judged by which axis is category.

	            var categories;

	            var xAxisModel = ecModel.getComponent('xAxis', this.get('xAxisIndex'));
	            var yAxisModel = ecModel.getComponent('yAxis', this.get('yAxisIndex'));
	            var xAxisType = xAxisModel.get('type');
	            var yAxisType = yAxisModel.get('type');
	            var addOrdinal;

	            // FIXME
	            // 考虑时间轴

	            if (xAxisType === 'category') {
	                option.layout = 'horizontal';
	                categories = xAxisModel.getCategories();
	                addOrdinal = true;
	            }
	            else if (yAxisType  === 'category') {
	                option.layout = 'vertical';
	                categories = yAxisModel.getCategories();
	                addOrdinal = true;
	            }
	            else {
	                option.layout = option.layout || 'horizontal';
	            }

	            var coordDims = ['x', 'y'];
	            var baseAxisDimIndex = option.layout === 'horizontal' ? 0 : 1;
	            var baseAxisDim = this._baseAxisDim = coordDims[baseAxisDimIndex];
	            var otherAxisDim = coordDims[1 - baseAxisDimIndex];
	            var data = option.data;

	            addOrdinal && zrUtil.each(data, function (item, index) {
	                zrUtil.isArray(item) && item.unshift(index);
	            });

	            var dimensions = [{
	                name: baseAxisDim,
	                otherDims: {
	                    tooltip: false
	                },
	                dimsDef: ['base']
	            }, {
	                name: otherAxisDim,
	                dimsDef: this.defaultValueDimensions.slice()
	            }];

	            dimensions = completeDimensions(dimensions, data, {
	                encodeDef: this.get('encode'),
	                dimsDef: this.get('dimensions')
	            });

	            var list = new List(dimensions, this);
	            list.initData(data, categories ? categories.slice() : null);

	            return list;
	        },

	        /**
	         * If horizontal, base axis is x, otherwise y.
	         * @override
	         */
	        getBaseAxis: function () {
	            var dim = this._baseAxisDim;
	            return this.ecModel.getComponent(dim + 'Axis', this.get(dim + 'AxisIndex')).axis;
	        }

	    };

	    var viewMixin = {

	        init: function () {
	            /**
	             * Old data.
	             * @private
	             * @type {module:echarts/chart/helper/WhiskerBoxDraw}
	             */
	            var whiskerBoxDraw = this._whiskerBoxDraw = new WhiskerBoxDraw(
	                this.getStyleUpdater()
	            );
	            this.group.add(whiskerBoxDraw.group);
	        },

	        render: function (seriesModel, ecModel, api) {
	            this._whiskerBoxDraw.updateData(seriesModel.getData());
	        },

	        remove: function (ecModel) {
	            this._whiskerBoxDraw.remove();
	        }
	    };

	    module.exports = {
	        seriesModelMixin: seriesModelMixin,
	        viewMixin: viewMixin
	    };


/***/ },
/* 260 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @module echarts/chart/helper/Symbol
	 */


	    var zrUtil = __webpack_require__(4);
	    var graphic = __webpack_require__(18);
	    var Path = __webpack_require__(20);

	    var WhiskerPath = Path.extend({

	        type: 'whiskerInBox',

	        shape: {},

	        buildPath: function (ctx, shape) {
	            for (var i in shape) {
	                if (shape.hasOwnProperty(i) && i.indexOf('ends') === 0) {
	                    var pts = shape[i];
	                    ctx.moveTo(pts[0][0], pts[0][1]);
	                    ctx.lineTo(pts[1][0], pts[1][1]);
	                }
	            }
	        }
	    });

	    /**
	     * @constructor
	     * @alias {module:echarts/chart/helper/WhiskerBox}
	     * @param {module:echarts/data/List} data
	     * @param {number} idx
	     * @param {Function} styleUpdater
	     * @param {boolean} isInit
	     * @extends {module:zrender/graphic/Group}
	     */
	    function WhiskerBox(data, idx, styleUpdater, isInit) {
	        graphic.Group.call(this);

	        /**
	         * @type {number}
	         * @readOnly
	         */
	        this.bodyIndex;

	        /**
	         * @type {number}
	         * @readOnly
	         */
	        this.whiskerIndex;

	        /**
	         * @type {Function}
	         */
	        this.styleUpdater = styleUpdater;

	        this._createContent(data, idx, isInit);

	        this.updateData(data, idx, isInit);

	        /**
	         * Last series model.
	         * @type {module:echarts/model/Series}
	         */
	        this._seriesModel;
	    }

	    var whiskerBoxProto = WhiskerBox.prototype;

	    whiskerBoxProto._createContent = function (data, idx, isInit) {
	        var itemLayout = data.getItemLayout(idx);
	        var constDim = itemLayout.chartLayout === 'horizontal' ? 1 : 0;
	        var count = 0;

	        // Whisker element.
	        this.add(new graphic.Polygon({
	            shape: {
	                points: isInit
	                    ? transInit(itemLayout.bodyEnds, constDim, itemLayout)
	                    : itemLayout.bodyEnds
	            },
	            style: {strokeNoScale: true},
	            z2: 100
	        }));
	        this.bodyIndex = count++;

	        // Box element.
	        var whiskerEnds = zrUtil.map(itemLayout.whiskerEnds, function (ends) {
	            return isInit ? transInit(ends, constDim, itemLayout) : ends;
	        });
	        this.add(new WhiskerPath({
	            shape: makeWhiskerEndsShape(whiskerEnds),
	            style: {strokeNoScale: true},
	            z2: 100
	        }));
	        this.whiskerIndex = count++;
	    };

	    function transInit(points, dim, itemLayout) {
	        return zrUtil.map(points, function (point) {
	            point = point.slice();
	            point[dim] = itemLayout.initBaseline;
	            return point;
	        });
	    }

	    function makeWhiskerEndsShape(whiskerEnds) {
	        // zr animation only support 2-dim array.
	        var shape = {};
	        zrUtil.each(whiskerEnds, function (ends, i) {
	            shape['ends' + i] = ends;
	        });
	        return shape;
	    }

	    /**
	     * Update symbol properties
	     * @param  {module:echarts/data/List} data
	     * @param  {number} idx
	     */
	    whiskerBoxProto.updateData = function (data, idx, isInit) {
	        var seriesModel = this._seriesModel = data.hostModel;
	        var itemLayout = data.getItemLayout(idx);
	        var updateMethod = graphic[isInit ? 'initProps' : 'updateProps'];
	        // this.childAt(this.bodyIndex).stopAnimation(true);
	        // this.childAt(this.whiskerIndex).stopAnimation(true);
	        updateMethod(
	            this.childAt(this.bodyIndex),
	            {shape: {points: itemLayout.bodyEnds}},
	            seriesModel, idx
	        );
	        updateMethod(
	            this.childAt(this.whiskerIndex),
	            {shape: makeWhiskerEndsShape(itemLayout.whiskerEnds)},
	            seriesModel, idx
	        );

	        this.styleUpdater.call(null, this, data, idx);
	    };

	    zrUtil.inherits(WhiskerBox, graphic.Group);


	    /**
	     * @constructor
	     * @alias module:echarts/chart/helper/WhiskerBoxDraw
	     */
	    function WhiskerBoxDraw(styleUpdater) {
	        this.group = new graphic.Group();
	        this.styleUpdater = styleUpdater;
	    }

	    var whiskerBoxDrawProto = WhiskerBoxDraw.prototype;

	    /**
	     * Update symbols draw by new data
	     * @param {module:echarts/data/List} data
	     */
	    whiskerBoxDrawProto.updateData = function (data) {
	        var group = this.group;
	        var oldData = this._data;
	        var styleUpdater = this.styleUpdater;

	        data.diff(oldData)
	            .add(function (newIdx) {
	                if (data.hasValue(newIdx)) {
	                    var symbolEl = new WhiskerBox(data, newIdx, styleUpdater, true);
	                    data.setItemGraphicEl(newIdx, symbolEl);
	                    group.add(symbolEl);
	                }
	            })
	            .update(function (newIdx, oldIdx) {
	                var symbolEl = oldData.getItemGraphicEl(oldIdx);

	                // Empty data
	                if (!data.hasValue(newIdx)) {
	                    group.remove(symbolEl);
	                    return;
	                }

	                if (!symbolEl) {
	                    symbolEl = new WhiskerBox(data, newIdx, styleUpdater);
	                }
	                else {
	                    symbolEl.updateData(data, newIdx);
	                }

	                // Add back
	                group.add(symbolEl);

	                data.setItemGraphicEl(newIdx, symbolEl);
	            })
	            .remove(function (oldIdx) {
	                var el = oldData.getItemGraphicEl(oldIdx);
	                el && group.remove(el);
	            })
	            .execute();

	        this._data = data;
	    };

	    /**
	     * Remove symbols.
	     * @param {module:echarts/data/List} data
	     */
	    whiskerBoxDrawProto.remove = function () {
	        var group = this.group;
	        var data = this._data;
	        this._data = null;
	        data && data.eachItemGraphicEl(function (el) {
	            el && group.remove(el);
	        });
	    };

	    module.exports = WhiskerBoxDraw;


/***/ },
/* 261 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var zrUtil = __webpack_require__(4);
	    var ChartView = __webpack_require__(80);
	    var graphic = __webpack_require__(18);
	    var whiskerBoxCommon = __webpack_require__(259);

	    var BoxplotView = ChartView.extend({

	        type: 'boxplot',

	        getStyleUpdater: function () {
	            return updateStyle;
	        },

	        dispose: zrUtil.noop
	    });

	    zrUtil.mixin(BoxplotView, whiskerBoxCommon.viewMixin, true);

	    // Update common properties
	    var normalStyleAccessPath = ['itemStyle', 'normal'];
	    var emphasisStyleAccessPath = ['itemStyle', 'emphasis'];

	    function updateStyle(itemGroup, data, idx) {
	        var itemModel = data.getItemModel(idx);
	        var normalItemStyleModel = itemModel.getModel(normalStyleAccessPath);
	        var borderColor = data.getItemVisual(idx, 'color');

	        // Exclude borderColor.
	        var itemStyle = normalItemStyleModel.getItemStyle(['borderColor']);

	        var whiskerEl = itemGroup.childAt(itemGroup.whiskerIndex);
	        whiskerEl.style.set(itemStyle);
	        whiskerEl.style.stroke = borderColor;
	        whiskerEl.dirty();

	        var bodyEl = itemGroup.childAt(itemGroup.bodyIndex);
	        bodyEl.style.set(itemStyle);
	        bodyEl.style.stroke = borderColor;
	        bodyEl.dirty();

	        var hoverStyle = itemModel.getModel(emphasisStyleAccessPath).getItemStyle();
	        graphic.setHoverStyle(itemGroup, hoverStyle);
	    }

	    module.exports = BoxplotView;



/***/ },
/* 262 */
/***/ function(module, exports) {

	

	    var borderColorQuery = ['itemStyle', 'normal', 'borderColor'];

	    module.exports = function (ecModel, api) {

	        var globalColors = ecModel.get('color');

	        ecModel.eachRawSeriesByType('boxplot', function (seriesModel) {

	            var defaulColor = globalColors[seriesModel.seriesIndex % globalColors.length];
	            var data = seriesModel.getData();

	            data.setVisual({
	                legendSymbol: 'roundRect',
	                // Use name 'color' but not 'borderColor' for legend usage and
	                // visual coding from other component like dataRange.
	                color: seriesModel.get(borderColorQuery) || defaulColor
	            });

	            // Only visible series has each data be visual encoded
	            if (!ecModel.isSeriesFiltered(seriesModel)) {
	                data.each(function (idx) {
	                    var itemModel = data.getItemModel(idx);
	                    data.setItemVisual(
	                        idx,
	                        {color: itemModel.get(borderColorQuery, true)}
	                    );
	                });
	            }
	        });

	    };


/***/ },
/* 263 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);
	    var numberUtil = __webpack_require__(7);
	    var parsePercent = numberUtil.parsePercent;
	    var each = zrUtil.each;

	    module.exports = function (ecModel) {

	        var groupResult = groupSeriesByAxis(ecModel);

	        each(groupResult, function (groupItem) {
	            var seriesModels = groupItem.seriesModels;

	            if (!seriesModels.length) {
	                return;
	            }

	            calculateBase(groupItem);

	            each(seriesModels, function (seriesModel, idx) {
	                layoutSingleSeries(
	                    seriesModel,
	                    groupItem.boxOffsetList[idx],
	                    groupItem.boxWidthList[idx]
	                );
	            });
	        });
	    };

	    /**
	     * Group series by axis.
	     */
	    function groupSeriesByAxis(ecModel) {
	        var result = [];
	        var axisList = [];

	        ecModel.eachSeriesByType('boxplot', function (seriesModel) {
	            var baseAxis = seriesModel.getBaseAxis();
	            var idx = zrUtil.indexOf(axisList, baseAxis);

	            if (idx < 0) {
	                idx = axisList.length;
	                axisList[idx] = baseAxis;
	                result[idx] = {axis: baseAxis, seriesModels: []};
	            }

	            result[idx].seriesModels.push(seriesModel);
	        });

	        return result;
	    }

	    /**
	     * Calculate offset and box width for each series.
	     */
	    function calculateBase(groupItem) {
	        var extent;
	        var baseAxis = groupItem.axis;
	        var seriesModels = groupItem.seriesModels;
	        var seriesCount = seriesModels.length;

	        var boxWidthList = groupItem.boxWidthList = [];
	        var boxOffsetList = groupItem.boxOffsetList = [];
	        var boundList = [];

	        var bandWidth;
	        if (baseAxis.type === 'category') {
	            bandWidth = baseAxis.getBandWidth();
	        }
	        else {
	            var maxDataCount = 0;
	            each(seriesModels, function (seriesModel) {
	                maxDataCount = Math.max(maxDataCount, seriesModel.getData().count());
	            });
	            extent = baseAxis.getExtent(),
	            Math.abs(extent[1] - extent[0]) / maxDataCount;
	        }

	        each(seriesModels, function (seriesModel) {
	            var boxWidthBound = seriesModel.get('boxWidth');
	            if (!zrUtil.isArray(boxWidthBound)) {
	                boxWidthBound = [boxWidthBound, boxWidthBound];
	            }
	            boundList.push([
	                parsePercent(boxWidthBound[0], bandWidth) || 0,
	                parsePercent(boxWidthBound[1], bandWidth) || 0
	            ]);
	        });

	        var availableWidth = bandWidth * 0.8 - 2;
	        var boxGap = availableWidth / seriesCount * 0.3;
	        var boxWidth = (availableWidth - boxGap * (seriesCount - 1)) / seriesCount;
	        var base = boxWidth / 2 - availableWidth / 2;

	        each(seriesModels, function (seriesModel, idx) {
	            boxOffsetList.push(base);
	            base += boxGap + boxWidth;

	            boxWidthList.push(
	                Math.min(Math.max(boxWidth, boundList[idx][0]), boundList[idx][1])
	            );
	        });
	    }

	    /**
	     * Calculate points location for each series.
	     */
	    function layoutSingleSeries(seriesModel, offset, boxWidth) {
	        var coordSys = seriesModel.coordinateSystem;
	        var data = seriesModel.getData();
	        var halfWidth = boxWidth / 2;
	        var chartLayout = seriesModel.get('layout');
	        var variableDim = chartLayout === 'horizontal' ? 0 : 1;
	        var constDim = 1 - variableDim;
	        var coordDims = ['x', 'y'];
	        var vDims = [];
	        var cDim;

	        zrUtil.each(data.dimensions, function (dimName) {
	            var dimInfo = data.getDimensionInfo(dimName);
	            var coordDim = dimInfo.coordDim;
	            if (coordDim === coordDims[constDim]) {
	                vDims.push(dimName);
	            }
	            else if (coordDim === coordDims[variableDim]) {
	                cDim = dimName;
	            }
	        });

	        if (cDim == null || vDims.length < 5) {
	            return;
	        }

	        data.each([cDim].concat(vDims), function () {
	            var args = arguments;
	            var axisDimVal = args[0];
	            var idx = args[vDims.length + 1];

	            var median = getPoint(args[3]);
	            var end1 = getPoint(args[1]);
	            var end5 = getPoint(args[5]);
	            var whiskerEnds = [
	                [end1, getPoint(args[2])],
	                [end5, getPoint(args[4])]
	            ];
	            layEndLine(end1);
	            layEndLine(end5);
	            layEndLine(median);

	            var bodyEnds = [];
	            addBodyEnd(whiskerEnds[0][1], 0);
	            addBodyEnd(whiskerEnds[1][1], 1);

	            data.setItemLayout(idx, {
	                chartLayout: chartLayout,
	                initBaseline: median[constDim],
	                median: median,
	                bodyEnds: bodyEnds,
	                whiskerEnds: whiskerEnds
	            });

	            function getPoint(val) {
	                var p = [];
	                p[variableDim] = axisDimVal;
	                p[constDim] = val;
	                var point;
	                if (isNaN(axisDimVal) || isNaN(val)) {
	                    point = [NaN, NaN];
	                }
	                else {
	                    point = coordSys.dataToPoint(p);
	                    point[variableDim] += offset;
	                }
	                return point;
	            }

	            function addBodyEnd(point, start) {
	                var point1 = point.slice();
	                var point2 = point.slice();
	                point1[variableDim] += halfWidth;
	                point2[variableDim] -= halfWidth;
	                start
	                    ? bodyEnds.push(point1, point2)
	                    : bodyEnds.push(point2, point1);
	            }

	            function layEndLine(endCenter) {
	                var line = [endCenter.slice(), endCenter.slice()];
	                line[0][variableDim] -= halfWidth;
	                line[1][variableDim] += halfWidth;
	                whiskerEnds.push(line);
	            }
	        });
	    }



/***/ },
/* 264 */
/***/ function(module, exports, __webpack_require__) {

	

	    var echarts = __webpack_require__(1);

	    __webpack_require__(265);
	    __webpack_require__(266);

	    echarts.registerPreprocessor(
	        __webpack_require__(267)
	    );

	    echarts.registerVisual(__webpack_require__(268));
	    echarts.registerLayout(__webpack_require__(269));



/***/ },
/* 265 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var zrUtil = __webpack_require__(4);
	    var SeriesModel = __webpack_require__(78);
	    var whiskerBoxCommon = __webpack_require__(259);

	    var CandlestickSeries = SeriesModel.extend({

	        type: 'series.candlestick',

	        dependencies: ['xAxis', 'yAxis', 'grid'],

	        /**
	         * @readOnly
	         */
	        defaultValueDimensions: ['open', 'close', 'lowest', 'highest'],

	        /**
	         * @type {Array.<string>}
	         * @readOnly
	         */
	        dimensions: null,

	        /**
	         * @override
	         */
	        defaultOption: {
	            zlevel: 0,                  // 一级层叠
	            z: 2,                       // 二级层叠
	            coordinateSystem: 'cartesian2d',
	            legendHoverLink: true,

	            hoverAnimation: true,

	            // xAxisIndex: 0,
	            // yAxisIndex: 0,

	            layout: null, // 'horizontal' or 'vertical'

	            itemStyle: {
	                normal: {
	                    color: '#c23531', // 阳线 positive
	                    color0: '#314656', // 阴线 negative     '#c23531', '#314656'
	                    borderWidth: 1,
	                    // FIXME
	                    // ec2中使用的是lineStyle.color 和 lineStyle.color0
	                    borderColor: '#c23531',
	                    borderColor0: '#314656'
	                },
	                emphasis: {
	                    borderWidth: 2
	                }
	            },

	            barMaxWidth: null,
	            barMinWidth: null,
	            barWidth: null,

	            animationUpdate: false,
	            animationEasing: 'linear',
	            animationDuration: 300
	        },

	        /**
	         * Get dimension for shadow in dataZoom
	         * @return {string} dimension name
	         */
	        getShadowDim: function () {
	            return 'open';
	        },

	        brushSelector: function (dataIndex, data, selectors) {
	            var itemLayout = data.getItemLayout(dataIndex);
	            return selectors.rect(itemLayout.brushRect);
	        }

	    });

	    zrUtil.mixin(CandlestickSeries, whiskerBoxCommon.seriesModelMixin, true);

	    module.exports = CandlestickSeries;



/***/ },
/* 266 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var zrUtil = __webpack_require__(4);
	    var ChartView = __webpack_require__(80);
	    var graphic = __webpack_require__(18);
	    var whiskerBoxCommon = __webpack_require__(259);

	    var CandlestickView = ChartView.extend({

	        type: 'candlestick',

	        getStyleUpdater: function () {
	            return updateStyle;
	        },

	        dispose: zrUtil.noop
	    });

	    zrUtil.mixin(CandlestickView, whiskerBoxCommon.viewMixin, true);

	    // Update common properties
	    var normalStyleAccessPath = ['itemStyle', 'normal'];
	    var emphasisStyleAccessPath = ['itemStyle', 'emphasis'];

	    function updateStyle(itemGroup, data, idx) {
	        var itemModel = data.getItemModel(idx);
	        var normalItemStyleModel = itemModel.getModel(normalStyleAccessPath);
	        var color = data.getItemVisual(idx, 'color');
	        var borderColor = data.getItemVisual(idx, 'borderColor') || color;

	        // Color must be excluded.
	        // Because symbol provide setColor individually to set fill and stroke
	        var itemStyle = normalItemStyleModel.getItemStyle(
	            ['color', 'color0', 'borderColor', 'borderColor0']
	        );

	        var whiskerEl = itemGroup.childAt(itemGroup.whiskerIndex);
	        whiskerEl.useStyle(itemStyle);
	        whiskerEl.style.stroke = borderColor;

	        var bodyEl = itemGroup.childAt(itemGroup.bodyIndex);
	        bodyEl.useStyle(itemStyle);
	        bodyEl.style.fill = color;
	        bodyEl.style.stroke = borderColor;

	        var hoverStyle = itemModel.getModel(emphasisStyleAccessPath).getItemStyle();
	        graphic.setHoverStyle(itemGroup, hoverStyle);
	    }


	    module.exports = CandlestickView;



/***/ },
/* 267 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);

	    module.exports = function (option) {
	        if (!option || !zrUtil.isArray(option.series)) {
	            return;
	        }

	        // Translate 'k' to 'candlestick'.
	        zrUtil.each(option.series, function (seriesItem) {
	            if (zrUtil.isObject(seriesItem) && seriesItem.type === 'k') {
	                seriesItem.type = 'candlestick';
	            }
	        });
	    };



/***/ },
/* 268 */
/***/ function(module, exports) {

	

	    var positiveBorderColorQuery = ['itemStyle', 'normal', 'borderColor'];
	    var negativeBorderColorQuery = ['itemStyle', 'normal', 'borderColor0'];
	    var positiveColorQuery = ['itemStyle', 'normal', 'color'];
	    var negativeColorQuery = ['itemStyle', 'normal', 'color0'];

	    module.exports = function (ecModel, api) {

	        ecModel.eachRawSeriesByType('candlestick', function (seriesModel) {

	            var data = seriesModel.getData();

	            data.setVisual({
	                legendSymbol: 'roundRect'
	            });

	            // Only visible series has each data be visual encoded
	            if (!ecModel.isSeriesFiltered(seriesModel)) {
	                data.each(function (idx) {
	                    var itemModel = data.getItemModel(idx);
	                    var sign = data.getItemLayout(idx).sign;

	                    data.setItemVisual(
	                        idx,
	                        {
	                            color: itemModel.get(
	                                sign > 0 ? positiveColorQuery : negativeColorQuery
	                            ),
	                            borderColor: itemModel.get(
	                                sign > 0 ? positiveBorderColorQuery : negativeBorderColorQuery
	                            )
	                        }
	                    );
	                });
	            }
	        });

	    };


/***/ },
/* 269 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);
	    var retrieve = __webpack_require__(4).retrieve;
	    var parsePercent = __webpack_require__(7).parsePercent;

	    module.exports = function (ecModel) {

	        ecModel.eachSeriesByType('candlestick', function (seriesModel) {

	            var coordSys = seriesModel.coordinateSystem;
	            var data = seriesModel.getData();
	            var candleWidth = calculateCandleWidth(seriesModel, data);
	            var chartLayout = seriesModel.get('layout');
	            var variableDim = chartLayout === 'horizontal' ? 0 : 1;
	            var constDim = 1 - variableDim;
	            var coordDims = ['x', 'y'];
	            var vDims = [];
	            var cDim;

	            zrUtil.each(data.dimensions, function (dimName) {
	                var dimInfo = data.getDimensionInfo(dimName);
	                var coordDim = dimInfo.coordDim;
	                if (coordDim === coordDims[constDim]) {
	                    vDims.push(dimName);
	                }
	                else if (coordDim === coordDims[variableDim]) {
	                    cDim = dimName;
	                }
	            });

	            if (cDim == null || vDims.length < 4) {
	                return;
	            }

	            data.each([cDim].concat(vDims), function () {
	                var args = arguments;
	                var axisDimVal = args[0];
	                var idx = args[vDims.length + 1];

	                var openVal = args[1];
	                var closeVal = args[2];
	                var lowestVal = args[3];
	                var highestVal = args[4];

	                var ocLow = Math.min(openVal, closeVal);
	                var ocHigh = Math.max(openVal, closeVal);

	                var ocLowPoint = getPoint(ocLow);
	                var ocHighPoint = getPoint(ocHigh);
	                var lowestPoint = getPoint(lowestVal);
	                var highestPoint = getPoint(highestVal);

	                var whiskerEnds = [
	                    [highestPoint, ocHighPoint],
	                    [lowestPoint, ocLowPoint]
	                ];

	                var bodyEnds = [];
	                addBodyEnd(ocHighPoint, 0);
	                addBodyEnd(ocLowPoint, 1);

	                data.setItemLayout(idx, {
	                    chartLayout: chartLayout,
	                    sign: openVal > closeVal ? -1 : openVal < closeVal ? 1 : 0,
	                    initBaseline: openVal > closeVal
	                        ? ocHighPoint[constDim] : ocLowPoint[constDim], // open point.
	                    bodyEnds: bodyEnds,
	                    whiskerEnds: whiskerEnds,
	                    brushRect: makeBrushRect()
	                });

	                function getPoint(val) {
	                    var p = [];
	                    p[variableDim] = axisDimVal;
	                    p[constDim] = val;
	                    return (isNaN(axisDimVal) || isNaN(val))
	                        ? [NaN, NaN]
	                        : coordSys.dataToPoint(p);
	                }

	                function addBodyEnd(point, start) {
	                    var point1 = point.slice();
	                    var point2 = point.slice();
	                    point1[variableDim] += candleWidth / 2;
	                    point2[variableDim] -= candleWidth / 2;
	                    start
	                        ? bodyEnds.push(point1, point2)
	                        : bodyEnds.push(point2, point1);
	                }

	                function makeBrushRect() {
	                    var pmin = getPoint(Math.min(openVal, closeVal, lowestVal, highestVal));
	                    var pmax = getPoint(Math.max(openVal, closeVal, lowestVal, highestVal));

	                    pmin[variableDim] -= candleWidth / 2;
	                    pmax[variableDim] -= candleWidth / 2;

	                    return {
	                        x: pmin[0],
	                        y: pmin[1],
	                        width: constDim ? candleWidth : pmax[0] - pmin[0],
	                        height: constDim ? pmax[1] - pmin[1] : candleWidth
	                    };
	                }

	            }, true);
	        });
	    };

	    function calculateCandleWidth(seriesModel, data) {
	        var baseAxis = seriesModel.getBaseAxis();
	        var extent;

	        var bandWidth = baseAxis.type === 'category'
	            ? baseAxis.getBandWidth()
	            : (
	                extent = baseAxis.getExtent(),
	                Math.abs(extent[1] - extent[0]) / data.count()
	            );

	        var barMaxWidth = parsePercent(
	            retrieve(seriesModel.get('barMaxWidth'), bandWidth),
	            bandWidth
	        );
	        var barMinWidth = parsePercent(
	            retrieve(seriesModel.get('barMinWidth'), 1),
	            bandWidth
	        );
	        var barWidth = seriesModel.get('barWidth');
	        return barWidth != null
	            ? parsePercent(barWidth, bandWidth)
	            // Put max outer to ensure bar visible in spite of overlap.
	            : Math.max(Math.min(bandWidth / 2, barMaxWidth), barMinWidth);
	    }



/***/ },
/* 270 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);
	    var echarts = __webpack_require__(1);

	    __webpack_require__(271);
	    __webpack_require__(272);

	    echarts.registerVisual(zrUtil.curry(
	        __webpack_require__(121), 'effectScatter', 'circle', null
	    ));
	    echarts.registerLayout(zrUtil.curry(
	        __webpack_require__(122), 'effectScatter'
	    ));


/***/ },
/* 271 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var createListFromArray = __webpack_require__(109);
	    var SeriesModel = __webpack_require__(78);

	    module.exports = SeriesModel.extend({

	        type: 'series.effectScatter',

	        dependencies: ['grid', 'polar'],

	        getInitialData: function (option, ecModel) {
	            var list = createListFromArray(option.data, this, ecModel);
	            return list;
	        },

	        brushSelector: 'point',

	        defaultOption: {
	            coordinateSystem: 'cartesian2d',
	            zlevel: 0,
	            z: 2,
	            legendHoverLink: true,

	            effectType: 'ripple',

	            progressive: 0,

	            // When to show the effect, option: 'render'|'emphasis'
	            showEffectOn: 'render',

	            // Ripple effect config
	            rippleEffect: {
	                period: 4,
	                // Scale of ripple
	                scale: 2.5,
	                // Brush type can be fill or stroke
	                brushType: 'fill'
	            },

	            // Cartesian coordinate system
	            // xAxisIndex: 0,
	            // yAxisIndex: 0,

	            // Polar coordinate system
	            // polarIndex: 0,

	            // Geo coordinate system
	            // geoIndex: 0,

	            // symbol: null,        // 图形类型
	            symbolSize: 10          // 图形大小，半宽（半径）参数，当图形为方向或菱形则总宽度为symbolSize * 2
	            // symbolRotate: null,  // 图形旋转控制

	            // large: false,
	            // Available when large is true
	            // largeThreshold: 2000,

	            // itemStyle: {
	            //     normal: {
	            //         opacity: 1
	            //     }
	            // }
	        }

	    });


/***/ },
/* 272 */
/***/ function(module, exports, __webpack_require__) {

	

	    var SymbolDraw = __webpack_require__(116);
	    var EffectSymbol = __webpack_require__(273);

	    __webpack_require__(1).extendChartView({

	        type: 'effectScatter',

	        init: function () {
	            this._symbolDraw = new SymbolDraw(EffectSymbol);
	        },

	        render: function (seriesModel, ecModel, api) {
	            var data = seriesModel.getData();
	            var effectSymbolDraw = this._symbolDraw;
	            effectSymbolDraw.updateData(data);
	            this.group.add(effectSymbolDraw.group);
	        },

	        updateLayout: function () {
	            this._symbolDraw.updateLayout();
	        },

	        remove: function (ecModel, api) {
	            this._symbolDraw && this._symbolDraw.remove(api);
	        },

	        dispose: function () {}
	    });


/***/ },
/* 273 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * Symbol with ripple effect
	 * @module echarts/chart/helper/EffectSymbol
	 */


	    var zrUtil = __webpack_require__(4);
	    var symbolUtil = __webpack_require__(111);
	    var graphic = __webpack_require__(18);
	    var numberUtil = __webpack_require__(7);
	    var Symbol = __webpack_require__(117);
	    var Group = graphic.Group;

	    var EFFECT_RIPPLE_NUMBER = 3;

	    function normalizeSymbolSize(symbolSize) {
	        if (!zrUtil.isArray(symbolSize)) {
	            symbolSize = [+symbolSize, +symbolSize];
	        }
	        return symbolSize;
	    }

	    function updateRipplePath(rippleGroup, effectCfg) {
	        rippleGroup.eachChild(function (ripplePath) {
	            ripplePath.attr({
	                z: effectCfg.z,
	                zlevel: effectCfg.zlevel,
	                style: {
	                    stroke: effectCfg.brushType === 'stroke' ? effectCfg.color : null,
	                    fill: effectCfg.brushType === 'fill' ? effectCfg.color : null
	                }
	            });
	        });
	    }
	    /**
	     * @constructor
	     * @param {module:echarts/data/List} data
	     * @param {number} idx
	     * @extends {module:zrender/graphic/Group}
	     */
	    function EffectSymbol(data, idx) {
	        Group.call(this);

	        var symbol = new Symbol(data, idx);
	        var rippleGroup = new Group();
	        this.add(symbol);
	        this.add(rippleGroup);

	        rippleGroup.beforeUpdate = function () {
	            this.attr(symbol.getScale());
	        };
	        this.updateData(data, idx);
	    }

	    var effectSymbolProto = EffectSymbol.prototype;

	    effectSymbolProto.stopEffectAnimation = function () {
	        this.childAt(1).removeAll();
	    };

	    effectSymbolProto.startEffectAnimation = function (effectCfg) {
	        var symbolType = effectCfg.symbolType;
	        var color = effectCfg.color;
	        var rippleGroup = this.childAt(1);

	        for (var i = 0; i < EFFECT_RIPPLE_NUMBER; i++) {
	            // var ripplePath = symbolUtil.createSymbol(
	            //     symbolType, -0.5, -0.5, 1, 1, color
	            // );
	            // If width/height are set too small (e.g., set to 1) on ios10
	            // and macOS Sierra, a circle stroke become a rect, no matter what
	            // the scale is set. So we set width/height as 2. See #4136.
	            var ripplePath = symbolUtil.createSymbol(
	                symbolType, -1, -1, 2, 2, color
	            );
	            ripplePath.attr({
	                style: {
	                    strokeNoScale: true
	                },
	                z2: 99,
	                silent: true,
	                scale: [0.5, 0.5]
	            });

	            var delay = -i / EFFECT_RIPPLE_NUMBER * effectCfg.period + effectCfg.effectOffset;
	            // TODO Configurable effectCfg.period
	            ripplePath.animate('', true)
	                .when(effectCfg.period, {
	                    scale: [effectCfg.rippleScale / 2, effectCfg.rippleScale / 2]
	                })
	                .delay(delay)
	                .start();
	            ripplePath.animateStyle(true)
	                .when(effectCfg.period, {
	                    opacity: 0
	                })
	                .delay(delay)
	                .start();

	            rippleGroup.add(ripplePath);
	        }

	        updateRipplePath(rippleGroup, effectCfg);
	    };

	    /**
	     * Update effect symbol
	     */
	    effectSymbolProto.updateEffectAnimation = function (effectCfg) {
	        var oldEffectCfg = this._effectCfg;
	        var rippleGroup = this.childAt(1);

	        // Must reinitialize effect if following configuration changed
	        var DIFFICULT_PROPS = ['symbolType', 'period', 'rippleScale'];
	        for (var i = 0; i < DIFFICULT_PROPS; i++) {
	            var propName = DIFFICULT_PROPS[i];
	            if (oldEffectCfg[propName] !== effectCfg[propName]) {
	                this.stopEffectAnimation();
	                this.startEffectAnimation(effectCfg);
	                return;
	            }
	        }

	        updateRipplePath(rippleGroup, effectCfg);
	    };

	    /**
	     * Highlight symbol
	     */
	    effectSymbolProto.highlight = function () {
	        this.trigger('emphasis');
	    };

	    /**
	     * Downplay symbol
	     */
	    effectSymbolProto.downplay = function () {
	        this.trigger('normal');
	    };

	    /**
	     * Update symbol properties
	     * @param  {module:echarts/data/List} data
	     * @param  {number} idx
	     */
	    effectSymbolProto.updateData = function (data, idx) {
	        var seriesModel = data.hostModel;

	        this.childAt(0).updateData(data, idx);

	        var rippleGroup = this.childAt(1);
	        var itemModel = data.getItemModel(idx);
	        var symbolType = data.getItemVisual(idx, 'symbol');
	        var symbolSize = normalizeSymbolSize(data.getItemVisual(idx, 'symbolSize'));
	        var color = data.getItemVisual(idx, 'color');

	        rippleGroup.attr('scale', symbolSize);

	        rippleGroup.traverse(function (ripplePath) {
	            ripplePath.attr({
	                fill: color
	            });
	        });

	        var symbolOffset = itemModel.getShallow('symbolOffset');
	        if (symbolOffset) {
	            var pos = rippleGroup.position;
	            pos[0] = numberUtil.parsePercent(symbolOffset[0], symbolSize[0]);
	            pos[1] = numberUtil.parsePercent(symbolOffset[1], symbolSize[1]);
	        }
	        rippleGroup.rotation = (itemModel.getShallow('symbolRotate') || 0) * Math.PI / 180 || 0;

	        var effectCfg = {};

	        effectCfg.showEffectOn = seriesModel.get('showEffectOn');
	        effectCfg.rippleScale = itemModel.get('rippleEffect.scale');
	        effectCfg.brushType = itemModel.get('rippleEffect.brushType');
	        effectCfg.period = itemModel.get('rippleEffect.period') * 1000;
	        effectCfg.effectOffset = idx / data.count();
	        effectCfg.z = itemModel.getShallow('z') || 0;
	        effectCfg.zlevel = itemModel.getShallow('zlevel') || 0;
	        effectCfg.symbolType = symbolType;
	        effectCfg.color = color;

	        this.off('mouseover').off('mouseout').off('emphasis').off('normal');

	        if (effectCfg.showEffectOn === 'render') {
	            this._effectCfg
	                ? this.updateEffectAnimation(effectCfg)
	                : this.startEffectAnimation(effectCfg);

	            this._effectCfg = effectCfg;
	        }
	        else {
	            // Not keep old effect config
	            this._effectCfg = null;

	            this.stopEffectAnimation();
	            var symbol = this.childAt(0);
	            var onEmphasis = function () {
	                symbol.trigger('emphasis');
	                if (effectCfg.showEffectOn !== 'render') {
	                    this.startEffectAnimation(effectCfg);
	                }
	            };
	            var onNormal = function () {
	                symbol.trigger('normal');
	                if (effectCfg.showEffectOn !== 'render') {
	                    this.stopEffectAnimation();
	                }
	            };
	            this.on('mouseover', onEmphasis, this)
	                .on('mouseout', onNormal, this)
	                .on('emphasis', onEmphasis, this)
	                .on('normal', onNormal, this);
	        }

	        this._effectCfg = effectCfg;
	    };

	    effectSymbolProto.fadeOut = function (cb) {
	        this.off('mouseover').off('mouseout').off('emphasis').off('normal');
	        cb && cb();
	    };

	    zrUtil.inherits(EffectSymbol, Group);

	    module.exports = EffectSymbol;


/***/ },
/* 274 */
/***/ function(module, exports, __webpack_require__) {

	

	    __webpack_require__(275);
	    __webpack_require__(276);

	    var echarts = __webpack_require__(1);
	    echarts.registerLayout(
	        __webpack_require__(281)
	    );
	    echarts.registerVisual(
	        __webpack_require__(282)
	    );


/***/ },
/* 275 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var SeriesModel = __webpack_require__(78);
	    var List = __webpack_require__(98);
	    var zrUtil = __webpack_require__(4);
	    var formatUtil = __webpack_require__(6);
	    var CoordinateSystem = __webpack_require__(76);

	    // Convert [ [{coord: []}, {coord: []}] ]
	    // to [ { coords: [[]] } ]
	    function preprocessOption (seriesOpt) {
	        var data = seriesOpt.data;
	        if (data && data[0] && data[0][0] && data[0][0].coord) {
	            if (true) {
	                console.warn('Lines data configuration has been changed to'
	                    + ' { coords:[[1,2],[2,3]] }');
	            }
	            seriesOpt.data = zrUtil.map(data, function (itemOpt) {
	                var coords = [
	                    itemOpt[0].coord, itemOpt[1].coord
	                ];
	                var target = {
	                    coords: coords
	                };
	                if (itemOpt[0].name) {
	                    target.fromName = itemOpt[0].name;
	                }
	                if (itemOpt[1].name) {
	                    target.toName = itemOpt[1].name;
	                }
	                return zrUtil.mergeAll([target, itemOpt[0], itemOpt[1]]);
	            });
	        }
	    }

	    var LinesSeries = SeriesModel.extend({

	        type: 'series.lines',

	        dependencies: ['grid', 'polar'],

	        visualColorAccessPath: 'lineStyle.normal.color',

	        init: function (option) {
	            // Not using preprocessor because mergeOption may not have series.type
	            preprocessOption(option);

	            LinesSeries.superApply(this, 'init', arguments);
	        },

	        mergeOption: function (option) {
	            preprocessOption(option);

	            LinesSeries.superApply(this, 'mergeOption', arguments);
	        },

	        getInitialData: function (option, ecModel) {
	            if (true) {
	                var CoordSys = CoordinateSystem.get(option.coordinateSystem);
	                if (!CoordSys) {
	                    throw new Error('Unkown coordinate system ' + option.coordinateSystem);
	                }
	            }

	            var lineData = new List(['value'], this);
	            lineData.hasItemOption = false;
	            lineData.initData(option.data, [], function (dataItem, dimName, dataIndex, dimIndex) {
	                // dataItem is simply coords
	                if (dataItem instanceof Array) {
	                    return NaN;
	                }
	                else {
	                    lineData.hasItemOption = true;
	                    var value = dataItem.value;
	                    if (value != null) {
	                        return value instanceof Array ? value[dimIndex] : value;
	                    }
	                }
	            });

	            return lineData;
	        },

	        formatTooltip: function (dataIndex) {
	            var data = this.getData();
	            var itemModel = data.getItemModel(dataIndex);
	            var name = itemModel.get('name');
	            if (name) {
	                return name;
	            }
	            var fromName = itemModel.get('fromName');
	            var toName = itemModel.get('toName');
	            var html = [];
	            fromName != null && html.push(fromName);
	            toName != null && html.push(toName);

	            return formatUtil.encodeHTML(html.join(' > '));
	        },

	        defaultOption: {
	            coordinateSystem: 'geo',
	            zlevel: 0,
	            z: 2,
	            legendHoverLink: true,

	            hoverAnimation: true,
	            // Cartesian coordinate system
	            xAxisIndex: 0,
	            yAxisIndex: 0,

	            symbol: ['none', 'none'],
	            symbolSize: [10, 10],
	            // Geo coordinate system
	            geoIndex: 0,

	            effect: {
	                show: false,
	                period: 4,
	                // Animation delay. support callback
	                // delay: 0,
	                // If move with constant speed px/sec
	                // period will be ignored if this property is > 0,
	                constantSpeed: 0,
	                symbol: 'circle',
	                symbolSize: 3,
	                loop: true,
	                // Length of trail, 0 - 1
	                trailLength: 0.2
	                // Same with lineStyle.normal.color
	                // color
	            },

	            large: false,
	            // Available when large is true
	            largeThreshold: 2000,

	            // If lines are polyline
	            // polyline not support curveness, label, animation
	            polyline: false,

	            label: {
	                normal: {
	                    show: false,
	                    position: 'end'
	                    // distance: 5,
	                    // formatter: 标签文本格式器，同Tooltip.formatter，不支持异步回调
	                }
	            },

	            lineStyle: {
	                normal: {
	                    opacity: 0.5
	                }
	            }
	        }
	    });


/***/ },
/* 276 */
/***/ function(module, exports, __webpack_require__) {

	

	    var LineDraw = __webpack_require__(210);
	    var EffectLine = __webpack_require__(277);
	    var Line = __webpack_require__(211);
	    var Polyline = __webpack_require__(278);
	    var EffectPolyline = __webpack_require__(279);
	    var LargeLineDraw = __webpack_require__(280);

	    __webpack_require__(1).extendChartView({

	        type: 'lines',

	        init: function () {},

	        render: function (seriesModel, ecModel, api) {
	            var data = seriesModel.getData();
	            var lineDraw = this._lineDraw;

	            var hasEffect = seriesModel.get('effect.show');
	            var isPolyline = seriesModel.get('polyline');
	            var isLarge = seriesModel.get('large') && data.count() >= seriesModel.get('largeThreshold');

	            if (true) {
	                if (hasEffect && isLarge) {
	                    console.warn('Large lines not support effect');
	                }
	            }
	            if (hasEffect !== this._hasEffet || isPolyline !== this._isPolyline || isLarge !== this._isLarge) {
	                if (lineDraw) {
	                    lineDraw.remove();
	                }
	                lineDraw = this._lineDraw = isLarge
	                    ? new LargeLineDraw()
	                    : new LineDraw(
	                        isPolyline
	                            ? (hasEffect ? EffectPolyline : Polyline)
	                            : (hasEffect ? EffectLine : Line)
	                    );
	                this._hasEffet = hasEffect;
	                this._isPolyline = isPolyline;
	                this._isLarge = isLarge;
	            }

	            var zlevel = seriesModel.get('zlevel');
	            var trailLength = seriesModel.get('effect.trailLength');

	            var zr = api.getZr();
	            // Avoid the drag cause ghost shadow
	            // FIXME Better way ?
	            zr.painter.getLayer(zlevel).clear(true);
	            // Config layer with motion blur
	            if (this._lastZlevel != null) {
	                zr.configLayer(this._lastZlevel, {
	                    motionBlur: false
	                });
	            }
	            if (hasEffect && trailLength) {
	                if (true) {
	                    var notInIndividual = false;
	                    ecModel.eachSeries(function (otherSeriesModel) {
	                        if (otherSeriesModel !== seriesModel && otherSeriesModel.get('zlevel') === zlevel) {
	                            notInIndividual = true;
	                        }
	                    });
	                    notInIndividual && console.warn('Lines with trail effect should have an individual zlevel');
	                }

	                zr.configLayer(zlevel, {
	                    motionBlur: true,
	                    lastFrameAlpha: Math.max(Math.min(trailLength / 10 + 0.9, 1), 0)
	                });
	            }

	            this.group.add(lineDraw.group);

	            lineDraw.updateData(data);

	            this._lastZlevel = zlevel;
	        },

	        updateLayout: function (seriesModel, ecModel, api) {
	            this._lineDraw.updateLayout(seriesModel);
	            // Not use motion when dragging or zooming
	            var zr = api.getZr();
	            zr.painter.getLayer(this._lastZlevel).clear(true);
	        },

	        remove: function (ecModel, api) {
	            this._lineDraw && this._lineDraw.remove(api, true);
	        },

	        dispose: function () {}
	    });


/***/ },
/* 277 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * Provide effect for line
	 * @module echarts/chart/helper/EffectLine
	 */


	    var graphic = __webpack_require__(18);
	    var Line = __webpack_require__(211);
	    var zrUtil = __webpack_require__(4);
	    var symbolUtil = __webpack_require__(111);
	    var vec2 = __webpack_require__(10);

	    var curveUtil = __webpack_require__(37);

	    /**
	     * @constructor
	     * @extends {module:zrender/graphic/Group}
	     * @alias {module:echarts/chart/helper/Line}
	     */
	    function EffectLine(lineData, idx, seriesScope) {
	        graphic.Group.call(this);

	        this.add(this.createLine(lineData, idx, seriesScope));

	        this._updateEffectSymbol(lineData, idx);
	    }

	    var effectLineProto = EffectLine.prototype;

	    effectLineProto.createLine = function (lineData, idx, seriesScope) {
	        return new Line(lineData, idx, seriesScope);
	    };

	    effectLineProto._updateEffectSymbol = function (lineData, idx) {
	        var itemModel = lineData.getItemModel(idx);
	        var effectModel = itemModel.getModel('effect');
	        var size = effectModel.get('symbolSize');
	        var symbolType = effectModel.get('symbol');
	        if (!zrUtil.isArray(size)) {
	            size = [size, size];
	        }
	        var color = effectModel.get('color') || lineData.getItemVisual(idx, 'color');
	        var symbol = this.childAt(1);

	        if (this._symbolType !== symbolType) {
	            // Remove previous
	            this.remove(symbol);

	            symbol = symbolUtil.createSymbol(
	                symbolType, -0.5, -0.5, 1, 1, color
	            );
	            symbol.z2 = 100;
	            symbol.culling = true;

	            this.add(symbol);
	        }

	        // Symbol may be removed if loop is false
	        if (!symbol) {
	            return;
	        }

	        // Shadow color is same with color in default
	        symbol.setStyle('shadowColor', color);
	        symbol.setStyle(effectModel.getItemStyle(['color']));

	        symbol.attr('scale', size);

	        symbol.setColor(color);
	        symbol.attr('scale', size);

	        this._symbolType = symbolType;

	        this._updateEffectAnimation(lineData, effectModel, idx);
	    };

	    effectLineProto._updateEffectAnimation = function (lineData, effectModel, idx) {

	        var symbol = this.childAt(1);
	        if (!symbol) {
	            return;
	        }

	        var self = this;

	        var points = lineData.getItemLayout(idx);

	        var period = effectModel.get('period') * 1000;
	        var loop = effectModel.get('loop');
	        var constantSpeed = effectModel.get('constantSpeed');
	        var delayExpr = zrUtil.retrieve(effectModel.get('delay'), function (idx) {
	            return idx / lineData.count() * period / 3;
	        });
	        var isDelayFunc = typeof delayExpr === 'function';

	        // Ignore when updating
	        symbol.ignore = true;

	        this.updateAnimationPoints(symbol, points);

	        if (constantSpeed > 0) {
	            period = this.getLineLength(symbol) / constantSpeed * 1000;
	        }

	        if (period !== this._period || loop !== this._loop) {

	            symbol.stopAnimation();

	            var delay = delayExpr;
	            if (isDelayFunc) {
	                delay = delayExpr(idx);
	            }
	            if (symbol.__t > 0) {
	                delay = -period * symbol.__t;
	            }
	            symbol.__t = 0;
	            var animator = symbol.animate('', loop)
	                .when(period, {
	                    __t: 1
	                })
	                .delay(delay)
	                .during(function () {
	                    self.updateSymbolPosition(symbol);
	                });
	            if (!loop) {
	                animator.done(function () {
	                    self.remove(symbol);
	                });
	            }
	            animator.start();
	        }

	        this._period = period;
	        this._loop = loop;
	    };

	    effectLineProto.getLineLength = function (symbol) {
	        // Not so accurate
	        return (vec2.dist(symbol.__p1, symbol.__cp1)
	            + vec2.dist(symbol.__cp1, symbol.__p2));
	    };

	    effectLineProto.updateAnimationPoints = function (symbol, points) {
	        symbol.__p1 = points[0];
	        symbol.__p2 = points[1];
	        symbol.__cp1 = points[2] || [
	            (points[0][0] + points[1][0]) / 2,
	            (points[0][1] + points[1][1]) / 2
	        ];
	    };

	    effectLineProto.updateData = function (lineData, idx, seriesScope) {
	        this.childAt(0).updateData(lineData, idx, seriesScope);
	        this._updateEffectSymbol(lineData, idx);
	    };

	    effectLineProto.updateSymbolPosition = function (symbol) {
	        var p1 = symbol.__p1;
	        var p2 = symbol.__p2;
	        var cp1 = symbol.__cp1;
	        var t = symbol.__t;
	        var pos = symbol.position;
	        var quadraticAt = curveUtil.quadraticAt;
	        var quadraticDerivativeAt = curveUtil.quadraticDerivativeAt;
	        pos[0] = quadraticAt(p1[0], cp1[0], p2[0], t);
	        pos[1] = quadraticAt(p1[1], cp1[1], p2[1], t);

	        // Tangent
	        var tx = quadraticDerivativeAt(p1[0], cp1[0], p2[0], t);
	        var ty = quadraticDerivativeAt(p1[1], cp1[1], p2[1], t);

	        symbol.rotation = -Math.atan2(ty, tx) - Math.PI / 2;

	        symbol.ignore = false;
	    };


	    effectLineProto.updateLayout = function (lineData, idx) {
	        this.childAt(0).updateLayout(lineData, idx);

	        var effectModel = lineData.getItemModel(idx).getModel('effect');
	        this._updateEffectAnimation(lineData, effectModel, idx);
	    };

	    zrUtil.inherits(EffectLine, graphic.Group);

	    module.exports = EffectLine;


/***/ },
/* 278 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @module echarts/chart/helper/Line
	 */


	    var graphic = __webpack_require__(18);
	    var zrUtil = __webpack_require__(4);

	    /**
	     * @constructor
	     * @extends {module:zrender/graphic/Group}
	     * @alias {module:echarts/chart/helper/Polyline}
	     */
	    function Polyline(lineData, idx, seriesScope) {
	        graphic.Group.call(this);

	        this._createPolyline(lineData, idx, seriesScope);
	    }

	    var polylineProto = Polyline.prototype;

	    polylineProto._createPolyline = function (lineData, idx, seriesScope) {
	        // var seriesModel = lineData.hostModel;
	        var points = lineData.getItemLayout(idx);

	        var line = new graphic.Polyline({
	            shape: {
	                points: points
	            }
	        });

	        this.add(line);

	        this._updateCommonStl(lineData, idx, seriesScope);
	    };

	    polylineProto.updateData = function (lineData, idx, seriesScope) {
	        var seriesModel = lineData.hostModel;

	        var line = this.childAt(0);
	        var target = {
	            shape: {
	                points: lineData.getItemLayout(idx)
	            }
	        };
	        graphic.updateProps(line, target, seriesModel, idx);

	        this._updateCommonStl(lineData, idx, seriesScope);
	    };

	    polylineProto._updateCommonStl = function (lineData, idx, seriesScope) {
	        var line = this.childAt(0);
	        var itemModel = lineData.getItemModel(idx);

	        var visualColor = lineData.getItemVisual(idx, 'color');

	        var lineStyle = seriesScope && seriesScope.lineStyle;
	        var hoverLineStyle = seriesScope && seriesScope.hoverLineStyle;

	        if (!seriesScope || lineData.hasItemOption) {
	            lineStyle = itemModel.getModel('lineStyle.normal').getLineStyle();
	            hoverLineStyle = itemModel.getModel('lineStyle.emphasis').getLineStyle();
	        }
	        line.useStyle(zrUtil.defaults(
	            {
	                strokeNoScale: true,
	                fill: 'none',
	                stroke: visualColor
	            },
	            lineStyle
	        ));
	        line.hoverStyle = hoverLineStyle;

	        graphic.setHoverStyle(this);
	    };

	    polylineProto.updateLayout = function (lineData, idx) {
	        var polyline = this.childAt(0);
	        polyline.setShape('points', lineData.getItemLayout(idx));
	    };

	    zrUtil.inherits(Polyline, graphic.Group);

	    module.exports = Polyline;


/***/ },
/* 279 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * Provide effect for line
	 * @module echarts/chart/helper/EffectLine
	 */


	    var Polyline = __webpack_require__(278);
	    var zrUtil = __webpack_require__(4);
	    var EffectLine = __webpack_require__(277);
	    var vec2 = __webpack_require__(10);

	    /**
	     * @constructor
	     * @extends {module:echarts/chart/helper/EffectLine}
	     * @alias {module:echarts/chart/helper/Polyline}
	     */
	    function EffectPolyline(lineData, idx, seriesScope) {
	        EffectLine.call(this, lineData, idx, seriesScope);
	        this._lastFrame = 0;
	        this._lastFramePercent = 0;
	    }

	    var effectPolylineProto = EffectPolyline.prototype;

	    // Overwrite
	    effectPolylineProto.createLine = function (lineData, idx, seriesScope) {
	        return new Polyline(lineData, idx, seriesScope);
	    };

	    // Overwrite
	    effectPolylineProto.updateAnimationPoints = function (symbol, points) {
	        this._points = points;
	        var accLenArr = [0];
	        var len = 0;
	        for (var i = 1; i < points.length; i++) {
	            var p1 = points[i - 1];
	            var p2 = points[i];
	            len += vec2.dist(p1, p2);
	            accLenArr.push(len);
	        }
	        if (len === 0) {
	            return;
	        }

	        for (var i = 0; i < accLenArr.length; i++) {
	            accLenArr[i] /= len;
	        }
	        this._offsets = accLenArr;
	        this._length = len;
	    };

	    // Overwrite
	    effectPolylineProto.getLineLength = function (symbol) {
	        return this._length;
	    };

	    // Overwrite
	    effectPolylineProto.updateSymbolPosition = function (symbol) {
	        var t = symbol.__t;
	        var points = this._points;
	        var offsets = this._offsets;
	        var len = points.length;

	        if (!offsets) {
	            // Has length 0
	            return;
	        }

	        var lastFrame = this._lastFrame;
	        var frame;

	        if (t < this._lastFramePercent) {
	            // Start from the next frame
	            // PENDING start from lastFrame ?
	            var start = Math.min(lastFrame + 1, len - 1);
	            for (frame = start; frame >= 0; frame--) {
	                if (offsets[frame] <= t) {
	                    break;
	                }
	            }
	            // PENDING really need to do this ?
	            frame = Math.min(frame, len - 2);
	        }
	        else {
	            for (var frame = lastFrame; frame < len; frame++) {
	                if (offsets[frame] > t) {
	                    break;
	                }
	            }
	            frame = Math.min(frame - 1, len - 2);
	        }

	        vec2.lerp(
	            symbol.position, points[frame], points[frame + 1],
	            (t - offsets[frame]) / (offsets[frame + 1] - offsets[frame])
	        );

	        var tx = points[frame + 1][0] - points[frame][0];
	        var ty = points[frame + 1][1] - points[frame][1];
	        symbol.rotation = -Math.atan2(ty, tx) - Math.PI / 2;

	        this._lastFrame = frame;
	        this._lastFramePercent = t;

	        symbol.ignore = false;
	    };

	    zrUtil.inherits(EffectPolyline, EffectLine);

	    module.exports = EffectPolyline;


/***/ },
/* 280 */
/***/ function(module, exports, __webpack_require__) {

	// TODO Batch by color



	    var graphic = __webpack_require__(18);

	    var quadraticContain = __webpack_require__(42);
	    var lineContain = __webpack_require__(40);

	    var LargeLineShape = graphic.extendShape({
	        shape: {
	            polyline: false,

	            segs: []
	        },

	        buildPath: function (path, shape) {
	            var segs = shape.segs;
	            var isPolyline = shape.polyline;

	            for (var i = 0; i < segs.length; i++) {
	                var seg = segs[i];
	                if (isPolyline) {
	                    path.moveTo(seg[0][0], seg[0][1]);
	                    for (var j = 1; j < seg.length; j++) {
	                        path.lineTo(seg[j][0], seg[j][1]);
	                    }
	                }
	                else {
	                    path.moveTo(seg[0][0], seg[0][1]);
	                    if (seg.length > 2) {
	                        path.quadraticCurveTo(seg[2][0], seg[2][1], seg[1][0], seg[1][1]);
	                    }
	                    else {
	                        path.lineTo(seg[1][0], seg[1][1]);
	                    }
	                }
	            }
	        },

	        findDataIndex: function (x, y) {
	            var shape = this.shape;
	            var segs = shape.segs;
	            var isPolyline = shape.polyline;
	            var lineWidth = Math.max(this.style.lineWidth, 1);

	            // Not consider transform
	            for (var i = 0; i < segs.length; i++) {
	                var seg = segs[i];
	                if (isPolyline) {
	                    for (var j = 1; j < seg.length; j++) {
	                        if (lineContain.containStroke(
	                            seg[j - 1][0], seg[j - 1][1], seg[j][0], seg[j][1], lineWidth, x, y
	                        )) {
	                            return i;
	                        }
	                    }
	                }
	                else {
	                    if (seg.length > 2) {
	                        if (quadraticContain.containStroke(
	                            seg[0][0], seg[0][1], seg[2][0], seg[2][1], seg[1][0], seg[1][1], lineWidth, x, y
	                        )) {
	                            return i;
	                        }
	                    }
	                    else {
	                        if (lineContain.containStroke(
	                            seg[0][0], seg[0][1], seg[1][0], seg[1][1], lineWidth, x, y
	                        )) {
	                            return i;
	                        }
	                    }
	                }
	            }

	            return -1;
	        }
	    });

	    function LargeLineDraw() {
	        this.group = new graphic.Group();

	        this._lineEl = new LargeLineShape();
	    }

	    var largeLineProto = LargeLineDraw.prototype;

	    /**
	     * Update symbols draw by new data
	     * @param {module:echarts/data/List} data
	     */
	    largeLineProto.updateData = function (data) {
	        this.group.removeAll();

	        var lineEl = this._lineEl;

	        var seriesModel = data.hostModel;

	        lineEl.setShape({
	            segs: data.mapArray(data.getItemLayout),
	            polyline: seriesModel.get('polyline')
	        });

	        lineEl.useStyle(
	            seriesModel.getModel('lineStyle.normal').getLineStyle()
	        );

	        var visualColor = data.getVisual('color');
	        if (visualColor) {
	            lineEl.setStyle('stroke', visualColor);
	        }
	        lineEl.setStyle('fill');

	        // Enable tooltip
	        // PENDING May have performance issue when path is extremely large
	        lineEl.seriesIndex = seriesModel.seriesIndex;
	        lineEl.on('mousemove', function (e) {
	            lineEl.dataIndex = null;
	            var dataIndex = lineEl.findDataIndex(e.offsetX, e.offsetY);
	            if (dataIndex > 0) {
	                // Provide dataIndex for tooltip
	                lineEl.dataIndex = dataIndex;
	            }
	        });

	        // Add back
	        this.group.add(lineEl);
	    };

	    largeLineProto.updateLayout = function (seriesModel) {
	        var data = seriesModel.getData();
	        this._lineEl.setShape({
	            segs: data.mapArray(data.getItemLayout)
	        });
	    };

	    largeLineProto.remove = function () {
	        this.group.removeAll();
	    };

	    module.exports = LargeLineDraw;


/***/ },
/* 281 */
/***/ function(module, exports, __webpack_require__) {

	

	    module.exports = function (ecModel) {
	        ecModel.eachSeriesByType('lines', function (seriesModel) {
	            var coordSys = seriesModel.coordinateSystem;
	            var lineData = seriesModel.getData();

	            // FIXME Use data dimensions ?
	            lineData.each(function (idx) {
	                var itemModel = lineData.getItemModel(idx);

	                var coords = (itemModel.option instanceof Array) ?
	                    itemModel.option : itemModel.get('coords');

	                if (true) {
	                    if (!(coords instanceof Array && coords.length > 0 && coords[0] instanceof Array)) {
	                        throw new Error('Invalid coords ' + JSON.stringify(coords) + '. Lines must have 2d coords array in data item.');
	                    }
	                }
	                var pts = [];

	                if (seriesModel.get('polyline')) {
	                    for (var i = 0; i < coords.length; i++) {
	                        pts.push(coordSys.dataToPoint(coords[i]));
	                    }
	                }
	                else {
	                    pts[0] = coordSys.dataToPoint(coords[0]);
	                    pts[1] = coordSys.dataToPoint(coords[1]);

	                    var curveness = itemModel.get('lineStyle.normal.curveness');
	                    if (+curveness) {
	                        pts[2] = [
	                            (pts[0][0] + pts[1][0]) / 2 - (pts[0][1] - pts[1][1]) * curveness,
	                            (pts[0][1] + pts[1][1]) / 2 - (pts[1][0] - pts[0][0]) * curveness
	                        ];
	                    }
	                }
	                lineData.setItemLayout(idx, pts);
	            });
	        });
	    };


/***/ },
/* 282 */
/***/ function(module, exports) {

	

	    function normalize(a) {
	        if (!(a instanceof Array)) {
	            a = [a, a];
	        }
	        return a;
	    }
	    module.exports = function (ecModel) {
	        ecModel.eachSeriesByType('lines', function (seriesModel) {
	            var data = seriesModel.getData();
	            var symbolType = normalize(seriesModel.get('symbol'));
	            var symbolSize = normalize(seriesModel.get('symbolSize'));

	            var opacityQuery = 'lineStyle.normal.opacity'.split('.');

	            data.setVisual('fromSymbol', symbolType && symbolType[0]);
	            data.setVisual('toSymbol', symbolType && symbolType[1]);
	            data.setVisual('fromSymbolSize', symbolSize && symbolSize[0]);
	            data.setVisual('toSymbolSize', symbolSize && symbolSize[1]);
	            data.setVisual('opacity', seriesModel.get(opacityQuery));

	            data.each(function (idx) {
	                var itemModel = data.getItemModel(idx);
	                var symbolType = normalize(itemModel.getShallow('symbol', true));
	                var symbolSize = normalize(itemModel.getShallow('symbolSize', true));
	                var opacity = itemModel.get(opacityQuery);

	                symbolType[0] && data.setItemVisual(idx, 'fromSymbol', symbolType[0]);
	                symbolType[1] && data.setItemVisual(idx, 'toSymbol', symbolType[1]);
	                symbolSize[0] && data.setItemVisual(idx, 'fromSymbolSize', symbolSize[0]);
	                symbolSize[1] && data.setItemVisual(idx, 'toSymbolSize', symbolSize[1]);

	                data.setItemVisual(idx, 'opacity', opacity);
	            });
	        });
	    };


/***/ },
/* 283 */
/***/ function(module, exports, __webpack_require__) {

	

	    __webpack_require__(284);
	    __webpack_require__(285);


/***/ },
/* 284 */
/***/ function(module, exports, __webpack_require__) {

	

	    var SeriesModel = __webpack_require__(78);
	    var createListFromArray = __webpack_require__(109);

	    module.exports = SeriesModel.extend({
	        type: 'series.heatmap',

	        getInitialData: function (option, ecModel) {
	            return createListFromArray(option.data, this, ecModel);
	        },

	        defaultOption: {

	            // Cartesian2D or geo
	            coordinateSystem: 'cartesian2d',

	            zlevel: 0,

	            z: 2,

	            // Cartesian coordinate system
	            // xAxisIndex: 0,
	            // yAxisIndex: 0,

	            // Geo coordinate system
	            geoIndex: 0,

	            blurSize: 30,

	            pointSize: 20,

	            maxOpacity: 1,

	            minOpacity: 0
	        }
	    });


/***/ },
/* 285 */
/***/ function(module, exports, __webpack_require__) {

	

	    var graphic = __webpack_require__(18);
	    var HeatmapLayer = __webpack_require__(286);
	    var zrUtil = __webpack_require__(4);

	    function getIsInPiecewiseRange(dataExtent, pieceList, selected) {
	        var dataSpan = dataExtent[1] - dataExtent[0];
	        pieceList = zrUtil.map(pieceList, function (piece) {
	            return {
	                interval: [
	                    (piece.interval[0] - dataExtent[0]) / dataSpan,
	                    (piece.interval[1] - dataExtent[0]) / dataSpan
	                ]
	            };
	        });
	        var len = pieceList.length;
	        var lastIndex = 0;
	        return function (val) {
	            // Try to find in the location of the last found
	            for (var i = lastIndex; i < len; i++) {
	                var interval = pieceList[i].interval;
	                if (interval[0] <= val && val <= interval[1]) {
	                    lastIndex = i;
	                    break;
	                }
	            }
	            if (i === len) { // Not found, back interation
	                for (var i = lastIndex - 1; i >= 0; i--) {
	                    var interval = pieceList[i].interval;
	                    if (interval[0] <= val && val <= interval[1]) {
	                        lastIndex = i;
	                        break;
	                    }
	                }
	            }
	            return i >= 0 && i < len && selected[i];
	        };
	    }

	    function getIsInContinuousRange(dataExtent, range) {
	        var dataSpan = dataExtent[1] - dataExtent[0];
	        range = [
	            (range[0] - dataExtent[0]) / dataSpan,
	            (range[1] - dataExtent[0]) / dataSpan
	        ];
	        return function (val) {
	            return val >= range[0] && val <= range[1];
	        };
	    }

	    function isGeoCoordSys(coordSys) {
	        var dimensions = coordSys.dimensions;
	        // Not use coorSys.type === 'geo' because coordSys maybe extended
	        return dimensions[0] === 'lng' && dimensions[1] === 'lat';
	    }

	    module.exports = __webpack_require__(1).extendChartView({

	        type: 'heatmap',

	        render: function (seriesModel, ecModel, api) {
	            var visualMapOfThisSeries;
	            ecModel.eachComponent('visualMap', function (visualMap) {
	                visualMap.eachTargetSeries(function (targetSeries) {
	                    if (targetSeries === seriesModel) {
	                        visualMapOfThisSeries = visualMap;
	                    }
	                });
	            });

	            if (true) {
	                if (!visualMapOfThisSeries) {
	                    throw new Error('Heatmap must use with visualMap');
	                }
	            }

	            this.group.removeAll();
	            var coordSys = seriesModel.coordinateSystem;
	            if (coordSys.type === 'cartesian2d' || coordSys.type === 'calendar') {
	                this._renderOnCartesianAndCalendar(coordSys, seriesModel, api);
	            }
	            else if (isGeoCoordSys(coordSys)) {
	                this._renderOnGeo(
	                    coordSys, seriesModel, visualMapOfThisSeries, api
	                );
	            }
	        },

	        dispose: function () {},

	        _renderOnCartesianAndCalendar: function (coordSys, seriesModel, api) {

	            if (coordSys.type === 'cartesian2d') {
	                var xAxis = coordSys.getAxis('x');
	                var yAxis = coordSys.getAxis('y');

	                if (true) {
	                    if (!(xAxis.type === 'category' && yAxis.type === 'category')) {
	                        throw new Error('Heatmap on cartesian must have two category axes');
	                    }
	                    if (!(xAxis.onBand && yAxis.onBand)) {
	                        throw new Error('Heatmap on cartesian must have two axes with boundaryGap true');
	                    }
	                }

	                var width = xAxis.getBandWidth();
	                var height = yAxis.getBandWidth();

	            }

	            var group = this.group;
	            var data = seriesModel.getData();

	            var itemStyleQuery = 'itemStyle.normal';
	            var hoverItemStyleQuery = 'itemStyle.emphasis';
	            var labelQuery = 'label.normal';
	            var hoverLabelQuery = 'label.emphasis';
	            var style = seriesModel.getModel(itemStyleQuery).getItemStyle(['color']);
	            var hoverStl = seriesModel.getModel(hoverItemStyleQuery).getItemStyle();
	            var labelModel = seriesModel.getModel('label.normal');
	            var hoverLabelModel = seriesModel.getModel('label.emphasis');
	            var coordSysType = coordSys.type;

	            var dataDims = coordSysType === 'cartesian2d'
	                ? [
	                    seriesModel.coordDimToDataDim('x')[0],
	                    seriesModel.coordDimToDataDim('y')[0],
	                    seriesModel.coordDimToDataDim('value')[0]
	                ]
	                : [
	                    seriesModel.coordDimToDataDim('time')[0],
	                    seriesModel.coordDimToDataDim('value')[0]
	                ];

	            data.each(function (idx) {
	                var rect;

	                if (coordSysType === 'cartesian2d') {
	                    // Ignore empty data
	                    if (isNaN(data.get(dataDims[2], idx))) {
	                        return;
	                    }

	                    var point = coordSys.dataToPoint([
	                        data.get(dataDims[0], idx),
	                        data.get(dataDims[1], idx)
	                    ]);

	                    rect = new graphic.Rect({
	                        shape: {
	                            x: point[0] - width / 2,
	                            y: point[1] - height / 2,
	                            width: width,
	                            height: height
	                        },
	                        style: {
	                            fill: data.getItemVisual(idx, 'color'),
	                            opacity: data.getItemVisual(idx, 'opacity')
	                        }
	                    });
	                }
	                else {
	                    // Ignore empty data
	                    if (isNaN(data.get(dataDims[1], idx))) {
	                        return;
	                    }

	                    rect = new graphic.Rect({
	                        z2: 1,
	                        shape: coordSys.dataToRect([data.get(dataDims[0], idx)]).contentShape,
	                        style: {
	                            fill: data.getItemVisual(idx, 'color'),
	                            opacity: data.getItemVisual(idx, 'opacity')
	                        }
	                    });
	                }

	                var itemModel = data.getItemModel(idx);

	                // Optimization for large datset
	                if (data.hasItemOption) {
	                    style = itemModel.getModel(itemStyleQuery).getItemStyle(['color']);
	                    hoverStl = itemModel.getModel(hoverItemStyleQuery).getItemStyle();
	                    labelModel = itemModel.getModel(labelQuery);
	                    hoverLabelModel = itemModel.getModel(hoverLabelQuery);
	                }

	                var rawValue = seriesModel.getRawValue(idx);
	                var defaultText = '-';
	                if (rawValue && rawValue[2] != null) {
	                    defaultText = rawValue[2];
	                }
	                if (labelModel.getShallow('show')) {
	                    graphic.setText(style, labelModel);
	                    style.text = seriesModel.getFormattedLabel(idx, 'normal') || defaultText;
	                }
	                if (hoverLabelModel.getShallow('show')) {
	                    graphic.setText(hoverStl, hoverLabelModel);
	                    hoverStl.text = seriesModel.getFormattedLabel(idx, 'emphasis') || defaultText;
	                }

	                rect.setStyle(style);

	                graphic.setHoverStyle(rect, data.hasItemOption ? hoverStl : zrUtil.extend({}, hoverStl));

	                group.add(rect);
	                data.setItemGraphicEl(idx, rect);
	            });
	        },

	        _renderOnGeo: function (geo, seriesModel, visualMapModel, api) {
	            var inRangeVisuals = visualMapModel.targetVisuals.inRange;
	            var outOfRangeVisuals = visualMapModel.targetVisuals.outOfRange;
	            // if (!visualMapping) {
	            //     throw new Error('Data range must have color visuals');
	            // }

	            var data = seriesModel.getData();
	            var hmLayer = this._hmLayer || (this._hmLayer || new HeatmapLayer());
	            hmLayer.blurSize = seriesModel.get('blurSize');
	            hmLayer.pointSize = seriesModel.get('pointSize');
	            hmLayer.minOpacity = seriesModel.get('minOpacity');
	            hmLayer.maxOpacity = seriesModel.get('maxOpacity');

	            var rect = geo.getViewRect().clone();
	            var roamTransform = geo.getRoamTransform().transform;
	            rect.applyTransform(roamTransform);

	            // Clamp on viewport
	            var x = Math.max(rect.x, 0);
	            var y = Math.max(rect.y, 0);
	            var x2 = Math.min(rect.width + rect.x, api.getWidth());
	            var y2 = Math.min(rect.height + rect.y, api.getHeight());
	            var width = x2 - x;
	            var height = y2 - y;

	            var points = data.mapArray(['lng', 'lat', 'value'], function (lng, lat, value) {
	                var pt = geo.dataToPoint([lng, lat]);
	                pt[0] -= x;
	                pt[1] -= y;
	                pt.push(value);
	                return pt;
	            });

	            var dataExtent = visualMapModel.getExtent();
	            var isInRange = visualMapModel.type === 'visualMap.continuous'
	                ? getIsInContinuousRange(dataExtent, visualMapModel.option.range)
	                : getIsInPiecewiseRange(
	                    dataExtent, visualMapModel.getPieceList(), visualMapModel.option.selected
	                );

	            hmLayer.update(
	                points, width, height,
	                inRangeVisuals.color.getNormalizer(),
	                {
	                    inRange: inRangeVisuals.color.getColorMapper(),
	                    outOfRange: outOfRangeVisuals.color.getColorMapper()
	                },
	                isInRange
	            );
	            var img = new graphic.Image({
	                style: {
	                    width: width,
	                    height: height,
	                    x: x,
	                    y: y,
	                    image: hmLayer.canvas
	                },
	                silent: true
	            });
	            this.group.add(img);
	        }
	    });



/***/ },
/* 286 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @file defines echarts Heatmap Chart
	 * @author Ovilia (me@zhangwenli.com)
	 * Inspired by https://github.com/mourner/simpleheat
	 *
	 * @module
	 */


	    var GRADIENT_LEVELS = 256;
	    var zrUtil = __webpack_require__(4);

	    /**
	     * Heatmap Chart
	     *
	     * @class
	     */
	    function Heatmap() {
	        var canvas = zrUtil.createCanvas();
	        this.canvas = canvas;

	        this.blurSize = 30;
	        this.pointSize = 20;

	        this.maxOpacity = 1;
	        this.minOpacity = 0;

	        this._gradientPixels = {};
	    }

	    Heatmap.prototype = {
	        /**
	         * Renders Heatmap and returns the rendered canvas
	         * @param {Array} data array of data, each has x, y, value
	         * @param {number} width canvas width
	         * @param {number} height canvas height
	         */
	        update: function(data, width, height, normalize, colorFunc, isInRange) {
	            var brush = this._getBrush();
	            var gradientInRange = this._getGradient(data, colorFunc, 'inRange');
	            var gradientOutOfRange = this._getGradient(data, colorFunc, 'outOfRange');
	            var r = this.pointSize + this.blurSize;

	            var canvas = this.canvas;
	            var ctx = canvas.getContext('2d');
	            var len = data.length;
	            canvas.width = width;
	            canvas.height = height;
	            for (var i = 0; i < len; ++i) {
	                var p = data[i];
	                var x = p[0];
	                var y = p[1];
	                var value = p[2];

	                // calculate alpha using value
	                var alpha = normalize(value);

	                // draw with the circle brush with alpha
	                ctx.globalAlpha = alpha;
	                ctx.drawImage(brush, x - r, y - r);
	            }

	            // colorize the canvas using alpha value and set with gradient
	            var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
	            var pixels = imageData.data;
	            var offset = 0;
	            var pixelLen = pixels.length;
	            var minOpacity = this.minOpacity;
	            var maxOpacity = this.maxOpacity;
	            var diffOpacity = maxOpacity - minOpacity;

	            while(offset < pixelLen) {
	                var alpha = pixels[offset + 3] / 256;
	                var gradientOffset = Math.floor(alpha * (GRADIENT_LEVELS - 1)) * 4;
	                // Simple optimize to ignore the empty data
	                if (alpha > 0) {
	                    var gradient = isInRange(alpha) ? gradientInRange : gradientOutOfRange;
	                    // Any alpha > 0 will be mapped to [minOpacity, maxOpacity]
	                    alpha > 0 && (alpha = alpha * diffOpacity + minOpacity);
	                    pixels[offset++] = gradient[gradientOffset];
	                    pixels[offset++] = gradient[gradientOffset + 1];
	                    pixels[offset++] = gradient[gradientOffset + 2];
	                    pixels[offset++] = gradient[gradientOffset + 3] * alpha * 256;
	                }
	                else {
	                    offset += 4;
	                }
	            }
	            ctx.putImageData(imageData, 0, 0);

	            return canvas;
	        },

	        /**
	         * get canvas of a black circle brush used for canvas to draw later
	         * @private
	         * @returns {Object} circle brush canvas
	         */
	        _getBrush: function() {
	            var brushCanvas = this._brushCanvas || (this._brushCanvas = zrUtil.createCanvas());
	            // set brush size
	            var r = this.pointSize + this.blurSize;
	            var d = r * 2;
	            brushCanvas.width = d;
	            brushCanvas.height = d;

	            var ctx = brushCanvas.getContext('2d');
	            ctx.clearRect(0, 0, d, d);

	            // in order to render shadow without the distinct circle,
	            // draw the distinct circle in an invisible place,
	            // and use shadowOffset to draw shadow in the center of the canvas
	            ctx.shadowOffsetX = d;
	            ctx.shadowBlur = this.blurSize;
	            // draw the shadow in black, and use alpha and shadow blur to generate
	            // color in color map
	            ctx.shadowColor = '#000';

	            // draw circle in the left to the canvas
	            ctx.beginPath();
	            ctx.arc(-r, r, this.pointSize, 0, Math.PI * 2, true);
	            ctx.closePath();
	            ctx.fill();
	            return brushCanvas;
	        },

	        /**
	         * get gradient color map
	         * @private
	         */
	        _getGradient: function (data, colorFunc, state) {
	            var gradientPixels = this._gradientPixels;
	            var pixelsSingleState = gradientPixels[state] || (gradientPixels[state] = new Uint8ClampedArray(256 * 4));
	            var color = [0, 0, 0, 0];
	            var off = 0;
	            for (var i = 0; i < 256; i++) {
	                colorFunc[state](i / 255, true, color);
	                pixelsSingleState[off++] = color[0];
	                pixelsSingleState[off++] = color[1];
	                pixelsSingleState[off++] = color[2];
	                pixelsSingleState[off++] = color[3];
	            }
	            return pixelsSingleState;
	        }
	    };

	    module.exports = Heatmap;



/***/ },
/* 287 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);

	    __webpack_require__(125);

	    __webpack_require__(288);
	    __webpack_require__(289);

	    var barLayoutGrid = __webpack_require__(145);
	    var echarts = __webpack_require__(1);

	    echarts.registerLayout(zrUtil.curry(barLayoutGrid, 'pictorialBar'));

	    echarts.registerVisual(zrUtil.curry(
	        __webpack_require__(121), 'pictorialBar', 'roundRect', null
	    ));

	    // In case developer forget to include grid component
	    __webpack_require__(124);


/***/ },
/* 288 */
/***/ function(module, exports, __webpack_require__) {

	

	    var PictorialBarSeries = __webpack_require__(141).extend({

	        type: 'series.pictorialBar',

	        dependencies: ['grid'],

	        defaultOption: {
	            symbol: 'circle',     // Customized bar shape
	            symbolSize: null,     // Can be ['100%', '100%'], null means auto.
	            symbolRotate: null,

	            symbolPosition: null, // 'start' or 'end' or 'center', null means auto.
	            symbolOffset: null,
	            symbolMargin: null,   // start margin and end margin. Can be a number or a percent string.
	                                  // Auto margin by defualt.
	            symbolRepeat: false,  // false/null/undefined, means no repeat.
	                                  // Can be true, means auto calculate repeat times and cut by data.
	                                  // Can be a number, specifies repeat times, and do not cut by data.
	                                  // Can be 'fixed', means auto calculate repeat times but do not cut by data.
	            symbolRepeatDirection: 'end', // 'end' means from 'start' to 'end'.

	            symbolClip: false,
	            symbolBoundingData: null, // Can be 60 or -40 or [-40, 60]
	            symbolPatternSize: 400, // 400 * 400 px

	            barGap: '-100%',      // In most case, overlap is needed.

	            // z can be set in data item, which is z2 actually.

	            // Disable progressive
	            progressive: 0,
	            hoverAnimation: false // Open only when needed.
	        },

	        getInitialData: function (option) {
	            // Disable stack.
	            option.stack = null;
	            return PictorialBarSeries.superApply(this, 'getInitialData', arguments);
	        }
	    });

	    module.exports = PictorialBarSeries;


/***/ },
/* 289 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);
	    var graphic = __webpack_require__(18);
	    var symbolUtil = __webpack_require__(111);
	    var numberUtil = __webpack_require__(7);
	    var helper = __webpack_require__(143);

	    var parsePercent = numberUtil.parsePercent;

	    var BAR_BORDER_WIDTH_QUERY = ['itemStyle', 'normal', 'borderWidth'];

	    // index: +isHorizontal
	    var LAYOUT_ATTRS = [
	        {xy: 'x', wh: 'width', index: 0, posDesc: ['left', 'right']},
	        {xy: 'y', wh: 'height', index: 1, posDesc: ['top', 'bottom']}
	    ];

	    var pathForLineWidth = new graphic.Circle();

	    var BarView = __webpack_require__(1).extendChartView({

	        type: 'pictorialBar',

	        render: function (seriesModel, ecModel, api) {
	            var group = this.group;
	            var data = seriesModel.getData();
	            var oldData = this._data;

	            var cartesian = seriesModel.coordinateSystem;
	            var baseAxis = cartesian.getBaseAxis();
	            var isHorizontal = !!baseAxis.isHorizontal();
	            var coordSysRect = cartesian.grid.getRect();

	            var opt = {
	                ecSize: {width: api.getWidth(), height: api.getHeight()},
	                seriesModel: seriesModel,
	                coordSys: cartesian,
	                coordSysExtent: [
	                    [coordSysRect.x, coordSysRect.x + coordSysRect.width],
	                    [coordSysRect.y, coordSysRect.y + coordSysRect.height]
	                ],
	                isHorizontal: isHorizontal,
	                valueDim: LAYOUT_ATTRS[+isHorizontal],
	                categoryDim: LAYOUT_ATTRS[1 - isHorizontal]
	            };

	            data.diff(oldData)
	                .add(function (dataIndex) {
	                    if (!data.hasValue(dataIndex)) {
	                        return;
	                    }

	                    var itemModel = getItemModel(data, dataIndex);
	                    var symbolMeta = getSymbolMeta(data, dataIndex, itemModel, opt);

	                    var bar = createBar(data, opt, symbolMeta);

	                    data.setItemGraphicEl(dataIndex, bar);
	                    group.add(bar);

	                    updateCommon(bar, opt, symbolMeta);
	                })
	                .update(function (newIndex, oldIndex) {
	                    var bar = oldData.getItemGraphicEl(oldIndex);

	                    if (!data.hasValue(newIndex)) {
	                        group.remove(bar);
	                        return;
	                    }

	                    var itemModel = getItemModel(data, newIndex);
	                    var symbolMeta = getSymbolMeta(data, newIndex, itemModel, opt);

	                    var pictorialShapeStr = getShapeStr(data, symbolMeta);
	                    if (bar && pictorialShapeStr !== bar.__pictorialShapeStr) {
	                        group.remove(bar);
	                        data.setItemGraphicEl(newIndex, null);
	                        bar = null;
	                    }

	                    if (bar) {
	                        updateBar(bar, opt, symbolMeta);
	                    }
	                    else {
	                        bar = createBar(data, opt, symbolMeta, true);
	                    }

	                    data.setItemGraphicEl(newIndex, bar);
	                    bar.__pictorialSymbolMeta = symbolMeta;
	                    // Add back
	                    group.add(bar);

	                    updateCommon(bar, opt, symbolMeta);
	                })
	                .remove(function (dataIndex) {
	                    var bar = oldData.getItemGraphicEl(dataIndex);
	                    bar && removeBar(oldData, dataIndex, bar.__pictorialSymbolMeta.animationModel, bar);
	                })
	                .execute();

	            this._data = data;

	            return this.group;
	        },

	        dispose: zrUtil.noop,

	        remove: function (ecModel, api) {
	            var group = this.group;
	            var data = this._data;
	            if (ecModel.get('animation')) {
	                if (data) {
	                    data.eachItemGraphicEl(function (bar) {
	                        removeBar(data, bar.dataIndex, ecModel, bar);
	                    });
	                }
	            }
	            else {
	                group.removeAll();
	            }
	        }
	    });


	    // Set or calculate default value about symbol, and calculate layout info.
	    function getSymbolMeta(data, dataIndex, itemModel, opt) {
	        var layout = data.getItemLayout(dataIndex);
	        var symbolRepeat = itemModel.get('symbolRepeat');
	        var symbolClip = itemModel.get('symbolClip');
	        var symbolPosition = itemModel.get('symbolPosition') || 'start';
	        var symbolRotate = itemModel.get('symbolRotate');
	        var rotation = (symbolRotate || 0) * Math.PI / 180 || 0;
	        var symbolPatternSize = itemModel.get('symbolPatternSize') || 2;
	        var isAnimationEnabled = itemModel.isAnimationEnabled();

	        var symbolMeta = {
	            dataIndex: dataIndex,
	            layout: layout,
	            itemModel: itemModel,
	            symbolType: data.getItemVisual(dataIndex, 'symbol') || 'circle',
	            color: data.getItemVisual(dataIndex, 'color'),
	            symbolClip: symbolClip,
	            symbolRepeat: symbolRepeat,
	            symbolRepeatDirection: itemModel.get('symbolRepeatDirection'),
	            symbolPatternSize: symbolPatternSize,
	            rotation: rotation,
	            animationModel: isAnimationEnabled ? itemModel : null,
	            hoverAnimation: isAnimationEnabled && itemModel.get('hoverAnimation'),
	            z2: itemModel.getShallow('z', true) || 0
	        };

	        prepareBarLength(itemModel, symbolRepeat, layout, opt, symbolMeta);

	        prepareSymbolSize(
	            data, dataIndex, layout, symbolRepeat, symbolClip, symbolMeta.boundingLength,
	            symbolMeta.pxSign, symbolPatternSize, opt, symbolMeta
	        );

	        prepareLineWidth(itemModel, symbolMeta.symbolScale, rotation, opt, symbolMeta);

	        var symbolSize = symbolMeta.symbolSize;
	        var symbolOffset = itemModel.get('symbolOffset');
	        if (zrUtil.isArray(symbolOffset)) {
	            symbolOffset = [
	                parsePercent(symbolOffset[0], symbolSize[0]),
	                parsePercent(symbolOffset[1], symbolSize[1])
	            ];
	        }

	        prepareLayoutInfo(
	            itemModel, symbolSize, layout, symbolRepeat, symbolClip, symbolOffset,
	            symbolPosition, symbolMeta.valueLineWidth, symbolMeta.boundingLength, symbolMeta.repeatCutLength,
	            opt, symbolMeta
	        );

	        return symbolMeta;
	    }

	    // bar length can be negative.
	    function prepareBarLength(itemModel, symbolRepeat, layout, opt, output) {
	        var valueDim = opt.valueDim;
	        var symbolBoundingData = itemModel.get('symbolBoundingData');
	        var valueAxis = opt.coordSys.getOtherAxis(opt.coordSys.getBaseAxis());
	        var zeroPx = valueAxis.toGlobalCoord(valueAxis.dataToCoord(0));
	        var pxSignIdx = 1 - +(layout[valueDim.wh] <= 0);
	        var boundingLength;

	        if (zrUtil.isArray(symbolBoundingData)) {
	            var symbolBoundingExtent = [
	                convertToCoordOnAxis(valueAxis, symbolBoundingData[0]) - zeroPx,
	                convertToCoordOnAxis(valueAxis, symbolBoundingData[1]) - zeroPx
	            ];
	            symbolBoundingExtent[1] < symbolBoundingExtent[0] && (symbolBoundingExtent.reverse());
	            boundingLength = symbolBoundingExtent[pxSignIdx];
	        }
	        else if (symbolBoundingData != null) {
	            boundingLength = convertToCoordOnAxis(valueAxis, symbolBoundingData) - zeroPx;
	        }
	        else if (symbolRepeat) {
	            boundingLength = opt.coordSysExtent[valueDim.index][pxSignIdx] - zeroPx;
	        }
	        else {
	            boundingLength = layout[valueDim.wh];
	        }

	        output.boundingLength = boundingLength;

	        if (symbolRepeat) {
	            output.repeatCutLength = layout[valueDim.wh];
	        }

	        output.pxSign = boundingLength > 0 ? 1 : boundingLength < 0 ? -1 : 0;
	    }

	    function convertToCoordOnAxis(axis, value) {
	        return axis.toGlobalCoord(axis.dataToCoord(axis.scale.parse(value)));
	    }

	    // Support ['100%', '100%']
	    function prepareSymbolSize(
	        data, dataIndex, layout, symbolRepeat, symbolClip, boundingLength,
	        pxSign, symbolPatternSize, opt, output
	    ) {
	        var valueDim = opt.valueDim;
	        var categoryDim = opt.categoryDim;
	        var categorySize = Math.abs(layout[categoryDim.wh]);

	        var symbolSize = data.getItemVisual(dataIndex, 'symbolSize');
	        if (zrUtil.isArray(symbolSize)) {
	            symbolSize = symbolSize.slice();
	        }
	        else {
	            if (symbolSize == null) {
	                symbolSize = '100%';
	            }
	            symbolSize = [symbolSize, symbolSize];
	        }

	        // Note: percentage symbolSize (like '100%') do not consider lineWidth, because it is
	        // to complicated to calculate real percent value if considering scaled lineWidth.
	        // So the actual size will bigger than layout size if lineWidth is bigger than zero,
	        // which can be tolerated in pictorial chart.

	        symbolSize[categoryDim.index] = parsePercent(
	            symbolSize[categoryDim.index],
	            categorySize
	        );
	        symbolSize[valueDim.index] = parsePercent(
	            symbolSize[valueDim.index],
	            symbolRepeat ? categorySize : Math.abs(boundingLength)
	        );

	        output.symbolSize = symbolSize;

	        // If x or y is less than zero, show reversed shape.
	        var symbolScale = output.symbolScale = [
	            symbolSize[0] / symbolPatternSize,
	            symbolSize[1] / symbolPatternSize
	        ];
	        // Follow convention, 'right' and 'top' is the normal scale.
	        symbolScale[valueDim.index] *= (opt.isHorizontal ? -1 : 1) * pxSign;
	    }

	    function prepareLineWidth(itemModel, symbolScale, rotation, opt, output) {
	        // In symbols are drawn with scale, so do not need to care about the case that width
	        // or height are too small. But symbol use strokeNoScale, where acture lineWidth should
	        // be calculated.
	        var valueLineWidth = itemModel.get(BAR_BORDER_WIDTH_QUERY) || 0;

	        if (valueLineWidth) {
	            pathForLineWidth.attr({
	                scale: symbolScale.slice(),
	                rotation: rotation
	            });
	            pathForLineWidth.updateTransform();
	            valueLineWidth /= pathForLineWidth.getLineScale();
	            valueLineWidth *= symbolScale[opt.valueDim.index];
	        }

	        output.valueLineWidth = valueLineWidth;
	    }

	    function prepareLayoutInfo(
	        itemModel, symbolSize, layout, symbolRepeat, symbolClip, symbolOffset,
	        symbolPosition, valueLineWidth, boundingLength, repeatCutLength, opt, output
	    ) {
	        var categoryDim = opt.categoryDim;
	        var valueDim = opt.valueDim;
	        var pxSign = output.pxSign;

	        var unitLength = Math.max(symbolSize[valueDim.index] + valueLineWidth, 0);
	        var pathLen = unitLength;

	        // Note: rotation will not effect the layout of symbols, because user may
	        // want symbols to rotate on its center, which should not be translated
	        // when rotating.

	        if (symbolRepeat) {
	            var absBoundingLength = Math.abs(boundingLength);

	            var symbolMargin = zrUtil.retrieve(itemModel.get('symbolMargin'), '15%') + '';
	            var hasEndGap = false;
	            if (symbolMargin.lastIndexOf('!') === symbolMargin.length - 1) {
	                hasEndGap = true;
	                symbolMargin = symbolMargin.slice(0, symbolMargin.length - 1);
	            }
	            symbolMargin = parsePercent(symbolMargin, symbolSize[valueDim.index]);

	            var uLenWithMargin = Math.max(unitLength + symbolMargin * 2, 0);

	            // When symbol margin is less than 0, margin at both ends will be subtracted
	            // to ensure that all of the symbols will not be overflow the given area.
	            var endFix = hasEndGap ? 0 : symbolMargin * 2;

	            // Both final repeatTimes and final symbolMargin area calculated based on
	            // boundingLength.
	            var repeatSpecified = numberUtil.isNumeric(symbolRepeat);
	            var repeatTimes = repeatSpecified
	                ? symbolRepeat
	                : toIntTimes((absBoundingLength + endFix) / uLenWithMargin);

	            // Adjust calculate margin, to ensure each symbol is displayed
	            // entirely in the given layout area.
	            var mDiff = absBoundingLength - repeatTimes * unitLength;
	            symbolMargin = mDiff / 2 / (hasEndGap ? repeatTimes : repeatTimes - 1);
	            uLenWithMargin = unitLength + symbolMargin * 2;
	            endFix = hasEndGap ? 0 : symbolMargin * 2;

	            // Update repeatTimes when not all symbol will be shown.
	            if (!repeatSpecified && symbolRepeat !== 'fixed') {
	                repeatTimes = repeatCutLength
	                    ? toIntTimes((Math.abs(repeatCutLength) + endFix) / uLenWithMargin)
	                    : 0;
	            }

	            pathLen = repeatTimes * uLenWithMargin - endFix;
	            output.repeatTimes = repeatTimes;
	            output.symbolMargin = symbolMargin;
	        }

	        var sizeFix = pxSign * (pathLen / 2);
	        var pathPosition = output.pathPosition = [];
	        pathPosition[categoryDim.index] = layout[categoryDim.wh] / 2;
	        pathPosition[valueDim.index] = symbolPosition === 'start'
	            ? sizeFix
	            : symbolPosition === 'end'
	            ? boundingLength - sizeFix
	            : boundingLength / 2; // 'center'
	        if (symbolOffset) {
	            pathPosition[0] += symbolOffset[0];
	            pathPosition[1] += symbolOffset[1];
	        }

	        var bundlePosition = output.bundlePosition = [];
	        bundlePosition[categoryDim.index] = layout[categoryDim.xy];
	        bundlePosition[valueDim.index] = layout[valueDim.xy];

	        var barRectShape = output.barRectShape = zrUtil.extend({}, layout);
	        barRectShape[valueDim.wh] = pxSign * Math.max(
	            Math.abs(layout[valueDim.wh]), Math.abs(pathPosition[valueDim.index] + sizeFix)
	        );
	        barRectShape[categoryDim.wh] = layout[categoryDim.wh];

	        var clipShape = output.clipShape = {};
	        // Consider that symbol may be overflow layout rect.
	        clipShape[categoryDim.xy] = -layout[categoryDim.xy];
	        clipShape[categoryDim.wh] = opt.ecSize[categoryDim.wh];
	        clipShape[valueDim.xy] = 0;
	        clipShape[valueDim.wh] = layout[valueDim.wh];
	    }

	    function createPath(symbolMeta) {
	        var symbolPatternSize = symbolMeta.symbolPatternSize;
	        var path = symbolUtil.createSymbol(
	            // Consider texture img, make a big size.
	            symbolMeta.symbolType,
	            -symbolPatternSize / 2,
	            -symbolPatternSize / 2,
	            symbolPatternSize,
	            symbolPatternSize,
	            symbolMeta.color
	        );
	        path.attr({
	            culling: true
	        });
	        path.type !== 'image' && path.setStyle({
	            strokeNoScale: true
	        });

	        return path;
	    }

	    function createOrUpdateRepeatSymbols(bar, opt, symbolMeta, isUpdate) {
	        var bundle = bar.__pictorialBundle;
	        var symbolSize = symbolMeta.symbolSize;
	        var valueLineWidth = symbolMeta.valueLineWidth;
	        var pathPosition = symbolMeta.pathPosition;
	        var valueDim = opt.valueDim;
	        var repeatTimes = symbolMeta.repeatTimes || 0;

	        var index = 0;
	        var unit = symbolSize[opt.valueDim.index] + valueLineWidth + symbolMeta.symbolMargin * 2;

	        eachPath(bar, function (path) {
	            path.__pictorialAnimationIndex = index;
	            path.__pictorialRepeatTimes = repeatTimes;
	            if (index < repeatTimes) {
	                updateAttr(path, null, makeTarget(index), symbolMeta, isUpdate);
	            }
	            else {
	                updateAttr(path, null, {scale: [0, 0]}, symbolMeta, isUpdate, function () {
	                    bundle.remove(path);
	                });
	            }

	            updateHoverAnimation(path, symbolMeta);

	            index++;
	        });

	        for (; index < repeatTimes; index++) {
	            var path = createPath(symbolMeta);
	            path.__pictorialAnimationIndex = index;
	            path.__pictorialRepeatTimes = repeatTimes;
	            bundle.add(path);

	            var target = makeTarget(index, true);

	            updateAttr(
	                path,
	                {
	                    position: target.position,
	                    scale: [0, 0]
	                },
	                {
	                    scale: target.scale,
	                    rotation: target.rotation
	                },
	                symbolMeta,
	                isUpdate
	            );

	            // FIXME
	            // If all emphasis/normal through action.
	            path
	                .on('mouseover', onMouseOver)
	                .on('mouseout', onMouseOut);

	            updateHoverAnimation(path, symbolMeta);
	        }

	        function makeTarget(index) {
	            var position = pathPosition.slice();
	            // (start && pxSign > 0) || (end && pxSign < 0): i = repeatTimes - index
	            // Otherwise: i = index;
	            var pxSign = symbolMeta.pxSign;
	            var i = index;
	            if (symbolMeta.symbolRepeatDirection === 'start' ? pxSign > 0 : pxSign < 0) {
	                i = repeatTimes - 1 - index;
	            }
	            position[valueDim.index] = unit * (i - repeatTimes / 2 + 0.5) + pathPosition[valueDim.index];

	            return {
	                position: position,
	                scale: symbolMeta.symbolScale.slice(),
	                rotation: symbolMeta.rotation
	            };
	        }

	        function onMouseOver() {
	            eachPath(bar, function (path) {
	                path.trigger('emphasis');
	            });
	        }

	        function onMouseOut() {
	            eachPath(bar, function (path) {
	                path.trigger('normal');
	            });
	        }
	    }

	    function createOrUpdateSingleSymbol(bar, opt, symbolMeta, isUpdate) {
	        var bundle = bar.__pictorialBundle;
	        var mainPath = bar.__pictorialMainPath;

	        if (!mainPath) {
	            mainPath = bar.__pictorialMainPath = createPath(symbolMeta);
	            bundle.add(mainPath);

	            updateAttr(
	                mainPath,
	                {
	                    position: symbolMeta.pathPosition.slice(),
	                    scale: [0, 0],
	                    rotation: symbolMeta.rotation
	                },
	                {
	                    scale: symbolMeta.symbolScale.slice()
	                },
	                symbolMeta,
	                isUpdate
	            );

	            mainPath
	                .on('mouseover', onMouseOver)
	                .on('mouseout', onMouseOut);
	        }
	        else {
	            updateAttr(
	                mainPath,
	                null,
	                {
	                    position: symbolMeta.pathPosition.slice(),
	                    scale: symbolMeta.symbolScale.slice(),
	                    rotation: symbolMeta.rotation
	                },
	                symbolMeta,
	                isUpdate
	            );
	        }

	        updateHoverAnimation(mainPath, symbolMeta);

	        function onMouseOver() {
	            this.trigger('emphasis');
	        }

	        function onMouseOut() {
	            this.trigger('normal');
	        }
	    }

	    // bar rect is used for label.
	    function createOrUpdateBarRect(bar, symbolMeta, isUpdate) {
	        var rectShape = zrUtil.extend({}, symbolMeta.barRectShape);

	        var barRect = bar.__pictorialBarRect;
	        if (!barRect) {
	            barRect = bar.__pictorialBarRect = new graphic.Rect({
	                z2: 2,
	                shape: rectShape,
	                silent: true,
	                style: {
	                    stroke: 'transparent',
	                    fill: 'transparent',
	                    lineWidth: 0
	                }
	            });

	            bar.add(barRect);
	        }
	        else {
	            updateAttr(barRect, null, {shape: rectShape}, symbolMeta, isUpdate);
	        }
	    }

	    function createOrUpdateClip(bar, opt, symbolMeta, isUpdate) {
	        // If not clip, symbol will be remove and rebuilt.
	        if (symbolMeta.symbolClip) {
	            var clipPath = bar.__pictorialClipPath;
	            var clipShape = zrUtil.extend({}, symbolMeta.clipShape);
	            var valueDim = opt.valueDim;
	            var animationModel = symbolMeta.animationModel;
	            var dataIndex = symbolMeta.dataIndex;

	            if (clipPath) {
	                graphic.updateProps(
	                    clipPath, {shape: clipShape}, animationModel, dataIndex
	                );
	            }
	            else {
	                clipShape[valueDim.wh] = 0;
	                clipPath = new graphic.Rect({shape: clipShape});
	                bar.__pictorialBundle.setClipPath(clipPath);
	                bar.__pictorialClipPath = clipPath;

	                var target = {};
	                target[valueDim.wh] = symbolMeta.clipShape[valueDim.wh];

	                graphic[isUpdate ? 'updateProps' : 'initProps'](
	                    clipPath, {shape: target}, animationModel, dataIndex
	                );
	            }
	        }
	    }

	    function getItemModel(data, dataIndex) {
	        var itemModel = data.getItemModel(dataIndex);
	        itemModel.getAnimationDelayParams = getAnimationDelayParams;
	        itemModel.isAnimationEnabled = isAnimationEnabled;
	        return itemModel;
	    }

	    function getAnimationDelayParams(path) {
	        // The order is the same as the z-order, see `symbolRepeatDiretion`.
	        return {
	            index: path.__pictorialAnimationIndex,
	            count: path.__pictorialRepeatTimes
	        };
	    }

	    function isAnimationEnabled() {
	        // `animation` prop can be set on itemModel in pictorial bar chart.
	        return this.parentModel.isAnimationEnabled() && !!this.getShallow('animation');
	    }

	    function updateHoverAnimation(path, symbolMeta) {
	        path.off('emphasis').off('normal');

	        var scale = symbolMeta.symbolScale.slice();

	        symbolMeta.hoverAnimation && path
	            .on('emphasis', function() {
	                this.animateTo({
	                    scale: [scale[0] * 1.1, scale[1] * 1.1]
	                }, 400, 'elasticOut');
	            })
	            .on('normal', function() {
	                this.animateTo({
	                    scale: scale.slice()
	                }, 400, 'elasticOut');
	            });
	    }

	    function createBar(data, opt, symbolMeta, isUpdate) {
	        // bar is the main element for each data.
	        var bar = new graphic.Group();
	        // bundle is used for location and clip.
	        var bundle = new graphic.Group();
	        bar.add(bundle);
	        bar.__pictorialBundle = bundle;
	        bundle.attr('position', symbolMeta.bundlePosition.slice());

	        if (symbolMeta.symbolRepeat) {
	            createOrUpdateRepeatSymbols(bar, opt, symbolMeta);
	        }
	        else {
	            createOrUpdateSingleSymbol(bar, opt, symbolMeta);
	        }

	        createOrUpdateBarRect(bar, symbolMeta, isUpdate);

	        createOrUpdateClip(bar, opt, symbolMeta, isUpdate);

	        bar.__pictorialShapeStr = getShapeStr(data, symbolMeta);
	        bar.__pictorialSymbolMeta = symbolMeta;

	        return bar;
	    }

	    function updateBar(bar, opt, symbolMeta) {
	        var animationModel = symbolMeta.animationModel;
	        var dataIndex = symbolMeta.dataIndex;
	        var bundle = bar.__pictorialBundle;

	        graphic.updateProps(
	            bundle, {position: symbolMeta.bundlePosition.slice()}, animationModel, dataIndex
	        );

	        if (symbolMeta.symbolRepeat) {
	            createOrUpdateRepeatSymbols(bar, opt, symbolMeta, true);
	        }
	        else {
	            createOrUpdateSingleSymbol(bar, opt, symbolMeta, true);
	        }

	        createOrUpdateBarRect(bar, symbolMeta, true);

	        createOrUpdateClip(bar, opt, symbolMeta, true);
	    }

	    function removeBar(data, dataIndex, animationModel, bar) {
	        // Not show text when animating
	        var labelRect = bar.__pictorialBarRect;
	        labelRect && (labelRect.style.text = '');

	        var pathes = [];
	        eachPath(bar, function (path) {
	            pathes.push(path);
	        });
	        bar.__pictorialMainPath && pathes.push(bar.__pictorialMainPath);

	        // I do not find proper remove animation for clip yet.
	        bar.__pictorialClipPath && (animationModel = null);

	        zrUtil.each(pathes, function (path) {
	            graphic.updateProps(
	                path, {scale: [0, 0]}, animationModel, dataIndex,
	                function () {
	                    bar.parent && bar.parent.remove(bar);
	                }
	            );
	        });

	        data.setItemGraphicEl(dataIndex, null);
	    }

	    function getShapeStr(data, symbolMeta) {
	        return [
	            data.getItemVisual(symbolMeta.dataIndex, 'symbol') || 'none',
	            !!symbolMeta.symbolRepeat,
	            !!symbolMeta.symbolClip
	        ].join(':');
	    }

	    function eachPath(bar, cb, context) {
	        // Do not use Group#eachChild, because it do not support remove.
	        zrUtil.each(bar.__pictorialBundle.children(), function (el) {
	            el !== bar.__pictorialBarRect && cb.call(context, el);
	        });
	    }

	    function updateAttr(el, immediateAttrs, animationAttrs, symbolMeta, isUpdate, cb) {
	        immediateAttrs && el.attr(immediateAttrs);
	        // when symbolCip used, only clip path has init animation, otherwise it would be weird effect.
	        if (symbolMeta.symbolClip && !isUpdate) {
	            animationAttrs && el.attr(animationAttrs);
	        }
	        else {
	            animationAttrs && graphic[isUpdate ? 'updateProps' : 'initProps'](
	                el, animationAttrs, symbolMeta.animationModel, symbolMeta.dataIndex, cb
	            );
	        }
	    }

	    function updateCommon(bar, opt, symbolMeta) {
	        var color = symbolMeta.color;
	        var dataIndex = symbolMeta.dataIndex;
	        var itemModel = symbolMeta.itemModel;
	        // Color must be excluded.
	        // Because symbol provide setColor individually to set fill and stroke
	        var normalStyle = itemModel.getModel('itemStyle.normal').getItemStyle(['color']);
	        var hoverStyle = itemModel.getModel('itemStyle.emphasis').getItemStyle();
	        var cursorStyle = itemModel.getShallow('cursor');

	        eachPath(bar, function (path) {
	            // PENDING setColor should be before setStyle!!!
	            path.setColor(color);
	            path.setStyle(zrUtil.defaults(
	                {
	                    fill: color,
	                    opacity: symbolMeta.opacity
	                },
	                normalStyle
	            ));
	            graphic.setHoverStyle(path, hoverStyle);

	            cursorStyle && (path.cursor = cursorStyle);
	            path.z2 = symbolMeta.z2;
	        });

	        var barRectHoverStyle = {};
	        var barPositionOutside = opt.valueDim.posDesc[+(symbolMeta.boundingLength > 0)];
	        var barRect = bar.__pictorialBarRect;

	        helper.setLabel(
	            barRect.style, barRectHoverStyle, itemModel,
	            color, opt.seriesModel, dataIndex, barPositionOutside
	        );

	        graphic.setHoverStyle(barRect, barRectHoverStyle);
	    }

	    function toIntTimes(times) {
	        var roundedTimes = Math.round(times);
	        // Escapse accurate error
	        return Math.abs(times - roundedTimes) < 1e-4
	            ? roundedTimes
	            : Math.ceil(times);
	    }

	    module.exports = BarView;


/***/ },
/* 290 */
/***/ function(module, exports, __webpack_require__) {

	

	    var echarts = __webpack_require__(1);
	    var zrUtil = __webpack_require__(4);

	    __webpack_require__(291);

	    __webpack_require__(308);

	    __webpack_require__(309);

	    echarts.registerLayout(__webpack_require__(311));

	    echarts.registerVisual(__webpack_require__(312));

	    echarts.registerProcessor(
	        zrUtil.curry(__webpack_require__(154), 'themeRiver')
	    );


/***/ },
/* 291 */
/***/ function(module, exports, __webpack_require__) {

	

	    __webpack_require__(292);
	    __webpack_require__(295);
	    __webpack_require__(297);
	    __webpack_require__(298);

	    __webpack_require__(307);

	    var echarts = __webpack_require__(1);

	    echarts.extendComponentView({
	        type: 'single'
	    });



/***/ },
/* 292 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * Single coordinate system creator.
	 */


	    var Single = __webpack_require__(293);

	    /**
	     * Create single coordinate system and inject it into seriesModel.
	     *
	     * @param {module:echarts/model/Global} ecModel
	     * @param {module:echarts/ExtensionAPI} api
	     * @return {Array.<module:echarts/coord/single/Single>}
	     */
	    function create(ecModel, api) {
	        var singles = [];

	        ecModel.eachComponent('singleAxis', function(axisModel, idx) {

	            var single = new Single(axisModel, ecModel, api);
	            single.name = 'single_' + idx;
	            single.resize(axisModel, api);
	            axisModel.coordinateSystem = single;
	            singles.push(single);

	        });

	        ecModel.eachSeries(function (seriesModel) {
	            if (seriesModel.get('coordinateSystem') === 'singleAxis') {
	                var singleAxisModel = ecModel.queryComponents({
	                    mainType: 'singleAxis',
	                    index: seriesModel.get('singleAxisIndex'),
	                    id: seriesModel.get('singleAxisId')
	                })[0];
	                seriesModel.coordinateSystem = singleAxisModel && singleAxisModel.coordinateSystem;
	            }
	        });

	        return singles;
	    }

	    __webpack_require__(76).register('single', {
	        create: create,
	        dimensions: Single.prototype.dimensions
	    });


/***/ },
/* 293 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * Single coordinates system.
	 */


	    var SingleAxis = __webpack_require__(294);
	    var axisHelper = __webpack_require__(101);
	    var layout = __webpack_require__(71);

	    /**
	     * Create a single coordinates system.
	     *
	     * @param {module:echarts/coord/single/AxisModel} axisModel
	     * @param {module:echarts/model/Global} ecModel
	     * @param {module:echarts/ExtensionAPI} api
	     */
	    function Single(axisModel, ecModel, api) {

	        /**
	         * @type {string}
	         * @readOnly
	         */
	        this.dimension = 'single';

	        /**
	         * Add it just for draw tooltip.
	         *
	         * @type {Array.<string>}
	         * @readOnly
	         */
	        this.dimensions = ['single'];

	        /**
	         * @private
	         * @type {module:echarts/coord/single/SingleAxis}.
	         */
	        this._axis = null;

	        /**
	         * @private
	         * @type {module:zrender/core/BoundingRect}
	         */
	        this._rect;

	        this._init(axisModel, ecModel, api);

	        /**
	         * @type {module:echarts/coord/single/AxisModel}
	         */
	        this.model = axisModel;
	    }

	    Single.prototype = {

	        type: 'singleAxis',

	        axisPointerEnabled: true,

	        constructor: Single,

	        /**
	         * Initialize single coordinate system.
	         *
	         * @param  {module:echarts/coord/single/AxisModel} axisModel
	         * @param  {module:echarts/model/Global} ecModel
	         * @param  {module:echarts/ExtensionAPI} api
	         * @private
	         */
	        _init: function (axisModel, ecModel, api) {

	            var dim = this.dimension;

	            var axis = new SingleAxis(
	                dim,
	                axisHelper.createScaleByModel(axisModel),
	                [0, 0],
	                axisModel.get('type'),
	                axisModel.get('position')
	            );

	            var isCategory = axis.type === 'category';
	            axis.onBand = isCategory && axisModel.get('boundaryGap');
	            axis.inverse = axisModel.get('inverse');
	            axis.orient = axisModel.get('orient');

	            axisModel.axis = axis;
	            axis.model = axisModel;
	            axis.coordinateSystem = this;
	            this._axis = axis;
	        },

	        /**
	         * Update axis scale after data processed
	         * @param  {module:echarts/model/Global} ecModel
	         * @param  {module:echarts/ExtensionAPI} api
	         */
	        update: function (ecModel, api) {
	            ecModel.eachSeries(function (seriesModel) {
	                if (seriesModel.coordinateSystem === this) {
	                    var data = seriesModel.getData();
	                    var dim = this.dimension;
	                    this._axis.scale.unionExtentFromData(
	                        data, seriesModel.coordDimToDataDim(dim)
	                    );
	                    axisHelper.niceScaleExtent(this._axis.scale, this._axis.model);
	                }
	            }, this);
	        },

	        /**
	         * Resize the single coordinate system.
	         *
	         * @param  {module:echarts/coord/single/AxisModel} axisModel
	         * @param  {module:echarts/ExtensionAPI} api
	         */
	        resize: function (axisModel, api) {
	            this._rect = layout.getLayoutRect(
	                {
	                    left: axisModel.get('left'),
	                    top: axisModel.get('top'),
	                    right: axisModel.get('right'),
	                    bottom: axisModel.get('bottom'),
	                    width: axisModel.get('width'),
	                    height: axisModel.get('height')
	                },
	                {
	                    width: api.getWidth(),
	                    height: api.getHeight()
	                }
	            );

	            this._adjustAxis();
	        },

	        /**
	         * @return {module:zrender/core/BoundingRect}
	         */
	        getRect: function () {
	            return this._rect;
	        },

	        /**
	         * @private
	         */
	        _adjustAxis: function () {

	            var rect = this._rect;
	            var axis = this._axis;

	            var isHorizontal = axis.isHorizontal();
	            var extent = isHorizontal ? [0, rect.width] : [0, rect.height];
	            var idx =  axis.reverse ? 1 : 0;

	            axis.setExtent(extent[idx], extent[1 - idx]);

	            this._updateAxisTransform(axis, isHorizontal ? rect.x : rect.y);

	        },

	        /**
	         * @param  {module:echarts/coord/single/SingleAxis} axis
	         * @param  {number} coordBase
	         */
	        _updateAxisTransform: function (axis, coordBase) {

	            var axisExtent = axis.getExtent();
	            var extentSum = axisExtent[0] + axisExtent[1];
	            var isHorizontal = axis.isHorizontal();

	            axis.toGlobalCoord = isHorizontal
	                ? function (coord) {
	                    return coord + coordBase;
	                }
	                : function (coord) {
	                    return extentSum - coord + coordBase;
	                };

	            axis.toLocalCoord = isHorizontal
	                ? function (coord) {
	                    return coord - coordBase;
	                }
	                : function (coord) {
	                    return extentSum - coord + coordBase;
	                };
	        },

	        /**
	         * Get axis.
	         *
	         * @return {module:echarts/coord/single/SingleAxis}
	         */
	        getAxis: function () {
	            return this._axis;
	        },

	        /**
	         * Get axis, add it just for draw tooltip.
	         *
	         * @return {[type]} [description]
	         */
	        getBaseAxis: function () {
	            return this._axis;
	        },

	        /**
	         * @return {Array.<module:echarts/coord/Axis>}
	         */
	        getAxes: function () {
	            return [this._axis];
	        },

	        /**
	         * @return {Object} {baseAxes: [], otherAxes: []}
	         */
	        getTooltipAxes: function () {
	            return {baseAxes: [this.getAxis()]};
	        },

	        /**
	         * If contain point.
	         *
	         * @param  {Array.<number>} point
	         * @return {boolean}
	         */
	        containPoint: function (point) {
	            var rect = this.getRect();
	            var axis = this.getAxis();
	            var orient = axis.orient;
	            if (orient === 'horizontal') {
	                return axis.contain(axis.toLocalCoord(point[0]))
	                && (point[1] >= rect.y && point[1] <= (rect.y + rect.height));
	            }
	            else {
	                return axis.contain(axis.toLocalCoord(point[1]))
	                && (point[0] >= rect.y && point[0] <= (rect.y + rect.height));
	            }
	        },

	        /**
	         * @param {Array.<number>} point
	         * @return {Array.<number>}
	         */
	        pointToData: function (point) {
	            var axis = this.getAxis();
	            return [axis.coordToData(axis.toLocalCoord(
	                point[axis.orient === 'horizontal' ? 0 : 1]
	            ))];
	        },

	        /**
	         * Convert the series data to concrete point.
	         *
	         * @param  {number|Array.<number>} val
	         * @return {Array.<number>}
	         */
	        dataToPoint: function (val) {
	            var axis = this.getAxis();
	            var rect = this.getRect();
	            var pt = [];
	            var idx = axis.orient === 'horizontal' ? 0 : 1;

	            if (val instanceof Array) {
	                val = val[0];
	            }

	            pt[idx] = axis.toGlobalCoord(axis.dataToCoord(+val));
	            pt[1 - idx] = idx === 0 ? (rect.y + rect.height / 2) : (rect.x + rect.width / 2);
	            return pt;
	        }

	    };

	    module.exports = Single;



/***/ },
/* 294 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);
	    var Axis = __webpack_require__(100);

	    /**
	     * @constructor  module:echarts/coord/single/SingleAxis
	     * @extends {module:echarts/coord/Axis}
	     * @param {string} dim
	     * @param {*} scale
	     * @param {Array.<number>} coordExtent
	     * @param {string} axisType
	     * @param {string} position
	     */
	    var SingleAxis = function (dim, scale, coordExtent, axisType, position) {

	        Axis.call(this, dim, scale, coordExtent);

	        /**
	         * Axis type
	         * - 'category'
	         * - 'value'
	         * - 'time'
	         * - 'log'
	         * @type {string}
	         */
	        this.type = axisType || 'value';

	        /**
	         * Axis position
	         *  - 'top'
	         *  - 'bottom'
	         *  - 'left'
	         *  - 'right'
	         *  @type {string}
	         */
	        this.position = position || 'bottom';

	        /**
	         * Axis orient
	         *  - 'horizontal'
	         *  - 'vertical'
	         * @type {[type]}
	         */
	        this.orient = null;

	        /**
	         * @type {number}
	         */
	        this._labelInterval = null;

	    };

	    SingleAxis.prototype = {

	        constructor: SingleAxis,

	        /**
	         * Axis model
	         * @type {module:echarts/coord/single/AxisModel}
	         */
	        model: null,

	        /**
	         * Judge the orient of the axis.
	         * @return {boolean}
	         */
	        isHorizontal: function () {
	            var position = this.position;
	            return position === 'top' || position === 'bottom';

	        },

	        /**
	         * @override
	         */
	        pointToData: function (point, clamp) {
	            return this.coordinateSystem.pointToData(point, clamp)[0];
	        },

	        /**
	         * Convert the local coord(processed by dataToCoord())
	         * to global coord(concrete pixel coord).
	         * designated by module:echarts/coord/single/Single.
	         * @type {Function}
	         */
	        toGlobalCoord: null,

	        /**
	         * Convert the global coord to local coord.
	         * designated by module:echarts/coord/single/Single.
	         * @type {Function}
	         */
	        toLocalCoord: null

	    };

	    zrUtil.inherits(SingleAxis, Axis);

	    module.exports = SingleAxis;


/***/ },
/* 295 */
/***/ function(module, exports, __webpack_require__) {

	

	    var AxisBuilder = __webpack_require__(135);
	    var zrUtil =  __webpack_require__(4);
	    var graphic = __webpack_require__(18);
	    var singleAxisHelper = __webpack_require__(296);
	    var getInterval = AxisBuilder.getInterval;
	    var ifIgnoreOnTick = AxisBuilder.ifIgnoreOnTick;

	    var axisBuilderAttrs = [
	        'axisLine', 'axisLabel', 'axisTick', 'axisName'
	    ];

	    var selfBuilderAttr = 'splitLine';

	    var SingleAxisView = __webpack_require__(136).extend({

	        type: 'singleAxis',

	        axisPointerClass: 'SingleAxisPointer',

	        render: function (axisModel, ecModel, api, payload) {

	            var group = this.group;

	            group.removeAll();

	            var layout =  singleAxisHelper.layout(axisModel);

	            var axisBuilder = new AxisBuilder(axisModel, layout);

	            zrUtil.each(axisBuilderAttrs, axisBuilder.add, axisBuilder);

	            group.add(axisBuilder.getGroup());

	            if (axisModel.get(selfBuilderAttr + '.show')) {
	                this['_' + selfBuilderAttr](axisModel, layout.labelInterval);
	            }

	            SingleAxisView.superCall(this, 'render', axisModel, ecModel, api, payload);
	        },

	        _splitLine: function(axisModel, labelInterval) {
	            var axis = axisModel.axis;

	            if (axis.scale.isBlank()) {
	                return;
	            }

	            var splitLineModel = axisModel.getModel('splitLine');
	            var lineStyleModel = splitLineModel.getModel('lineStyle');
	            var lineWidth = lineStyleModel.get('width');
	            var lineColors = lineStyleModel.get('color');
	            var lineInterval = getInterval(splitLineModel, labelInterval);

	            lineColors = lineColors instanceof Array ? lineColors : [lineColors];

	            var gridRect = axisModel.coordinateSystem.getRect();
	            var isHorizontal = axis.isHorizontal();

	            var splitLines = [];
	            var lineCount = 0;

	            var ticksCoords = axis.getTicksCoords();

	            var p1 = [];
	            var p2 = [];

	            for (var i = 0; i < ticksCoords.length; ++i) {
	                if (ifIgnoreOnTick(axis, i, lineInterval)) {
	                    continue;
	                }
	                var tickCoord = axis.toGlobalCoord(ticksCoords[i]);
	                if (isHorizontal) {
	                    p1[0] = tickCoord;
	                    p1[1] = gridRect.y;
	                    p2[0] = tickCoord;
	                    p2[1] = gridRect.y + gridRect.height;
	                }
	                else {
	                    p1[0] = gridRect.x;
	                    p1[1] = tickCoord;
	                    p2[0] = gridRect.x + gridRect.width;
	                    p2[1] = tickCoord;
	                }
	                var colorIndex = (lineCount++) % lineColors.length;
	                splitLines[colorIndex] = splitLines[colorIndex] || [];
	                splitLines[colorIndex].push(new graphic.Line(
	                    graphic.subPixelOptimizeLine({
	                        shape: {
	                            x1: p1[0],
	                            y1: p1[1],
	                            x2: p2[0],
	                            y2: p2[1]
	                        },
	                        style: {
	                            lineWidth: lineWidth
	                        },
	                        silent: true
	                    })));
	            }

	            for (var i = 0; i < splitLines.length; ++i) {
	                this.group.add(graphic.mergePath(splitLines[i], {
	                    style: {
	                        stroke: lineColors[i % lineColors.length],
	                        lineDash: lineStyleModel.getLineDash(lineWidth),
	                        lineWidth: lineWidth
	                    },
	                    silent: true
	                }));
	            }
	        }
	    });

	    module.exports = SingleAxisView;



/***/ },
/* 296 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);

	    var helper = {};

	    /**
	     * @param {Object} opt {labelInside}
	     * @return {Object} {
	     *  position, rotation, labelDirection, labelOffset,
	     *  tickDirection, labelRotate, labelInterval, z2
	     * }
	     */
	    helper.layout = function (axisModel, opt) {
	        opt = opt || {};
	        var single = axisModel.coordinateSystem;
	        var axis = axisModel.axis;
	        var layout = {};

	        var axisPosition = axis.position;
	        var orient = axis.orient;

	        var rect = single.getRect();
	        var rectBound = [rect.x, rect.x + rect.width, rect.y, rect.y + rect.height];

	        var positionMap = {
	            horizontal: {top: rectBound[2], bottom: rectBound[3]},
	            vertical: {left: rectBound[0], right: rectBound[1]}
	        };

	        layout.position = [
	            orient === 'vertical'
	                ? positionMap.vertical[axisPosition]
	                : rectBound[0],
	            orient === 'horizontal'
	                ? positionMap.horizontal[axisPosition]
	                : rectBound[3]
	        ];

	        var r = {horizontal: 0, vertical: 1};
	        layout.rotation = Math.PI / 2 * r[orient];

	        var directionMap = {top: -1, bottom: 1, right: 1, left: -1};

	        layout.labelDirection = layout.tickDirection
	            = layout.nameDirection
	            = directionMap[axisPosition];

	        if (axisModel.get('axisTick.inside')) {
	            layout.tickDirection = -layout.tickDirection;
	        }

	        if (zrUtil.retrieve(opt.labelInside, axisModel.get('axisLabel.inside'))) {
	            layout.labelDirection = -layout.labelDirection;
	        }

	        var labelRotation = opt.rotate;
	        labelRotation == null && (labelRotation = axisModel.get('axisLabel.rotate'));
	        layout.labelRotation = axisPosition === 'top' ? -labelRotation : labelRotation;

	        layout.labelInterval = axis.getLabelInterval();

	        layout.z2 = 1;

	        return layout;
	    };

	    module.exports = helper;



/***/ },
/* 297 */
/***/ function(module, exports, __webpack_require__) {

	

	    var ComponentModel = __webpack_require__(69);
	    var axisModelCreator = __webpack_require__(131);
	    var zrUtil =  __webpack_require__(4);

	    var AxisModel = ComponentModel.extend({

	        type: 'singleAxis',

	        layoutMode: 'box',

	        /**
	         * @type {module:echarts/coord/single/SingleAxis}
	         */
	        axis: null,

	        /**
	         * @type {module:echarts/coord/single/Single}
	         */
	        coordinateSystem: null,

	        /**
	         * @override
	         */
	        getCoordSysModel: function () {
	            return this;
	        }

	    });

	    var defaultOption = {

	        left: '5%',
	        top: '5%',
	        right: '5%',
	        bottom: '5%',

	        type: 'value',

	        position: 'bottom',

	        orient: 'horizontal',

	        axisLine: {
	            show: true,
	            lineStyle: {
	                width: 2,
	                type: 'solid'
	            }
	        },

	        // Single coordinate system and single axis is the,
	        // which is used as the parent tooltip model.
	        // same model, so we set default tooltip show as true.
	        tooltip: {
	            show: true
	        },

	        axisTick: {
	            show: true,
	            length: 6,
	            lineStyle: {
	                width: 2
	            }
	        },

	        axisLabel: {
	            show: true,
	            interval: 'auto'
	        },

	        splitLine: {
	            show: true,
	            lineStyle: {
	                type: 'dashed',
	                opacity: 0.2
	            }
	        }
	    };

	    function getAxisType(axisName, option) {
	        return option.type || (option.data ? 'category' : 'value');
	    }

	    zrUtil.merge(AxisModel.prototype, __webpack_require__(112));

	    axisModelCreator('single', AxisModel, getAxisType, defaultOption);

	    module.exports = AxisModel;


/***/ },
/* 298 */
/***/ function(module, exports, __webpack_require__) {

	

	    var echarts = __webpack_require__(1);
	    var axisPointerModelHelper = __webpack_require__(137);
	    var axisTrigger = __webpack_require__(299);
	    var zrUtil = __webpack_require__(4);

	    __webpack_require__(301);
	    __webpack_require__(302);

	    // CartesianAxisPointer is not supposed to be required here. But consider
	    // echarts.simple.js and online build tooltip, which only require gridSimple,
	    // CartesianAxisPointer should be able to required somewhere.
	    __webpack_require__(304);

	    echarts.registerPreprocessor(function (option) {
	        // Always has a global axisPointerModel for default setting.
	        if (option) {
	            (!option.axisPointer || option.axisPointer.length === 0)
	                && (option.axisPointer = {});

	            var link = option.axisPointer.link;
	            // Normalize to array to avoid object mergin. But if link
	            // is not set, remain null/undefined, otherwise it will
	            // override existent link setting.
	            if (link && !zrUtil.isArray(link)) {
	                option.axisPointer.link = [link];
	            }
	        }
	    });

	    // This process should proformed after coordinate systems created
	    // and series data processed. So put it on statistic processing stage.
	    echarts.registerProcessor(echarts.PRIORITY.PROCESSOR.STATISTIC, function (ecModel, api) {
	        // Build axisPointerModel, mergin tooltip.axisPointer model for each axis.
	        // allAxesInfo should be updated when setOption performed.
	        ecModel.getComponent('axisPointer').coordSysAxesInfo
	            = axisPointerModelHelper.collect(ecModel, api);
	    });

	    // Broadcast to all views.
	    echarts.registerAction({
	        type: 'updateAxisPointer',
	        event: 'updateAxisPointer',
	        update: ':updateAxisPointer'
	    }, axisTrigger);



/***/ },
/* 299 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);
	    var modelUtil = __webpack_require__(5);
	    var modelHelper = __webpack_require__(137);
	    var findPointFromSeries = __webpack_require__(300);

	    var each = zrUtil.each;
	    var curry = zrUtil.curry;
	    var get = modelUtil.makeGetter();

	    /**
	     * Basic logic: check all axis, if they do not demand show/highlight,
	     * then hide/downplay them.
	     *
	     * @param {Object} coordSysAxesInfo
	     * @param {Object} payload
	     * @param {string} [payload.currTrigger] 'click' | 'mousemove' | 'leave'
	     * @param {Array.<number>} [payload.x] x and y, which are mandatory, specify a point to
	     *              trigger axisPointer and tooltip.
	     * @param {Array.<number>} [payload.y] x and y, which are mandatory, specify a point to
	     *              trigger axisPointer and tooltip.
	     * @param {Object} [payload.seriesIndex] finder, optional, restrict target axes.
	     * @param {Object} [payload.dataIndex] finder, restrict target axes.
	     * @param {Object} [payload.axesInfo] finder, restrict target axes.
	     *        [{
	     *          axisDim: 'x'|'y'|'angle'|...,
	     *          axisIndex: ...,
	     *          value: ...
	     *        }, ...]
	     * @param {Function} [payload.dispatchAction]
	     * @param {Object} [payload.tooltipOption]
	     * @param {Object|Array.<number>|Function} [payload.position] Tooltip position,
	     *        which can be specified in dispatchAction
	     * @param {module:echarts/model/Global} ecModel
	     * @param {module:echarts/ExtensionAPI} api
	     * @return {Object} content of event obj for echarts.connect.
	     */
	    function axisTrigger(payload, ecModel, api) {
	        var currTrigger = payload.currTrigger;
	        var point = [payload.x, payload.y];
	        var finder = payload;
	        var dispatchAction = payload.dispatchAction || zrUtil.bind(api.dispatchAction, api);
	        var coordSysAxesInfo = ecModel.getComponent('axisPointer').coordSysAxesInfo;

	        if (illegalPoint(point)) {
	            // Used in the default behavior of `connection`: use the sample seriesIndex
	            // and dataIndex. And also used in the tooltipView trigger.
	            point = findPointFromSeries({
	                seriesIndex: finder.seriesIndex,
	                // Do not use dataIndexInside from other ec instance.
	                // FIXME: auto detect it?
	                dataIndex: finder.dataIndex
	            }, ecModel).point;
	        }
	        var isIllegalPoint = illegalPoint(point);

	        // Axis and value can be specified when calling dispatchAction({type: 'updateAxisPointer'}).
	        // Notice: In this case, it is difficult to get the `point` (which is necessary to show
	        // tooltip, so if point is not given, we just use the point found by sample seriesIndex
	        // and dataIndex.
	        var inputAxesInfo = finder.axesInfo;

	        var axesInfo = coordSysAxesInfo.axesInfo;
	        var shouldHide = currTrigger === 'leave' || illegalPoint(point);
	        var outputFinder = {};

	        var showValueMap = {};
	        var dataByCoordSys = {list: [], map: {}};
	        var updaters = {
	            showPointer: curry(showPointer, showValueMap),
	            showTooltip: curry(showTooltip, dataByCoordSys)
	        };

	        // Process for triggered axes.
	        each(coordSysAxesInfo.coordSysMap, function (coordSys, coordSysKey) {
	            // If a point given, it must be contained by the coordinate system.
	            var coordSysContainsPoint = isIllegalPoint || coordSys.containPoint(point);

	            each(coordSysAxesInfo.coordSysAxesInfo[coordSysKey], function (axisInfo, key) {
	                var axis = axisInfo.axis;
	                var inputAxisInfo = findInputAxisInfo(inputAxesInfo, axisInfo);
	                // If no inputAxesInfo, no axis is restricted.
	                if (!shouldHide && coordSysContainsPoint && (!inputAxesInfo || inputAxisInfo)) {
	                    var val = inputAxisInfo && inputAxisInfo.value;
	                    if (val == null && !isIllegalPoint) {
	                        val = axis.pointToData(point);
	                    }
	                    val != null && processOnAxis(axisInfo, val, updaters, false, outputFinder);
	                }
	            });
	        });

	        // Process for linked axes.
	        var linkTriggers = {};
	        each(axesInfo, function (tarAxisInfo, tarKey) {
	            var linkGroup = tarAxisInfo.linkGroup;

	            // If axis has been triggered in the previous stage, it should not be triggered by link.
	            if (linkGroup && !showValueMap[tarKey]) {
	                each(linkGroup.axesInfo, function (srcAxisInfo, srcKey) {
	                    var srcValItem = showValueMap[srcKey];
	                    // If srcValItem exist, source axis is triggered, so link to target axis.
	                    if (srcAxisInfo !== tarAxisInfo && srcValItem) {
	                        var val = srcValItem.value;
	                        linkGroup.mapper && (val = tarAxisInfo.axis.scale.parse(linkGroup.mapper(
	                            val, makeMapperParam(srcAxisInfo), makeMapperParam(tarAxisInfo)
	                        )));
	                        linkTriggers[tarAxisInfo.key] = val;
	                    }
	                });
	            }
	        });
	        each(linkTriggers, function (val, tarKey) {
	            processOnAxis(axesInfo[tarKey], val, updaters, true, outputFinder);
	        });

	        updateModelActually(showValueMap, axesInfo, outputFinder);
	        dispatchTooltipActually(dataByCoordSys, point, payload, dispatchAction);
	        dispatchHighDownActually(axesInfo, dispatchAction, api);

	        return outputFinder;
	    }

	    function processOnAxis(axisInfo, newValue, updaters, dontSnap, outputFinder) {
	        var axis = axisInfo.axis;

	        if (axis.scale.isBlank() || !axis.containData(newValue)) {
	            return;
	        }

	        if (!axisInfo.involveSeries) {
	            updaters.showPointer(axisInfo, newValue);
	            return;
	        }

	        // Heavy calculation. So put it after axis.containData checking.
	        var payloadInfo = buildPayloadsBySeries(newValue, axisInfo);
	        var payloadBatch = payloadInfo.payloadBatch;
	        var snapToValue = payloadInfo.snapToValue;

	        // Fill content of event obj for echarts.connect.
	        // By defualt use the first involved series data as a sample to connect.
	        if (payloadBatch[0] && outputFinder.seriesIndex == null) {
	            zrUtil.extend(outputFinder, payloadBatch[0]);
	        }

	        // If no linkSource input, this process is for collecting link
	        // target, where snap should not be accepted.
	        if (!dontSnap && axisInfo.snap) {
	            if (axis.containData(snapToValue) && snapToValue != null) {
	                newValue = snapToValue;
	            }
	        }

	        updaters.showPointer(axisInfo, newValue, payloadBatch, outputFinder);
	        // Tooltip should always be snapToValue, otherwise there will be
	        // incorrect "axis value ~ series value" mapping displayed in tooltip.
	        updaters.showTooltip(axisInfo, payloadInfo, snapToValue);
	    }

	    function buildPayloadsBySeries(value, axisInfo) {
	        var axis = axisInfo.axis;
	        var dim = axis.dim;
	        var snapToValue = value;
	        var payloadBatch = [];
	        var minDist = Number.MAX_VALUE;
	        var minDiff = -1;

	        each(axisInfo.seriesModels, function (series, idx) {
	            var dataDim = series.coordDimToDataDim(dim);
	            var seriesNestestValue;
	            var dataIndices;

	            if (series.getAxisTooltipData) {
	                var result = series.getAxisTooltipData(dataDim, value, axis);
	                dataIndices = result.dataIndices;
	                seriesNestestValue = result.nestestValue;
	            }
	            else {
	                dataIndices = series.getData().indicesOfNearest(
	                    dataDim[0],
	                    value,
	                    // Add a threshold to avoid find the wrong dataIndex
	                    // when data length is not same.
	                    false, axis.type === 'category' ? 0.5 : null
	                );
	                if (!dataIndices.length) {
	                    return;
	                }
	                seriesNestestValue = series.getData().get(dataDim[0], dataIndices[0]);
	            }

	            if (seriesNestestValue == null || !isFinite(seriesNestestValue)) {
	                return;
	            }

	            var diff = value - seriesNestestValue;
	            var dist = Math.abs(diff);
	            // Consider category case
	            if (dist <= minDist) {
	                if (dist < minDist || (diff >= 0 && minDiff < 0)) {
	                    minDist = dist;
	                    minDiff = diff;
	                    snapToValue = seriesNestestValue;
	                    payloadBatch.length = 0;
	                }
	                each(dataIndices, function (dataIndex) {
	                    payloadBatch.push({
	                        seriesIndex: series.seriesIndex,
	                        dataIndexInside: dataIndex,
	                        dataIndex: series.getData().getRawIndex(dataIndex)
	                    });
	                });
	            }
	        });

	        return {
	            payloadBatch: payloadBatch,
	            snapToValue: snapToValue
	        };
	    }

	    function showPointer(showValueMap, axisInfo, value, payloadBatch) {
	        showValueMap[axisInfo.key] = {value: value, payloadBatch: payloadBatch};
	    }

	    function showTooltip(dataByCoordSys, axisInfo, payloadInfo, value) {
	        var payloadBatch = payloadInfo.payloadBatch;
	        var axis = axisInfo.axis;
	        var axisModel = axis.model;
	        var axisPointerModel = axisInfo.axisPointerModel;

	        // If no data, do not create anything in dataByCoordSys,
	        // whose length will be used to judge whether dispatch action.
	        if (!axisInfo.triggerTooltip || !payloadBatch.length) {
	            return;
	        }

	        var coordSysModel = axisInfo.coordSys.model;
	        var coordSysKey = modelHelper.makeKey(coordSysModel);
	        var coordSysItem = dataByCoordSys.map[coordSysKey];
	        if (!coordSysItem) {
	            coordSysItem = dataByCoordSys.map[coordSysKey] = {
	                coordSysId: coordSysModel.id,
	                coordSysIndex: coordSysModel.componentIndex,
	                coordSysType: coordSysModel.type,
	                coordSysMainType: coordSysModel.mainType,
	                dataByAxis: []
	            };
	            dataByCoordSys.list.push(coordSysItem);
	        }

	        coordSysItem.dataByAxis.push({
	            axisDim: axis.dim,
	            axisIndex: axisModel.componentIndex,
	            axisType: axisModel.type,
	            axisId: axisModel.id,
	            value: value,
	            // Caustion: viewHelper.getValueLabel is actually on "view stage", which
	            // depends that all models have been updated. So it should not be performed
	            // here. Considering axisPointerModel used here is volatile, which is hard
	            // to be retrieve in TooltipView, we prepare parameters here.
	            valueLabelOpt: {
	                precision: axisPointerModel.get('label.precision'),
	                formatter: axisPointerModel.get('label.formatter')
	            },
	            seriesDataIndices: payloadBatch.slice()
	        });
	    }

	    function updateModelActually(showValueMap, axesInfo, outputFinder) {
	        var outputAxesInfo = outputFinder.axesInfo = [];
	        // Basic logic: If no 'show' required, 'hide' this axisPointer.
	        each(axesInfo, function (axisInfo, key) {
	            var option = axisInfo.axisPointerModel.option;
	            var valItem = showValueMap[key];

	            if (valItem) {
	                !axisInfo.useHandle && (option.status = 'show');
	                option.value = valItem.value;
	                // For label formatter param and highlight.
	                option.seriesDataIndices = (valItem.payloadBatch || []).slice();
	            }
	            // When always show (e.g., handle used), remain
	            // original value and status.
	            else {
	                // If hide, value still need to be set, consider
	                // click legend to toggle axis blank.
	                !axisInfo.useHandle && (option.status = 'hide');
	            }

	            // If status is 'hide', should be no info in payload.
	            option.status === 'show' && outputAxesInfo.push({
	                axisDim: axisInfo.axis.dim,
	                axisIndex: axisInfo.axis.model.componentIndex,
	                value: option.value
	            });
	        });
	    }

	    function dispatchTooltipActually(dataByCoordSys, point, payload, dispatchAction) {
	        // Basic logic: If no showTip required, hideTip will be dispatched.
	        if (illegalPoint(point) || !dataByCoordSys.list.length) {
	            dispatchAction({type: 'hideTip'});
	            return;
	        }

	        // In most case only one axis (or event one series is used). It is
	        // convinient to fetch payload.seriesIndex and payload.dataIndex
	        // dirtectly. So put the first seriesIndex and dataIndex of the first
	        // axis on the payload.
	        var sampleItem = ((dataByCoordSys.list[0].dataByAxis[0] || {}).seriesDataIndices || [])[0] || {};

	        dispatchAction({
	            type: 'showTip',
	            escapeConnect: true,
	            x: point[0],
	            y: point[1],
	            tooltipOption: payload.tooltipOption,
	            position: payload.position,
	            dataIndexInside: sampleItem.dataIndexInside,
	            dataIndex: sampleItem.dataIndex,
	            seriesIndex: sampleItem.seriesIndex,
	            dataByCoordSys: dataByCoordSys.list
	        });
	    }

	    function dispatchHighDownActually(axesInfo, dispatchAction, api) {
	        // FIXME
	        // highlight status modification shoule be a stage of main process?
	        // (Consider confilct (e.g., legend and axisPointer) and setOption)

	        var zr = api.getZr();
	        var highDownKey = 'axisPointerLastHighlights';
	        var lastHighlights = get(zr)[highDownKey] || {};
	        var newHighlights = get(zr)[highDownKey] = {};

	        // Update highlight/downplay status according to axisPointer model.
	        // Build hash map and remove duplicate incidentally.
	        each(axesInfo, function (axisInfo, key) {
	            var option = axisInfo.axisPointerModel.option;
	            option.status === 'show' && each(option.seriesDataIndices, function (batchItem) {
	                var key = batchItem.seriesIndex + ' | ' + batchItem.dataIndex;
	                newHighlights[key] = batchItem;
	            });
	        });

	        // Diff.
	        var toHighlight = [];
	        var toDownplay = [];
	        zrUtil.each(lastHighlights, function (batchItem, key) {
	            !newHighlights[key] && toDownplay.push(batchItem);
	        });
	        zrUtil.each(newHighlights, function (batchItem, key) {
	            !lastHighlights[key] && toHighlight.push(batchItem);
	        });

	        toDownplay.length && api.dispatchAction({
	            type: 'downplay', escapeConnect: true, batch: toDownplay
	        });
	        toHighlight.length && api.dispatchAction({
	            type: 'highlight', escapeConnect: true, batch: toHighlight
	        });
	    }

	    function findInputAxisInfo(inputAxesInfo, axisInfo) {
	        for (var i = 0; i < (inputAxesInfo || []).length; i++) {
	            var inputAxisInfo = inputAxesInfo[i];
	            if (axisInfo.axis.dim === inputAxisInfo.axisDim
	                && axisInfo.axis.model.componentIndex === inputAxisInfo.axisIndex
	            ) {
	                return inputAxisInfo;
	            }
	        }
	    }

	    function makeMapperParam(axisInfo) {
	        var axisModel = axisInfo.axis.model;
	        var item = {};
	        var dim = item.axisDim = axisInfo.axis.dim;
	        item.axisIndex = item[dim + 'AxisIndex'] = axisModel.componentIndex;
	        item.axisName = item[dim + 'AxisName'] = axisModel.name;
	        item.axisId = item[dim + 'AxisId'] = axisModel.id;
	        return item;
	    }

	    function illegalPoint(point) {
	        return !point || point[0] == null || isNaN(point[0]) || point[1] == null || isNaN(point[1]);
	    }

	    module.exports = axisTrigger;


/***/ },
/* 300 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);
	    var modelUtil = __webpack_require__(5);

	    /**
	     * @param {Object} finder contains {seriesIndex, dataIndex, dataIndexInside}
	     * @param {module:echarts/model/Global} ecModel
	     * @return {Object} {point: [x, y], el: ...} point Will not be null.
	     */
	    module.exports = function (finder, ecModel) {
	        var point = [];
	        var seriesIndex = finder.seriesIndex;
	        var seriesModel;
	        if (seriesIndex == null || !(
	            seriesModel = ecModel.getSeriesByIndex(seriesIndex)
	        )) {
	            return {point: []};
	        }

	        var data = seriesModel.getData();
	        var dataIndex = modelUtil.queryDataIndex(data, finder);
	        if (dataIndex == null || zrUtil.isArray(dataIndex)) {
	            return {point: []};
	        }

	        var el = data.getItemGraphicEl(dataIndex);
	        var coordSys = seriesModel.coordinateSystem;

	        if (seriesModel.getTooltipPosition) {
	            point = seriesModel.getTooltipPosition(dataIndex) || [];
	        }
	        else if (coordSys && coordSys.dataToPoint) {
	            point = coordSys.dataToPoint(
	                data.getValues(
	                    zrUtil.map(coordSys.dimensions, function (dim) {
	                        return seriesModel.coordDimToDataDim(dim)[0];
	                    }), dataIndex, true
	                )
	            ) || [];
	        }
	        else if (el) {
	            // Use graphic bounding rect
	            var rect = el.getBoundingRect().clone();
	            rect.applyTransform(el.transform);
	            point = [
	                rect.x + rect.width / 2,
	                rect.y + rect.height / 2
	            ];
	        }

	        return {point: point, el: el};
	    };




/***/ },
/* 301 */
/***/ function(module, exports, __webpack_require__) {

	

	    var echarts = __webpack_require__(1);

	    var AxisPointerModel = echarts.extendComponentModel({

	        type: 'axisPointer',

	        coordSysAxesInfo: null,

	        defaultOption: {
	            // 'auto' means that show when triggered by tooltip or handle.
	            show: 'auto',
	            // 'click' | 'mousemove' | 'none'
	            triggerOn: null, // set default in AxisPonterView.js

	            zlevel: 0,
	            z: 50,

	            type: 'line',
	            // axispointer triggered by tootip determine snap automatically,
	            // see `modelHelper`.
	            snap: false,
	            triggerTooltip: true,

	            value: null,
	            status: null, // Init value depends on whether handle is used.

	            // [group0, group1, ...]
	            // Each group can be: {
	            //      mapper: function () {},
	            //      singleTooltip: 'multiple',  // 'multiple' or 'single'
	            //      xAxisId: ...,
	            //      yAxisName: ...,
	            //      angleAxisIndex: ...
	            // }
	            // mapper: can be ignored.
	            //      input: {axisInfo, value}
	            //      output: {axisInfo, value}
	            link: [],

	            // Do not set 'auto' here, otherwise global animation: false
	            // will not effect at this axispointer.
	            animation: null,
	            animationDurationUpdate: 200,

	            lineStyle: {
	                color: '#aaa',
	                width: 1,
	                type: 'solid'
	            },

	            shadowStyle: {
	                color: 'rgba(150,150,150,0.3)'
	            },

	            label: {
	                show: true,
	                formatter: null, // string | Function
	                precision: 'auto', // Or a number like 0, 1, 2 ...
	                margin: 3,
	                textStyle: {
	                    color: '#fff'
	                },
	                padding: [5, 7, 5, 7],
	                backgroundColor: 'auto', // default: axis line color
	                borderColor: null,
	                borderWidth: 0,
	                shadowBlur: 3,
	                shadowColor: '#aaa'
	                // Considering applicability, common style should
	                // better not have shadowOffset.
	                // shadowOffsetX: 0,
	                // shadowOffsetY: 2
	            },

	            handle: {
	                show: false,
	                icon: 'M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4h1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7v-1.2h6.6z M13.3,22H6.7v-1.2h6.6z M13.3,19.6H6.7v-1.2h6.6z', // jshint ignore:line
	                size: 45,
	                // handle margin is from symbol center to axis, which is stable when circular move.
	                margin: 50,
	                // color: '#1b8bbd'
	                // color: '#2f4554'
	                color: '#333',
	                shadowBlur: 3,
	                shadowColor: '#aaa',
	                shadowOffsetX: 0,
	                shadowOffsetY: 2,

	                // For mobile performance
	                throttle: 40
	            }
	        }

	    });

	    module.exports = AxisPointerModel;



/***/ },
/* 302 */
/***/ function(module, exports, __webpack_require__) {

	

	    var globalListener = __webpack_require__(303);

	    var AxisPonterView = __webpack_require__(1).extendComponentView({

	        type: 'axisPointer',

	        render: function (globalAxisPointerModel, ecModel, api) {
	            var globalTooltipModel = ecModel.getComponent('tooltip');
	            var triggerOn = globalAxisPointerModel.get('triggerOn')
	                || (globalTooltipModel && globalTooltipModel.get('triggerOn') || 'mousemove|click');

	            // Register global listener in AxisPointerView to enable
	            // AxisPointerView to be independent to Tooltip.
	            globalListener.register(
	                'axisPointer',
	                api,
	                function (currTrigger, e, dispatchAction) {
	                    // If 'none', it is not controlled by mouse totally.
	                    if (triggerOn !== 'none'
	                        && (currTrigger === 'leave' || triggerOn.indexOf(currTrigger) >= 0)
	                    ) {
	                        dispatchAction({
	                            type: 'updateAxisPointer',
	                            currTrigger: currTrigger,
	                            x: e && e.offsetX,
	                            y: e && e.offsetY
	                        });
	                    }
	                }
	            );
	        },

	        /**
	         * @override
	         */
	        remove: function (ecModel, api) {
	            globalListener.disopse(api.getZr(), 'axisPointer');
	            AxisPonterView.superApply(this._model, 'remove', arguments);
	        },

	        /**
	         * @override
	         */
	        dispose: function (ecModel, api) {
	            globalListener.unregister('axisPointer', api);
	            AxisPonterView.superApply(this._model, 'dispose', arguments);
	        }

	    });



/***/ },
/* 303 */
/***/ function(module, exports, __webpack_require__) {

	

	    var env = __webpack_require__(2);
	    var zrUtil = __webpack_require__(4);
	    var get = __webpack_require__(5).makeGetter();

	    var each = zrUtil.each;

	    var globalListener = {};

	    /**
	     * @param {string} key
	     * @param {module:echarts/ExtensionAPI} api
	     * @param {Function} handler
	     *      param: {string} currTrigger
	     *      param: {Array.<number>} point
	     */
	    globalListener.register = function (key, api, handler) {
	        if (env.node) {
	            return;
	        }

	        var zr = api.getZr();
	        get(zr).records || (get(zr).records = {});

	        initGlobalListeners(zr, api);

	        var record = get(zr).records[key] || (get(zr).records[key] = {});
	        record.handler = handler;
	    };

	    function initGlobalListeners(zr, api) {
	        if (get(zr).initialized) {
	            return;
	        }

	        get(zr).initialized = true;

	        useHandler('click', zrUtil.curry(doEnter, 'click'));
	        useHandler('mousemove', zrUtil.curry(doEnter, 'mousemove'));
	        // useHandler('mouseout', onLeave);
	        useHandler('globalout', onLeave);

	        function useHandler(eventType, cb) {
	            zr.on(eventType, function (e) {
	                var dis = makeDispatchAction(api);

	                each(get(zr).records, function (record) {
	                    record && cb(record, e, dis.dispatchAction);
	                });

	                dispatchTooltipFinally(dis.pendings, api);
	            });
	        }
	    }

	    function dispatchTooltipFinally(pendings, api) {
	        var showLen = pendings.showTip.length;
	        var hideLen = pendings.hideTip.length;

	        var actuallyPayload;
	        if (showLen) {
	            actuallyPayload = pendings.showTip[showLen - 1];
	        }
	        else if (hideLen) {
	            actuallyPayload = pendings.hideTip[hideLen - 1];
	        }
	        if (actuallyPayload) {
	            actuallyPayload.dispatchAction = null;
	            api.dispatchAction(actuallyPayload);
	        }
	    }

	    function onLeave(record, e, dispatchAction) {
	        record.handler('leave', null, dispatchAction);
	    }

	    function doEnter(currTrigger, record, e, dispatchAction) {
	        record.handler(currTrigger, e, dispatchAction);
	    }

	    function makeDispatchAction(api) {
	        var pendings = {
	            showTip: [],
	            hideTip: []
	        };
	        // FIXME
	        // better approach?
	        // 'showTip' and 'hideTip' can be triggered by axisPointer and tooltip,
	        // which may be conflict, (axisPointer call showTip but tooltip call hideTip);
	        // So we have to add "final stage" to merge those dispatched actions.
	        var dispatchAction = function (payload) {
	            var pendingList = pendings[payload.type];
	            if (pendingList) {
	                pendingList.push(payload);
	            }
	            else {
	                payload.dispatchAction = dispatchAction;
	                api.dispatchAction(payload);
	            }
	        };

	        return {
	            dispatchAction: dispatchAction,
	            pendings: pendings
	        };
	    }

	    /**
	     * @param {string} key
	     * @param {module:echarts/ExtensionAPI} api
	     */
	    globalListener.unregister = function (key, api) {
	        if (env.node) {
	            return;
	        }
	        var zr = api.getZr();
	        var record = (get(zr).records || {})[key];
	        if (record) {
	            get(zr).records[key] = null;
	        }
	    };

	    module.exports = globalListener;


/***/ },
/* 304 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var graphic = __webpack_require__(18);
	    var BaseAxisPointer = __webpack_require__(305);
	    var viewHelper = __webpack_require__(306);
	    var cartesianAxisHelper = __webpack_require__(138);
	    var AxisView = __webpack_require__(136);

	    var CartesianAxisPointer = BaseAxisPointer.extend({

	        /**
	         * @override
	         */
	        makeElOption: function (elOption, value, axisModel, axisPointerModel, api) {
	            var axis = axisModel.axis;
	            var grid = axis.grid;
	            var axisPointerType = axisPointerModel.get('type');
	            var otherExtent = getCartesian(grid, axis).getOtherAxis(axis).getGlobalExtent();
	            var pixelValue = axis.toGlobalCoord(axis.dataToCoord(value, true));

	            if (axisPointerType && axisPointerType !== 'none') {
	                var elStyle = viewHelper.buildElStyle(axisPointerModel);
	                var pointerOption = pointerShapeBuilder[axisPointerType](
	                    axis, pixelValue, otherExtent, elStyle
	                );
	                pointerOption.style = elStyle;
	                elOption.graphicKey = pointerOption.type;
	                elOption.pointer = pointerOption;
	            }

	            var layoutInfo = cartesianAxisHelper.layout(grid.model, axisModel);
	            viewHelper.buildCartesianSingleLabelElOption(
	                value, elOption, layoutInfo, axisModel, axisPointerModel, api
	            );
	        },

	        /**
	         * @override
	         */
	        getHandleTransform: function (value, axisModel, axisPointerModel) {
	            var layoutInfo = cartesianAxisHelper.layout(axisModel.axis.grid.model, axisModel, {
	                labelInside: false
	            });
	            layoutInfo.labelMargin = axisPointerModel.get('handle.margin');
	            return {
	                position: viewHelper.getTransformedPosition(axisModel.axis, value, layoutInfo),
	                rotation: layoutInfo.rotation + (layoutInfo.labelDirection < 0 ? Math.PI : 0)
	            };
	        },

	        /**
	         * @override
	         */
	        updateHandleTransform: function (transform, delta, axisModel, axisPointerModel) {
	            var axis = axisModel.axis;
	            var grid = axis.grid;
	            var axisExtent = axis.getGlobalExtent(true);
	            var otherExtent = getCartesian(grid, axis).getOtherAxis(axis).getGlobalExtent();
	            var dimIndex = axis.dim === 'x' ? 0 : 1;

	            var currPosition = transform.position;
	            currPosition[dimIndex] += delta[dimIndex];
	            currPosition[dimIndex] = Math.min(axisExtent[1], currPosition[dimIndex]);
	            currPosition[dimIndex] = Math.max(axisExtent[0], currPosition[dimIndex]);

	            var cursorOtherValue = (otherExtent[1] + otherExtent[0]) / 2;
	            var cursorPoint = [cursorOtherValue, cursorOtherValue];
	            cursorPoint[dimIndex] = currPosition[dimIndex];

	            // Make tooltip do not overlap axisPointer and in the middle of the grid.
	            var tooltipOptions = [{verticalAlign: 'middle'}, {align: 'center'}];

	            return {
	                position: currPosition,
	                rotation: transform.rotation,
	                cursorPoint: cursorPoint,
	                tooltipOption: tooltipOptions[dimIndex]
	            };
	        }

	    });

	    function getCartesian(grid, axis) {
	        var opt = {};
	        opt[axis.dim + 'AxisIndex'] = axis.index;
	        return grid.getCartesian(opt);
	    }

	    var pointerShapeBuilder = {

	        line: function (axis, pixelValue, otherExtent, elStyle) {
	            var targetShape = viewHelper.makeLineShape(
	                [pixelValue, otherExtent[0]],
	                [pixelValue, otherExtent[1]],
	                getAxisDimIndex(axis)
	            );
	            graphic.subPixelOptimizeLine({
	                shape: targetShape,
	                style: elStyle
	            });
	            return {
	                type: 'Line',
	                shape: targetShape
	            };
	        },

	        shadow: function (axis, pixelValue, otherExtent, elStyle) {
	            var bandWidth = axis.getBandWidth();
	            var span = otherExtent[1] - otherExtent[0];
	            return {
	                type: 'Rect',
	                shape: viewHelper.makeRectShape(
	                    [pixelValue - bandWidth / 2, otherExtent[0]],
	                    [bandWidth, span],
	                    getAxisDimIndex(axis)
	                )
	            };
	        }
	    };

	    function getAxisDimIndex(axis) {
	        return axis.dim === 'x' ? 0 : 1;
	    }

	    AxisView.registerAxisPointerClass('CartesianAxisPointer', CartesianAxisPointer);

	    module.exports = CartesianAxisPointer;


/***/ },
/* 305 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var zrUtil = __webpack_require__(4);
	    var clazzUtil = __webpack_require__(13);
	    var graphic = __webpack_require__(18);
	    var get = __webpack_require__(5).makeGetter();
	    var axisPointerModelHelper = __webpack_require__(137);
	    var eventTool = __webpack_require__(88);
	    var throttle = __webpack_require__(81);

	    var clone = zrUtil.clone;
	    var bind = zrUtil.bind;

	    /**
	     * Base axis pointer class in 2D.
	     * Implemenents {module:echarts/component/axis/IAxisPointer}.
	     */
	    function BaseAxisPointer () {
	    }

	    BaseAxisPointer.prototype = {

	        /**
	         * @private
	         */
	        _group: null,

	        /**
	         * @private
	         */
	        _lastGraphicKey: null,

	        /**
	         * @private
	         */
	        _handle: null,

	        /**
	         * @private
	         */
	        _dragging: false,

	        /**
	         * @private
	         */
	        _lastValue: null,

	        /**
	         * @private
	         */
	        _lastStatus: null,

	        /**
	         * @private
	         */
	        _payloadInfo: null,

	        /**
	         * In px, arbitrary value. Do not set too small,
	         * no animation is ok for most cases.
	         * @protected
	         */
	        animationThreshold: 15,

	        /**
	         * @implement
	         */
	        render: function (axisModel, axisPointerModel, api, forceRender) {
	            var value = axisPointerModel.get('value');
	            var status = axisPointerModel.get('status');

	            // Bind them to `this`, not in closure, otherwise they will not
	            // be replaced when user calling setOption in not merge mode.
	            this._axisModel = axisModel;
	            this._axisPointerModel = axisPointerModel;
	            this._api = api;

	            // Optimize: `render` will be called repeatly during mouse move.
	            // So it is power consuming if performing `render` each time,
	            // especially on mobile device.
	            if (!forceRender
	                && this._lastValue === value
	                && this._lastStatus === status
	            ) {
	                return;
	            }
	            this._lastValue = value;
	            this._lastStatus = status;

	            var group = this._group;
	            var handle = this._handle;

	            if (!status || status === 'hide') {
	                // Do not clear here, for animation better.
	                group && group.hide();
	                handle && handle.hide();
	                return;
	            }
	            group && group.show();
	            handle && handle.show();

	            // Otherwise status is 'show'
	            var elOption = {};
	            this.makeElOption(elOption, value, axisModel, axisPointerModel, api);

	            // Enable change axis pointer type.
	            var graphicKey = elOption.graphicKey;
	            if (graphicKey !== this._lastGraphicKey) {
	                this.clear(api);
	            }
	            this._lastGraphicKey = graphicKey;

	            var moveAnimation = this._moveAnimation =
	                this.determineAnimation(axisModel, axisPointerModel);

	            if (!group) {
	                group = this._group = new graphic.Group();
	                this.createPointerEl(group, elOption, axisModel, axisPointerModel);
	                this.createLabelEl(group, elOption, axisModel, axisPointerModel);
	                api.getZr().add(group);
	            }
	            else {
	                var doUpdateProps = zrUtil.curry(updateProps, axisPointerModel, moveAnimation);
	                this.updatePointerEl(group, elOption, doUpdateProps, axisPointerModel);
	                this.updateLabelEl(group, elOption, doUpdateProps, axisPointerModel);
	            }

	            updateMandatoryProps(group, axisPointerModel, true);

	            this._renderHandle(value);
	        },

	        /**
	         * @implement
	         */
	        remove: function (api) {
	            this.clear(api);
	        },

	        /**
	         * @implement
	         */
	        dispose: function (api) {
	            this.clear(api);
	        },

	        /**
	         * @protected
	         */
	        determineAnimation: function (axisModel, axisPointerModel) {
	            var animation = axisPointerModel.get('animation');
	            var axis = axisModel.axis;
	            var isCategoryAxis = axis.type === 'category';
	            var useSnap = axisPointerModel.get('snap');

	            // Value axis without snap always do not snap.
	            if (!useSnap && !isCategoryAxis) {
	                return false;
	            }

	            if (animation === 'auto' || animation == null) {
	                var animationThreshold = this.animationThreshold;
	                if (isCategoryAxis && axis.getBandWidth() > animationThreshold) {
	                    return true;
	                }

	                // It is important to auto animation when snap used. Consider if there is
	                // a dataZoom, animation will be disabled when too many points exist, while
	                // it will be enabled for better visual effect when little points exist.
	                if (useSnap) {
	                    var seriesDataCount = axisPointerModelHelper.getAxisInfo(axisModel).seriesDataCount;
	                    var axisExtent = axis.getExtent();
	                    // Approximate band width
	                    return Math.abs(axisExtent[0] - axisExtent[1]) / seriesDataCount > animationThreshold;
	                }

	                return false;
	            }

	            return animation === true;
	        },

	        /**
	         * add {pointer, label, graphicKey} to elOption
	         * @protected
	         */
	        makeElOption: function (elOption, value, axisModel, axisPointerModel, api) {
	            // Shoule be implemenented by sub-class.
	        },

	        /**
	         * @protected
	         */
	        createPointerEl: function (group, elOption, axisModel, axisPointerModel) {
	            var pointerOption = elOption.pointer;
	            if (pointerOption) {
	                var pointerEl = get(group).pointerEl = new graphic[pointerOption.type](
	                    clone(elOption.pointer)
	                );
	                group.add(pointerEl);
	            }
	        },

	        /**
	         * @protected
	         */
	        createLabelEl: function (group, elOption, axisModel, axisPointerModel) {
	            if (elOption.label) {
	                var labelEl = get(group).labelEl = new graphic.Rect(
	                    clone(elOption.label)
	                );

	                group.add(labelEl);
	                updateLabelShowHide(labelEl, axisPointerModel);
	            }
	        },

	        /**
	         * @protected
	         */
	        updatePointerEl: function (group, elOption, updateProps) {
	            var pointerEl = get(group).pointerEl;
	            if (pointerEl) {
	                pointerEl.setStyle(elOption.pointer.style);
	                updateProps(pointerEl, {shape: elOption.pointer.shape});
	            }
	        },

	        /**
	         * @protected
	         */
	        updateLabelEl: function (group, elOption, updateProps, axisPointerModel) {
	            var labelEl = get(group).labelEl;
	            if (labelEl) {
	                labelEl.setStyle(elOption.label.style);
	                updateProps(labelEl, {
	                    // Consider text length change in vertical axis, animation should
	                    // be used on shape, otherwise the effect will be weird.
	                    shape: elOption.label.shape,
	                    position: elOption.label.position
	                });

	                updateLabelShowHide(labelEl, axisPointerModel);
	            }
	        },

	        /**
	         * @private
	         */
	        _renderHandle: function (value) {
	            if (this._dragging || !this.updateHandleTransform) {
	                return;
	            }

	            var axisPointerModel = this._axisPointerModel;
	            var zr = this._api.getZr();
	            var handle = this._handle;
	            var handleModel = axisPointerModel.getModel('handle');

	            var status = axisPointerModel.get('status');
	            if (!handleModel.get('show') || !status || status === 'hide') {
	                handle && zr.remove(handle);
	                this._handle = null;
	                return;
	            }

	            var isInit;
	            if (!this._handle) {
	                isInit = true;
	                handle = this._handle = createIcon(handleModel, {
	                    onmousemove: function (e) {
	                        // Fot mobile devicem, prevent screen slider on the button.
	                        eventTool.stop(e.event);
	                    },
	                    onmousedown: bind(this._onHandleDragMove, this, 0, 0),
	                    drift: bind(this._onHandleDragMove, this),
	                    ondragend: bind(this._onHandleDragEnd, this)
	                });
	                zr.add(handle);
	            }

	            updateMandatoryProps(handle, axisPointerModel, false);

	            // update style
	            var includeStyles = [
	                'color', 'borderColor', 'borderWidth', 'opacity',
	                'shadowColor', 'shadowBlur', 'shadowOffsetX', 'shadowOffsetY'
	            ];
	            handle.setStyle(handleModel.getItemStyle(null, includeStyles));

	            // update position
	            var handleSize = handleModel.get('size');
	            if (!zrUtil.isArray(handleSize)) {
	                handleSize = [handleSize, handleSize];
	            }
	            handle.attr('scale', [handleSize[0] / 2, handleSize[1] / 2]);

	            throttle.createOrUpdate(
	                this,
	                '_doDispatchAxisPointer',
	                handleModel.get('throttle') || 0,
	                'fixRate'
	            );

	            this._moveHandleToValue(value, isInit);
	        },

	        /**
	         * @private
	         */
	        _moveHandleToValue: function (value, isInit) {
	            updateProps(
	                this._axisPointerModel,
	                !isInit && this._moveAnimation,
	                this._handle,
	                getHandleTransProps(this.getHandleTransform(
	                    value, this._axisModel, this._axisPointerModel
	                ))
	            );
	        },

	        /**
	         * @private
	         */
	        _onHandleDragMove: function (dx, dy) {
	            var handle = this._handle;
	            if (!handle) {
	                return;
	            }

	            this._dragging = true;

	            // Persistent for throttle.
	            var trans = this.updateHandleTransform(
	                getHandleTransProps(handle),
	                [dx, dy],
	                this._axisModel,
	                this._axisPointerModel
	            );
	            this._payloadInfo = trans;

	            handle.stopAnimation();
	            handle.attr(getHandleTransProps(trans));
	            get(handle).lastProp = null;

	            this._doDispatchAxisPointer();
	        },

	        /**
	         * Throttled method.
	         * @private
	         */
	        _doDispatchAxisPointer: function () {
	            var handle = this._handle;
	            if (!handle) {
	                return;
	            }

	            var payloadInfo = this._payloadInfo;
	            var axisModel = this._axisModel;
	            this._api.dispatchAction({
	                type: 'updateAxisPointer',
	                x: payloadInfo.cursorPoint[0],
	                y: payloadInfo.cursorPoint[1],
	                tooltipOption: payloadInfo.tooltipOption,
	                axesInfo: [{
	                    axisDim: axisModel.axis.dim,
	                    axisIndex: axisModel.componentIndex
	                }]
	            });
	        },

	        /**
	         * @private
	         */
	        _onHandleDragEnd: function (moveAnimation) {
	            this._dragging = false;
	            var handle = this._handle;
	            if (!handle) {
	                return;
	            }

	            var value = this._axisPointerModel.get('value');
	            // Consider snap or categroy axis, handle may be not consistent with
	            // axisPointer. So move handle to align the exact value position when
	            // drag ended.
	            this._moveHandleToValue(value);

	            // For the effect: tooltip will be shown when finger holding on handle
	            // button, and will be hidden after finger left handle button.
	            this._api.dispatchAction({
	                type: 'hideTip'
	            });
	        },

	        /**
	         * Should be implemenented by sub-class if support `handle`.
	         * @protected
	         * @param {number} value
	         * @param {module:echarts/model/Model} axisModel
	         * @param {module:echarts/model/Model} axisPointerModel
	         * @return {Object} {position: [x, y], rotation: 0}
	         */
	        getHandleTransform: null,

	        /**
	         * * Should be implemenented by sub-class if support `handle`.
	         * @protected
	         * @param {Object} transform {position, rotation}
	         * @param {Array.<number>} delta [dx, dy]
	         * @param {module:echarts/model/Model} axisModel
	         * @param {module:echarts/model/Model} axisPointerModel
	         * @return {Object} {position: [x, y], rotation: 0, cursorPoint: [x, y]}
	         */
	        updateHandleTransform: null,

	        /**
	         * @private
	         */
	        clear: function (api) {
	            this._lastValue = null;
	            this._lastStatus = null;

	            var zr = api.getZr();
	            var group = this._group;
	            var handle = this._handle;
	            if (zr && group) {
	                this._lastGraphicKey = null;
	                group && zr.remove(group);
	                handle && zr.remove(handle);
	                this._group = null;
	                this._handle = null;
	                this._payloadInfo = null;
	            }
	        },

	        /**
	         * @protected
	         */
	        doClear: function () {
	            // Implemented by sub-class if necessary.
	        },

	        /**
	         * @protected
	         * @param {Array.<number>} xy
	         * @param {Array.<number>} wh
	         * @param {number} [xDimIndex=0] or 1
	         */
	        buildLabel: function (xy, wh, xDimIndex) {
	            xDimIndex = xDimIndex || 0;
	            return {
	                x: xy[xDimIndex],
	                y: xy[1 - xDimIndex],
	                width: wh[xDimIndex],
	                height: wh[1 - xDimIndex]
	            };
	        }
	    };

	    BaseAxisPointer.prototype.constructor = BaseAxisPointer;


	    function updateProps(animationModel, moveAnimation, el, props) {
	        // Animation optimize.
	        if (!propsEqual(get(el).lastProp, props)) {
	            get(el).lastProp = props;
	            moveAnimation
	                ? graphic.updateProps(el, props, animationModel)
	                : (el.stopAnimation(), el.attr(props));
	        }
	    }

	    function propsEqual(lastProps, newProps) {
	        if (zrUtil.isObject(lastProps) && zrUtil.isObject(newProps)) {
	            var equals = true;
	            zrUtil.each(newProps, function (item, key) {
	                equals &= propsEqual(lastProps[key], item);
	            });
	            return !!equals;
	        }
	        else {
	            return lastProps === newProps;
	        }
	    }

	    function updateLabelShowHide(labelEl, axisPointerModel) {
	        labelEl[axisPointerModel.get('label.show') ? 'show' : 'hide']();
	    }

	    function getHandleTransProps(trans) {
	        return {
	            position: trans.position.slice(),
	            rotation: trans.rotation || 0
	        };
	    }

	    function createIcon(handleModel, handlers) {
	        var iconStr = handleModel.get('icon');
	        var style = {
	            x: -1, y: -1, width: 2, height: 2
	        };
	        var opt = zrUtil.extend({
	            style: {
	                strokeNoScale: true
	            },
	            rectHover: true,
	            cursor: 'move',
	            draggable: true
	        }, handlers);

	        return iconStr.indexOf('image://') === 0
	            ? (
	                style.image = iconStr.slice(8),
	                opt.style = style,
	                new graphic.Image(opt)
	            )
	            : graphic.makePath(
	                iconStr.replace('path://', ''),
	                opt,
	                style,
	                'center'
	            );
	    }

	    function updateMandatoryProps(group, axisPointerModel, silent) {
	        var z = axisPointerModel.get('z');
	        var zlevel = axisPointerModel.get('zlevel');

	        group && group.traverse(function (el) {
	            if (el.type !== 'group') {
	                z != null && (el.z = z);
	                zlevel != null && (el.zlevel = zlevel);
	                el.silent = silent;
	            }
	        });
	    }

	    clazzUtil.enableClassExtend(BaseAxisPointer);

	    module.exports = BaseAxisPointer;


/***/ },
/* 306 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var zrUtil = __webpack_require__(4);
	    var graphic = __webpack_require__(18);
	    var textContain = __webpack_require__(8);
	    var formatUtil = __webpack_require__(6);
	    var matrix = __webpack_require__(11);
	    var axisHelper = __webpack_require__(101);
	    var AxisBuilder = __webpack_require__(135);

	    var helper = {};

	    /**
	     * @param {module:echarts/model/Model} axisPointerModel
	     */
	    helper.buildElStyle = function (axisPointerModel) {
	        var axisPointerType = axisPointerModel.get('type');
	        var styleModel = axisPointerModel.getModel(axisPointerType + 'Style');
	        var style;
	        if (axisPointerType === 'line') {
	            style = styleModel.getLineStyle();
	            style.fill = null;
	        }
	        else if (axisPointerType === 'shadow') {
	            style = styleModel.getAreaStyle();
	            style.stroke = null;
	        }
	        return style;
	    };

	    /**
	     * @param {Function} labelPos {align, verticalAlign, position}
	     */
	    helper.buildLabelElOption = function (
	        elOption, axisModel, axisPointerModel, api, labelPos
	    ) {
	        var value = axisPointerModel.get('value');
	        var text = helper.getValueLabel(
	            value, axisModel.axis, axisModel.ecModel,
	            axisPointerModel.get('seriesDataIndices'),
	            {
	                precision: axisPointerModel.get('label.precision'),
	                formatter: axisPointerModel.get('label.formatter')
	            }
	        );
	        var labelModel = axisPointerModel.getModel('label');
	        var textStyleModel = labelModel.getModel('textStyle');
	        var paddings = formatUtil.normalizeCssArray(labelModel.get('padding') || 0);

	        var font = textStyleModel.getFont();
	        var textRect = textContain.getBoundingRect(
	            text, font, labelPos.textAlign, labelPos.textBaseline
	        );

	        var position = labelPos.position;
	        var width = textRect.width + paddings[1] + paddings[3];
	        var height = textRect.height + paddings[0] + paddings[2];

	        // Adjust by align.
	        var align = labelPos.align;
	        align === 'right' && (position[0] -= width);
	        align === 'center' && (position[0] -= width / 2);
	        var verticalAlign = labelPos.verticalAlign;
	        verticalAlign === 'bottom' && (position[1] -= height);
	        verticalAlign === 'middle' && (position[1] -= height / 2);

	        // Not overflow ec container
	        confineInContainer(position, width, height, api);

	        var bgColor = labelModel.get('backgroundColor');
	        if (!bgColor || bgColor === 'auto') {
	            bgColor = axisModel.get('axisLine.lineStyle.color');
	        }

	        elOption.label = {
	            shape: {x: 0, y: 0, width: width, height: height, r: labelModel.get('borderRadius')},
	            position: position.slice(),
	            style: {
	                text: text,
	                textFont: font,
	                textFill: textStyleModel.getTextColor(),
	                textPosition: 'inside',
	                fill: bgColor,
	                stroke: labelModel.get('borderColor') || 'transparent',
	                lineWidth: labelModel.get('borderWidth') || 0,
	                shadowBlur: labelModel.get('shadowBlur'),
	                shadowColor: labelModel.get('shadowColor'),
	                shadowOffsetX: labelModel.get('shadowOffsetX'),
	                shadowOffsetY: labelModel.get('shadowOffsetY')
	            },
	            // Lable should be over axisPointer.
	            z2: 10
	        };
	    };

	    // Do not overflow ec container
	    function confineInContainer(position, width, height, api) {
	        var viewWidth = api.getWidth();
	        var viewHeight = api.getHeight();
	        position[0] = Math.min(position[0] + width, viewWidth) - width;
	        position[1] = Math.min(position[1] + height, viewHeight) - height;
	        position[0] = Math.max(position[0], 0);
	        position[1] = Math.max(position[1], 0);
	    }

	    /**
	     * @param {number} value
	     * @param {module:echarts/coord/Axis} axis
	     * @param {module:echarts/model/Global} ecModel
	     * @param {Object} opt
	     * @param {Array.<Object>} seriesDataIndices
	     * @param {number|string} opt.precision 'auto' or a number
	     * @param {string|Function} opt.formatter label formatter
	     */
	    helper.getValueLabel = function (value, axis, ecModel, seriesDataIndices, opt) {
	        var text = axis.scale.getLabel(
	            // If `precision` is set, width can be fixed (like '12.00500'), which
	            // helps to debounce when when moving label.
	            value, {precision: opt.precision}
	        );
	        var formatter = opt.formatter;

	        if (formatter) {
	            var params = {
	                value: axisHelper.getAxisRawValue(axis, value),
	                seriesData: []
	            };
	            zrUtil.each(seriesDataIndices, function (idxItem) {
	                var series = ecModel.getSeriesByIndex(idxItem.seriesIndex);
	                var dataIndex = idxItem.dataIndexInside;
	                var dataParams = series && series.getDataParams(dataIndex);
	                dataParams && params.seriesData.push(dataParams);
	            });

	            if (zrUtil.isString(formatter)) {
	                text = formatter.replace('{value}', text);
	            }
	            else if (zrUtil.isFunction(formatter)) {
	                text = formatter(params);
	            }
	        }

	        return text;
	    };

	    /**
	     * @param {module:echarts/coord/Axis} axis
	     * @param {number} value
	     * @param {Object} layoutInfo {
	     *  rotation, position, labelOffset, labelDirection, labelMargin
	     * }
	     */
	    helper.getTransformedPosition = function (axis, value, layoutInfo) {
	        var transform = matrix.create();
	        matrix.rotate(transform, transform, layoutInfo.rotation);
	        matrix.translate(transform, transform, layoutInfo.position);

	        return graphic.applyTransform([
	            axis.dataToCoord(value),
	            (layoutInfo.labelOffset || 0)
	                + (layoutInfo.labelDirection || 1) * (layoutInfo.labelMargin || 0)
	        ], transform);
	    };

	    helper.buildCartesianSingleLabelElOption = function (
	        value, elOption, layoutInfo, axisModel, axisPointerModel, api
	    ) {
	        var textLayout = AxisBuilder.innerTextLayout(
	            layoutInfo.rotation, 0, layoutInfo.labelDirection
	        );
	        layoutInfo.labelMargin = axisPointerModel.get('label.margin');
	        helper.buildLabelElOption(elOption, axisModel, axisPointerModel, api, {
	            position: helper.getTransformedPosition(axisModel.axis, value, layoutInfo),
	            align: textLayout.textAlign,
	            verticalAlign: textLayout.textVerticalAlign
	        });
	    };

	    /**
	     * @param {Array.<number>} p1
	     * @param {Array.<number>} p2
	     * @param {number} [xDimIndex=0] or 1
	     */
	    helper.makeLineShape = function (p1, p2, xDimIndex) {
	        xDimIndex = xDimIndex || 0;
	        return {
	            x1: p1[xDimIndex],
	            y1: p1[1 - xDimIndex],
	            x2: p2[xDimIndex],
	            y2: p2[1 - xDimIndex]
	        };
	    };

	    /**
	     * @param {Array.<number>} xy
	     * @param {Array.<number>} wh
	     * @param {number} [xDimIndex=0] or 1
	     */
	    helper.makeRectShape = function (xy, wh, xDimIndex) {
	        xDimIndex = xDimIndex || 0;
	        return {
	            x: xy[xDimIndex],
	            y: xy[1 - xDimIndex],
	            width: wh[xDimIndex],
	            height: wh[1 - xDimIndex]
	        };
	    };

	    helper.makeSectorShape = function (cx, cy, r0, r, startAngle, endAngle) {
	        return {
	            cx: cx,
	            cy: cy,
	            r0: r0,
	            r: r,
	            startAngle: startAngle,
	            endAngle: endAngle,
	            clockwise: true
	        };
	    };

	    module.exports = helper;


/***/ },
/* 307 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var graphic = __webpack_require__(18);
	    var BaseAxisPointer = __webpack_require__(305);
	    var viewHelper = __webpack_require__(306);
	    var singleAxisHelper = __webpack_require__(296);
	    var AxisView = __webpack_require__(136);

	    var XY = ['x', 'y'];
	    var WH = ['width', 'height'];

	    var SingleAxisPointer = BaseAxisPointer.extend({

	        /**
	         * @override
	         */
	        makeElOption: function (elOption, value, axisModel, axisPointerModel, api) {
	            var axis = axisModel.axis;
	            var coordSys = axis.coordinateSystem;
	            var otherExtent = getGlobalExtent(coordSys, 1 - getPointDimIndex(axis));
	            var pixelValue = coordSys.dataToPoint(value)[0];

	            var axisPointerType = axisPointerModel.get('type');
	            if (axisPointerType && axisPointerType !== 'none') {
	                var elStyle = viewHelper.buildElStyle(axisPointerModel);
	                var pointerOption = pointerShapeBuilder[axisPointerType](
	                    axis, pixelValue, otherExtent, elStyle
	                );
	                pointerOption.style = elStyle;

	                elOption.graphicKey = pointerOption.type;
	                elOption.pointer = pointerOption;
	            }

	            var layoutInfo = singleAxisHelper.layout(axisModel);
	            viewHelper.buildCartesianSingleLabelElOption(
	                value, elOption, layoutInfo, axisModel, axisPointerModel, api
	            );
	        },

	        /**
	         * @override
	         */
	        getHandleTransform: function (value, axisModel, axisPointerModel) {
	            var layoutInfo = singleAxisHelper.layout(axisModel, {labelInside: false});
	            layoutInfo.labelMargin = axisPointerModel.get('handle.margin');
	            return {
	                position: viewHelper.getTransformedPosition(axisModel.axis, value, layoutInfo),
	                rotation: layoutInfo.rotation + (layoutInfo.labelDirection < 0 ? Math.PI : 0)
	            };
	        },

	        /**
	         * @override
	         */
	        updateHandleTransform: function (transform, delta, axisModel, axisPointerModel) {
	            var axis = axisModel.axis;
	            var coordSys = axis.coordinateSystem;
	            var dimIndex = getPointDimIndex(axis);
	            var axisExtent = getGlobalExtent(coordSys, dimIndex);
	            var currPosition = transform.position;
	            currPosition[dimIndex] += delta[dimIndex];
	            currPosition[dimIndex] = Math.min(axisExtent[1], currPosition[dimIndex]);
	            currPosition[dimIndex] = Math.max(axisExtent[0], currPosition[dimIndex]);
	            var otherExtent = getGlobalExtent(coordSys, 1 - dimIndex);
	            var cursorOtherValue = (otherExtent[1] + otherExtent[0]) / 2;
	            var cursorPoint = [cursorOtherValue, cursorOtherValue];
	            cursorPoint[dimIndex] = currPosition[dimIndex];

	            return {
	                position: currPosition,
	                rotation: transform.rotation,
	                cursorPoint: cursorPoint,
	                tooltipOption: {
	                    verticalAlign: 'middle'
	                }
	            };
	        }
	    });

	    var pointerShapeBuilder = {

	        line: function (axis, pixelValue, otherExtent, elStyle) {
	            var targetShape = viewHelper.makeLineShape(
	                [pixelValue, otherExtent[0]],
	                [pixelValue, otherExtent[1]],
	                getPointDimIndex(axis)
	            );
	            graphic.subPixelOptimizeLine({
	                shape: targetShape,
	                style: elStyle
	            });
	            return {
	                type: 'Line',
	                shape: targetShape
	            };
	        },

	        shadow: function (axis, pixelValue, otherExtent, elStyle) {
	            var bandWidth = axis.getBandWidth();
	            var span = otherExtent[1] - otherExtent[0];
	            return {
	                type: 'Rect',
	                shape: viewHelper.makeRectShape(
	                    [pixelValue - bandWidth / 2, otherExtent[0]],
	                    [bandWidth, span],
	                    getPointDimIndex(axis)
	                )
	            };
	        }
	    };

	    function getPointDimIndex(axis) {
	        return axis.isHorizontal() ? 0 : 1;
	    }

	    function getGlobalExtent(coordSys, dimIndex) {
	        var rect = coordSys.getRect();
	        return [rect[XY[dimIndex]], rect[XY[dimIndex]] + rect[WH[dimIndex]]];
	    }

	    AxisView.registerAxisPointerClass('SingleAxisPointer', SingleAxisPointer);

	    module.exports = SingleAxisPointer;


/***/ },
/* 308 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	/**
	 * @file  Define the themeRiver view's series model
	 * @author Deqing Li(annong035@gmail.com)
	 */


	    var completeDimensions = __webpack_require__(110);
	    var SeriesModel = __webpack_require__(78);
	    var List = __webpack_require__(98);
	    var zrUtil = __webpack_require__(4);
	    var formatUtil = __webpack_require__(6);
	    var encodeHTML = formatUtil.encodeHTML;
	    var nest = __webpack_require__(255);

	    var DATA_NAME_INDEX = 2;

	    var ThemeRiverSeries = SeriesModel.extend({

	        type: 'series.themeRiver',

	        dependencies: ['singleAxis'],

	        /**
	         * @readOnly
	         * @type {module:zrender/core/util#HashMap}
	         */
	        nameMap: null,

	        /**
	         * @override
	         */
	        init: function (option) {
	            ThemeRiverSeries.superApply(this, 'init', arguments);

	            // Put this function here is for the sake of consistency of code
	            // Enable legend selection for each data item
	            // Use a function instead of direct access because data reference may changed
	            this.legendDataProvider = function () {
	                return this.getRawData();
	            };
	        },

	        /**
	         * If there is no value of a certain point in the time for some event,set it value to 0.
	         *
	         * @param {Array} data  initial data in the option
	         * @return {Array}
	         */
	        fixData: function (data) {
	            var rawDataLength = data.length;

	            // grouped data by name
	            var dataByName = nest()
	                .key(function (dataItem) {
	                    return dataItem[2];
	                })
	                .entries(data);

	            // data group in each layer
	            var layData = zrUtil.map(dataByName, function (d) {
	                return {
	                    name: d.key,
	                    dataList: d.values
	                };
	            });

	            var layerNum = layData.length;
	            var largestLayer = -1;
	            var index = -1;
	            for (var i = 0; i < layerNum; ++i) {
	                var len = layData[i].dataList.length;
	                if (len > largestLayer) {
	                    largestLayer = len;
	                    index = i;
	                }
	            }

	            for (var k = 0; k < layerNum; ++k) {
	                if (k === index) {
	                    continue;
	                }
	                var name = layData[k].name;
	                for (var j = 0; j < largestLayer; ++j) {
	                    var timeValue = layData[index].dataList[j][0];
	                    var length = layData[k].dataList.length;
	                    var keyIndex = -1;
	                    for (var l = 0; l < length; ++l) {
	                        var value = layData[k].dataList[l][0];
	                        if (value === timeValue) {
	                            keyIndex = l;
	                            break;
	                        }
	                    }
	                    if (keyIndex === -1) {
	                        data[rawDataLength] = [];
	                        data[rawDataLength][0] = timeValue;
	                        data[rawDataLength][1] = 0;
	                        data[rawDataLength][2] = name;
	                        rawDataLength++;

	                    }
	                }
	            }
	            return data;
	        },

	        /**
	         * @override
	         * @param  {Object} option  the initial option that user gived
	         * @param  {module:echarts/model/Model} ecModel  the model object for themeRiver option
	         * @return {module:echarts/data/List}
	         */
	        getInitialData: function (option, ecModel) {

	            var dimensions = [];

	            var singleAxisModel = ecModel.queryComponents({
	                mainType: 'singleAxis',
	                index: this.get('singleAxisIndex'),
	                id: this.get('singleAxisId')
	            })[0];

	            var axisType = singleAxisModel.get('type');

	            dimensions = [
	                {
	                    name: 'time',
	                    // FIXME common?
	                    type: axisType === 'category'
	                        ? 'ordinal'
	                        : axisType === 'time'
	                        ? 'time'
	                        : 'float'
	                },
	                {
	                    name: 'value',
	                    type: 'float'
	                },
	                {
	                    name: 'name',
	                    type: 'ordinal'
	                }
	            ];

	            // filter the data item with the value of label is undefined
	            var filterData = zrUtil.filter(option.data, function (dataItem) {
	                return dataItem[2] !== undefined;
	            });

	            var data = this.fixData(filterData || []);
	            var nameList = [];
	            var nameMap = this.nameMap = zrUtil.createHashMap();
	            var count = 0;

	            for (var i = 0; i < data.length; ++i) {
	                nameList.push(data[i][DATA_NAME_INDEX]);
	                if (!nameMap.get(data[i][DATA_NAME_INDEX])) {
	                    nameMap.set(data[i][DATA_NAME_INDEX], count);
	                    count++;
	                }
	            }

	            dimensions = completeDimensions(dimensions, data);

	            var list = new List(dimensions, this);

	            list.initData(data, nameList);

	            return list;
	        },

	        /**
	         * Used by single coordinate
	         *
	         * @param {string} axisDim  the dimension for single coordinate
	         * @return {Array.<string> } specified dimensions on the axis.
	         */
	        coordDimToDataDim: function (axisDim) {
	            return ['time'];
	        },

	        /**
	         * The raw data is divided into multiple layers and each layer
	         *     has same name.
	         *
	         * @return {Array.<Array.<number>>}
	         */
	        getLayerSeries: function () {
	            var data = this.getData();
	            var lenCount = data.count();
	            var indexArr = [];

	            for (var i = 0; i < lenCount; ++i) {
	                indexArr[i] = i;
	            }
	            // data group by name
	            var dataByName = nest()
	                .key(function (index) {
	                    return data.get('name', index);
	                })
	                .entries(indexArr);

	            var layerSeries = zrUtil.map(dataByName, function (d) {
	                return {
	                    name: d.key,
	                    indices: d.values
	                };
	            });

	            for (var j = 0; j < layerSeries.length; ++j) {
	                layerSeries[j].indices.sort(comparer);
	            }

	            function comparer(index1, index2) {
	                return data.get('time', index1) - data.get('time', index2);
	            }

	            return layerSeries;
	        },

	        /**
	         * Get data indices for show tooltip content
	         *
	         * @param {Array.<string>|string} dim  single coordinate dimension
	         * @param {number} value axis value
	         * @param {module:echarts/coord/single/SingleAxis} baseAxis  single Axis used
	         *     the themeRiver.
	         * @return {Object} {dataIndices, nestestValue}
	         */
	        getAxisTooltipData: function (dim, value, baseAxis) {
	            if (!zrUtil.isArray(dim)) {
	                dim = dim ? [dim] : [];
	            }

	            var data = this.getData();
	            var layerSeries = this.getLayerSeries();
	            var indices = [];
	            var layerNum = layerSeries.length;
	            var nestestValue;

	            for (var i = 0; i < layerNum; ++i) {
	                var minDist = Number.MAX_VALUE;
	                var nearestIdx = -1;
	                var pointNum = layerSeries[i].indices.length;
	                for (var j = 0; j < pointNum; ++j) {
	                    var theValue = data.get(dim[0], layerSeries[i].indices[j]);
	                    var dist = Math.abs(theValue - value);
	                    if (dist <= minDist) {
	                        nestestValue = theValue;
	                        minDist = dist;
	                        nearestIdx = layerSeries[i].indices[j];
	                    }
	                }
	                indices.push(nearestIdx);
	            }

	            return {dataIndices: indices, nestestValue: nestestValue};
	        },

	        /**
	         * @override
	         * @param {number} dataIndex  index of data
	         */
	        formatTooltip: function (dataIndex) {
	            var data = this.getData();
	            var htmlName = data.get('name', dataIndex);
	            var htmlValue = data.get('value', dataIndex);
	            if (isNaN(htmlValue) || htmlValue == null) {
	                htmlValue = '-';
	            }
	            return encodeHTML(htmlName + ' : ' + htmlValue);
	        },

	        defaultOption: {
	            zlevel: 0,
	            z: 2,

	            coordinateSystem: 'singleAxis',

	            // gap in axis's orthogonal orientation
	            boundaryGap: ['10%', '10%'],

	            // legendHoverLink: true,

	            singleAxisIndex: 0,

	            animationEasing: 'linear',

	            label: {
	                normal: {
	                    margin: 4,
	                    textAlign: 'right',
	                    show: true,
	                    position: 'left',
	                    textStyle: {
	                        color: '#000',
	                        fontSize: 11
	                    }
	                },
	                emphasis: {
	                    show: true
	                }
	            }
	        }
	    });

	    module.exports = ThemeRiverSeries;



/***/ },
/* 309 */
/***/ function(module, exports, __webpack_require__) {

	/* WEBPACK VAR INJECTION */(function(process) {/**
	 * @file  The file used to draw themeRiver view
	 * @author  Deqing Li(annong035@gmail.com)
	 */


	    var poly = __webpack_require__(120);
	    var graphic = __webpack_require__(18);
	    var zrUtil = __webpack_require__(4);
	    var DataDiffer = __webpack_require__(99);

	    module.exports = __webpack_require__(1).extendChartView({

	        type: 'themeRiver',

	        init: function () {
	            this._layers = [];
	        },

	        render: function (seriesModel, ecModel, api) {
	            var data = seriesModel.getData();
	            var rawData = seriesModel.getRawData();

	            if (!data.count()) {
	                return;
	            }

	            var group = this.group;

	            var layerSeries = seriesModel.getLayerSeries();

	            var layoutInfo = data.getLayout('layoutInfo');
	            var rect = layoutInfo.rect;
	            var boundaryGap = layoutInfo.boundaryGap;

	            group.attr('position', [0, rect.y + boundaryGap[0]]);

	            function keyGetter(item) {
	                return item.name;
	            }
	            var dataDiffer = new DataDiffer(
	                this._layersSeries || [], layerSeries,
	                keyGetter, keyGetter
	            );

	            var newLayersGroups = {};

	            dataDiffer.add(zrUtil.bind(zrUtil.curry(process, 'add'), this))
	                .update(zrUtil.bind(zrUtil.curry(process, 'update'), this))
	                .remove(zrUtil.bind(zrUtil.curry(process, 'remove'), this))
	                .execute();

	            function process(status, idx, oldIdx) {
	                var oldLayersGroups = this._layers;
	                if (status === 'remove') {
	                    group.remove(oldLayersGroups[idx]);
	                    return;
	                }
	                var points0 = [];
	                var points1 = [];
	                var color;
	                var indices = layerSeries[idx].indices;
	                for (var j = 0; j < indices.length; j++) {
	                    var layout = data.getItemLayout(indices[j]);
	                    var x = layout.x;
	                    var y0 = layout.y0;
	                    var y = layout.y;

	                    points0.push([x, y0]);
	                    points1.push([x, y0 + y]);

	                    color = rawData.getItemVisual(indices[j], 'color');
	                }

	                var polygon;
	                var text;
	                var textLayout = data.getItemLayout(indices[0]);
	                var itemModel = data.getItemModel(indices[j - 1]);
	                var labelModel = itemModel.getModel('label.normal');
	                var margin = labelModel.get('margin');
	                if (status === 'add') {
	                    var layerGroup = newLayersGroups[idx] = new graphic.Group();
	                    polygon = new poly.Polygon({
	                        shape: {
	                            points: points0,
	                            stackedOnPoints: points1,
	                            smooth: 0.4,
	                            stackedOnSmooth: 0.4,
	                            smoothConstraint: false
	                        },
	                        z2: 0
	                    });
	                    text = new graphic.Text({
	                        style: {
	                            x: textLayout.x - margin,
	                            y: textLayout.y0 + textLayout.y / 2
	                        }
	                    });
	                    layerGroup.add(polygon);
	                    layerGroup.add(text);
	                    group.add(layerGroup);

	                    polygon.setClipPath(createGridClipShape(polygon.getBoundingRect(), seriesModel, function () {
	                        polygon.removeClipPath();
	                    }));
	                }
	                else {
	                    var layerGroup = oldLayersGroups[oldIdx];
	                    polygon = layerGroup.childAt(0);
	                    text = layerGroup.childAt(1);
	                    group.add(layerGroup);

	                    newLayersGroups[idx] = layerGroup;

	                    graphic.updateProps(polygon, {
	                        shape: {
	                            points: points0,
	                            stackedOnPoints: points1
	                        }
	                    }, seriesModel);

	                    graphic.updateProps(text, {
	                        style: {
	                            x: textLayout.x - margin,
	                            y: textLayout.y0 + textLayout.y / 2
	                        }
	                    }, seriesModel);
	                }

	                var hoverItemStyleModel = itemModel.getModel('itemStyle.emphasis');
	                var itemStyleModel = itemModel.getModel('itemStyle.normal');
	                var textStyleModel = labelModel.getModel('textStyle');

	                text.setStyle({
	                    text: labelModel.get('show')
	                        ? seriesModel.getFormattedLabel(indices[j - 1], 'normal')
	                            || data.getName(indices[j - 1])
	                        : '',
	                    textFont: textStyleModel.getFont(),
	                    textAlign: labelModel.get('textAlign'),
	                    textVerticalAlign: 'middle'
	                });

	                polygon.setStyle(zrUtil.extend({
	                    fill: color
	                }, itemStyleModel.getItemStyle(['color'])));

	                graphic.setHoverStyle(polygon, hoverItemStyleModel.getItemStyle());
	            }

	            this._layersSeries = layerSeries;
	            this._layers = newLayersGroups;
	        },

	        dispose: function () {}
	    });

	    // add animation to the view
	    function createGridClipShape(rect, seriesModel, cb) {
	        var rectEl = new graphic.Rect({
	            shape: {
	                x: rect.x - 10,
	                y: rect.y - 10,
	                width: 0,
	                height: rect.height + 20
	            }
	        });
	        graphic.initProps(rectEl, {
	            shape: {
	                width: rect.width + 20,
	                height: rect.height + 20
	            }
	        }, seriesModel, cb);

	        return rectEl;
	    }



	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(310)))

/***/ },
/* 310 */
/***/ function(module, exports) {

	// shim for using process in browser
	var process = module.exports = {};

	// cached from whatever global is present so that test runners that stub it
	// don't break things.  But we need to wrap it in a try catch in case it is
	// wrapped in strict mode code which doesn't define any globals.  It's inside a
	// function because try/catches deoptimize in certain engines.

	var cachedSetTimeout;
	var cachedClearTimeout;

	function defaultSetTimout() {
	    throw new Error('setTimeout has not been defined');
	}
	function defaultClearTimeout () {
	    throw new Error('clearTimeout has not been defined');
	}
	(function () {
	    try {
	        if (typeof setTimeout === 'function') {
	            cachedSetTimeout = setTimeout;
	        } else {
	            cachedSetTimeout = defaultSetTimout;
	        }
	    } catch (e) {
	        cachedSetTimeout = defaultSetTimout;
	    }
	    try {
	        if (typeof clearTimeout === 'function') {
	            cachedClearTimeout = clearTimeout;
	        } else {
	            cachedClearTimeout = defaultClearTimeout;
	        }
	    } catch (e) {
	        cachedClearTimeout = defaultClearTimeout;
	    }
	} ())
	function runTimeout(fun) {
	    if (cachedSetTimeout === setTimeout) {
	        //normal enviroments in sane situations
	        return setTimeout(fun, 0);
	    }
	    // if setTimeout wasn't available but was latter defined
	    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
	        cachedSetTimeout = setTimeout;
	        return setTimeout(fun, 0);
	    }
	    try {
	        // when when somebody has screwed with setTimeout but no I.E. maddness
	        return cachedSetTimeout(fun, 0);
	    } catch(e){
	        try {
	            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
	            return cachedSetTimeout.call(null, fun, 0);
	        } catch(e){
	            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
	            return cachedSetTimeout.call(this, fun, 0);
	        }
	    }


	}
	function runClearTimeout(marker) {
	    if (cachedClearTimeout === clearTimeout) {
	        //normal enviroments in sane situations
	        return clearTimeout(marker);
	    }
	    // if clearTimeout wasn't available but was latter defined
	    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
	        cachedClearTimeout = clearTimeout;
	        return clearTimeout(marker);
	    }
	    try {
	        // when when somebody has screwed with setTimeout but no I.E. maddness
	        return cachedClearTimeout(marker);
	    } catch (e){
	        try {
	            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally
	            return cachedClearTimeout.call(null, marker);
	        } catch (e){
	            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
	            // Some versions of I.E. have different rules for clearTimeout vs setTimeout
	            return cachedClearTimeout.call(this, marker);
	        }
	    }



	}
	var queue = [];
	var draining = false;
	var currentQueue;
	var queueIndex = -1;

	function cleanUpNextTick() {
	    if (!draining || !currentQueue) {
	        return;
	    }
	    draining = false;
	    if (currentQueue.length) {
	        queue = currentQueue.concat(queue);
	    } else {
	        queueIndex = -1;
	    }
	    if (queue.length) {
	        drainQueue();
	    }
	}

	function drainQueue() {
	    if (draining) {
	        return;
	    }
	    var timeout = runTimeout(cleanUpNextTick);
	    draining = true;

	    var len = queue.length;
	    while(len) {
	        currentQueue = queue;
	        queue = [];
	        while (++queueIndex < len) {
	            if (currentQueue) {
	                currentQueue[queueIndex].run();
	            }
	        }
	        queueIndex = -1;
	        len = queue.length;
	    }
	    currentQueue = null;
	    draining = false;
	    runClearTimeout(timeout);
	}

	process.nextTick = function (fun) {
	    var args = new Array(arguments.length - 1);
	    if (arguments.length > 1) {
	        for (var i = 1; i < arguments.length; i++) {
	            args[i - 1] = arguments[i];
	        }
	    }
	    queue.push(new Item(fun, args));
	    if (queue.length === 1 && !draining) {
	        runTimeout(drainQueue);
	    }
	};

	// v8 likes predictible objects
	function Item(fun, array) {
	    this.fun = fun;
	    this.array = array;
	}
	Item.prototype.run = function () {
	    this.fun.apply(null, this.array);
	};
	process.title = 'browser';
	process.browser = true;
	process.env = {};
	process.argv = [];
	process.version = ''; // empty string to avoid regexp issues
	process.versions = {};

	function noop() {}

	process.on = noop;
	process.addListener = noop;
	process.once = noop;
	process.off = noop;
	process.removeListener = noop;
	process.removeAllListeners = noop;
	process.emit = noop;

	process.binding = function (name) {
	    throw new Error('process.binding is not supported');
	};

	process.cwd = function () { return '/' };
	process.chdir = function (dir) {
	    throw new Error('process.chdir is not supported');
	};
	process.umask = function() { return 0; };


/***/ },
/* 311 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @file  Using layout algorithm transform the raw data to layout information.
	 * @author Deqing Li(annong035@gmail.com)
	 */


	    var zrUtil = __webpack_require__(4);
	    var numberUtil =  __webpack_require__(7);


	    module.exports = function (ecModel, api) {

	        ecModel.eachSeriesByType('themeRiver', function (seriesModel) {

	            var data = seriesModel.getData();

	            var single = seriesModel.coordinateSystem;

	            var layoutInfo = {};

	            // use the axis boundingRect for view
	            var rect = single.getRect();

	            layoutInfo.rect = rect;

	            var boundaryGap = seriesModel.get('boundaryGap');

	            var axis = single.getAxis();

	            layoutInfo.boundaryGap = boundaryGap;

	            if (axis.orient === 'horizontal') {
	                boundaryGap[0] = numberUtil.parsePercent(boundaryGap[0], rect.height);
	                boundaryGap[1] = numberUtil.parsePercent(boundaryGap[1], rect.height);
	                var height = rect.height - boundaryGap[0] - boundaryGap[1];
	                themeRiverLayout(data, seriesModel, height);
	            }
	            else {
	                boundaryGap[0] = numberUtil.parsePercent(boundaryGap[0], rect.width);
	                boundaryGap[1] = numberUtil.parsePercent(boundaryGap[1], rect.width);
	                var width = rect.width - boundaryGap[0] - boundaryGap[1];
	                themeRiverLayout(data, seriesModel, width);
	            }

	            data.setLayout('layoutInfo', layoutInfo);
	        });
	    };

	    /**
	     * The layout information about themeriver
	     *
	     * @param {module:echarts/data/List} data  data in the series
	     * @param {module:echarts/model/Series} seriesModel  the model object of themeRiver series
	     * @param {number} height  value used to compute every series height
	     */
	    function themeRiverLayout(data, seriesModel, height) {
	        if (!data.count()) {
	            return;
	        }
	        var coordSys = seriesModel.coordinateSystem;
	        // the data in each layer are organized into a series.
	        var layerSeries = seriesModel.getLayerSeries();

	        // the points in each layer.
	        var layerPoints = zrUtil.map(layerSeries, function (singleLayer) {
	            return zrUtil.map(singleLayer.indices, function (idx) {
	                var pt = coordSys.dataToPoint(data.get('time', idx));
	                pt[1] = data.get('value', idx);
	                return pt;
	            });
	        });

	        var base = computeBaseline(layerPoints);
	        var baseLine = base.y0;
	        var ky = height / base.max;

	        // set layout information for each item.
	        var n = layerSeries.length;
	        var m = layerSeries[0].indices.length;
	        var baseY0;
	        for (var j = 0; j < m; ++j) {
	            baseY0 = baseLine[j] * ky;
	            data.setItemLayout(layerSeries[0].indices[j], {
	                layerIndex: 0,
	                x: layerPoints[0][j][0],
	                y0: baseY0,
	                y: layerPoints[0][j][1] * ky
	            });
	            for (var i = 1; i < n; ++i) {
	                baseY0 += layerPoints[i - 1][j][1] * ky;
	                data.setItemLayout(layerSeries[i].indices[j], {
	                    layerIndex: i,
	                    x: layerPoints[i][j][0],
	                    y0: baseY0,
	                    y: layerPoints[i][j][1] * ky
	                });
	            }
	        }
	    }

	    /**
	     * Compute the baseLine of the rawdata
	     * Inspired by Lee Byron's paper Stacked Graphs - Geometry & Aesthetics
	     *
	     * @param  {Array.<Array>} data  the points in each layer
	     * @return {Array}
	     */
	    function computeBaseline(data) {
	        var layerNum = data.length;
	        var pointNum = data[0].length;
	        var sums = [];
	        var y0 = [];
	        var max = 0;
	        var temp;
	        var base = {};

	        for (var i = 0; i < pointNum; ++i) {
	            for (var j = 0, temp = 0; j < layerNum; ++j) {
	                temp += data[j][i][1];
	            }
	            if (temp > max) {
	                max = temp;
	            }
	            sums.push(temp);
	        }

	        for (var k = 0; k < pointNum; ++k) {
	            y0[k] = (max - sums[k]) / 2;
	        }
	        max = 0;

	        for (var l = 0; l < pointNum; ++l) {
	            var sum = sums[l] + y0[l];
	            if (sum > max) {
	                max = sum;
	            }
	        }
	        base.y0 = y0;
	        base.max = max;

	        return base;
	    }



/***/ },
/* 312 */
/***/ function(module, exports) {

	/**
	 * @file Visual encoding for themeRiver view
	 * @author  Deqing Li(annong035@gmail.com)
	 */


	    module.exports = function (ecModel) {
	        ecModel.eachSeriesByType('themeRiver', function (seriesModel) {
	            var data = seriesModel.getData();
	            var rawData = seriesModel.getRawData();
	            var colorList = seriesModel.get('color');

	            data.each(function (index) {
	                var name = data.getName(index);
	                var color = colorList[(seriesModel.nameMap.get(name) - 1) % colorList.length];
	                rawData.setItemVisual(index, 'color', color);
	            });
	        });
	    };



/***/ },
/* 313 */
/***/ function(module, exports, __webpack_require__) {

	

	    var echarts = __webpack_require__(1);
	    var zrUtil = __webpack_require__(4);
	    var graphicUtil = __webpack_require__(18);
	    var labelHelper = __webpack_require__(118);
	    var createListFromArray = __webpack_require__(109);
	    var barGrid = __webpack_require__(145);

	    var ITEM_STYLE_NORMAL_PATH = ['itemStyle', 'normal'];
	    var ITEM_STYLE_EMPHASIS_PATH = ['itemStyle', 'emphasis'];
	    var LABEL_NORMAL = ['label', 'normal'];
	    var LABEL_EMPHASIS = ['label', 'emphasis'];

	    /**
	     * To reduce total package size of each coordinate systems, the modules `prepareCustom`
	     * of each coordinate systems are not required by each coordinate systems directly, but
	     * required by the module `custom`.
	     *
	     * prepareInfoForCustomSeries {Function}: optional
	     *     @return {Object} {coordSys: {...}, api: {
	     *         coord: function (data, clamp) {}, // return point in global.
	     *         size: function (dataSize, dataItem) {} // return size of each axis in coordSys.
	     *     }}
	     */
	    var prepareCustoms = {
	        cartesian2d: __webpack_require__(314),
	        geo: __webpack_require__(315),
	        singleAxis: __webpack_require__(316),
	        polar: __webpack_require__(317),
	        calendar: __webpack_require__(318)
	    };

	    // ------
	    // Model
	    // ------

	    echarts.extendSeriesModel({

	        type: 'series.custom',

	        dependencies: ['grid', 'polar', 'geo', 'singleAxis', 'calendar'],

	        defaultOption: {
	            coordinateSystem: 'cartesian2d',
	            zlevel: 0,
	            z: 2,
	            legendHoverLink: true

	            // Cartesian coordinate system
	            // xAxisIndex: 0,
	            // yAxisIndex: 0,

	            // Polar coordinate system
	            // polarIndex: 0,

	            // Geo coordinate system
	            // geoIndex: 0,

	            // label: {}
	            // itemStyle: {}
	        },

	        getInitialData: function (option, ecModel) {
	            return createListFromArray(option.data, this, ecModel);
	        }
	    });

	    // -----
	    // View
	    // -----

	    echarts.extendChartView({

	        type: 'custom',

	        /**
	         * @private
	         * @type {module:echarts/data/List}
	         */
	        _data: null,

	        /**
	         * @override
	         */
	        render: function (customSeries, ecModel, api) {
	            var oldData = this._data;
	            var data = customSeries.getData();
	            var group = this.group;
	            var renderItem = makeRenderItem(customSeries, data, ecModel, api);

	            data.diff(oldData)
	                .add(function (newIdx) {
	                    data.hasValue(newIdx) && createOrUpdate(
	                        null, newIdx, renderItem(newIdx), customSeries, group, data
	                    );
	                })
	                .update(function (newIdx, oldIdx) {
	                    var el = oldData.getItemGraphicEl(oldIdx);
	                    data.hasValue(newIdx)
	                        ? createOrUpdate(
	                            el, newIdx, renderItem(newIdx), customSeries, group, data
	                        )
	                        : (el && group.remove(el));
	                })
	                .remove(function (oldIdx) {
	                    var el = oldData.getItemGraphicEl(oldIdx);
	                    el && group.remove(el);
	                })
	                .execute();

	            this._data = data;
	        },

	        /**
	         * @override
	         */
	        dispose: zrUtil.noop
	    });


	    function createEl(elOption) {
	        var graphicType = elOption.type;
	        var el;

	        if (graphicType === 'path') {
	            var shape = elOption.shape;
	            el = graphicUtil.makePath(
	                shape.pathData,
	                null,
	                {
	                    x: shape.x || 0,
	                    y: shape.y || 0,
	                    width: shape.width || 0,
	                    height: shape.height || 0
	                },
	                'center'
	            );
	            el.__customPathData = elOption.pathData;
	        }
	        else if (graphicType === 'image') {
	            el = new graphicUtil.Image({
	            });
	            el.__customImagePath = elOption.style.image;
	        }
	        else if (graphicType === 'text') {
	            el = new graphicUtil.Text({
	            });
	            el.__customText = elOption.style.text;
	        }
	        else {
	            var Clz = graphicUtil[graphicType.charAt(0).toUpperCase() + graphicType.slice(1)];

	            if (true) {
	                zrUtil.assert(Clz, 'graphic type "' + graphicType + '" can not be found.');
	            }

	            el = new Clz();
	        }

	        el.__customGraphicType = graphicType;

	        return el;
	    }

	    function updateEl(el, dataIndex, elOption, animatableModel, data, isInit) {
	        var targetProps = {};
	        var elOptionStyle = elOption.style || {};

	        elOption.shape && (targetProps.shape = zrUtil.clone(elOption.shape));
	        elOption.position && (targetProps.position = elOption.position.slice());
	        elOption.scale && (targetProps.scale = elOption.scale.slice());
	        elOption.origin && (targetProps.origin = elOption.origin.slice());
	        elOption.rotation && (targetProps.rotation = elOption.rotation);

	        if (el.type === 'image' && elOption.style) {
	            var targetStyle = targetProps.style = {};
	            zrUtil.each(['x', 'y', 'width', 'height'], function (prop) {
	                prepareStyleTransition(prop, targetStyle, elOptionStyle, el.style, isInit);
	            });
	        }

	        if (el.type === 'text' && elOption.style) {
	            var targetStyle = targetProps.style = {};
	            zrUtil.each(['x', 'y'], function (prop) {
	                prepareStyleTransition(prop, targetStyle, elOptionStyle, el.style, isInit);
	            });
	        }

	        if (el.type !== 'group') {
	            el.useStyle(elOptionStyle);

	            // Init animation.
	            if (isInit) {
	                el.style.opacity = 0;
	                var targetOpacity = elOptionStyle.opacity;
	                targetOpacity == null && (targetOpacity = 1);
	                graphicUtil.initProps(el, {style: {opacity: targetOpacity}}, animatableModel, dataIndex);
	            }
	        }

	        if (isInit) {
	            el.attr(targetProps);
	        }
	        else {
	            graphicUtil.updateProps(el, targetProps, animatableModel, dataIndex);
	        }

	        // z2 must not be null/undefined, otherwise sort error may occur.
	        el.attr({z2: elOption.z2 || 0, silent: elOption.silent});

	        elOption.styleEmphasis !== false && graphicUtil.setHoverStyle(el, elOption.styleEmphasis);
	    }

	    function prepareStyleTransition(prop, targetStyle, elOptionStyle, oldElStyle, isInit) {
	        if (elOptionStyle[prop] != null && !isInit) {
	            targetStyle[prop] = elOptionStyle[prop];
	            elOptionStyle[prop] = oldElStyle[prop];
	        }
	    }

	    function makeRenderItem(customSeries, data, ecModel, api) {
	        var renderItem = customSeries.get('renderItem');
	        var coordSys = customSeries.coordinateSystem;

	        if (true) {
	            zrUtil.assert(renderItem, 'series.render is required.');
	            zrUtil.assert(
	                coordSys.prepareCustoms || prepareCustoms[coordSys.type],
	                'This coordSys does not support custom series.'
	            );
	        }

	        var prepareResult = coordSys.prepareCustoms
	            ? coordSys.prepareCustoms()
	            : prepareCustoms[coordSys.type](coordSys);

	        var userAPI = zrUtil.defaults({
	            getWidth: api.getWidth,
	            getHeight: api.getHeight,
	            getZr: api.getZr,
	            getDevicePixelRatio: api.getDevicePixelRatio,
	            value: value,
	            style: style,
	            styleEmphasis: styleEmphasis,
	            visual: visual,
	            barLayout: barLayout,
	            currentSeriesIndices: currentSeriesIndices,
	            font: font
	        }, prepareResult.api);

	        var userParams = {
	            context: {},
	            seriesId: customSeries.id,
	            seriesName: customSeries.name,
	            seriesIndex: customSeries.seriesIndex,
	            coordSys: prepareResult.coordSys,
	            dataInsideLength: data.count(),
	            encode: wrapEncodeDef(customSeries.getData())
	        };

	        // Do not support call `api` asynchronously without dataIndexInside input.
	        var currDataIndexInside;
	        var currDirty = true;
	        var currItemModel;
	        var currLabelNormalModel;
	        var currLabelEmphasisModel;
	        var currLabelValueDim;
	        var currVisualColor;

	        return function (dataIndexInside) {
	            currDataIndexInside = dataIndexInside;
	            currDirty = true;
	            return renderItem && renderItem(
	                zrUtil.defaults({
	                    dataIndexInside: dataIndexInside,
	                    dataIndex: data.getRawIndex(dataIndexInside)
	                }, userParams),
	                userAPI
	            ) || {};
	        };

	        // Do not update cache until api called.
	        function updateCache(dataIndexInside) {
	            dataIndexInside == null && (dataIndexInside = currDataIndexInside);
	            if (currDirty) {
	                currItemModel = data.getItemModel(dataIndexInside);
	                currLabelNormalModel = currItemModel.getModel(LABEL_NORMAL);
	                currLabelEmphasisModel = currItemModel.getModel(LABEL_EMPHASIS);
	                currLabelValueDim = labelHelper.findLabelValueDim(data);
	                currVisualColor = data.getItemVisual(dataIndexInside, 'color');

	                currDirty = false;
	            }
	        }

	        /**
	         * @public
	         * @param {nubmer|string} dim
	         * @param {number} [dataIndexInside=currDataIndexInside]
	         * @return {number|string} value
	         */
	        function value(dim, dataIndexInside) {
	            dataIndexInside == null && (dataIndexInside = currDataIndexInside);
	            return data.get(data.getDimension(dim || 0), dataIndexInside);
	        }

	        /**
	         * By default, `visual` is applied to style (to support visualMap).
	         * `visual.color` is applied at `fill`. If user want apply visual.color on `stroke`,
	         * it can be implemented as:
	         * `api.style({stroke: api.visual('color'), fill: null})`;
	         * @public
	         * @param {Object} [extra]
	         * @param {number} [dataIndexInside=currDataIndexInside]
	         */
	        function style(extra, dataIndexInside) {
	            dataIndexInside == null && (dataIndexInside = currDataIndexInside);
	            updateCache(dataIndexInside);

	            var itemStyle = currItemModel.getModel(ITEM_STYLE_NORMAL_PATH).getItemStyle();

	            currVisualColor != null && (itemStyle.fill = currVisualColor);
	            var opacity = data.getItemVisual(dataIndexInside, 'opacity');
	            opacity != null && (itemStyle.opacity = opacity);

	            labelHelper.setTextToStyle(
	                data, dataIndexInside, currLabelValueDim, itemStyle,
	                customSeries, currLabelNormalModel, currVisualColor
	            );

	            extra && zrUtil.extend(itemStyle, extra);
	            return itemStyle;
	        }

	        /**
	         * @public
	         * @param {Object} [extra]
	         * @param {number} [dataIndexInside=currDataIndexInside]
	         */
	        function styleEmphasis(extra, dataIndexInside) {
	            dataIndexInside == null && (dataIndexInside = currDataIndexInside);
	            updateCache(dataIndexInside);

	            var itemStyle = currItemModel.getModel(ITEM_STYLE_EMPHASIS_PATH).getItemStyle();

	            labelHelper.setTextToStyle(
	                data, dataIndexInside, currLabelValueDim, itemStyle,
	                customSeries, currLabelEmphasisModel, currVisualColor
	            );

	            extra && zrUtil.extend(itemStyle, extra);
	            return itemStyle;
	        }

	        /**
	         * @public
	         * @param {string} visualType
	         * @param {number} [dataIndexInside=currDataIndexInside]
	         */
	        function visual(visualType, dataIndexInside) {
	            dataIndexInside == null && (dataIndexInside = currDataIndexInside);
	            return data.getItemVisual(dataIndexInside, visualType);
	        }

	        /**
	         * @public
	         * @param {number} opt.count Positive interger.
	         * @param {number} [opt.barWidth]
	         * @param {number} [opt.barMaxWidth]
	         * @param {number} [opt.barGap]
	         * @param {number} [opt.barCategoryGap]
	         * @return {Object} {width, offset, offsetCenter} is not support, return undefined.
	         */
	        function barLayout(opt) {
	            if (coordSys.getBaseAxis) {
	                var baseAxis = coordSys.getBaseAxis();
	                return barGrid.getLayoutOnAxis(zrUtil.defaults({axis: baseAxis}, opt), api);
	            }
	        }

	        /**
	         * @public
	         * @return {Array.<number>}
	         */
	        function currentSeriesIndices() {
	            return ecModel.getCurrentSeriesIndices();
	        }

	        /**
	         * @public
	         * @param {Object} opt
	         * @param {string} [opt.fontStyle]
	         * @param {number} [opt.fontWeight]
	         * @param {number} [opt.fontSize]
	         * @param {string} [opt.fontFamily]
	         * @return {string} font string
	         */
	        function font(opt) {
	            return graphicUtil.getFont(opt, ecModel);
	        }
	    }

	    function wrapEncodeDef(data) {
	        var encodeDef = {};
	        zrUtil.each(data.dimensions, function (dimName, dataDimIndex) {
	            var dimInfo = data.getDimensionInfo(dimName);
	            if (!dimInfo.isExtraCoord) {
	                var coordDim = dimInfo.coordDim;
	                var dataDims = encodeDef[coordDim] = encodeDef[coordDim] || [];
	                dataDims[dimInfo.coordDimIndex] = dataDimIndex;
	            }
	        });
	        return encodeDef;
	    }

	    function createOrUpdate(el, dataIndex, elOption, animatableModel, group, data) {
	        el = doCreateOrUpdate(el, dataIndex, elOption, animatableModel, group, data);
	        el && data.setItemGraphicEl(dataIndex, el);
	    }

	    function doCreateOrUpdate(el, dataIndex, elOption, animatableModel, group, data) {
	        var elOptionType = elOption.type;
	        if (el
	            && elOptionType !== el.__customGraphicType
	            && (elOptionType !== 'path' || elOption.pathData !== el.__customPathData)
	            && (elOptionType !== 'image' || elOption.style.image !== el.__customImagePath)
	            && (elOptionType !== 'text' || elOption.style.text !== el.__customText)
	        ) {
	            group.remove(el);
	            el = null;
	        }

	        // `elOption.type` is undefined when `renderItem` returns nothing.
	        if (elOptionType == null) {
	            return;
	        }

	        var isInit = !el;
	        !el && (el = createEl(elOption));
	        updateEl(el, dataIndex, elOption, animatableModel, data, isInit);

	        elOptionType === 'group' && zrUtil.each(elOption.children, function (childOption, index) {
	            doCreateOrUpdate(el.childAt(index), dataIndex, childOption, animatableModel, el, data);
	        });

	        group.add(el);

	        return el;
	    }




/***/ },
/* 314 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);

	    function dataToCoordSize(dataSize, dataItem) {
	        // dataItem is necessary in log axis.
	        dataItem = dataItem || [0, 0];
	        return zrUtil.map(['x', 'y'], function (dim, dimIdx) {
	            var axis = this.getAxis(dim);
	            var val = dataItem[dimIdx];
	            var halfSize = dataSize[dimIdx] / 2;
	            return axis.type === 'category'
	                ? axis.getBandWidth()
	                : Math.abs(axis.dataToCoord(val - halfSize) - axis.dataToCoord(val + halfSize));
	        }, this);
	    }

	    function prepareCustom(coordSys) {
	        var rect = coordSys.grid.getRect();
	        return {
	            coordSys: {
	                // The name exposed to user is always 'cartesian2d' but not 'grid'.
	                type: 'cartesian2d',
	                x: rect.x,
	                y: rect.y,
	                width: rect.width,
	                height: rect.height
	            },
	            api: {
	                coord: zrUtil.bind(coordSys.dataToPoint, coordSys),
	                size: zrUtil.bind(dataToCoordSize, coordSys)
	            }
	        };
	    }

	    module.exports = prepareCustom;


/***/ },
/* 315 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);

	    function dataToCoordSize(dataSize, dataItem) {
	        dataItem = dataItem || [0, 0];
	        return zrUtil.map([0, 1], function (dimIdx) {
	            var val = dataItem[dimIdx];
	            var halfSize = dataSize[dimIdx] / 2;
	            var p1 = [];
	            var p2 = [];
	            p1[dimIdx] = val - halfSize;
	            p2[dimIdx] = val + halfSize;
	            p1[1 - dimIdx] = p2[1 - dimIdx] = dataItem[1 - dimIdx];
	            return Math.abs(this.dataToPoint(p1)[dimIdx] - this.dataToPoint(p2)[dimIdx]);
	        }, this);
	    }

	    function prepareCustom(coordSys) {
	        var rect = coordSys.getBoundingRect();
	        return {
	            coordSys: {
	                type: 'geo',
	                x: rect.x,
	                y: rect.y,
	                width: rect.width,
	                height: rect.height
	            },
	            api: {
	                coord: zrUtil.bind(coordSys.dataToPoint, coordSys),
	                size: zrUtil.bind(dataToCoordSize, coordSys)
	            }
	        };
	    }

	    module.exports = prepareCustom;


/***/ },
/* 316 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);

	    function dataToCoordSize(dataSize, dataItem) {
	        // dataItem is necessary in log axis.
	        var axis = this.getAxis();
	        var val = dataItem instanceof Array ? dataItem[0] : dataItem;
	        var halfSize = (dataSize instanceof Array ? dataSize[0] : dataSize) / 2;
	        return axis.type === 'category'
	            ? axis.getBandWidth()
	            : Math.abs(axis.dataToCoord(val - halfSize) - axis.dataToCoord(val + halfSize));
	    }

	    function prepareCustom(coordSys) {
	        var rect = coordSys.getRect();

	        return {
	            coordSys: {
	                type: 'singleAxis',
	                x: rect.x,
	                y: rect.y,
	                width: rect.width,
	                height: rect.height
	            },
	            api: {
	                coord: zrUtil.bind(coordSys.dataToPoint, coordSys),
	                size: zrUtil.bind(dataToCoordSize, coordSys)
	            }
	        };
	    }

	    module.exports = prepareCustom;


/***/ },
/* 317 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);

	    function dataToCoordSize(dataSize, dataItem) {
	        // dataItem is necessary in log axis.
	        return zrUtil.map(['Radius', 'Angle'], function (dim, dimIdx) {
	            var axis = this['get' + dim + 'Axis']();
	            var val = dataItem[dimIdx];
	            var halfSize = dataSize[dimIdx] / 2;
	            var method = 'dataTo' + dim;

	            var result = axis.type === 'category'
	                ? axis.getBandWidth()
	                : Math.abs(axis[method](val - halfSize) - axis[method](val + halfSize));

	            if (dim === 'Angle') {
	                result = result * Math.PI / 180;
	            }

	            return result;

	        }, this);
	    }

	    function prepareCustom(coordSys) {
	        var radiusAxis = coordSys.getRadiusAxis();
	        var angleAxis = coordSys.getAngleAxis();
	        var radius = radiusAxis.getExtent();
	        radius[0] > radius[1] && radius.reverse();

	        return {
	            coordSys: {
	                type: 'polar',
	                cx: coordSys.cx,
	                cy: coordSys.cy,
	                r: radius[1],
	                r0: radius[0]
	            },
	            api: {
	                coord: zrUtil.bind(function (data) {
	                    var radius = radiusAxis.dataToRadius(data[0]);
	                    var angle = angleAxis.dataToAngle(data[1]);
	                    var coord = coordSys.coordToPoint([radius, angle]);
	                    coord.push(radius, angle * Math.PI / 180);
	                    return coord;
	                }),
	                size: zrUtil.bind(dataToCoordSize, coordSys)
	            }
	        };
	    }

	    module.exports = prepareCustom;


/***/ },
/* 318 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);

	    function prepareCustom(coordSys) {
	        var rect = coordSys.getRect();
	        var rangeInfo = coordSys.getRangeInfo();

	        return {
	            coordSys: {
	                type: 'calendar',
	                x: rect.x,
	                y: rect.y,
	                width: rect.width,
	                height: rect.height,
	                cellWidth: coordSys.getCellWidth(),
	                cellHeight: coordSys.getCellHeight(),
	                rangeInfo: {
	                    start: rangeInfo.start,
	                    end: rangeInfo.end,
	                    weeks: rangeInfo.weeks,
	                    dayCount: rangeInfo.allDay
	                }
	            },
	            api: {
	                coord: zrUtil.bind(coordSys.dataToPoint, coordSys)
	            }
	        };
	    }

	    module.exports = prepareCustom;


/***/ },
/* 319 */
/***/ function(module, exports, __webpack_require__) {

	

	    var echarts = __webpack_require__(1);
	    var zrUtil = __webpack_require__(4);
	    var modelUtil = __webpack_require__(5);
	    var graphicUtil = __webpack_require__(18);
	    var layoutUtil = __webpack_require__(71);

	    // -------------
	    // Preprocessor
	    // -------------

	    echarts.registerPreprocessor(function (option) {
	        var graphicOption = option.graphic;

	        // Convert
	        // {graphic: [{left: 10, type: 'circle'}, ...]}
	        // or
	        // {graphic: {left: 10, type: 'circle'}}
	        // to
	        // {graphic: [{elements: [{left: 10, type: 'circle'}, ...]}]}
	        if (zrUtil.isArray(graphicOption)) {
	            if (!graphicOption[0] || !graphicOption[0].elements) {
	                option.graphic = [{elements: graphicOption}];
	            }
	            else {
	                // Only one graphic instance can be instantiated. (We dont
	                // want that too many views are created in echarts._viewMap)
	                option.graphic = [option.graphic[0]];
	            }
	        }
	        else if (graphicOption && !graphicOption.elements) {
	            option.graphic = [{elements: [graphicOption]}];
	        }
	    });

	    // ------
	    // Model
	    // ------

	    var GraphicModel = echarts.extendComponentModel({

	        type: 'graphic',

	        defaultOption: {

	            // Extra properties for each elements:
	            //
	            // left/right/top/bottom: (like 12, '22%', 'center', default undefined)
	            //      If left/rigth is set, shape.x/shape.cx/position will not be used.
	            //      If top/bottom is set, shape.y/shape.cy/position will not be used.
	            //      This mechanism is useful when you want to position a group/element
	            //      against the right side or the center of this container.
	            //
	            // width/height: (can only be pixel value, default 0)
	            //      Only be used to specify contianer(group) size, if needed. And
	            //      can not be percentage value (like '33%'). See the reason in the
	            //      layout algorithm below.
	            //
	            // bounding: (enum: 'all' (default) | 'raw')
	            //      Specify how to calculate boundingRect when locating.
	            //      'all': Get uioned and transformed boundingRect
	            //          from both itself and its descendants.
	            //          This mode simplies confining a group of elements in the bounding
	            //          of their ancester container (e.g., using 'right: 0').
	            //      'raw': Only use the boundingRect of itself and before transformed.
	            //          This mode is similar to css behavior, which is useful when you
	            //          want an element to be able to overflow its container. (Consider
	            //          a rotated circle needs to be located in a corner.)

	            // Note: elements is always behind its ancestors in this elements array.
	            elements: [],
	            parentId: null
	        },

	        /**
	         * Save el options for the sake of the performance (only update modified graphics).
	         * The order is the same as those in option. (ancesters -> descendants)
	         *
	         * @private
	         * @type {Array.<Object>}
	         */
	        _elOptionsToUpdate: null,

	        /**
	         * @override
	         */
	        mergeOption: function (option) {
	            // Prevent default merge to elements
	            var elements = this.option.elements;
	            this.option.elements = null;

	            GraphicModel.superApply(this, 'mergeOption', arguments);

	            this.option.elements = elements;
	        },

	        /**
	         * @override
	         */
	        optionUpdated: function (newOption, isInit) {
	            var thisOption = this.option;
	            var newList = (isInit ? thisOption : newOption).elements;
	            var existList = thisOption.elements = isInit ? [] : thisOption.elements;

	            var flattenedList = [];
	            this._flatten(newList, flattenedList);

	            var mappingResult = modelUtil.mappingToExists(existList, flattenedList);
	            modelUtil.makeIdAndName(mappingResult);

	            // Clear elOptionsToUpdate
	            var elOptionsToUpdate = this._elOptionsToUpdate = [];

	            zrUtil.each(mappingResult, function (resultItem, index) {
	                var newElOption = resultItem.option;

	                if (true) {
	                    zrUtil.assert(
	                        zrUtil.isObject(newElOption) || resultItem.exist,
	                        'Empty graphic option definition'
	                    );
	                }

	                if (!newElOption) {
	                    return;
	                }

	                elOptionsToUpdate.push(newElOption);

	                setKeyInfoToNewElOption(resultItem, newElOption);

	                mergeNewElOptionToExist(existList, index, newElOption);

	                setLayoutInfoToExist(existList[index], newElOption);

	            }, this);

	            // Clean
	            for (var i = existList.length - 1; i >= 0; i--) {
	                if (existList[i] == null) {
	                    existList.splice(i, 1);
	                }
	                else {
	                    // $action should be volatile, otherwise option gotten from
	                    // `getOption` will contain unexpected $action.
	                    delete existList[i].$action;
	                }
	            }
	        },

	        /**
	         * Convert
	         * [{
	         *  type: 'group',
	         *  id: 'xx',
	         *  children: [{type: 'circle'}, {type: 'polygon'}]
	         * }]
	         * to
	         * [
	         *  {type: 'group', id: 'xx'},
	         *  {type: 'circle', parentId: 'xx'},
	         *  {type: 'polygon', parentId: 'xx'}
	         * ]
	         *
	         * @private
	         * @param {Array.<Object>} optionList option list
	         * @param {Array.<Object>} result result of flatten
	         * @param {Object} parentOption parent option
	         */
	        _flatten: function (optionList, result, parentOption) {
	            zrUtil.each(optionList, function (option) {
	                if (!option) {
	                    return;
	                }

	                if (parentOption) {
	                    option.parentOption = parentOption;
	                }

	                result.push(option);

	                var children = option.children;
	                if (option.type === 'group' && children) {
	                    this._flatten(children, result, option);
	                }
	                // Deleting for JSON output, and for not affecting group creation.
	                delete option.children;
	            }, this);
	        },

	        // FIXME
	        // Pass to view using payload? setOption has a payload?
	        useElOptionsToUpdate: function () {
	            var els = this._elOptionsToUpdate;
	            // Clear to avoid render duplicately when zooming.
	            this._elOptionsToUpdate = null;
	            return els;
	        }
	    });

	    // -----
	    // View
	    // -----

	    echarts.extendComponentView({

	        type: 'graphic',

	        /**
	         * @override
	         */
	        init: function (ecModel, api) {

	            /**
	             * @private
	             * @type {module:zrender/core/util.HashMap}
	             */
	            this._elMap = zrUtil.createHashMap();

	            /**
	             * @private
	             * @type {module:echarts/graphic/GraphicModel}
	             */
	            this._lastGraphicModel;
	        },

	        /**
	         * @override
	         */
	        render: function (graphicModel, ecModel, api) {

	            // Having leveraged between use cases and algorithm complexity, a very
	            // simple layout mechanism is used:
	            // The size(width/height) can be determined by itself or its parent (not
	            // implemented yet), but can not by its children. (Top-down travel)
	            // The location(x/y) can be determined by the bounding rect of itself
	            // (can including its descendants or not) and the size of its parent.
	            // (Bottom-up travel)

	            // When `chart.clear()` or `chart.setOption({...}, true)` with the same id,
	            // view will be reused.
	            if (graphicModel !== this._lastGraphicModel) {
	                this._clear();
	            }
	            this._lastGraphicModel = graphicModel;

	            this._updateElements(graphicModel, api);
	            this._relocate(graphicModel, api);
	        },

	        /**
	         * Update graphic elements.
	         *
	         * @private
	         * @param {Object} graphicModel graphic model
	         * @param {module:echarts/ExtensionAPI} api extension API
	         */
	        _updateElements: function (graphicModel, api) {
	            var elOptionsToUpdate = graphicModel.useElOptionsToUpdate();

	            if (!elOptionsToUpdate) {
	                return;
	            }

	            var elMap = this._elMap;
	            var rootGroup = this.group;

	            // Top-down tranverse to assign graphic settings to each elements.
	            zrUtil.each(elOptionsToUpdate, function (elOption) {
	                var $action = elOption.$action;
	                var id = elOption.id;
	                var existEl = elMap.get(id);
	                var parentId = elOption.parentId;
	                var targetElParent = parentId != null ? elMap.get(parentId) : rootGroup;

	                // In top/bottom mode, textVertical should not be used. And textBaseline
	                // should not be 'alphabetic', which cause inaccurately locating.
	                if (elOption.hv && elOption.hv[1] && elOption.type === 'text') {
	                    elOption.style = zrUtil.defaults({textBaseline: 'middle'}, elOption.style);
	                    elOption.style.textVerticalAlign = null;
	                }

	                // Remove unnecessary props to avoid potential problems.
	                var elOptionCleaned = getCleanedElOption(elOption);

	                // For simple, do not support parent change, otherwise reorder is needed.
	                if (true) {
	                    existEl && zrUtil.assert(
	                        targetElParent === existEl.parent,
	                        'Changing parent is not supported.'
	                    );
	                }

	                if (!$action || $action === 'merge') {
	                    existEl
	                        ? existEl.attr(elOptionCleaned)
	                        : createEl(id, targetElParent, elOptionCleaned, elMap);
	                }
	                else if ($action === 'replace') {
	                    removeEl(existEl, elMap);
	                    createEl(id, targetElParent, elOptionCleaned, elMap);
	                }
	                else if ($action === 'remove') {
	                    removeEl(existEl, elMap);
	                }

	                var el = elMap.get(id);
	                if (el) {
	                    el.__ecGraphicWidth = elOption.width;
	                    el.__ecGraphicHeight = elOption.height;
	                }
	            });
	        },

	        /**
	         * Locate graphic elements.
	         *
	         * @private
	         * @param {Object} graphicModel graphic model
	         * @param {module:echarts/ExtensionAPI} api extension API
	         */
	        _relocate: function (graphicModel, api) {
	            var elOptions = graphicModel.option.elements;
	            var rootGroup = this.group;
	            var elMap = this._elMap;

	            // Bottom-up tranvese all elements (consider ec resize) to locate elements.
	            for (var i = elOptions.length - 1; i >= 0; i--) {
	                var elOption = elOptions[i];
	                var el = elMap.get(elOption.id);

	                if (!el) {
	                    continue;
	                }

	                var parentEl = el.parent;
	                var containerInfo = parentEl === rootGroup
	                    ? {
	                        width: api.getWidth(),
	                        height: api.getHeight()
	                    }
	                    : { // Like 'position:absolut' in css, default 0.
	                        width: parentEl.__ecGraphicWidth || 0,
	                        height: parentEl.__ecGraphicHeight || 0
	                    };

	                layoutUtil.positionElement(
	                    el, elOption, containerInfo, null,
	                    {hv: elOption.hv, boundingMode: elOption.bounding}
	                );
	            }
	        },

	        /**
	         * Clear all elements.
	         *
	         * @private
	         */
	        _clear: function () {
	            var elMap = this._elMap;
	            elMap.each(function (el) {
	                removeEl(el, elMap);
	            });
	            this._elMap = zrUtil.createHashMap();
	        },

	        /**
	         * @override
	         */
	        dispose: function () {
	            this._clear();
	        }
	    });

	    function createEl(id, targetElParent, elOption, elMap) {
	        var graphicType = elOption.type;

	        if (true) {
	            zrUtil.assert(graphicType, 'graphic type MUST be set');
	        }

	        var Clz = graphicUtil[graphicType.charAt(0).toUpperCase() + graphicType.slice(1)];

	        if (true) {
	            zrUtil.assert(Clz, 'graphic type can not be found');
	        }

	        var el = new Clz(elOption);
	        targetElParent.add(el);
	        elMap.set(id, el);
	        el.__ecGraphicId = id;
	    }

	    function removeEl(existEl, elMap) {
	        var existElParent = existEl && existEl.parent;
	        if (existElParent) {
	            existEl.type === 'group' && existEl.traverse(function (el) {
	                removeEl(el, elMap);
	            });
	            elMap.removeKey(existEl.__ecGraphicId);
	            existElParent.remove(existEl);
	        }
	    }

	    // Remove unnecessary props to avoid potential problems.
	    function getCleanedElOption(elOption) {
	        elOption = zrUtil.extend({}, elOption);
	        zrUtil.each(
	            ['id', 'parentId', '$action', 'hv', 'bounding'].concat(layoutUtil.LOCATION_PARAMS),
	            function (name) {
	                delete elOption[name];
	            }
	        );
	        return elOption;
	    }

	    function isSetLoc(obj, props) {
	        var isSet;
	        zrUtil.each(props, function (prop) {
	            obj[prop] != null && obj[prop] !== 'auto' && (isSet = true);
	        });
	        return isSet;
	    }

	    function setKeyInfoToNewElOption(resultItem, newElOption) {
	        var existElOption = resultItem.exist;

	        // Set id and type after id assigned.
	        newElOption.id = resultItem.keyInfo.id;
	        !newElOption.type && existElOption && (newElOption.type = existElOption.type);

	        // Set parent id if not specified
	        if (newElOption.parentId == null) {
	            var newElParentOption = newElOption.parentOption;
	            if (newElParentOption) {
	                newElOption.parentId = newElParentOption.id;
	            }
	            else if (existElOption) {
	                newElOption.parentId = existElOption.parentId;
	            }
	        }

	        // Clear
	        newElOption.parentOption = null;
	    }

	    function mergeNewElOptionToExist(existList, index, newElOption) {
	        // Update existing options, for `getOption` feature.
	        var newElOptCopy = zrUtil.extend({}, newElOption);
	        var existElOption = existList[index];

	        var $action = newElOption.$action || 'merge';
	        if ($action === 'merge') {
	            if (existElOption) {

	                if (true) {
	                    var newType = newElOption.type;
	                    zrUtil.assert(
	                        !newType || existElOption.type === newType,
	                        'Please set $action: "replace" to change `type`'
	                    );
	                }

	                // We can ensure that newElOptCopy and existElOption are not
	                // the same object, so `merge` will not change newElOptCopy.
	                zrUtil.merge(existElOption, newElOptCopy, true);
	                // Rigid body, use ignoreSize.
	                layoutUtil.mergeLayoutParam(existElOption, newElOptCopy, {ignoreSize: true});
	                // Will be used in render.
	                layoutUtil.copyLayoutParams(newElOption, existElOption);
	            }
	            else {
	                existList[index] = newElOptCopy;
	            }
	        }
	        else if ($action === 'replace') {
	            existList[index] = newElOptCopy;
	        }
	        else if ($action === 'remove') {
	            // null will be cleaned later.
	            existElOption && (existList[index] = null);
	        }
	    }

	    function setLayoutInfoToExist(existItem, newElOption) {
	        if (!existItem) {
	            return;
	        }
	        existItem.hv = newElOption.hv = [
	            // Rigid body, dont care `width`.
	            isSetLoc(newElOption, ['left', 'right']),
	            // Rigid body, dont care `height`.
	            isSetLoc(newElOption, ['top', 'bottom'])
	        ];
	        // Give default group size. Otherwise layout error may occur.
	        if (existItem.type === 'group') {
	            existItem.width == null && (existItem.width = newElOption.width = 0);
	            existItem.height == null && (existItem.height = newElOption.height = 0);
	        }
	    }



/***/ },
/* 320 */
/***/ function(module, exports, __webpack_require__) {

	

	    __webpack_require__(124);

	    __webpack_require__(304);

	    __webpack_require__(298);



/***/ },
/* 321 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * Legend component entry file8
	 */


	    __webpack_require__(322);
	    __webpack_require__(323);
	    __webpack_require__(324);

	    var echarts = __webpack_require__(1);
	    // Series Filter
	    echarts.registerProcessor(__webpack_require__(326));


/***/ },
/* 322 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var zrUtil = __webpack_require__(4);
	    var Model = __webpack_require__(12);

	    var LegendModel = __webpack_require__(1).extendComponentModel({

	        type: 'legend',

	        dependencies: ['series'],

	        layoutMode: {
	            type: 'box',
	            ignoreSize: true
	        },

	        init: function (option, parentModel, ecModel) {
	            this.mergeDefaultAndTheme(option, ecModel);

	            option.selected = option.selected || {};
	        },

	        mergeOption: function (option) {
	            LegendModel.superCall(this, 'mergeOption', option);
	        },

	        optionUpdated: function () {
	            this._updateData(this.ecModel);

	            var legendData = this._data;

	            // If selectedMode is single, try to select one
	            if (legendData[0] && this.get('selectedMode') === 'single') {
	                var hasSelected = false;
	                // If has any selected in option.selected
	                for (var i = 0; i < legendData.length; i++) {
	                    var name = legendData[i].get('name');
	                    if (this.isSelected(name)) {
	                        // Force to unselect others
	                        this.select(name);
	                        hasSelected = true;
	                        break;
	                    }
	                }
	                // Try select the first if selectedMode is single
	                !hasSelected && this.select(legendData[0].get('name'));
	            }
	        },

	        _updateData: function (ecModel) {
	            var legendData = zrUtil.map(this.get('data') || [], function (dataItem) {
	                // Can be string or number
	                if (typeof dataItem === 'string' || typeof dataItem === 'number') {
	                    dataItem = {
	                        name: dataItem
	                    };
	                }
	                return new Model(dataItem, this, this.ecModel);
	            }, this);
	            this._data = legendData;

	            var availableNames = zrUtil.map(ecModel.getSeries(), function (series) {
	                return series.name;
	            });
	            ecModel.eachSeries(function (seriesModel) {
	                if (seriesModel.legendDataProvider) {
	                    var data = seriesModel.legendDataProvider();
	                    availableNames = availableNames.concat(data.mapArray(data.getName));
	                }
	            });
	            /**
	             * @type {Array.<string>}
	             * @private
	             */
	            this._availableNames = availableNames;
	        },

	        /**
	         * @return {Array.<module:echarts/model/Model>}
	         */
	        getData: function () {
	            return this._data;
	        },

	        /**
	         * @param {string} name
	         */
	        select: function (name) {
	            var selected = this.option.selected;
	            var selectedMode = this.get('selectedMode');
	            if (selectedMode === 'single') {
	                var data = this._data;
	                zrUtil.each(data, function (dataItem) {
	                    selected[dataItem.get('name')] = false;
	                });
	            }
	            selected[name] = true;
	        },

	        /**
	         * @param {string} name
	         */
	        unSelect: function (name) {
	            if (this.get('selectedMode') !== 'single') {
	                this.option.selected[name] = false;
	            }
	        },

	        /**
	         * @param {string} name
	         */
	        toggleSelected: function (name) {
	            var selected = this.option.selected;
	            // Default is true
	            if (!selected.hasOwnProperty(name)) {
	                selected[name] = true;
	            }
	            this[selected[name] ? 'unSelect' : 'select'](name);
	        },

	        /**
	         * @param {string} name
	         */
	        isSelected: function (name) {
	            var selected = this.option.selected;
	            return !(selected.hasOwnProperty(name) && !selected[name])
	                && zrUtil.indexOf(this._availableNames, name) >= 0;
	        },

	        defaultOption: {
	            // 一级层叠
	            zlevel: 0,
	            // 二级层叠
	            z: 4,
	            show: true,

	            // 布局方式，默认为水平布局，可选为：
	            // 'horizontal' | 'vertical'
	            orient: 'horizontal',

	            left: 'center',
	            // right: 'center',

	            top: 'top',
	            // bottom: 'top',

	            // 水平对齐
	            // 'auto' | 'left' | 'right'
	            // 默认为 'auto', 根据 x 的位置判断是左对齐还是右对齐
	            align: 'auto',

	            backgroundColor: 'rgba(0,0,0,0)',
	            // 图例边框颜色
	            borderColor: '#ccc',
	            // 图例边框线宽，单位px，默认为0（无边框）
	            borderWidth: 0,
	            // 图例内边距，单位px，默认各方向内边距为5，
	            // 接受数组分别设定上右下左边距，同css
	            padding: 5,
	            // 各个item之间的间隔，单位px，默认为10，
	            // 横向布局时为水平间隔，纵向布局时为纵向间隔
	            itemGap: 10,
	            // 图例图形宽度
	            itemWidth: 25,
	            // 图例图形高度
	            itemHeight: 14,

	            // 图例关闭时候的颜色
	            inactiveColor: '#ccc',

	            textStyle: {
	                // 图例文字颜色
	                color: '#333'
	            },
	            // formatter: '',
	            // 选择模式，默认开启图例开关
	            selectedMode: true,
	            // 配置默认选中状态，可配合LEGEND.SELECTED事件做动态数据载入
	            // selected: null,
	            // 图例内容（详见legend.data，数组中每一项代表一个item
	            // data: [],

	            // Tooltip 相关配置
	            tooltip: {
	                show: false
	            }
	        }
	    });

	    module.exports = LegendModel;


/***/ },
/* 323 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @file Legend action
	 */


	    var echarts = __webpack_require__(1);
	    var zrUtil = __webpack_require__(4);

	    function legendSelectActionHandler(methodName, payload, ecModel) {
	        var selectedMap = {};
	        var isToggleSelect = methodName === 'toggleSelected';
	        var isSelected;
	        // Update all legend components
	        ecModel.eachComponent('legend', function (legendModel) {
	            if (isToggleSelect && isSelected != null) {
	                // Force other legend has same selected status
	                // Or the first is toggled to true and other are toggled to false
	                // In the case one legend has some item unSelected in option. And if other legend
	                // doesn't has the item, they will assume it is selected.
	                legendModel[isSelected ? 'select' : 'unSelect'](payload.name);
	            }
	            else {
	                legendModel[methodName](payload.name);
	                isSelected = legendModel.isSelected(payload.name);
	            }
	            var legendData = legendModel.getData();
	            zrUtil.each(legendData, function (model) {
	                var name = model.get('name');
	                // Wrap element
	                if (name === '\n' || name === '') {
	                    return;
	                }
	                var isItemSelected = legendModel.isSelected(name);
	                if (selectedMap.hasOwnProperty(name)) {
	                    // Unselected if any legend is unselected
	                    selectedMap[name] = selectedMap[name] && isItemSelected;
	                }
	                else {
	                    selectedMap[name] = isItemSelected;
	                }
	            });
	        });
	        // Return the event explicitly
	        return {
	            name: payload.name,
	            selected: selectedMap
	        };
	    }
	    /**
	     * @event legendToggleSelect
	     * @type {Object}
	     * @property {string} type 'legendToggleSelect'
	     * @property {string} [from]
	     * @property {string} name Series name or data item name
	     */
	    echarts.registerAction(
	        'legendToggleSelect', 'legendselectchanged',
	        zrUtil.curry(legendSelectActionHandler, 'toggleSelected')
	    );

	    /**
	     * @event legendSelect
	     * @type {Object}
	     * @property {string} type 'legendSelect'
	     * @property {string} name Series name or data item name
	     */
	    echarts.registerAction(
	        'legendSelect', 'legendselected',
	        zrUtil.curry(legendSelectActionHandler, 'select')
	    );

	    /**
	     * @event legendUnSelect
	     * @type {Object}
	     * @property {string} type 'legendUnSelect'
	     * @property {string} name Series name or data item name
	     */
	    echarts.registerAction(
	        'legendUnSelect', 'legendunselected',
	        zrUtil.curry(legendSelectActionHandler, 'unSelect')
	    );


/***/ },
/* 324 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);
	    var symbolCreator = __webpack_require__(111);
	    var graphic = __webpack_require__(18);
	    var listComponentHelper = __webpack_require__(325);

	    var curry = zrUtil.curry;

	    function dispatchSelectAction(name, api) {
	        api.dispatchAction({
	            type: 'legendToggleSelect',
	            name: name
	        });
	    }

	    function dispatchHighlightAction(seriesModel, dataName, api) {
	        // If element hover will move to a hoverLayer.
	        var el = api.getZr().storage.getDisplayList()[0];
	        if (!(el && el.useHoverLayer)) {
	            seriesModel.get('legendHoverLink') && api.dispatchAction({
	                type: 'highlight',
	                seriesName: seriesModel.name,
	                name: dataName
	            });
	        }
	    }

	    function dispatchDownplayAction(seriesModel, dataName, api) {
	        // If element hover will move to a hoverLayer.
	        var el = api.getZr().storage.getDisplayList()[0];
	        if (!(el && el.useHoverLayer)) {
	            seriesModel.get('legendHoverLink') && api.dispatchAction({
	                type: 'downplay',
	                seriesName: seriesModel.name,
	                name: dataName
	            });
	        }
	    }

	    module.exports = __webpack_require__(1).extendComponentView({

	        type: 'legend',

	        init: function () {
	            this._symbolTypeStore = {};
	        },

	        render: function (legendModel, ecModel, api) {
	            var group = this.group;
	            group.removeAll();

	            if (!legendModel.get('show')) {
	                return;
	            }

	            var selectMode = legendModel.get('selectedMode');
	            var itemAlign = legendModel.get('align');

	            if (itemAlign === 'auto') {
	                itemAlign = (legendModel.get('left') === 'right'
	                    && legendModel.get('orient') === 'vertical')
	                    ? 'right' : 'left';
	            }

	            var legendDrawedMap = zrUtil.createHashMap();

	            zrUtil.each(legendModel.getData(), function (itemModel) {
	                var name = itemModel.get('name');

	                // Use empty string or \n as a newline string
	                if (name === '' || name === '\n') {
	                    group.add(new graphic.Group({
	                        newline: true
	                    }));
	                    return;
	                }

	                var seriesModel = ecModel.getSeriesByName(name)[0];

	                if (legendDrawedMap.get(name)) {
	                    // Have been drawed
	                    return;
	                }

	                // Series legend
	                if (seriesModel) {
	                    var data = seriesModel.getData();
	                    var color = data.getVisual('color');

	                    // If color is a callback function
	                    if (typeof color === 'function') {
	                        // Use the first data
	                        color = color(seriesModel.getDataParams(0));
	                    }

	                    // Using rect symbol defaultly
	                    var legendSymbolType = data.getVisual('legendSymbol') || 'roundRect';
	                    var symbolType = data.getVisual('symbol');

	                    var itemGroup = this._createItem(
	                        name, itemModel, legendModel,
	                        legendSymbolType, symbolType,
	                        itemAlign, color,
	                        selectMode
	                    );

	                    itemGroup.on('click', curry(dispatchSelectAction, name, api))
	                        .on('mouseover', curry(dispatchHighlightAction, seriesModel, null, api))
	                        .on('mouseout', curry(dispatchDownplayAction, seriesModel, null, api));

	                    legendDrawedMap.set(name, true);
	                }
	                else {
	                    // Data legend of pie, funnel
	                    ecModel.eachRawSeries(function (seriesModel) {
	                        // In case multiple series has same data name
	                        if (legendDrawedMap.get(name)) {
	                            return;
	                        }
	                        if (seriesModel.legendDataProvider) {
	                            var data = seriesModel.legendDataProvider();
	                            var idx = data.indexOfName(name);
	                            if (idx < 0) {
	                                return;
	                            }

	                            var color = data.getItemVisual(idx, 'color');

	                            var legendSymbolType = 'roundRect';

	                            var itemGroup = this._createItem(
	                                name, itemModel, legendModel,
	                                legendSymbolType, null,
	                                itemAlign, color,
	                                selectMode
	                            );

	                            itemGroup.on('click', curry(dispatchSelectAction, name, api))
	                                // FIXME Should not specify the series name
	                                .on('mouseover', curry(dispatchHighlightAction, seriesModel, name, api))
	                                .on('mouseout', curry(dispatchDownplayAction, seriesModel, name, api));

	                            legendDrawedMap.set(name, true);
	                        }
	                    }, this);
	                }

	                if (true) {
	                    if (!legendDrawedMap.get(name)) {
	                        console.warn(name + ' series not exists. Legend data should be same with series name or data name.');
	                    }
	                }
	            }, this);

	            listComponentHelper.layout(group, legendModel, api);
	            // Render background after group is layout
	            // FIXME
	            listComponentHelper.addBackground(group, legendModel);
	        },

	        _createItem: function (
	            name, itemModel, legendModel,
	            legendSymbolType, symbolType,
	            itemAlign, color, selectMode
	        ) {
	            var itemWidth = legendModel.get('itemWidth');
	            var itemHeight = legendModel.get('itemHeight');
	            var inactiveColor = legendModel.get('inactiveColor');

	            var isSelected = legendModel.isSelected(name);
	            var itemGroup = new graphic.Group();

	            var textStyleModel = itemModel.getModel('textStyle');

	            var itemIcon = itemModel.get('icon');

	            var tooltipModel = itemModel.getModel('tooltip');
	            var legendGlobalTooltipModel = tooltipModel.parentModel;

	            // Use user given icon first
	            legendSymbolType = itemIcon || legendSymbolType;
	            itemGroup.add(symbolCreator.createSymbol(
	                legendSymbolType, 0, 0, itemWidth, itemHeight, isSelected ? color : inactiveColor
	            ));

	            // Compose symbols
	            // PENDING
	            if (!itemIcon && symbolType
	                // At least show one symbol, can't be all none
	                && ((symbolType !== legendSymbolType) || symbolType == 'none')
	            ) {
	                var size = itemHeight * 0.8;
	                if (symbolType === 'none') {
	                    symbolType = 'circle';
	                }
	                // Put symbol in the center
	                itemGroup.add(symbolCreator.createSymbol(
	                    symbolType, (itemWidth - size) / 2, (itemHeight - size) / 2, size, size,
	                    isSelected ? color : inactiveColor
	                ));
	            }

	            // Text
	            var textX = itemAlign === 'left' ? itemWidth + 5 : -5;
	            var textAlign = itemAlign;

	            var formatter = legendModel.get('formatter');
	            var content = name;
	            if (typeof formatter === 'string' && formatter) {
	                content = formatter.replace('{name}', name != null ? name : '');
	            }
	            else if (typeof formatter === 'function') {
	                content = formatter(name);
	            }

	            var text = new graphic.Text({
	                style: {
	                    text: content,
	                    x: textX,
	                    y: itemHeight / 2,
	                    fill: isSelected ? textStyleModel.getTextColor() : inactiveColor,
	                    textFont: textStyleModel.getFont(),
	                    textAlign: textAlign,
	                    textVerticalAlign: 'middle'
	                }
	            });
	            itemGroup.add(text);

	            // Add a invisible rect to increase the area of mouse hover
	            var hitRect = new graphic.Rect({
	                shape: itemGroup.getBoundingRect(),
	                invisible: true,
	                tooltip: tooltipModel.get('show') ? zrUtil.extend({
	                    content: name,
	                    // Defaul formatter
	                    formatter: legendGlobalTooltipModel.get('formatter', true) || function () {
	                        return name;
	                    },
	                    formatterParams: {
	                        componentType: 'legend',
	                        legendIndex: legendModel.componentIndex,
	                        name: name,
	                        $vars: ['name']
	                    }
	                }, tooltipModel.option) : null
	            });
	            itemGroup.add(hitRect);

	            itemGroup.eachChild(function (child) {
	                child.silent = true;
	            });

	            hitRect.silent = !selectMode;



	            this.group.add(itemGroup);

	            graphic.setHoverStyle(itemGroup);

	            return itemGroup;
	        }
	    });


/***/ },
/* 325 */
/***/ function(module, exports, __webpack_require__) {

	
	    // List layout
	    var layout = __webpack_require__(71);
	    var formatUtil = __webpack_require__(6);
	    var graphic = __webpack_require__(18);

	    function positionGroup(group, model, api) {
	        layout.positionElement(
	            group, model.getBoxLayoutParams(),
	            {
	                width: api.getWidth(),
	                height: api.getHeight()
	            },
	            model.get('padding')
	        );
	    }

	    module.exports = {
	        /**
	         * Layout list like component.
	         * It will box layout each items in group of component and then position the whole group in the viewport
	         * @param {module:zrender/group/Group} group
	         * @param {module:echarts/model/Component} componentModel
	         * @param {module:echarts/ExtensionAPI}
	         */
	        layout: function (group, componentModel, api) {
	            var rect = layout.getLayoutRect(componentModel.getBoxLayoutParams(), {
	                width: api.getWidth(),
	                height: api.getHeight()
	            }, componentModel.get('padding'));
	            layout.box(
	                componentModel.get('orient'),
	                group,
	                componentModel.get('itemGap'),
	                rect.width,
	                rect.height
	            );

	            positionGroup(group, componentModel, api);
	        },

	        addBackground: function (group, componentModel) {
	            var padding = formatUtil.normalizeCssArray(
	                componentModel.get('padding')
	            );
	            var boundingRect = group.getBoundingRect();
	            var style = componentModel.getItemStyle(['color', 'opacity']);
	            style.fill = componentModel.get('backgroundColor');
	            var rect = new graphic.Rect({
	                shape: {
	                    x: boundingRect.x - padding[3],
	                    y: boundingRect.y - padding[0],
	                    width: boundingRect.width + padding[1] + padding[3],
	                    height: boundingRect.height + padding[0] + padding[2]
	                },
	                style: style,
	                silent: true,
	                z2: -1
	            });
	            graphic.subPixelOptimizeRect(rect);

	            group.add(rect);
	        }
	    };


/***/ },
/* 326 */
/***/ function(module, exports) {

	
	   module.exports = function (ecModel) {
	        var legendModels = ecModel.findComponents({
	            mainType: 'legend'
	        });
	        if (legendModels && legendModels.length) {
	            ecModel.filterSeries(function (series) {
	                // If in any legend component the status is not selected.
	                // Because in legend series is assumed selected when it is not in the legend data.
	                for (var i = 0; i < legendModels.length; i++) {
	                    if (!legendModels[i].isSelected(series.name)) {
	                        return false;
	                    }
	                }
	                return true;
	            });
	        }
	    };


/***/ },
/* 327 */
/***/ function(module, exports, __webpack_require__) {

	// FIXME Better way to pack data in graphic element


	    __webpack_require__(298);

	    __webpack_require__(328);

	    __webpack_require__(329);


	    // Show tip action
	    /**
	     * @action
	     * @property {string} type
	     * @property {number} seriesIndex
	     * @property {number} dataIndex
	     * @property {number} [x]
	     * @property {number} [y]
	     */
	    __webpack_require__(1).registerAction(
	        {
	            type: 'showTip',
	            event: 'showTip',
	            update: 'tooltip:manuallyShowTip'
	        },
	        // noop
	        function () {}
	    );
	    // Hide tip action
	    __webpack_require__(1).registerAction(
	        {
	            type: 'hideTip',
	            event: 'hideTip',
	            update: 'tooltip:manuallyHideTip'
	        },
	        // noop
	        function () {}
	    );


/***/ },
/* 328 */
/***/ function(module, exports, __webpack_require__) {

	

	    __webpack_require__(1).extendComponentModel({

	        type: 'tooltip',

	        dependencies: ['axisPointer'],

	        defaultOption: {
	            zlevel: 0,

	            z: 8,

	            show: true,

	            // tooltip主体内容
	            showContent: true,

	            // 'trigger' only works on coordinate system.
	            // 'item' | 'axis' | 'none'
	            trigger: 'item',

	            // 'click' | 'mousemove' | 'none'
	            triggerOn: 'mousemove|click',

	            alwaysShowContent: false,

	            displayMode: 'single', // 'single' | 'multipleByCoordSys'

	            // 位置 {Array} | {Function}
	            // position: null
	            // Consider triggered from axisPointer handle, verticalAlign should be 'middle'
	            // align: null,
	            // verticalAlign: null,

	            // 是否约束 content 在 viewRect 中。默认 false 是为了兼容以前版本。
	            confine: false,

	            // 内容格式器：{string}（Template） ¦ {Function}
	            // formatter: null

	            showDelay: 0,

	            // 隐藏延迟，单位ms
	            hideDelay: 100,

	            // 动画变换时间，单位s
	            transitionDuration: 0.4,

	            enterable: false,

	            // 提示背景颜色，默认为透明度为0.7的黑色
	            backgroundColor: 'rgba(50,50,50,0.7)',

	            // 提示边框颜色
	            borderColor: '#333',

	            // 提示边框圆角，单位px，默认为4
	            borderRadius: 4,

	            // 提示边框线宽，单位px，默认为0（无边框）
	            borderWidth: 0,

	            // 提示内边距，单位px，默认各方向内边距为5，
	            // 接受数组分别设定上右下左边距，同css
	            padding: 5,

	            // Extra css text
	            extraCssText: '',

	            // 坐标轴指示器，坐标轴触发有效
	            axisPointer: {
	                // 默认为直线
	                // 可选为：'line' | 'shadow' | 'cross'
	                type: 'line',

	                // type 为 line 的时候有效，指定 tooltip line 所在的轴，可选
	                // 可选 'x' | 'y' | 'angle' | 'radius' | 'auto'
	                // 默认 'auto'，会选择类型为 cateogry 的轴，对于双数值轴，笛卡尔坐标系会默认选择 x 轴
	                // 极坐标系会默认选择 angle 轴
	                axis: 'auto',

	                animation: 'auto',
	                animationDurationUpdate: 200,
	                animationEasingUpdate: 'exponentialOut',

	                crossStyle: {
	                    color: '#999',
	                    width: 1,
	                    type: 'dashed',

	                    // TODO formatter
	                    textStyle: {}
	                }

	                // lineStyle and shadowStyle should not be specified here,
	                // otherwise it will always override those styles on option.axisPointer.
	            },
	            textStyle: {
	                color: '#fff',
	                fontSize: 14
	            }
	        }
	    });


/***/ },
/* 329 */
/***/ function(module, exports, __webpack_require__) {

	

	    var TooltipContent = __webpack_require__(330);
	    var zrUtil = __webpack_require__(4);
	    var formatUtil = __webpack_require__(6);
	    var numberUtil = __webpack_require__(7);
	    var graphic = __webpack_require__(18);
	    var findPointFromSeries = __webpack_require__(300);
	    var layoutUtil = __webpack_require__(71);
	    var env = __webpack_require__(2);
	    var Model = __webpack_require__(12);
	    var globalListener = __webpack_require__(303);
	    var axisHelper = __webpack_require__(101);
	    var axisPointerViewHelper = __webpack_require__(306);

	    var bind = zrUtil.bind;
	    var each = zrUtil.each;
	    var parsePercent = numberUtil.parsePercent;


	    var proxyRect = new graphic.Rect({
	        shape: {x: -1, y: -1, width: 2, height: 2}
	    });

	    __webpack_require__(1).extendComponentView({

	        type: 'tooltip',

	        init: function (ecModel, api) {
	            if (env.node) {
	                return;
	            }
	            var tooltipContent = new TooltipContent(api.getDom(), api);
	            this._tooltipContent = tooltipContent;
	        },

	        render: function (tooltipModel, ecModel, api) {
	            if (env.node) {
	                return;
	            }

	            // Reset
	            this.group.removeAll();

	            /**
	             * @private
	             * @type {module:echarts/component/tooltip/TooltipModel}
	             */
	            this._tooltipModel = tooltipModel;

	            /**
	             * @private
	             * @type {module:echarts/model/Global}
	             */
	            this._ecModel = ecModel;

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

	            /**
	             * Should be cleaned when render.
	             * @private
	             * @type {Array.<Array.<Object>>}
	             */
	            this._lastDataByCoordSys = null;

	            /**
	             * @private
	             * @type {boolean}
	             */
	            this._alwaysShowContent = tooltipModel.get('alwaysShowContent');

	            var tooltipContent = this._tooltipContent;
	            tooltipContent.update();
	            tooltipContent.setEnterable(tooltipModel.get('enterable'));

	            this._initGlobalListener();

	            this._keepShow();
	        },

	        _initGlobalListener: function () {
	            var tooltipModel = this._tooltipModel;
	            var triggerOn = tooltipModel.get('triggerOn');

	            globalListener.register(
	                'itemTooltip',
	                this._api,
	                bind(function (currTrigger, e, dispatchAction) {
	                    // If 'none', it is not controlled by mouse totally.
	                    if (triggerOn !== 'none') {
	                        if (triggerOn.indexOf(currTrigger) >= 0) {
	                            this._tryShow(e, dispatchAction);
	                        }
	                        else if (currTrigger === 'leave') {
	                            this._hide(dispatchAction);
	                        }
	                    }
	                }, this)
	            );
	        },

	        _keepShow: function () {
	            var tooltipModel = this._tooltipModel;
	            var ecModel = this._ecModel;
	            var api = this._api;

	            // Try to keep the tooltip show when refreshing
	            if (this._lastX != null
	                && this._lastY != null
	                // When user is willing to control tooltip totally using API,
	                // self.manuallyShowTip({x, y}) might cause tooltip hide,
	                // which is not expected.
	                && tooltipModel.get('triggerOn') !== 'none'
	            ) {
	                var self = this;
	                clearTimeout(this._refreshUpdateTimeout);
	                this._refreshUpdateTimeout = setTimeout(function () {
	                    // Show tip next tick after other charts are rendered
	                    // In case highlight action has wrong result
	                    // FIXME
	                    self.manuallyShowTip(tooltipModel, ecModel, api, {
	                        x: self._lastX,
	                        y: self._lastY
	                    });
	                });
	            }
	        },

	        /**
	         * Show tip manually by
	         * dispatchAction({
	         *     type: 'showTip',
	         *     x: 10,
	         *     y: 10
	         * });
	         * Or
	         * dispatchAction({
	         *      type: 'showTip',
	         *      seriesIndex: 0,
	         *      dataIndex or dataIndexInside or name
	         * });
	         *
	         *  TODO Batch
	         */
	        manuallyShowTip: function (tooltipModel, ecModel, api, payload) {
	            if (payload.from === this.uid || env.node) {
	                return;
	            }

	            var dispatchAction = makeDispatchAction(payload, api);

	            // Reset ticket
	            this._ticket = '';

	            // When triggered from axisPointer.
	            var dataByCoordSys = payload.dataByCoordSys;

	            if (payload.tooltip && payload.x != null && payload.y != null) {
	                var el = proxyRect;
	                el.position = [payload.x, payload.y];
	                el.update();
	                el.tooltip = payload.tooltip;
	                // Manually show tooltip while view is not using zrender elements.
	                this._tryShow({
	                    offsetX: payload.x,
	                    offsetY: payload.y,
	                    target: el
	                }, dispatchAction);
	            }
	            else if (dataByCoordSys) {
	                this._tryShow({
	                    offsetX: payload.x,
	                    offsetY: payload.y,
	                    position: payload.position,
	                    event: {},
	                    dataByCoordSys: payload.dataByCoordSys,
	                    tooltipOption: payload.tooltipOption
	                }, dispatchAction);
	            }
	            else if (payload.seriesIndex != null) {

	                if (this._manuallyAxisShowTip(tooltipModel, ecModel, api, payload)) {
	                    return;
	                }

	                var pointInfo = findPointFromSeries(payload, ecModel);
	                var cx = pointInfo.point[0];
	                var cy = pointInfo.point[1];
	                if (cx != null && cy != null) {
	                    this._tryShow({
	                        offsetX: cx,
	                        offsetY: cy,
	                        position: payload.position,
	                        target: pointInfo.el,
	                        event: {}
	                    }, dispatchAction);
	                }
	            }
	            else if (payload.x != null && payload.y != null) {
	                // FIXME
	                // should wrap dispatchAction like `axisPointer/globalListener` ?
	                api.dispatchAction({
	                    type: 'updateAxisPointer',
	                    x: payload.x,
	                    y: payload.y
	                });

	                this._tryShow({
	                    offsetX: payload.x,
	                    offsetY: payload.y,
	                    position: payload.position,
	                    target: api.getZr().findHover(payload.x, payload.y).target,
	                    event: {}
	                }, dispatchAction);
	            }
	        },

	        manuallyHideTip: function (tooltipModel, ecModel, api, payload) {
	            var tooltipContent = this._tooltipContent;

	            if (!this._alwaysShowContent) {
	                tooltipContent.hideLater(this._tooltipModel.get('hideDelay'));
	            }

	            this._lastX = this._lastY = null;

	            if (payload.from !== this.uid) {
	                this._hide(makeDispatchAction(payload, api));
	            }
	        },

	        // Be compatible with previous design, that is, when tooltip.type is 'axis' and
	        // dispatchAction 'showTip' with seriesIndex and dataIndex will trigger axis pointer
	        // and tooltip.
	        _manuallyAxisShowTip: function (tooltipModel, ecModel, api, payload) {
	            var seriesIndex = payload.seriesIndex;
	            var dataIndex = payload.dataIndex;
	            var coordSysAxesInfo = ecModel.getComponent('axisPointer').coordSysAxesInfo;

	            if (seriesIndex == null || dataIndex == null || coordSysAxesInfo == null) {
	                return;
	            }

	            var seriesModel = ecModel.getSeriesByIndex(seriesIndex);
	            if (!seriesModel) {
	                return;
	            }

	            var data = seriesModel.getData();
	            var tooltipModel = buildTooltipModel([
	                data.getItemModel(dataIndex),
	                seriesModel,
	                (seriesModel.coordinateSystem || {}).model,
	                tooltipModel
	            ]);

	            if (tooltipModel.get('trigger') !== 'axis') {
	                return;
	            }

	            api.dispatchAction({
	                type: 'updateAxisPointer',
	                seriesIndex: seriesIndex,
	                dataIndex: dataIndex,
	                position: payload.position
	            });

	            return true;
	        },

	        _tryShow: function (e, dispatchAction) {
	            var el = e.target;
	            var tooltipModel = this._tooltipModel;

	            if (!tooltipModel) {
	                return;
	            }

	            // Save mouse x, mouse y. So we can try to keep showing the tip if chart is refreshed
	            this._lastX = e.offsetX;
	            this._lastY = e.offsetY;

	            var dataByCoordSys = e.dataByCoordSys;
	            if (dataByCoordSys && dataByCoordSys.length) {
	                this._showAxisTooltip(dataByCoordSys, e);
	            }
	            // Always show item tooltip if mouse is on the element with dataIndex
	            else if (el && el.dataIndex != null) {
	                this._lastDataByCoordSys = null;
	                this._showSeriesItemTooltip(e, el, dispatchAction);
	            }
	            // Tooltip provided directly. Like legend.
	            else if (el && el.tooltip) {
	                this._lastDataByCoordSys = null;
	                this._showComponentItemTooltip(e, el, dispatchAction);
	            }
	            else {
	                this._lastDataByCoordSys = null;
	                this._hide(dispatchAction);
	            }
	        },

	        _showOrMove: function (tooltipModel, cb) {
	            // showDelay is used in this case: tooltip.enterable is set
	            // as true. User intent to move mouse into tooltip and click
	            // something. `showDelay` makes it easyer to enter the content
	            // but tooltip do not move immediately.
	            var delay = tooltipModel.get('showDelay');
	            cb = zrUtil.bind(cb, this);
	            clearTimeout(this._showTimout);
	            delay > 0
	                ? (this._showTimout = setTimeout(cb, delay))
	                : cb();
	        },

	        _showAxisTooltip: function (dataByCoordSys, e) {
	            var ecModel = this._ecModel;
	            var globalTooltipModel = this._tooltipModel;
	            var point = [e.offsetX, e.offsetY];
	            var singleDefaultHTML = [];
	            var singleParamsList = [];
	            var singleTooltipModel = buildTooltipModel([
	                e.tooltipOption,
	                globalTooltipModel
	            ]);

	            each(dataByCoordSys, function (itemCoordSys) {
	                // var coordParamList = [];
	                // var coordDefaultHTML = [];
	                // var coordTooltipModel = buildTooltipModel([
	                //     e.tooltipOption,
	                //     itemCoordSys.tooltipOption,
	                //     ecModel.getComponent(itemCoordSys.coordSysMainType, itemCoordSys.coordSysIndex),
	                //     globalTooltipModel
	                // ]);
	                // var displayMode = coordTooltipModel.get('displayMode');
	                // var paramsList = displayMode === 'single' ? singleParamsList : [];

	                each(itemCoordSys.dataByAxis, function (item) {
	                    var axisModel = ecModel.getComponent(item.axisDim + 'Axis', item.axisIndex);
	                    var axisValue = item.value;
	                    var seriesDefaultHTML = [];

	                    if (!axisModel || axisValue == null) {
	                        return;
	                    }

	                    var valueLabel = axisPointerViewHelper.getValueLabel(
	                        axisValue, axisModel.axis, ecModel,
	                        item.seriesDataIndices,
	                        item.valueLabelOpt
	                    );

	                    zrUtil.each(item.seriesDataIndices, function (idxItem) {
	                        var series = ecModel.getSeriesByIndex(idxItem.seriesIndex);
	                        var dataIndex = idxItem.dataIndexInside;
	                        var dataParams = series && series.getDataParams(dataIndex);
	                        dataParams.axisDim = item.axisDim;
	                        dataParams.axisIndex = item.axisIndex;
	                        dataParams.axisType = item.axisType;
	                        dataParams.axisId = item.axisId;
	                        dataParams.axisValue = axisHelper.getAxisRawValue(axisModel.axis, axisValue);
	                        dataParams.axisValueLabel = valueLabel;

	                        if (dataParams) {
	                            singleParamsList.push(dataParams);
	                            seriesDefaultHTML.push(series.formatTooltip(dataIndex, true));
	                        }
	                    });

	                    // Default tooltip content
	                    // FIXME
	                    // (1) shold be the first data which has name?
	                    // (2) themeRiver, firstDataIndex is array, and first line is unnecessary.
	                    var firstLine = valueLabel;
	                    singleDefaultHTML.push(
	                        (firstLine ? formatUtil.encodeHTML(firstLine) + '<br />' : '')
	                        + seriesDefaultHTML.join('<br />')
	                    );
	                });
	            }, this);

	            // In most case, the second axis is shown upper than the first one.
	            singleDefaultHTML.reverse();
	            singleDefaultHTML = singleDefaultHTML.join('<br /><br />');

	            var positionExpr = e.position;
	            this._showOrMove(singleTooltipModel, function () {
	                if (this._updateContentNotChangedOnAxis(dataByCoordSys)) {
	                    this._updatePosition(
	                        singleTooltipModel,
	                        positionExpr,
	                        point[0], point[1],
	                        this._tooltipContent,
	                        singleParamsList
	                    );
	                }
	                else {
	                    this._showTooltipContent(
	                        singleTooltipModel, singleDefaultHTML, singleParamsList, Math.random(),
	                        point[0], point[1], positionExpr
	                    );
	                }
	            });

	            // Do not trigger events here, because this branch only be entered
	            // from dispatchAction.
	        },

	        _showSeriesItemTooltip: function (e, el, dispatchAction) {
	            var ecModel = this._ecModel;
	            // Use dataModel in element if possible
	            // Used when mouseover on a element like markPoint or edge
	            // In which case, the data is not main data in series.
	            var seriesIndex = el.seriesIndex;
	            var seriesModel = ecModel.getSeriesByIndex(seriesIndex);

	            // For example, graph link.
	            var dataModel = el.dataModel || seriesModel;
	            var dataIndex = el.dataIndex;
	            var dataType = el.dataType;
	            var data = dataModel.getData();

	            var tooltipModel = buildTooltipModel([
	                data.getItemModel(dataIndex),
	                dataModel,
	                seriesModel && (seriesModel.coordinateSystem || {}).model,
	                this._tooltipModel
	            ]);

	            var tooltipTrigger = tooltipModel.get('trigger');
	            if (tooltipTrigger != null && tooltipTrigger !== 'item') {
	                return;
	            }

	            var params = dataModel.getDataParams(dataIndex, dataType);
	            var defaultHtml = dataModel.formatTooltip(dataIndex, false, dataType);
	            var asyncTicket = 'item_' + dataModel.name + '_' + dataIndex;

	            this._showOrMove(tooltipModel, function () {
	                this._showTooltipContent(
	                    tooltipModel, defaultHtml, params, asyncTicket,
	                    e.offsetX, e.offsetY, e.position, e.target
	                );
	            });

	            // FIXME
	            // duplicated showtip if manuallyShowTip is called from dispatchAction.
	            dispatchAction({
	                type: 'showTip',
	                dataIndexInside: dataIndex,
	                dataIndex: data.getRawIndex(dataIndex),
	                seriesIndex: seriesIndex,
	                from: this.uid
	            });
	        },

	        _showComponentItemTooltip: function (e, el, dispatchAction) {
	            var tooltipOpt = el.tooltip;
	            if (typeof tooltipOpt === 'string') {
	                var content = tooltipOpt;
	                tooltipOpt = {
	                    content: content,
	                    // Fixed formatter
	                    formatter: content
	                };
	            }
	            var subTooltipModel = new Model(tooltipOpt, this._tooltipModel, this._ecModel);
	            var defaultHtml = subTooltipModel.get('content');
	            var asyncTicket = Math.random();

	            // Do not check whether `trigger` is 'none' here, because `trigger`
	            // only works on cooridinate system. In fact, we have not found case
	            // that requires setting `trigger` nothing on component yet.

	            this._showOrMove(subTooltipModel, function () {
	                this._showTooltipContent(
	                    subTooltipModel, defaultHtml, subTooltipModel.get('formatterParams') || {},
	                    asyncTicket, e.offsetX, e.offsetY, e.position, el
	                );
	            });

	            // If not dispatch showTip, tip may be hide triggered by axis.
	            dispatchAction({
	                type: 'showTip',
	                from: this.uid
	            });
	        },

	        _showTooltipContent: function (
	            tooltipModel, defaultHtml, params, asyncTicket, x, y, positionExpr, el
	        ) {
	            // Reset ticket
	            this._ticket = '';

	            if (!tooltipModel.get('showContent') || !tooltipModel.get('show')) {
	                return;
	            }

	            var tooltipContent = this._tooltipContent;

	            var formatter = tooltipModel.get('formatter');
	            positionExpr = positionExpr || tooltipModel.get('position');
	            var html = defaultHtml;

	            if (formatter && typeof formatter === 'string') {
	                html = formatUtil.formatTpl(formatter, params, true);
	            }
	            else if (typeof formatter === 'function') {
	                var callback = bind(function (cbTicket, html) {
	                    if (cbTicket === this._ticket) {
	                        tooltipContent.setContent(html);
	                        this._updatePosition(
	                            tooltipModel, positionExpr, x, y, tooltipContent, params, el
	                        );
	                    }
	                }, this);
	                this._ticket = asyncTicket;
	                html = formatter(params, asyncTicket, callback);
	            }

	            tooltipContent.setContent(html);
	            tooltipContent.show(tooltipModel);

	            this._updatePosition(
	                tooltipModel, positionExpr, x, y, tooltipContent, params, el
	            );
	        },

	        /**
	         * @param  {string|Function|Array.<number>} positionExpr
	         * @param  {number} x Mouse x
	         * @param  {number} y Mouse y
	         * @param  {boolean} confine Whether confine tooltip content in view rect.
	         * @param  {Object|<Array.<Object>} params
	         * @param  {module:zrender/Element} el target element
	         * @param  {module:echarts/ExtensionAPI} api
	         * @return {Array.<number>}
	         */
	        _updatePosition: function (tooltipModel, positionExpr, x, y, content, params, el) {
	            var viewWidth = this._api.getWidth();
	            var viewHeight = this._api.getHeight();
	            positionExpr = positionExpr || tooltipModel.get('position');

	            var contentSize = content.getSize();
	            var align = tooltipModel.get('align');
	            var vAlign = tooltipModel.get('verticalAlign');
	            var rect = el && el.getBoundingRect().clone();
	            el && rect.applyTransform(el.transform);

	            if (typeof positionExpr === 'function') {
	                // Callback of position can be an array or a string specify the position
	                positionExpr = positionExpr([x, y], params, content.el, rect, {
	                    viewSize: [viewWidth, viewHeight],
	                    contentSize: contentSize.slice()
	                });
	            }

	            if (zrUtil.isArray(positionExpr)) {
	                x = parsePercent(positionExpr[0], viewWidth);
	                y = parsePercent(positionExpr[1], viewHeight);
	            }
	            else if (zrUtil.isObject(positionExpr)) {
	                positionExpr.width = contentSize[0];
	                positionExpr.height = contentSize[1];
	                var layoutRect = layoutUtil.getLayoutRect(
	                    positionExpr, {width: viewWidth, height: viewHeight}
	                );
	                x = layoutRect.x;
	                y = layoutRect.y;
	                align = null;
	                // When positionExpr is left/top/right/bottom,
	                // align and verticalAlign will not work.
	                vAlign = null;
	            }
	            // Specify tooltip position by string 'top' 'bottom' 'left' 'right' around graphic element
	            else if (typeof positionExpr === 'string' && el) {
	                var pos = calcTooltipPosition(
	                    positionExpr, rect, contentSize
	                );
	                x = pos[0];
	                y = pos[1];
	            }
	            else {
	                var pos = refixTooltipPosition(
	                    x, y, content.el, viewWidth, viewHeight, align ? null : 20, vAlign ? null : 20
	                );
	                x = pos[0];
	                y = pos[1];
	            }

	            align && (x -= isCenterAlign(align) ? contentSize[0] / 2 : align === 'right' ? contentSize[0] : 0);
	            vAlign && (y -= isCenterAlign(vAlign) ? contentSize[1] / 2 : vAlign === 'bottom' ? contentSize[1] : 0);

	            if (tooltipModel.get('confine')) {
	                var pos = confineTooltipPosition(
	                    x, y, content.el, viewWidth, viewHeight
	                );
	                x = pos[0];
	                y = pos[1];
	            }

	            content.moveTo(x, y);
	        },

	        // FIXME
	        // Should we remove this but leave this to user?
	        _updateContentNotChangedOnAxis: function (dataByCoordSys) {
	            var lastCoordSys = this._lastDataByCoordSys;
	            var contentNotChanged = !!lastCoordSys
	                && lastCoordSys.length === dataByCoordSys.length;

	            contentNotChanged && each(lastCoordSys, function (lastItemCoordSys, indexCoordSys) {
	                var lastDataByAxis = lastItemCoordSys.dataByAxis || {};
	                var thisItemCoordSys = dataByCoordSys[indexCoordSys] || {};
	                var thisDataByAxis = thisItemCoordSys.dataByAxis || [];
	                contentNotChanged &= lastDataByAxis.length === thisDataByAxis.length;

	                contentNotChanged && each(lastDataByAxis, function (lastItem, indexAxis) {
	                    var thisItem = thisDataByAxis[indexAxis] || {};
	                    var lastIndices = lastItem.seriesDataIndices || [];
	                    var newIndices = thisItem.seriesDataIndices || [];

	                    contentNotChanged &=
	                        lastItem.value === thisItem.value
	                        && lastItem.axisType === thisItem.axisType
	                        && lastItem.axisId === thisItem.axisId
	                        && lastIndices.length === newIndices.length;

	                    contentNotChanged && each(lastIndices, function (lastIdxItem, j) {
	                        var newIdxItem = newIndices[j];
	                        contentNotChanged &=
	                            lastIdxItem.seriesIndex === newIdxItem.seriesIndex
	                            && lastIdxItem.dataIndex === newIdxItem.dataIndex;
	                    });
	                });
	            });

	            this._lastDataByCoordSys = dataByCoordSys;

	            return !!contentNotChanged;
	        },

	        _hide: function (dispatchAction) {
	            // Do not directly hideLater here, because this behavior may be prevented
	            // in dispatchAction when showTip is dispatched.

	            // FIXME
	            // duplicated hideTip if manuallyHideTip is called from dispatchAction.
	            this._lastDataByCoordSys = null;
	            dispatchAction({
	                type: 'hideTip',
	                from: this.uid
	            });
	        },

	        dispose: function (ecModel, api) {
	            if (env.node) {
	                return;
	            }
	            this._tooltipContent.hide();
	            globalListener.unregister('itemTooltip', api);
	        }
	    });


	    /**
	     * @param {Array.<Object|module:echarts/model/Model>} modelCascade
	     * From top to bottom. (the last one should be globalTooltipModel);
	     */
	    function buildTooltipModel(modelCascade) {
	        var resultModel = modelCascade.pop();
	        while (modelCascade.length) {
	            var tooltipOpt = modelCascade.pop();
	            if (tooltipOpt) {
	                if (tooltipOpt instanceof Model) {
	                    tooltipOpt = tooltipOpt.get('tooltip', true);
	                }
	                // In each data item tooltip can be simply write:
	                // {
	                //  value: 10,
	                //  tooltip: 'Something you need to know'
	                // }
	                if (typeof tooltipOpt === 'string') {
	                    tooltipOpt = {formatter: tooltipOpt};
	                }
	                resultModel = new Model(tooltipOpt, resultModel, resultModel.ecModel);
	            }
	        }
	        return resultModel;
	    }

	    function makeDispatchAction(payload, api) {
	        return payload.dispatchAction || zrUtil.bind(api.dispatchAction, api);
	    }

	    function refixTooltipPosition(x, y, el, viewWidth, viewHeight, gapH, gapV) {
	        var width = el.clientWidth;
	        var height = el.clientHeight;

	        if (gapH != null) {
	            if (x + width + gapH > viewWidth) {
	                x -= width + gapH;
	            }
	            else {
	                x += gapH;
	            }
	        }
	        if (gapV != null) {
	            if (y + height + gapV > viewHeight) {
	                y -= height + gapV;
	            }
	            else {
	                y += gapV;
	            }
	        }
	        return [x, y];
	    }

	    function confineTooltipPosition(x, y, el, viewWidth, viewHeight) {
	        var width = el.clientWidth;
	        var height = el.clientHeight;

	        x = Math.min(x + width, viewWidth) - width;
	        y = Math.min(y + height, viewHeight) - height;
	        x = Math.max(x, 0);
	        y = Math.max(y, 0);

	        return [x, y];
	    }

	    function calcTooltipPosition(position, rect, contentSize) {
	        var domWidth = contentSize[0];
	        var domHeight = contentSize[1];
	        var gap = 5;
	        var x = 0;
	        var y = 0;
	        var rectWidth = rect.width;
	        var rectHeight = rect.height;
	        switch (position) {
	            case 'inside':
	                x = rect.x + rectWidth / 2 - domWidth / 2;
	                y = rect.y + rectHeight / 2 - domHeight / 2;
	                break;
	            case 'top':
	                x = rect.x + rectWidth / 2 - domWidth / 2;
	                y = rect.y - domHeight - gap;
	                break;
	            case 'bottom':
	                x = rect.x + rectWidth / 2 - domWidth / 2;
	                y = rect.y + rectHeight + gap;
	                break;
	            case 'left':
	                x = rect.x - domWidth - gap;
	                y = rect.y + rectHeight / 2 - domHeight / 2;
	                break;
	            case 'right':
	                x = rect.x + rectWidth + gap;
	                y = rect.y + rectHeight / 2 - domHeight / 2;
	        }
	        return [x, y];
	    }

	    function isCenterAlign(align) {
	        return align === 'center' || align === 'middle';
	    }



/***/ },
/* 330 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @module echarts/component/tooltip/TooltipContent
	 */


	    var zrUtil = __webpack_require__(4);
	    var zrColor = __webpack_require__(31);
	    var eventUtil = __webpack_require__(88);
	    var formatUtil = __webpack_require__(6);
	    var each = zrUtil.each;
	    var toCamelCase = formatUtil.toCamelCase;
	    var env = __webpack_require__(2);

	    var vendors = ['', '-webkit-', '-moz-', '-o-'];

	    var gCssText = 'position:absolute;display:block;border-style:solid;white-space:nowrap;z-index:9999999;';

	    /**
	     * @param {number} duration
	     * @return {string}
	     * @inner
	     */
	    function assembleTransition(duration) {
	        var transitionCurve = 'cubic-bezier(0.23, 1, 0.32, 1)';
	        var transitionText = 'left ' + duration + 's ' + transitionCurve + ','
	                            + 'top ' + duration + 's ' + transitionCurve;
	        return zrUtil.map(vendors, function (vendorPrefix) {
	            return vendorPrefix + 'transition:' + transitionText;
	        }).join(';');
	    }

	    /**
	     * @param {Object} textStyle
	     * @return {string}
	     * @inner
	     */
	    function assembleFont(textStyleModel) {
	        var cssText = [];

	        var fontSize = textStyleModel.get('fontSize');
	        var color = textStyleModel.getTextColor();

	        color && cssText.push('color:' + color);

	        cssText.push('font:' + textStyleModel.getFont());

	        fontSize &&
	            cssText.push('line-height:' + Math.round(fontSize * 3 / 2) + 'px');

	        each(['decoration', 'align'], function (name) {
	            var val = textStyleModel.get(name);
	            val && cssText.push('text-' + name + ':' + val);
	        });

	        return cssText.join(';');
	    }

	    /**
	     * @param {Object} tooltipModel
	     * @return {string}
	     * @inner
	     */
	    function assembleCssText(tooltipModel) {

	        var cssText = [];

	        var transitionDuration = tooltipModel.get('transitionDuration');
	        var backgroundColor = tooltipModel.get('backgroundColor');
	        var textStyleModel = tooltipModel.getModel('textStyle');
	        var padding = tooltipModel.get('padding');

	        // Animation transition. Do not animate when transitionDuration is 0.
	        transitionDuration &&
	            cssText.push(assembleTransition(transitionDuration));

	        if (backgroundColor) {
	            if (env.canvasSupported) {
	                cssText.push('background-Color:' + backgroundColor);
	            }
	            else {
	                // for ie
	                cssText.push(
	                    'background-Color:#' + zrColor.toHex(backgroundColor)
	                );
	                cssText.push('filter:alpha(opacity=70)');
	            }
	        }

	        // Border style
	        each(['width', 'color', 'radius'], function (name) {
	            var borderName = 'border-' + name;
	            var camelCase = toCamelCase(borderName);
	            var val = tooltipModel.get(camelCase);
	            val != null &&
	                cssText.push(borderName + ':' + val + (name === 'color' ? '' : 'px'));
	        });

	        // Text style
	        cssText.push(assembleFont(textStyleModel));

	        // Padding
	        if (padding != null) {
	            cssText.push('padding:' + formatUtil.normalizeCssArray(padding).join('px ') + 'px');
	        }

	        return cssText.join(';') + ';';
	    }

	    /**
	     * @alias module:echarts/component/tooltip/TooltipContent
	     * @constructor
	     */
	    function TooltipContent(container, api) {
	        var el = document.createElement('div');
	        var zr = this._zr = api.getZr();

	        this.el = el;

	        this._x = api.getWidth() / 2;
	        this._y = api.getHeight() / 2;

	        container.appendChild(el);

	        this._container = container;

	        this._show = false;

	        /**
	         * @private
	         */
	        this._hideTimeout;

	        var self = this;
	        el.onmouseenter = function () {
	            // clear the timeout in hideLater and keep showing tooltip
	            if (self._enterable) {
	                clearTimeout(self._hideTimeout);
	                self._show = true;
	            }
	            self._inContent = true;
	        };
	        el.onmousemove = function (e) {
	            e = e || window.event;
	            if (!self._enterable) {
	                // Try trigger zrender event to avoid mouse
	                // in and out shape too frequently
	                var handler = zr.handler;
	                eventUtil.normalizeEvent(container, e, true);
	                handler.dispatch('mousemove', e);
	            }
	        };
	        el.onmouseleave = function () {
	            if (self._enterable) {
	                if (self._show) {
	                    self.hideLater(self._hideDelay);
	                }
	            }
	            self._inContent = false;
	        };
	    }

	    TooltipContent.prototype = {

	        constructor: TooltipContent,

	        /**
	         * @private
	         * @type {boolean}
	         */
	        _enterable: true,

	        /**
	         * Update when tooltip is rendered
	         */
	        update: function () {
	            // FIXME
	            // Move this logic to ec main?
	            var container = this._container;
	            var stl = container.currentStyle
	                || document.defaultView.getComputedStyle(container);
	            var domStyle = container.style;
	            if (domStyle.position !== 'absolute' && stl.position !== 'absolute') {
	                domStyle.position = 'relative';
	            }
	            // Hide the tooltip
	            // PENDING
	            // this.hide();
	        },

	        show: function (tooltipModel) {
	            clearTimeout(this._hideTimeout);
	            var el = this.el;

	            el.style.cssText = gCssText + assembleCssText(tooltipModel)
	                // http://stackoverflow.com/questions/21125587/css3-transition-not-working-in-chrome-anymore
	                + ';left:' + this._x + 'px;top:' + this._y + 'px;'
	                + (tooltipModel.get('extraCssText') || '');

	            el.style.display = el.innerHTML ?  'block' : 'none';

	            this._show = true;
	        },

	        setContent: function (content) {
	            this.el.innerHTML = content == null ? '' : content;
	        },

	        setEnterable: function (enterable) {
	            this._enterable = enterable;
	        },

	        getSize: function () {
	            var el = this.el;
	            return [el.clientWidth, el.clientHeight];
	        },

	        moveTo: function (x, y) {
	            // xy should be based on canvas root. But tooltipContent is
	            // the sibling of canvas root. So padding of ec container
	            // should be considered here.
	            var zr = this._zr;
	            var viewportRoot;
	            if (zr && zr.painter && (viewportRoot = zr.painter.getViewportRoot())) {
	                x += viewportRoot.offsetLeft || 0;
	                y += viewportRoot.offsetTop || 0;
	            }

	            var style = this.el.style;
	            style.left = x + 'px';
	            style.top = y + 'px';

	            this._x = x;
	            this._y = y;
	        },

	        hide: function () {
	            this.el.style.display = 'none';
	            this._show = false;
	        },

	        hideLater: function (time) {
	            if (this._show && !(this._inContent && this._enterable)) {
	                if (time) {
	                    this._hideDelay = time;
	                    // Set show false to avoid invoke hideLater mutiple times
	                    this._show = false;
	                    this._hideTimeout = setTimeout(zrUtil.bind(this.hide, this), time);
	                }
	                else {
	                    this.hide();
	                }
	            }
	        },

	        isShow: function () {
	            return this._show;
	        }
	    };

	    module.exports = TooltipContent;


/***/ },
/* 331 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var zrUtil = __webpack_require__(4);

	    __webpack_require__(332);
	    __webpack_require__(338);
	    __webpack_require__(340);
	    __webpack_require__(298);

	    __webpack_require__(342);

	    // For reducing size of echarts.min, barLayoutPolar is required by polar.
	    __webpack_require__(1).registerLayout(zrUtil.curry(__webpack_require__(343), 'bar'));

	    // Polar view
	    __webpack_require__(1).extendComponentView({
	        type: 'polar'
	    });


/***/ },
/* 332 */
/***/ function(module, exports, __webpack_require__) {

	// TODO Axis scale


	    var Polar = __webpack_require__(333);
	    var numberUtil = __webpack_require__(7);
	    var zrUtil = __webpack_require__(4);

	    var axisHelper = __webpack_require__(101);
	    var niceScaleExtent = axisHelper.niceScaleExtent;

	    // 依赖 PolarModel 做预处理
	    __webpack_require__(336);

	    /**
	     * Resize method bound to the polar
	     * @param {module:echarts/coord/polar/PolarModel} polarModel
	     * @param {module:echarts/ExtensionAPI} api
	     */
	    function resizePolar(polarModel, api) {
	        var center = polarModel.get('center');
	        var radius = polarModel.get('radius');
	        var width = api.getWidth();
	        var height = api.getHeight();
	        var parsePercent = numberUtil.parsePercent;

	        this.cx = parsePercent(center[0], width);
	        this.cy = parsePercent(center[1], height);

	        var radiusAxis = this.getRadiusAxis();
	        var size = Math.min(width, height) / 2;
	        // var idx = radiusAxis.inverse ? 1 : 0;
	        radiusAxis.setExtent(0, parsePercent(radius, size));
	    }

	    /**
	     * Update polar
	     */
	    function updatePolarScale(ecModel, api) {
	        var polar = this;
	        var angleAxis = polar.getAngleAxis();
	        var radiusAxis = polar.getRadiusAxis();
	        // Reset scale
	        angleAxis.scale.setExtent(Infinity, -Infinity);
	        radiusAxis.scale.setExtent(Infinity, -Infinity);

	        ecModel.eachSeries(function (seriesModel) {
	            if (seriesModel.coordinateSystem === polar) {
	                var data = seriesModel.getData();
	                radiusAxis.scale.unionExtentFromData(data, 'radius');
	                angleAxis.scale.unionExtentFromData(data, 'angle');
	            }
	        });

	        niceScaleExtent(angleAxis.scale, angleAxis.model);
	        niceScaleExtent(radiusAxis.scale, radiusAxis.model);

	        // Fix extent of category angle axis
	        if (angleAxis.type === 'category' && !angleAxis.onBand) {
	            var extent = angleAxis.getExtent();
	            var diff = 360 / angleAxis.scale.count();
	            angleAxis.inverse ? (extent[1] += diff) : (extent[1] -= diff);
	            angleAxis.setExtent(extent[0], extent[1]);
	        }
	    }

	    /**
	     * Set common axis properties
	     * @param {module:echarts/coord/polar/AngleAxis|module:echarts/coord/polar/RadiusAxis}
	     * @param {module:echarts/coord/polar/AxisModel}
	     * @inner
	     */
	    function setAxis(axis, axisModel) {
	        axis.type = axisModel.get('type');
	        axis.scale = axisHelper.createScaleByModel(axisModel);
	        axis.onBand = axisModel.get('boundaryGap') && axis.type === 'category';

	        // FIXME Radius axis not support inverse axis
	        if (axisModel.mainType === 'angleAxis') {
	            var startAngle = axisModel.get('startAngle');
	            axis.inverse = axisModel.get('inverse') ^ axisModel.get('clockwise');
	            axis.setExtent(startAngle, startAngle + (axis.inverse ? -360 : 360));
	        }

	        // Inject axis instance
	        axisModel.axis = axis;
	        axis.model = axisModel;
	    }


	    var polarCreator = {

	        dimensions: Polar.prototype.dimensions,

	        create: function (ecModel, api) {
	            var polarList = [];
	            ecModel.eachComponent('polar', function (polarModel, idx) {
	                var polar = new Polar(idx);
	                // Inject resize and update method
	                polar.resize = resizePolar;
	                polar.update = updatePolarScale;

	                var radiusAxis = polar.getRadiusAxis();
	                var angleAxis = polar.getAngleAxis();

	                var radiusAxisModel = polarModel.findAxisModel('radiusAxis');
	                var angleAxisModel = polarModel.findAxisModel('angleAxis');

	                setAxis(radiusAxis, radiusAxisModel);
	                setAxis(angleAxis, angleAxisModel);

	                polar.resize(polarModel, api);
	                polarList.push(polar);

	                polarModel.coordinateSystem = polar;
	                polar.model = polarModel;
	            });
	            // Inject coordinateSystem to series
	            ecModel.eachSeries(function (seriesModel) {
	                if (seriesModel.get('coordinateSystem') === 'polar') {
	                    var polarModel = ecModel.queryComponents({
	                        mainType: 'polar',
	                        index: seriesModel.get('polarIndex'),
	                        id: seriesModel.get('polarId')
	                    })[0];

	                    if (true) {
	                        if (!polarModel) {
	                            throw new Error(
	                                'Polar "' + zrUtil.retrieve(
	                                    seriesModel.get('polarIndex'),
	                                    seriesModel.get('polarId'),
	                                    0
	                                ) + '" not found'
	                            );
	                        }
	                    }
	                    seriesModel.coordinateSystem = polarModel.coordinateSystem;
	                }
	            });

	            return polarList;
	        }
	    };

	    __webpack_require__(76).register('polar', polarCreator);


/***/ },
/* 333 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	/**
	 * @module echarts/coord/polar/Polar
	 */


	    var RadiusAxis = __webpack_require__(334);
	    var AngleAxis = __webpack_require__(335);

	    /**
	     * @alias {module:echarts/coord/polar/Polar}
	     * @constructor
	     * @param {string} name
	     */
	    var Polar = function (name) {

	        /**
	         * @type {string}
	         */
	        this.name = name || '';

	        /**
	         * x of polar center
	         * @type {number}
	         */
	        this.cx = 0;

	        /**
	         * y of polar center
	         * @type {number}
	         */
	        this.cy = 0;

	        /**
	         * @type {module:echarts/coord/polar/RadiusAxis}
	         * @private
	         */
	        this._radiusAxis = new RadiusAxis();

	        /**
	         * @type {module:echarts/coord/polar/AngleAxis}
	         * @private
	         */
	        this._angleAxis = new AngleAxis();

	        this._radiusAxis.polar = this._angleAxis.polar = this;
	    };

	    Polar.prototype = {

	        type: 'polar',

	        axisPointerEnabled: true,

	        constructor: Polar,

	        /**
	         * @param {Array.<string>}
	         * @readOnly
	         */
	        dimensions: ['radius', 'angle'],

	        /**
	         * @type {module:echarts/coord/PolarModel}
	         */
	        model: null,

	        /**
	         * If contain coord
	         * @param {Array.<number>} point
	         * @return {boolean}
	         */
	        containPoint: function (point) {
	            var coord = this.pointToCoord(point);
	            return this._radiusAxis.contain(coord[0])
	                && this._angleAxis.contain(coord[1]);
	        },

	        /**
	         * If contain data
	         * @param {Array.<number>} data
	         * @return {boolean}
	         */
	        containData: function (data) {
	            return this._radiusAxis.containData(data[0])
	                && this._angleAxis.containData(data[1]);
	        },

	        /**
	         * @param {string} dim
	         * @return {module:echarts/coord/polar/AngleAxis|module:echarts/coord/polar/RadiusAxis}
	         */
	        getAxis: function (dim) {
	            return this['_' + dim + 'Axis'];
	        },

	        /**
	         * @return {Array.<module:echarts/coord/Axis>}
	         */
	        getAxes: function () {
	            return [this._radiusAxis, this._angleAxis];
	        },

	        /**
	         * Get axes by type of scale
	         * @param {string} scaleType
	         * @return {module:echarts/coord/polar/AngleAxis|module:echarts/coord/polar/RadiusAxis}
	         */
	        getAxesByScale: function (scaleType) {
	            var axes = [];
	            var angleAxis = this._angleAxis;
	            var radiusAxis = this._radiusAxis;
	            angleAxis.scale.type === scaleType && axes.push(angleAxis);
	            radiusAxis.scale.type === scaleType && axes.push(radiusAxis);

	            return axes;
	        },

	        /**
	         * @return {module:echarts/coord/polar/AngleAxis}
	         */
	        getAngleAxis: function () {
	            return this._angleAxis;
	        },

	        /**
	         * @return {module:echarts/coord/polar/RadiusAxis}
	         */
	        getRadiusAxis: function () {
	            return this._radiusAxis;
	        },

	        /**
	         * @param {module:echarts/coord/polar/Axis}
	         * @return {module:echarts/coord/polar/Axis}
	         */
	        getOtherAxis: function (axis) {
	            var angleAxis = this._angleAxis;
	            return axis === angleAxis ? this._radiusAxis : angleAxis;
	        },

	        /**
	         * Base axis will be used on stacking.
	         *
	         * @return {module:echarts/coord/polar/Axis}
	         */
	        getBaseAxis: function () {
	            return this.getAxesByScale('ordinal')[0]
	                || this.getAxesByScale('time')[0]
	                || this.getAngleAxis();
	        },

	        /**
	         * @param {string} [dim] 'radius' or 'angle' or 'auto' or null/undefined
	         * @return {Object} {baseAxes: [], otherAxes: []}
	         */
	        getTooltipAxes: function (dim) {
	            var baseAxis = (dim != null && dim !== 'auto')
	                ? this.getAxis(dim) : this.getBaseAxis();
	            return {
	                baseAxes: [baseAxis],
	                otherAxes: [this.getOtherAxis(baseAxis)]
	            };
	        },

	        /**
	         * Convert series data to a list of (x, y) points
	         * @param {module:echarts/data/List} data
	         * @return {Array}
	         *  Return list of coordinates. For example:
	         *  `[[10, 10], [20, 20], [30, 30]]`
	         */
	        dataToPoints: function (data) {
	            return data.mapArray(this.dimensions, function (radius, angle) {
	                return this.dataToPoint([radius, angle]);
	            }, true, this);
	        },

	        /**
	         * Convert a single data item to (x, y) point.
	         * Parameter data is an array which the first element is radius and the second is angle
	         * @param {Array.<number>} data
	         * @param {boolean} [clamp=false]
	         * @return {Array.<number>}
	         */
	        dataToPoint: function (data, clamp) {
	            return this.coordToPoint([
	                this._radiusAxis.dataToRadius(data[0], clamp),
	                this._angleAxis.dataToAngle(data[1], clamp)
	            ]);
	        },

	        /**
	         * Convert a (x, y) point to data
	         * @param {Array.<number>} point
	         * @param {boolean} [clamp=false]
	         * @return {Array.<number>}
	         */
	        pointToData: function (point, clamp) {
	            var coord = this.pointToCoord(point);
	            return [
	                this._radiusAxis.radiusToData(coord[0], clamp),
	                this._angleAxis.angleToData(coord[1], clamp)
	            ];
	        },

	        /**
	         * Convert a (x, y) point to (radius, angle) coord
	         * @param {Array.<number>} point
	         * @return {Array.<number>}
	         */
	        pointToCoord: function (point) {
	            var dx = point[0] - this.cx;
	            var dy = point[1] - this.cy;
	            var angleAxis = this.getAngleAxis();
	            var extent = angleAxis.getExtent();
	            var minAngle = Math.min(extent[0], extent[1]);
	            var maxAngle = Math.max(extent[0], extent[1]);
	            // Fix fixed extent in polarCreator
	            // FIXME
	            angleAxis.inverse
	                ? (minAngle = maxAngle - 360)
	                : (maxAngle = minAngle + 360);

	            var radius = Math.sqrt(dx * dx + dy * dy);
	            dx /= radius;
	            dy /= radius;

	            var radian = Math.atan2(-dy, dx) / Math.PI * 180;

	            // move to angleExtent
	            var dir = radian < minAngle ? 1 : -1;
	            while (radian < minAngle || radian > maxAngle) {
	                radian += dir * 360;
	            }

	            return [radius, radian];
	        },

	        /**
	         * Convert a (radius, angle) coord to (x, y) point
	         * @param {Array.<number>} coord
	         * @return {Array.<number>}
	         */
	        coordToPoint: function (coord) {
	            var radius = coord[0];
	            var radian = coord[1] / 180 * Math.PI;
	            var x = Math.cos(radian) * radius + this.cx;
	            // Inverse the y
	            var y = -Math.sin(radian) * radius + this.cy;

	            return [x, y];
	        }

	    };

	    module.exports = Polar;


/***/ },
/* 334 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var zrUtil = __webpack_require__(4);
	    var Axis = __webpack_require__(100);

	    function RadiusAxis(scale, radiusExtent) {

	        Axis.call(this, 'radius', scale, radiusExtent);

	        /**
	         * Axis type
	         *  - 'category'
	         *  - 'value'
	         *  - 'time'
	         *  - 'log'
	         * @type {string}
	         */
	        this.type = 'category';
	    }

	    RadiusAxis.prototype = {

	        constructor: RadiusAxis,

	        /**
	         * @override
	         */
	        pointToData: function (point, clamp) {
	            return this.polar.pointToData(point, clamp)[this.dim === 'radius' ? 0 : 1];
	        },

	        dataToRadius: Axis.prototype.dataToCoord,

	        radiusToData: Axis.prototype.coordToData
	    };

	    zrUtil.inherits(RadiusAxis, Axis);

	    module.exports = RadiusAxis;


/***/ },
/* 335 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var zrUtil = __webpack_require__(4);
	    var Axis = __webpack_require__(100);

	    function AngleAxis(scale, angleExtent) {

	        angleExtent = angleExtent || [0, 360];

	        Axis.call(this, 'angle', scale, angleExtent);

	        /**
	         * Axis type
	         *  - 'category'
	         *  - 'value'
	         *  - 'time'
	         *  - 'log'
	         * @type {string}
	         */
	        this.type = 'category';
	    }

	    AngleAxis.prototype = {

	        constructor: AngleAxis,

	        /**
	         * @override
	         */
	        pointToData: function (point, clamp) {
	            return this.polar.pointToData(point, clamp)[this.dim === 'radius' ? 0 : 1];
	        },

	        dataToAngle: Axis.prototype.dataToCoord,

	        angleToData: Axis.prototype.coordToData
	    };

	    zrUtil.inherits(AngleAxis, Axis);

	    module.exports = AngleAxis;


/***/ },
/* 336 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    __webpack_require__(337);

	    __webpack_require__(1).extendComponentModel({

	        type: 'polar',

	        dependencies: ['polarAxis', 'angleAxis'],

	        /**
	         * @type {module:echarts/coord/polar/Polar}
	         */
	        coordinateSystem: null,

	        /**
	         * @param {string} axisType
	         * @return {module:echarts/coord/polar/AxisModel}
	         */
	        findAxisModel: function (axisType) {
	            var foundAxisModel;
	            var ecModel = this.ecModel;

	            ecModel.eachComponent(axisType, function (axisModel) {
	                if (axisModel.getCoordSysModel() === this) {
	                    foundAxisModel = axisModel;
	                }
	            }, this);
	            return foundAxisModel;
	        },

	        defaultOption: {

	            zlevel: 0,

	            z: 0,

	            center: ['50%', '50%'],

	            radius: '80%'
	        }
	    });


/***/ },
/* 337 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var zrUtil = __webpack_require__(4);
	    var ComponentModel = __webpack_require__(69);
	    var axisModelCreator = __webpack_require__(131);

	    var PolarAxisModel = ComponentModel.extend({

	        type: 'polarAxis',

	        /**
	         * @type {module:echarts/coord/polar/AngleAxis|module:echarts/coord/polar/RadiusAxis}
	         */
	        axis: null,

	        /**
	         * @override
	         */
	        getCoordSysModel: function () {
	            return this.ecModel.queryComponents({
	                mainType: 'polar',
	                index: this.option.polarIndex,
	                id: this.option.polarId
	            })[0];
	        }

	    });

	    zrUtil.merge(PolarAxisModel.prototype, __webpack_require__(112));

	    var polarAxisDefaultExtendedOption = {
	        angle: {
	            // polarIndex: 0,
	            // polarId: '',

	            startAngle: 90,

	            clockwise: true,

	            splitNumber: 12,

	            axisLabel: {
	                rotate: false
	            }
	        },
	        radius: {
	            // polarIndex: 0,
	            // polarId: '',

	            splitNumber: 5
	        }
	    };

	    function getAxisType(axisDim, option) {
	        // Default axis with data is category axis
	        return option.type || (option.data ? 'category' : 'value');
	    }

	    axisModelCreator('angle', PolarAxisModel, getAxisType, polarAxisDefaultExtendedOption.angle);
	    axisModelCreator('radius', PolarAxisModel, getAxisType, polarAxisDefaultExtendedOption.radius);



/***/ },
/* 338 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    __webpack_require__(332);

	    __webpack_require__(339);


/***/ },
/* 339 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var zrUtil = __webpack_require__(4);
	    var graphic = __webpack_require__(18);
	    var Model = __webpack_require__(12);

	    var elementList = ['axisLine', 'axisLabel', 'axisTick', 'splitLine', 'splitArea'];

	    function getAxisLineShape(polar, r0, r, angle) {
	        var start = polar.coordToPoint([r0, angle]);
	        var end = polar.coordToPoint([r, angle]);

	        return {
	            x1: start[0],
	            y1: start[1],
	            x2: end[0],
	            y2: end[1]
	        };
	    }

	    __webpack_require__(136).extend({

	        type: 'angleAxis',

	        axisPointerClass: 'PolarAxisPointer',

	        render: function (angleAxisModel, ecModel) {
	            this.group.removeAll();
	            if (!angleAxisModel.get('show')) {
	                return;
	            }

	            var angleAxis = angleAxisModel.axis;
	            var polar = angleAxis.polar;
	            var radiusExtent = polar.getRadiusAxis().getExtent();
	            var ticksAngles = angleAxis.getTicksCoords();

	            if (angleAxis.type !== 'category') {
	                // Remove the last tick which will overlap the first tick
	                ticksAngles.pop();
	            }

	            zrUtil.each(elementList, function (name) {
	                if (angleAxisModel.get(name +'.show')
	                    && (!angleAxis.scale.isBlank() || name === 'axisLine')
	                ) {
	                    this['_' + name](angleAxisModel, polar, ticksAngles, radiusExtent);
	                }
	            }, this);
	        },

	        /**
	         * @private
	         */
	        _axisLine: function (angleAxisModel, polar, ticksAngles, radiusExtent) {
	            var lineStyleModel = angleAxisModel.getModel('axisLine.lineStyle');

	            var circle = new graphic.Circle({
	                shape: {
	                    cx: polar.cx,
	                    cy: polar.cy,
	                    r: radiusExtent[1]
	                },
	                style: lineStyleModel.getLineStyle(),
	                z2: 1,
	                silent: true
	            });
	            circle.style.fill = null;

	            this.group.add(circle);
	        },

	        /**
	         * @private
	         */
	        _axisTick: function (angleAxisModel, polar, ticksAngles, radiusExtent) {
	            var tickModel = angleAxisModel.getModel('axisTick');

	            var tickLen = (tickModel.get('inside') ? -1 : 1) * tickModel.get('length');

	            var lines = zrUtil.map(ticksAngles, function (tickAngle) {
	                return new graphic.Line({
	                    shape: getAxisLineShape(polar, radiusExtent[1], radiusExtent[1] + tickLen, tickAngle)
	                });
	            });
	            this.group.add(graphic.mergePath(
	                lines, {
	                    style: zrUtil.defaults(
	                        tickModel.getModel('lineStyle').getLineStyle(),
	                        {
	                            stroke: angleAxisModel.get('axisLine.lineStyle.color')
	                        }
	                    )
	                }
	            ));
	        },

	        /**
	         * @private
	         */
	        _axisLabel: function (angleAxisModel, polar, ticksAngles, radiusExtent) {
	            var axis = angleAxisModel.axis;

	            var categoryData = angleAxisModel.get('data');

	            var labelModel = angleAxisModel.getModel('axisLabel');
	            var axisTextStyleModel = labelModel.getModel('textStyle');

	            var labels = angleAxisModel.getFormattedLabels();

	            var labelMargin = labelModel.get('margin');
	            var labelsAngles = axis.getLabelsCoords();

	            // Use length of ticksAngles because it may remove the last tick to avoid overlapping
	            for (var i = 0; i < ticksAngles.length; i++) {
	                var r = radiusExtent[1];
	                var p = polar.coordToPoint([r + labelMargin, labelsAngles[i]]);
	                var cx = polar.cx;
	                var cy = polar.cy;

	                var labelTextAlign = Math.abs(p[0] - cx) / r < 0.3
	                    ? 'center' : (p[0] > cx ? 'left' : 'right');
	                var labelTextBaseline = Math.abs(p[1] - cy) / r < 0.3
	                    ? 'middle' : (p[1] > cy ? 'top' : 'bottom');

	                var textStyleModel = axisTextStyleModel;
	                if (categoryData && categoryData[i] && categoryData[i].textStyle) {
	                    textStyleModel = new Model(
	                        categoryData[i].textStyle, axisTextStyleModel
	                    );
	                }
	                this.group.add(new graphic.Text({
	                    style: {
	                        x: p[0],
	                        y: p[1],
	                        fill: textStyleModel.getTextColor() || angleAxisModel.get('axisLine.lineStyle.color'),
	                        text: labels[i],
	                        textAlign: labelTextAlign,
	                        textVerticalAlign: labelTextBaseline,
	                        textFont: textStyleModel.getFont()
	                    },
	                    silent: true
	                }));
	            }
	        },

	        /**
	         * @private
	         */
	        _splitLine: function (angleAxisModel, polar, ticksAngles, radiusExtent) {
	            var splitLineModel = angleAxisModel.getModel('splitLine');
	            var lineStyleModel = splitLineModel.getModel('lineStyle');
	            var lineColors = lineStyleModel.get('color');
	            var lineCount = 0;

	            lineColors = lineColors instanceof Array ? lineColors : [lineColors];

	            var splitLines = [];

	            for (var i = 0; i < ticksAngles.length; i++) {
	                var colorIndex = (lineCount++) % lineColors.length;
	                splitLines[colorIndex] = splitLines[colorIndex] || [];
	                splitLines[colorIndex].push(new graphic.Line({
	                    shape: getAxisLineShape(polar, radiusExtent[0], radiusExtent[1], ticksAngles[i])
	                }));
	            }

	            // Simple optimization
	            // Batching the lines if color are the same
	            for (var i = 0; i < splitLines.length; i++) {
	                this.group.add(graphic.mergePath(splitLines[i], {
	                    style: zrUtil.defaults({
	                        stroke: lineColors[i % lineColors.length]
	                    }, lineStyleModel.getLineStyle()),
	                    silent: true,
	                    z: angleAxisModel.get('z')
	                }));
	            }
	        },

	        /**
	         * @private
	         */
	        _splitArea: function (angleAxisModel, polar, ticksAngles, radiusExtent) {

	            var splitAreaModel = angleAxisModel.getModel('splitArea');
	            var areaStyleModel = splitAreaModel.getModel('areaStyle');
	            var areaColors = areaStyleModel.get('color');
	            var lineCount = 0;

	            areaColors = areaColors instanceof Array ? areaColors : [areaColors];

	            var splitAreas = [];

	            var RADIAN = Math.PI / 180;
	            var prevAngle = -ticksAngles[0] * RADIAN;
	            var r0 = Math.min(radiusExtent[0], radiusExtent[1]);
	            var r1 = Math.max(radiusExtent[0], radiusExtent[1]);

	            var clockwise = angleAxisModel.get('clockwise');

	            for (var i = 1; i < ticksAngles.length; i++) {
	                var colorIndex = (lineCount++) % areaColors.length;
	                splitAreas[colorIndex] = splitAreas[colorIndex] || [];
	                splitAreas[colorIndex].push(new graphic.Sector({
	                    shape: {
	                        cx: polar.cx,
	                        cy: polar.cy,
	                        r0: r0,
	                        r: r1,
	                        startAngle: prevAngle,
	                        endAngle: -ticksAngles[i] * RADIAN,
	                        clockwise: clockwise
	                    },
	                    silent: true
	                }));
	                prevAngle = -ticksAngles[i] * RADIAN;
	            }

	            // Simple optimization
	            // Batching the lines if color are the same
	            for (var i = 0; i < splitAreas.length; i++) {
	                this.group.add(graphic.mergePath(splitAreas[i], {
	                    style: zrUtil.defaults({
	                        fill: areaColors[i % areaColors.length]
	                    }, areaStyleModel.getAreaStyle()),
	                    silent: true
	                }));
	            }
	        }
	    });


/***/ },
/* 340 */
/***/ function(module, exports, __webpack_require__) {

	

	    __webpack_require__(332);

	    __webpack_require__(341);


/***/ },
/* 341 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var zrUtil = __webpack_require__(4);
	    var graphic = __webpack_require__(18);
	    var AxisBuilder = __webpack_require__(135);

	    var axisBuilderAttrs = [
	        'axisLine', 'axisLabel', 'axisTick', 'axisName'
	    ];
	    var selfBuilderAttrs = [
	        'splitLine', 'splitArea'
	    ];

	    __webpack_require__(136).extend({

	        type: 'radiusAxis',

	        axisPointerClass: 'PolarAxisPointer',

	        render: function (radiusAxisModel, ecModel) {
	            this.group.removeAll();
	            if (!radiusAxisModel.get('show')) {
	                return;
	            }
	            var radiusAxis = radiusAxisModel.axis;
	            var polar = radiusAxis.polar;
	            var angleAxis = polar.getAngleAxis();
	            var ticksCoords = radiusAxis.getTicksCoords();
	            var axisAngle = angleAxis.getExtent()[0];
	            var radiusExtent = radiusAxis.getExtent();

	            var layout = layoutAxis(polar, radiusAxisModel, axisAngle);
	            var axisBuilder = new AxisBuilder(radiusAxisModel, layout);
	            zrUtil.each(axisBuilderAttrs, axisBuilder.add, axisBuilder);
	            this.group.add(axisBuilder.getGroup());

	            zrUtil.each(selfBuilderAttrs, function (name) {
	                if (radiusAxisModel.get(name +'.show') && !radiusAxis.scale.isBlank()) {
	                    this['_' + name](radiusAxisModel, polar, axisAngle, radiusExtent, ticksCoords);
	                }
	            }, this);
	        },

	        /**
	         * @private
	         */
	        _splitLine: function (radiusAxisModel, polar, axisAngle, radiusExtent, ticksCoords) {
	            var splitLineModel = radiusAxisModel.getModel('splitLine');
	            var lineStyleModel = splitLineModel.getModel('lineStyle');
	            var lineColors = lineStyleModel.get('color');
	            var lineCount = 0;

	            lineColors = lineColors instanceof Array ? lineColors : [lineColors];

	            var splitLines = [];

	            for (var i = 0; i < ticksCoords.length; i++) {
	                var colorIndex = (lineCount++) % lineColors.length;
	                splitLines[colorIndex] = splitLines[colorIndex] || [];
	                splitLines[colorIndex].push(new graphic.Circle({
	                    shape: {
	                        cx: polar.cx,
	                        cy: polar.cy,
	                        r: ticksCoords[i]
	                    },
	                    silent: true
	                }));
	            }

	            // Simple optimization
	            // Batching the lines if color are the same
	            for (var i = 0; i < splitLines.length; i++) {
	                this.group.add(graphic.mergePath(splitLines[i], {
	                    style: zrUtil.defaults({
	                        stroke: lineColors[i % lineColors.length],
	                        fill: null
	                    }, lineStyleModel.getLineStyle()),
	                    silent: true
	                }));
	            }
	        },

	        /**
	         * @private
	         */
	        _splitArea: function (radiusAxisModel, polar, axisAngle, radiusExtent, ticksCoords) {

	            var splitAreaModel = radiusAxisModel.getModel('splitArea');
	            var areaStyleModel = splitAreaModel.getModel('areaStyle');
	            var areaColors = areaStyleModel.get('color');
	            var lineCount = 0;

	            areaColors = areaColors instanceof Array ? areaColors : [areaColors];

	            var splitAreas = [];

	            var prevRadius = ticksCoords[0];
	            for (var i = 1; i < ticksCoords.length; i++) {
	                var colorIndex = (lineCount++) % areaColors.length;
	                splitAreas[colorIndex] = splitAreas[colorIndex] || [];
	                splitAreas[colorIndex].push(new graphic.Sector({
	                    shape: {
	                        cx: polar.cx,
	                        cy: polar.cy,
	                        r0: prevRadius,
	                        r: ticksCoords[i],
	                        startAngle: 0,
	                        endAngle: Math.PI * 2
	                    },
	                    silent: true
	                }));
	                prevRadius = ticksCoords[i];
	            }

	            // Simple optimization
	            // Batching the lines if color are the same
	            for (var i = 0; i < splitAreas.length; i++) {
	                this.group.add(graphic.mergePath(splitAreas[i], {
	                    style: zrUtil.defaults({
	                        fill: areaColors[i % areaColors.length]
	                    }, areaStyleModel.getAreaStyle()),
	                    silent: true
	                }));
	            }
	        }
	    });

	    /**
	     * @inner
	     */
	    function layoutAxis(polar, radiusAxisModel, axisAngle) {
	        return {
	            position: [polar.cx, polar.cy],
	            rotation: axisAngle / 180 * Math.PI,
	            labelDirection: -1,
	            tickDirection: -1,
	            nameDirection: 1,
	            labelRotate: radiusAxisModel.getModel('axisLabel').get('rotate'),
	            // Over splitLine and splitArea
	            z2: 1
	        };
	    }


/***/ },
/* 342 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var formatUtil = __webpack_require__(6);
	    var BaseAxisPointer = __webpack_require__(305);
	    var graphic = __webpack_require__(18);
	    var viewHelper = __webpack_require__(306);
	    var matrix = __webpack_require__(11);
	    var AxisBuilder = __webpack_require__(135);
	    var AxisView = __webpack_require__(136);

	    var PolarAxisPointer = BaseAxisPointer.extend({

	        /**
	         * @override
	         */
	        makeElOption: function (elOption, value, axisModel, axisPointerModel, api) {
	            var axis = axisModel.axis;

	            if (axis.dim === 'angle') {
	                this.animationThreshold = Math.PI / 18;
	            }

	            var polar = axis.polar;
	            var otherAxis = polar.getOtherAxis(axis);
	            var otherExtent = otherAxis.getExtent();

	            var coordValue;
	            coordValue = axis['dataTo' + formatUtil.capitalFirst(axis.dim)](value);

	            var axisPointerType = axisPointerModel.get('type');
	            if (axisPointerType && axisPointerType !== 'none') {
	                var elStyle = viewHelper.buildElStyle(axisPointerModel);
	                var pointerOption = pointerShapeBuilder[axisPointerType](
	                    axis, polar, coordValue, otherExtent, elStyle
	                );
	                pointerOption.style = elStyle;
	                elOption.graphicKey = pointerOption.type;
	                elOption.pointer = pointerOption;
	            }

	            var labelMargin = axisPointerModel.get('label.margin');
	            var labelPos = getLabelPosition(value, axisModel, axisPointerModel, polar, labelMargin);
	            viewHelper.buildLabelElOption(elOption, axisModel, axisPointerModel, api, labelPos);
	        }

	        // Do not support handle, utill any user requires it.

	    });

	    function getLabelPosition(value, axisModel, axisPointerModel, polar, labelMargin) {
	        var axis = axisModel.axis;
	        var coord = axis.dataToCoord(value);
	        var axisAngle = polar.getAngleAxis().getExtent()[0];
	        axisAngle = axisAngle / 180 * Math.PI;
	        var radiusExtent = polar.getRadiusAxis().getExtent();
	        var position;
	        var align;
	        var verticalAlign;

	        if (axis.dim === 'radius') {
	            var transform = matrix.create();
	            matrix.rotate(transform, transform, axisAngle);
	            matrix.translate(transform, transform, [polar.cx, polar.cy]);
	            position = graphic.applyTransform([coord, -labelMargin], transform);

	            var labelRotation = axisModel.getModel('axisLabel').get('rotate') || 0;
	            var labelLayout = AxisBuilder.innerTextLayout(
	                axisAngle, labelRotation * Math.PI / 180, -1
	            );
	            align = labelLayout.textAlign;
	            verticalAlign = labelLayout.textVerticalAlign;
	        }
	        else { // angle axis
	            var r = radiusExtent[1];
	            position = polar.coordToPoint([r + labelMargin, coord]);
	            var cx = polar.cx;
	            var cy = polar.cy;
	            align = Math.abs(position[0] - cx) / r < 0.3
	                ? 'center' : (position[0] > cx ? 'left' : 'right');
	            verticalAlign = Math.abs(position[1] - cy) / r < 0.3
	                ? 'middle' : (position[1] > cy ? 'top' : 'bottom');
	        }

	        return {
	            position: position,
	            align: align,
	            verticalAlign: verticalAlign
	        };
	    }


	    var pointerShapeBuilder = {

	        line: function (axis, polar, coordValue, otherExtent, elStyle) {
	            return axis.dim === 'angle'
	                ? {
	                    type: 'Line',
	                    shape: viewHelper.makeLineShape(
	                        polar.coordToPoint([otherExtent[0], coordValue]),
	                        polar.coordToPoint([otherExtent[1], coordValue])
	                    )
	                }
	                : {
	                    type: 'Circle',
	                    shape: {
	                        cx: polar.cx,
	                        cy: polar.cy,
	                        r: coordValue
	                    }
	                };
	        },

	        shadow: function (axis, polar, coordValue, otherExtent, elStyle) {
	            var bandWidth = axis.getBandWidth();
	            var radian = Math.PI / 180;

	            return axis.dim === 'angle'
	                ? {
	                    type: 'Sector',
	                    shape: viewHelper.makeSectorShape(
	                        polar.cx, polar.cy,
	                        otherExtent[0], otherExtent[1],
	                        // In ECharts y is negative if angle is positive
	                        (-coordValue - bandWidth / 2) * radian,
	                        (-coordValue + bandWidth / 2) * radian
	                    )
	                }
	                : {
	                    type: 'Sector',
	                    shape: viewHelper.makeSectorShape(
	                        polar.cx, polar.cy,
	                        coordValue - bandWidth / 2,
	                        coordValue + bandWidth / 2,
	                        0, Math.PI * 2
	                    )
	                };
	        }
	    };

	    AxisView.registerAxisPointerClass('PolarAxisPointer', PolarAxisPointer);

	    module.exports = PolarAxisPointer;


/***/ },
/* 343 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var zrUtil = __webpack_require__(4);
	    var parsePercent = __webpack_require__(7).parsePercent;

	    function getSeriesStackId(seriesModel) {
	        return seriesModel.get('stack')
	            || '__ec_stack_' + seriesModel.seriesIndex;
	    }

	    function getAxisKey(axis) {
	        return axis.dim;
	    }

	    /**
	     * @param {string} seriesType
	     * @param {module:echarts/model/Global} ecModel
	     * @param {module:echarts/ExtensionAPI} api
	     */
	    function barLayoutPolar(seriesType, ecModel, api) {

	        var width = api.getWidth();
	        var height = api.getHeight();

	        var lastStackCoords = {};
	        var lastStackCoordsOrigin = {};

	        var barWidthAndOffset = calRadialBar(
	            zrUtil.filter(
	                ecModel.getSeriesByType(seriesType),
	                function (seriesModel) {
	                    return !ecModel.isSeriesFiltered(seriesModel)
	                        && seriesModel.coordinateSystem
	                        && seriesModel.coordinateSystem.type === 'polar';
	                }
	            )
	        );

	        ecModel.eachSeriesByType(seriesType, function (seriesModel) {
	            // Check series coordinate, do layout for polar only
	            if (seriesModel.coordinateSystem.type !== 'polar') {
	                return;
	            }

	            var data = seriesModel.getData();
	            var polar = seriesModel.coordinateSystem;
	            var angleAxis = polar.getAngleAxis();
	            var baseAxis = polar.getBaseAxis();

	            var stackId = getSeriesStackId(seriesModel);
	            var columnLayoutInfo
	                = barWidthAndOffset[getAxisKey(baseAxis)][stackId];
	            var columnOffset = columnLayoutInfo.offset;
	            var columnWidth = columnLayoutInfo.width;
	            var valueAxis = polar.getOtherAxis(baseAxis);

	            var center = seriesModel.get('center') || ['50%', '50%'];
	            var cx = parsePercent(center[0], width);
	            var cy = parsePercent(center[1], height);

	            var barMinHeight = seriesModel.get('barMinHeight') || 0;
	            var barMinAngle = seriesModel.get('barMinAngle') || 0;

	            var valueAxisStart = valueAxis.getExtent()[0];
	            var valueMax = valueAxis.model.get('max');
	            var valueMin = valueAxis.model.get('min');

	            var coords = polar.dataToPoints(data);
	            lastStackCoords[stackId] = lastStackCoords[stackId] || [];
	            lastStackCoordsOrigin[stackId] = lastStackCoordsOrigin[stackId] || []; // Fix #4243

	            data.each(valueAxis.dim, function (value, idx) {
	                if (isNaN(value)) {
	                    return;
	                }

	                if (!lastStackCoords[stackId][idx]) {
	                    lastStackCoords[stackId][idx] = {
	                        p: valueAxisStart, // Positive stack
	                        n: valueAxisStart  // Negative stack
	                    };
	                    lastStackCoordsOrigin[stackId][idx] = {
	                        p: valueAxisStart, // Positive stack
	                        n: valueAxisStart  // Negative stack
	                    };
	                }
	                var sign = value >= 0 ? 'p' : 'n';
	                var coord = polar.pointToCoord(coords[idx]);

	                var lastCoordOrigin = lastStackCoordsOrigin[stackId][idx][sign];
	                var r0;
	                var r;
	                var startAngle;
	                var endAngle;

	                if (valueAxis.dim === 'radius') {
	                    // radial sector
	                    r0 = lastCoordOrigin;
	                    r = coord[0];
	                    startAngle = (-coord[1] + columnOffset) * Math.PI / 180;
	                    endAngle = startAngle + columnWidth * Math.PI / 180;

	                    if (Math.abs(r) < barMinHeight) {
	                        r = r0 + (r < 0 ? -1 : 1) * barMinHeight;
	                    }

	                    lastStackCoordsOrigin[stackId][idx][sign] = r;
	                }
	                else {
	                    // tangential sector
	                    r0 = coord[0] + columnOffset;
	                    r = r0 + columnWidth;

	                    // clamp data if min or max is defined for valueAxis
	                    if (valueMax != null) {
	                        value = Math.min(value, valueMax);
	                    }
	                    if (valueMin != null) {
	                        value = Math.max(value, valueMin);
	                    }

	                    var angle = angleAxis.dataToAngle(value);
	                    if (Math.abs(angle - lastCoordOrigin) < barMinAngle) {
	                        angle = lastCoordOrigin - (value < 0 ? -1 : 1)
	                            * barMinAngle;
	                    }

	                    startAngle = -lastCoordOrigin * Math.PI / 180;
	                    endAngle = -angle * Math.PI / 180;

	                    // if the previous stack is at the end of the ring,
	                    // add a round to differentiate it from origin
	                    var extent = angleAxis.getExtent();
	                    var stackCoord = angle;
	                    if (stackCoord === extent[0] && value > 0) {
	                        stackCoord = extent[1];
	                    }
	                    else if (stackCoord === extent[1] && value < 0) {
	                        stackCoord = extent[0];
	                    }
	                    lastStackCoordsOrigin[stackId][idx][sign] = stackCoord;
	                }

	                data.setItemLayout(idx, {
	                    cx: cx,
	                    cy: cy,
	                    r0: r0,
	                    r: r,
	                    startAngle: startAngle,
	                    endAngle: endAngle
	                });

	            }, true);

	        }, this);

	    }

	    /**
	     * Calculate bar width and offset for radial bar charts
	     */
	    function calRadialBar(barSeries, api) {
	        // Columns info on each category axis. Key is polar name
	        var columnsMap = {};

	        zrUtil.each(barSeries, function (seriesModel, idx) {
	            var data = seriesModel.getData();
	            var polar = seriesModel.coordinateSystem;

	            var baseAxis = polar.getBaseAxis();

	            var axisExtent = baseAxis.getExtent();
	            var bandWidth = baseAxis.type === 'category'
	                ? baseAxis.getBandWidth()
	                : (Math.abs(axisExtent[1] - axisExtent[0]) / data.count());

	            var columnsOnAxis = columnsMap[getAxisKey(baseAxis)] || {
	                bandWidth: bandWidth,
	                remainedWidth: bandWidth,
	                autoWidthCount: 0,
	                categoryGap: '20%',
	                gap: '30%',
	                stacks: {}
	            };
	            var stacks = columnsOnAxis.stacks;
	            columnsMap[getAxisKey(baseAxis)] = columnsOnAxis;

	            var stackId = getSeriesStackId(seriesModel);

	            if (!stacks[stackId]) {
	                columnsOnAxis.autoWidthCount++;
	            }
	            stacks[stackId] = stacks[stackId] || {
	                width: 0,
	                maxWidth: 0
	            };

	            var barWidth = parsePercent(
	                seriesModel.get('barWidth'),
	                bandWidth
	            );
	            var barMaxWidth = parsePercent(
	                seriesModel.get('barMaxWidth'),
	                bandWidth
	            );
	            var barGap = seriesModel.get('barGap');
	            var barCategoryGap = seriesModel.get('barCategoryGap');

	            if (barWidth && !stacks[stackId].width) {
	                barWidth = Math.min(columnsOnAxis.remainedWidth, barWidth);
	                stacks[stackId].width = barWidth;
	                columnsOnAxis.remainedWidth -= barWidth;
	            }

	            barMaxWidth && (stacks[stackId].maxWidth = barMaxWidth);
	            (barGap != null) && (columnsOnAxis.gap = barGap);
	            (barCategoryGap != null) && (columnsOnAxis.categoryGap = barCategoryGap);
	        });


	        var result = {};

	        zrUtil.each(columnsMap, function (columnsOnAxis, coordSysName) {

	            result[coordSysName] = {};

	            var stacks = columnsOnAxis.stacks;
	            var bandWidth = columnsOnAxis.bandWidth;
	            var categoryGap = parsePercent(columnsOnAxis.categoryGap, bandWidth);
	            var barGapPercent = parsePercent(columnsOnAxis.gap, 1);

	            var remainedWidth = columnsOnAxis.remainedWidth;
	            var autoWidthCount = columnsOnAxis.autoWidthCount;
	            var autoWidth = (remainedWidth - categoryGap)
	                / (autoWidthCount + (autoWidthCount - 1) * barGapPercent);
	            autoWidth = Math.max(autoWidth, 0);

	            // Find if any auto calculated bar exceeded maxBarWidth
	            zrUtil.each(stacks, function (column, stack) {
	                var maxWidth = column.maxWidth;
	                if (maxWidth && maxWidth < autoWidth) {
	                    maxWidth = Math.min(maxWidth, remainedWidth);
	                    if (column.width) {
	                        maxWidth = Math.min(maxWidth, column.width);
	                    }
	                    remainedWidth -= maxWidth;
	                    column.width = maxWidth;
	                    autoWidthCount--;
	                }
	            });

	            // Recalculate width again
	            autoWidth = (remainedWidth - categoryGap)
	                / (autoWidthCount + (autoWidthCount - 1) * barGapPercent);
	            autoWidth = Math.max(autoWidth, 0);

	            var widthSum = 0;
	            var lastColumn;
	            zrUtil.each(stacks, function (column, idx) {
	                if (!column.width) {
	                    column.width = autoWidth;
	                }
	                lastColumn = column;
	                widthSum += column.width * (1 + barGapPercent);
	            });
	            if (lastColumn) {
	                widthSum -= lastColumn.width * barGapPercent;
	            }

	            var offset = -widthSum / 2;
	            zrUtil.each(stacks, function (column, stackId) {
	                result[coordSysName][stackId] = result[coordSysName][stackId] || {
	                    offset: offset,
	                    width: column.width
	                };

	                offset += column.width * (1 + barGapPercent);
	            });
	        });

	        return result;
	    }

	    module.exports = barLayoutPolar;



/***/ },
/* 344 */
/***/ function(module, exports, __webpack_require__) {

	

	    __webpack_require__(345);

	    __webpack_require__(171);

	    __webpack_require__(346);

	    __webpack_require__(187);

	    var echarts = __webpack_require__(1);
	    var zrUtil = __webpack_require__(4);

	    function makeAction(method, actionInfo) {
	        actionInfo.update = 'updateView';
	        echarts.registerAction(actionInfo, function (payload, ecModel) {
	            var selected = {};

	            ecModel.eachComponent(
	                { mainType: 'geo', query: payload},
	                function (geoModel) {
	                    geoModel[method](payload.name);
	                    var geo = geoModel.coordinateSystem;
	                    zrUtil.each(geo.regions, function (region) {
	                        selected[region.name] = geoModel.isSelected(region.name) || false;
	                    });
	                }
	            );

	            return {
	                selected: selected,
	                name: payload.name
	            };
	        });
	    }

	    makeAction('toggleSelected', {
	        type: 'geoToggleSelect',
	        event: 'geoselectchanged'
	    });
	    makeAction('select', {
	        type: 'geoSelect',
	        event: 'geoselected'
	    });
	    makeAction('unSelect', {
	        type: 'geoUnSelect',
	        event: 'geounselected'
	    });


/***/ },
/* 345 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';

	    var modelUtil = __webpack_require__(5);
	    var ComponentModel = __webpack_require__(69);
	    var Model = __webpack_require__(12);
	    var zrUtil = __webpack_require__(4);

	    var selectableMixin = __webpack_require__(148);

	    var geoCreator = __webpack_require__(171);

	    var GeoModel = ComponentModel.extend({

	        type: 'geo',

	        /**
	         * @type {module:echarts/coord/geo/Geo}
	         */
	        coordinateSystem: null,

	        layoutMode: 'box',

	        init: function (option) {
	            ComponentModel.prototype.init.apply(this, arguments);

	            // Default label emphasis `position` and `show`
	            modelUtil.defaultEmphasis(
	                option.label, ['position', 'show', 'textStyle', 'distance', 'formatter']
	            );
	        },

	        optionUpdated: function () {
	            var option = this.option;
	            var self = this;

	            option.regions = geoCreator.getFilledRegions(option.regions, option.map);

	            this._optionModelMap = zrUtil.reduce(option.regions || [], function (optionModelMap, regionOpt) {
	                if (regionOpt.name) {
	                    optionModelMap.set(regionOpt.name, new Model(regionOpt, self));
	                }
	                return optionModelMap;
	            }, zrUtil.createHashMap());

	            this.updateSelectedMap(option.regions);
	        },

	        defaultOption: {

	            zlevel: 0,

	            z: 0,

	            show: true,

	            left: 'center',

	            top: 'center',


	            // width:,
	            // height:,
	            // right
	            // bottom

	            // Aspect is width / height. Inited to be geoJson bbox aspect
	            // This parameter is used for scale this aspect
	            aspectScale: 0.75,

	            ///// Layout with center and size
	            // If you wan't to put map in a fixed size box with right aspect ratio
	            // This two properties may more conveninet
	            // layoutCenter: [50%, 50%]
	            // layoutSize: 100


	            silent: false,

	            // Map type
	            map: '',

	            // Define left-top, right-bottom coords to control view
	            // For example, [ [180, 90], [-180, -90] ]
	            boundingCoords: null,

	            // Default on center of map
	            center: null,

	            zoom: 1,

	            scaleLimit: null,

	            // selectedMode: false

	            label: {
	                normal: {
	                    show: false,
	                    textStyle: {
	                        color: '#000'
	                    }
	                },
	                emphasis: {
	                    show: true,
	                    textStyle: {
	                        color: 'rgb(100,0,0)'
	                    }
	                }
	            },

	            itemStyle: {
	                normal: {
	                    // color: 各异,
	                    borderWidth: 0.5,
	                    borderColor: '#444',
	                    color: '#eee'
	                },
	                emphasis: {                 // 也是选中样式
	                    color: 'rgba(255,215,0,0.8)'
	                }
	            },

	            regions: []
	        },

	        /**
	         * Get model of region
	         * @param  {string} name
	         * @return {module:echarts/model/Model}
	         */
	        getRegionModel: function (name) {
	            return this._optionModelMap.get(name) || new Model(null, this, this.ecModel);
	        },

	        /**
	         * Format label
	         * @param {string} name Region name
	         * @param {string} [status='normal'] 'normal' or 'emphasis'
	         * @return {string}
	         */
	        getFormattedLabel: function (name, status) {
	            var regionModel = this.getRegionModel(name);
	            var formatter = regionModel.get('label.' + status + '.formatter');
	            var params = {
	                name: name
	            };
	            if (typeof formatter === 'function') {
	                params.status = status;
	                return formatter(params);
	            }
	            else if (typeof formatter === 'string') {
	                var serName = params.seriesName;
	                return formatter.replace('{a}', serName != null ? serName : '');
	            }
	        },

	        setZoom: function (zoom) {
	            this.option.zoom = zoom;
	        },

	        setCenter: function (center) {
	            this.option.center = center;
	        }
	    });

	    zrUtil.mixin(GeoModel, selectableMixin);

	    module.exports = GeoModel;


/***/ },
/* 346 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var MapDraw = __webpack_require__(182);

	    module.exports = __webpack_require__(1).extendComponentView({

	        type: 'geo',

	        init: function (ecModel, api) {
	            var mapDraw = new MapDraw(api, true);
	            this._mapDraw = mapDraw;

	            this.group.add(mapDraw.group);
	        },

	        render: function (geoModel, ecModel, api, payload) {
	            // Not render if it is an toggleSelect action from self
	            if (payload && payload.type === 'geoToggleSelect'
	                && payload.from === this.uid
	            ) {
	                return;
	            }

	            var mapDraw = this._mapDraw;
	            if (geoModel.get('show')) {
	                mapDraw.draw(geoModel, ecModel, api, this, payload);
	            }
	            else {
	                this._mapDraw.group.removeAll();
	            }

	            this.group.silent = geoModel.get('silent');
	        },

	        dispose: function () {
	            this._mapDraw && this._mapDraw.remove();
	        }

	    });


/***/ },
/* 347 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * Brush component entry
	 */


	    __webpack_require__(1).registerPreprocessor(
	        __webpack_require__(348)
	    );

	    __webpack_require__(349);
	    __webpack_require__(353);
	    __webpack_require__(354);
	    __webpack_require__(355);

	    __webpack_require__(356);



/***/ },
/* 348 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @file brush preprocessor
	 */


	    var zrUtil = __webpack_require__(4);

	    var DEFAULT_TOOLBOX_BTNS = ['rect', 'polygon', 'keep', 'clear'];

	    module.exports = function (option, isNew) {
	        var brushComponents = option && option.brush;
	        if (!zrUtil.isArray(brushComponents)) {
	            brushComponents = brushComponents ? [brushComponents] : [];
	        }

	        if (!brushComponents.length) {
	            return;
	        }

	        var brushComponentSpecifiedBtns = [];

	        zrUtil.each(brushComponents, function (brushOpt) {
	            var tbs = brushOpt.hasOwnProperty('toolbox')
	                ? brushOpt.toolbox : [];

	            if (tbs instanceof Array) {
	                brushComponentSpecifiedBtns = brushComponentSpecifiedBtns.concat(tbs);
	            }
	        });

	        var toolbox = option && option.toolbox;

	        if (zrUtil.isArray(toolbox)) {
	            toolbox = toolbox[0];
	        }
	        if (!toolbox) {
	            toolbox = {feature: {}};
	            option.toolbox = [toolbox];
	        }

	        var toolboxFeature = (toolbox.feature || (toolbox.feature = {}));
	        var toolboxBrush = toolboxFeature.brush || (toolboxFeature.brush = {});
	        var brushTypes = toolboxBrush.type || (toolboxBrush.type = []);

	        brushTypes.push.apply(brushTypes, brushComponentSpecifiedBtns);

	        removeDuplicate(brushTypes);

	        if (isNew && !brushTypes.length) {
	            brushTypes.push.apply(brushTypes, DEFAULT_TOOLBOX_BTNS);
	        }
	    };

	    function removeDuplicate(arr) {
	        var map = {};
	        zrUtil.each(arr, function (val) {
	            map[val] = 1;
	        });
	        arr.length = 0;
	        zrUtil.each(map, function (flag, val) {
	            arr.push(val);
	        });
	    }



/***/ },
/* 349 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @file Brush visual coding.
	 */


	    var echarts = __webpack_require__(1);
	    var visualSolution = __webpack_require__(350);
	    var zrUtil = __webpack_require__(4);
	    var BoundingRect = __webpack_require__(9);
	    var selector = __webpack_require__(351);
	    var throttle = __webpack_require__(81);
	    var BrushTargetManager = __webpack_require__(352);

	    var STATE_LIST = ['inBrush', 'outOfBrush'];
	    var DISPATCH_METHOD = '__ecBrushSelect';
	    var DISPATCH_FLAG = '__ecInBrushSelectEvent';
	    var PRIORITY_BRUSH = echarts.PRIORITY.VISUAL.BRUSH;

	    /**
	     * Layout for visual, the priority higher than other layout, and before brush visual.
	     */
	    echarts.registerLayout(PRIORITY_BRUSH, function (ecModel, api, payload) {
	        ecModel.eachComponent({mainType: 'brush'}, function (brushModel) {

	            payload && payload.type === 'takeGlobalCursor' && brushModel.setBrushOption(
	                payload.key === 'brush' ? payload.brushOption : {brushType: false}
	            );

	            var brushTargetManager = brushModel.brushTargetManager = new BrushTargetManager(brushModel.option, ecModel);

	            brushTargetManager.setInputRanges(brushModel.areas, ecModel);
	        });
	    });

	    /**
	     * Register the visual encoding if this modules required.
	     */
	    echarts.registerVisual(PRIORITY_BRUSH, function (ecModel, api, payload) {

	        var brushSelected = [];
	        var throttleType;
	        var throttleDelay;

	        ecModel.eachComponent({mainType: 'brush'}, function (brushModel, brushIndex) {

	            var thisBrushSelected = {
	                brushId: brushModel.id,
	                brushIndex: brushIndex,
	                brushName: brushModel.name,
	                areas: zrUtil.clone(brushModel.areas),
	                selected: []
	            };
	            // Every brush component exists in event params, convenient
	            // for user to find by index.
	            brushSelected.push(thisBrushSelected);

	            var brushOption = brushModel.option;
	            var brushLink = brushOption.brushLink;
	            var linkedSeriesMap = [];
	            var selectedDataIndexForLink = [];
	            var rangeInfoBySeries = [];
	            var hasBrushExists = 0;

	            if (!brushIndex) { // Only the first throttle setting works.
	                throttleType = brushOption.throttleType;
	                throttleDelay = brushOption.throttleDelay;
	            }

	            // Add boundingRect and selectors to range.
	            var areas = zrUtil.map(brushModel.areas, function (area) {
	                return bindSelector(
	                    zrUtil.defaults(
	                        {boundingRect: boundingRectBuilders[area.brushType](area)},
	                        area
	                    )
	                );
	            });

	            var visualMappings = visualSolution.createVisualMappings(
	                brushModel.option, STATE_LIST, function (mappingOption) {
	                    mappingOption.mappingMethod = 'fixed';
	                }
	            );

	            zrUtil.isArray(brushLink) && zrUtil.each(brushLink, function (seriesIndex) {
	                linkedSeriesMap[seriesIndex] = 1;
	            });

	            function linkOthers(seriesIndex) {
	                return brushLink === 'all' || linkedSeriesMap[seriesIndex];
	            }

	            // If no supported brush or no brush on the series,
	            // all visuals should be in original state.
	            function brushed(rangeInfoList) {
	                return !!rangeInfoList.length;
	            }

	            /**
	             * Logic for each series: (If the logic has to be modified one day, do it carefully!)
	             *
	             * ( brushed ┬ && ┬hasBrushExist ┬ && linkOthers  ) => StepA: ┬record, ┬ StepB: ┬visualByRecord.
	             *   !brushed┘    ├hasBrushExist ┤                            └nothing,┘        ├visualByRecord.
	             *                └!hasBrushExist┘                                              └nothing.
	             * ( !brushed  && ┬hasBrushExist ┬ && linkOthers  ) => StepA:  nothing,  StepB: ┬visualByRecord.
	             *                └!hasBrushExist┘                                              └nothing.
	             * ( brushed ┬ &&                     !linkOthers ) => StepA:  nothing,  StepB: ┬visualByCheck.
	             *   !brushed┘                                                                  └nothing.
	             * ( !brushed  &&                     !linkOthers ) => StepA:  nothing,  StepB:  nothing.
	             */

	            // Step A
	            ecModel.eachSeries(function (seriesModel, seriesIndex) {
	                var rangeInfoList = rangeInfoBySeries[seriesIndex] = [];

	                seriesModel.subType === 'parallel'
	                    ? stepAParallel(seriesModel, seriesIndex, rangeInfoList)
	                    : stepAOthers(seriesModel, seriesIndex, rangeInfoList);
	            });

	            function stepAParallel(seriesModel, seriesIndex) {
	                var coordSys = seriesModel.coordinateSystem;
	                hasBrushExists |= coordSys.hasAxisBrushed();

	                linkOthers(seriesIndex) && coordSys.eachActiveState(
	                    seriesModel.getData(),
	                    function (activeState, dataIndex) {
	                        activeState === 'active' && (selectedDataIndexForLink[dataIndex] = 1);
	                    }
	                );
	            }

	            function stepAOthers(seriesModel, seriesIndex, rangeInfoList) {
	                var selectorsByBrushType = getSelectorsByBrushType(seriesModel);
	                if (!selectorsByBrushType || brushModelNotControll(brushModel, seriesIndex)) {
	                    return;
	                }

	                zrUtil.each(areas, function (area) {
	                    selectorsByBrushType[area.brushType]
	                        && brushModel.brushTargetManager.controlSeries(area, seriesModel, ecModel)
	                        && rangeInfoList.push(area);
	                    hasBrushExists |= brushed(rangeInfoList);
	                });

	                if (linkOthers(seriesIndex) && brushed(rangeInfoList)) {
	                    var data = seriesModel.getData();
	                    data.each(function (dataIndex) {
	                        if (checkInRange(selectorsByBrushType, rangeInfoList, data, dataIndex)) {
	                            selectedDataIndexForLink[dataIndex] = 1;
	                        }
	                    });
	                }
	            }

	            // Step B
	            ecModel.eachSeries(function (seriesModel, seriesIndex) {
	                var seriesBrushSelected = {
	                    seriesId: seriesModel.id,
	                    seriesIndex: seriesIndex,
	                    seriesName: seriesModel.name,
	                    dataIndex: []
	                };
	                // Every series exists in event params, convenient
	                // for user to find series by seriesIndex.
	                thisBrushSelected.selected.push(seriesBrushSelected);

	                var selectorsByBrushType = getSelectorsByBrushType(seriesModel);
	                var rangeInfoList = rangeInfoBySeries[seriesIndex];

	                var data = seriesModel.getData();
	                var getValueState = linkOthers(seriesIndex)
	                    ? function (dataIndex) {
	                        return selectedDataIndexForLink[dataIndex]
	                            ? (seriesBrushSelected.dataIndex.push(data.getRawIndex(dataIndex)), 'inBrush')
	                            : 'outOfBrush';
	                    }
	                    : function (dataIndex) {
	                        return checkInRange(selectorsByBrushType, rangeInfoList, data, dataIndex)
	                            ? (seriesBrushSelected.dataIndex.push(data.getRawIndex(dataIndex)), 'inBrush')
	                            : 'outOfBrush';
	                    };

	                // If no supported brush or no brush, all visuals are in original state.
	                (linkOthers(seriesIndex) ? hasBrushExists : brushed(rangeInfoList))
	                    && visualSolution.applyVisual(
	                        STATE_LIST, visualMappings, data, getValueState
	                    );
	            });

	        });

	        dispatchAction(api, throttleType, throttleDelay, brushSelected, payload);
	    });

	    function dispatchAction(api, throttleType, throttleDelay, brushSelected, payload) {
	        // This event will not be triggered when `setOpion`, otherwise dead lock may
	        // triggered when do `setOption` in event listener, which we do not find
	        // satisfactory way to solve yet. Some considered resolutions:
	        // (a) Diff with prevoius selected data ant only trigger event when changed.
	        // But store previous data and diff precisely (i.e., not only by dataIndex, but
	        // also detect value changes in selected data) might bring complexity or fragility.
	        // (b) Use spectial param like `silent` to suppress event triggering.
	        // But such kind of volatile param may be weird in `setOption`.
	        if (!payload) {
	            return;
	        }

	        var zr = api.getZr();
	        if (zr[DISPATCH_FLAG]) {
	            return;
	        }

	        if (!zr[DISPATCH_METHOD]) {
	            zr[DISPATCH_METHOD] = doDispatch;
	        }

	        var fn = throttle.createOrUpdate(zr, DISPATCH_METHOD, throttleDelay, throttleType);

	        fn(api, brushSelected);
	    }

	    function doDispatch(api, brushSelected) {
	        if (!api.isDisposed()) {
	            var zr = api.getZr();
	            zr[DISPATCH_FLAG] = true;
	            api.dispatchAction({
	                type: 'brushSelect',
	                batch: brushSelected
	            });
	            zr[DISPATCH_FLAG] = false;
	        }
	    }

	    function checkInRange(selectorsByBrushType, rangeInfoList, data, dataIndex) {
	        for (var i = 0, len = rangeInfoList.length; i < len; i++) {
	            var area = rangeInfoList[i];
	            if (selectorsByBrushType[area.brushType](
	                dataIndex, data, area.selectors, area
	            )) {
	                return true;
	            }
	        }
	    }

	    function getSelectorsByBrushType(seriesModel) {
	        var brushSelector = seriesModel.brushSelector;
	        if (zrUtil.isString(brushSelector)) {
	            var sels = [];
	            zrUtil.each(selector, function (selectorsByElementType, brushType) {
	                sels[brushType] = function (dataIndex, data, selectors, area) {
	                    var itemLayout = data.getItemLayout(dataIndex);
	                    return selectorsByElementType[brushSelector](itemLayout, selectors, area);
	                };
	            });
	            return sels;
	        }
	        else if (zrUtil.isFunction(brushSelector)) {
	            var bSelector = {};
	            zrUtil.each(selector, function (sel, brushType) {
	                bSelector[brushType] = brushSelector;
	            });
	            return bSelector;
	        }
	        return brushSelector;
	    }

	    function brushModelNotControll(brushModel, seriesIndex) {
	        var seriesIndices = brushModel.option.seriesIndex;
	        return seriesIndices != null
	            && seriesIndices !== 'all'
	            && (
	                zrUtil.isArray(seriesIndices)
	                ? zrUtil.indexOf(seriesIndices, seriesIndex) < 0
	                : seriesIndex !== seriesIndices
	            );
	    }

	    function bindSelector(area) {
	        var selectors = area.selectors = {};
	        zrUtil.each(selector[area.brushType], function (selFn, elType) {
	            // Do not use function binding or curry for performance.
	            selectors[elType] = function (itemLayout) {
	                return selFn(itemLayout, selectors, area);
	            };
	        });
	        return area;
	    }

	    var boundingRectBuilders = {

	        lineX: zrUtil.noop,

	        lineY: zrUtil.noop,

	        rect: function (area) {
	            return getBoundingRectFromMinMax(area.range);
	        },

	        polygon: function (area) {
	            var minMax;
	            var range = area.range;

	            for (var i = 0, len = range.length; i < len; i++) {
	                minMax = minMax || [[Infinity, -Infinity], [Infinity, -Infinity]];
	                var rg = range[i];
	                rg[0] < minMax[0][0] && (minMax[0][0] = rg[0]);
	                rg[0] > minMax[0][1] && (minMax[0][1] = rg[0]);
	                rg[1] < minMax[1][0] && (minMax[1][0] = rg[1]);
	                rg[1] > minMax[1][1] && (minMax[1][1] = rg[1]);
	            }

	            return minMax && getBoundingRectFromMinMax(minMax);
	        }
	    };

	    function getBoundingRectFromMinMax(minMax) {
	        return new BoundingRect(
	            minMax[0][0],
	            minMax[1][0],
	            minMax[0][1] - minMax[0][0],
	            minMax[1][1] - minMax[1][0]
	        );
	    }



/***/ },
/* 350 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @file Visual solution, for consistent option specification.
	 */


	    var zrUtil = __webpack_require__(4);
	    var VisualMapping = __webpack_require__(203);
	    var each = zrUtil.each;

	    function hasKeys(obj) {
	        if (obj) {
	            for (var name in obj){
	                if (obj.hasOwnProperty(name)) {
	                    return true;
	                }
	            }
	        }
	    }

	    var visualSolution = {

	        /**
	         * @param {Object} option
	         * @param {Array.<string>} stateList
	         * @param {Function} [supplementVisualOption]
	         * @return {Object} visualMappings <state, <visualType, module:echarts/visual/VisualMapping>>
	         */
	        createVisualMappings: function (option, stateList, supplementVisualOption) {
	            var visualMappings = {};

	            each(stateList, function (state) {
	                var mappings = visualMappings[state] = createMappings();

	                each(option[state], function (visualData, visualType) {
	                    if (!VisualMapping.isValidType(visualType)) {
	                        return;
	                    }
	                    var mappingOption = {
	                        type: visualType,
	                        visual: visualData
	                    };
	                    supplementVisualOption && supplementVisualOption(mappingOption, state);
	                    mappings[visualType] = new VisualMapping(mappingOption);

	                    // Prepare a alpha for opacity, for some case that opacity
	                    // is not supported, such as rendering using gradient color.
	                    if (visualType === 'opacity') {
	                        mappingOption = zrUtil.clone(mappingOption);
	                        mappingOption.type = 'colorAlpha';
	                        mappings.__hidden.__alphaForOpacity = new VisualMapping(mappingOption);
	                    }
	                });
	            });

	            return visualMappings;

	            function createMappings() {
	                var Creater = function () {};
	                // Make sure hidden fields will not be visited by
	                // object iteration (with hasOwnProperty checking).
	                Creater.prototype.__hidden = Creater.prototype;
	                var obj = new Creater();
	                return obj;
	            }
	        },

	        /**
	         * @param {Object} thisOption
	         * @param {Object} newOption
	         * @param {Array.<string>} keys
	         */
	        replaceVisualOption: function (thisOption, newOption, keys) {
	            // Visual attributes merge is not supported, otherwise it
	            // brings overcomplicated merge logic. See #2853. So if
	            // newOption has anyone of these keys, all of these keys
	            // will be reset. Otherwise, all keys remain.
	            var has;
	            zrUtil.each(keys, function (key) {
	                if (newOption.hasOwnProperty(key) && hasKeys(newOption[key])) {
	                    has = true;
	                }
	            });
	            has && zrUtil.each(keys, function (key) {
	                if (newOption.hasOwnProperty(key) && hasKeys(newOption[key])) {
	                    thisOption[key] = zrUtil.clone(newOption[key]);
	                }
	                else {
	                    delete thisOption[key];
	                }
	            });
	        },

	        /**
	         * @param {Array.<string>} stateList
	         * @param {Object} visualMappings <state, Object.<visualType, module:echarts/visual/VisualMapping>>
	         * @param {module:echarts/data/List} list
	         * @param {Function} getValueState param: valueOrIndex, return: state.
	         * @param {object} [scope] Scope for getValueState
	         * @param {string} [dimension] Concrete dimension, if used.
	         */
	        applyVisual: function (stateList, visualMappings, data, getValueState, scope, dimension) {
	            var visualTypesMap = {};
	            zrUtil.each(stateList, function (state) {
	                var visualTypes = VisualMapping.prepareVisualTypes(visualMappings[state]);
	                visualTypesMap[state] = visualTypes;
	            });

	            var dataIndex;

	            function getVisual(key) {
	                return data.getItemVisual(dataIndex, key);
	            }

	            function setVisual(key, value) {
	                data.setItemVisual(dataIndex, key, value);
	            }

	            if (dimension == null) {
	                data.each(eachItem, true);
	            }
	            else {
	                data.each([dimension], eachItem, true);
	            }

	            function eachItem(valueOrIndex, index) {
	                dataIndex = dimension == null ? valueOrIndex : index;

	                var rawDataItem = data.getRawDataItem(dataIndex);
	                // Consider performance
	                if (rawDataItem && rawDataItem.visualMap === false) {
	                    return;
	                }

	                var valueState = getValueState.call(scope, valueOrIndex);
	                var mappings = visualMappings[valueState];
	                var visualTypes = visualTypesMap[valueState];

	                for (var i = 0, len = visualTypes.length; i < len; i++) {
	                    var type = visualTypes[i];
	                    mappings[type] && mappings[type].applyVisual(
	                        valueOrIndex, getVisual, setVisual
	                    );
	                }
	            }
	        }
	    };

	    module.exports = visualSolution;



/***/ },
/* 351 */
/***/ function(module, exports, __webpack_require__) {

	

	    var polygonContain = __webpack_require__(175).contain;
	    var BoundingRect = __webpack_require__(9);

	    // Key of the first level is brushType: `line`, `rect`, `polygon`.
	    // Key of the second level is chart element type: `point`, `rect`.
	    // See moudule:echarts/component/helper/BrushController
	    // function param:
	    //      {Object} itemLayout fetch from data.getItemLayout(dataIndex)
	    //      {Object} selectors {point: selector, rect: selector, ...}
	    //      {Object} area {range: [[], [], ..], boudingRect}
	    // function return:
	    //      {boolean} Whether in the given brush.
	    var selector = {
	        lineX: getLineSelectors(0),
	        lineY: getLineSelectors(1),
	        rect: {
	            point: function (itemLayout, selectors, area) {
	                return area.boundingRect.contain(itemLayout[0], itemLayout[1]);
	            },
	            rect: function (itemLayout, selectors, area) {
	                return area.boundingRect.intersect(itemLayout);
	            }
	        },
	        polygon: {
	            point: function (itemLayout, selectors, area) {
	                return area.boundingRect.contain(itemLayout[0], itemLayout[1])
	                    && polygonContain(area.range, itemLayout[0], itemLayout[1]);
	            },
	            rect: function (itemLayout, selectors, area) {
	                var points = area.range;

	                if (points.length <= 1) {
	                    return false;
	                }

	                var x = itemLayout.x;
	                var y = itemLayout.y;
	                var width = itemLayout.width;
	                var height = itemLayout.height;
	                var p = points[0];

	                if (polygonContain(points, x, y)
	                    || polygonContain(points, x + width, y)
	                    || polygonContain(points, x, y + height)
	                    || polygonContain(points, x + width, y + height)
	                    || BoundingRect.create(itemLayout).contain(p[0], p[1])
	                    || lineIntersectPolygon(x, y, x + width, y, points)
	                    || lineIntersectPolygon(x, y, x, y + height, points)
	                    || lineIntersectPolygon(x + width, y, x + width, y + height, points)
	                    || lineIntersectPolygon(x, y + height, x + width, y + height, points)
	                ) {
	                    return true;
	                }
	            }
	        }
	    };

	    function getLineSelectors(xyIndex) {
	        var xy = ['x', 'y'];
	        var wh = ['width', 'height'];

	        return {
	            point: function (itemLayout, selectors, area) {
	                var range = area.range;
	                var p = itemLayout[xyIndex];
	                return inLineRange(p, range);
	            },
	            rect: function (itemLayout, selectors, area) {
	                var range = area.range;
	                var layoutRange = [
	                    itemLayout[xy[xyIndex]],
	                    itemLayout[xy[xyIndex]] + itemLayout[wh[xyIndex]]
	                ];
	                layoutRange[1] < layoutRange[0] && layoutRange.reverse();
	                return inLineRange(layoutRange[0], range)
	                    || inLineRange(layoutRange[1], range)
	                    || inLineRange(range[0], layoutRange)
	                    || inLineRange(range[1], layoutRange);
	            }
	        };
	    }

	    function inLineRange(p, range) {
	        return range[0] <= p && p <= range[1];
	    }

	    function lineIntersectPolygon(lx, ly, l2x, l2y, points) {
	        for (var i = 0, p2 = points[points.length - 1]; i < points.length; i++) {
	            var p = points[i];
	            if (lineIntersect(lx, ly, l2x, l2y, p[0], p[1], p2[0], p2[1])) {
	                return true;
	            }
	            p2 = p;
	        }
	    }

	    // Code from <http://blog.csdn.net/rickliuxiao/article/details/6259322> with some fix.
	    // See <https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection>
	    function lineIntersect(a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y) {
	        var delta = determinant(a2x - a1x, b1x - b2x, a2y - a1y, b1y - b2y);
	        if (nearZero(delta)) { // parallel
	            return false;
	        }
	        var namenda = determinant(b1x - a1x, b1x - b2x, b1y - a1y, b1y - b2y) / delta;
	        if (namenda < 0 || namenda > 1) {
	            return false;
	        }
	        var miu = determinant(a2x - a1x, b1x - a1x, a2y - a1y, b1y - a1y) / delta;
	        if (miu < 0 || miu > 1) {
	            return false;
	        }
	        return true;
	    }

	    function nearZero(val) {
	        return val <= (1e-6) && val >= -(1e-6);
	    }

	    function determinant(v1, v2, v3, v4) {
	        return v1 * v4 - v2 * v3;
	    }

	    module.exports = selector;



/***/ },
/* 352 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);
	    var graphic = __webpack_require__(18);
	    var modelUtil = __webpack_require__(5);
	    var brushHelper = __webpack_require__(246);

	    var each = zrUtil.each;
	    var indexOf = zrUtil.indexOf;
	    var curry = zrUtil.curry;

	    var COORD_CONVERTS = ['dataToPoint', 'pointToData'];

	    // FIXME
	    // how to genarialize to more coordinate systems.
	    var INCLUDE_FINDER_MAIN_TYPES = [
	        'grid', 'xAxis', 'yAxis', 'geo', 'graph',
	        'polar', 'radiusAxis', 'angleAxis', 'bmap'
	    ];

	    /**
	     * [option in constructor]:
	     * {
	     *     Index/Id/Name of geo, xAxis, yAxis, grid: See util/model#parseFinder.
	     * }
	     *
	     *
	     * [targetInfo]:
	     *
	     * There can be multiple axes in a single targetInfo. Consider the case
	     * of `grid` component, a targetInfo represents a grid which contains one or more
	     * cartesian and one or more axes. And consider the case of parallel system,
	     * which has multiple axes in a coordinate system.
	     * Can be {
	     *     panelId: ...,
	     *     coordSys: <a representitive cartesian in grid (first cartesian by default)>,
	     *     coordSyses: all cartesians.
	     *     gridModel: <grid component>
	     *     xAxes: correspond to coordSyses on index
	     *     yAxes: correspond to coordSyses on index
	     * }
	     * or {
	     *     panelId: ...,
	     *     coordSys: <geo coord sys>
	     *     coordSyses: [<geo coord sys>]
	     *     geoModel: <geo component>
	     * }
	     *
	     *
	     * [panelOpt]:
	     *
	     * Make from targetInfo. Input to BrushController.
	     * {
	     *     panelId: ...,
	     *     rect: ...
	     * }
	     *
	     *
	     * [area]:
	     *
	     * Generated by BrushController or user input.
	     * {
	     *     panelId: Used to locate coordInfo directly. If user inpput, no panelId.
	     *     brushType: determine how to convert to/from coord('rect' or 'polygon' or 'lineX/Y').
	     *     Index/Id/Name of geo, xAxis, yAxis, grid: See util/model#parseFinder.
	     *     range: pixel range.
	     *     coordRange: representitive coord range (the first one of coordRanges).
	     *     coordRanges: <Array> coord ranges, used in multiple cartesian in one grid.
	     * }
	     */

	    /**
	     * @param {Object} option contains Index/Id/Name of xAxis/yAxis/geo/grid
	     *        Each can be {number|Array.<number>}. like: {xAxisIndex: [3, 4]}
	     * @param {module:echarts/model/Global} ecModel
	     * @param {Object} [opt]
	     * @param {Array.<string>} [opt.include] include coordinate system types.
	     */
	    function BrushTargetManager(option, ecModel, opt) {
	        /**
	         * @private
	         * @type {Array.<Object>}
	         */
	        var targetInfoList = this._targetInfoList = [];
	        var info = {};
	        var foundCpts = parseFinder(ecModel, option);

	        each(targetInfoBuilders, function (builder, type) {
	            if (!opt || !opt.include || indexOf(opt.include, type) >= 0) {
	                builder(foundCpts, targetInfoList, info);
	            }
	        });
	    }

	    var proto = BrushTargetManager.prototype;

	    proto.setOutputRanges = function (areas, ecModel) {
	        this.matchOutputRanges(areas, ecModel, function (area, coordRange, coordSys) {
	            (area.coordRanges || (area.coordRanges = [])).push(coordRange);
	            // area.coordRange is the first of area.coordRanges
	            if (!area.coordRange) {
	                area.coordRange = coordRange;
	                // In 'category' axis, coord to pixel is not reversible, so we can not
	                // rebuild range by coordRange accrately, which may bring trouble when
	                // brushing only one item. So we use __rangeOffset to rebuilding range
	                // by coordRange. And this it only used in brush component so it is no
	                // need to be adapted to coordRanges.
	                var result = coordConvert[area.brushType](0, coordSys, coordRange);
	                area.__rangeOffset = {
	                    offset: diffProcessor[area.brushType](result.values, area.range, [1, 1]),
	                    xyMinMax: result.xyMinMax
	                };
	            }
	        });
	    };

	    proto.matchOutputRanges = function (areas, ecModel, cb) {
	        each(areas, function (area) {
	            var targetInfo = this.findTargetInfo(area, ecModel);

	            if (targetInfo && targetInfo !== true) {
	                zrUtil.each(
	                    targetInfo.coordSyses,
	                    function (coordSys) {
	                        var result = coordConvert[area.brushType](1, coordSys, area.range);
	                        cb(area, result.values, coordSys, ecModel);
	                    }
	                );
	            }
	        }, this);
	    };

	    proto.setInputRanges = function (areas, ecModel) {
	        each(areas, function (area) {
	            var targetInfo = this.findTargetInfo(area, ecModel);

	            if (true) {
	                zrUtil.assert(
	                    !targetInfo || targetInfo === true || area.coordRange,
	                    'coordRange must be specified when coord index specified.'
	                );
	                zrUtil.assert(
	                    !targetInfo || targetInfo !== true || area.range,
	                    'range must be specified in global brush.'
	                );
	            }

	            area.range = area.range || [];

	            // convert coordRange to global range and set panelId.
	            if (targetInfo && targetInfo !== true) {
	                area.panelId = targetInfo.panelId;
	                // (1) area.range shoule always be calculate from coordRange but does
	                // not keep its original value, for the sake of the dataZoom scenario,
	                // where area.coordRange remains unchanged but area.range may be changed.
	                // (2) Only support converting one coordRange to pixel range in brush
	                // component. So do not consider `coordRanges`.
	                // (3) About __rangeOffset, see comment above.
	                var result = coordConvert[area.brushType](0, targetInfo.coordSys, area.coordRange);
	                var rangeOffset = area.__rangeOffset;
	                area.range = rangeOffset
	                    ? diffProcessor[area.brushType](
	                        result.values,
	                        rangeOffset.offset,
	                        getScales(result.xyMinMax, rangeOffset.xyMinMax)
	                    )
	                    : result.values;
	            }
	        }, this);
	    };

	    proto.makePanelOpts = function (api, getDefaultBrushType) {
	        return zrUtil.map(this._targetInfoList, function (targetInfo) {
	            var rect = targetInfo.getPanelRect();
	            return {
	                panelId: targetInfo.panelId,
	                defaultBrushType: getDefaultBrushType && getDefaultBrushType(targetInfo),
	                clipPath: brushHelper.makeRectPanelClipPath(rect),
	                isTargetByCursor: brushHelper.makeRectIsTargetByCursor(
	                    rect, api, targetInfo.coordSysModel
	                ),
	                getLinearBrushOtherExtent: brushHelper.makeLinearBrushOtherExtent(rect)
	            };
	        });
	    };

	    proto.controlSeries = function (area, seriesModel, ecModel) {
	        // Check whether area is bound in coord, and series do not belong to that coord.
	        // If do not do this check, some brush (like lineX) will controll all axes.
	        var targetInfo = this.findTargetInfo(area, ecModel);
	        return targetInfo === true || (
	            targetInfo && indexOf(targetInfo.coordSyses, seriesModel.coordinateSystem) >= 0
	        );
	    };

	    /**
	     * If return Object, a coord found.
	     * If reutrn true, global found.
	     * Otherwise nothing found.
	     *
	     * @param {Object} area
	     * @param {Array} targetInfoList
	     * @return {Obejct|boolean}
	     */
	    proto.findTargetInfo = function (area, ecModel) {
	        var targetInfoList = this._targetInfoList;
	        var foundCpts = parseFinder(ecModel, area);

	        for (var i = 0; i < targetInfoList.length; i++) {
	            var targetInfo = targetInfoList[i];
	            var areaPanelId = area.panelId;
	            if (areaPanelId) {
	                if (targetInfo.panelId === areaPanelId) {
	                    return targetInfo;
	                }
	            }
	            else {
	                for (var i = 0; i < targetInfoMatchers.length; i++) {
	                    if (targetInfoMatchers[i](foundCpts, targetInfo)) {
	                        return targetInfo;
	                    }
	                }
	            }
	        }

	        return true;
	    };

	    function formatMinMax(minMax) {
	        minMax[0] > minMax[1] && minMax.reverse();
	        return minMax;
	    }

	    function parseFinder(ecModel, option) {
	        return modelUtil.parseFinder(
	            ecModel, option, {includeMainTypes: INCLUDE_FINDER_MAIN_TYPES}
	        );
	    }

	    var targetInfoBuilders = {

	        grid: function (foundCpts, targetInfoList) {
	            var xAxisModels = foundCpts.xAxisModels;
	            var yAxisModels = foundCpts.yAxisModels;
	            var gridModels = foundCpts.gridModels;
	            // Remove duplicated.
	            var gridModelMap = zrUtil.createHashMap();
	            var xAxesHas = {};
	            var yAxesHas = {};

	            if (!xAxisModels && !yAxisModels && !gridModels) {
	                return;
	            }

	            each(xAxisModels, function (axisModel) {
	                var gridModel = axisModel.axis.grid.model;
	                gridModelMap.set(gridModel.id, gridModel);
	                xAxesHas[gridModel.id] = true;
	            });
	            each(yAxisModels, function (axisModel) {
	                var gridModel = axisModel.axis.grid.model;
	                gridModelMap.set(gridModel.id, gridModel);
	                yAxesHas[gridModel.id] = true;
	            });
	            each(gridModels, function (gridModel) {
	                gridModelMap.set(gridModel.id, gridModel);
	                xAxesHas[gridModel.id] = true;
	                yAxesHas[gridModel.id] = true;
	            });

	            gridModelMap.each(function (gridModel) {
	                var grid = gridModel.coordinateSystem;
	                var cartesians = [];

	                each(grid.getCartesians(), function (cartesian, index) {
	                    if (indexOf(xAxisModels, cartesian.getAxis('x').model) >= 0
	                        || indexOf(yAxisModels, cartesian.getAxis('y').model) >= 0
	                    ) {
	                        cartesians.push(cartesian);
	                    }
	                });
	                targetInfoList.push({
	                    panelId: 'grid--' + gridModel.id,
	                    gridModel: gridModel,
	                    coordSysModel: gridModel,
	                    // Use the first one as the representitive coordSys.
	                    coordSys: cartesians[0],
	                    coordSyses: cartesians,
	                    getPanelRect: panelRectBuilder.grid,
	                    xAxisDeclared: xAxesHas[gridModel.id],
	                    yAxisDeclared: yAxesHas[gridModel.id]
	                });
	            });
	        },

	        geo: function (foundCpts, targetInfoList) {
	            each(foundCpts.geoModels, function (geoModel) {
	                var coordSys = geoModel.coordinateSystem;
	                targetInfoList.push({
	                    panelId: 'geo--' + geoModel.id,
	                    geoModel: geoModel,
	                    coordSysModel: geoModel,
	                    coordSys: coordSys,
	                    coordSyses: [coordSys],
	                    getPanelRect: panelRectBuilder.geo
	                });
	            });
	        }
	    };

	    var targetInfoMatchers = [

	        // grid
	        function (foundCpts, targetInfo) {
	            var xAxisModel = foundCpts.xAxisModel;
	            var yAxisModel = foundCpts.yAxisModel;
	            var gridModel = foundCpts.gridModel;

	            !gridModel && xAxisModel && (gridModel = xAxisModel.axis.grid.model);
	            !gridModel && yAxisModel && (gridModel = yAxisModel.axis.grid.model);

	            return gridModel && gridModel === targetInfo.gridModel;
	        },

	        // geo
	        function (foundCpts, targetInfo) {
	            var geoModel = foundCpts.geoModel;
	            return geoModel && geoModel === targetInfo.geoModel;
	        }
	    ];

	    var panelRectBuilder = {

	        grid: function () {
	            // grid is not Transformable.
	            return this.coordSys.grid.getRect().clone();
	        },

	        geo: function () {
	            var coordSys = this.coordSys;
	            var rect = coordSys.getBoundingRect().clone();
	            // geo roam and zoom transform
	            rect.applyTransform(graphic.getTransform(coordSys));
	            return rect;
	        }
	    };

	    var coordConvert = {

	        lineX: curry(axisConvert, 0),

	        lineY: curry(axisConvert, 1),

	        rect: function (to, coordSys, rangeOrCoordRange) {
	            var xminymin = coordSys[COORD_CONVERTS[to]]([rangeOrCoordRange[0][0], rangeOrCoordRange[1][0]]);
	            var xmaxymax = coordSys[COORD_CONVERTS[to]]([rangeOrCoordRange[0][1], rangeOrCoordRange[1][1]]);
	            var values = [
	                formatMinMax([xminymin[0], xmaxymax[0]]),
	                formatMinMax([xminymin[1], xmaxymax[1]])
	            ];
	            return {values: values, xyMinMax: values};
	        },

	        polygon: function (to, coordSys, rangeOrCoordRange) {
	            var xyMinMax = [[Infinity, -Infinity], [Infinity, -Infinity]];
	            var values = zrUtil.map(rangeOrCoordRange, function (item) {
	                var p = coordSys[COORD_CONVERTS[to]](item);
	                xyMinMax[0][0] = Math.min(xyMinMax[0][0], p[0]);
	                xyMinMax[1][0] = Math.min(xyMinMax[1][0], p[1]);
	                xyMinMax[0][1] = Math.max(xyMinMax[0][1], p[0]);
	                xyMinMax[1][1] = Math.max(xyMinMax[1][1], p[1]);
	                return p;
	            });
	            return {values: values, xyMinMax: xyMinMax};
	        }
	    };

	    function axisConvert(axisNameIndex, to, coordSys, rangeOrCoordRange) {
	        if (true) {
	            zrUtil.assert(
	                coordSys.type === 'cartesian2d',
	                'lineX/lineY brush is available only in cartesian2d.'
	            );
	        }

	        var axis = coordSys.getAxis(['x', 'y'][axisNameIndex]);
	        var values = formatMinMax(zrUtil.map([0, 1], function (i) {
	            return to
	                ? axis.coordToData(axis.toLocalCoord(rangeOrCoordRange[i]))
	                : axis.toGlobalCoord(axis.dataToCoord(rangeOrCoordRange[i]));
	        }));
	        var xyMinMax = [];
	        xyMinMax[axisNameIndex] = values;
	        xyMinMax[1 - axisNameIndex] = [NaN, NaN];

	        return {values: values, xyMinMax: xyMinMax};
	    }

	    var diffProcessor = {
	        lineX: curry(axisDiffProcessor, 0),

	        lineY: curry(axisDiffProcessor, 1),

	        rect: function (values, refer, scales) {
	            return [
	                [values[0][0] - scales[0] * refer[0][0], values[0][1] - scales[0] * refer[0][1]],
	                [values[1][0] - scales[1] * refer[1][0], values[1][1] - scales[1] * refer[1][1]]
	            ];
	        },

	        polygon: function (values, refer, scales) {
	            return zrUtil.map(values, function (item, idx) {
	                return [item[0] - scales[0] * refer[idx][0], item[1] - scales[1] * refer[idx][1]];
	            });
	        }
	    };

	    function axisDiffProcessor(axisNameIndex, values, refer, scales) {
	        return [
	            values[0] - scales[axisNameIndex] * refer[0],
	            values[1] - scales[axisNameIndex] * refer[1]
	        ];
	    }

	    // We have to process scale caused by dataZoom manually,
	    // although it might be not accurate.
	    function getScales(xyMinMaxCurr, xyMinMaxOrigin) {
	        var sizeCurr = getSize(xyMinMaxCurr);
	        var sizeOrigin = getSize(xyMinMaxOrigin);
	        var scales = [sizeCurr[0] / sizeOrigin[0], sizeCurr[1] / sizeOrigin[1]];
	        isNaN(scales[0]) && (scales[0] = 1);
	        isNaN(scales[1]) && (scales[1] = 1);
	        return scales;
	    }

	    function getSize(xyMinMax) {
	        return xyMinMax
	            ? [xyMinMax[0][1] - xyMinMax[0][0], xyMinMax[1][1] - xyMinMax[1][0]]
	            : [NaN, NaN];
	    }

	    module.exports = BrushTargetManager;


/***/ },
/* 353 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @file Brush model
	 */


	    var echarts = __webpack_require__(1);
	    var zrUtil = __webpack_require__(4);
	    var visualSolution = __webpack_require__(350);
	    var Model = __webpack_require__(12);

	    var DEFAULT_OUT_OF_BRUSH_COLOR = ['#ddd'];

	    var BrushModel = echarts.extendComponentModel({

	        type: 'brush',

	        dependencies: ['geo', 'grid', 'xAxis', 'yAxis', 'parallel', 'series'],

	        /**
	         * @protected
	         */
	        defaultOption: {
	            // inBrush: null,
	            // outOfBrush: null,
	            toolbox: null,          // Default value see preprocessor.
	            brushLink: null,        // Series indices array, broadcast using dataIndex.
	                                    // or 'all', which means all series. 'none' or null means no series.
	            seriesIndex: 'all',     // seriesIndex array, specify series controlled by this brush component.
	            geoIndex: null,         //
	            xAxisIndex: null,
	            yAxisIndex: null,

	            brushType: 'rect',      // Default brushType, see BrushController.
	            brushMode: 'single',    // Default brushMode, 'single' or 'multiple'
	            transformable: true,    // Default transformable.
	            brushStyle: {           // Default brushStyle
	                borderWidth: 1,
	                color: 'rgba(120,140,180,0.3)',
	                borderColor: 'rgba(120,140,180,0.8)'
	            },

	            throttleType: 'fixRate',// Throttle in brushSelected event. 'fixRate' or 'debounce'.
	                                    // If null, no throttle. Valid only in the first brush component
	            throttleDelay: 0,       // Unit: ms, 0 means every event will be triggered.

	            // FIXME
	            // 试验效果
	            removeOnClick: true,

	            z: 10000
	        },

	        /**
	         * @readOnly
	         * @type {Array.<Object>}
	         */
	        areas: [],

	        /**
	         * Current activated brush type.
	         * If null, brush is inactived.
	         * see module:echarts/component/helper/BrushController
	         * @readOnly
	         * @type {string}
	         */
	        brushType: null,

	        /**
	         * Current brush opt.
	         * see module:echarts/component/helper/BrushController
	         * @readOnly
	         * @type {Object}
	         */
	        brushOption: {},

	        /**
	         * @readOnly
	         * @type {Array.<Object>}
	         */
	        coordInfoList: [],

	        optionUpdated: function (newOption, isInit) {
	            var thisOption = this.option;

	            !isInit && visualSolution.replaceVisualOption(
	                thisOption, newOption, ['inBrush', 'outOfBrush']
	            );

	            thisOption.inBrush = thisOption.inBrush || {};
	            // Always give default visual, consider setOption at the second time.
	            thisOption.outOfBrush = thisOption.outOfBrush || {color: DEFAULT_OUT_OF_BRUSH_COLOR};
	        },

	        /**
	         * If ranges is null/undefined, range state remain.
	         *
	         * @param {Array.<Object>} [ranges]
	         */
	        setAreas: function (areas) {
	            if (true) {
	                zrUtil.assert(zrUtil.isArray(areas));
	                zrUtil.each(areas, function (area) {
	                    zrUtil.assert(area.brushType, 'Illegal areas');
	                });
	            }

	            // If ranges is null/undefined, range state remain.
	            // This helps user to dispatchAction({type: 'brush'}) with no areas
	            // set but just want to get the current brush select info from a `brush` event.
	            if (!areas) {
	                return;
	            }

	            this.areas = zrUtil.map(areas, function (area) {
	                return generateBrushOption(this.option, area);
	            }, this);
	        },

	        /**
	         * see module:echarts/component/helper/BrushController
	         * @param {Object} brushOption
	         */
	        setBrushOption: function (brushOption) {
	            this.brushOption = generateBrushOption(this.option, brushOption);
	            this.brushType = this.brushOption.brushType;
	        }

	    });

	    function generateBrushOption(option, brushOption) {
	        return zrUtil.merge(
	            {
	                brushType: option.brushType,
	                brushMode: option.brushMode,
	                transformable: option.transformable,
	                brushStyle: new Model(option.brushStyle).getItemStyle(),
	                removeOnClick: option.removeOnClick,
	                z: option.z
	            },
	            brushOption,
	            true
	        );
	    }

	    module.exports = BrushModel;



/***/ },
/* 354 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);
	    var BrushController = __webpack_require__(245);
	    var echarts = __webpack_require__(1);

	    module.exports = echarts.extendComponentView({

	        type: 'brush',

	        init: function (ecModel, api) {

	            /**
	             * @readOnly
	             * @type {module:echarts/model/Global}
	             */
	            this.ecModel = ecModel;

	            /**
	             * @readOnly
	             * @type {module:echarts/ExtensionAPI}
	             */
	            this.api = api;

	            /**
	             * @readOnly
	             * @type {module:echarts/component/brush/BrushModel}
	             */
	            this.model;

	            /**
	             * @private
	             * @type {module:echarts/component/helper/BrushController}
	             */
	            (this._brushController = new BrushController(api.getZr()))
	                .on('brush', zrUtil.bind(this._onBrush, this))
	                .mount();
	        },

	        /**
	         * @override
	         */
	        render: function (brushModel) {
	            this.model = brushModel;
	            return updateController.apply(this, arguments);
	        },

	        /**
	         * @override
	         */
	        updateView: updateController,

	        /**
	         * @override
	         */
	        updateLayout: updateController,

	        /**
	         * @override
	         */
	        updateVisual: updateController,

	        /**
	         * @override
	         */
	        dispose: function () {
	            this._brushController.dispose();
	        },

	        /**
	         * @private
	         */
	        _onBrush: function (areas, opt) {
	            var modelId = this.model.id;

	            this.model.brushTargetManager.setOutputRanges(areas, this.ecModel);

	            // Action is not dispatched on drag end, because the drag end
	            // emits the same params with the last drag move event, and
	            // may have some delay when using touch pad, which makes
	            // animation not smooth (when using debounce).
	            (!opt.isEnd || opt.removeOnClick) && this.api.dispatchAction({
	                type: 'brush',
	                brushId: modelId,
	                areas: zrUtil.clone(areas),
	                $from: modelId
	            });
	        }

	    });

	    function updateController(brushModel, ecModel, api, payload) {
	        // Do not update controller when drawing.
	        (!payload || payload.$from !== brushModel.id) && this._brushController
	            .setPanels(brushModel.brushTargetManager.makePanelOpts(api))
	            .enableBrush(brushModel.brushOption)
	            .updateCovers(brushModel.areas.slice());
	    }



/***/ },
/* 355 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @file Brush action
	 */


	    var echarts = __webpack_require__(1);

	    /**
	     * payload: {
	     *      brushIndex: number, or,
	     *      brushId: string, or,
	     *      brushName: string,
	     *      globalRanges: Array
	     * }
	     */
	    echarts.registerAction(
	         {type: 'brush', event: 'brush', update: 'updateView'},
	        function (payload, ecModel) {
	            ecModel.eachComponent({mainType: 'brush', query: payload}, function (brushModel) {
	                brushModel.setAreas(payload.areas);
	            });
	        }
	    );

	    /**
	     * payload: {
	     *      brushComponents: [
	     *          {
	     *              brushId,
	     *              brushIndex,
	     *              brushName,
	     *              series: [
	     *                  {
	     *                      seriesId,
	     *                      seriesIndex,
	     *                      seriesName,
	     *                      rawIndices: [21, 34, ...]
	     *                  },
	     *                  ...
	     *              ]
	     *          },
	     *          ...
	     *      ]
	     * }
	     */
	    echarts.registerAction(
	         {type: 'brushSelect', event: 'brushSelected', update: 'none'},
	        function () {}
	    );


/***/ },
/* 356 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var featureManager = __webpack_require__(357);
	    var zrUtil = __webpack_require__(4);

	    function Brush(model, ecModel, api) {
	        this.model = model;
	        this.ecModel = ecModel;
	        this.api = api;

	        /**
	         * @private
	         * @type {string}
	         */
	        this._brushType;

	        /**
	         * @private
	         * @type {string}
	         */
	        this._brushMode;
	    }

	    Brush.defaultOption = {
	        show: true,
	        type: ['rect', 'polygon', 'lineX', 'lineY', 'keep', 'clear'],
	        icon: {
	            rect: 'M7.3,34.7 M0.4,10V-0.2h9.8 M89.6,10V-0.2h-9.8 M0.4,60v10.2h9.8 M89.6,60v10.2h-9.8 M12.3,22.4V10.5h13.1 M33.6,10.5h7.8 M49.1,10.5h7.8 M77.5,22.4V10.5h-13 M12.3,31.1v8.2 M77.7,31.1v8.2 M12.3,47.6v11.9h13.1 M33.6,59.5h7.6 M49.1,59.5 h7.7 M77.5,47.6v11.9h-13', // jshint ignore:line
	            polygon: 'M55.2,34.9c1.7,0,3.1,1.4,3.1,3.1s-1.4,3.1-3.1,3.1 s-3.1-1.4-3.1-3.1S53.5,34.9,55.2,34.9z M50.4,51c1.7,0,3.1,1.4,3.1,3.1c0,1.7-1.4,3.1-3.1,3.1c-1.7,0-3.1-1.4-3.1-3.1 C47.3,52.4,48.7,51,50.4,51z M55.6,37.1l1.5-7.8 M60.1,13.5l1.6-8.7l-7.8,4 M59,19l-1,5.3 M24,16.1l6.4,4.9l6.4-3.3 M48.5,11.6 l-5.9,3.1 M19.1,12.8L9.7,5.1l1.1,7.7 M13.4,29.8l1,7.3l6.6,1.6 M11.6,18.4l1,6.1 M32.8,41.9 M26.6,40.4 M27.3,40.2l6.1,1.6 M49.9,52.1l-5.6-7.6l-4.9-1.2', // jshint ignore:line
	            lineX: 'M15.2,30 M19.7,15.6V1.9H29 M34.8,1.9H40.4 M55.3,15.6V1.9H45.9 M19.7,44.4V58.1H29 M34.8,58.1H40.4 M55.3,44.4 V58.1H45.9 M12.5,20.3l-9.4,9.6l9.6,9.8 M3.1,29.9h16.5 M62.5,20.3l9.4,9.6L62.3,39.7 M71.9,29.9H55.4', // jshint ignore:line
	            lineY: 'M38.8,7.7 M52.7,12h13.2v9 M65.9,26.6V32 M52.7,46.3h13.2v-9 M24.9,12H11.8v9 M11.8,26.6V32 M24.9,46.3H11.8v-9 M48.2,5.1l-9.3-9l-9.4,9.2 M38.9-3.9V12 M48.2,53.3l-9.3,9l-9.4-9.2 M38.9,62.3V46.4', // jshint ignore:line
	            keep: 'M4,10.5V1h10.3 M20.7,1h6.1 M33,1h6.1 M55.4,10.5V1H45.2 M4,17.3v6.6 M55.6,17.3v6.6 M4,30.5V40h10.3 M20.7,40 h6.1 M33,40h6.1 M55.4,30.5V40H45.2 M21,18.9h62.9v48.6H21V18.9z', // jshint ignore:line
	            clear: 'M22,14.7l30.9,31 M52.9,14.7L22,45.7 M4.7,16.8V4.2h13.1 M26,4.2h7.8 M41.6,4.2h7.8 M70.3,16.8V4.2H57.2 M4.7,25.9v8.6 M70.3,25.9v8.6 M4.7,43.2v12.6h13.1 M26,55.8h7.8 M41.6,55.8h7.8 M70.3,43.2v12.6H57.2' // jshint ignore:line
	        },
	        title: {
	            rect: '矩形选择',
	            polygon: '圈选',
	            lineX: '横向选择',
	            lineY: '纵向选择',
	            keep: '保持选择',
	            clear: '清除选择'
	        }
	    };

	    var proto = Brush.prototype;

	    proto.render =
	    proto.updateView =
	    proto.updateLayout = function (featureModel, ecModel, api) {
	        var brushType;
	        var brushMode;
	        var isBrushed;

	        ecModel.eachComponent({mainType: 'brush'}, function (brushModel) {
	            brushType = brushModel.brushType;
	            brushMode = brushModel.brushOption.brushMode || 'single';
	            isBrushed |= brushModel.areas.length;
	        });
	        this._brushType = brushType;
	        this._brushMode = brushMode;

	        zrUtil.each(featureModel.get('type', true), function (type) {
	            featureModel.setIconStatus(
	                type,
	                (
	                    type === 'keep'
	                    ? brushMode === 'multiple'
	                    : type === 'clear'
	                    ? isBrushed
	                    : type === brushType
	                ) ? 'emphasis' : 'normal'
	            );
	        });
	    };

	    proto.getIcons = function () {
	        var model = this.model;
	        var availableIcons = model.get('icon', true);
	        var icons = {};
	        zrUtil.each(model.get('type', true), function (type) {
	            if (availableIcons[type]) {
	                icons[type] = availableIcons[type];
	            }
	        });
	        return icons;
	    };

	    proto.onclick = function (ecModel, api, type) {
	        var api = this.api;
	        var brushType = this._brushType;
	        var brushMode = this._brushMode;

	        if (type === 'clear') {
	            // Trigger parallel action firstly
	            api.dispatchAction({
	                type: 'axisAreaSelect',
	                intervals: []
	            });

	            api.dispatchAction({
	                type: 'brush',
	                command: 'clear',
	                // Clear all areas of all brush components.
	                areas: []
	            });
	        }
	        else {
	            api.dispatchAction({
	                type: 'takeGlobalCursor',
	                key: 'brush',
	                brushOption: {
	                    brushType: type === 'keep'
	                        ? brushType
	                        : (brushType === type ? false : type),
	                    brushMode: type === 'keep'
	                        ? (brushMode === 'multiple' ? 'single' : 'multiple')
	                        : brushMode
	                }
	            });
	        }
	    };

	    featureManager.register('brush', Brush);

	    module.exports = Brush;


/***/ },
/* 357 */
/***/ function(module, exports) {

	'use strict';


	    var features = {};

	    module.exports = {
	        register: function (name, ctor) {
	            features[name] = ctor;
	        },

	        get: function (name) {
	            return features[name];
	        }
	    };


/***/ },
/* 358 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	/**
	 * @file calendar.js
	 * @author dxh
	 */



	    __webpack_require__(359);
	    __webpack_require__(360);
	    __webpack_require__(361);




/***/ },
/* 359 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var layout = __webpack_require__(71);
	    var numberUtil = __webpack_require__(7);
	    var zrUtil = __webpack_require__(4);

	    // (24*60*60*1000)
	    var ONE_DAY = 86400000;

	    /**
	     * Calendar
	     *
	     * @constructor
	     *
	     * @param {Object} calendarModel calendarModel
	     * @param {Object} ecModel       ecModel
	     * @param {Object} api           api
	     */
	    function Calendar(calendarModel, ecModel, api) {
	        this._model = calendarModel;
	    }

	    Calendar.prototype = {

	        constructor: Calendar,

	        type: 'calendar',

	        dimensions: ['time', 'value'],

	        // Required in createListFromData
	        getDimensionsInfo: function () {
	            return [{name: 'time', type: 'time'}];
	        },

	        getRangeInfo: function () {
	            return this._rangeInfo;
	        },

	        getModel: function () {
	            return this._model;
	        },

	        getRect: function () {
	            return this._rect;
	        },

	        getCellWidth: function () {
	            return this._sw;
	        },

	        getCellHeight: function () {
	            return this._sh;
	        },

	        getOrient: function () {
	            return this._orient;
	        },

	        /**
	         * getFirstDayOfWeek
	         *
	         * @example
	         *     0 : start at Sunday
	         *     1 : start at Monday
	         *
	         * @return {number}
	         */
	        getFirstDayOfWeek: function () {
	            return this._firstDayOfWeek;
	        },

	        /**
	         * get date info
	         *
	         * @param  {string|number} date date
	         * @return {Object}      info
	         */
	        getDateInfo: function (date) {

	            date = numberUtil.parseDate(date);

	            var y = date.getFullYear();

	            var m = date.getMonth() + 1;
	            m = m < 10 ? '0' + m : m;

	            var d = date.getDate();
	            d = d < 10 ? '0' + d : d;

	            var day = date.getDay();

	            day = Math.abs((day + 7 - this.getFirstDayOfWeek()) % 7);

	            return {
	                y: y,
	                m: m,
	                d: d,
	                day: day,
	                time: date.getTime(),
	                formatedDate: y + '-' + m + '-' + d,
	                date: date
	            };
	        },

	        getNextNDay: function (date, n) {
	            n = n || 0;
	            if (n === 0) {
	                return this.getDateInfo(date);
	            }

	            var time = this.getDateInfo(date).time;

	            return this.getDateInfo(time + ONE_DAY * n);
	        },

	        update: function (ecModel, api) {

	            this._firstDayOfWeek = this._model.getModel('dayLabel').get('firstDay');
	            this._orient = this._model.get('orient');
	            this._lineWidth = this._model.getModel('itemStyle.normal').getItemStyle().lineWidth || 0;


	            this._rangeInfo = this._getRangeInfo(this._initRangeOption());
	            var weeks = this._rangeInfo.weeks || 1;
	            var whNames = ['width', 'height'];
	            var cellSize = this._model.get('cellSize').slice();
	            var layoutParams = this._model.getBoxLayoutParams();
	            var cellNumbers = this._orient === 'horizontal' ? [weeks, 7] : [7, weeks];

	            zrUtil.each([0, 1], function (idx) {
	                if (cellSizeSpecified(cellSize, idx)) {
	                    layoutParams[whNames[idx]] = cellSize[idx] * cellNumbers[idx];
	                }
	            });

	            var whGlobal = {
	                width: api.getWidth(),
	                height: api.getHeight()
	            };
	            var calendarRect = this._rect = layout.getLayoutRect(layoutParams, whGlobal);

	            zrUtil.each([0, 1], function (idx) {
	                if (!cellSizeSpecified(cellSize, idx)) {
	                    cellSize[idx] = calendarRect[whNames[idx]] / cellNumbers[idx];
	                }
	            });

	            function cellSizeSpecified(cellSize, idx) {
	                return cellSize[idx] != null && cellSize[idx] !== 'auto';
	            }

	            this._sw = cellSize[0];
	            this._sh = cellSize[1];
	        },


	        /**
	         * Convert a time data(time, value) item to (x, y) point.
	         *
	         * @override
	         * @param  {Array|number} data data
	         * @param  {boolean} [clamp=true] out of range
	         * @return {Array} point
	         */
	        dataToPoint: function (data, clamp) {
	            zrUtil.isArray(data) && (data = data[0]);
	            clamp == null && (clamp = true);

	            var dayInfo = this.getDateInfo(data);
	            var range = this._rangeInfo;
	            var date = dayInfo.formatedDate;

	            // if not in range return [NaN, NaN]
	            if (clamp && !(dayInfo.time >= range.start.time && dayInfo.time <= range.end.time)) {
	                return [NaN, NaN];
	            }

	            var week = dayInfo.day;
	            var nthWeek = this._getRangeInfo([range.start.time, date]).weeks;

	            if (this._orient === 'vertical') {
	                return [
	                    this._rect.x + week * this._sw + this._sw / 2,
	                    this._rect.y + (nthWeek - 1) * this._sh + this._sh / 2
	                ];

	            }

	            return [
	                this._rect.x + (nthWeek - 1) * this._sw + this._sw / 2,
	                this._rect.y + week * this._sh + this._sh / 2
	            ];

	        },

	        /**
	         * Convert a (x, y) point to time data
	         *
	         * @override
	         * @param  {string} point point
	         * @return {string}       data
	         */
	        pointToData: function (point) {

	            var date = this.pointToDate(point);

	            return date && date.time;
	        },

	        /**
	         * Convert a time date item to (x, y) four point.
	         *
	         * @param  {Array} data  date[0] is date
	         * @param  {boolean} [clamp=true]  out of range
	         * @return {Object}       point
	         */
	        dataToRect: function (data, clamp) {
	            var point = this.dataToPoint(data, clamp);

	            return {
	                contentShape: {
	                    x: point[0] - (this._sw - this._lineWidth) / 2,
	                    y: point[1] - (this._sh - this._lineWidth) / 2,
	                    width: this._sw - this._lineWidth,
	                    height: this._sh - this._lineWidth
	                },

	                center: point,

	                tl: [
	                    point[0] - this._sw / 2,
	                    point[1] - this._sh / 2
	                ],

	                tr: [
	                    point[0] + this._sw / 2,
	                    point[1] - this._sh / 2
	                ],

	                br: [
	                    point[0] + this._sw / 2,
	                    point[1] + this._sh / 2
	                ],

	                bl: [
	                    point[0] - this._sw / 2,
	                    point[1] + this._sh / 2
	                ]

	            };
	        },

	        /**
	         * Convert a (x, y) point to time date
	         *
	         * @param  {string} point point
	         * @return {Object}       date
	         */
	        pointToDate: function (point) {
	            var nthX = Math.floor((point[0] - this._rect.x) / this._sw) + 1;
	            var nthY = Math.floor((point[1] - this._rect.y) / this._sh) + 1;
	            var range = this._rangeInfo.range;

	            if (this._orient === 'vertical') {
	                return this._getDateByWeeksAndDay(nthY, nthX - 1, range);
	            }

	            return this._getDateByWeeksAndDay(nthX, nthY - 1, range);
	        },

	        /**
	         * @inheritDoc
	         */
	        convertToPixel: zrUtil.curry(doConvert, 'dataToPoint'),

	        /**
	         * @inheritDoc
	         */
	        convertFromPixel: zrUtil.curry(doConvert, 'pointToData'),

	        /**
	         * initRange
	         *
	         * @private
	         * @return {Array} [start, end]
	         */
	        _initRangeOption: function () {
	            var range = this._model.get('range');

	            var rg = range;

	            if (zrUtil.isArray(rg) && rg.length === 1) {
	                rg = rg[0];
	            }

	            if (/^\d{4}$/.test(rg)) {
	                range = [rg + '-01-01', rg + '-12-31'];
	            }

	            if (/^\d{4}[\/|-]\d{1,2}$/.test(rg)) {

	                var start = this.getDateInfo(rg);
	                var firstDay = start.date;
	                firstDay.setMonth(firstDay.getMonth() + 1);

	                var end = this.getNextNDay(firstDay, -1);
	                range = [start.formatedDate, end.formatedDate];
	            }

	            if (/^\d{4}[\/|-]\d{1,2}[\/|-]\d{1,2}$/.test(rg)) {
	                range = [rg, rg];
	            }

	            var tmp = this._getRangeInfo(range);

	            if (tmp.start.time > tmp.end.time) {
	                range.reverse();
	            }

	            return range;
	        },

	        /**
	         * range info
	         *
	         * @private
	         * @param  {Array} range range ['2017-01-01', '2017-07-08']
	         * @return {Object}       obj
	         */
	        _getRangeInfo: function (range) {

	            var start = this.getDateInfo(range[0]);
	            var end = this.getDateInfo(range[1]);

	            var allDay = Math.floor(end.time / ONE_DAY) - Math.floor(start.time / ONE_DAY) + 1;

	            var weeks = Math.floor((allDay + start.day + 6) / 7);

	            return {
	                range: [start.formatedDate, end.formatedDate],
	                start: start,
	                end: end,
	                allDay: allDay,
	                weeks: weeks,
	                fweek: start.day,
	                lweek: end.day
	            };
	        },

	        /**
	         * get date by nthWeeks and week day in range
	         *
	         * @private
	         * @param  {number} nthWeek the week
	         * @param  {number} day   the week day
	         * @param  {Array} range [d1, d2]
	         * @return {Object}
	         */
	        _getDateByWeeksAndDay: function (nthWeek, day, range) {
	            var rangeInfo = this._getRangeInfo(range);

	            if (nthWeek > rangeInfo.weeks
	                || (nthWeek === 0 && day < rangeInfo.fweek)
	                || (nthWeek === rangeInfo.weeks && day > rangeInfo.lweek)
	            ) {
	                return false;
	            }

	            var nthDay = (nthWeek - 1) * 7 - rangeInfo.fweek + day;

	            var time = rangeInfo.start.time + nthDay * ONE_DAY;

	            return this.getDateInfo(time);

	        }
	    };

	    Calendar.dimensions =  Calendar.prototype.dimensions;

	    Calendar.getDimensionsInfo =  Calendar.prototype.getDimensionsInfo;

	    Calendar.create = function (ecModel, api) {
	        var calendarList = [];

	        ecModel.eachComponent('calendar', function (calendarModel) {
	            var calendar = new Calendar(calendarModel, ecModel, api);
	            calendarList.push(calendar);
	            calendarModel.coordinateSystem = calendar;
	        });

	        ecModel.eachSeries(function (calendarSeries) {
	            if (calendarSeries.get('coordinateSystem') === 'calendar') {
	                // Inject coordinate system
	                calendarSeries.coordinateSystem = calendarList[calendarSeries.get('calendarIndex') || 0];
	            }
	        });
	        return calendarList;
	    };

	    function doConvert(methodName, ecModel, finder, value) {
	        var calendarModel = finder.calendarModel;
	        var seriesModel = finder.seriesModel;

	        var coordSys = calendarModel
	            ? calendarModel.coordinateSystem
	            : seriesModel
	            ? seriesModel.coordinateSystem
	            : null;

	        return coordSys === this ? coordSys[methodName](value) : null;
	    }

	    __webpack_require__(76).register('calendar', Calendar);

	    module.exports = Calendar;



/***/ },
/* 360 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var ComponentModel = __webpack_require__(69);
	    var zrUtil = __webpack_require__(4);
	    var layout = __webpack_require__(71);

	    var CalendarModel = ComponentModel.extend({

	        type: 'calendar',

	        /**
	         * @type {module:echarts/coord/calendar/Calendar}
	         */
	        coordinateSystem: null,

	        defaultOption: {
	            zlevel: 0,
	            z: 2,
	            left: 80,
	            top: 60,

	            cellSize: 20,

	            // horizontal vertical
	            orient: 'horizontal',

	            // month separate line style
	            splitLine: {
	                show: true,
	                lineStyle: {
	                    color: '#000',
	                    width: 1,
	                    type: 'solid'
	                }
	            },

	            // rect style  temporarily unused emphasis
	            itemStyle: {
	                normal: {
	                    color: '#fff',
	                    borderWidth: 1,
	                    borderColor: '#ccc'
	                }
	            },

	            // week text style
	            dayLabel: {
	                show: true,

	                // a week first day
	                firstDay: 0,

	                // start end
	                position: 'start',
	                margin: '50%', // 50% of cellSize
	                nameMap: 'en',
	                textStyle: {
	                    color: '#000'
	                }
	            },

	            // month text style
	            monthLabel: {
	                show: true,

	                // start end
	                position: 'start',
	                margin: 5,

	                // center or left
	                align: 'center',

	                // cn en []
	                nameMap: 'en',
	                formatter: null,
	                textStyle: {
	                    color: '#000'
	                }
	            },

	            // year text style
	            yearLabel: {
	                show: true,

	                // top bottom left right
	                position: null,
	                margin: 30,
	                formatter: null,
	                textStyle: {
	                    color: '#ccc',
	                    fontFamily: 'sans-serif',
	                    fontWeight: 'bolder',
	                    fontSize: 20
	                }
	            }
	        },

	        /**
	         * @override
	         */
	        init: function (option, parentModel, ecModel, extraOpt) {
	            var inputPositionParams = layout.getLayoutParams(option);

	            CalendarModel.superApply(this, 'init', arguments);

	            mergeAndNormalizeLayoutParams(option, inputPositionParams);
	        },

	        /**
	         * @override
	         */
	        mergeOption: function (option, extraOpt) {
	            CalendarModel.superApply(this, 'mergeOption', arguments);

	            mergeAndNormalizeLayoutParams(this.option, option);
	        }
	    });

	    function mergeAndNormalizeLayoutParams(target, raw) {
	        // Normalize cellSize
	        var cellSize = target.cellSize;

	        if (!zrUtil.isArray(cellSize)) {
	            cellSize = target.cellSize = [cellSize, cellSize];
	        }
	        else if (cellSize.length === 1) {
	            cellSize[1] = cellSize[0];
	        }

	        var ignoreSize = zrUtil.map([0, 1], function (hvIdx) {
	            // If user have set `width` or both `left` and `right`, cellSize
	            // will be automatically set to 'auto', otherwise the default
	            // setting of cellSize will make `width` setting not work.
	            if (layout.sizeCalculable(raw, hvIdx)) {
	                cellSize[hvIdx] = 'auto';
	            }
	            return cellSize[hvIdx] != null && cellSize[hvIdx] !== 'auto';
	        });

	        layout.mergeLayoutParam(target, raw, {
	            type: 'box', ignoreSize: ignoreSize
	        });
	    }

	    module.exports = CalendarModel;




/***/ },
/* 361 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var zrUtil = __webpack_require__(4);
	    var graphic = __webpack_require__(18);
	    var formatUtil = __webpack_require__(6);
	    var numberUtil = __webpack_require__(7);

	    var MONTH_TEXT = {
	        EN: [
	                'Jan', 'Feb', 'Mar',
	                'Apr', 'May', 'Jun',
	                'Jul', 'Aug', 'Sep',
	                'Oct', 'Nov', 'Dec'
	            ],
	        CN: [
	                '一月', '二月', '三月',
	                '四月', '五月', '六月',
	                '七月', '八月', '九月',
	                '十月', '十一月', '十二月'
	            ]
	    };

	    var WEEK_TEXT = {
	        EN: ['S', 'M', 'T', 'W', 'T', 'F', 'S'],
	        CN: ['日', '一', '二', '三', '四', '五', '六']
	    };

	    module.exports = __webpack_require__(1).extendComponentView({

	        type: 'calendar',

	        /**
	         * top/left line points
	         *  @private
	         */
	        _tlpoints: null,

	        /**
	         * bottom/right line points
	         *  @private
	         */
	        _blpoints: null,

	        /**
	         * first day of month
	         *  @private
	         */
	        _firstDayOfMonth: null,

	        /**
	         * first day point of month
	         *  @private
	         */
	        _firstDayPoints: null,

	        render: function (calendarModel, ecModel, api) {

	            var group = this.group;

	            group.removeAll();

	            var coordSys = calendarModel.coordinateSystem;

	            // range info
	            var rangeData = coordSys.getRangeInfo();
	            var orient = coordSys.getOrient();

	            this._renderDayRect(calendarModel, rangeData, group);

	            // _renderLines must be called prior to following function
	            this._renderLines(calendarModel, rangeData, orient, group);

	            this._renderYearText(calendarModel, rangeData, orient, group);

	            this._renderMonthText(calendarModel, orient, group);

	            this._renderWeekText(calendarModel, rangeData, orient, group);
	        },

	        // render day rect
	        _renderDayRect: function (calendarModel, rangeData, group) {
	            var coordSys = calendarModel.coordinateSystem;
	            var itemRectStyleModel = calendarModel.getModel('itemStyle.normal').getItemStyle();
	            var sw = coordSys.getCellWidth();
	            var sh = coordSys.getCellHeight();

	            for (var i = rangeData.start.time;
	                i <= rangeData.end.time;
	                i = coordSys.getNextNDay(i, 1).time
	            ) {

	                var point = coordSys.dataToRect([i], false).tl;

	                // every rect
	                var rect = new graphic.Rect({
	                    shape: {
	                        x: point[0],
	                        y: point[1],
	                        width: sw,
	                        height: sh
	                    },
	                    cursor: 'default',
	                    style: itemRectStyleModel
	                });

	                group.add(rect);
	            }

	        },

	        // render separate line
	        _renderLines: function (calendarModel, rangeData, orient, group) {

	            var self = this;

	            var coordSys = calendarModel.coordinateSystem;

	            var lineStyleModel = calendarModel.getModel('splitLine.lineStyle').getLineStyle();
	            var show = calendarModel.get('splitLine.show');

	            var lineWidth = lineStyleModel.lineWidth;

	            this._tlpoints = [];
	            this._blpoints = [];
	            this._firstDayOfMonth = [];
	            this._firstDayPoints = [];


	            var firstDay = rangeData.start;

	            for (var i = 0; firstDay.time <= rangeData.end.time; i++) {
	                addPoints(firstDay.formatedDate);

	                if (i === 0) {
	                    firstDay = coordSys.getDateInfo(rangeData.start.y + '-' + rangeData.start.m);
	                }

	                var date = firstDay.date;
	                date.setMonth(date.getMonth() + 1);
	                firstDay = coordSys.getDateInfo(date);
	            }

	            addPoints(coordSys.getNextNDay(rangeData.end.time, 1).formatedDate);

	            function addPoints(date) {

	                self._firstDayOfMonth.push(coordSys.getDateInfo(date));
	                self._firstDayPoints.push(coordSys.dataToRect([date], false).tl);

	                var points = self._getLinePointsOfOneWeek(calendarModel, date, orient);

	                self._tlpoints.push(points[0]);
	                self._blpoints.push(points[points.length - 1]);

	                show && self._drawSplitline(points, lineStyleModel, group);
	            }


	            // render top/left line
	            show && this._drawSplitline(self._getEdgesPoints(self._tlpoints, lineWidth, orient), lineStyleModel, group);

	            // render bottom/right line
	            show && this._drawSplitline(self._getEdgesPoints(self._blpoints, lineWidth, orient), lineStyleModel, group);

	        },

	        // get points at both ends
	        _getEdgesPoints: function (points, lineWidth, orient) {
	            var rs = [points[0].slice(), points[points.length - 1].slice()];
	            var idx = orient === 'horizontal' ? 0 : 1;

	            // both ends of the line are extend half lineWidth
	            rs[0][idx] = rs[0][idx] - lineWidth / 2;
	            rs[1][idx] = rs[1][idx] + lineWidth / 2;

	            return rs;
	        },

	        // render split line
	        _drawSplitline: function (points, lineStyleModel, group) {

	            var poyline = new graphic.Polyline({
	                z2: 20,
	                shape: {
	                    points: points
	                },
	                style: lineStyleModel
	            });

	            group.add(poyline);
	        },

	        // render month line of one week points
	        _getLinePointsOfOneWeek: function (calendarModel, date, orient) {

	            var coordSys = calendarModel.coordinateSystem;
	            date = coordSys.getDateInfo(date);

	            var points = [];

	            for (var i = 0; i < 7; i++) {

	                var tmpD = coordSys.getNextNDay(date.time, i);
	                var point = coordSys.dataToRect([tmpD.time], false);

	                points[2 * tmpD.day] = point.tl;
	                points[2 * tmpD.day + 1] = point[orient === 'horizontal' ? 'bl' : 'tr'];
	            }

	            return points;

	        },

	        _formatterLabel: function (formatter, params) {

	            if (typeof formatter === 'string' && formatter) {
	                return formatUtil.formatTplSimple(formatter, params);
	            }

	            if (typeof formatter === 'function') {
	                return formatter(params);
	            }

	            return params.nameMap;

	        },

	        _yearTextPositionControl: function (point, orient, position, margin) {

	            point = point.slice();
	            var aligns = ['center', 'bottom'];

	            if (position === 'top') {
	                point[1] -= margin;
	            }
	            if (position === 'bottom') {
	                point[1] += margin;
	                aligns = ['center', 'top'];
	            }
	            if (position === 'left') {
	                point[0] -= margin;
	            }
	            if (position === 'right') {
	                point[0] += margin;
	                aligns = ['center', 'top'];
	            }

	            var rotate = 0;
	            if (position === 'left' || position === 'right') {
	                rotate = Math.PI / 2;
	            }

	            return {
	                rotation: rotate,
	                origin: point,
	                style: {
	                    x: point[0],
	                    y: point[1],
	                    textAlign: aligns[0],
	                    textVerticalAlign: aligns[1]
	                }
	            };
	        },

	        // render year
	        _renderYearText: function (calendarModel, rangeData, orient, group) {
	            var yearLabel = calendarModel.getModel('yearLabel');

	            if (!yearLabel.get('show')) {
	                return;
	            }

	            var yearLabelStyleModel = calendarModel.getModel('yearLabel.textStyle');
	            var margin = yearLabel.get('margin');
	            var pos = yearLabel.get('position');

	            if (!pos) {
	                pos = orient !== 'horizontal' ? 'top' : 'left';
	            }

	            var points = [this._tlpoints[this._tlpoints.length - 1], this._blpoints[0]];
	            var xc = (points[0][0] + points[1][0]) / 2;
	            var yc = (points[0][1] + points[1][1]) / 2;

	            var idx = orient === 'horizontal' ? 0 : 1;


	            var posPoints = {
	                top: [xc, points[idx][1]],
	                bottom: [xc, points[1 - idx][1]],
	                left: [points[1 - idx][0], yc],
	                right: [points[idx][0], yc]
	            };

	            var name = rangeData.start.y;

	            if (+rangeData.end.y > +rangeData.start.y) {
	                name = name + '-' + rangeData.end.y;
	            }

	            var formatter = yearLabel.get('formatter');

	            var params = {
	                start: rangeData.start.y,
	                end: rangeData.end.y,
	                nameMap: name
	            };

	            var content = this._formatterLabel(formatter, params);

	            var yearText = new graphic.Text(
	                zrUtil.merge({
	                    z2: 30,
	                    style: {
	                        text: content,
	                        font: yearLabelStyleModel.getFont(),
	                        fill: yearLabelStyleModel.getTextColor()
	                    }
	                }, this._yearTextPositionControl(posPoints[pos], orient, pos, margin))
	            );

	            group.add(yearText);
	        },

	        _monthTextPositionControl: function (point, isCenter, orient, position, margin) {
	            var align = 'left';
	            var vAlign = 'top';
	            var x = point[0];
	            var y = point[1];

	            if (orient === 'horizontal') {
	                y = y + margin;

	                if (isCenter) {
	                    align = 'center';
	                }

	                if (position === 'start') {
	                    vAlign = 'bottom';
	                }
	            }
	            else {
	                x = x + margin;

	                if (isCenter) {
	                    vAlign = 'middle';
	                }

	                if (position === 'start') {
	                    align = 'right';
	                }
	            }

	            return {
	                x: x,
	                y: y,
	                textAlign: align,
	                textVerticalAlign: vAlign
	            };
	        },

	        // render month and year text
	        _renderMonthText: function (calendarModel, orient, group) {
	            var monthLabel = calendarModel.getModel('monthLabel');

	            if (!monthLabel.get('show')) {
	                return;
	            }

	            var monthLabelStyleModel = calendarModel.getModel('monthLabel.textStyle');
	            var nameMap = monthLabel.get('nameMap');
	            var margin = monthLabel.get('margin');
	            var pos = monthLabel.get('position');
	            var align = monthLabel.get('align');

	            var termPoints = [this._tlpoints, this._blpoints];

	            if (zrUtil.isString(nameMap)) {
	                nameMap = MONTH_TEXT[nameMap.toUpperCase()] || [];
	            }

	            var idx = pos === 'start' ? 0 : 1;
	            var axis = orient === 'horizontal' ? 0 : 1;
	            margin = pos === 'start' ? -margin : margin;
	            var isCenter = (align === 'center');

	            for (var i = 0; i < termPoints[idx].length - 1; i++) {

	                var tmp = termPoints[idx][i].slice();
	                var firstDay = this._firstDayOfMonth[i];

	                if (isCenter) {
	                    var firstDayPoints = this._firstDayPoints[i];
	                    tmp[axis] = (firstDayPoints[axis] + termPoints[0][i + 1][axis]) / 2;
	                }

	                var formatter = monthLabel.get('formatter');
	                var name = nameMap[+firstDay.m - 1];
	                var params = {
	                    yyyy: firstDay.y,
	                    yy: (firstDay.y + '').slice(2),
	                    MM: firstDay.m,
	                    M: +firstDay.m,
	                    nameMap: name
	                };

	                var content = this._formatterLabel(formatter, params);

	                var monthText = new graphic.Text({
	                    z2: 30,
	                    style: zrUtil.extend({
	                        text: content,
	                        font: monthLabelStyleModel.getFont(),
	                        fill: monthLabelStyleModel.getTextColor()
	                    }, this._monthTextPositionControl(tmp, isCenter, orient, pos, margin))
	                });

	                group.add(monthText);
	            }
	        },

	        _weekTextPositionControl: function (point, orient, position, margin, cellSize) {
	            var align = 'center';
	            var vAlign = 'middle';
	            var x = point[0];
	            var y = point[1];
	            var isStart = position === 'start';

	            if (orient === 'horizontal') {
	                x = x + margin + (isStart ? 1 : -1) * cellSize[0] / 2;
	                align = isStart ? 'right' : 'left';
	            }
	            else {
	                y = y + margin + (isStart ? 1 : -1) * cellSize[1] / 2;
	                vAlign = isStart ? 'bottom' : 'top';
	            }

	            return {
	                x: x,
	                y: y,
	                textAlign: align,
	                textVerticalAlign: vAlign
	            };
	        },

	        // render weeks
	        _renderWeekText: function (calendarModel, rangeData, orient, group) {
	            var dayLabel = calendarModel.getModel('dayLabel');

	            if (!dayLabel.get('show')) {
	                return;
	            }

	            var coordSys = calendarModel.coordinateSystem;
	            var dayLabelStyleModel = calendarModel.getModel('dayLabel.textStyle');
	            var pos = dayLabel.get('position');
	            var nameMap = dayLabel.get('nameMap');
	            var margin = dayLabel.get('margin');
	            var firstDayOfWeek = coordSys.getFirstDayOfWeek();

	            if (zrUtil.isString(nameMap)) {
	                nameMap = WEEK_TEXT[nameMap.toUpperCase()] || [];
	            }

	            var start = coordSys.getNextNDay(
	                rangeData.end.time, (7 - rangeData.lweek)
	            ).time;

	            var cellSize = [coordSys.getCellWidth(), coordSys.getCellHeight()];
	            margin = numberUtil.parsePercent(margin, cellSize[orient === 'horizontal' ? 0 : 1]);

	            if (pos === 'start') {
	                start = coordSys.getNextNDay(
	                    rangeData.start.time, -(7 + rangeData.fweek)
	                ).time;
	                margin = -margin;
	            }

	            for (var i = 0; i < 7; i++) {

	                var tmpD = coordSys.getNextNDay(start, i);
	                var point = coordSys.dataToRect([tmpD.time], false).center;
	                var day = i;
	                day = Math.abs((i + firstDayOfWeek) % 7);
	                var weekText = new graphic.Text({
	                    z2: 30,
	                    style: zrUtil.extend({
	                        text: nameMap[day],
	                        font: dayLabelStyleModel.getFont(),
	                        fill: dayLabelStyleModel.getTextColor()
	                    }, this._weekTextPositionControl(point, orient, pos, margin, cellSize))
	                });
	                group.add(weekText);
	            }
	        }
	    });



/***/ },
/* 362 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var echarts = __webpack_require__(1);
	    var graphic = __webpack_require__(18);
	    var layout = __webpack_require__(71);

	    // Model
	    echarts.extendComponentModel({

	        type: 'title',

	        layoutMode: {type: 'box', ignoreSize: true},

	        defaultOption: {
	            // 一级层叠
	            zlevel: 0,
	            // 二级层叠
	            z: 6,
	            show: true,

	            text: '',
	            // 超链接跳转
	            // link: null,
	            // 仅支持self | blank
	            target: 'blank',
	            subtext: '',

	            // 超链接跳转
	            // sublink: null,
	            // 仅支持self | blank
	            subtarget: 'blank',

	            // 'center' ¦ 'left' ¦ 'right'
	            // ¦ {number}（x坐标，单位px）
	            left: 0,
	            // 'top' ¦ 'bottom' ¦ 'center'
	            // ¦ {number}（y坐标，单位px）
	            top: 0,

	            // 水平对齐
	            // 'auto' | 'left' | 'right' | 'center'
	            // 默认根据 left 的位置判断是左对齐还是右对齐
	            // textAlign: null
	            //
	            // 垂直对齐
	            // 'auto' | 'top' | 'bottom' | 'middle'
	            // 默认根据 top 位置判断是上对齐还是下对齐
	            // textBaseline: null

	            backgroundColor: 'rgba(0,0,0,0)',

	            // 标题边框颜色
	            borderColor: '#ccc',

	            // 标题边框线宽，单位px，默认为0（无边框）
	            borderWidth: 0,

	            // 标题内边距，单位px，默认各方向内边距为5，
	            // 接受数组分别设定上右下左边距，同css
	            padding: 5,

	            // 主副标题纵向间隔，单位px，默认为10，
	            itemGap: 10,
	            textStyle: {
	                fontSize: 18,
	                fontWeight: 'bolder',
	                color: '#333'
	            },
	            subtextStyle: {
	                color: '#aaa'
	            }
	        }
	    });

	    // View
	    echarts.extendComponentView({

	        type: 'title',

	        render: function (titleModel, ecModel, api) {
	            this.group.removeAll();

	            if (!titleModel.get('show')) {
	                return;
	            }

	            var group = this.group;

	            var textStyleModel = titleModel.getModel('textStyle');
	            var subtextStyleModel = titleModel.getModel('subtextStyle');

	            var textAlign = titleModel.get('textAlign');
	            var textBaseline = titleModel.get('textBaseline');

	            var textEl = new graphic.Text({
	                style: {
	                    text: titleModel.get('text'),
	                    textFont: textStyleModel.getFont(),
	                    fill: textStyleModel.getTextColor()
	                },
	                z2: 10
	            });

	            var textRect = textEl.getBoundingRect();

	            var subText = titleModel.get('subtext');
	            var subTextEl = new graphic.Text({
	                style: {
	                    text: subText,
	                    textFont: subtextStyleModel.getFont(),
	                    fill: subtextStyleModel.getTextColor(),
	                    y: textRect.height + titleModel.get('itemGap'),
	                    textBaseline: 'top'
	                },
	                z2: 10
	            });

	            var link = titleModel.get('link');
	            var sublink = titleModel.get('sublink');

	            textEl.silent = !link;
	            subTextEl.silent = !sublink;

	            if (link) {
	                textEl.on('click', function () {
	                    window.open(link, '_' + titleModel.get('target'));
	                });
	            }
	            if (sublink) {
	                subTextEl.on('click', function () {
	                    window.open(sublink, '_' + titleModel.get('subtarget'));
	                });
	            }

	            group.add(textEl);
	            subText && group.add(subTextEl);
	            // If no subText, but add subTextEl, there will be an empty line.

	            var groupRect = group.getBoundingRect();
	            var layoutOption = titleModel.getBoxLayoutParams();
	            layoutOption.width = groupRect.width;
	            layoutOption.height = groupRect.height;
	            var layoutRect = layout.getLayoutRect(
	                layoutOption, {
	                    width: api.getWidth(),
	                    height: api.getHeight()
	                }, titleModel.get('padding')
	            );
	            // Adjust text align based on position
	            if (!textAlign) {
	                // Align left if title is on the left. center and right is same
	                textAlign = titleModel.get('left') || titleModel.get('right');
	                if (textAlign === 'middle') {
	                    textAlign = 'center';
	                }
	                // Adjust layout by text align
	                if (textAlign === 'right') {
	                    layoutRect.x += layoutRect.width;
	                }
	                else if (textAlign === 'center') {
	                    layoutRect.x += layoutRect.width / 2;
	                }
	            }
	            if (!textBaseline) {
	                textBaseline = titleModel.get('top') || titleModel.get('bottom');
	                if (textBaseline === 'center') {
	                    textBaseline = 'middle';
	                }
	                if (textBaseline === 'bottom') {
	                    layoutRect.y += layoutRect.height;
	                }
	                else if (textBaseline === 'middle') {
	                    layoutRect.y += layoutRect.height / 2;
	                }

	                textBaseline = textBaseline || 'top';
	            }

	            group.attr('position', [layoutRect.x, layoutRect.y]);
	            var alignStyle = {
	                textAlign: textAlign,
	                textVerticalAlign: textBaseline
	            };
	            textEl.setStyle(alignStyle);
	            subTextEl.setStyle(alignStyle);

	            // Render background
	            // Get groupRect again because textAlign has been changed
	            groupRect = group.getBoundingRect();
	            var padding = layoutRect.margin;
	            var style = titleModel.getItemStyle(['color', 'opacity']);
	            style.fill = titleModel.get('backgroundColor');
	            var rect = new graphic.Rect({
	                shape: {
	                    x: groupRect.x - padding[3],
	                    y: groupRect.y - padding[0],
	                    width: groupRect.width + padding[1] + padding[3],
	                    height: groupRect.height + padding[0] + padding[2]
	                },
	                style: style,
	                silent: true
	            });
	            graphic.subPixelOptimizeRect(rect);

	            group.add(rect);
	        }
	    });


/***/ },
/* 363 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * DataZoom component entry
	 */


	    __webpack_require__(364);

	    __webpack_require__(365);
	    __webpack_require__(368);

	    __webpack_require__(369);
	    __webpack_require__(370);

	    __webpack_require__(371);
	    __webpack_require__(372);

	    __webpack_require__(374);
	    __webpack_require__(375);



/***/ },
/* 364 */
/***/ function(module, exports, __webpack_require__) {

	

	    __webpack_require__(69).registerSubTypeDefaulter('dataZoom', function (option) {
	        // Default 'slider' when no type specified.
	        return 'slider';
	    });



/***/ },
/* 365 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @file Data zoom model
	 */


	    var zrUtil = __webpack_require__(4);
	    var env = __webpack_require__(2);
	    var echarts = __webpack_require__(1);
	    var modelUtil = __webpack_require__(5);
	    var helper = __webpack_require__(366);
	    var AxisProxy = __webpack_require__(367);
	    var each = zrUtil.each;
	    var eachAxisDim = helper.eachAxisDim;

	    var DataZoomModel = echarts.extendComponentModel({

	        type: 'dataZoom',

	        dependencies: [
	            'xAxis', 'yAxis', 'zAxis', 'radiusAxis', 'angleAxis', 'singleAxis', 'series'
	        ],

	        /**
	         * @protected
	         */
	        defaultOption: {
	            zlevel: 0,
	            z: 4,                   // Higher than normal component (z: 2).
	            orient: null,           // Default auto by axisIndex. Possible value: 'horizontal', 'vertical'.
	            xAxisIndex: null,       // Default the first horizontal category axis.
	            yAxisIndex: null,       // Default the first vertical category axis.

	            filterMode: 'filter',   // Possible values: 'filter' or 'empty' or 'weakFilter'.
	                                    // 'filter': data items which are out of window will be removed. This option is
	                                    //          applicable when filtering outliers. For each data item, it will be
	                                    //          filtered if one of the relevant dimensions is out of the window.
	                                    // 'weakFilter': data items which are out of window will be removed. This option
	                                    //          is applicable when filtering outliers. For each data item, it will be
	                                    //          filtered only if all  of the relevant dimensions are out of the same
	                                    //          side of the window.
	                                    // 'empty': data items which are out of window will be set to empty.
	                                    //          This option is applicable when user should not neglect
	                                    //          that there are some data items out of window.
	                                    // 'none': Do not filter.
	                                    // Taking line chart as an example, line will be broken in
	                                    // the filtered points when filterModel is set to 'empty', but
	                                    // be connected when set to 'filter'.

	            throttle: null,         // Dispatch action by the fixed rate, avoid frequency.
	                                    // default 100. Do not throttle when use null/undefined.
	                                    // If animation === true and animationDurationUpdate > 0,
	                                    // default value is 100, otherwise 20.
	            start: 0,               // Start percent. 0 ~ 100
	            end: 100,               // End percent. 0 ~ 100
	            startValue: null,       // Start value. If startValue specified, start is ignored.
	            endValue: null,         // End value. If endValue specified, end is ignored.
	            minSpan: null,          // 0 ~ 100
	            maxSpan: null,          // 0 ~ 100
	            minValueSpan: null,     // The range of dataZoom can not be smaller than that.
	            maxValueSpan: null      // The range of dataZoom can not be larger than that.
	        },

	        /**
	         * @override
	         */
	        init: function (option, parentModel, ecModel) {

	            /**
	             * key like x_0, y_1
	             * @private
	             * @type {Object}
	             */
	            this._dataIntervalByAxis = {};

	            /**
	             * @private
	             */
	            this._dataInfo = {};

	            /**
	             * key like x_0, y_1
	             * @private
	             */
	            this._axisProxies = {};

	            /**
	             * @readOnly
	             */
	            this.textStyleModel;

	            /**
	             * @private
	             */
	            this._autoThrottle = true;

	            /**
	             * 'percent' or 'value'
	             * @private
	             */
	            this._rangePropMode = ['percent', 'percent'];

	            var rawOption = retrieveRaw(option);

	            this.mergeDefaultAndTheme(option, ecModel);

	            this.doInit(rawOption);
	        },

	        /**
	         * @override
	         */
	        mergeOption: function (newOption) {
	            var rawOption = retrieveRaw(newOption);

	            //FIX #2591
	            zrUtil.merge(this.option, newOption, true);

	            this.doInit(rawOption);
	        },

	        /**
	         * @protected
	         */
	        doInit: function (rawOption) {
	            var thisOption = this.option;

	            // Disable realtime view update if canvas is not supported.
	            if (!env.canvasSupported) {
	                thisOption.realtime = false;
	            }

	            this._setDefaultThrottle(rawOption);

	            updateRangeUse(this, rawOption);

	            each([['start', 'startValue'], ['end', 'endValue']], function (names, index) {
	                // start/end has higher priority over startValue/endValue if they
	                // both set, but we should make chart.setOption({endValue: 1000})
	                // effective, rather than chart.setOption({endValue: 1000, end: null}).
	                if (this._rangePropMode[index] === 'value') {
	                    thisOption[names[0]] = null;
	                }
	                // Otherwise do nothing and use the merge result.
	            }, this);

	            this.textStyleModel = this.getModel('textStyle');

	            this._resetTarget();

	            this._giveAxisProxies();
	        },

	        /**
	         * @private
	         */
	        _giveAxisProxies: function () {
	            var axisProxies = this._axisProxies;

	            this.eachTargetAxis(function (dimNames, axisIndex, dataZoomModel, ecModel) {
	                var axisModel = this.dependentModels[dimNames.axis][axisIndex];

	                // If exists, share axisProxy with other dataZoomModels.
	                var axisProxy = axisModel.__dzAxisProxy || (
	                    // Use the first dataZoomModel as the main model of axisProxy.
	                    axisModel.__dzAxisProxy = new AxisProxy(
	                        dimNames.name, axisIndex, this, ecModel
	                    )
	                );
	                // FIXME
	                // dispose __dzAxisProxy

	                axisProxies[dimNames.name + '_' + axisIndex] = axisProxy;
	            }, this);
	        },

	        /**
	         * @private
	         */
	        _resetTarget: function () {
	            var thisOption = this.option;

	            var autoMode = this._judgeAutoMode();

	            eachAxisDim(function (dimNames) {
	                var axisIndexName = dimNames.axisIndex;
	                thisOption[axisIndexName] = modelUtil.normalizeToArray(
	                    thisOption[axisIndexName]
	                );
	            }, this);

	            if (autoMode === 'axisIndex') {
	                this._autoSetAxisIndex();
	            }
	            else if (autoMode === 'orient') {
	                this._autoSetOrient();
	            }
	        },

	        /**
	         * @private
	         */
	        _judgeAutoMode: function () {
	            // Auto set only works for setOption at the first time.
	            // The following is user's reponsibility. So using merged
	            // option is OK.
	            var thisOption = this.option;

	            var hasIndexSpecified = false;
	            eachAxisDim(function (dimNames) {
	                // When user set axisIndex as a empty array, we think that user specify axisIndex
	                // but do not want use auto mode. Because empty array may be encountered when
	                // some error occured.
	                if (thisOption[dimNames.axisIndex] != null) {
	                    hasIndexSpecified = true;
	                }
	            }, this);

	            var orient = thisOption.orient;

	            if (orient == null && hasIndexSpecified) {
	                return 'orient';
	            }
	            else if (!hasIndexSpecified) {
	                if (orient == null) {
	                    thisOption.orient = 'horizontal';
	                }
	                return 'axisIndex';
	            }
	        },

	        /**
	         * @private
	         */
	        _autoSetAxisIndex: function () {
	            var autoAxisIndex = true;
	            var orient = this.get('orient', true);
	            var thisOption = this.option;
	            var dependentModels = this.dependentModels;

	            if (autoAxisIndex) {
	                // Find axis that parallel to dataZoom as default.
	                var dimName = orient === 'vertical' ? 'y' : 'x';

	                if (dependentModels[dimName + 'Axis'].length) {
	                    thisOption[dimName + 'AxisIndex'] = [0];
	                    autoAxisIndex = false;
	                }
	                else {
	                    each(dependentModels.singleAxis, function (singleAxisModel) {
	                        if (autoAxisIndex && singleAxisModel.get('orient', true) === orient) {
	                            thisOption.singleAxisIndex = [singleAxisModel.componentIndex];
	                            autoAxisIndex = false;
	                        }
	                    });
	                }
	            }

	            if (autoAxisIndex) {
	                // Find the first category axis as default. (consider polar)
	                eachAxisDim(function (dimNames) {
	                    if (!autoAxisIndex) {
	                        return;
	                    }
	                    var axisIndices = [];
	                    var axisModels = this.dependentModels[dimNames.axis];
	                    if (axisModels.length && !axisIndices.length) {
	                        for (var i = 0, len = axisModels.length; i < len; i++) {
	                            if (axisModels[i].get('type') === 'category') {
	                                axisIndices.push(i);
	                            }
	                        }
	                    }
	                    thisOption[dimNames.axisIndex] = axisIndices;
	                    if (axisIndices.length) {
	                        autoAxisIndex = false;
	                    }
	                }, this);
	            }

	            if (autoAxisIndex) {
	                // FIXME
	                // 这里是兼容ec2的写法（没指定xAxisIndex和yAxisIndex时把scatter和双数值轴折柱纳入dataZoom控制），
	                // 但是实际是否需要Grid.js#getScaleByOption来判断（考虑time，log等axis type）？

	                // If both dataZoom.xAxisIndex and dataZoom.yAxisIndex is not specified,
	                // dataZoom component auto adopts series that reference to
	                // both xAxis and yAxis which type is 'value'.
	                this.ecModel.eachSeries(function (seriesModel) {
	                    if (this._isSeriesHasAllAxesTypeOf(seriesModel, 'value')) {
	                        eachAxisDim(function (dimNames) {
	                            var axisIndices = thisOption[dimNames.axisIndex];

	                            var axisIndex = seriesModel.get(dimNames.axisIndex);
	                            var axisId = seriesModel.get(dimNames.axisId);

	                            var axisModel = seriesModel.ecModel.queryComponents({
	                                mainType: dimNames.axis,
	                                index: axisIndex,
	                                id: axisId
	                            })[0];

	                            if (true) {
	                                if (!axisModel) {
	                                    throw new Error(
	                                        dimNames.axis + ' "' + zrUtil.retrieve(
	                                            axisIndex,
	                                            axisId,
	                                            0
	                                        ) + '" not found'
	                                    );
	                                }
	                            }
	                            axisIndex = axisModel.componentIndex;

	                            if (zrUtil.indexOf(axisIndices, axisIndex) < 0) {
	                                axisIndices.push(axisIndex);
	                            }
	                        });
	                    }
	                }, this);
	            }
	        },

	        /**
	         * @private
	         */
	        _autoSetOrient: function () {
	            var dim;

	            // Find the first axis
	            this.eachTargetAxis(function (dimNames) {
	                !dim && (dim = dimNames.name);
	            }, this);

	            this.option.orient = dim === 'y' ? 'vertical' : 'horizontal';
	        },

	        /**
	         * @private
	         */
	        _isSeriesHasAllAxesTypeOf: function (seriesModel, axisType) {
	            // FIXME
	            // 需要series的xAxisIndex和yAxisIndex都首先自动设置上。
	            // 例如series.type === scatter时。

	            var is = true;
	            eachAxisDim(function (dimNames) {
	                var seriesAxisIndex = seriesModel.get(dimNames.axisIndex);
	                var axisModel = this.dependentModels[dimNames.axis][seriesAxisIndex];

	                if (!axisModel || axisModel.get('type') !== axisType) {
	                    is = false;
	                }
	            }, this);
	            return is;
	        },

	        /**
	         * @private
	         */
	        _setDefaultThrottle: function (rawOption) {
	            // When first time user set throttle, auto throttle ends.
	            if (rawOption.hasOwnProperty('throttle')) {
	                this._autoThrottle = false;
	            }
	            if (this._autoThrottle) {
	                var globalOption = this.ecModel.option;
	                this.option.throttle =
	                    (globalOption.animation && globalOption.animationDurationUpdate > 0)
	                    ? 100 : 20;
	            }
	        },

	        /**
	         * @public
	         */
	        getFirstTargetAxisModel: function () {
	            var firstAxisModel;
	            eachAxisDim(function (dimNames) {
	                if (firstAxisModel == null) {
	                    var indices = this.get(dimNames.axisIndex);
	                    if (indices.length) {
	                        firstAxisModel = this.dependentModels[dimNames.axis][indices[0]];
	                    }
	                }
	            }, this);

	            return firstAxisModel;
	        },

	        /**
	         * @public
	         * @param {Function} callback param: axisModel, dimNames, axisIndex, dataZoomModel, ecModel
	         */
	        eachTargetAxis: function (callback, context) {
	            var ecModel = this.ecModel;
	            eachAxisDim(function (dimNames) {
	                each(
	                    this.get(dimNames.axisIndex),
	                    function (axisIndex) {
	                        callback.call(context, dimNames, axisIndex, this, ecModel);
	                    },
	                    this
	                );
	            }, this);
	        },

	        /**
	         * @param {string} dimName
	         * @param {number} axisIndex
	         * @return {module:echarts/component/dataZoom/AxisProxy} If not found, return null/undefined.
	         */
	        getAxisProxy: function (dimName, axisIndex) {
	            return this._axisProxies[dimName + '_' + axisIndex];
	        },

	        /**
	         * @param {string} dimName
	         * @param {number} axisIndex
	         * @return {module:echarts/model/Model} If not found, return null/undefined.
	         */
	        getAxisModel: function (dimName, axisIndex) {
	            var axisProxy = this.getAxisProxy(dimName, axisIndex);
	            return axisProxy && axisProxy.getAxisModel();
	        },

	        /**
	         * If not specified, set to undefined.
	         *
	         * @public
	         * @param {Object} opt
	         * @param {number} [opt.start]
	         * @param {number} [opt.end]
	         * @param {number} [opt.startValue]
	         * @param {number} [opt.endValue]
	         * @param {boolean} [ignoreUpdateRangeUsg=false]
	         */
	        setRawRange: function (opt, ignoreUpdateRangeUsg) {
	            each(['start', 'end', 'startValue', 'endValue'], function (name) {
	                // If any of those prop is null/undefined, we should alos set
	                // them, because only one pair between start/end and
	                // startValue/endValue can work.
	                this.option[name] = opt[name];
	            }, this);

	            !ignoreUpdateRangeUsg && updateRangeUse(this, opt);
	        },

	        /**
	         * @public
	         * @return {Array.<number>} [startPercent, endPercent]
	         */
	        getPercentRange: function () {
	            var axisProxy = this.findRepresentativeAxisProxy();
	            if (axisProxy) {
	                return axisProxy.getDataPercentWindow();
	            }
	        },

	        /**
	         * @public
	         * For example, chart.getModel().getComponent('dataZoom').getValueRange('y', 0);
	         *
	         * @param {string} [axisDimName]
	         * @param {number} [axisIndex]
	         * @return {Array.<number>} [startValue, endValue] value can only be '-' or finite number.
	         */
	        getValueRange: function (axisDimName, axisIndex) {
	            if (axisDimName == null && axisIndex == null) {
	                var axisProxy = this.findRepresentativeAxisProxy();
	                if (axisProxy) {
	                    return axisProxy.getDataValueWindow();
	                }
	            }
	            else {
	                return this.getAxisProxy(axisDimName, axisIndex).getDataValueWindow();
	            }
	        },

	        /**
	         * @public
	         * @param {module:echarts/model/Model} [axisModel] If axisModel given, find axisProxy
	         *      corresponding to the axisModel
	         * @return {module:echarts/component/dataZoom/AxisProxy}
	         */
	        findRepresentativeAxisProxy: function (axisModel) {
	            if (axisModel) {
	                return axisModel.__dzAxisProxy;
	            }

	            // Find the first hosted axisProxy
	            var axisProxies = this._axisProxies;
	            for (var key in axisProxies) {
	                if (axisProxies.hasOwnProperty(key) && axisProxies[key].hostedBy(this)) {
	                    return axisProxies[key];
	                }
	            }

	            // If no hosted axis find not hosted axisProxy.
	            // Consider this case: dataZoomModel1 and dataZoomModel2 control the same axis,
	            // and the option.start or option.end settings are different. The percentRange
	            // should follow axisProxy.
	            // (We encounter this problem in toolbox data zoom.)
	            for (var key in axisProxies) {
	                if (axisProxies.hasOwnProperty(key) && !axisProxies[key].hostedBy(this)) {
	                    return axisProxies[key];
	                }
	            }
	        },

	        /**
	         * @return {Array.<string>}
	         */
	        getRangePropMode: function () {
	            return this._rangePropMode.slice();
	        }
	    });

	    function retrieveRaw(option) {
	        var ret = {};
	        each(
	            ['start', 'end', 'startValue', 'endValue', 'throttle'],
	            function (name) {
	                option.hasOwnProperty(name) && (ret[name] = option[name]);
	            }
	        );
	        return ret;
	    }

	    function updateRangeUse(dataZoomModel, rawOption) {
	        each([['start', 'startValue'], ['end', 'endValue']], function (names, index) {
	            var rangePropMode = dataZoomModel._rangePropMode;
	            if (rawOption[names[0]] != null) {
	                rangePropMode[index] = 'percent';
	            }
	            else if (rawOption[names[1]] != null) {
	                rangePropMode[index] = 'value';
	            }
	            // else remain its original setting.
	        });
	    }

	    module.exports = DataZoomModel;



/***/ },
/* 366 */
/***/ function(module, exports, __webpack_require__) {

	
	    var formatUtil = __webpack_require__(6);
	    var zrUtil = __webpack_require__(4);

	    var helper = {};

	    var AXIS_DIMS = ['x', 'y', 'z', 'radius', 'angle', 'single'];
	    // Supported coords.
	    var COORDS = ['cartesian2d', 'polar', 'singleAxis'];

	    /**
	     * @param {string} coordType
	     * @return {boolean}
	     */
	    helper.isCoordSupported = function (coordType) {
	        return zrUtil.indexOf(COORDS, coordType) >= 0;
	    };

	    /**
	     * Create "each" method to iterate names.
	     *
	     * @pubilc
	     * @param  {Array.<string>} names
	     * @param  {Array.<string>=} attrs
	     * @return {Function}
	     */
	    helper.createNameEach = function (names, attrs) {
	        names = names.slice();
	        var capitalNames = zrUtil.map(names, formatUtil.capitalFirst);
	        attrs = (attrs || []).slice();
	        var capitalAttrs = zrUtil.map(attrs, formatUtil.capitalFirst);

	        return function (callback, context) {
	            zrUtil.each(names, function (name, index) {
	                var nameObj = {name: name, capital: capitalNames[index]};

	                for (var j = 0; j < attrs.length; j++) {
	                    nameObj[attrs[j]] = name + capitalAttrs[j];
	                }

	                callback.call(context, nameObj);
	            });
	        };
	    };

	    /**
	     * Iterate each dimension name.
	     *
	     * @public
	     * @param {Function} callback The parameter is like:
	     *                            {
	     *                                name: 'angle',
	     *                                capital: 'Angle',
	     *                                axis: 'angleAxis',
	     *                                axisIndex: 'angleAixs',
	     *                                index: 'angleIndex'
	     *                            }
	     * @param {Object} context
	     */
	    helper.eachAxisDim = helper.createNameEach(AXIS_DIMS, ['axisIndex', 'axis', 'index', 'id']);

	    /**
	     * If tow dataZoomModels has the same axis controlled, we say that they are 'linked'.
	     * dataZoomModels and 'links' make up one or more graphics.
	     * This function finds the graphic where the source dataZoomModel is in.
	     *
	     * @public
	     * @param {Function} forEachNode Node iterator.
	     * @param {Function} forEachEdgeType edgeType iterator
	     * @param {Function} edgeIdGetter Giving node and edgeType, return an array of edge id.
	     * @return {Function} Input: sourceNode, Output: Like {nodes: [], dims: {}}
	     */
	    helper.createLinkedNodesFinder = function (forEachNode, forEachEdgeType, edgeIdGetter) {

	        return function (sourceNode) {
	            var result = {
	                nodes: [],
	                records: {} // key: edgeType.name, value: Object (key: edge id, value: boolean).
	            };

	            forEachEdgeType(function (edgeType) {
	                result.records[edgeType.name] = {};
	            });

	            if (!sourceNode) {
	                return result;
	            }

	            absorb(sourceNode, result);

	            var existsLink;
	            do {
	                existsLink = false;
	                forEachNode(processSingleNode);
	            }
	            while (existsLink);

	            function processSingleNode(node) {
	                if (!isNodeAbsorded(node, result) && isLinked(node, result)) {
	                    absorb(node, result);
	                    existsLink = true;
	                }
	            }

	            return result;
	        };

	        function isNodeAbsorded(node, result) {
	            return zrUtil.indexOf(result.nodes, node) >= 0;
	        }

	        function isLinked(node, result) {
	            var hasLink = false;
	            forEachEdgeType(function (edgeType) {
	                zrUtil.each(edgeIdGetter(node, edgeType) || [], function (edgeId) {
	                    result.records[edgeType.name][edgeId] && (hasLink = true);
	                });
	            });
	            return hasLink;
	        }

	        function absorb(node, result) {
	            result.nodes.push(node);
	            forEachEdgeType(function (edgeType) {
	                zrUtil.each(edgeIdGetter(node, edgeType) || [], function (edgeId) {
	                    result.records[edgeType.name][edgeId] = true;
	                });
	            });
	        }
	    };

	    module.exports = helper;


/***/ },
/* 367 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @file Axis operator
	 */


	    var zrUtil = __webpack_require__(4);
	    var numberUtil = __webpack_require__(7);
	    var helper = __webpack_require__(366);
	    var each = zrUtil.each;
	    var asc = numberUtil.asc;

	    /**
	     * Operate single axis.
	     * One axis can only operated by one axis operator.
	     * Different dataZoomModels may be defined to operate the same axis.
	     * (i.e. 'inside' data zoom and 'slider' data zoom components)
	     * So dataZoomModels share one axisProxy in that case.
	     *
	     * @class
	     */
	    var AxisProxy = function (dimName, axisIndex, dataZoomModel, ecModel) {

	        /**
	         * @private
	         * @type {string}
	         */
	        this._dimName = dimName;

	        /**
	         * @private
	         */
	        this._axisIndex = axisIndex;

	        /**
	         * @private
	         * @type {Array.<number>}
	         */
	        this._valueWindow;

	        /**
	         * @private
	         * @type {Array.<number>}
	         */
	        this._percentWindow;

	        /**
	         * @private
	         * @type {Array.<number>}
	         */
	        this._dataExtent;

	        /**
	         * {minSpan, maxSpan, minValueSpan, maxValueSpan}
	         * @private
	         * @type {Object}
	         */
	        this._minMaxSpan;

	        /**
	         * @readOnly
	         * @type {module: echarts/model/Global}
	         */
	        this.ecModel = ecModel;

	        /**
	         * @private
	         * @type {module: echarts/component/dataZoom/DataZoomModel}
	         */
	        this._dataZoomModel = dataZoomModel;
	    };

	    AxisProxy.prototype = {

	        constructor: AxisProxy,

	        /**
	         * Whether the axisProxy is hosted by dataZoomModel.
	         *
	         * @public
	         * @param {module: echarts/component/dataZoom/DataZoomModel} dataZoomModel
	         * @return {boolean}
	         */
	        hostedBy: function (dataZoomModel) {
	            return this._dataZoomModel === dataZoomModel;
	        },

	        /**
	         * @return {Array.<number>} Value can only be NaN or finite value.
	         */
	        getDataValueWindow: function () {
	            return this._valueWindow.slice();
	        },

	        /**
	         * @return {Array.<number>}
	         */
	        getDataPercentWindow: function () {
	            return this._percentWindow.slice();
	        },

	        /**
	         * @public
	         * @param {number} axisIndex
	         * @return {Array} seriesModels
	         */
	        getTargetSeriesModels: function () {
	            var seriesModels = [];
	            var ecModel = this.ecModel;

	            ecModel.eachSeries(function (seriesModel) {
	                if (helper.isCoordSupported(seriesModel.get('coordinateSystem'))) {
	                    var dimName = this._dimName;
	                    var axisModel = ecModel.queryComponents({
	                        mainType: dimName + 'Axis',
	                        index: seriesModel.get(dimName + 'AxisIndex'),
	                        id: seriesModel.get(dimName + 'AxisId')
	                    })[0];
	                    if (this._axisIndex === (axisModel && axisModel.componentIndex)) {
	                        seriesModels.push(seriesModel);
	                    }
	                }
	            }, this);

	            return seriesModels;
	        },

	        getAxisModel: function () {
	            return this.ecModel.getComponent(this._dimName + 'Axis', this._axisIndex);
	        },

	        getOtherAxisModel: function () {
	            var axisDim = this._dimName;
	            var ecModel = this.ecModel;
	            var axisModel = this.getAxisModel();
	            var isCartesian = axisDim === 'x' || axisDim === 'y';
	            var otherAxisDim;
	            var coordSysIndexName;
	            if (isCartesian) {
	                coordSysIndexName = 'gridIndex';
	                otherAxisDim = axisDim === 'x' ? 'y' : 'x';
	            }
	            else {
	                coordSysIndexName = 'polarIndex';
	                otherAxisDim = axisDim === 'angle' ? 'radius' : 'angle';
	            }
	            var foundOtherAxisModel;
	            ecModel.eachComponent(otherAxisDim + 'Axis', function (otherAxisModel) {
	                if ((otherAxisModel.get(coordSysIndexName) || 0)
	                    === (axisModel.get(coordSysIndexName) || 0)
	                ) {
	                    foundOtherAxisModel = otherAxisModel;
	                }
	            });
	            return foundOtherAxisModel;
	        },

	        getMinMaxSpan: function () {
	            return zrUtil.clone(this._minMaxSpan);
	        },

	        /**
	         * Only calculate by given range and this._dataExtent, do not change anything.
	         *
	         * @param {Object} opt
	         * @param {number} [opt.start]
	         * @param {number} [opt.end]
	         * @param {number} [opt.startValue]
	         * @param {number} [opt.endValue]
	         */
	        calculateDataWindow: function (opt) {
	            var dataExtent = this._dataExtent;
	            var axisModel = this.getAxisModel();
	            var scale = axisModel.axis.scale;
	            var rangePropMode = this._dataZoomModel.getRangePropMode();
	            var percentExtent = [0, 100];
	            var percentWindow = [
	                opt.start,
	                opt.end
	            ];
	            var valueWindow = [];

	            each(['startValue', 'endValue'], function (prop) {
	                valueWindow.push(opt[prop] != null ? scale.parse(opt[prop]) : null);
	            });

	            // Normalize bound.
	            each([0, 1], function (idx) {
	                var boundValue = valueWindow[idx];
	                var boundPercent = percentWindow[idx];

	                // Notice: dataZoom is based either on `percentProp` ('start', 'end') or
	                // on `valueProp` ('startValue', 'endValue'). The former one is suitable
	                // for cases that a dataZoom component controls multiple axes with different
	                // unit or extent, and the latter one is suitable for accurate zoom by pixel
	                // (e.g., in dataZoomSelect). `valueProp` can be calculated from `percentProp`,
	                // but it is awkward that `percentProp` can not be obtained from `valueProp`
	                // accurately (because all of values that are overflow the `dataExtent` will
	                // be calculated to percent '100%'). So we have to use
	                // `dataZoom.getRangePropMode()` to mark which prop is used.
	                // `rangePropMode` is updated only when setOption or dispatchAction, otherwise
	                // it remains its original value.

	                if (rangePropMode[idx] === 'percent') {
	                    if (boundPercent == null) {
	                        boundPercent = percentExtent[idx];
	                    }
	                    // Use scale.parse to math round for category or time axis.
	                    boundValue = scale.parse(numberUtil.linearMap(
	                        boundPercent, percentExtent, dataExtent, true
	                    ));
	                }
	                else {
	                    // Calculating `percent` from `value` may be not accurate, because
	                    // This calculation can not be inversed, because all of values that
	                    // are overflow the `dataExtent` will be calculated to percent '100%'
	                    boundPercent = numberUtil.linearMap(
	                        boundValue, dataExtent, percentExtent, true
	                    );
	                }

	                // valueWindow[idx] = round(boundValue);
	                // percentWindow[idx] = round(boundPercent);
	                valueWindow[idx] = boundValue;
	                percentWindow[idx] = boundPercent;
	            });

	            return {
	                valueWindow: asc(valueWindow),
	                percentWindow: asc(percentWindow)
	            };
	        },

	        /**
	         * Notice: reset should not be called before series.restoreData() called,
	         * so it is recommanded to be called in "process stage" but not "model init
	         * stage".
	         *
	         * @param {module: echarts/component/dataZoom/DataZoomModel} dataZoomModel
	         */
	        reset: function (dataZoomModel) {
	            if (dataZoomModel !== this._dataZoomModel) {
	                return;
	            }

	            // Culculate data window and data extent, and record them.
	            this._dataExtent = calculateDataExtent(
	                this, this._dimName, this.getTargetSeriesModels()
	            );

	            var dataWindow = this.calculateDataWindow(dataZoomModel.option);

	            this._valueWindow = dataWindow.valueWindow;
	            this._percentWindow = dataWindow.percentWindow;

	            setMinMaxSpan(this);

	            // Update axis setting then.
	            setAxisModel(this);
	        },

	        /**
	         * @param {module: echarts/component/dataZoom/DataZoomModel} dataZoomModel
	         */
	        restore: function (dataZoomModel) {
	            if (dataZoomModel !== this._dataZoomModel) {
	                return;
	            }

	            this._valueWindow = this._percentWindow = null;
	            setAxisModel(this, true);
	        },

	        /**
	         * @param {module: echarts/component/dataZoom/DataZoomModel} dataZoomModel
	         */
	        filterData: function (dataZoomModel) {
	            if (dataZoomModel !== this._dataZoomModel) {
	                return;
	            }

	            var axisDim = this._dimName;
	            var seriesModels = this.getTargetSeriesModels();
	            var filterMode = dataZoomModel.get('filterMode');
	            var valueWindow = this._valueWindow;

	            if (filterMode === 'none') {
	                return;
	            }

	            // FIXME
	            // Toolbox may has dataZoom injected. And if there are stacked bar chart
	            // with NaN data, NaN will be filtered and stack will be wrong.
	            // So we need to force the mode to be set empty.
	            // In fect, it is not a big deal that do not support filterMode-'filter'
	            // when using toolbox#dataZoom, utill tooltip#dataZoom support "single axis
	            // selection" some day, which might need "adapt to data extent on the
	            // otherAxis", which is disabled by filterMode-'empty'.
	            var otherAxisModel = this.getOtherAxisModel();
	            if (dataZoomModel.get('$fromToolbox')
	                && otherAxisModel
	                && otherAxisModel.get('type') === 'category'
	            ) {
	                filterMode = 'empty';
	            }

	            // Process series data
	            each(seriesModels, function (seriesModel) {
	                var seriesData = seriesModel.getData();
	                var dataDims = seriesModel.coordDimToDataDim(axisDim);

	                if (filterMode === 'weakFilter') {
	                    seriesData && seriesData.filterSelf(function (dataIndex) {
	                        var leftOut;
	                        var rightOut;
	                        var hasValue;
	                        for (var i = 0; i < dataDims.length; i++) {
	                            var value = seriesData.get(dataDims[i], dataIndex);
	                            var thisHasValue = !isNaN(value);
	                            var thisLeftOut = value < valueWindow[0];
	                            var thisRightOut = value > valueWindow[1];
	                            if (thisHasValue && !thisLeftOut && !thisRightOut) {
	                                return true;
	                            }
	                            thisHasValue && (hasValue = true);
	                            thisLeftOut && (leftOut = true);
	                            thisRightOut && (rightOut = true);
	                        }
	                        // If both left out and right out, do not filter.
	                        return hasValue && leftOut && rightOut;
	                    });
	                }
	                else {
	                    seriesData && each(dataDims, function (dim) {
	                        if (filterMode === 'empty') {
	                            seriesModel.setData(
	                                seriesData.map(dim, function (value) {
	                                    return !isInWindow(value) ? NaN : value;
	                                })
	                            );
	                        }
	                        else {
	                            seriesData.filterSelf(dim, isInWindow);
	                        }
	                    });
	                }
	            });

	            function isInWindow(value) {
	                return value >= valueWindow[0] && value <= valueWindow[1];
	            }
	        }
	    };

	    function calculateDataExtent(axisProxy, axisDim, seriesModels) {
	        var dataExtent = [Infinity, -Infinity];

	        each(seriesModels, function (seriesModel) {
	            var seriesData = seriesModel.getData();
	            if (seriesData) {
	                each(seriesModel.coordDimToDataDim(axisDim), function (dim) {
	                    var seriesExtent = seriesData.getDataExtent(dim);
	                    seriesExtent[0] < dataExtent[0] && (dataExtent[0] = seriesExtent[0]);
	                    seriesExtent[1] > dataExtent[1] && (dataExtent[1] = seriesExtent[1]);
	                });
	            }
	        });

	        if (dataExtent[1] < dataExtent[0]) {
	            dataExtent = [NaN, NaN];
	        }

	        // It is important to get "consistent" extent when more then one axes is
	        // controlled by a `dataZoom`, otherwise those axes will not be synchronized
	        // when zooming. But it is difficult to know what is "consistent", considering
	        // axes have different type or even different meanings (For example, two
	        // time axes are used to compare data of the same date in different years).
	        // So basically dataZoom just obtains extent by series.data (in category axis
	        // extent can be obtained from axis.data).
	        // Nevertheless, user can set min/max/scale on axes to make extent of axes
	        // consistent.
	        fixExtentByAxis(axisProxy, dataExtent);

	        return dataExtent;
	    }

	    function fixExtentByAxis(axisProxy, dataExtent) {
	        var axisModel = axisProxy.getAxisModel();
	        var min = axisModel.getMin(true);

	        // For category axis, if min/max/scale are not set, extent is determined
	        // by axis.data by default.
	        var isCategoryAxis = axisModel.get('type') === 'category';
	        var axisDataLen = isCategoryAxis && (axisModel.get('data') || []).length;

	        if (min != null && min !== 'dataMin') {
	            dataExtent[0] = min;
	        }
	        else if (isCategoryAxis) {
	            dataExtent[0] = axisDataLen > 0 ? 0 : NaN;
	        }

	        var max = axisModel.getMax(true);
	        if (max != null && max !== 'dataMax') {
	            dataExtent[1] = max;
	        }
	        else if (isCategoryAxis) {
	            dataExtent[1] = axisDataLen > 0 ? axisDataLen - 1 : NaN;
	        }

	        if (!axisModel.get('scale', true)) {
	            dataExtent[0] > 0 && (dataExtent[0] = 0);
	            dataExtent[1] < 0 && (dataExtent[1] = 0);
	        }

	        // For value axis, if min/max/scale are not set, we just use the extent obtained
	        // by series data, which may be a little different from the extent calculated by
	        // `axisHelper.getScaleExtent`. But the different just affects the experience a
	        // little when zooming. So it will not be fixed until some users require it strongly.

	        return dataExtent;
	    }

	    function setAxisModel(axisProxy, isRestore) {
	        var axisModel = axisProxy.getAxisModel();

	        var percentWindow = axisProxy._percentWindow;
	        var valueWindow = axisProxy._valueWindow;

	        if (!percentWindow) {
	            return;
	        }

	        // [0, 500]: arbitrary value, guess axis extent.
	        var precision = numberUtil.getPixelPrecision(valueWindow, [0, 500]);
	        // isRestore or isFull
	        var useOrigin = isRestore || (percentWindow[0] === 0 && percentWindow[1] === 100);

	        axisModel.setRange(
	            useOrigin ? null : +valueWindow[0].toFixed(precision),
	            useOrigin ? null : +valueWindow[1].toFixed(precision)
	        );
	    }

	    function setMinMaxSpan(axisProxy) {
	        var minMaxSpan = axisProxy._minMaxSpan = {};
	        var dataZoomModel = axisProxy._dataZoomModel;

	        each(['min', 'max'], function (minMax) {
	            minMaxSpan[minMax + 'Span'] = dataZoomModel.get(minMax + 'Span');

	            // minValueSpan and maxValueSpan has higher priority than minSpan and maxSpan
	            var valueSpan = dataZoomModel.get(minMax + 'ValueSpan');
	            if (valueSpan != null) {
	                minMaxSpan[minMax + 'ValueSpan'] = valueSpan;

	                valueSpan = axisProxy.getAxisModel().axis.scale.parse(valueSpan);
	                if (valueSpan != null) {
	                    minMaxSpan[minMax + 'Span'] = numberUtil.linearMap(
	                        valueSpan, axisProxy._dataExtent, [0, 100], true
	                    );
	                }
	            }
	        });
	    }

	    module.exports = AxisProxy;



/***/ },
/* 368 */
/***/ function(module, exports, __webpack_require__) {

	

	    var ComponentView = __webpack_require__(79);

	    module.exports = ComponentView.extend({

	        type: 'dataZoom',

	        render: function (dataZoomModel, ecModel, api, payload) {
	            this.dataZoomModel = dataZoomModel;
	            this.ecModel = ecModel;
	            this.api = api;
	        },

	        /**
	         * Find the first target coordinate system.
	         *
	         * @protected
	         * @return {Object} {
	         *                   grid: [
	         *                       {model: coord0, axisModels: [axis1, axis3], coordIndex: 1},
	         *                       {model: coord1, axisModels: [axis0, axis2], coordIndex: 0},
	         *                       ...
	         *                   ],  // cartesians must not be null/undefined.
	         *                   polar: [
	         *                       {model: coord0, axisModels: [axis4], coordIndex: 0},
	         *                       ...
	         *                   ],  // polars must not be null/undefined.
	         *                   singleAxis: [
	         *                       {model: coord0, axisModels: [], coordIndex: 0}
	         *                   ]
	         */
	        getTargetCoordInfo: function () {
	            var dataZoomModel = this.dataZoomModel;
	            var ecModel = this.ecModel;
	            var coordSysLists = {};

	            dataZoomModel.eachTargetAxis(function (dimNames, axisIndex) {
	                var axisModel = ecModel.getComponent(dimNames.axis, axisIndex);
	                if (axisModel) {
	                    var coordModel = axisModel.getCoordSysModel();
	                    coordModel && save(
	                        coordModel,
	                        axisModel,
	                        coordSysLists[coordModel.mainType] || (coordSysLists[coordModel.mainType] = []),
	                        coordModel.componentIndex
	                    );
	                }
	            }, this);

	            function save(coordModel, axisModel, store, coordIndex) {
	                var item;
	                for (var i = 0; i < store.length; i++) {
	                    if (store[i].model === coordModel) {
	                        item = store[i];
	                        break;
	                    }
	                }
	                if (!item) {
	                    store.push(item = {
	                        model: coordModel, axisModels: [], coordIndex: coordIndex
	                    });
	                }
	                item.axisModels.push(axisModel);
	            }

	            return coordSysLists;
	        }

	    });



/***/ },
/* 369 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @file Data zoom model
	 */


	    var DataZoomModel = __webpack_require__(365);

	    var SliderZoomModel = DataZoomModel.extend({

	        type: 'dataZoom.slider',

	        layoutMode: 'box',

	        /**
	         * @protected
	         */
	        defaultOption: {
	            show: true,

	            // ph => placeholder. Using placehoder here because
	            // deault value can only be drived in view stage.
	            right: 'ph',  // Default align to grid rect.
	            top: 'ph',    // Default align to grid rect.
	            width: 'ph',  // Default align to grid rect.
	            height: 'ph', // Default align to grid rect.
	            left: null,   // Default align to grid rect.
	            bottom: null, // Default align to grid rect.

	            backgroundColor: 'rgba(47,69,84,0)',    // Background of slider zoom component.
	            // dataBackgroundColor: '#ddd',         // Background coor of data shadow and border of box,
	                                                    // highest priority, remain for compatibility of
	                                                    // previous version, but not recommended any more.
	            dataBackground: {
	                lineStyle: {
	                    color: '#2f4554',
	                    width: 0.5,
	                    opacity: 0.3
	                },
	                areaStyle: {
	                    color: 'rgba(47,69,84,0.3)',
	                    opacity: 0.3
	                }
	            },
	            borderColor: '#ddd',                    // border color of the box. For compatibility,
	                                                    // if dataBackgroundColor is set, borderColor
	                                                    // is ignored.

	            fillerColor: 'rgba(167,183,204,0.4)',     // Color of selected area.
	            // handleColor: 'rgba(89,170,216,0.95)',     // Color of handle.
	            // handleIcon: 'path://M4.9,17.8c0-1.4,4.5-10.5,5.5-12.4c0-0.1,0.6-1.1,0.9-1.1c0.4,0,0.9,1,0.9,1.1c1.1,2.2,5.4,11,5.4,12.4v17.8c0,1.5-0.6,2.1-1.3,2.1H6.1c-0.7,0-1.3-0.6-1.3-2.1V17.8z',
	            handleIcon: 'M8.2,13.6V3.9H6.3v9.7H3.1v14.9h3.3v9.7h1.8v-9.7h3.3V13.6H8.2z M9.7,24.4H4.8v-1.4h4.9V24.4z M9.7,19.1H4.8v-1.4h4.9V19.1z',
	            // Percent of the slider height
	            handleSize: '100%',

	            handleStyle: {
	                color: '#a7b7cc'
	            },

	            labelPrecision: null,
	            labelFormatter: null,
	            showDetail: true,
	            showDataShadow: 'auto',                 // Default auto decision.
	            realtime: true,
	            zoomLock: false,                        // Whether disable zoom.
	            textStyle: {
	                color: '#333'
	            }
	        }

	    });

	    module.exports = SliderZoomModel;



/***/ },
/* 370 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);
	    var graphic = __webpack_require__(18);
	    var throttle = __webpack_require__(81);
	    var DataZoomView = __webpack_require__(368);
	    var Rect = graphic.Rect;
	    var numberUtil = __webpack_require__(7);
	    var linearMap = numberUtil.linearMap;
	    var layout = __webpack_require__(71);
	    var sliderMove = __webpack_require__(239);
	    var eventTool = __webpack_require__(88);

	    var asc = numberUtil.asc;
	    var bind = zrUtil.bind;
	    // var mathMax = Math.max;
	    var each = zrUtil.each;

	    // Constants
	    var DEFAULT_LOCATION_EDGE_GAP = 7;
	    var DEFAULT_FRAME_BORDER_WIDTH = 1;
	    var DEFAULT_FILLER_SIZE = 30;
	    var HORIZONTAL = 'horizontal';
	    var VERTICAL = 'vertical';
	    var LABEL_GAP = 5;
	    var SHOW_DATA_SHADOW_SERIES_TYPE = ['line', 'bar', 'candlestick', 'scatter'];

	    var SliderZoomView = DataZoomView.extend({

	        type: 'dataZoom.slider',

	        init: function (ecModel, api) {

	            /**
	             * @private
	             * @type {Object}
	             */
	            this._displayables = {};

	            /**
	             * @private
	             * @type {string}
	             */
	            this._orient;

	            /**
	             * [0, 100]
	             * @private
	             */
	            this._range;

	            /**
	             * [coord of the first handle, coord of the second handle]
	             * @private
	             */
	            this._handleEnds;

	            /**
	             * [length, thick]
	             * @private
	             * @type {Array.<number>}
	             */
	            this._size;

	            /**
	             * @private
	             * @type {number}
	             */
	            this._handleWidth;

	            /**
	             * @private
	             * @type {number}
	             */
	            this._handleHeight;

	            /**
	             * @private
	             */
	            this._location;

	            /**
	             * @private
	             */
	            this._dragging;

	            /**
	             * @private
	             */
	            this._dataShadowInfo;

	            this.api = api;
	        },

	        /**
	         * @override
	         */
	        render: function (dataZoomModel, ecModel, api, payload) {
	            SliderZoomView.superApply(this, 'render', arguments);

	            throttle.createOrUpdate(
	                this,
	                '_dispatchZoomAction',
	                this.dataZoomModel.get('throttle'),
	                'fixRate'
	            );

	            this._orient = dataZoomModel.get('orient');

	            if (this.dataZoomModel.get('show') === false) {
	                this.group.removeAll();
	                return;
	            }

	            // Notice: this._resetInterval() should not be executed when payload.type
	            // is 'dataZoom', origin this._range should be maintained, otherwise 'pan'
	            // or 'zoom' info will be missed because of 'throttle' of this.dispatchAction,
	            if (!payload || payload.type !== 'dataZoom' || payload.from !== this.uid) {
	                this._buildView();
	            }

	            this._updateView();
	        },

	        /**
	         * @override
	         */
	        remove: function () {
	            SliderZoomView.superApply(this, 'remove', arguments);
	            throttle.clear(this, '_dispatchZoomAction');
	        },

	        /**
	         * @override
	         */
	        dispose: function () {
	            SliderZoomView.superApply(this, 'dispose', arguments);
	            throttle.clear(this, '_dispatchZoomAction');
	        },

	        _buildView: function () {
	            var thisGroup = this.group;

	            thisGroup.removeAll();

	            this._resetLocation();
	            this._resetInterval();

	            var barGroup = this._displayables.barGroup = new graphic.Group();

	            this._renderBackground();

	            this._renderHandle();

	            this._renderDataShadow();

	            thisGroup.add(barGroup);

	            this._positionGroup();
	        },

	        /**
	         * @private
	         */
	        _resetLocation: function () {
	            var dataZoomModel = this.dataZoomModel;
	            var api = this.api;

	            // If some of x/y/width/height are not specified,
	            // auto-adapt according to target grid.
	            var coordRect = this._findCoordRect();
	            var ecSize = {width: api.getWidth(), height: api.getHeight()};
	            // Default align by coordinate system rect.
	            var positionInfo = this._orient === HORIZONTAL
	                ? {
	                    // Why using 'right', because right should be used in vertical,
	                    // and it is better to be consistent for dealing with position param merge.
	                    right: ecSize.width - coordRect.x - coordRect.width,
	                    top: (ecSize.height - DEFAULT_FILLER_SIZE - DEFAULT_LOCATION_EDGE_GAP),
	                    width: coordRect.width,
	                    height: DEFAULT_FILLER_SIZE
	                }
	                : { // vertical
	                    right: DEFAULT_LOCATION_EDGE_GAP,
	                    top: coordRect.y,
	                    width: DEFAULT_FILLER_SIZE,
	                    height: coordRect.height
	                };

	            // Do not write back to option and replace value 'ph', because
	            // the 'ph' value should be recalculated when resize.
	            var layoutParams = layout.getLayoutParams(dataZoomModel.option);

	            // Replace the placeholder value.
	            zrUtil.each(['right', 'top', 'width', 'height'], function (name) {
	                if (layoutParams[name] === 'ph') {
	                    layoutParams[name] = positionInfo[name];
	                }
	            });

	            var layoutRect = layout.getLayoutRect(
	                layoutParams,
	                ecSize,
	                dataZoomModel.padding
	            );

	            this._location = {x: layoutRect.x, y: layoutRect.y};
	            this._size = [layoutRect.width, layoutRect.height];
	            this._orient === VERTICAL && this._size.reverse();
	        },

	        /**
	         * @private
	         */
	        _positionGroup: function () {
	            var thisGroup = this.group;
	            var location = this._location;
	            var orient = this._orient;

	            // Just use the first axis to determine mapping.
	            var targetAxisModel = this.dataZoomModel.getFirstTargetAxisModel();
	            var inverse = targetAxisModel && targetAxisModel.get('inverse');

	            var barGroup = this._displayables.barGroup;
	            var otherAxisInverse = (this._dataShadowInfo || {}).otherAxisInverse;

	            // Transform barGroup.
	            barGroup.attr(
	                (orient === HORIZONTAL && !inverse)
	                ? {scale: otherAxisInverse ? [1, 1] : [1, -1]}
	                : (orient === HORIZONTAL && inverse)
	                ? {scale: otherAxisInverse ? [-1, 1] : [-1, -1]}
	                : (orient === VERTICAL && !inverse)
	                ? {scale: otherAxisInverse ? [1, -1] : [1, 1], rotation: Math.PI / 2}
	                // Dont use Math.PI, considering shadow direction.
	                : {scale: otherAxisInverse ? [-1, -1] : [-1, 1], rotation: Math.PI / 2}
	            );

	            // Position barGroup
	            var rect = thisGroup.getBoundingRect([barGroup]);
	            thisGroup.attr('position', [location.x - rect.x, location.y - rect.y]);
	        },

	        /**
	         * @private
	         */
	        _getViewExtent: function () {
	            return [0, this._size[0]];
	        },

	        _renderBackground: function () {
	            var dataZoomModel = this.dataZoomModel;
	            var size = this._size;
	            var barGroup = this._displayables.barGroup;

	            barGroup.add(new Rect({
	                silent: true,
	                shape: {
	                    x: 0, y: 0, width: size[0], height: size[1]
	                },
	                style: {
	                    fill: dataZoomModel.get('backgroundColor')
	                },
	                z2: -40
	            }));

	            // Click panel, over shadow, below handles.
	            barGroup.add(new Rect({
	                shape: {
	                    x: 0, y: 0, width: size[0], height: size[1]
	                },
	                style: {
	                    fill: 'transparent'
	                },
	                z2: 0,
	                onclick: zrUtil.bind(this._onClickPanelClick, this)
	            }));
	        },

	        _renderDataShadow: function () {
	            var info = this._dataShadowInfo = this._prepareDataShadowInfo();

	            if (!info) {
	                return;
	            }

	            var size = this._size;
	            var seriesModel = info.series;
	            var data = seriesModel.getRawData();
	            var otherDim = seriesModel.getShadowDim
	                ? seriesModel.getShadowDim() // @see candlestick
	                : info.otherDim;

	            if (otherDim == null) {
	                return;
	            }

	            var otherDataExtent = data.getDataExtent(otherDim);
	            // Nice extent.
	            var otherOffset = (otherDataExtent[1] - otherDataExtent[0]) * 0.3;
	            otherDataExtent = [
	                otherDataExtent[0] - otherOffset,
	                otherDataExtent[1] + otherOffset
	            ];
	            var otherShadowExtent = [0, size[1]];

	            var thisShadowExtent = [0, size[0]];

	            var areaPoints = [[size[0], 0], [0, 0]];
	            var linePoints = [];
	            var step = thisShadowExtent[1] / (data.count() - 1);
	            var thisCoord = 0;

	            // Optimize for large data shadow
	            var stride = Math.round(data.count() / size[0]);
	            var lastIsEmpty;
	            data.each([otherDim], function (value, index) {
	                if (stride > 0 && (index % stride)) {
	                    thisCoord += step;
	                    return;
	                }

	                // FIXME
	                // Should consider axis.min/axis.max when drawing dataShadow.

	                // FIXME
	                // 应该使用统一的空判断？还是在list里进行空判断？
	                var isEmpty = value == null || isNaN(value) || value === '';
	                // See #4235.
	                var otherCoord = isEmpty
	                    ? 0 : linearMap(value, otherDataExtent, otherShadowExtent, true);

	                // Attempt to draw data shadow precisely when there are empty value.
	                if (isEmpty && !lastIsEmpty && index) {
	                    areaPoints.push([areaPoints[areaPoints.length - 1][0], 0]);
	                    linePoints.push([linePoints[linePoints.length - 1][0], 0]);
	                }
	                else if (!isEmpty && lastIsEmpty) {
	                    areaPoints.push([thisCoord, 0]);
	                    linePoints.push([thisCoord, 0]);
	                }

	                areaPoints.push([thisCoord, otherCoord]);
	                linePoints.push([thisCoord, otherCoord]);

	                thisCoord += step;
	                lastIsEmpty = isEmpty;
	            });

	            var dataZoomModel = this.dataZoomModel;
	            // var dataBackgroundModel = dataZoomModel.getModel('dataBackground');
	            this._displayables.barGroup.add(new graphic.Polygon({
	                shape: {points: areaPoints},
	                style: zrUtil.defaults(
	                    {fill: dataZoomModel.get('dataBackgroundColor')},
	                    dataZoomModel.getModel('dataBackground.areaStyle').getAreaStyle()
	                ),
	                silent: true,
	                z2: -20
	            }));
	            this._displayables.barGroup.add(new graphic.Polyline({
	                shape: {points: linePoints},
	                style: dataZoomModel.getModel('dataBackground.lineStyle').getLineStyle(),
	                silent: true,
	                z2: -19
	            }));
	        },

	        _prepareDataShadowInfo: function () {
	            var dataZoomModel = this.dataZoomModel;
	            var showDataShadow = dataZoomModel.get('showDataShadow');

	            if (showDataShadow === false) {
	                return;
	            }

	            // Find a representative series.
	            var result;
	            var ecModel = this.ecModel;

	            dataZoomModel.eachTargetAxis(function (dimNames, axisIndex) {
	                var seriesModels = dataZoomModel
	                    .getAxisProxy(dimNames.name, axisIndex)
	                    .getTargetSeriesModels();

	                zrUtil.each(seriesModels, function (seriesModel) {
	                    if (result) {
	                        return;
	                    }

	                    if (showDataShadow !== true && zrUtil.indexOf(
	                            SHOW_DATA_SHADOW_SERIES_TYPE, seriesModel.get('type')
	                        ) < 0
	                    ) {
	                        return;
	                    }

	                    var thisAxis = ecModel.getComponent(dimNames.axis, axisIndex).axis;
	                    var otherDim = getOtherDim(dimNames.name);
	                    var otherAxisInverse;
	                    var coordSys = seriesModel.coordinateSystem;
	                    if (otherDim != null && coordSys.getOtherAxis) {
	                        otherAxisInverse = coordSys.getOtherAxis(thisAxis).inverse;
	                    }

	                    result = {
	                        thisAxis: thisAxis,
	                        series: seriesModel,
	                        thisDim: dimNames.name,
	                        otherDim: otherDim,
	                        otherAxisInverse: otherAxisInverse
	                    };

	                }, this);

	            }, this);

	            return result;
	        },

	        _renderHandle: function () {
	            var displaybles = this._displayables;
	            var handles = displaybles.handles = [];
	            var handleLabels = displaybles.handleLabels = [];
	            var barGroup = this._displayables.barGroup;
	            var size = this._size;
	            var dataZoomModel = this.dataZoomModel;

	            barGroup.add(displaybles.filler = new Rect({
	                draggable: true,
	                cursor: 'move',
	                drift: bind(this._onDragMove, this, 'all'),
	                onmousemove: function (e) {
	                    // Fot mobile devicem, prevent screen slider on the button.
	                    eventTool.stop(e.event);
	                },
	                ondragstart: bind(this._showDataInfo, this, true),
	                ondragend: bind(this._onDragEnd, this),
	                onmouseover: bind(this._showDataInfo, this, true),
	                onmouseout: bind(this._showDataInfo, this, false),
	                style: {
	                    fill: dataZoomModel.get('fillerColor'),
	                    textPosition : 'inside'
	                }
	            }));

	            // Frame border.
	            barGroup.add(new Rect(graphic.subPixelOptimizeRect({
	                silent: true,
	                shape: {
	                    x: 0,
	                    y: 0,
	                    width: size[0],
	                    height: size[1]
	                },
	                style: {
	                    stroke: dataZoomModel.get('dataBackgroundColor')
	                        || dataZoomModel.get('borderColor'),
	                    lineWidth: DEFAULT_FRAME_BORDER_WIDTH,
	                    fill: 'rgba(0,0,0,0)'
	                }
	            })));

	            var iconStr = dataZoomModel.get('handleIcon');
	            each([0, 1], function (handleIndex) {
	                var iconOpt = {
	                    style: {
	                        strokeNoScale: true
	                    },
	                    rectHover: true,
	                    cursor: this._orient === 'vertical' ? 'ns-resize' : 'ew-resize',
	                    draggable: true,
	                    drift: bind(this._onDragMove, this, handleIndex),
	                    onmousemove: function (e) {
	                        // Fot mobile devicem, prevent screen slider on the button.
	                        eventTool.stop(e.event);
	                    },
	                    ondragend: bind(this._onDragEnd, this),
	                    onmouseover: bind(this._showDataInfo, this, true),
	                    onmouseout: bind(this._showDataInfo, this, false)
	                };
	                var iconStyle = {x: -1, y: 0, width: 2, height: 2};

	                var path = iconStr.indexOf('image://') === 0
	                    ? (
	                        iconStyle.image = iconStr.slice(8),
	                        iconOpt.style = iconStyle,
	                        new graphic.Image(iconOpt)
	                    )
	                    : graphic.makePath(
	                        iconStr.replace('path://', ''),
	                        iconOpt,
	                        iconStyle,
	                        'center'
	                    );

	                var bRect = path.getBoundingRect();
	                this._handleHeight = numberUtil.parsePercent(dataZoomModel.get('handleSize'), this._size[1]);
	                this._handleWidth = bRect.width / bRect.height * this._handleHeight;

	                path.setStyle(dataZoomModel.getModel('handleStyle').getItemStyle());
	                var handleColor = dataZoomModel.get('handleColor');
	                // Compatitable with previous version
	                if (handleColor != null) {
	                    path.style.fill = handleColor;
	                }

	                barGroup.add(handles[handleIndex] = path);

	                var textStyleModel = dataZoomModel.textStyleModel;

	                this.group.add(
	                    handleLabels[handleIndex] = new graphic.Text({
	                    silent: true,
	                    invisible: true,
	                    style: {
	                        x: 0, y: 0, text: '',
	                        textVerticalAlign: 'middle',
	                        textAlign: 'center',
	                        fill: textStyleModel.getTextColor(),
	                        textFont: textStyleModel.getFont()
	                    },
	                    z2: 10
	                }));

	            }, this);
	        },

	        /**
	         * @private
	         */
	        _resetInterval: function () {
	            var range = this._range = this.dataZoomModel.getPercentRange();
	            var viewExtent = this._getViewExtent();

	            this._handleEnds = [
	                linearMap(range[0], [0, 100], viewExtent, true),
	                linearMap(range[1], [0, 100], viewExtent, true)
	            ];
	        },

	        /**
	         * @private
	         * @param {(number|string)} handleIndex 0 or 1 or 'all'
	         * @param {number} delta
	         */
	        _updateInterval: function (handleIndex, delta) {
	            var dataZoomModel = this.dataZoomModel;
	            var handleEnds = this._handleEnds;
	            var viewExtend = this._getViewExtent();
	            var minMaxSpan = dataZoomModel.findRepresentativeAxisProxy().getMinMaxSpan();
	            var percentExtent = [0, 100];

	            sliderMove(
	                delta,
	                handleEnds,
	                viewExtend,
	                dataZoomModel.get('zoomLock') ? 'all' : handleIndex,
	                minMaxSpan.minSpan != null
	                    ? linearMap(minMaxSpan.minSpan, percentExtent, viewExtend, true) : null,
	                minMaxSpan.maxSpan != null
	                    ? linearMap(minMaxSpan.maxSpan, percentExtent, viewExtend, true) : null
	            );

	            this._range = asc([
	                linearMap(handleEnds[0], viewExtend, percentExtent, true),
	                linearMap(handleEnds[1], viewExtend, percentExtent, true)
	            ]);
	        },

	        /**
	         * @private
	         */
	        _updateView: function (nonRealtime) {
	            var displaybles = this._displayables;
	            var handleEnds = this._handleEnds;
	            var handleInterval = asc(handleEnds.slice());
	            var size = this._size;

	            each([0, 1], function (handleIndex) {
	                // Handles
	                var handle = displaybles.handles[handleIndex];
	                var handleHeight = this._handleHeight;
	                handle.attr({
	                    scale: [handleHeight / 2, handleHeight / 2],
	                    position: [handleEnds[handleIndex], size[1] / 2 - handleHeight / 2]
	                });
	            }, this);

	            // Filler
	            displaybles.filler.setShape({
	                x: handleInterval[0],
	                y: 0,
	                width: handleInterval[1] - handleInterval[0],
	                height: size[1]
	            });

	            this._updateDataInfo(nonRealtime);
	        },

	        /**
	         * @private
	         */
	        _updateDataInfo: function (nonRealtime) {
	            var dataZoomModel = this.dataZoomModel;
	            var displaybles = this._displayables;
	            var handleLabels = displaybles.handleLabels;
	            var orient = this._orient;
	            var labelTexts = ['', ''];

	            // FIXME
	            // date型，支持formatter，autoformatter（ec2 date.getAutoFormatter）
	            if (dataZoomModel.get('showDetail')) {
	                var axisProxy = dataZoomModel.findRepresentativeAxisProxy();

	                if (axisProxy) {
	                    var axis = axisProxy.getAxisModel().axis;
	                    var range = this._range;

	                    var dataInterval = nonRealtime
	                        // See #4434, data and axis are not processed and reset yet in non-realtime mode.
	                        ? axisProxy.calculateDataWindow({
	                            start: range[0], end: range[1]
	                        }).valueWindow
	                        : axisProxy.getDataValueWindow();

	                    labelTexts = [
	                        this._formatLabel(dataInterval[0], axis),
	                        this._formatLabel(dataInterval[1], axis)
	                    ];
	                }
	            }

	            var orderedHandleEnds = asc(this._handleEnds.slice());

	            setLabel.call(this, 0);
	            setLabel.call(this, 1);

	            function setLabel(handleIndex) {
	                // Label
	                // Text should not transform by barGroup.
	                // Ignore handlers transform
	                var barTransform = graphic.getTransform(
	                    displaybles.handles[handleIndex].parent, this.group
	                );
	                var direction = graphic.transformDirection(
	                    handleIndex === 0 ? 'right' : 'left', barTransform
	                );
	                var offset = this._handleWidth / 2 + LABEL_GAP;
	                var textPoint = graphic.applyTransform(
	                    [
	                        orderedHandleEnds[handleIndex] + (handleIndex === 0 ? -offset : offset),
	                        this._size[1] / 2
	                    ],
	                    barTransform
	                );
	                handleLabels[handleIndex].setStyle({
	                    x: textPoint[0],
	                    y: textPoint[1],
	                    textVerticalAlign: orient === HORIZONTAL ? 'middle' : direction,
	                    textAlign: orient === HORIZONTAL ? direction : 'center',
	                    text: labelTexts[handleIndex]
	                });
	            }
	        },

	        /**
	         * @private
	         */
	        _formatLabel: function (value, axis) {
	            var dataZoomModel = this.dataZoomModel;
	            var labelFormatter = dataZoomModel.get('labelFormatter');

	            var labelPrecision = dataZoomModel.get('labelPrecision');
	            if (labelPrecision == null || labelPrecision === 'auto') {
	                labelPrecision = axis.getPixelPrecision();
	            }

	            var valueStr = (value == null || isNaN(value))
	                ? ''
	                // FIXME Glue code
	                : (axis.type === 'category' || axis.type === 'time')
	                    ? axis.scale.getLabel(Math.round(value))
	                    // param of toFixed should less then 20.
	                    : value.toFixed(Math.min(labelPrecision, 20));

	            return zrUtil.isFunction(labelFormatter)
	                ? labelFormatter(value, valueStr)
	                : zrUtil.isString(labelFormatter)
	                ? labelFormatter.replace('{value}', valueStr)
	                : valueStr;
	        },

	        /**
	         * @private
	         * @param {boolean} showOrHide true: show, false: hide
	         */
	        _showDataInfo: function (showOrHide) {
	            // Always show when drgging.
	            showOrHide = this._dragging || showOrHide;

	            var handleLabels = this._displayables.handleLabels;
	            handleLabels[0].attr('invisible', !showOrHide);
	            handleLabels[1].attr('invisible', !showOrHide);
	        },

	        _onDragMove: function (handleIndex, dx, dy) {
	            this._dragging = true;

	            // Transform dx, dy to bar coordination.
	            var barTransform = this._displayables.barGroup.getLocalTransform();
	            var vertex = graphic.applyTransform([dx, dy], barTransform, true);

	            this._updateInterval(handleIndex, vertex[0]);

	            var realtime = this.dataZoomModel.get('realtime');

	            this._updateView(!realtime);

	            if (realtime) {
	                realtime && this._dispatchZoomAction();
	            }
	        },

	        _onDragEnd: function () {
	            this._dragging = false;
	            this._showDataInfo(false);
	            this._dispatchZoomAction();
	        },

	        _onClickPanelClick: function (e) {
	            var size = this._size;
	            var localPoint = this._displayables.barGroup.transformCoordToLocal(e.offsetX, e.offsetY);

	            if (localPoint[0] < 0 || localPoint[0] > size[0]
	                || localPoint[1] < 0 || localPoint[1] > size[1]
	            ) {
	                return;
	            }

	            var handleEnds = this._handleEnds;
	            var center = (handleEnds[0] + handleEnds[1]) / 2;

	            this._updateInterval('all', localPoint[0] - center);
	            this._updateView();
	            this._dispatchZoomAction();
	        },

	        /**
	         * This action will be throttled.
	         * @private
	         */
	        _dispatchZoomAction: function () {
	            var range = this._range;

	            this.api.dispatchAction({
	                type: 'dataZoom',
	                from: this.uid,
	                dataZoomId: this.dataZoomModel.id,
	                start: range[0],
	                end: range[1]
	            });
	        },

	        /**
	         * @private
	         */
	        _findCoordRect: function () {
	            // Find the grid coresponding to the first axis referred by dataZoom.
	            var rect;
	            each(this.getTargetCoordInfo(), function (coordInfoList) {
	                if (!rect && coordInfoList.length) {
	                    var coordSys = coordInfoList[0].model.coordinateSystem;
	                    rect = coordSys.getRect && coordSys.getRect();
	                }
	            });
	            if (!rect) {
	                var width = this.api.getWidth();
	                var height = this.api.getHeight();
	                rect = {
	                    x: width * 0.2,
	                    y: height * 0.2,
	                    width: width * 0.6,
	                    height: height * 0.6
	                };
	            }

	            return rect;
	        }

	    });

	    function getOtherDim(thisDim) {
	        // FIXME
	        // 这个逻辑和getOtherAxis里一致，但是写在这里是否不好
	        var map = {x: 'y', y: 'x', radius: 'angle', angle: 'radius'};
	        return map[thisDim];
	    }

	    module.exports = SliderZoomView;



/***/ },
/* 371 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @file Data zoom model
	 */


	    module.exports = __webpack_require__(365).extend({

	        type: 'dataZoom.inside',

	        /**
	         * @protected
	         */
	        defaultOption: {
	            disabled: false,   // Whether disable this inside zoom.
	            zoomLock: false,   // Whether disable zoom but only pan.
	            zoomOnMouseWheel: true, // Can be: true / false / 'shift' / 'ctrl' / 'alt'.
	            moveOnMouseMove: true,   // Can be: true / false / 'shift' / 'ctrl' / 'alt'.
	            preventDefaultMouseMove: true
	        }
	    });


/***/ },
/* 372 */
/***/ function(module, exports, __webpack_require__) {

	

	    var DataZoomView = __webpack_require__(368);
	    var zrUtil = __webpack_require__(4);
	    var sliderMove = __webpack_require__(239);
	    var roams = __webpack_require__(373);
	    var bind = zrUtil.bind;

	    var InsideZoomView = DataZoomView.extend({

	        type: 'dataZoom.inside',

	        /**
	         * @override
	         */
	        init: function (ecModel, api) {
	            /**
	             * 'throttle' is used in this.dispatchAction, so we save range
	             * to avoid missing some 'pan' info.
	             * @private
	             * @type {Array.<number>}
	             */
	            this._range;
	        },

	        /**
	         * @override
	         */
	        render: function (dataZoomModel, ecModel, api, payload) {
	            InsideZoomView.superApply(this, 'render', arguments);

	            // Notice: origin this._range should be maintained, and should not be re-fetched
	            // from dataZoomModel when payload.type is 'dataZoom', otherwise 'pan' or 'zoom'
	            // info will be missed because of 'throttle' of this.dispatchAction.
	            if (roams.shouldRecordRange(payload, dataZoomModel.id)) {
	                this._range = dataZoomModel.getPercentRange();
	            }

	            // Reset controllers.
	            zrUtil.each(this.getTargetCoordInfo(), function (coordInfoList, coordSysName) {

	                var allCoordIds = zrUtil.map(coordInfoList, function (coordInfo) {
	                    return roams.generateCoordId(coordInfo.model);
	                });

	                zrUtil.each(coordInfoList, function (coordInfo) {
	                    var coordModel = coordInfo.model;
	                    var dataZoomOption = dataZoomModel.option;

	                    roams.register(
	                        api,
	                        {
	                            coordId: roams.generateCoordId(coordModel),
	                            allCoordIds: allCoordIds,
	                            containsPoint: function (e, x, y) {
	                                return coordModel.coordinateSystem.containPoint([x, y]);
	                            },
	                            dataZoomId: dataZoomModel.id,
	                            throttleRate: dataZoomModel.get('throttle', true),
	                            panGetRange: bind(this._onPan, this, coordInfo, coordSysName),
	                            zoomGetRange: bind(this._onZoom, this, coordInfo, coordSysName),
	                            zoomLock: dataZoomOption.zoomLock,
	                            disabled: dataZoomOption.disabled,
	                            roamControllerOpt: {
	                                zoomOnMouseWheel: dataZoomOption.zoomOnMouseWheel,
	                                moveOnMouseMove: dataZoomOption.moveOnMouseMove,
	                                preventDefaultMouseMove: dataZoomOption.preventDefaultMouseMove
	                            }
	                        }
	                    );
	                }, this);

	            }, this);
	        },

	        /**
	         * @override
	         */
	        dispose: function () {
	            roams.unregister(this.api, this.dataZoomModel.id);
	            InsideZoomView.superApply(this, 'dispose', arguments);
	            this._range = null;
	        },

	        /**
	         * @private
	         */
	        _onPan: function (coordInfo, coordSysName, controller, dx, dy, oldX, oldY, newX, newY) {
	            var range = this._range.slice();

	            // Calculate transform by the first axis.
	            var axisModel = coordInfo.axisModels[0];
	            if (!axisModel) {
	                return;
	            }

	            var directionInfo = getDirectionInfo[coordSysName](
	                [oldX, oldY], [newX, newY], axisModel, controller, coordInfo
	            );

	            var percentDelta = directionInfo.signal
	                * (range[1] - range[0])
	                * directionInfo.pixel / directionInfo.pixelLength;

	            sliderMove(percentDelta, range, [0, 100], 'all');

	            return (this._range = range);
	        },

	        /**
	         * @private
	         */
	        _onZoom: function (coordInfo, coordSysName, controller, scale, mouseX, mouseY) {
	            var range = this._range.slice();

	            // Calculate transform by the first axis.
	            var axisModel = coordInfo.axisModels[0];
	            if (!axisModel) {
	                return;
	            }

	            var directionInfo = getDirectionInfo[coordSysName](
	                null, [mouseX, mouseY], axisModel, controller, coordInfo
	            );
	            var percentPoint = (
	                directionInfo.signal > 0
	                    ? (directionInfo.pixelStart + directionInfo.pixelLength - directionInfo.pixel)
	                    : (directionInfo.pixel - directionInfo.pixelStart)
	                ) / directionInfo.pixelLength * (range[1] - range[0]) + range[0];

	            scale = Math.max(1 / scale, 0);
	            range[0] = (range[0] - percentPoint) * scale + percentPoint;
	            range[1] = (range[1] - percentPoint) * scale + percentPoint;

	            // Restrict range.
	            var minMaxSpan = this.dataZoomModel.findRepresentativeAxisProxy().getMinMaxSpan();
	            sliderMove(0, range, [0, 100], 0, minMaxSpan.minSpan, minMaxSpan.maxSpan);

	            return (this._range = range);
	        }

	    });

	    var getDirectionInfo = {

	        grid: function (oldPoint, newPoint, axisModel, controller, coordInfo) {
	            var axis = axisModel.axis;
	            var ret = {};
	            var rect = coordInfo.model.coordinateSystem.getRect();
	            oldPoint = oldPoint || [0, 0];

	            if (axis.dim === 'x') {
	                ret.pixel = newPoint[0] - oldPoint[0];
	                ret.pixelLength = rect.width;
	                ret.pixelStart = rect.x;
	                ret.signal = axis.inverse ? 1 : -1;
	            }
	            else { // axis.dim === 'y'
	                ret.pixel = newPoint[1] - oldPoint[1];
	                ret.pixelLength = rect.height;
	                ret.pixelStart = rect.y;
	                ret.signal = axis.inverse ? -1 : 1;
	            }

	            return ret;
	        },

	        polar: function (oldPoint, newPoint, axisModel, controller, coordInfo) {
	            var axis = axisModel.axis;
	            var ret = {};
	            var polar = coordInfo.model.coordinateSystem;
	            var radiusExtent = polar.getRadiusAxis().getExtent();
	            var angleExtent = polar.getAngleAxis().getExtent();

	            oldPoint = oldPoint ? polar.pointToCoord(oldPoint) : [0, 0];
	            newPoint = polar.pointToCoord(newPoint);

	            if (axisModel.mainType === 'radiusAxis') {
	                ret.pixel = newPoint[0] - oldPoint[0];
	                // ret.pixelLength = Math.abs(radiusExtent[1] - radiusExtent[0]);
	                // ret.pixelStart = Math.min(radiusExtent[0], radiusExtent[1]);
	                ret.pixelLength = radiusExtent[1] - radiusExtent[0];
	                ret.pixelStart = radiusExtent[0];
	                ret.signal = axis.inverse ? 1 : -1;
	            }
	            else { // 'angleAxis'
	                ret.pixel = newPoint[1] - oldPoint[1];
	                // ret.pixelLength = Math.abs(angleExtent[1] - angleExtent[0]);
	                // ret.pixelStart = Math.min(angleExtent[0], angleExtent[1]);
	                ret.pixelLength = angleExtent[1] - angleExtent[0];
	                ret.pixelStart = angleExtent[0];
	                ret.signal = axis.inverse ? -1 : 1;
	            }

	            return ret;
	        },

	        singleAxis: function (oldPoint, newPoint, axisModel, controller, coordInfo) {
	            var axis = axisModel.axis;
	            var rect = coordInfo.model.coordinateSystem.getRect();
	            var ret = {};

	            oldPoint = oldPoint || [0, 0];

	            if (axis.orient === 'horizontal') {
	                ret.pixel = newPoint[0] - oldPoint[0];
	                ret.pixelLength = rect.width;
	                ret.pixelStart = rect.x;
	                ret.signal = axis.inverse ? 1 : -1;
	            }
	            else { // 'vertical'
	                ret.pixel = newPoint[1] - oldPoint[1];
	                ret.pixelLength = rect.height;
	                ret.pixelStart = rect.y;
	                ret.signal = axis.inverse ? -1 : 1;
	            }

	            return ret;
	        }
	    };

	    module.exports = InsideZoomView;


/***/ },
/* 373 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @file Roam controller manager.
	 */


	    // Only create one roam controller for each coordinate system.
	    // one roam controller might be refered by two inside data zoom
	    // components (for example, one for x and one for y). When user
	    // pan or zoom, only dispatch one action for those data zoom
	    // components.

	    var zrUtil = __webpack_require__(4);
	    var RoamController = __webpack_require__(183);
	    var throttle = __webpack_require__(81);
	    var curry = zrUtil.curry;

	    var ATTR = '\0_ec_dataZoom_roams';

	    var roams = {

	        /**
	         * @public
	         * @param {module:echarts/ExtensionAPI} api
	         * @param {Object} dataZoomInfo
	         * @param {string} dataZoomInfo.coordId
	         * @param {Function} dataZoomInfo.containsPoint
	         * @param {Array.<string>} dataZoomInfo.allCoordIds
	         * @param {string} dataZoomInfo.dataZoomId
	         * @param {number} dataZoomInfo.throttleRate
	         * @param {Function} dataZoomInfo.panGetRange
	         * @param {Function} dataZoomInfo.zoomGetRange
	         * @param {boolean} [dataZoomInfo.zoomLock]
	         * @param {boolean} [dataZoomInfo.disabled]
	         */
	        register: function (api, dataZoomInfo) {
	            var store = giveStore(api);
	            var theDataZoomId = dataZoomInfo.dataZoomId;
	            var theCoordId = dataZoomInfo.coordId;

	            // Do clean when a dataZoom changes its target coordnate system.
	            // Avoid memory leak, dispose all not-used-registered.
	            zrUtil.each(store, function (record, coordId) {
	                var dataZoomInfos = record.dataZoomInfos;
	                if (dataZoomInfos[theDataZoomId]
	                    && zrUtil.indexOf(dataZoomInfo.allCoordIds, theCoordId) < 0
	                ) {
	                    delete dataZoomInfos[theDataZoomId];
	                    record.count--;
	                }
	            });

	            cleanStore(store);

	            var record = store[theCoordId];
	            // Create if needed.
	            if (!record) {
	                record = store[theCoordId] = {
	                    coordId: theCoordId,
	                    dataZoomInfos: {},
	                    count: 0
	                };
	                record.controller = createController(api, record);
	                record.dispatchAction = zrUtil.curry(dispatchAction, api);
	            }

	            // Update reference of dataZoom.
	            !(record.dataZoomInfos[theDataZoomId]) && record.count++;
	            record.dataZoomInfos[theDataZoomId] = dataZoomInfo;

	            var controllerParams = mergeControllerParams(record.dataZoomInfos);
	            record.controller.enable(controllerParams.controlType, controllerParams.opt);

	            // Consider resize, area should be always updated.
	            record.controller.setPointerChecker(dataZoomInfo.containsPoint);

	            // Update throttle.
	            throttle.createOrUpdate(
	                record,
	                'dispatchAction',
	                dataZoomInfo.throttleRate,
	                'fixRate'
	            );
	        },

	        /**
	         * @public
	         * @param {module:echarts/ExtensionAPI} api
	         * @param {string} dataZoomId
	         */
	        unregister: function (api, dataZoomId) {
	            var store = giveStore(api);

	            zrUtil.each(store, function (record) {
	                record.controller.dispose();
	                var dataZoomInfos = record.dataZoomInfos;
	                if (dataZoomInfos[dataZoomId]) {
	                    delete dataZoomInfos[dataZoomId];
	                    record.count--;
	                }
	            });

	            cleanStore(store);
	        },

	        /**
	         * @public
	         */
	        shouldRecordRange: function (payload, dataZoomId) {
	            if (payload && payload.type === 'dataZoom' && payload.batch) {
	                for (var i = 0, len = payload.batch.length; i < len; i++) {
	                    if (payload.batch[i].dataZoomId === dataZoomId) {
	                        return false;
	                    }
	                }
	            }
	            return true;
	        },

	        /**
	         * @public
	         */
	        generateCoordId: function (coordModel) {
	            return coordModel.type + '\0_' + coordModel.id;
	        }
	    };

	    /**
	     * Key: coordId, value: {dataZoomInfos: [], count, controller}
	     * @type {Array.<Object>}
	     */
	    function giveStore(api) {
	        // Mount store on zrender instance, so that we do not
	        // need to worry about dispose.
	        var zr = api.getZr();
	        return zr[ATTR] || (zr[ATTR] = {});
	    }

	    function createController(api, newRecord) {
	        var controller = new RoamController(api.getZr());
	        controller.on('pan', curry(onPan, newRecord));
	        controller.on('zoom', curry(onZoom, newRecord));

	        return controller;
	    }

	    function cleanStore(store) {
	        zrUtil.each(store, function (record, coordId) {
	            if (!record.count) {
	                record.controller.dispose();
	                delete store[coordId];
	            }
	        });
	    }

	    function onPan(record, dx, dy, oldX, oldY, newX, newY) {
	        wrapAndDispatch(record, function (info) {
	            return info.panGetRange(record.controller, dx, dy, oldX, oldY, newX, newY);
	        });
	    }

	    function onZoom(record, scale, mouseX, mouseY) {
	        wrapAndDispatch(record, function (info) {
	            return info.zoomGetRange(record.controller, scale, mouseX, mouseY);
	        });
	    }

	    function wrapAndDispatch(record, getRange) {
	        var batch = [];

	        zrUtil.each(record.dataZoomInfos, function (info) {
	            var range = getRange(info);
	            !info.disabled && range && batch.push({
	                dataZoomId: info.dataZoomId,
	                start: range[0],
	                end: range[1]
	            });
	        });

	        record.dispatchAction(batch);
	    }

	    /**
	     * This action will be throttled.
	     */
	    function dispatchAction(api, batch) {
	        api.dispatchAction({
	            type: 'dataZoom',
	            batch: batch
	        });
	    }

	    /**
	     * Merge roamController settings when multiple dataZooms share one roamController.
	     */
	    function mergeControllerParams(dataZoomInfos) {
	        var controlType;
	        var opt = {};
	        var typePriority = {
	            'true': 2,
	            'move': 1,
	            'false': 0,
	            'undefined': -1
	        };
	        zrUtil.each(dataZoomInfos, function (dataZoomInfo) {
	            var oneType = dataZoomInfo.disabled ? false : dataZoomInfo.zoomLock ? 'move' : true;
	            typePriority[oneType] > typePriority[controlType] && (controlType = oneType);
	            // Do not support that different 'shift'/'ctrl'/'alt' setting used in one coord sys.
	            zrUtil.extend(opt, dataZoomInfo.roamControllerOpt);
	        });

	        return {
	            controlType: controlType,
	            opt: opt
	        };
	    }

	    module.exports = roams;



/***/ },
/* 374 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @file Data zoom processor
	 */


	    var echarts = __webpack_require__(1);

	    echarts.registerProcessor(function (ecModel, api) {

	        ecModel.eachComponent('dataZoom', function (dataZoomModel) {
	            // We calculate window and reset axis here but not in model
	            // init stage and not after action dispatch handler, because
	            // reset should be called after seriesData.restoreData.
	            dataZoomModel.eachTargetAxis(resetSingleAxis);

	            // Caution: data zoom filtering is order sensitive when using
	            // percent range and no min/max/scale set on axis.
	            // For example, we have dataZoom definition:
	            // [
	            //      {xAxisIndex: 0, start: 30, end: 70},
	            //      {yAxisIndex: 0, start: 20, end: 80}
	            // ]
	            // In this case, [20, 80] of y-dataZoom should be based on data
	            // that have filtered by x-dataZoom using range of [30, 70],
	            // but should not be based on full raw data. Thus sliding
	            // x-dataZoom will change both ranges of xAxis and yAxis,
	            // while sliding y-dataZoom will only change the range of yAxis.
	            // So we should filter x-axis after reset x-axis immediately,
	            // and then reset y-axis and filter y-axis.
	            dataZoomModel.eachTargetAxis(filterSingleAxis);
	        });

	        ecModel.eachComponent('dataZoom', function (dataZoomModel) {
	            // Fullfill all of the range props so that user
	            // is able to get them from chart.getOption().
	            var axisProxy = dataZoomModel.findRepresentativeAxisProxy();
	            var percentRange = axisProxy.getDataPercentWindow();
	            var valueRange = axisProxy.getDataValueWindow();

	            dataZoomModel.setRawRange({
	                start: percentRange[0],
	                end: percentRange[1],
	                startValue: valueRange[0],
	                endValue: valueRange[1]
	            }, true);
	        });
	    });

	    function resetSingleAxis(dimNames, axisIndex, dataZoomModel) {
	        dataZoomModel.getAxisProxy(dimNames.name, axisIndex).reset(dataZoomModel);
	    }

	    function filterSingleAxis(dimNames, axisIndex, dataZoomModel) {
	        dataZoomModel.getAxisProxy(dimNames.name, axisIndex).filterData(dataZoomModel);
	    }




/***/ },
/* 375 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @file Data zoom action
	 */


	    var zrUtil = __webpack_require__(4);
	    var helper = __webpack_require__(366);
	    var echarts = __webpack_require__(1);


	    echarts.registerAction('dataZoom', function (payload, ecModel) {

	        var linkedNodesFinder = helper.createLinkedNodesFinder(
	            zrUtil.bind(ecModel.eachComponent, ecModel, 'dataZoom'),
	            helper.eachAxisDim,
	            function (model, dimNames) {
	                return model.get(dimNames.axisIndex);
	            }
	        );

	        var effectedModels = [];

	        ecModel.eachComponent(
	            {mainType: 'dataZoom', query: payload},
	            function (model, index) {
	                effectedModels.push.apply(
	                    effectedModels, linkedNodesFinder(model).nodes
	                );
	            }
	        );

	        zrUtil.each(effectedModels, function (dataZoomModel, index) {
	            dataZoomModel.setRawRange({
	                start: payload.start,
	                end: payload.end,
	                startValue: payload.startValue,
	                endValue: payload.endValue
	            });
	        });

	    });



/***/ },
/* 376 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * visualMap component entry
	 */


	    __webpack_require__(377);
	    __webpack_require__(388);



/***/ },
/* 377 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * DataZoom component entry
	 */


	    __webpack_require__(1).registerPreprocessor(
	        __webpack_require__(378)
	    );

	    __webpack_require__(379);
	    __webpack_require__(380);
	    __webpack_require__(381);
	    __webpack_require__(384);
	    __webpack_require__(387);



/***/ },
/* 378 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @file VisualMap preprocessor
	 */


	    var zrUtil = __webpack_require__(4);
	    var each = zrUtil.each;

	    module.exports = function (option) {
	        var visualMap = option && option.visualMap;

	        if (!zrUtil.isArray(visualMap)) {
	            visualMap = visualMap ? [visualMap] : [];
	        }

	        each(visualMap, function (opt) {
	            if (!opt) {
	                return;
	            }

	            // rename splitList to pieces
	            if (has(opt, 'splitList') && !has(opt, 'pieces')) {
	                opt.pieces = opt.splitList;
	                delete opt.splitList;
	            }

	            var pieces = opt.pieces;
	            if (pieces && zrUtil.isArray(pieces)) {
	                each(pieces, function (piece) {
	                    if (zrUtil.isObject(piece)) {
	                        if (has(piece, 'start') && !has(piece, 'min')) {
	                            piece.min = piece.start;
	                        }
	                        if (has(piece, 'end') && !has(piece, 'max')) {
	                            piece.max = piece.end;
	                        }
	                    }
	                });
	            }
	        });
	    };

	    function has(obj, name) {
	        return obj && obj.hasOwnProperty && obj.hasOwnProperty(name);
	    }



/***/ },
/* 379 */
/***/ function(module, exports, __webpack_require__) {

	

	    __webpack_require__(69).registerSubTypeDefaulter('visualMap', function (option) {
	        // Compatible with ec2, when splitNumber === 0, continuous visualMap will be used.
	        return (
	                !option.categories
	                && (
	                    !(
	                        option.pieces
	                            ? option.pieces.length > 0
	                            : option.splitNumber > 0
	                    )
	                    || option.calculable
	                )
	            )
	            ? 'continuous' : 'piecewise';
	    });



/***/ },
/* 380 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @file Data range visual coding.
	 */


	    var echarts = __webpack_require__(1);
	    var visualSolution = __webpack_require__(350);
	    var VisualMapping = __webpack_require__(203);
	    var zrUtil = __webpack_require__(4);

	    echarts.registerVisual(echarts.PRIORITY.VISUAL.COMPONENT, function (ecModel) {
	        ecModel.eachComponent('visualMap', function (visualMapModel) {
	            processSingleVisualMap(visualMapModel, ecModel);
	        });

	        prepareVisualMeta(ecModel);
	    });

	    function processSingleVisualMap(visualMapModel, ecModel) {
	        visualMapModel.eachTargetSeries(function (seriesModel) {
	            var data = seriesModel.getData();

	            visualSolution.applyVisual(
	                visualMapModel.stateList,
	                visualMapModel.targetVisuals,
	                data,
	                visualMapModel.getValueState,
	                visualMapModel,
	                visualMapModel.getDataDimension(data)
	            );
	        });
	    }

	    // Only support color.
	    function prepareVisualMeta(ecModel) {
	        ecModel.eachSeries(function (seriesModel) {
	            var data = seriesModel.getData();
	            var visualMetaList = [];

	            ecModel.eachComponent('visualMap', function (visualMapModel) {
	                if (visualMapModel.isTargetSeries(seriesModel)) {
	                    var visualMeta = visualMapModel.getVisualMeta(
	                        zrUtil.bind(getColorVisual, null, seriesModel, visualMapModel)
	                    ) || {stops: [], outerColors: []};
	                    visualMeta.dimension = visualMapModel.getDataDimension(data);
	                    visualMetaList.push(visualMeta);
	                }
	            });

	            // console.log(JSON.stringify(visualMetaList.map(a => a.stops)));
	            seriesModel.getData().setVisual('visualMeta', visualMetaList);
	        });
	    }

	    // FIXME
	    // performance and export for heatmap?
	    // value can be Infinity or -Infinity
	    function getColorVisual(seriesModel, visualMapModel, value, valueState) {
	        var mappings = visualMapModel.targetVisuals[valueState];
	        var visualTypes = VisualMapping.prepareVisualTypes(mappings);
	        var resultVisual = {
	            color: seriesModel.getData().getVisual('color') // default color.
	        };

	        for (var i = 0, len = visualTypes.length; i < len; i++) {
	            var type = visualTypes[i];
	            var mapping = mappings[
	                type === 'opacity' ? '__alphaForOpacity' : type
	            ];
	            mapping && mapping.applyVisual(value, getVisual, setVisual);
	        }

	        return resultVisual.color;

	        function getVisual(key) {
	            return resultVisual[key];
	        }

	        function setVisual(key, value) {
	            resultVisual[key] = value;
	        }
	    }




/***/ },
/* 381 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @file Data zoom model
	 */


	    var VisualMapModel = __webpack_require__(382);
	    var zrUtil = __webpack_require__(4);
	    var numberUtil = __webpack_require__(7);

	    // Constant
	    var DEFAULT_BAR_BOUND = [20, 140];

	    var ContinuousModel = VisualMapModel.extend({

	        type: 'visualMap.continuous',

	        /**
	         * @protected
	         */
	        defaultOption: {
	            align: 'auto',          // 'auto', 'left', 'right', 'top', 'bottom'
	            calculable: false,      // This prop effect default component type determine,
	                                    // See echarts/component/visualMap/typeDefaulter.
	            range: null,            // selected range. In default case `range` is [min, max]
	                                    // and can auto change along with modification of min max,
	                                    // util use specifid a range.
	            realtime: true,         // Whether realtime update.
	            itemHeight: null,       // The length of the range control edge.
	            itemWidth: null,        // The length of the other side.
	            hoverLink: true,        // Enable hover highlight.
	            hoverLinkDataSize: null,// The size of hovered data.
	            hoverLinkOnHandle: true // Whether trigger hoverLink when hover handle.
	        },

	        /**
	         * @override
	         */
	        optionUpdated: function (newOption, isInit) {
	            ContinuousModel.superApply(this, 'optionUpdated', arguments);

	            this.resetTargetSeries();
	            this.resetExtent();

	            this.resetVisual(function (mappingOption) {
	                mappingOption.mappingMethod = 'linear';
	                mappingOption.dataExtent = this.getExtent();
	            });

	            this._resetRange();
	        },

	        /**
	         * @protected
	         * @override
	         */
	        resetItemSize: function () {
	            ContinuousModel.superApply(this, 'resetItemSize', arguments);

	            var itemSize = this.itemSize;

	            this._orient === 'horizontal' && itemSize.reverse();

	            (itemSize[0] == null || isNaN(itemSize[0])) && (itemSize[0] = DEFAULT_BAR_BOUND[0]);
	            (itemSize[1] == null || isNaN(itemSize[1])) && (itemSize[1] = DEFAULT_BAR_BOUND[1]);
	        },

	        /**
	         * @private
	         */
	        _resetRange: function () {
	            var dataExtent = this.getExtent();
	            var range = this.option.range;

	            if (!range || range.auto) {
	                // `range` should always be array (so we dont use other
	                // value like 'auto') for user-friend. (consider getOption).
	                dataExtent.auto = 1;
	                this.option.range = dataExtent;
	            }
	            else if (zrUtil.isArray(range)) {
	                if (range[0] > range[1]) {
	                    range.reverse();
	                }
	                range[0] = Math.max(range[0], dataExtent[0]);
	                range[1] = Math.min(range[1], dataExtent[1]);
	            }
	        },

	        /**
	         * @protected
	         * @override
	         */
	        completeVisualOption: function () {
	            VisualMapModel.prototype.completeVisualOption.apply(this, arguments);

	            zrUtil.each(this.stateList, function (state) {
	                var symbolSize = this.option.controller[state].symbolSize;
	                if (symbolSize && symbolSize[0] !== symbolSize[1]) {
	                    symbolSize[0] = 0; // For good looking.
	                }
	            }, this);
	        },

	        /**
	         * @override
	         */
	        setSelected: function (selected) {
	            this.option.range = selected.slice();
	            this._resetRange();
	        },

	        /**
	         * @public
	         */
	        getSelected: function () {
	            var dataExtent = this.getExtent();

	            var dataInterval = numberUtil.asc(
	                (this.get('range') || []).slice()
	            );

	            // Clamp
	            dataInterval[0] > dataExtent[1] && (dataInterval[0] = dataExtent[1]);
	            dataInterval[1] > dataExtent[1] && (dataInterval[1] = dataExtent[1]);
	            dataInterval[0] < dataExtent[0] && (dataInterval[0] = dataExtent[0]);
	            dataInterval[1] < dataExtent[0] && (dataInterval[1] = dataExtent[0]);

	            return dataInterval;
	        },

	        /**
	         * @override
	         */
	        getValueState: function (value) {
	            var range = this.option.range;
	            var dataExtent = this.getExtent();

	            // When range[0] === dataExtent[0], any value larger than dataExtent[0] maps to 'inRange'.
	            // range[1] is processed likewise.
	            return (
	                (range[0] <= dataExtent[0] || range[0] <= value)
	                && (range[1] >= dataExtent[1] || value <= range[1])
	            ) ? 'inRange' : 'outOfRange';
	        },

	        /**
	         * @params {Array.<number>} range target value: range[0] <= value && value <= range[1]
	         * @return {Array.<Object>} [{seriesId, dataIndices: <Array.<number>>}, ...]
	         */
	        findTargetDataIndices: function (range) {
	            var result = [];

	            this.eachTargetSeries(function (seriesModel) {
	                var dataIndices = [];
	                var data = seriesModel.getData();

	                data.each(this.getDataDimension(data), function (value, dataIndex) {
	                    range[0] <= value && value <= range[1] && dataIndices.push(dataIndex);
	                }, true, this);

	                result.push({seriesId: seriesModel.id, dataIndex: dataIndices});
	            }, this);

	            return result;
	        },

	        /**
	         * @implement
	         */
	        getVisualMeta: function (getColorVisual) {
	            var oVals = getColorStopValues(this, 'outOfRange', this.getExtent());
	            var iVals = getColorStopValues(this, 'inRange', this.option.range.slice());
	            var stops = [];

	            function setStop(value, valueState) {
	                stops.push({
	                    value: value,
	                    color: getColorVisual(value, valueState)
	                });
	            }

	            // Format to: outOfRange -- inRange -- outOfRange.
	            var iIdx = 0;
	            var oIdx = 0;
	            var iLen = iVals.length;
	            var oLen = oVals.length;

	            for (; oIdx < oLen && (!iVals.length || oVals[oIdx] <= iVals[0]); oIdx++) {
	                // If oVal[oIdx] === iVals[iIdx], oVal[oIdx] should be ignored.
	                if (oVals[oIdx] < iVals[iIdx]) {
	                    setStop(oVals[oIdx], 'outOfRange');
	                }
	            }
	            for (var first = 1; iIdx < iLen; iIdx++, first = 0) {
	                // If range is full, value beyond min, max will be clamped.
	                // make a singularity
	                first && stops.length && setStop(iVals[iIdx], 'outOfRange');
	                setStop(iVals[iIdx], 'inRange');
	            }
	            for (var first = 1; oIdx < oLen; oIdx++) {
	                if (!iVals.length || iVals[iVals.length - 1] < oVals[oIdx]) {
	                    // make a singularity
	                    if (first) {
	                        stops.length && setStop(stops[stops.length - 1].value, 'outOfRange');
	                        first = 0;
	                    }
	                    setStop(oVals[oIdx], 'outOfRange');
	                }
	            }

	            var stopsLen = stops.length;

	            return {
	                stops: stops,
	                outerColors: [
	                    stopsLen ? stops[0].color : 'transparent',
	                    stopsLen ? stops[stopsLen - 1].color : 'transparent'
	                ]
	            };
	        }

	    });

	    function getColorStopValues(visualMapModel, valueState, dataExtent) {
	        if (dataExtent[0] === dataExtent[1]) {
	            return dataExtent.slice();
	        }

	        // When using colorHue mapping, it is not linear color any more.
	        // Moreover, canvas gradient seems not to be accurate linear.
	        // FIXME
	        // Should be arbitrary value 100? or based on pixel size?
	        var count = 200;
	        var step = (dataExtent[1] - dataExtent[0]) / count;

	        var value = dataExtent[0];
	        var stopValues = [];
	        for (var i = 0; i <= count && value < dataExtent[1]; i++) {
	            stopValues.push(value);
	            value += step;
	        }
	        stopValues.push(dataExtent[1]);

	        return stopValues;
	    }

	    module.exports = ContinuousModel;



/***/ },
/* 382 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @file Controller visual map model
	 */


	    var echarts = __webpack_require__(1);
	    var zrUtil = __webpack_require__(4);
	    var env = __webpack_require__(2);
	    var visualDefault = __webpack_require__(383);
	    var VisualMapping = __webpack_require__(203);
	    var visualSolution = __webpack_require__(350);
	    var mapVisual = VisualMapping.mapVisual;
	    var modelUtil = __webpack_require__(5);
	    var eachVisual = VisualMapping.eachVisual;
	    var numberUtil = __webpack_require__(7);
	    var isArray = zrUtil.isArray;
	    var each = zrUtil.each;
	    var asc = numberUtil.asc;
	    var linearMap = numberUtil.linearMap;
	    var noop = zrUtil.noop;

	    var DEFAULT_COLOR = ['#f6efa6', '#d88273', '#bf444c'];

	    var VisualMapModel = echarts.extendComponentModel({

	        type: 'visualMap',

	        dependencies: ['series'],

	        /**
	         * @readOnly
	         * @type {Array.<string>}
	         */
	        stateList: ['inRange', 'outOfRange'],

	        /**
	         * @readOnly
	         * @type {Array.<string>}
	         */
	        replacableOptionKeys: [
	            'inRange', 'outOfRange', 'target', 'controller', 'color'
	        ],

	        /**
	         * [lowerBound, upperBound]
	         *
	         * @readOnly
	         * @type {Array.<number>}
	         */
	        dataBound: [-Infinity, Infinity],

	        /**
	         * @readOnly
	         * @type {string|Object}
	         */
	        layoutMode: {type: 'box', ignoreSize: true},

	        /**
	         * @protected
	         */
	        defaultOption: {
	            show: true,

	            zlevel: 0,
	            z: 4,

	            seriesIndex: null,       // 所控制的series indices，默认所有有value的series.

	                                    // set min: 0, max: 200, only for campatible with ec2.
	                                    // In fact min max should not have default value.
	            min: 0,                 // min value, must specified if pieces is not specified.
	            max: 200,               // max value, must specified if pieces is not specified.

	            dimension: null,
	            inRange: null,          // 'color', 'colorHue', 'colorSaturation', 'colorLightness', 'colorAlpha',
	                                    // 'symbol', 'symbolSize'
	            outOfRange: null,       // 'color', 'colorHue', 'colorSaturation',
	                                    // 'colorLightness', 'colorAlpha',
	                                    // 'symbol', 'symbolSize'

	            left: 0,                // 'center' ¦ 'left' ¦ 'right' ¦ {number} (px)
	            right: null,            // The same as left.
	            top: null,              // 'top' ¦ 'bottom' ¦ 'center' ¦ {number} (px)
	            bottom: 0,              // The same as top.

	            itemWidth: null,
	            itemHeight: null,
	            inverse: false,
	            orient: 'vertical',        // 'horizontal' ¦ 'vertical'

	            backgroundColor: 'rgba(0,0,0,0)',
	            borderColor: '#ccc',       // 值域边框颜色
	            contentColor: '#5793f3',
	            inactiveColor: '#aaa',
	            borderWidth: 0,            // 值域边框线宽，单位px，默认为0（无边框）
	            padding: 5,                // 值域内边距，单位px，默认各方向内边距为5，
	                                       // 接受数组分别设定上右下左边距，同css
	            textGap: 10,               //
	            precision: 0,              // 小数精度，默认为0，无小数点
	            color: null,               //颜色（deprecated，兼容ec2，顺序同pieces，不同于inRange/outOfRange）

	            formatter: null,
	            text: null,                // 文本，如['高', '低']，兼容ec2，text[0]对应高值，text[1]对应低值
	            textStyle: {
	                color: '#333'          // 值域文字颜色
	            }
	        },

	        /**
	         * @protected
	         */
	        init: function (option, parentModel, ecModel) {

	            /**
	             * @private
	             * @type {Array.<number>}
	             */
	            this._dataExtent;

	            /**
	             * @readOnly
	             */
	            this.targetVisuals = {};

	            /**
	             * @readOnly
	             */
	            this.controllerVisuals = {};

	            /**
	             * @readOnly
	             */
	            this.textStyleModel;

	            /**
	             * [width, height]
	             * @readOnly
	             * @type {Array.<number>}
	             */
	            this.itemSize;

	            this.mergeDefaultAndTheme(option, ecModel);
	        },

	        /**
	         * @protected
	         */
	        optionUpdated: function (newOption, isInit) {
	            var thisOption = this.option;

	            // FIXME
	            // necessary?
	            // Disable realtime view update if canvas is not supported.
	            if (!env.canvasSupported) {
	                thisOption.realtime = false;
	            }

	            !isInit && visualSolution.replaceVisualOption(
	                thisOption, newOption, this.replacableOptionKeys
	            );

	            this.textStyleModel = this.getModel('textStyle');

	            this.resetItemSize();

	            this.completeVisualOption();
	        },

	        /**
	         * @protected
	         */
	        resetVisual: function (supplementVisualOption) {
	            var stateList = this.stateList;
	            supplementVisualOption = zrUtil.bind(supplementVisualOption, this);

	            this.controllerVisuals = visualSolution.createVisualMappings(
	                this.option.controller, stateList, supplementVisualOption
	            );
	            this.targetVisuals = visualSolution.createVisualMappings(
	                this.option.target, stateList, supplementVisualOption
	            );
	        },


	        /**
	         * @protected
	         */
	        resetTargetSeries: function () {
	            var thisOption = this.option;
	            var allSeriesIndex = thisOption.seriesIndex == null;
	            thisOption.seriesIndex = allSeriesIndex
	                ? [] : modelUtil.normalizeToArray(thisOption.seriesIndex);

	            allSeriesIndex && this.ecModel.eachSeries(function (seriesModel, index) {
	                thisOption.seriesIndex.push(index);
	            });
	        },

	        /**
	         * @public
	         */
	        eachTargetSeries: function (callback, context) {
	            zrUtil.each(this.option.seriesIndex, function (seriesIndex) {
	                callback.call(context, this.ecModel.getSeriesByIndex(seriesIndex));
	            }, this);
	        },

	        /**
	         * @pubilc
	         */
	        isTargetSeries: function (seriesModel) {
	            var is = false;
	            this.eachTargetSeries(function (model) {
	                model === seriesModel && (is = true);
	            });
	            return is;
	        },

	        /**
	         * @example
	         * this.formatValueText(someVal); // format single numeric value to text.
	         * this.formatValueText(someVal, true); // format single category value to text.
	         * this.formatValueText([min, max]); // format numeric min-max to text.
	         * this.formatValueText([this.dataBound[0], max]); // using data lower bound.
	         * this.formatValueText([min, this.dataBound[1]]); // using data upper bound.
	         *
	         * @param {number|Array.<number>} value Real value, or this.dataBound[0 or 1].
	         * @param {boolean} [isCategory=false] Only available when value is number.
	         * @param {Array.<string>} edgeSymbols Open-close symbol when value is interval.
	         * @return {string}
	         * @protected
	         */
	        formatValueText: function(value, isCategory, edgeSymbols) {
	            var option = this.option;
	            var precision = option.precision;
	            var dataBound = this.dataBound;
	            var formatter = option.formatter;
	            var isMinMax;
	            var textValue;
	            edgeSymbols = edgeSymbols || ['<', '>'];

	            if (zrUtil.isArray(value)) {
	                value = value.slice();
	                isMinMax = true;
	            }

	            textValue = isCategory
	                ? value
	                : (isMinMax
	                    ? [toFixed(value[0]), toFixed(value[1])]
	                    : toFixed(value)
	                );

	            if (zrUtil.isString(formatter)) {
	                return formatter
	                    .replace('{value}', isMinMax ? textValue[0] : textValue)
	                    .replace('{value2}', isMinMax ? textValue[1] : textValue);
	            }
	            else if (zrUtil.isFunction(formatter)) {
	                return isMinMax
	                    ? formatter(value[0], value[1])
	                    : formatter(value);
	            }

	            if (isMinMax) {
	                if (value[0] === dataBound[0]) {
	                    return edgeSymbols[0] + ' ' + textValue[1];
	                }
	                else if (value[1] === dataBound[1]) {
	                    return edgeSymbols[1] + ' ' + textValue[0];
	                }
	                else {
	                    return textValue[0] + ' - ' + textValue[1];
	                }
	            }
	            else { // Format single value (includes category case).
	                return textValue;
	            }

	            function toFixed(val) {
	                return val === dataBound[0]
	                    ? 'min'
	                    : val === dataBound[1]
	                    ? 'max'
	                    : (+val).toFixed(precision);
	            }
	        },

	        /**
	         * @protected
	         */
	        resetExtent: function () {
	            var thisOption = this.option;

	            // Can not calculate data extent by data here.
	            // Because series and data may be modified in processing stage.
	            // So we do not support the feature "auto min/max".

	            var extent = asc([thisOption.min, thisOption.max]);

	            this._dataExtent = extent;
	        },

	        /**
	         * @public
	         * @param {module:echarts/data/List} list
	         * @return {string} Concrete dimention. If return null/undefined,
	         *                  no dimension used.
	         */
	        getDataDimension: function (list) {
	            var optDim = this.option.dimension;
	            return optDim != null
	                ? optDim : list.dimensions.length - 1;
	        },

	        /**
	         * @public
	         * @override
	         */
	        getExtent: function () {
	            return this._dataExtent.slice();
	        },

	        /**
	         * @protected
	         */
	        completeVisualOption: function () {
	            var thisOption = this.option;
	            var base = {inRange: thisOption.inRange, outOfRange: thisOption.outOfRange};

	            var target = thisOption.target || (thisOption.target = {});
	            var controller = thisOption.controller || (thisOption.controller = {});

	            zrUtil.merge(target, base); // Do not override
	            zrUtil.merge(controller, base); // Do not override

	            var isCategory = this.isCategory();

	            completeSingle.call(this, target);
	            completeSingle.call(this, controller);
	            completeInactive.call(this, target, 'inRange', 'outOfRange');
	            // completeInactive.call(this, target, 'outOfRange', 'inRange');
	            completeController.call(this, controller);

	            function completeSingle(base) {
	                // Compatible with ec2 dataRange.color.
	                // The mapping order of dataRange.color is: [high value, ..., low value]
	                // whereas inRange.color and outOfRange.color is [low value, ..., high value]
	                // Notice: ec2 has no inverse.
	                if (isArray(thisOption.color)
	                    // If there has been inRange: {symbol: ...}, adding color is a mistake.
	                    // So adding color only when no inRange defined.
	                    && !base.inRange
	                ) {
	                    base.inRange = {color: thisOption.color.slice().reverse()};
	                }

	                // Compatible with previous logic, always give a defautl color, otherwise
	                // simple config with no inRange and outOfRange will not work.
	                // Originally we use visualMap.color as the default color, but setOption at
	                // the second time the default color will be erased. So we change to use
	                // constant DEFAULT_COLOR.
	                // If user do not want the defualt color, set inRange: {color: null}.
	                base.inRange = base.inRange || {color: DEFAULT_COLOR};

	                // If using shortcut like: {inRange: 'symbol'}, complete default value.
	                each(this.stateList, function (state) {
	                    var visualType = base[state];

	                    if (zrUtil.isString(visualType)) {
	                        var defa = visualDefault.get(visualType, 'active', isCategory);
	                        if (defa) {
	                            base[state] = {};
	                            base[state][visualType] = defa;
	                        }
	                        else {
	                            // Mark as not specified.
	                            delete base[state];
	                        }
	                    }
	                }, this);
	            }

	            function completeInactive(base, stateExist, stateAbsent) {
	                var optExist = base[stateExist];
	                var optAbsent = base[stateAbsent];

	                if (optExist && !optAbsent) {
	                    optAbsent = base[stateAbsent] = {};
	                    each(optExist, function (visualData, visualType) {
	                        if (!VisualMapping.isValidType(visualType)) {
	                            return;
	                        }

	                        var defa = visualDefault.get(visualType, 'inactive', isCategory);

	                        if (defa != null) {
	                            optAbsent[visualType] = defa;

	                            // Compatibable with ec2:
	                            // Only inactive color to rgba(0,0,0,0) can not
	                            // make label transparent, so use opacity also.
	                            if (visualType === 'color'
	                                && !optAbsent.hasOwnProperty('opacity')
	                                && !optAbsent.hasOwnProperty('colorAlpha')
	                            ) {
	                                optAbsent.opacity = [0, 0];
	                            }
	                        }
	                    });
	                }
	            }

	            function completeController(controller) {
	                var symbolExists = (controller.inRange || {}).symbol
	                    || (controller.outOfRange || {}).symbol;
	                var symbolSizeExists = (controller.inRange || {}).symbolSize
	                    || (controller.outOfRange || {}).symbolSize;
	                var inactiveColor = this.get('inactiveColor');

	                each(this.stateList, function (state) {

	                    var itemSize = this.itemSize;
	                    var visuals = controller[state];

	                    // Set inactive color for controller if no other color
	                    // attr (like colorAlpha) specified.
	                    if (!visuals) {
	                        visuals = controller[state] = {
	                            color: isCategory ? inactiveColor : [inactiveColor]
	                        };
	                    }

	                    // Consistent symbol and symbolSize if not specified.
	                    if (visuals.symbol == null) {
	                        visuals.symbol = symbolExists
	                            && zrUtil.clone(symbolExists)
	                            || (isCategory ? 'roundRect' : ['roundRect']);
	                    }
	                    if (visuals.symbolSize == null) {
	                        visuals.symbolSize = symbolSizeExists
	                            && zrUtil.clone(symbolSizeExists)
	                            || (isCategory ? itemSize[0] : [itemSize[0], itemSize[0]]);
	                    }

	                    // Filter square and none.
	                    visuals.symbol = mapVisual(visuals.symbol, function (symbol) {
	                        return (symbol === 'none' || symbol === 'square') ? 'roundRect' : symbol;
	                    });

	                    // Normalize symbolSize
	                    var symbolSize = visuals.symbolSize;

	                    if (symbolSize != null) {
	                        var max = -Infinity;
	                        // symbolSize can be object when categories defined.
	                        eachVisual(symbolSize, function (value) {
	                            value > max && (max = value);
	                        });
	                        visuals.symbolSize = mapVisual(symbolSize, function (value) {
	                            return linearMap(value, [0, max], [0, itemSize[0]], true);
	                        });
	                    }

	                }, this);
	            }
	        },

	        /**
	         * @protected
	         */
	        resetItemSize: function () {
	            this.itemSize = [
	                parseFloat(this.get('itemWidth')),
	                parseFloat(this.get('itemHeight'))
	            ];
	        },

	        /**
	         * @public
	         */
	        isCategory: function () {
	            return !!this.option.categories;
	        },

	        /**
	         * @public
	         * @abstract
	         */
	        setSelected: noop,

	        /**
	         * @public
	         * @abstract
	         * @param {*|module:echarts/data/List} valueOrData
	         * @param {number} dataIndex
	         * @return {string} state See this.stateList
	         */
	        getValueState: noop,

	        /**
	         * FIXME
	         * Do not publish to thirt-part-dev temporarily
	         * util the interface is stable. (Should it return
	         * a function but not visual meta?)
	         *
	         * @pubilc
	         * @abstract
	         * @param {Function} getColorVisual
	         *        params: value, valueState
	         *        return: color
	         * @return {Object} visualMeta
	         *        should includes {stops, outerColors}
	         *        outerColor means [colorBeyondMinValue, colorBeyondMaxValue]
	         */
	        getVisualMeta: noop

	    });

	    module.exports = VisualMapModel;



/***/ },
/* 383 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @file Visual mapping.
	 */


	    var zrUtil = __webpack_require__(4);

	    var visualDefault = {

	        /**
	         * @public
	         */
	        get: function (visualType, key, isCategory) {
	            var value = zrUtil.clone(
	                (defaultOption[visualType] || {})[key]
	            );

	            return isCategory
	                ? (zrUtil.isArray(value) ? value[value.length - 1] : value)
	                : value;
	        }

	    };

	    var defaultOption = {

	        color: {
	            active: ['#006edd', '#e0ffff'],
	            inactive: ['rgba(0,0,0,0)']
	        },

	        colorHue: {
	            active: [0, 360],
	            inactive: [0, 0]
	        },

	        colorSaturation: {
	            active: [0.3, 1],
	            inactive: [0, 0]
	        },

	        colorLightness: {
	            active: [0.9, 0.5],
	            inactive: [0, 0]
	        },

	        colorAlpha: {
	            active: [0.3, 1],
	            inactive: [0, 0]
	        },

	        opacity: {
	            active: [0.3, 1],
	            inactive: [0, 0]
	        },

	        symbol: {
	            active: ['circle', 'roundRect', 'diamond'],
	            inactive: ['none']
	        },

	        symbolSize: {
	            active: [10, 50],
	            inactive: [0, 0]
	        }
	    };

	    module.exports = visualDefault;




/***/ },
/* 384 */
/***/ function(module, exports, __webpack_require__) {

	

	    var VisualMapView = __webpack_require__(385);
	    var graphic = __webpack_require__(18);
	    var zrUtil = __webpack_require__(4);
	    var numberUtil = __webpack_require__(7);
	    var sliderMove = __webpack_require__(239);
	    var LinearGradient = __webpack_require__(65);
	    var helper = __webpack_require__(386);
	    var modelUtil = __webpack_require__(5);
	    var eventTool = __webpack_require__(88);

	    var linearMap = numberUtil.linearMap;
	    var each = zrUtil.each;
	    var mathMin = Math.min;
	    var mathMax = Math.max;

	    // Arbitrary value
	    var HOVER_LINK_SIZE = 12;
	    var HOVER_LINK_OUT = 6;

	    // Notice:
	    // Any "interval" should be by the order of [low, high].
	    // "handle0" (handleIndex === 0) maps to
	    // low data value: this._dataInterval[0] and has low coord.
	    // "handle1" (handleIndex === 1) maps to
	    // high data value: this._dataInterval[1] and has high coord.
	    // The logic of transform is implemented in this._createBarGroup.

	    var ContinuousView = VisualMapView.extend({

	        type: 'visualMap.continuous',

	        /**
	         * @override
	         */
	        init: function () {

	            ContinuousView.superApply(this, 'init', arguments);

	            /**
	             * @private
	             */
	            this._shapes = {};

	            /**
	             * @private
	             */
	            this._dataInterval = [];

	            /**
	             * @private
	             */
	            this._handleEnds = [];

	            /**
	             * @private
	             */
	            this._orient;

	            /**
	             * @private
	             */
	            this._useHandle;

	            /**
	             * @private
	             */
	            this._hoverLinkDataIndices = [];

	            /**
	             * @private
	             */
	            this._dragging;

	            /**
	             * @private
	             */
	            this._hovering;
	        },

	        /**
	         * @protected
	         * @override
	         */
	        doRender: function (visualMapModel, ecModel, api, payload) {
	            if (!payload || payload.type !== 'selectDataRange' || payload.from !== this.uid) {
	                this._buildView();
	            }
	        },

	        /**
	         * @private
	         */
	        _buildView: function () {
	            this.group.removeAll();

	            var visualMapModel = this.visualMapModel;
	            var thisGroup = this.group;

	            this._orient = visualMapModel.get('orient');
	            this._useHandle = visualMapModel.get('calculable');

	            this._resetInterval();

	            this._renderBar(thisGroup);

	            var dataRangeText = visualMapModel.get('text');
	            this._renderEndsText(thisGroup, dataRangeText, 0);
	            this._renderEndsText(thisGroup, dataRangeText, 1);

	            // Do this for background size calculation.
	            this._updateView(true);

	            // After updating view, inner shapes is built completely,
	            // and then background can be rendered.
	            this.renderBackground(thisGroup);

	            // Real update view
	            this._updateView();

	            this._enableHoverLinkToSeries();
	            this._enableHoverLinkFromSeries();

	            this.positionGroup(thisGroup);
	        },

	        /**
	         * @private
	         */
	        _renderEndsText: function (group, dataRangeText, endsIndex) {
	            if (!dataRangeText) {
	                return;
	            }

	            // Compatible with ec2, text[0] map to high value, text[1] map low value.
	            var text = dataRangeText[1 - endsIndex];
	            text = text != null ? text + '' : '';

	            var visualMapModel = this.visualMapModel;
	            var textGap = visualMapModel.get('textGap');
	            var itemSize = visualMapModel.itemSize;

	            var barGroup = this._shapes.barGroup;
	            var position = this._applyTransform(
	                [
	                    itemSize[0] / 2,
	                    endsIndex === 0 ? -textGap : itemSize[1] + textGap
	                ],
	                barGroup
	            );
	            var align = this._applyTransform(
	                endsIndex === 0 ? 'bottom' : 'top',
	                barGroup
	            );
	            var orient = this._orient;
	            var textStyleModel = this.visualMapModel.textStyleModel;

	            this.group.add(new graphic.Text({
	                style: {
	                    x: position[0],
	                    y: position[1],
	                    textVerticalAlign: orient === 'horizontal' ? 'middle' : align,
	                    textAlign: orient === 'horizontal' ? align : 'center',
	                    text: text,
	                    textFont: textStyleModel.getFont(),
	                    fill: textStyleModel.getTextColor()
	                }
	            }));
	        },

	        /**
	         * @private
	         */
	        _renderBar: function (targetGroup) {
	            var visualMapModel = this.visualMapModel;
	            var shapes = this._shapes;
	            var itemSize = visualMapModel.itemSize;
	            var orient = this._orient;
	            var useHandle = this._useHandle;
	            var itemAlign = helper.getItemAlign(visualMapModel, this.api, itemSize);
	            var barGroup = shapes.barGroup = this._createBarGroup(itemAlign);

	            // Bar
	            barGroup.add(shapes.outOfRange = createPolygon());
	            barGroup.add(shapes.inRange = createPolygon(
	                null,
	                useHandle ? 'move' : null,
	                zrUtil.bind(this._dragHandle, this, 'all', false),
	                zrUtil.bind(this._dragHandle, this, 'all', true)
	            ));

	            var textRect = visualMapModel.textStyleModel.getTextRect('国');
	            var textSize = mathMax(textRect.width, textRect.height);

	            // Handle
	            if (useHandle) {
	                shapes.handleThumbs = [];
	                shapes.handleLabels = [];
	                shapes.handleLabelPoints = [];

	                this._createHandle(barGroup, 0, itemSize, textSize, orient, itemAlign);
	                this._createHandle(barGroup, 1, itemSize, textSize, orient, itemAlign);
	            }

	            this._createIndicator(barGroup, itemSize, textSize, orient);

	            targetGroup.add(barGroup);
	        },

	        /**
	         * @private
	         */
	        _createHandle: function (barGroup, handleIndex, itemSize, textSize, orient) {
	            var onDrift = zrUtil.bind(this._dragHandle, this, handleIndex, false);
	            var onDragEnd = zrUtil.bind(this._dragHandle, this, handleIndex, true);
	            var handleThumb = createPolygon(
	                createHandlePoints(handleIndex, textSize),
	                'move',
	                onDrift,
	                onDragEnd
	            );
	            handleThumb.position[0] = itemSize[0];
	            barGroup.add(handleThumb);

	            // Text is always horizontal layout but should not be effected by
	            // transform (orient/inverse). So label is built separately but not
	            // use zrender/graphic/helper/RectText, and is located based on view
	            // group (according to handleLabelPoint) but not barGroup.
	            var textStyleModel = this.visualMapModel.textStyleModel;
	            var handleLabel = new graphic.Text({
	                draggable: true,
	                drift: onDrift,
	                onmousemove: function (e) {
	                    // Fot mobile devicem, prevent screen slider on the button.
	                    eventTool.stop(e.event);
	                },
	                ondragend: onDragEnd,
	                style: {
	                    x: 0, y: 0, text: '',
	                    textFont: textStyleModel.getFont(),
	                    fill: textStyleModel.getTextColor()
	                }
	            });
	            this.group.add(handleLabel);

	            var handleLabelPoint = [
	                orient === 'horizontal'
	                    ? textSize / 2
	                    : textSize * 1.5,
	                orient === 'horizontal'
	                    ? (handleIndex === 0 ? -(textSize * 1.5) : (textSize * 1.5))
	                    : (handleIndex === 0 ? -textSize / 2 : textSize / 2)
	            ];

	            var shapes = this._shapes;
	            shapes.handleThumbs[handleIndex] = handleThumb;
	            shapes.handleLabelPoints[handleIndex] = handleLabelPoint;
	            shapes.handleLabels[handleIndex] = handleLabel;
	        },

	        /**
	         * @private
	         */
	        _createIndicator: function (barGroup, itemSize, textSize, orient) {
	            var indicator = createPolygon([[0, 0]], 'move');
	            indicator.position[0] = itemSize[0];
	            indicator.attr({invisible: true, silent: true});
	            barGroup.add(indicator);

	            var textStyleModel = this.visualMapModel.textStyleModel;
	            var indicatorLabel = new graphic.Text({
	                silent: true,
	                invisible: true,
	                style: {
	                    x: 0, y: 0, text: '',
	                    textFont: textStyleModel.getFont(),
	                    fill: textStyleModel.getTextColor()
	                }
	            });
	            this.group.add(indicatorLabel);

	            var indicatorLabelPoint = [
	                orient === 'horizontal' ? textSize / 2 : HOVER_LINK_OUT + 3,
	                0
	            ];

	            var shapes = this._shapes;
	            shapes.indicator = indicator;
	            shapes.indicatorLabel = indicatorLabel;
	            shapes.indicatorLabelPoint = indicatorLabelPoint;
	        },

	        /**
	         * @private
	         */
	        _dragHandle: function (handleIndex, isEnd, dx, dy) {
	            if (!this._useHandle) {
	                return;
	            }

	            this._dragging = !isEnd;

	            if (!isEnd) {
	                // Transform dx, dy to bar coordination.
	                var vertex = this._applyTransform([dx, dy], this._shapes.barGroup, true);
	                this._updateInterval(handleIndex, vertex[1]);

	                // Considering realtime, update view should be executed
	                // before dispatch action.
	                this._updateView();
	            }

	            // dragEnd do not dispatch action when realtime.
	            if (isEnd === !this.visualMapModel.get('realtime')) { // jshint ignore:line
	                this.api.dispatchAction({
	                    type: 'selectDataRange',
	                    from: this.uid,
	                    visualMapId: this.visualMapModel.id,
	                    selected: this._dataInterval.slice()
	                });
	            }

	            if (isEnd) {
	                !this._hovering && this._clearHoverLinkToSeries();
	            }
	            else if (useHoverLinkOnHandle(this.visualMapModel)) {
	                this._doHoverLinkToSeries(this._handleEnds[handleIndex], false);
	            }
	        },

	        /**
	         * @private
	         */
	        _resetInterval: function () {
	            var visualMapModel = this.visualMapModel;

	            var dataInterval = this._dataInterval = visualMapModel.getSelected();
	            var dataExtent = visualMapModel.getExtent();
	            var sizeExtent = [0, visualMapModel.itemSize[1]];

	            this._handleEnds = [
	                linearMap(dataInterval[0], dataExtent, sizeExtent, true),
	                linearMap(dataInterval[1], dataExtent, sizeExtent, true)
	            ];
	        },

	        /**
	         * @private
	         * @param {(number|string)} handleIndex 0 or 1 or 'all'
	         * @param {number} dx
	         * @param {number} dy
	         */
	        _updateInterval: function (handleIndex, delta) {
	            delta = delta || 0;
	            var visualMapModel = this.visualMapModel;
	            var handleEnds = this._handleEnds;
	            var sizeExtent = [0, visualMapModel.itemSize[1]];

	            sliderMove(
	                delta,
	                handleEnds,
	                sizeExtent,
	                handleIndex,
	                // cross is forbiden
	                0
	            );

	            var dataExtent = visualMapModel.getExtent();
	            // Update data interval.
	            this._dataInterval = [
	                linearMap(handleEnds[0], sizeExtent, dataExtent, true),
	                linearMap(handleEnds[1], sizeExtent, dataExtent, true)
	            ];
	        },

	        /**
	         * @private
	         */
	        _updateView: function (forSketch) {
	            var visualMapModel = this.visualMapModel;
	            var dataExtent = visualMapModel.getExtent();
	            var shapes = this._shapes;

	            var outOfRangeHandleEnds = [0, visualMapModel.itemSize[1]];
	            var inRangeHandleEnds = forSketch ? outOfRangeHandleEnds : this._handleEnds;

	            var visualInRange = this._createBarVisual(
	                this._dataInterval, dataExtent, inRangeHandleEnds, 'inRange'
	            );
	            var visualOutOfRange = this._createBarVisual(
	                dataExtent, dataExtent, outOfRangeHandleEnds, 'outOfRange'
	            );

	            shapes.inRange
	                .setStyle({
	                    fill: visualInRange.barColor,
	                    opacity: visualInRange.opacity
	                })
	                .setShape('points', visualInRange.barPoints);
	            shapes.outOfRange
	                .setStyle({
	                    fill: visualOutOfRange.barColor,
	                    opacity: visualOutOfRange.opacity
	                })
	                .setShape('points', visualOutOfRange.barPoints);

	            this._updateHandle(inRangeHandleEnds, visualInRange);
	        },

	        /**
	         * @private
	         */
	        _createBarVisual: function (dataInterval, dataExtent, handleEnds, forceState) {
	            var opts = {
	                forceState: forceState,
	                convertOpacityToAlpha: true
	            };
	            var colorStops = this._makeColorGradient(dataInterval, opts);

	            var symbolSizes = [
	                this.getControllerVisual(dataInterval[0], 'symbolSize', opts),
	                this.getControllerVisual(dataInterval[1], 'symbolSize', opts)
	            ];
	            var barPoints = this._createBarPoints(handleEnds, symbolSizes);

	            return {
	                barColor: new LinearGradient(0, 0, 0, 1, colorStops),
	                barPoints: barPoints,
	                handlesColor: [
	                    colorStops[0].color,
	                    colorStops[colorStops.length - 1].color
	                ]
	            };
	        },

	        /**
	         * @private
	         */
	        _makeColorGradient: function (dataInterval, opts) {
	            // Considering colorHue, which is not linear, so we have to sample
	            // to calculate gradient color stops, but not only caculate head
	            // and tail.
	            var sampleNumber = 100; // Arbitrary value.
	            var colorStops = [];
	            var step = (dataInterval[1] - dataInterval[0]) / sampleNumber;

	            colorStops.push({
	                color: this.getControllerVisual(dataInterval[0], 'color', opts),
	                offset: 0
	            });

	            for (var i = 1; i < sampleNumber; i++) {
	                var currValue = dataInterval[0] + step * i;
	                if (currValue > dataInterval[1]) {
	                    break;
	                }
	                colorStops.push({
	                    color: this.getControllerVisual(currValue, 'color', opts),
	                    offset: i / sampleNumber
	                });
	            }

	            colorStops.push({
	                color: this.getControllerVisual(dataInterval[1], 'color', opts),
	                offset: 1
	            });

	            return colorStops;
	        },

	        /**
	         * @private
	         */
	        _createBarPoints: function (handleEnds, symbolSizes) {
	            var itemSize = this.visualMapModel.itemSize;

	            return [
	                [itemSize[0] - symbolSizes[0], handleEnds[0]],
	                [itemSize[0], handleEnds[0]],
	                [itemSize[0], handleEnds[1]],
	                [itemSize[0] - symbolSizes[1], handleEnds[1]]
	            ];
	        },

	        /**
	         * @private
	         */
	        _createBarGroup: function (itemAlign) {
	            var orient = this._orient;
	            var inverse = this.visualMapModel.get('inverse');

	            return new graphic.Group(
	                (orient === 'horizontal' && !inverse)
	                ? {scale: itemAlign === 'bottom' ? [1, 1] : [-1, 1], rotation: Math.PI / 2}
	                : (orient === 'horizontal' && inverse)
	                ? {scale: itemAlign === 'bottom' ? [-1, 1] : [1, 1], rotation: -Math.PI / 2}
	                : (orient === 'vertical' && !inverse)
	                ? {scale: itemAlign === 'left' ? [1, -1] : [-1, -1]}
	                : {scale: itemAlign === 'left' ? [1, 1] : [-1, 1]}
	            );
	        },

	        /**
	         * @private
	         */
	        _updateHandle: function (handleEnds, visualInRange) {
	            if (!this._useHandle) {
	                return;
	            }

	            var shapes = this._shapes;
	            var visualMapModel = this.visualMapModel;
	            var handleThumbs = shapes.handleThumbs;
	            var handleLabels = shapes.handleLabels;

	            each([0, 1], function (handleIndex) {
	                var handleThumb = handleThumbs[handleIndex];
	                handleThumb.setStyle('fill', visualInRange.handlesColor[handleIndex]);
	                handleThumb.position[1] = handleEnds[handleIndex];

	                // Update handle label position.
	                var textPoint = graphic.applyTransform(
	                    shapes.handleLabelPoints[handleIndex],
	                    graphic.getTransform(handleThumb, this.group)
	                );
	                handleLabels[handleIndex].setStyle({
	                    x: textPoint[0],
	                    y: textPoint[1],
	                    text: visualMapModel.formatValueText(this._dataInterval[handleIndex]),
	                    textVerticalAlign: 'middle',
	                    textAlign: this._applyTransform(
	                        this._orient === 'horizontal'
	                            ? (handleIndex === 0 ? 'bottom' : 'top')
	                            : 'left',
	                        shapes.barGroup
	                    )
	                });
	            }, this);
	        },

	        /**
	         * @private
	         * @param {number} cursorValue
	         * @param {number} textValue
	         * @param {string} [rangeSymbol]
	         * @param {number} [halfHoverLinkSize]
	         */
	        _showIndicator: function (cursorValue, textValue, rangeSymbol, halfHoverLinkSize) {
	            var visualMapModel = this.visualMapModel;
	            var dataExtent = visualMapModel.getExtent();
	            var itemSize = visualMapModel.itemSize;
	            var sizeExtent = [0, itemSize[1]];
	            var pos = linearMap(cursorValue, dataExtent, sizeExtent, true);

	            var shapes = this._shapes;
	            var indicator = shapes.indicator;
	            if (!indicator) {
	                return;
	            }

	            indicator.position[1] = pos;
	            indicator.attr('invisible', false);
	            indicator.setShape('points', createIndicatorPoints(
	                !!rangeSymbol, halfHoverLinkSize, pos, itemSize[1]
	            ));

	            var opts = {convertOpacityToAlpha: true};
	            var color = this.getControllerVisual(cursorValue, 'color', opts);
	            indicator.setStyle('fill', color);

	            // Update handle label position.
	            var textPoint = graphic.applyTransform(
	                shapes.indicatorLabelPoint,
	                graphic.getTransform(indicator, this.group)
	            );

	            var indicatorLabel = shapes.indicatorLabel;
	            indicatorLabel.attr('invisible', false);
	            var align = this._applyTransform('left', shapes.barGroup);
	            var orient = this._orient;
	            indicatorLabel.setStyle({
	                text: (rangeSymbol ? rangeSymbol : '') + visualMapModel.formatValueText(textValue),
	                textVerticalAlign: orient === 'horizontal' ? align : 'middle',
	                textAlign: orient === 'horizontal' ? 'center' : align,
	                x: textPoint[0],
	                y: textPoint[1]
	            });
	        },

	        /**
	         * @private
	         */
	        _enableHoverLinkToSeries: function () {
	            var self = this;
	            this._shapes.barGroup

	                .on('mousemove', function (e) {
	                    self._hovering = true;

	                    if (!self._dragging) {
	                        var itemSize = self.visualMapModel.itemSize;
	                        var pos = self._applyTransform(
	                            [e.offsetX, e.offsetY], self._shapes.barGroup, true, true
	                        );
	                        // For hover link show when hover handle, which might be
	                        // below or upper than sizeExtent.
	                        pos[1] = mathMin(mathMax(0, pos[1]), itemSize[1]);

	                        self._doHoverLinkToSeries(
	                            pos[1],
	                            0 <= pos[0] && pos[0] <= itemSize[0]
	                        );
	                    }
	                })

	                .on('mouseout', function () {
	                    // When mouse is out of handle, hoverLink still need
	                    // to be displayed when realtime is set as false.
	                    self._hovering = false;
	                    !self._dragging && self._clearHoverLinkToSeries();
	                });
	        },

	        /**
	         * @private
	         */
	        _enableHoverLinkFromSeries: function () {
	            var zr = this.api.getZr();

	            if (this.visualMapModel.option.hoverLink) {
	                zr.on('mouseover', this._hoverLinkFromSeriesMouseOver, this);
	                zr.on('mouseout', this._hideIndicator, this);
	            }
	            else {
	                this._clearHoverLinkFromSeries();
	            }
	        },

	        /**
	         * @private
	         */
	        _doHoverLinkToSeries: function (cursorPos, hoverOnBar) {
	            var visualMapModel = this.visualMapModel;
	            var itemSize = visualMapModel.itemSize;

	            if (!visualMapModel.option.hoverLink) {
	                return;
	            }

	            var sizeExtent = [0, itemSize[1]];
	            var dataExtent = visualMapModel.getExtent();

	            // For hover link show when hover handle, which might be below or upper than sizeExtent.
	            cursorPos = mathMin(mathMax(sizeExtent[0], cursorPos), sizeExtent[1]);

	            var halfHoverLinkSize = getHalfHoverLinkSize(visualMapModel, dataExtent, sizeExtent);
	            var hoverRange = [cursorPos - halfHoverLinkSize, cursorPos + halfHoverLinkSize];
	            var cursorValue = linearMap(cursorPos, sizeExtent, dataExtent, true);
	            var valueRange = [
	                linearMap(hoverRange[0], sizeExtent, dataExtent, true),
	                linearMap(hoverRange[1], sizeExtent, dataExtent, true)
	            ];
	            // Consider data range is out of visualMap range, see test/visualMap-continuous.html,
	            // where china and india has very large population.
	            hoverRange[0] < sizeExtent[0] && (valueRange[0] = -Infinity);
	            hoverRange[1] > sizeExtent[1] && (valueRange[1] = Infinity);

	            // Do not show indicator when mouse is over handle,
	            // otherwise labels overlap, especially when dragging.
	            if (hoverOnBar) {
	                if (valueRange[0] === -Infinity) {
	                    this._showIndicator(cursorValue, valueRange[1], '< ', halfHoverLinkSize);
	                }
	                else if (valueRange[1] === Infinity) {
	                    this._showIndicator(cursorValue, valueRange[0], '> ', halfHoverLinkSize);
	                }
	                else {
	                    this._showIndicator(cursorValue, cursorValue, '≈ ', halfHoverLinkSize);
	                }
	            }

	            // When realtime is set as false, handles, which are in barGroup,
	            // also trigger hoverLink, which help user to realize where they
	            // focus on when dragging. (see test/heatmap-large.html)
	            // When realtime is set as true, highlight will not show when hover
	            // handle, because the label on handle, which displays a exact value
	            // but not range, might mislead users.
	            var oldBatch = this._hoverLinkDataIndices;
	            var newBatch = [];
	            if (hoverOnBar || useHoverLinkOnHandle(visualMapModel)) {
	                newBatch = this._hoverLinkDataIndices = visualMapModel.findTargetDataIndices(valueRange);
	            }

	            var resultBatches = modelUtil.compressBatches(oldBatch, newBatch);
	            this._dispatchHighDown('downplay', helper.convertDataIndex(resultBatches[0]));
	            this._dispatchHighDown('highlight', helper.convertDataIndex(resultBatches[1]));
	        },

	        /**
	         * @private
	         */
	        _hoverLinkFromSeriesMouseOver: function (e) {
	            var el = e.target;
	            var visualMapModel = this.visualMapModel;

	            if (!el || el.dataIndex == null) {
	                return;
	            }

	            var dataModel = this.ecModel.getSeriesByIndex(el.seriesIndex);

	            if (!visualMapModel.isTargetSeries(dataModel)) {
	                return;
	            }

	            var data = dataModel.getData(el.dataType);
	            var dim = data.getDimension(visualMapModel.getDataDimension(data));
	            var value = data.get(dim, el.dataIndex, true);

	            if (!isNaN(value)) {
	                this._showIndicator(value, value);
	            }
	        },

	        /**
	         * @private
	         */
	        _hideIndicator: function () {
	            var shapes = this._shapes;
	            shapes.indicator && shapes.indicator.attr('invisible', true);
	            shapes.indicatorLabel && shapes.indicatorLabel.attr('invisible', true);
	        },

	        /**
	         * @private
	         */
	        _clearHoverLinkToSeries: function () {
	            this._hideIndicator();

	            var indices = this._hoverLinkDataIndices;

	            this._dispatchHighDown('downplay', helper.convertDataIndex(indices));

	            indices.length = 0;
	        },

	        /**
	         * @private
	         */
	        _clearHoverLinkFromSeries: function () {
	            this._hideIndicator();

	            var zr = this.api.getZr();
	            zr.off('mouseover', this._hoverLinkFromSeriesMouseOver);
	            zr.off('mouseout', this._hideIndicator);
	        },

	        /**
	         * @private
	         */
	        _applyTransform: function (vertex, element, inverse, global) {
	            var transform = graphic.getTransform(element, global ? null : this.group);

	            return graphic[
	                zrUtil.isArray(vertex) ? 'applyTransform' : 'transformDirection'
	            ](vertex, transform, inverse);
	        },

	        /**
	         * @private
	         */
	        _dispatchHighDown: function (type, batch) {
	            batch && batch.length && this.api.dispatchAction({
	                type: type,
	                batch: batch
	            });
	        },

	        /**
	         * @override
	         */
	        dispose: function () {
	            this._clearHoverLinkFromSeries();
	            this._clearHoverLinkToSeries();
	        },

	        /**
	         * @override
	         */
	        remove: function () {
	            this._clearHoverLinkFromSeries();
	            this._clearHoverLinkToSeries();
	        }

	    });

	    function createPolygon(points, cursor, onDrift, onDragEnd) {
	        return new graphic.Polygon({
	            shape: {points: points},
	            draggable: !!onDrift,
	            cursor: cursor,
	            drift: onDrift,
	            onmousemove: function (e) {
	                // Fot mobile devicem, prevent screen slider on the button.
	                eventTool.stop(e.event);
	            },
	            ondragend: onDragEnd
	        });
	    }

	    function createHandlePoints(handleIndex, textSize) {
	        return handleIndex === 0
	            ? [[0, 0], [textSize, 0], [textSize, -textSize]]
	            : [[0, 0], [textSize, 0], [textSize, textSize]];
	    }

	    function createIndicatorPoints(isRange, halfHoverLinkSize, pos, extentMax) {
	        return isRange
	            ? [ // indicate range
	                [0, -mathMin(halfHoverLinkSize, mathMax(pos, 0))],
	                [HOVER_LINK_OUT, 0],
	                [0, mathMin(halfHoverLinkSize, mathMax(extentMax - pos, 0))]
	            ]
	            : [ // indicate single value
	                [0, 0], [5, -5], [5, 5]
	            ];
	    }

	    function getHalfHoverLinkSize(visualMapModel, dataExtent, sizeExtent) {
	        var halfHoverLinkSize = HOVER_LINK_SIZE / 2;
	        var hoverLinkDataSize = visualMapModel.get('hoverLinkDataSize');
	        if (hoverLinkDataSize) {
	            halfHoverLinkSize = linearMap(hoverLinkDataSize, dataExtent, sizeExtent, true) / 2;
	        }
	        return halfHoverLinkSize;
	    }

	    function useHoverLinkOnHandle(visualMapModel) {
	        return !visualMapModel.get('realtime') && visualMapModel.get('hoverLinkOnHandle');
	    }

	    module.exports = ContinuousView;



/***/ },
/* 385 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);
	    var graphic = __webpack_require__(18);
	    var formatUtil = __webpack_require__(6);
	    var layout = __webpack_require__(71);
	    var echarts = __webpack_require__(1);
	    var VisualMapping = __webpack_require__(203);

	    module.exports = echarts.extendComponentView({

	        type: 'visualMap',

	        /**
	         * @readOnly
	         * @type {Object}
	         */
	        autoPositionValues: {left: 1, right: 1, top: 1, bottom: 1},

	        init: function (ecModel, api) {
	            /**
	             * @readOnly
	             * @type {module:echarts/model/Global}
	             */
	            this.ecModel = ecModel;

	            /**
	             * @readOnly
	             * @type {module:echarts/ExtensionAPI}
	             */
	            this.api = api;

	            /**
	             * @readOnly
	             * @type {module:echarts/component/visualMap/visualMapModel}
	             */
	            this.visualMapModel;
	        },

	        /**
	         * @protected
	         */
	        render: function (visualMapModel, ecModel, api, payload) {
	            this.visualMapModel = visualMapModel;

	            if (visualMapModel.get('show') === false) {
	                this.group.removeAll();
	                return;
	            }

	            this.doRender.apply(this, arguments);
	        },

	        /**
	         * @protected
	         */
	        renderBackground: function (group) {
	            var visualMapModel = this.visualMapModel;
	            var padding = formatUtil.normalizeCssArray(visualMapModel.get('padding') || 0);
	            var rect = group.getBoundingRect();

	            group.add(new graphic.Rect({
	                z2: -1, // Lay background rect on the lowest layer.
	                silent: true,
	                shape: {
	                    x: rect.x - padding[3],
	                    y: rect.y - padding[0],
	                    width: rect.width + padding[3] + padding[1],
	                    height: rect.height + padding[0] + padding[2]
	                },
	                style: {
	                    fill: visualMapModel.get('backgroundColor'),
	                    stroke: visualMapModel.get('borderColor'),
	                    lineWidth: visualMapModel.get('borderWidth')
	                }
	            }));
	        },

	        /**
	         * @protected
	         * @param {number} targetValue can be Infinity or -Infinity
	         * @param {string=} visualCluster Only can be 'color' 'opacity' 'symbol' 'symbolSize'
	         * @param {Object} [opts]
	         * @param {string=} [opts.forceState] Specify state, instead of using getValueState method.
	         * @param {string=} [opts.convertOpacityToAlpha=false] For color gradient in controller widget.
	         * @return {*} Visual value.
	         */
	        getControllerVisual: function (targetValue, visualCluster, opts) {
	            opts = opts || {};

	            var forceState = opts.forceState;
	            var visualMapModel = this.visualMapModel;
	            var visualObj = {};

	            // Default values.
	            if (visualCluster === 'symbol') {
	                visualObj.symbol = visualMapModel.get('itemSymbol');
	            }
	            if (visualCluster === 'color') {
	                var defaultColor = visualMapModel.get('contentColor');
	                visualObj.color = defaultColor;
	            }

	            function getter(key) {
	                return visualObj[key];
	            }

	            function setter(key, value) {
	                visualObj[key] = value;
	            }

	            var mappings = visualMapModel.controllerVisuals[
	                forceState || visualMapModel.getValueState(targetValue)
	            ];
	            var visualTypes = VisualMapping.prepareVisualTypes(mappings);

	            zrUtil.each(visualTypes, function (type) {
	                var visualMapping = mappings[type];
	                if (opts.convertOpacityToAlpha && type === 'opacity') {
	                    type = 'colorAlpha';
	                    visualMapping = mappings.__alphaForOpacity;
	                }
	                if (VisualMapping.dependsOn(type, visualCluster)) {
	                    visualMapping && visualMapping.applyVisual(
	                        targetValue, getter, setter
	                    );
	                }
	            });

	            return visualObj[visualCluster];
	        },

	        /**
	         * @protected
	         */
	        positionGroup: function (group) {
	            var model = this.visualMapModel;
	            var api = this.api;

	            layout.positionElement(
	                group,
	                model.getBoxLayoutParams(),
	                {width: api.getWidth(), height: api.getHeight()}
	            );
	        },

	        /**
	         * @protected
	         * @abstract
	         */
	        doRender: zrUtil.noop

	    });



/***/ },
/* 386 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);
	    var layout = __webpack_require__(71);

	    var helper = {

	        /**
	         * @param {module:echarts/component/visualMap/VisualMapModel} visualMapModel\
	         * @param {module:echarts/ExtensionAPI} api
	         * @param {Array.<number>} itemSize always [short, long]
	         * @return {string} 'left' or 'right' or 'top' or 'bottom'
	         */
	        getItemAlign: function (visualMapModel, api, itemSize) {
	            var modelOption = visualMapModel.option;
	            var itemAlign = modelOption.align;

	            if (itemAlign != null && itemAlign !== 'auto') {
	                return itemAlign;
	            }

	            // Auto decision align.
	            var ecSize = {width: api.getWidth(), height: api.getHeight()};
	            var realIndex = modelOption.orient === 'horizontal' ? 1 : 0;

	            var paramsSet = [
	                ['left', 'right', 'width'],
	                ['top', 'bottom', 'height']
	            ];
	            var reals = paramsSet[realIndex];
	            var fakeValue = [0, null, 10];

	            var layoutInput = {};
	            for (var i = 0; i < 3; i++) {
	                layoutInput[paramsSet[1 - realIndex][i]] = fakeValue[i];
	                layoutInput[reals[i]] = i === 2 ? itemSize[0] : modelOption[reals[i]];
	            }

	            var rParam = [['x', 'width', 3], ['y', 'height', 0]][realIndex];
	            var rect = layout.getLayoutRect(layoutInput, ecSize, modelOption.padding);

	            return reals[
	                (rect.margin[rParam[2]] || 0) + rect[rParam[0]] + rect[rParam[1]] * 0.5
	                    < ecSize[rParam[1]] * 0.5 ? 0 : 1
	            ];
	        },

	        /**
	         * Prepare dataIndex for outside usage, where dataIndex means rawIndex, and
	         * dataIndexInside means filtered index.
	         */
	        convertDataIndex: function (batch) {
	            zrUtil.each(batch || [], function (batchItem) {
	                if (batch.dataIndex != null) {
	                    batch.dataIndexInside = batch.dataIndex;
	                    batch.dataIndex = null;
	                }
	            });
	            return batch;
	        }

	    };


	    module.exports = helper;



/***/ },
/* 387 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @file Data range action
	 */


	    var echarts = __webpack_require__(1);

	    var actionInfo = {
	        type: 'selectDataRange',
	        event: 'dataRangeSelected',
	        // FIXME use updateView appears wrong
	        update: 'update'
	    };

	    echarts.registerAction(actionInfo, function (payload, ecModel) {

	        ecModel.eachComponent({mainType: 'visualMap', query: payload}, function (model) {
	            model.setSelected(payload.selected);
	        });

	    });



/***/ },
/* 388 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * DataZoom component entry
	 */


	    __webpack_require__(1).registerPreprocessor(
	        __webpack_require__(378)
	    );

	    __webpack_require__(379);
	    __webpack_require__(380);
	    __webpack_require__(389);
	    __webpack_require__(390);
	    __webpack_require__(387);



/***/ },
/* 389 */
/***/ function(module, exports, __webpack_require__) {

	

	    var VisualMapModel = __webpack_require__(382);
	    var zrUtil = __webpack_require__(4);
	    var VisualMapping = __webpack_require__(203);
	    var visualDefault = __webpack_require__(383);
	    var reformIntervals = __webpack_require__(7).reformIntervals;

	    var PiecewiseModel = VisualMapModel.extend({

	        type: 'visualMap.piecewise',

	        /**
	         * Order Rule:
	         *
	         * option.categories / option.pieces / option.text / option.selected:
	         *     If !option.inverse,
	         *     Order when vertical: ['top', ..., 'bottom'].
	         *     Order when horizontal: ['left', ..., 'right'].
	         *     If option.inverse, the meaning of
	         *     the order should be reversed.
	         *
	         * this._pieceList:
	         *     The order is always [low, ..., high].
	         *
	         * Mapping from location to low-high:
	         *     If !option.inverse
	         *     When vertical, top is high.
	         *     When horizontal, right is high.
	         *     If option.inverse, reverse.
	         */

	        /**
	         * @protected
	         */
	        defaultOption: {
	            selected: null,             // Object. If not specified, means selected.
	                                        // When pieces and splitNumber: {'0': true, '5': true}
	                                        // When categories: {'cate1': false, 'cate3': true}
	                                        // When selected === false, means all unselected.

	            minOpen: false,             // Whether include values that smaller than `min`.
	            maxOpen: false,             // Whether include values that bigger than `max`.

	            align: 'auto',              // 'auto', 'left', 'right'
	            itemWidth: 20,              // When put the controller vertically, it is the length of
	                                        // horizontal side of each item. Otherwise, vertical side.
	            itemHeight: 14,             // When put the controller vertically, it is the length of
	                                        // vertical side of each item. Otherwise, horizontal side.
	            itemSymbol: 'roundRect',
	            pieceList: null,            // Each item is Object, with some of those attrs:
	                                        // {min, max, lt, gt, lte, gte, value,
	                                        // color, colorSaturation, colorAlpha, opacity,
	                                        // symbol, symbolSize}, which customize the range or visual
	                                        // coding of the certain piece. Besides, see "Order Rule".
	            categories: null,           // category names, like: ['some1', 'some2', 'some3'].
	                                        // Attr min/max are ignored when categories set. See "Order Rule"
	            splitNumber: 5,             // If set to 5, auto split five pieces equally.
	                                        // If set to 0 and component type not set, component type will be
	                                        // determined as "continuous". (It is less reasonable but for ec2
	                                        // compatibility, see echarts/component/visualMap/typeDefaulter)
	            selectedMode: 'multiple',   // Can be 'multiple' or 'single'.
	            itemGap: 10,                // The gap between two items, in px.
	            hoverLink: true,            // Enable hover highlight.

	            showLabel: null             // By default, when text is used, label will hide (the logic
	                                        // is remained for compatibility reason)
	        },

	        /**
	         * @override
	         */
	        optionUpdated: function (newOption, isInit) {
	            PiecewiseModel.superApply(this, 'optionUpdated', arguments);

	            /**
	             * The order is always [low, ..., high].
	             * [{text: string, interval: Array.<number>}, ...]
	             * @private
	             * @type {Array.<Object>}
	             */
	            this._pieceList = [];

	            this.resetTargetSeries();
	            this.resetExtent();

	            /**
	             * 'pieces', 'categories', 'splitNumber'
	             * @type {string}
	             */
	            var mode = this._mode = this._determineMode();

	            resetMethods[this._mode].call(this);

	            this._resetSelected(newOption, isInit);

	            var categories = this.option.categories;

	            this.resetVisual(function (mappingOption, state) {
	                if (mode === 'categories') {
	                    mappingOption.mappingMethod = 'category';
	                    mappingOption.categories = zrUtil.clone(categories);
	                }
	                else {
	                    mappingOption.dataExtent = this.getExtent();
	                    mappingOption.mappingMethod = 'piecewise';
	                    mappingOption.pieceList = zrUtil.map(this._pieceList, function (piece) {
	                        var piece = zrUtil.clone(piece);
	                        if (state !== 'inRange') {
	                            // FIXME
	                            // outOfRange do not support special visual in pieces.
	                            piece.visual = null;
	                        }
	                        return piece;
	                    });
	                }
	            });
	        },

	        /**
	         * @protected
	         * @override
	         */
	        completeVisualOption: function () {
	            // Consider this case:
	            // visualMap: {
	            //      pieces: [{symbol: 'circle', lt: 0}, {symbol: 'rect', gte: 0}]
	            // }
	            // where no inRange/outOfRange set but only pieces. So we should make
	            // default inRange/outOfRange for this case, otherwise visuals that only
	            // appear in `pieces` will not be taken into account in visual encoding.

	            var option = this.option;
	            var visualTypesInPieces = {};
	            var visualTypes = VisualMapping.listVisualTypes();
	            var isCategory = this.isCategory();

	            zrUtil.each(option.pieces, function (piece) {
	                zrUtil.each(visualTypes, function (visualType) {
	                    if (piece.hasOwnProperty(visualType)) {
	                        visualTypesInPieces[visualType] = 1;
	                    }
	                });
	            });

	            zrUtil.each(visualTypesInPieces, function (v, visualType) {
	                var exists = 0;
	                zrUtil.each(this.stateList, function (state) {
	                    exists |= has(option, state, visualType)
	                        || has(option.target, state, visualType);
	                }, this);

	                !exists && zrUtil.each(this.stateList, function (state) {
	                    (option[state] || (option[state] = {}))[visualType] = visualDefault.get(
	                        visualType, state === 'inRange' ? 'active' : 'inactive', isCategory
	                    );
	                });
	            }, this);

	            function has(obj, state, visualType) {
	                return obj && obj[state] && (
	                    zrUtil.isObject(obj[state])
	                        ? obj[state].hasOwnProperty(visualType)
	                        : obj[state] === visualType // e.g., inRange: 'symbol'
	                );
	            }

	            VisualMapModel.prototype.completeVisualOption.apply(this, arguments);
	        },

	        _resetSelected: function (newOption, isInit) {
	            var thisOption = this.option;
	            var pieceList = this._pieceList;

	            // Selected do not merge but all override.
	            var selected = (isInit ? thisOption : newOption).selected || {};
	            thisOption.selected = selected;

	            // Consider 'not specified' means true.
	            zrUtil.each(pieceList, function (piece, index) {
	                var key = this.getSelectedMapKey(piece);
	                if (!selected.hasOwnProperty(key)) {
	                    selected[key] = true;
	                }
	            }, this);

	            if (thisOption.selectedMode === 'single') {
	                // Ensure there is only one selected.
	                var hasSel = false;

	                zrUtil.each(pieceList, function (piece, index) {
	                    var key = this.getSelectedMapKey(piece);
	                    if (selected[key]) {
	                        hasSel
	                            ? (selected[key] = false)
	                            : (hasSel = true);
	                    }
	                }, this);
	            }
	            // thisOption.selectedMode === 'multiple', default: all selected.
	        },

	        /**
	         * @public
	         */
	        getSelectedMapKey: function (piece) {
	            return this._mode === 'categories'
	                ? piece.value + '' : piece.index + '';
	        },

	        /**
	         * @public
	         */
	        getPieceList: function () {
	            return this._pieceList;
	        },

	        /**
	         * @private
	         * @return {string}
	         */
	        _determineMode: function () {
	            var option = this.option;

	            return option.pieces && option.pieces.length > 0
	                ? 'pieces'
	                : this.option.categories
	                ? 'categories'
	                : 'splitNumber';
	        },

	        /**
	         * @public
	         * @override
	         */
	        setSelected: function (selected) {
	            this.option.selected = zrUtil.clone(selected);
	        },

	        /**
	         * @public
	         * @override
	         */
	        getValueState: function (value) {
	            var index = VisualMapping.findPieceIndex(value, this._pieceList);

	            return index != null
	                ? (this.option.selected[this.getSelectedMapKey(this._pieceList[index])]
	                    ? 'inRange' : 'outOfRange'
	                )
	                : 'outOfRange';
	        },

	        /**
	         * @public
	         * @params {number} pieceIndex piece index in visualMapModel.getPieceList()
	         * @return {Array.<Object>} [{seriesId, dataIndices: <Array.<number>>}, ...]
	         */
	        findTargetDataIndices: function (pieceIndex) {
	            var result = [];

	            this.eachTargetSeries(function (seriesModel) {
	                var dataIndices = [];
	                var data = seriesModel.getData();

	                data.each(this.getDataDimension(data), function (value, dataIndex) {
	                    // Should always base on model pieceList, because it is order sensitive.
	                    var pIdx = VisualMapping.findPieceIndex(value, this._pieceList);
	                    pIdx === pieceIndex && dataIndices.push(dataIndex);
	                }, true, this);

	                result.push({seriesId: seriesModel.id, dataIndex: dataIndices});
	            }, this);

	            return result;
	        },

	        /**
	         * @private
	         * @param {Object} piece piece.value or piece.interval is required.
	         * @return {number} Can be Infinity or -Infinity
	         */
	        getRepresentValue: function (piece) {
	            var representValue;
	            if (this.isCategory()) {
	                representValue = piece.value;
	            }
	            else {
	                if (piece.value != null) {
	                    representValue = piece.value;
	                }
	                else {
	                    var pieceInterval = piece.interval || [];
	                    representValue = (pieceInterval[0] === -Infinity && pieceInterval[1] === Infinity)
	                        ? 0
	                        : (pieceInterval[0] + pieceInterval[1]) / 2;
	                }
	            }
	            return representValue;
	        },

	        getVisualMeta: function (getColorVisual) {
	            // Do not support category. (category axis is ordinal, numerical)
	            if (this.isCategory()) {
	                return;
	            }

	            var stops = [];
	            var outerColors = [];
	            var visualMapModel = this;

	            function setStop(interval, valueState) {
	                var representValue = visualMapModel.getRepresentValue({interval: interval});
	                if (!valueState) {
	                    valueState = visualMapModel.getValueState(representValue);
	                }
	                var color = getColorVisual(representValue, valueState);
	                if (interval[0] === -Infinity) {
	                    outerColors[0] = color;
	                }
	                else if (interval[1] === Infinity) {
	                    outerColors[1] = color;
	                }
	                else {
	                    stops.push(
	                        {value: interval[0], color: color},
	                        {value: interval[1], color: color}
	                    );
	                }
	            }

	            // Suplement
	            var pieceList = this._pieceList.slice();
	            if (!pieceList.length) {
	                pieceList.push({interval: [-Infinity, Infinity]});
	            }
	            else {
	                var edge = pieceList[0].interval[0];
	                edge !== -Infinity && pieceList.unshift({interval: [-Infinity, edge]});
	                edge = pieceList[pieceList.length - 1].interval[1];
	                edge !== Infinity && pieceList.push({interval: [edge, Infinity]});
	            }

	            var curr = -Infinity;
	            zrUtil.each(pieceList, function (piece) {
	                var interval = piece.interval;
	                if (interval) {
	                    // Fulfill gap.
	                    interval[0] > curr && setStop([curr, interval[0]], 'outOfRange');
	                    setStop(interval.slice());
	                    curr = interval[1];
	                }
	            }, this);

	            return {stops: stops, outerColors: outerColors};
	        }

	    });

	    /**
	     * Key is this._mode
	     * @type {Object}
	     * @this {module:echarts/component/viusalMap/PiecewiseMode}
	     */
	    var resetMethods = {

	        splitNumber: function () {
	            var thisOption = this.option;
	            var pieceList = this._pieceList;
	            var precision = thisOption.precision;
	            var dataExtent = this.getExtent();
	            var splitNumber = thisOption.splitNumber;
	            splitNumber = Math.max(parseInt(splitNumber, 10), 1);
	            thisOption.splitNumber = splitNumber;

	            var splitStep = (dataExtent[1] - dataExtent[0]) / splitNumber;
	            // Precision auto-adaption
	            while (+splitStep.toFixed(precision) !== splitStep && precision < 5) {
	                precision++;
	            }
	            thisOption.precision = precision;
	            splitStep = +splitStep.toFixed(precision);

	            var index = 0;

	            if (thisOption.minOpen) {
	                pieceList.push({
	                    index: index++,
	                    interval: [-Infinity, dataExtent[0]],
	                    close: [0, 0]
	                });
	            }

	            for (
	                var curr = dataExtent[0], len = index + splitNumber;
	                index < len;
	                curr += splitStep
	            ) {
	                var max = index === splitNumber - 1 ? dataExtent[1] : (curr + splitStep);

	                pieceList.push({
	                    index: index++,
	                    interval: [curr, max],
	                    close: [1, 1]
	                });
	            }

	            if (thisOption.maxOpen) {
	                pieceList.push({
	                    index: index++,
	                    interval: [dataExtent[1], Infinity],
	                    close: [0, 0]
	                });
	            }

	            reformIntervals(pieceList);

	            zrUtil.each(pieceList, function (piece) {
	                piece.text = this.formatValueText(piece.interval);
	            }, this);
	        },

	        categories: function () {
	            var thisOption = this.option;
	            zrUtil.each(thisOption.categories, function (cate) {
	                // FIXME category模式也使用pieceList，但在visualMapping中不是使用pieceList。
	                // 是否改一致。
	                this._pieceList.push({
	                    text: this.formatValueText(cate, true),
	                    value: cate
	                });
	            }, this);

	            // See "Order Rule".
	            normalizeReverse(thisOption, this._pieceList);
	        },

	        pieces: function () {
	            var thisOption = this.option;
	            var pieceList = this._pieceList;

	            zrUtil.each(thisOption.pieces, function (pieceListItem, index) {

	                if (!zrUtil.isObject(pieceListItem)) {
	                    pieceListItem = {value: pieceListItem};
	                }

	                var item = {text: '', index: index};

	                if (pieceListItem.label != null) {
	                    item.text = pieceListItem.label;
	                }

	                if (pieceListItem.hasOwnProperty('value')) {
	                    var value = item.value = pieceListItem.value;
	                    item.interval = [value, value];
	                    item.close = [1, 1];
	                }
	                else {
	                    // `min` `max` is legacy option.
	                    // `lt` `gt` `lte` `gte` is recommanded.
	                    var interval = item.interval = [];
	                    var close = item.close = [0, 0];

	                    var closeList = [1, 0, 1];
	                    var infinityList = [-Infinity, Infinity];

	                    var useMinMax = [];
	                    for (var lg = 0; lg < 2; lg++) {
	                        var names = [['gte', 'gt', 'min'], ['lte', 'lt', 'max']][lg];
	                        for (var i = 0; i < 3 && interval[lg] == null; i++) {
	                            interval[lg] = pieceListItem[names[i]];
	                            close[lg] = closeList[i];
	                            useMinMax[lg] = i === 2;
	                        }
	                        interval[lg] == null && (interval[lg] = infinityList[lg]);
	                    }
	                    useMinMax[0] && interval[1] === Infinity && (close[0] = 0);
	                    useMinMax[1] && interval[0] === -Infinity && (close[1] = 0);

	                    if (true) {
	                        if (interval[0] > interval[1]) {
	                            console.warn(
	                                'Piece ' + index + 'is illegal: ' + interval
	                                + ' lower bound should not greater then uppper bound.'
	                            );
	                        }
	                    }

	                    if (interval[0] === interval[1] && close[0] && close[1]) {
	                        // Consider: [{min: 5, max: 5, visual: {...}}, {min: 0, max: 5}],
	                        // we use value to lift the priority when min === max
	                        item.value = interval[0];
	                    }
	                }

	                item.visual = VisualMapping.retrieveVisuals(pieceListItem);

	                pieceList.push(item);

	            }, this);

	            // See "Order Rule".
	            normalizeReverse(thisOption, pieceList);
	            // Only pieces
	            reformIntervals(pieceList);

	            zrUtil.each(pieceList, function (piece) {
	                var close = piece.close;
	                var edgeSymbols = [['<', '≤'][close[1]], ['>', '≥'][close[0]]];
	                piece.text = piece.text || this.formatValueText(
	                    piece.value != null ? piece.value : piece.interval,
	                    false,
	                    edgeSymbols
	                );
	            }, this);
	        }
	    };

	    function normalizeReverse(thisOption, pieceList) {
	        var inverse = thisOption.inverse;
	        if (thisOption.orient === 'vertical' ? !inverse : inverse) {
	             pieceList.reverse();
	        }
	    }

	    module.exports = PiecewiseModel;


/***/ },
/* 390 */
/***/ function(module, exports, __webpack_require__) {

	

	    var VisualMapView = __webpack_require__(385);
	    var zrUtil = __webpack_require__(4);
	    var graphic = __webpack_require__(18);
	    var symbolCreators = __webpack_require__(111);
	    var layout = __webpack_require__(71);
	    var helper = __webpack_require__(386);

	    var PiecewiseVisualMapView = VisualMapView.extend({

	        type: 'visualMap.piecewise',

	        /**
	         * @protected
	         * @override
	         */
	        doRender: function () {
	            var thisGroup = this.group;

	            thisGroup.removeAll();

	            var visualMapModel = this.visualMapModel;
	            var textGap = visualMapModel.get('textGap');
	            var textStyleModel = visualMapModel.textStyleModel;
	            var textFont = textStyleModel.getFont();
	            var textFill = textStyleModel.getTextColor();
	            var itemAlign = this._getItemAlign();
	            var itemSize = visualMapModel.itemSize;
	            var viewData = this._getViewData();
	            var endsText = viewData.endsText;
	            var showLabel = zrUtil.retrieve(visualMapModel.get('showLabel', true), !endsText);

	            endsText && this._renderEndsText(
	                thisGroup, endsText[0], itemSize, showLabel, itemAlign
	            );

	            zrUtil.each(viewData.viewPieceList, renderItem, this);

	            endsText && this._renderEndsText(
	                thisGroup, endsText[1], itemSize, showLabel, itemAlign
	            );

	            layout.box(
	                visualMapModel.get('orient'), thisGroup, visualMapModel.get('itemGap')
	            );

	            this.renderBackground(thisGroup);

	            this.positionGroup(thisGroup);

	            function renderItem(item) {
	                var piece = item.piece;

	                var itemGroup = new graphic.Group();
	                itemGroup.onclick = zrUtil.bind(this._onItemClick, this, piece);

	                this._enableHoverLink(itemGroup, item.indexInModelPieceList);

	                var representValue = visualMapModel.getRepresentValue(piece);

	                this._createItemSymbol(
	                    itemGroup, representValue, [0, 0, itemSize[0], itemSize[1]]
	                );

	                if (showLabel) {
	                    var visualState = this.visualMapModel.getValueState(representValue);

	                    itemGroup.add(new graphic.Text({
	                        style: {
	                            x: itemAlign === 'right' ? -textGap : itemSize[0] + textGap,
	                            y: itemSize[1] / 2,
	                            text: piece.text,
	                            textVerticalAlign: 'middle',
	                            textAlign: itemAlign,
	                            textFont: textFont,
	                            fill: textFill,
	                            opacity: visualState === 'outOfRange' ? 0.5 : 1
	                        }
	                    }));
	                }

	                thisGroup.add(itemGroup);
	            }
	        },

	        /**
	         * @private
	         */
	        _enableHoverLink: function (itemGroup, pieceIndex) {
	            itemGroup
	                .on('mouseover', zrUtil.bind(onHoverLink, this, 'highlight'))
	                .on('mouseout', zrUtil.bind(onHoverLink, this, 'downplay'));

	            function onHoverLink(method) {
	                var visualMapModel = this.visualMapModel;

	                visualMapModel.option.hoverLink && this.api.dispatchAction({
	                    type: method,
	                    batch: helper.convertDataIndex(
	                        visualMapModel.findTargetDataIndices(pieceIndex)
	                    )
	                });
	            }
	        },

	        /**
	         * @private
	         */
	        _getItemAlign: function () {
	            var visualMapModel = this.visualMapModel;
	            var modelOption = visualMapModel.option;

	            if (modelOption.orient === 'vertical') {
	                return helper.getItemAlign(
	                    visualMapModel, this.api, visualMapModel.itemSize
	                );
	            }
	            else { // horizontal, most case left unless specifying right.
	                var align = modelOption.align;
	                if (!align || align === 'auto') {
	                    align = 'left';
	                }
	                return align;
	            }
	        },

	        /**
	         * @private
	         */
	        _renderEndsText: function (group, text, itemSize, showLabel, itemAlign) {
	            if (!text) {
	                return;
	            }

	            var itemGroup = new graphic.Group();
	            var textStyleModel = this.visualMapModel.textStyleModel;

	            itemGroup.add(new graphic.Text({
	                style: {
	                    x: showLabel ? (itemAlign === 'right' ? itemSize[0] : 0) : itemSize[0] / 2,
	                    y: itemSize[1] / 2,
	                    textVerticalAlign: 'middle',
	                    textAlign: showLabel ? itemAlign : 'center',
	                    text: text,
	                    textFont: textStyleModel.getFont(),
	                    fill: textStyleModel.getTextColor()
	                }
	            }));

	            group.add(itemGroup);
	        },

	        /**
	         * @private
	         * @return {Object} {peiceList, endsText} The order is the same as screen pixel order.
	         */
	        _getViewData: function () {
	            var visualMapModel = this.visualMapModel;

	            var viewPieceList = zrUtil.map(visualMapModel.getPieceList(), function (piece, index) {
	                return {piece: piece, indexInModelPieceList: index};
	            });
	            var endsText = visualMapModel.get('text');

	            // Consider orient and inverse.
	            var orient = visualMapModel.get('orient');
	            var inverse = visualMapModel.get('inverse');

	            // Order of model pieceList is always [low, ..., high]
	            if (orient === 'horizontal' ? inverse : !inverse) {
	                viewPieceList.reverse();
	            }
	            // Origin order of endsText is [high, low]
	            else if (endsText) {
	                endsText = endsText.slice().reverse();
	            }

	            return {viewPieceList: viewPieceList, endsText: endsText};
	        },

	        /**
	         * @private
	         */
	        _createItemSymbol: function (group, representValue, shapeParam) {
	            group.add(symbolCreators.createSymbol(
	                this.getControllerVisual(representValue, 'symbol'),
	                shapeParam[0], shapeParam[1], shapeParam[2], shapeParam[3],
	                this.getControllerVisual(representValue, 'color')
	            ));
	        },

	        /**
	         * @private
	         */
	        _onItemClick: function (piece) {
	            var visualMapModel = this.visualMapModel;
	            var option = visualMapModel.option;
	            var selected = zrUtil.clone(option.selected);
	            var newKey = visualMapModel.getSelectedMapKey(piece);

	            if (option.selectedMode === 'single') {
	                selected[newKey] = true;
	                zrUtil.each(selected, function (o, key) {
	                    selected[key] = key === newKey;
	                });
	            }
	            else {
	                selected[newKey] = !selected[newKey];
	            }

	            this.api.dispatchAction({
	                type: 'selectDataRange',
	                from: this.uid,
	                visualMapId: this.visualMapModel.id,
	                selected: selected
	            });
	        }
	    });

	    module.exports = PiecewiseVisualMapView;



/***/ },
/* 391 */
/***/ function(module, exports, __webpack_require__) {

	// HINT Markpoint can't be used too much


	    __webpack_require__(392);
	    __webpack_require__(394);

	    __webpack_require__(1).registerPreprocessor(function (opt) {
	        // Make sure markPoint component is enabled
	        opt.markPoint = opt.markPoint || {};
	    });


/***/ },
/* 392 */
/***/ function(module, exports, __webpack_require__) {

	

	    module.exports = __webpack_require__(393).extend({

	        type: 'markPoint',

	        defaultOption: {
	            zlevel: 0,
	            z: 5,
	            symbol: 'pin',
	            symbolSize: 50,
	            //symbolRotate: 0,
	            //symbolOffset: [0, 0]
	            tooltip: {
	                trigger: 'item'
	            },
	            label: {
	                normal: {
	                    show: true,
	                    position: 'inside'
	                },
	                emphasis: {
	                    show: true
	                }
	            },
	            itemStyle: {
	                normal: {
	                    borderWidth: 2
	                }
	            }
	        }
	    });


/***/ },
/* 393 */
/***/ function(module, exports, __webpack_require__) {

	

	    var modelUtil = __webpack_require__(5);
	    var zrUtil = __webpack_require__(4);
	    var env = __webpack_require__(2);

	    var formatUtil = __webpack_require__(6);
	    var addCommas = formatUtil.addCommas;
	    var encodeHTML = formatUtil.encodeHTML;

	    function fillLabel(opt) {
	        modelUtil.defaultEmphasis(
	            opt.label,
	            modelUtil.LABEL_OPTIONS
	        );
	    }
	    var MarkerModel = __webpack_require__(1).extendComponentModel({

	        type: 'marker',

	        dependencies: ['series', 'grid', 'polar', 'geo'],
	        /**
	         * @overrite
	         */
	        init: function (option, parentModel, ecModel, extraOpt) {

	            if (true) {
	                if (this.type === 'marker') {
	                    throw new Error('Marker component is abstract component. Use markLine, markPoint, markArea instead.');
	                }
	            }
	            this.mergeDefaultAndTheme(option, ecModel);
	            this.mergeOption(option, ecModel, extraOpt.createdBySelf, true);
	        },

	        /**
	         * @return {boolean}
	         */
	        isAnimationEnabled: function () {
	            if (env.node) {
	                return false;
	            }

	            var hostSeries = this.__hostSeries;
	            return this.getShallow('animation') && hostSeries && hostSeries.isAnimationEnabled();
	        },

	        mergeOption: function (newOpt, ecModel, createdBySelf, isInit) {
	            var MarkerModel = this.constructor;
	            var modelPropName = this.mainType + 'Model';
	            if (!createdBySelf) {
	                ecModel.eachSeries(function (seriesModel) {

	                    var markerOpt = seriesModel.get(this.mainType);

	                    var markerModel = seriesModel[modelPropName];
	                    if (!markerOpt || !markerOpt.data) {
	                        seriesModel[modelPropName] = null;
	                        return;
	                    }
	                    if (!markerModel) {
	                        if (isInit) {
	                            // Default label emphasis `position` and `show`
	                            fillLabel(markerOpt);
	                        }
	                        zrUtil.each(markerOpt.data, function (item) {
	                            // FIXME Overwrite fillLabel method ?
	                            if (item instanceof Array) {
	                                fillLabel(item[0]);
	                                fillLabel(item[1]);
	                            }
	                            else {
	                                fillLabel(item);
	                            }
	                        });

	                        markerModel = new MarkerModel(
	                            markerOpt, this, ecModel
	                        );

	                        zrUtil.extend(markerModel, {
	                            mainType: this.mainType,
	                            // Use the same series index and name
	                            seriesIndex: seriesModel.seriesIndex,
	                            name: seriesModel.name,
	                            createdBySelf: true
	                        });

	                        markerModel.__hostSeries = seriesModel;
	                    }
	                    else {
	                        markerModel.mergeOption(markerOpt, ecModel, true);
	                    }
	                    seriesModel[modelPropName] = markerModel;
	                }, this);
	            }
	        },

	        formatTooltip: function (dataIndex) {
	            var data = this.getData();
	            var value = this.getRawValue(dataIndex);
	            var formattedValue = zrUtil.isArray(value)
	                ? zrUtil.map(value, addCommas).join(', ') : addCommas(value);
	            var name = data.getName(dataIndex);
	            var html = encodeHTML(this.name);
	            if (value != null || name) {
	                html += '<br />';
	            }
	            if (name) {
	                html += encodeHTML(name);
	                if (value != null) {
	                    html += ' : ';
	                }
	            }
	            if (value != null) {
	                html += encodeHTML(formattedValue);
	            }
	            return html;
	        },

	        getData: function () {
	            return this._data;
	        },

	        setData: function (data) {
	            this._data = data;
	        }
	    });

	    zrUtil.mixin(MarkerModel, modelUtil.dataFormatMixin);

	    module.exports = MarkerModel;


/***/ },
/* 394 */
/***/ function(module, exports, __webpack_require__) {

	

	    var SymbolDraw = __webpack_require__(116);
	    var zrUtil = __webpack_require__(4);
	    var numberUtil = __webpack_require__(7);

	    var List = __webpack_require__(98);

	    var markerHelper = __webpack_require__(395);

	    function updateMarkerLayout(mpData, seriesModel, api) {
	        var coordSys = seriesModel.coordinateSystem;
	        mpData.each(function (idx) {
	            var itemModel = mpData.getItemModel(idx);
	            var point;
	            var xPx = numberUtil.parsePercent(itemModel.get('x'), api.getWidth());
	            var yPx = numberUtil.parsePercent(itemModel.get('y'), api.getHeight());
	            if (!isNaN(xPx) && !isNaN(yPx)) {
	                point = [xPx, yPx];
	            }
	            // Chart like bar may have there own marker positioning logic
	            else if (seriesModel.getMarkerPosition) {
	                // Use the getMarkerPoisition
	                point = seriesModel.getMarkerPosition(
	                    mpData.getValues(mpData.dimensions, idx)
	                );
	            }
	            else if (coordSys) {
	                var x = mpData.get(coordSys.dimensions[0], idx);
	                var y = mpData.get(coordSys.dimensions[1], idx);
	                point = coordSys.dataToPoint([x, y]);

	            }

	            // Use x, y if has any
	            if (!isNaN(xPx)) {
	                point[0] = xPx;
	            }
	            if (!isNaN(yPx)) {
	                point[1] = yPx;
	            }

	            mpData.setItemLayout(idx, point);
	        });
	    }

	    __webpack_require__(396).extend({

	        type: 'markPoint',

	        updateLayout: function (markPointModel, ecModel, api) {
	            ecModel.eachSeries(function (seriesModel) {
	                var mpModel = seriesModel.markPointModel;
	                if (mpModel) {
	                    updateMarkerLayout(mpModel.getData(), seriesModel, api);
	                    this.markerGroupMap.get(seriesModel.id).updateLayout(mpModel);
	                }
	            }, this);
	        },

	        renderSeries: function (seriesModel, mpModel, ecModel, api) {
	            var coordSys = seriesModel.coordinateSystem;
	            var seriesId = seriesModel.id;
	            var seriesData = seriesModel.getData();

	            var symbolDrawMap = this.markerGroupMap;
	            var symbolDraw = symbolDrawMap.get(seriesId)
	                || symbolDrawMap.set(seriesId, new SymbolDraw());

	            var mpData = createList(coordSys, seriesModel, mpModel);

	            // FIXME
	            mpModel.setData(mpData);

	            updateMarkerLayout(mpModel.getData(), seriesModel, api);

	            mpData.each(function (idx) {
	                var itemModel = mpData.getItemModel(idx);
	                var symbolSize = itemModel.getShallow('symbolSize');
	                if (typeof symbolSize === 'function') {
	                    // FIXME 这里不兼容 ECharts 2.x，2.x 貌似参数是整个数据？
	                    symbolSize = symbolSize(
	                        mpModel.getRawValue(idx), mpModel.getDataParams(idx)
	                    );
	                }
	                mpData.setItemVisual(idx, {
	                    symbolSize: symbolSize,
	                    color: itemModel.get('itemStyle.normal.color')
	                        || seriesData.getVisual('color'),
	                    symbol: itemModel.getShallow('symbol')
	                });
	            });

	            // TODO Text are wrong
	            symbolDraw.updateData(mpData);
	            this.group.add(symbolDraw.group);

	            // Set host model for tooltip
	            // FIXME
	            mpData.eachItemGraphicEl(function (el) {
	                el.traverse(function (child) {
	                    child.dataModel = mpModel;
	                });
	            });

	            symbolDraw.__keep = true;

	            symbolDraw.group.silent = mpModel.get('silent') || seriesModel.get('silent');
	        }
	    });

	    /**
	     * @inner
	     * @param {module:echarts/coord/*} [coordSys]
	     * @param {module:echarts/model/Series} seriesModel
	     * @param {module:echarts/model/Model} mpModel
	     */
	    function createList(coordSys, seriesModel, mpModel) {
	        var coordDimsInfos;
	        if (coordSys) {
	            coordDimsInfos = zrUtil.map(coordSys && coordSys.dimensions, function (coordDim) {
	                var info = seriesModel.getData().getDimensionInfo(
	                    seriesModel.coordDimToDataDim(coordDim)[0]
	                ) || {}; // In map series data don't have lng and lat dimension. Fallback to same with coordSys
	                info.name = coordDim;
	                return info;
	            });
	        }
	        else {
	            coordDimsInfos =[{
	                name: 'value',
	                type: 'float'
	            }];
	        }

	        var mpData = new List(coordDimsInfos, mpModel);
	        var dataOpt = zrUtil.map(mpModel.get('data'), zrUtil.curry(
	                markerHelper.dataTransform, seriesModel
	            ));
	        if (coordSys) {
	            dataOpt = zrUtil.filter(
	                dataOpt, zrUtil.curry(markerHelper.dataFilter, coordSys)
	            );
	        }

	        mpData.initData(dataOpt, null,
	            coordSys ? markerHelper.dimValueGetter : function (item) {
	                return item.value;
	            }
	        );
	        return mpData;
	    }



/***/ },
/* 395 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);
	    var numberUtil = __webpack_require__(7);
	    var indexOf = zrUtil.indexOf;

	    function hasXOrY(item) {
	        return !(isNaN(parseFloat(item.x)) && isNaN(parseFloat(item.y)));
	    }

	    function hasXAndY(item) {
	        return !isNaN(parseFloat(item.x)) && !isNaN(parseFloat(item.y));
	    }

	    function getPrecision(data, valueAxisDim, dataIndex) {
	        var precision = -1;
	        do {
	            precision = Math.max(
	                numberUtil.getPrecision(data.get(
	                    valueAxisDim, dataIndex
	                )),
	                precision
	            );
	            data = data.stackedOn;
	        } while (data);

	        return precision;
	    }

	    function markerTypeCalculatorWithExtent(
	        mlType, data, otherDataDim, targetDataDim, otherCoordIndex, targetCoordIndex
	    ) {
	        var coordArr = [];
	        var value = numCalculate(data, targetDataDim, mlType);

	        var dataIndex = data.indicesOfNearest(targetDataDim, value, true)[0];
	        coordArr[otherCoordIndex] = data.get(otherDataDim, dataIndex, true);
	        coordArr[targetCoordIndex] = data.get(targetDataDim, dataIndex, true);

	        var precision = getPrecision(data, targetDataDim, dataIndex);
	        if (precision >= 0) {
	            coordArr[targetCoordIndex] = +coordArr[targetCoordIndex].toFixed(precision);
	        }

	        return coordArr;
	    }

	    var curry = zrUtil.curry;
	    // TODO Specified percent
	    var markerTypeCalculator = {
	        /**
	         * @method
	         * @param {module:echarts/data/List} data
	         * @param {string} baseAxisDim
	         * @param {string} valueAxisDim
	         */
	        min: curry(markerTypeCalculatorWithExtent, 'min'),
	        /**
	         * @method
	         * @param {module:echarts/data/List} data
	         * @param {string} baseAxisDim
	         * @param {string} valueAxisDim
	         */
	        max: curry(markerTypeCalculatorWithExtent, 'max'),

	        /**
	         * @method
	         * @param {module:echarts/data/List} data
	         * @param {string} baseAxisDim
	         * @param {string} valueAxisDim
	         */
	        average: curry(markerTypeCalculatorWithExtent, 'average')
	    };

	    /**
	     * Transform markPoint data item to format used in List by do the following
	     * 1. Calculate statistic like `max`, `min`, `average`
	     * 2. Convert `item.xAxis`, `item.yAxis` to `item.coord` array
	     * @param  {module:echarts/model/Series} seriesModel
	     * @param  {module:echarts/coord/*} [coordSys]
	     * @param  {Object} item
	     * @return {Object}
	     */
	    var dataTransform = function (seriesModel, item) {
	        var data = seriesModel.getData();
	        var coordSys = seriesModel.coordinateSystem;

	        // 1. If not specify the position with pixel directly
	        // 2. If `coord` is not a data array. Which uses `xAxis`,
	        // `yAxis` to specify the coord on each dimension

	        // parseFloat first because item.x and item.y can be percent string like '20%'
	        if (item && !hasXAndY(item) && !zrUtil.isArray(item.coord) && coordSys) {
	            var dims = coordSys.dimensions;
	            var axisInfo = getAxisInfo(item, data, coordSys, seriesModel);

	            // Clone the option
	            // Transform the properties xAxis, yAxis, radiusAxis, angleAxis, geoCoord to value
	            item = zrUtil.clone(item);

	            if (item.type
	                && markerTypeCalculator[item.type]
	                && axisInfo.baseAxis && axisInfo.valueAxis
	            ) {
	                var otherCoordIndex = indexOf(dims, axisInfo.baseAxis.dim);
	                var targetCoordIndex = indexOf(dims, axisInfo.valueAxis.dim);

	                item.coord = markerTypeCalculator[item.type](
	                    data, axisInfo.baseDataDim, axisInfo.valueDataDim,
	                    otherCoordIndex, targetCoordIndex
	                );
	                // Force to use the value of calculated value.
	                item.value = item.coord[targetCoordIndex];
	            }
	            else {
	                // FIXME Only has one of xAxis and yAxis.
	                var coord = [
	                    item.xAxis != null ? item.xAxis : item.radiusAxis,
	                    item.yAxis != null ? item.yAxis : item.angleAxis
	                ];
	                // Each coord support max, min, average
	                for (var i = 0; i < 2; i++) {
	                    if (markerTypeCalculator[coord[i]]) {
	                        var dataDim = seriesModel.coordDimToDataDim(dims[i])[0];
	                        coord[i] = numCalculate(data, dataDim, coord[i]);
	                    }
	                }
	                item.coord = coord;
	            }
	        }
	        return item;
	    };

	    var getAxisInfo = function (item, data, coordSys, seriesModel) {
	        var ret = {};

	        if (item.valueIndex != null || item.valueDim != null) {
	            ret.valueDataDim = item.valueIndex != null
	                ? data.getDimension(item.valueIndex) : item.valueDim;
	            ret.valueAxis = coordSys.getAxis(seriesModel.dataDimToCoordDim(ret.valueDataDim));
	            ret.baseAxis = coordSys.getOtherAxis(ret.valueAxis);
	            ret.baseDataDim = seriesModel.coordDimToDataDim(ret.baseAxis.dim)[0];
	        }
	        else {
	            ret.baseAxis = seriesModel.getBaseAxis();
	            ret.valueAxis = coordSys.getOtherAxis(ret.baseAxis);
	            ret.baseDataDim = seriesModel.coordDimToDataDim(ret.baseAxis.dim)[0];
	            ret.valueDataDim = seriesModel.coordDimToDataDim(ret.valueAxis.dim)[0];
	        }

	        return ret;
	    };

	    /**
	     * Filter data which is out of coordinateSystem range
	     * [dataFilter description]
	     * @param  {module:echarts/coord/*} [coordSys]
	     * @param  {Object} item
	     * @return {boolean}
	     */
	    var dataFilter = function (coordSys, item) {
	        // Alwalys return true if there is no coordSys
	        return (coordSys && coordSys.containData && item.coord && !hasXOrY(item))
	            ? coordSys.containData(item.coord) : true;
	    };

	    var dimValueGetter = function (item, dimName, dataIndex, dimIndex) {
	        // x, y, radius, angle
	        if (dimIndex < 2) {
	            return item.coord && item.coord[dimIndex];
	        }
	        return item.value;
	    };

	    var numCalculate = function (data, valueDataDim, type) {
	        if (type === 'average') {
	            var sum = 0;
	            var count = 0;
	            data.each(valueDataDim, function (val, idx) {
	                if (!isNaN(val)) {
	                    sum += val;
	                    count++;
	                }
	            }, true);
	            return sum / count;
	        }
	        else {
	            return data.getDataExtent(valueDataDim, true)[type === 'max' ? 1 : 0];
	        }
	    };

	    module.exports = {
	        dataTransform: dataTransform,
	        dataFilter: dataFilter,
	        dimValueGetter: dimValueGetter,
	        getAxisInfo: getAxisInfo,
	        numCalculate: numCalculate
	    };


/***/ },
/* 396 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);

	    module.exports = __webpack_require__(1).extendComponentView({

	        type: 'marker',

	        init: function () {
	            /**
	             * Markline grouped by series
	             * @private
	             * @type {module:zrender/core/util.HashMap}
	             */
	            this.markerGroupMap = zrUtil.createHashMap();
	        },

	        render: function (markerModel, ecModel, api) {
	            var markerGroupMap = this.markerGroupMap;
	            markerGroupMap.each(function (item) {
	                item.__keep = false;
	            });

	            var markerModelKey = this.type + 'Model';
	            ecModel.eachSeries(function (seriesModel) {
	                var markerModel = seriesModel[markerModelKey];
	                markerModel && this.renderSeries(seriesModel, markerModel, ecModel, api);
	            }, this);

	            markerGroupMap.each(function (item) {
	                !item.__keep && this.group.remove(item.group);
	            }, this);
	        },

	        renderSeries: function () {}
	    });


/***/ },
/* 397 */
/***/ function(module, exports, __webpack_require__) {

	

	    __webpack_require__(398);
	    __webpack_require__(399);

	    __webpack_require__(1).registerPreprocessor(function (opt) {
	        // Make sure markLine component is enabled
	        opt.markLine = opt.markLine || {};
	    });


/***/ },
/* 398 */
/***/ function(module, exports, __webpack_require__) {

	

	    module.exports = __webpack_require__(393).extend({

	        type: 'markLine',

	        defaultOption: {
	            zlevel: 0,
	            z: 5,

	            symbol: ['circle', 'arrow'],
	            symbolSize: [8, 16],

	            //symbolRotate: 0,

	            precision: 2,
	            tooltip: {
	                trigger: 'item'
	            },
	            label: {
	                normal: {
	                    show: true,
	                    position: 'end'
	                },
	                emphasis: {
	                    show: true
	                }
	            },
	            lineStyle: {
	                normal: {
	                    type: 'dashed'
	                },
	                emphasis: {
	                    width: 3
	                }
	            },
	            animationEasing: 'linear'
	        }
	    });


/***/ },
/* 399 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);
	    var List = __webpack_require__(98);
	    var numberUtil = __webpack_require__(7);

	    var markerHelper = __webpack_require__(395);

	    var LineDraw = __webpack_require__(210);

	    var markLineTransform = function (seriesModel, coordSys, mlModel, item) {
	        var data = seriesModel.getData();
	        // Special type markLine like 'min', 'max', 'average'
	        var mlType = item.type;

	        if (!zrUtil.isArray(item)
	            && (
	                mlType === 'min' || mlType === 'max' || mlType === 'average'
	                // In case
	                // data: [{
	                //   yAxis: 10
	                // }]
	                || (item.xAxis != null || item.yAxis != null)
	            )
	        ) {
	            var valueAxis;
	            var valueDataDim;
	            var value;

	            if (item.yAxis != null || item.xAxis != null) {
	                valueDataDim = item.yAxis != null ? 'y' : 'x';
	                valueAxis = coordSys.getAxis(valueDataDim);

	                value = zrUtil.retrieve(item.yAxis, item.xAxis);
	            }
	            else {
	                var axisInfo = markerHelper.getAxisInfo(item, data, coordSys, seriesModel);
	                valueDataDim = axisInfo.valueDataDim;
	                valueAxis = axisInfo.valueAxis;
	                value = markerHelper.numCalculate(data, valueDataDim, mlType);
	            }
	            var valueIndex = valueDataDim === 'x' ? 0 : 1;
	            var baseIndex = 1 - valueIndex;

	            var mlFrom = zrUtil.clone(item);
	            var mlTo = {};

	            mlFrom.type = null;

	            mlFrom.coord = [];
	            mlTo.coord = [];
	            mlFrom.coord[baseIndex] = -Infinity;
	            mlTo.coord[baseIndex] = Infinity;

	            var precision = mlModel.get('precision');
	            if (precision >= 0 && typeof value === 'number') {
	                value = +value.toFixed(precision);
	            }

	            mlFrom.coord[valueIndex] = mlTo.coord[valueIndex] = value;

	            item = [mlFrom, mlTo, { // Extra option for tooltip and label
	                type: mlType,
	                valueIndex: item.valueIndex,
	                // Force to use the value of calculated value.
	                value: value
	            }];
	        }

	        item = [
	            markerHelper.dataTransform(seriesModel, item[0]),
	            markerHelper.dataTransform(seriesModel, item[1]),
	            zrUtil.extend({}, item[2])
	        ];

	        // Avoid line data type is extended by from(to) data type
	        item[2].type = item[2].type || '';

	        // Merge from option and to option into line option
	        zrUtil.merge(item[2], item[0]);
	        zrUtil.merge(item[2], item[1]);

	        return item;
	    };

	    function isInifinity(val) {
	        return !isNaN(val) && !isFinite(val);
	    }

	    // If a markLine has one dim
	    function ifMarkLineHasOnlyDim(dimIndex, fromCoord, toCoord, coordSys) {
	        var otherDimIndex = 1 - dimIndex;
	        var dimName = coordSys.dimensions[dimIndex];
	        return isInifinity(fromCoord[otherDimIndex]) && isInifinity(toCoord[otherDimIndex])
	            && fromCoord[dimIndex] === toCoord[dimIndex] && coordSys.getAxis(dimName).containData(fromCoord[dimIndex]);
	    }

	    function markLineFilter(coordSys, item) {
	        if (coordSys.type === 'cartesian2d') {
	            var fromCoord = item[0].coord;
	            var toCoord = item[1].coord;
	            // In case
	            // {
	            //  markLine: {
	            //    data: [{ yAxis: 2 }]
	            //  }
	            // }
	            if (
	                fromCoord && toCoord &&
	                (ifMarkLineHasOnlyDim(1, fromCoord, toCoord, coordSys)
	                || ifMarkLineHasOnlyDim(0, fromCoord, toCoord, coordSys))
	            ) {
	                return true;
	            }
	        }
	        return markerHelper.dataFilter(coordSys, item[0])
	            && markerHelper.dataFilter(coordSys, item[1]);
	    }

	    function updateSingleMarkerEndLayout(
	        data, idx, isFrom, seriesModel, api
	    ) {
	        var coordSys = seriesModel.coordinateSystem;
	        var itemModel = data.getItemModel(idx);

	        var point;
	        var xPx = numberUtil.parsePercent(itemModel.get('x'), api.getWidth());
	        var yPx = numberUtil.parsePercent(itemModel.get('y'), api.getHeight());
	        if (!isNaN(xPx) && !isNaN(yPx)) {
	            point = [xPx, yPx];
	        }
	        else {
	            // Chart like bar may have there own marker positioning logic
	            if (seriesModel.getMarkerPosition) {
	                // Use the getMarkerPoisition
	                point = seriesModel.getMarkerPosition(
	                    data.getValues(data.dimensions, idx)
	                );
	            }
	            else {
	                var dims = coordSys.dimensions;
	                var x = data.get(dims[0], idx);
	                var y = data.get(dims[1], idx);
	                point = coordSys.dataToPoint([x, y]);
	            }
	            // Expand line to the edge of grid if value on one axis is Inifnity
	            // In case
	            //  markLine: {
	            //    data: [{
	            //      yAxis: 2
	            //      // or
	            //      type: 'average'
	            //    }]
	            //  }
	            if (coordSys.type === 'cartesian2d') {
	                var xAxis = coordSys.getAxis('x');
	                var yAxis = coordSys.getAxis('y');
	                var dims = coordSys.dimensions;
	                if (isInifinity(data.get(dims[0], idx))) {
	                    point[0] = xAxis.toGlobalCoord(xAxis.getExtent()[isFrom ? 0 : 1]);
	                }
	                else if (isInifinity(data.get(dims[1], idx))) {
	                    point[1] = yAxis.toGlobalCoord(yAxis.getExtent()[isFrom ? 0 : 1]);
	                }
	            }

	            // Use x, y if has any
	            if (!isNaN(xPx)) {
	                point[0] = xPx;
	            }
	            if (!isNaN(yPx)) {
	                point[1] = yPx;
	            }
	        }

	        data.setItemLayout(idx, point);
	    }

	    __webpack_require__(396).extend({

	        type: 'markLine',

	        updateLayout: function (markLineModel, ecModel, api) {
	            ecModel.eachSeries(function (seriesModel) {
	                var mlModel = seriesModel.markLineModel;
	                if (mlModel) {
	                    var mlData = mlModel.getData();
	                    var fromData = mlModel.__from;
	                    var toData = mlModel.__to;
	                    // Update visual and layout of from symbol and to symbol
	                    fromData.each(function (idx) {
	                        updateSingleMarkerEndLayout(fromData, idx, true, seriesModel, api);
	                        updateSingleMarkerEndLayout(toData, idx, false, seriesModel, api);
	                    });
	                    // Update layout of line
	                    mlData.each(function (idx) {
	                        mlData.setItemLayout(idx, [
	                            fromData.getItemLayout(idx),
	                            toData.getItemLayout(idx)
	                        ]);
	                    });

	                    this.markerGroupMap.get(seriesModel.id).updateLayout();

	                }
	            }, this);
	        },

	        renderSeries: function (seriesModel, mlModel, ecModel, api) {
	            var coordSys = seriesModel.coordinateSystem;
	            var seriesId = seriesModel.id;
	            var seriesData = seriesModel.getData();

	            var lineDrawMap = this.markerGroupMap;
	            var lineDraw = lineDrawMap.get(seriesId)
	                || lineDrawMap.set(seriesId, new LineDraw());
	            this.group.add(lineDraw.group);

	            var mlData = createList(coordSys, seriesModel, mlModel);

	            var fromData = mlData.from;
	            var toData = mlData.to;
	            var lineData = mlData.line;

	            mlModel.__from = fromData;
	            mlModel.__to = toData;
	            // Line data for tooltip and formatter
	            mlModel.setData(lineData);

	            var symbolType = mlModel.get('symbol');
	            var symbolSize = mlModel.get('symbolSize');
	            if (!zrUtil.isArray(symbolType)) {
	                symbolType = [symbolType, symbolType];
	            }
	            if (typeof symbolSize === 'number') {
	                symbolSize = [symbolSize, symbolSize];
	            }

	            // Update visual and layout of from symbol and to symbol
	            mlData.from.each(function (idx) {
	                updateDataVisualAndLayout(fromData, idx, true);
	                updateDataVisualAndLayout(toData, idx, false);
	            });

	            // Update visual and layout of line
	            lineData.each(function (idx) {
	                var lineColor = lineData.getItemModel(idx).get('lineStyle.normal.color');
	                lineData.setItemVisual(idx, {
	                    color: lineColor || fromData.getItemVisual(idx, 'color')
	                });
	                lineData.setItemLayout(idx, [
	                    fromData.getItemLayout(idx),
	                    toData.getItemLayout(idx)
	                ]);

	                lineData.setItemVisual(idx, {
	                    'fromSymbolSize': fromData.getItemVisual(idx, 'symbolSize'),
	                    'fromSymbol': fromData.getItemVisual(idx, 'symbol'),
	                    'toSymbolSize': toData.getItemVisual(idx, 'symbolSize'),
	                    'toSymbol': toData.getItemVisual(idx, 'symbol')
	                });
	            });

	            lineDraw.updateData(lineData);

	            // Set host model for tooltip
	            // FIXME
	            mlData.line.eachItemGraphicEl(function (el, idx) {
	                el.traverse(function (child) {
	                    child.dataModel = mlModel;
	                });
	            });

	            function updateDataVisualAndLayout(data, idx, isFrom) {
	                var itemModel = data.getItemModel(idx);

	                updateSingleMarkerEndLayout(
	                    data, idx, isFrom, seriesModel, api
	                );

	                data.setItemVisual(idx, {
	                    symbolSize: itemModel.get('symbolSize') || symbolSize[isFrom ? 0 : 1],
	                    symbol: itemModel.get('symbol', true) || symbolType[isFrom ? 0 : 1],
	                    color: itemModel.get('itemStyle.normal.color') || seriesData.getVisual('color')
	                });
	            }

	            lineDraw.__keep = true;

	            lineDraw.group.silent = mlModel.get('silent') || seriesModel.get('silent');
	        }
	    });

	    /**
	     * @inner
	     * @param {module:echarts/coord/*} coordSys
	     * @param {module:echarts/model/Series} seriesModel
	     * @param {module:echarts/model/Model} mpModel
	     */
	    function createList(coordSys, seriesModel, mlModel) {

	        var coordDimsInfos;
	        if (coordSys) {
	            coordDimsInfos = zrUtil.map(coordSys && coordSys.dimensions, function (coordDim) {
	                var info = seriesModel.getData().getDimensionInfo(
	                    seriesModel.coordDimToDataDim(coordDim)[0]
	                ) || {}; // In map series data don't have lng and lat dimension. Fallback to same with coordSys
	                info.name = coordDim;
	                return info;
	            });
	        }
	        else {
	            coordDimsInfos =[{
	                name: 'value',
	                type: 'float'
	            }];
	        }

	        var fromData = new List(coordDimsInfos, mlModel);
	        var toData = new List(coordDimsInfos, mlModel);
	        // No dimensions
	        var lineData = new List([], mlModel);

	        var optData = zrUtil.map(mlModel.get('data'), zrUtil.curry(
	            markLineTransform, seriesModel, coordSys, mlModel
	        ));
	        if (coordSys) {
	            optData = zrUtil.filter(
	                optData, zrUtil.curry(markLineFilter, coordSys)
	            );
	        }
	        var dimValueGetter = coordSys ? markerHelper.dimValueGetter : function (item) {
	            return item.value;
	        };
	        fromData.initData(
	            zrUtil.map(optData, function (item) { return item[0]; }),
	            null, dimValueGetter
	        );
	        toData.initData(
	            zrUtil.map(optData, function (item) { return item[1]; }),
	            null, dimValueGetter
	        );
	        lineData.initData(
	            zrUtil.map(optData, function (item) { return item[2]; })
	        );
	        lineData.hasItemOption = true;
	        return {
	            from: fromData,
	            to: toData,
	            line: lineData
	        };
	    }


/***/ },
/* 400 */
/***/ function(module, exports, __webpack_require__) {

	

	    __webpack_require__(401);
	    __webpack_require__(402);

	    __webpack_require__(1).registerPreprocessor(function (opt) {
	        // Make sure markArea component is enabled
	        opt.markArea = opt.markArea || {};
	    });


/***/ },
/* 401 */
/***/ function(module, exports, __webpack_require__) {

	

	    module.exports = __webpack_require__(393).extend({

	        type: 'markArea',

	        defaultOption: {
	            zlevel: 0,
	            // PENDING
	            z: 1,
	            tooltip: {
	                trigger: 'item'
	            },
	            // markArea should fixed on the coordinate system
	            animation: false,
	            label: {
	                normal: {
	                    show: true,
	                    position: 'top'
	                },
	                emphasis: {
	                    show: true,
	                    position: 'top'
	                }
	            },
	            itemStyle: {
	                normal: {
	                    // color and borderColor default to use color from series
	                    // color: 'auto'
	                    // borderColor: 'auto'
	                    borderWidth: 0
	                }
	            }
	        }
	    });


/***/ },
/* 402 */
/***/ function(module, exports, __webpack_require__) {

	// TODO Better on polar


	    var zrUtil = __webpack_require__(4);
	    var List = __webpack_require__(98);
	    var numberUtil = __webpack_require__(7);
	    var graphic = __webpack_require__(18);
	    var colorUtil = __webpack_require__(31);

	    var markerHelper = __webpack_require__(395);

	    var markAreaTransform = function (seriesModel, coordSys, maModel, item) {
	        var lt = markerHelper.dataTransform(seriesModel, item[0]);
	        var rb = markerHelper.dataTransform(seriesModel, item[1]);
	        var retrieve = zrUtil.retrieve;

	        // FIXME make sure lt is less than rb
	        var ltCoord = lt.coord;
	        var rbCoord = rb.coord;
	        ltCoord[0] = retrieve(ltCoord[0], -Infinity);
	        ltCoord[1] = retrieve(ltCoord[1], -Infinity);

	        rbCoord[0] = retrieve(rbCoord[0], Infinity);
	        rbCoord[1] = retrieve(rbCoord[1], Infinity);

	        // Merge option into one
	        var result = zrUtil.mergeAll([{}, lt, rb]);

	        result.coord = [
	            lt.coord, rb.coord
	        ];
	        result.x0 = lt.x;
	        result.y0 = lt.y;
	        result.x1 = rb.x;
	        result.y1 = rb.y;
	        return result;
	    };

	    function isInifinity(val) {
	        return !isNaN(val) && !isFinite(val);
	    }

	    // If a markArea has one dim
	    function ifMarkLineHasOnlyDim(dimIndex, fromCoord, toCoord, coordSys) {
	        var otherDimIndex = 1 - dimIndex;
	        return isInifinity(fromCoord[otherDimIndex]) && isInifinity(toCoord[otherDimIndex]);
	    }

	    function markAreaFilter(coordSys, item) {
	        var fromCoord = item.coord[0];
	        var toCoord = item.coord[1];
	        if (coordSys.type === 'cartesian2d') {
	            // In case
	            // {
	            //  markArea: {
	            //    data: [{ yAxis: 2 }]
	            //  }
	            // }
	            if (
	                fromCoord && toCoord &&
	                (ifMarkLineHasOnlyDim(1, fromCoord, toCoord, coordSys)
	                || ifMarkLineHasOnlyDim(0, fromCoord, toCoord, coordSys))
	            ) {
	                return true;
	            }
	        }
	        return markerHelper.dataFilter(coordSys, {
	                coord: fromCoord,
	                x: item.x0,
	                y: item.y0
	            })
	            || markerHelper.dataFilter(coordSys, {
	                coord: toCoord,
	                x: item.x1,
	                y: item.y1
	            });
	    }

	    // dims can be ['x0', 'y0'], ['x1', 'y1'], ['x0', 'y1'], ['x1', 'y0']
	    function getSingleMarkerEndPoint(data, idx, dims, seriesModel, api) {
	        var coordSys = seriesModel.coordinateSystem;
	        var itemModel = data.getItemModel(idx);

	        var point;
	        var xPx = numberUtil.parsePercent(itemModel.get(dims[0]), api.getWidth());
	        var yPx = numberUtil.parsePercent(itemModel.get(dims[1]), api.getHeight());
	        if (!isNaN(xPx) && !isNaN(yPx)) {
	            point = [xPx, yPx];
	        }
	        else {
	            // Chart like bar may have there own marker positioning logic
	            if (seriesModel.getMarkerPosition) {
	                // Use the getMarkerPoisition
	                point = seriesModel.getMarkerPosition(
	                    data.getValues(dims, idx)
	                );
	            }
	            else {
	                var x = data.get(dims[0], idx);
	                var y = data.get(dims[1], idx);
	                point = coordSys.dataToPoint([x, y], true);
	            }
	            if (coordSys.type === 'cartesian2d') {
	                var xAxis = coordSys.getAxis('x');
	                var yAxis = coordSys.getAxis('y');
	                var x = data.get(dims[0], idx);
	                var y = data.get(dims[1], idx);
	                if (isInifinity(x)) {
	                    point[0] = xAxis.toGlobalCoord(xAxis.getExtent()[dims[0] === 'x0' ? 0 : 1]);
	                }
	                else if (isInifinity(y)) {
	                    point[1] = yAxis.toGlobalCoord(yAxis.getExtent()[dims[1] === 'y0' ? 0 : 1]);
	                }
	            }

	            // Use x, y if has any
	            if (!isNaN(xPx)) {
	                point[0] = xPx;
	            }
	            if (!isNaN(yPx)) {
	                point[1] = yPx;
	            }
	        }

	        return point;
	    }

	    var dimPermutations = [['x0', 'y0'], ['x1', 'y0'], ['x1', 'y1'], ['x0', 'y1']];

	    __webpack_require__(396).extend({

	        type: 'markArea',

	        updateLayout: function (markAreaModel, ecModel, api) {
	            ecModel.eachSeries(function (seriesModel) {
	                var maModel = seriesModel.markAreaModel;
	                if (maModel) {
	                    var areaData = maModel.getData();
	                    areaData.each(function (idx) {
	                        var points = zrUtil.map(dimPermutations, function (dim) {
	                            return getSingleMarkerEndPoint(areaData, idx, dim, seriesModel, api);
	                        });
	                        // Layout
	                        areaData.setItemLayout(idx, points);
	                        var el = areaData.getItemGraphicEl(idx);
	                        el.setShape('points', points);
	                    });
	                }
	            }, this);
	        },

	        renderSeries: function (seriesModel, maModel, ecModel, api) {
	            var coordSys = seriesModel.coordinateSystem;
	            var seriesName = seriesModel.name;
	            var seriesData = seriesModel.getData();

	            var areaGroupMap = this.markerGroupMap;
	            var polygonGroup = areaGroupMap.get(seriesName)
	                || areaGroupMap.set(seriesName, {group: new graphic.Group()});

	            this.group.add(polygonGroup.group);
	            polygonGroup.__keep = true;

	            var areaData = createList(coordSys, seriesModel, maModel);

	            // Line data for tooltip and formatter
	            maModel.setData(areaData);

	            // Update visual and layout of line
	            areaData.each(function (idx) {
	                // Layout
	                areaData.setItemLayout(idx, zrUtil.map(dimPermutations, function (dim) {
	                    return getSingleMarkerEndPoint(areaData, idx, dim, seriesModel, api);
	                }));

	                // Visual
	                areaData.setItemVisual(idx, {
	                    color: seriesData.getVisual('color')
	                });
	            });


	            areaData.diff(polygonGroup.__data)
	                .add(function (idx) {
	                    var polygon = new graphic.Polygon({
	                        shape: {
	                            points: areaData.getItemLayout(idx)
	                        }
	                    });
	                    areaData.setItemGraphicEl(idx, polygon);
	                    polygonGroup.group.add(polygon);
	                })
	                .update(function (newIdx, oldIdx) {
	                    var polygon = polygonGroup.__data.getItemGraphicEl(oldIdx);
	                    graphic.updateProps(polygon, {
	                        shape: {
	                            points: areaData.getItemLayout(newIdx)
	                        }
	                    }, maModel, newIdx);
	                    polygonGroup.group.add(polygon);
	                    areaData.setItemGraphicEl(newIdx, polygon);
	                })
	                .remove(function (idx) {
	                    var polygon = polygonGroup.__data.getItemGraphicEl(idx);
	                    polygonGroup.group.remove(polygon);
	                })
	                .execute();

	            areaData.eachItemGraphicEl(function (polygon, idx) {
	                var itemModel = areaData.getItemModel(idx);
	                var labelModel = itemModel.getModel('label.normal');
	                var labelHoverModel = itemModel.getModel('label.emphasis');
	                var color = areaData.getItemVisual(idx, 'color');
	                polygon.useStyle(
	                    zrUtil.defaults(
	                        itemModel.getModel('itemStyle.normal').getItemStyle(),
	                        {
	                            fill: colorUtil.modifyAlpha(color, 0.4),
	                            stroke: color
	                        }
	                    )
	                );

	                polygon.hoverStyle = itemModel.getModel('itemStyle.normal').getItemStyle();

	                var defaultValue = areaData.getName(idx) || '';
	                var textColor = color || polygon.style.fill;

	                if (labelModel.getShallow('show')) {
	                    graphic.setText(polygon.style, labelModel, textColor);
	                    polygon.style.text = zrUtil.retrieve(
	                        maModel.getFormattedLabel(idx, 'normal'),
	                        defaultValue
	                    );
	                }
	                else {
	                    polygon.style.text = '';
	                }

	                if (labelHoverModel.getShallow('show')) {
	                    graphic.setText(polygon.hoverStyle, labelHoverModel, textColor);
	                    polygon.hoverStyle.text = zrUtil.retrieve(
	                        maModel.getFormattedLabel(idx, 'emphasis'),
	                        defaultValue
	                    );
	                }
	                else {
	                    polygon.hoverStyle.text = '';
	                }

	                graphic.setHoverStyle(polygon, {});

	                polygon.dataModel = maModel;
	            });

	            polygonGroup.__data = areaData;

	            polygonGroup.group.silent = maModel.get('silent') || seriesModel.get('silent');
	        }
	    });

	    /**
	     * @inner
	     * @param {module:echarts/coord/*} coordSys
	     * @param {module:echarts/model/Series} seriesModel
	     * @param {module:echarts/model/Model} mpModel
	     */
	    function createList(coordSys, seriesModel, maModel) {

	        var coordDimsInfos;
	        var areaData;
	        var dims = ['x0', 'y0', 'x1', 'y1'];
	        if (coordSys) {
	            coordDimsInfos = zrUtil.map(coordSys && coordSys.dimensions, function (coordDim) {
	                var info = seriesModel.getData().getDimensionInfo(
	                    seriesModel.coordDimToDataDim(coordDim)[0]
	                ) || {}; // In map series data don't have lng and lat dimension. Fallback to same with coordSys
	                info.name = coordDim;
	                return info;
	            });
	            areaData = new List(zrUtil.map(dims, function (dim, idx) {
	                return {
	                    name: dim,
	                    type: coordDimsInfos[idx % 2].type
	                };
	            }), maModel);
	        }
	        else {
	            coordDimsInfos =[{
	                name: 'value',
	                type: 'float'
	            }];
	            areaData = new List(coordDimsInfos, maModel);
	        }

	        var optData = zrUtil.map(maModel.get('data'), zrUtil.curry(
	            markAreaTransform, seriesModel, coordSys, maModel
	        ));
	        if (coordSys) {
	            optData = zrUtil.filter(
	                optData, zrUtil.curry(markAreaFilter, coordSys)
	            );
	        }

	        var dimValueGetter = coordSys ? function (item, dimName, dataIndex, dimIndex) {
	            return item.coord[Math.floor(dimIndex / 2)][dimIndex % 2];
	        } : function (item) {
	            return item.value;
	        };
	        areaData.initData(optData, null, dimValueGetter);
	        areaData.hasItemOption = true;
	        return areaData;
	    }


/***/ },
/* 403 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * DataZoom component entry
	 */


	    var echarts = __webpack_require__(1);

	    echarts.registerPreprocessor(__webpack_require__(404));

	    __webpack_require__(405);
	    __webpack_require__(406);
	    __webpack_require__(407);
	    __webpack_require__(409);



/***/ },
/* 404 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @file Timeline preprocessor
	 */


	    var zrUtil = __webpack_require__(4);

	    module.exports = function (option) {
	        var timelineOpt = option && option.timeline;

	        if (!zrUtil.isArray(timelineOpt)) {
	            timelineOpt = timelineOpt ? [timelineOpt] : [];
	        }

	        zrUtil.each(timelineOpt, function (opt) {
	            if (!opt) {
	                return;
	            }

	            compatibleEC2(opt);
	        });
	    };

	    function compatibleEC2(opt) {
	        var type = opt.type;

	        var ec2Types = {'number': 'value', 'time': 'time'};

	        // Compatible with ec2
	        if (ec2Types[type]) {
	            opt.axisType = ec2Types[type];
	            delete opt.type;
	        }

	        transferItem(opt);

	        if (has(opt, 'controlPosition')) {
	            var controlStyle = opt.controlStyle || (opt.controlStyle = {});
	            if (!has(controlStyle, 'position')) {
	                controlStyle.position = opt.controlPosition;
	            }
	            if (controlStyle.position === 'none' && !has(controlStyle, 'show')) {
	                controlStyle.show = false;
	                delete controlStyle.position;
	            }
	            delete opt.controlPosition;
	        }

	        zrUtil.each(opt.data || [], function (dataItem) {
	            if (zrUtil.isObject(dataItem) && !zrUtil.isArray(dataItem)) {
	                if (!has(dataItem, 'value') && has(dataItem, 'name')) {
	                    // In ec2, using name as value.
	                    dataItem.value = dataItem.name;
	                }
	                transferItem(dataItem);
	            }
	        });
	    }

	    function transferItem(opt) {
	        var itemStyle = opt.itemStyle || (opt.itemStyle = {});

	        var itemStyleEmphasis = itemStyle.emphasis || (itemStyle.emphasis = {});

	        // Transfer label out
	        var label = opt.label || (opt.label || {});
	        var labelNormal = label.normal || (label.normal = {});
	        var excludeLabelAttr = {normal: 1, emphasis: 1};

	        zrUtil.each(label, function (value, name) {
	            if (!excludeLabelAttr[name] && !has(labelNormal, name)) {
	                labelNormal[name] = value;
	            }
	        });

	        if (itemStyleEmphasis.label && !has(label, 'emphasis')) {
	            label.emphasis = itemStyleEmphasis.label;
	            delete itemStyleEmphasis.label;
	        }
	    }

	    function has(obj, attr) {
	        return obj.hasOwnProperty(attr);
	    }



/***/ },
/* 405 */
/***/ function(module, exports, __webpack_require__) {

	

	    __webpack_require__(69).registerSubTypeDefaulter('timeline', function () {
	        // Only slider now.
	        return 'slider';
	    });



/***/ },
/* 406 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @file Timeilne action
	 */


	    var echarts = __webpack_require__(1);
	    var zrUtil = __webpack_require__(4);

	    echarts.registerAction(

	        {type: 'timelineChange', event: 'timelineChanged', update: 'prepareAndUpdate'},

	        function (payload, ecModel) {

	            var timelineModel = ecModel.getComponent('timeline');
	            if (timelineModel && payload.currentIndex != null) {
	                timelineModel.setCurrentIndex(payload.currentIndex);

	                if (!timelineModel.get('loop', true) && timelineModel.isIndexMax()) {
	                    timelineModel.setPlayState(false);
	                }
	            }

	            // Set normalized currentIndex to payload.
	            ecModel.resetOption('timeline');

	            return zrUtil.defaults({
	                currentIndex: timelineModel.option.currentIndex
	            }, payload);
	        }
	    );

	    echarts.registerAction(

	        {type: 'timelinePlayChange', event: 'timelinePlayChanged', update: 'update'},

	        function (payload, ecModel) {
	            var timelineModel = ecModel.getComponent('timeline');
	            if (timelineModel && payload.playState != null) {
	                timelineModel.setPlayState(payload.playState);
	            }
	        }
	    );



/***/ },
/* 407 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @file Silder timeline model
	 */


	    var TimelineModel = __webpack_require__(408);
	    var zrUtil = __webpack_require__(4);
	    var modelUtil = __webpack_require__(5);

	    var SliderTimelineModel = TimelineModel.extend({

	        type: 'timeline.slider',

	        /**
	         * @protected
	         */
	        defaultOption: {

	            backgroundColor: 'rgba(0,0,0,0)',   // 时间轴背景颜色
	            borderColor: '#ccc',               // 时间轴边框颜色
	            borderWidth: 0,                    // 时间轴边框线宽，单位px，默认为0（无边框）

	            orient: 'horizontal',              // 'vertical'
	            inverse: false,

	            tooltip: {                          // boolean or Object
	                trigger: 'item'                 // data item may also have tootip attr.
	            },

	            symbol: 'emptyCircle',
	            symbolSize: 10,

	            lineStyle: {
	                show: true,
	                width: 2,
	                color: '#304654'
	            },
	            label: {                            // 文本标签
	                position: 'auto',           // auto left right top bottom
	                                            // When using number, label position is not
	                                            // restricted by viewRect.
	                                            // positive: right/bottom, negative: left/top
	                normal: {
	                    show: true,
	                    interval: 'auto',
	                    rotate: 0,
	                    // formatter: null,
	                    textStyle: {                // 其余属性默认使用全局文本样式，详见TEXTSTYLE
	                        color: '#304654'
	                    }
	                },
	                emphasis: {
	                    show: true,
	                    textStyle: {                // 其余属性默认使用全局文本样式，详见TEXTSTYLE
	                        color: '#c23531'
	                    }
	                }
	            },
	            itemStyle: {
	                normal: {
	                    color: '#304654',
	                    borderWidth: 1
	                },
	                emphasis: {
	                    color: '#c23531'
	                }
	            },

	            checkpointStyle: {
	                symbol: 'circle',
	                symbolSize: 13,
	                color: '#c23531',
	                borderWidth: 5,
	                borderColor: 'rgba(194,53,49, 0.5)',
	                animation: true,
	                animationDuration: 300,
	                animationEasing: 'quinticInOut'
	            },

	            controlStyle: {
	                show: true,
	                showPlayBtn: true,
	                showPrevBtn: true,
	                showNextBtn: true,
	                itemSize: 22,
	                itemGap: 12,
	                position: 'left',  // 'left' 'right' 'top' 'bottom'
	                playIcon: 'path://M31.6,53C17.5,53,6,41.5,6,27.4S17.5,1.8,31.6,1.8C45.7,1.8,57.2,13.3,57.2,27.4S45.7,53,31.6,53z M31.6,3.3 C18.4,3.3,7.5,14.1,7.5,27.4c0,13.3,10.8,24.1,24.1,24.1C44.9,51.5,55.7,40.7,55.7,27.4C55.7,14.1,44.9,3.3,31.6,3.3z M24.9,21.3 c0-2.2,1.6-3.1,3.5-2l10.5,6.1c1.899,1.1,1.899,2.9,0,4l-10.5,6.1c-1.9,1.1-3.5,0.2-3.5-2V21.3z', // jshint ignore:line
	                stopIcon: 'path://M30.9,53.2C16.8,53.2,5.3,41.7,5.3,27.6S16.8,2,30.9,2C45,2,56.4,13.5,56.4,27.6S45,53.2,30.9,53.2z M30.9,3.5C17.6,3.5,6.8,14.4,6.8,27.6c0,13.3,10.8,24.1,24.101,24.1C44.2,51.7,55,40.9,55,27.6C54.9,14.4,44.1,3.5,30.9,3.5z M36.9,35.8c0,0.601-0.4,1-0.9,1h-1.3c-0.5,0-0.9-0.399-0.9-1V19.5c0-0.6,0.4-1,0.9-1H36c0.5,0,0.9,0.4,0.9,1V35.8z M27.8,35.8 c0,0.601-0.4,1-0.9,1h-1.3c-0.5,0-0.9-0.399-0.9-1V19.5c0-0.6,0.4-1,0.9-1H27c0.5,0,0.9,0.4,0.9,1L27.8,35.8L27.8,35.8z', // jshint ignore:line
	                nextIcon: 'path://M18.6,50.8l22.5-22.5c0.2-0.2,0.3-0.4,0.3-0.7c0-0.3-0.1-0.5-0.3-0.7L18.7,4.4c-0.1-0.1-0.2-0.3-0.2-0.5 c0-0.4,0.3-0.8,0.8-0.8c0.2,0,0.5,0.1,0.6,0.3l23.5,23.5l0,0c0.2,0.2,0.3,0.4,0.3,0.7c0,0.3-0.1,0.5-0.3,0.7l-0.1,0.1L19.7,52 c-0.1,0.1-0.3,0.2-0.5,0.2c-0.4,0-0.8-0.3-0.8-0.8C18.4,51.2,18.5,51,18.6,50.8z', // jshint ignore:line
	                prevIcon: 'path://M43,52.8L20.4,30.3c-0.2-0.2-0.3-0.4-0.3-0.7c0-0.3,0.1-0.5,0.3-0.7L42.9,6.4c0.1-0.1,0.2-0.3,0.2-0.5 c0-0.4-0.3-0.8-0.8-0.8c-0.2,0-0.5,0.1-0.6,0.3L18.3,28.8l0,0c-0.2,0.2-0.3,0.4-0.3,0.7c0,0.3,0.1,0.5,0.3,0.7l0.1,0.1L41.9,54 c0.1,0.1,0.3,0.2,0.5,0.2c0.4,0,0.8-0.3,0.8-0.8C43.2,53.2,43.1,53,43,52.8z', // jshint ignore:line
	                normal: {
	                    color: '#304654',
	                    borderColor: '#304654',
	                    borderWidth: 1
	                },
	                emphasis: {
	                    color: '#c23531',
	                    borderColor: '#c23531',
	                    borderWidth: 2
	                }
	            },
	            data: []
	        }

	    });

	    zrUtil.mixin(SliderTimelineModel, modelUtil.dataFormatMixin);

	    module.exports = SliderTimelineModel;


/***/ },
/* 408 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @file Timeline model
	 */


	    var ComponentModel = __webpack_require__(69);
	    var List = __webpack_require__(98);
	    var zrUtil = __webpack_require__(4);
	    var modelUtil = __webpack_require__(5);

	    var TimelineModel = ComponentModel.extend({

	        type: 'timeline',

	        layoutMode: 'box',

	        /**
	         * @protected
	         */
	        defaultOption: {

	            zlevel: 0,                  // 一级层叠
	            z: 4,                       // 二级层叠
	            show: true,

	            axisType: 'time',  // 模式是时间类型，支持 value, category

	            realtime: true,

	            left: '20%',
	            top: null,
	            right: '20%',
	            bottom: 0,
	            width: null,
	            height: 40,
	            padding: 5,

	            controlPosition: 'left',           // 'left' 'right' 'top' 'bottom' 'none'
	            autoPlay: false,
	            rewind: false,                     // 反向播放
	            loop: true,
	            playInterval: 2000,                // 播放时间间隔，单位ms

	            currentIndex: 0,

	            itemStyle: {
	                normal: {},
	                emphasis: {}
	            },
	            label: {
	                normal: {
	                    textStyle: {
	                        color: '#000'
	                    }
	                },
	                emphasis: {}
	            },

	            data: []
	        },

	        /**
	         * @override
	         */
	        init: function (option, parentModel, ecModel) {

	            /**
	             * @private
	             * @type {module:echarts/data/List}
	             */
	            this._data;

	            /**
	             * @private
	             * @type {Array.<string>}
	             */
	            this._names;

	            this.mergeDefaultAndTheme(option, ecModel);
	            this._initData();
	        },

	        /**
	         * @override
	         */
	        mergeOption: function (option) {
	            TimelineModel.superApply(this, 'mergeOption', arguments);
	            this._initData();
	        },

	        /**
	         * @param {number} [currentIndex]
	         */
	        setCurrentIndex: function (currentIndex) {
	            if (currentIndex == null) {
	                currentIndex = this.option.currentIndex;
	            }
	            var count = this._data.count();

	            if (this.option.loop) {
	                currentIndex = (currentIndex % count + count) % count;
	            }
	            else {
	                currentIndex >= count && (currentIndex = count - 1);
	                currentIndex < 0 && (currentIndex = 0);
	            }

	            this.option.currentIndex = currentIndex;
	        },

	        /**
	         * @return {number} currentIndex
	         */
	        getCurrentIndex: function () {
	            return this.option.currentIndex;
	        },

	        /**
	         * @return {boolean}
	         */
	        isIndexMax: function () {
	            return this.getCurrentIndex() >= this._data.count() - 1;
	        },

	        /**
	         * @param {boolean} state true: play, false: stop
	         */
	        setPlayState: function (state) {
	            this.option.autoPlay = !!state;
	        },

	        /**
	         * @return {boolean} true: play, false: stop
	         */
	        getPlayState: function () {
	            return !!this.option.autoPlay;
	        },

	        /**
	         * @private
	         */
	        _initData: function () {
	            var thisOption = this.option;
	            var dataArr = thisOption.data || [];
	            var axisType = thisOption.axisType;
	            var names = this._names = [];

	            if (axisType === 'category') {
	                var idxArr = [];
	                zrUtil.each(dataArr, function (item, index) {
	                    var value = modelUtil.getDataItemValue(item);
	                    var newItem;

	                    if (zrUtil.isObject(item)) {
	                        newItem = zrUtil.clone(item);
	                        newItem.value = index;
	                    }
	                    else {
	                        newItem = index;
	                    }

	                    idxArr.push(newItem);

	                    if (!zrUtil.isString(value) && (value == null || isNaN(value))) {
	                        value = '';
	                    }

	                    names.push(value + '');
	                });
	                dataArr = idxArr;
	            }

	            var dimType = ({category: 'ordinal', time: 'time'})[axisType] || 'number';

	            var data = this._data = new List([{name: 'value', type: dimType}], this);

	            data.initData(dataArr, names);
	        },

	        getData: function () {
	            return this._data;
	        },

	        /**
	         * @public
	         * @return {Array.<string>} categoreis
	         */
	        getCategories: function () {
	            if (this.get('axisType') === 'category') {
	                return this._names.slice();
	            }
	        }

	    });

	    module.exports = TimelineModel;


/***/ },
/* 409 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @file Silder timeline view
	 */


	    var zrUtil = __webpack_require__(4);
	    var graphic = __webpack_require__(18);
	    var layout = __webpack_require__(71);
	    var TimelineView = __webpack_require__(410);
	    var TimelineAxis = __webpack_require__(411);
	    var symbolUtil = __webpack_require__(111);
	    var axisHelper = __webpack_require__(101);
	    var BoundingRect = __webpack_require__(9);
	    var matrix = __webpack_require__(11);
	    var numberUtil = __webpack_require__(7);
	    var formatUtil = __webpack_require__(6);
	    var encodeHTML = formatUtil.encodeHTML;

	    var bind = zrUtil.bind;
	    var each = zrUtil.each;

	    var PI = Math.PI;

	    module.exports = TimelineView.extend({

	        type: 'timeline.slider',

	        init: function (ecModel, api) {

	            this.api = api;

	            /**
	             * @private
	             * @type {module:echarts/component/timeline/TimelineAxis}
	             */
	            this._axis;

	            /**
	             * @private
	             * @type {module:zrender/core/BoundingRect}
	             */
	            this._viewRect;

	            /**
	             * @type {number}
	             */
	            this._timer;

	            /**
	             * @type {module:zrender/Element}
	             */
	            this._currentPointer;

	            /**
	             * @type {module:zrender/container/Group}
	             */
	            this._mainGroup;

	            /**
	             * @type {module:zrender/container/Group}
	             */
	            this._labelGroup;
	        },

	        /**
	         * @override
	         */
	        render: function (timelineModel, ecModel, api, payload) {
	            this.model = timelineModel;
	            this.api = api;
	            this.ecModel = ecModel;

	            this.group.removeAll();

	            if (timelineModel.get('show', true)) {

	                var layoutInfo = this._layout(timelineModel, api);
	                var mainGroup = this._createGroup('mainGroup');
	                var labelGroup = this._createGroup('labelGroup');

	                /**
	                 * @private
	                 * @type {module:echarts/component/timeline/TimelineAxis}
	                 */
	                var axis = this._axis = this._createAxis(layoutInfo, timelineModel);

	                timelineModel.formatTooltip = function (dataIndex) {
	                    return encodeHTML(axis.scale.getLabel(dataIndex));
	                };

	                each(
	                    ['AxisLine', 'AxisTick', 'Control', 'CurrentPointer'],
	                    function (name) {
	                        this['_render' + name](layoutInfo, mainGroup, axis, timelineModel);
	                    },
	                    this
	                );

	                this._renderAxisLabel(layoutInfo, labelGroup, axis, timelineModel);
	                this._position(layoutInfo, timelineModel);
	            }

	            this._doPlayStop();
	        },

	        /**
	         * @override
	         */
	        remove: function () {
	            this._clearTimer();
	            this.group.removeAll();
	        },

	        /**
	         * @override
	         */
	        dispose: function () {
	            this._clearTimer();
	        },

	        _layout: function (timelineModel, api) {
	            var labelPosOpt = timelineModel.get('label.normal.position');
	            var orient = timelineModel.get('orient');
	            var viewRect = getViewRect(timelineModel, api);
	            // Auto label offset.
	            if (labelPosOpt == null || labelPosOpt === 'auto') {
	                labelPosOpt = orient === 'horizontal'
	                    ? ((viewRect.y + viewRect.height / 2) < api.getHeight() / 2 ? '-' : '+')
	                    : ((viewRect.x + viewRect.width / 2) < api.getWidth() / 2 ? '+' : '-');
	            }
	            else if (isNaN(labelPosOpt)) {
	                labelPosOpt = ({
	                    horizontal: {top: '-', bottom: '+'},
	                    vertical: {left: '-', right: '+'}
	                })[orient][labelPosOpt];
	            }

	            var labelAlignMap = {
	                horizontal: 'center',
	                vertical: (labelPosOpt >= 0 || labelPosOpt === '+') ? 'left' : 'right'
	            };

	            var labelBaselineMap = {
	                horizontal: (labelPosOpt >= 0 || labelPosOpt === '+') ? 'top' : 'bottom',
	                vertical: 'middle'
	            };
	            var rotationMap = {
	                horizontal: 0,
	                vertical: PI / 2
	            };

	            // Position
	            var mainLength = orient === 'vertical' ? viewRect.height : viewRect.width;

	            var controlModel = timelineModel.getModel('controlStyle');
	            var showControl = controlModel.get('show');
	            var controlSize = showControl ? controlModel.get('itemSize') : 0;
	            var controlGap = showControl ? controlModel.get('itemGap') : 0;
	            var sizePlusGap = controlSize + controlGap;

	            // Special label rotate.
	            var labelRotation = timelineModel.get('label.normal.rotate') || 0;
	            labelRotation = labelRotation * PI / 180; // To radian.

	            var playPosition;
	            var prevBtnPosition;
	            var nextBtnPosition;
	            var axisExtent;
	            var controlPosition = controlModel.get('position', true);
	            var showControl = controlModel.get('show', true);
	            var showPlayBtn = showControl && controlModel.get('showPlayBtn', true);
	            var showPrevBtn = showControl && controlModel.get('showPrevBtn', true);
	            var showNextBtn = showControl && controlModel.get('showNextBtn', true);
	            var xLeft = 0;
	            var xRight = mainLength;

	            // position[0] means left, position[1] means middle.
	            if (controlPosition === 'left' || controlPosition === 'bottom') {
	                showPlayBtn && (playPosition = [0, 0], xLeft += sizePlusGap);
	                showPrevBtn && (prevBtnPosition = [xLeft, 0], xLeft += sizePlusGap);
	                showNextBtn && (nextBtnPosition = [xRight - controlSize, 0], xRight -= sizePlusGap);
	            }
	            else { // 'top' 'right'
	                showPlayBtn && (playPosition = [xRight - controlSize, 0], xRight -= sizePlusGap);
	                showPrevBtn && (prevBtnPosition = [0, 0], xLeft += sizePlusGap);
	                showNextBtn && (nextBtnPosition = [xRight - controlSize, 0], xRight -= sizePlusGap);
	            }
	            axisExtent = [xLeft, xRight];

	            if (timelineModel.get('inverse')) {
	                axisExtent.reverse();
	            }

	            return {
	                viewRect: viewRect,
	                mainLength: mainLength,
	                orient: orient,

	                rotation: rotationMap[orient],
	                labelRotation: labelRotation,
	                labelPosOpt: labelPosOpt,
	                labelAlign: timelineModel.get('label.normal.textStyle.align') || labelAlignMap[orient],
	                labelBaseline: timelineModel.get('label.normal.textStyle.baseline') || labelBaselineMap[orient],

	                // Based on mainGroup.
	                playPosition: playPosition,
	                prevBtnPosition: prevBtnPosition,
	                nextBtnPosition: nextBtnPosition,
	                axisExtent: axisExtent,

	                controlSize: controlSize,
	                controlGap: controlGap
	            };
	        },

	        _position: function (layoutInfo, timelineModel) {
	            // Position is be called finally, because bounding rect is needed for
	            // adapt content to fill viewRect (auto adapt offset).

	            // Timeline may be not all in the viewRect when 'offset' is specified
	            // as a number, because it is more appropriate that label aligns at
	            // 'offset' but not the other edge defined by viewRect.

	            var mainGroup = this._mainGroup;
	            var labelGroup = this._labelGroup;

	            var viewRect = layoutInfo.viewRect;
	            if (layoutInfo.orient === 'vertical') {
	                // transfrom to horizontal, inverse rotate by left-top point.
	                var m = matrix.create();
	                var rotateOriginX = viewRect.x;
	                var rotateOriginY = viewRect.y + viewRect.height;
	                matrix.translate(m, m, [-rotateOriginX, -rotateOriginY]);
	                matrix.rotate(m, m, -PI / 2);
	                matrix.translate(m, m, [rotateOriginX, rotateOriginY]);
	                viewRect = viewRect.clone();
	                viewRect.applyTransform(m);
	            }

	            var viewBound = getBound(viewRect);
	            var mainBound = getBound(mainGroup.getBoundingRect());
	            var labelBound = getBound(labelGroup.getBoundingRect());

	            var mainPosition = mainGroup.position;
	            var labelsPosition = labelGroup.position;

	            labelsPosition[0] = mainPosition[0] = viewBound[0][0];

	            var labelPosOpt = layoutInfo.labelPosOpt;

	            if (isNaN(labelPosOpt)) { // '+' or '-'
	                var mainBoundIdx = labelPosOpt === '+' ? 0 : 1;
	                toBound(mainPosition, mainBound, viewBound, 1, mainBoundIdx);
	                toBound(labelsPosition, labelBound, viewBound, 1, 1 - mainBoundIdx);
	            }
	            else {
	                var mainBoundIdx = labelPosOpt >= 0 ? 0 : 1;
	                toBound(mainPosition, mainBound, viewBound, 1, mainBoundIdx);
	                labelsPosition[1] = mainPosition[1] + labelPosOpt;
	            }

	            mainGroup.attr('position', mainPosition);
	            labelGroup.attr('position', labelsPosition);
	            mainGroup.rotation = labelGroup.rotation = layoutInfo.rotation;

	            setOrigin(mainGroup);
	            setOrigin(labelGroup);

	            function setOrigin(targetGroup) {
	                var pos = targetGroup.position;
	                targetGroup.origin = [
	                    viewBound[0][0] - pos[0],
	                    viewBound[1][0] - pos[1]
	                ];
	            }

	            function getBound(rect) {
	                // [[xmin, xmax], [ymin, ymax]]
	                return [
	                    [rect.x, rect.x + rect.width],
	                    [rect.y, rect.y + rect.height]
	                ];
	            }

	            function toBound(fromPos, from, to, dimIdx, boundIdx) {
	                fromPos[dimIdx] += to[dimIdx][boundIdx] - from[dimIdx][boundIdx];
	            }
	        },

	        _createAxis: function (layoutInfo, timelineModel) {
	            var data = timelineModel.getData();
	            var axisType = timelineModel.get('axisType');

	            var scale = axisHelper.createScaleByModel(timelineModel, axisType);
	            var dataExtent = data.getDataExtent('value');
	            scale.setExtent(dataExtent[0], dataExtent[1]);
	            this._customizeScale(scale, data);
	            scale.niceTicks();

	            var axis = new TimelineAxis('value', scale, layoutInfo.axisExtent, axisType);
	            axis.model = timelineModel;

	            return axis;
	        },

	        _customizeScale: function (scale, data) {

	            scale.getTicks = function () {
	                return data.mapArray(['value'], function (value) {
	                    return value;
	                });
	            };

	            scale.getTicksLabels = function () {
	                return zrUtil.map(this.getTicks(), scale.getLabel, scale);
	            };
	        },

	        _createGroup: function (name) {
	            var newGroup = this['_' + name] = new graphic.Group();
	            this.group.add(newGroup);
	            return newGroup;
	        },

	        _renderAxisLine: function (layoutInfo, group, axis, timelineModel) {
	            var axisExtent = axis.getExtent();

	            if (!timelineModel.get('lineStyle.show')) {
	                return;
	            }

	            group.add(new graphic.Line({
	                shape: {
	                    x1: axisExtent[0], y1: 0,
	                    x2: axisExtent[1], y2: 0
	                },
	                style: zrUtil.extend(
	                    {lineCap: 'round'},
	                    timelineModel.getModel('lineStyle').getLineStyle()
	                ),
	                silent: true,
	                z2: 1
	            }));
	        },

	        /**
	         * @private
	         */
	        _renderAxisTick: function (layoutInfo, group, axis, timelineModel) {
	            var data = timelineModel.getData();
	            var ticks = axis.scale.getTicks();

	            each(ticks, function (value, dataIndex) {

	                var tickCoord = axis.dataToCoord(value);
	                var itemModel = data.getItemModel(dataIndex);
	                var itemStyleModel = itemModel.getModel('itemStyle.normal');
	                var hoverStyleModel = itemModel.getModel('itemStyle.emphasis');
	                var symbolOpt = {
	                    position: [tickCoord, 0],
	                    onclick: bind(this._changeTimeline, this, dataIndex)
	                };
	                var el = giveSymbol(itemModel, itemStyleModel, group, symbolOpt);
	                graphic.setHoverStyle(el, hoverStyleModel.getItemStyle());

	                if (itemModel.get('tooltip')) {
	                    el.dataIndex = dataIndex;
	                    el.dataModel = timelineModel;
	                }
	                else {
	                    el.dataIndex = el.dataModel = null;
	                }

	            }, this);
	        },

	        /**
	         * @private
	         */
	        _renderAxisLabel: function (layoutInfo, group, axis, timelineModel) {
	            var labelModel = timelineModel.getModel('label.normal');

	            if (!labelModel.get('show')) {
	                return;
	            }

	            var data = timelineModel.getData();
	            var ticks = axis.scale.getTicks();
	            var labels = axisHelper.getFormattedLabels(
	                axis, labelModel.get('formatter')
	            );
	            var labelInterval = axis.getLabelInterval();

	            each(ticks, function (tick, dataIndex) {
	                if (axis.isLabelIgnored(dataIndex, labelInterval)) {
	                    return;
	                }

	                var itemModel = data.getItemModel(dataIndex);
	                var itemTextStyleModel = itemModel.getModel('label.normal.textStyle');
	                var hoverTextStyleModel = itemModel.getModel('label.emphasis.textStyle');
	                var tickCoord = axis.dataToCoord(tick);
	                var textEl = new graphic.Text({
	                    style: {
	                        text: labels[dataIndex],
	                        textAlign: layoutInfo.labelAlign,
	                        textVerticalAlign: layoutInfo.labelBaseline,
	                        textFont: itemTextStyleModel.getFont(),
	                        fill: itemTextStyleModel.getTextColor()
	                    },
	                    position: [tickCoord, 0],
	                    rotation: layoutInfo.labelRotation - layoutInfo.rotation,
	                    onclick: bind(this._changeTimeline, this, dataIndex),
	                    silent: false
	                });

	                group.add(textEl);
	                graphic.setHoverStyle(textEl, hoverTextStyleModel.getItemStyle());

	            }, this);
	        },

	        /**
	         * @private
	         */
	        _renderControl: function (layoutInfo, group, axis, timelineModel) {
	            var controlSize = layoutInfo.controlSize;
	            var rotation = layoutInfo.rotation;

	            var itemStyle = timelineModel.getModel('controlStyle.normal').getItemStyle();
	            var hoverStyle = timelineModel.getModel('controlStyle.emphasis').getItemStyle();
	            var rect = [0, -controlSize / 2, controlSize, controlSize];
	            var playState = timelineModel.getPlayState();
	            var inverse = timelineModel.get('inverse', true);

	            makeBtn(
	                layoutInfo.nextBtnPosition,
	                'controlStyle.nextIcon',
	                bind(this._changeTimeline, this, inverse ? '-' : '+')
	            );
	            makeBtn(
	                layoutInfo.prevBtnPosition,
	                'controlStyle.prevIcon',
	                bind(this._changeTimeline, this, inverse ? '+' : '-')
	            );
	            makeBtn(
	                layoutInfo.playPosition,
	                'controlStyle.' + (playState ? 'stopIcon' : 'playIcon'),
	                bind(this._handlePlayClick, this, !playState),
	                true
	            );

	            function makeBtn(position, iconPath, onclick, willRotate) {
	                if (!position) {
	                    return;
	                }
	                var opt = {
	                    position: position,
	                    origin: [controlSize / 2, 0],
	                    rotation: willRotate ? -rotation : 0,
	                    rectHover: true,
	                    style: itemStyle,
	                    onclick: onclick
	                };
	                var btn = makeIcon(timelineModel, iconPath, rect, opt);
	                group.add(btn);
	                graphic.setHoverStyle(btn, hoverStyle);
	            }
	        },

	        _renderCurrentPointer: function (layoutInfo, group, axis, timelineModel) {
	            var data = timelineModel.getData();
	            var currentIndex = timelineModel.getCurrentIndex();
	            var pointerModel = data.getItemModel(currentIndex).getModel('checkpointStyle');
	            var me = this;

	            var callback = {
	                onCreate: function (pointer) {
	                    pointer.draggable = true;
	                    pointer.drift = bind(me._handlePointerDrag, me);
	                    pointer.ondragend = bind(me._handlePointerDragend, me);
	                    pointerMoveTo(pointer, currentIndex, axis, timelineModel, true);
	                },
	                onUpdate: function (pointer) {
	                    pointerMoveTo(pointer, currentIndex, axis, timelineModel);
	                }
	            };

	            // Reuse when exists, for animation and drag.
	            this._currentPointer = giveSymbol(
	                pointerModel, pointerModel, this._mainGroup, {}, this._currentPointer, callback
	            );
	        },

	        _handlePlayClick: function (nextState) {
	            this._clearTimer();
	            this.api.dispatchAction({
	                type: 'timelinePlayChange',
	                playState: nextState,
	                from: this.uid
	            });
	        },

	        _handlePointerDrag: function (dx, dy, e) {
	            this._clearTimer();
	            this._pointerChangeTimeline([e.offsetX, e.offsetY]);
	        },

	        _handlePointerDragend: function (e) {
	            this._pointerChangeTimeline([e.offsetX, e.offsetY], true);
	        },

	        _pointerChangeTimeline: function (mousePos, trigger) {
	            var toCoord = this._toAxisCoord(mousePos)[0];

	            var axis = this._axis;
	            var axisExtent = numberUtil.asc(axis.getExtent().slice());

	            toCoord > axisExtent[1] && (toCoord = axisExtent[1]);
	            toCoord < axisExtent[0] && (toCoord = axisExtent[0]);

	            this._currentPointer.position[0] = toCoord;
	            this._currentPointer.dirty();

	            var targetDataIndex = this._findNearestTick(toCoord);
	            var timelineModel = this.model;

	            if (trigger || (
	                targetDataIndex !== timelineModel.getCurrentIndex()
	                && timelineModel.get('realtime')
	            )) {
	                this._changeTimeline(targetDataIndex);
	            }
	        },

	        _doPlayStop: function () {
	            this._clearTimer();

	            if (this.model.getPlayState()) {
	                this._timer = setTimeout(
	                    bind(handleFrame, this),
	                    this.model.get('playInterval')
	                );
	            }

	            function handleFrame() {
	                // Do not cache
	                var timelineModel = this.model;
	                this._changeTimeline(
	                    timelineModel.getCurrentIndex()
	                    + (timelineModel.get('rewind', true) ? -1 : 1)
	                );
	            }
	        },

	        _toAxisCoord: function (vertex) {
	            var trans = this._mainGroup.getLocalTransform();
	            return graphic.applyTransform(vertex, trans, true);
	        },

	        _findNearestTick: function (axisCoord) {
	            var data = this.model.getData();
	            var dist = Infinity;
	            var targetDataIndex;
	            var axis = this._axis;

	            data.each(['value'], function (value, dataIndex) {
	                var coord = axis.dataToCoord(value);
	                var d = Math.abs(coord - axisCoord);
	                if (d < dist) {
	                    dist = d;
	                    targetDataIndex = dataIndex;
	                }
	            });

	            return targetDataIndex;
	        },

	        _clearTimer: function () {
	            if (this._timer) {
	                clearTimeout(this._timer);
	                this._timer = null;
	            }
	        },

	        _changeTimeline: function (nextIndex) {
	            var currentIndex = this.model.getCurrentIndex();

	            if (nextIndex === '+') {
	                nextIndex = currentIndex + 1;
	            }
	            else if (nextIndex === '-') {
	                nextIndex = currentIndex - 1;
	            }

	            this.api.dispatchAction({
	                type: 'timelineChange',
	                currentIndex: nextIndex,
	                from: this.uid
	            });
	        }

	    });

	    function getViewRect(model, api) {
	        return layout.getLayoutRect(
	            model.getBoxLayoutParams(),
	            {
	                width: api.getWidth(),
	                height: api.getHeight()
	            },
	            model.get('padding')
	        );
	    }

	    function makeIcon(timelineModel, objPath, rect, opts) {
	        var icon = graphic.makePath(
	            timelineModel.get(objPath).replace(/^path:\/\//, ''),
	            zrUtil.clone(opts || {}),
	            new BoundingRect(rect[0], rect[1], rect[2], rect[3]),
	            'center'
	        );

	        return icon;
	    }

	    /**
	     * Create symbol or update symbol
	     * opt: basic position and event handlers
	     */
	    function giveSymbol(hostModel, itemStyleModel, group, opt, symbol, callback) {
	        var color = itemStyleModel.get('color');

	        if (!symbol) {
	            var symbolType = hostModel.get('symbol');
	            symbol = symbolUtil.createSymbol(symbolType, -1, -1, 2, 2, color);
	            symbol.setStyle('strokeNoScale', true);
	            group.add(symbol);
	            callback && callback.onCreate(symbol);
	        }
	        else {
	            symbol.setColor(color);
	            group.add(symbol); // Group may be new, also need to add.
	            callback && callback.onUpdate(symbol);
	        }

	        // Style
	        var itemStyle = itemStyleModel.getItemStyle(['color', 'symbol', 'symbolSize']);
	        symbol.setStyle(itemStyle);

	        // Transform and events.
	        opt = zrUtil.merge({
	            rectHover: true,
	            z2: 100
	        }, opt, true);

	        var symbolSize = hostModel.get('symbolSize');
	        symbolSize = symbolSize instanceof Array
	            ? symbolSize.slice()
	            : [+symbolSize, +symbolSize];
	        symbolSize[0] /= 2;
	        symbolSize[1] /= 2;
	        opt.scale = symbolSize;

	        var symbolOffset = hostModel.get('symbolOffset');
	        if (symbolOffset) {
	            var pos = opt.position = opt.position || [0, 0];
	            pos[0] += numberUtil.parsePercent(symbolOffset[0], symbolSize[0]);
	            pos[1] += numberUtil.parsePercent(symbolOffset[1], symbolSize[1]);
	        }

	        var symbolRotate = hostModel.get('symbolRotate');
	        opt.rotation = (symbolRotate || 0) * Math.PI / 180 || 0;

	        symbol.attr(opt);

	        // FIXME
	        // (1) When symbol.style.strokeNoScale is true and updateTransform is not performed,
	        // getBoundingRect will return wrong result.
	        // (This is supposed to be resolved in zrender, but it is a little difficult to
	        // leverage performance and auto updateTransform)
	        // (2) All of ancesters of symbol do not scale, so we can just updateTransform symbol.
	        symbol.updateTransform();

	        return symbol;
	    }

	    function pointerMoveTo(pointer, dataIndex, axis, timelineModel, noAnimation) {
	        if (pointer.dragging) {
	            return;
	        }

	        var pointerModel = timelineModel.getModel('checkpointStyle');
	        var toCoord = axis.dataToCoord(timelineModel.getData().get(['value'], dataIndex));

	        if (noAnimation || !pointerModel.get('animation', true)) {
	            pointer.attr({position: [toCoord, 0]});
	        }
	        else {
	            pointer.stopAnimation(true);
	            pointer.animateTo(
	                {position: [toCoord, 0]},
	                pointerModel.get('animationDuration', true),
	                pointerModel.get('animationEasing', true)
	            );
	        }
	    }



/***/ },
/* 410 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @file Timeline view
	 */


	    // var zrUtil = require('zrender/lib/core/util');
	    // var graphic = require('../../util/graphic');
	    var ComponentView = __webpack_require__(79);

	    module.exports = ComponentView.extend({

	        type: 'timeline'
	    });



/***/ },
/* 411 */
/***/ function(module, exports, __webpack_require__) {

	

	    var zrUtil = __webpack_require__(4);
	    var Axis = __webpack_require__(100);
	    var axisHelper = __webpack_require__(101);

	    /**
	     * Extend axis 2d
	     * @constructor module:echarts/coord/cartesian/Axis2D
	     * @extends {module:echarts/coord/cartesian/Axis}
	     * @param {string} dim
	     * @param {*} scale
	     * @param {Array.<number>} coordExtent
	     * @param {string} axisType
	     * @param {string} position
	     */
	    var TimelineAxis = function (dim, scale, coordExtent, axisType) {

	        Axis.call(this, dim, scale, coordExtent);

	        /**
	         * Axis type
	         *  - 'category'
	         *  - 'value'
	         *  - 'time'
	         *  - 'log'
	         * @type {string}
	         */
	        this.type = axisType || 'value';

	        /**
	         * @private
	         * @type {number}
	         */
	        this._autoLabelInterval;

	        /**
	         * Axis model
	         * @param {module:echarts/component/TimelineModel}
	         */
	        this.model = null;
	    };

	    TimelineAxis.prototype = {

	        constructor: TimelineAxis,

	        /**
	         * @public
	         * @return {number}
	         */
	        getLabelInterval: function () {
	            var timelineModel = this.model;
	            var labelModel = timelineModel.getModel('label.normal');
	            var labelInterval = labelModel.get('interval');

	            if (labelInterval != null && labelInterval != 'auto') {
	                return labelInterval;
	            }

	            var labelInterval = this._autoLabelInterval;

	            if (!labelInterval) {
	                labelInterval = this._autoLabelInterval = axisHelper.getAxisLabelInterval(
	                    zrUtil.map(this.scale.getTicks(), this.dataToCoord, this),
	                    axisHelper.getFormattedLabels(this, labelModel.get('formatter')),
	                    labelModel.getModel('textStyle').getFont(),
	                    timelineModel.get('orient') === 'horizontal'
	                );
	            }

	            return labelInterval;
	        },

	        /**
	         * If label is ignored.
	         * Automatically used when axis is category and label can not be all shown
	         * @public
	         * @param  {number} idx
	         * @return {boolean}
	         */
	        isLabelIgnored: function (idx) {
	            if (this.type === 'category') {
	                var labelInterval = this.getLabelInterval();
	                return ((typeof labelInterval === 'function')
	                    && !labelInterval(idx, this.scale.getLabel(idx)))
	                    || idx % (labelInterval + 1);
	            }
	        }

	    };

	    zrUtil.inherits(TimelineAxis, Axis);

	    module.exports = TimelineAxis;


/***/ },
/* 412 */
/***/ function(module, exports, __webpack_require__) {

	

	    __webpack_require__(413);
	    __webpack_require__(414);

	    __webpack_require__(415);
	    __webpack_require__(416);
	    __webpack_require__(417);
	    __webpack_require__(418);
	    __webpack_require__(423);


/***/ },
/* 413 */
/***/ function(module, exports, __webpack_require__) {

	

	    var featureManager = __webpack_require__(357);
	    var zrUtil = __webpack_require__(4);

	    var ToolboxModel = __webpack_require__(1).extendComponentModel({

	        type: 'toolbox',

	        layoutMode: {
	            type: 'box',
	            ignoreSize: true
	        },

	        mergeDefaultAndTheme: function (option) {
	            ToolboxModel.superApply(this, 'mergeDefaultAndTheme', arguments);

	            zrUtil.each(this.option.feature, function (featureOpt, featureName) {
	                var Feature = featureManager.get(featureName);
	                Feature && zrUtil.merge(featureOpt, Feature.defaultOption);
	            });
	        },

	        defaultOption: {

	            show: true,

	            z: 6,

	            zlevel: 0,

	            orient: 'horizontal',

	            left: 'right',

	            top: 'top',

	            // right
	            // bottom

	            backgroundColor: 'transparent',

	            borderColor: '#ccc',

	            borderWidth: 0,

	            padding: 5,

	            itemSize: 15,

	            itemGap: 8,

	            showTitle: true,

	            iconStyle: {
	                normal: {
	                    borderColor: '#666',
	                    color: 'none'
	                },
	                emphasis: {
	                    borderColor: '#3E98C5'
	                }
	            }
	            // textStyle: {},

	            // feature
	        }
	    });

	    module.exports = ToolboxModel;


/***/ },
/* 414 */
/***/ function(module, exports, __webpack_require__) {

	/* WEBPACK VAR INJECTION */(function(process) {

	    var featureManager = __webpack_require__(357);
	    var zrUtil = __webpack_require__(4);
	    var graphic = __webpack_require__(18);
	    var Model = __webpack_require__(12);
	    var DataDiffer = __webpack_require__(99);
	    var listComponentHelper = __webpack_require__(325);
	    var textContain = __webpack_require__(8);

	    module.exports = __webpack_require__(1).extendComponentView({

	        type: 'toolbox',

	        render: function (toolboxModel, ecModel, api, payload) {
	            var group = this.group;
	            group.removeAll();

	            if (!toolboxModel.get('show')) {
	                return;
	            }

	            var itemSize = +toolboxModel.get('itemSize');
	            var featureOpts = toolboxModel.get('feature') || {};
	            var features = this._features || (this._features = {});

	            var featureNames = [];
	            zrUtil.each(featureOpts, function (opt, name) {
	                featureNames.push(name);
	            });

	            (new DataDiffer(this._featureNames || [], featureNames))
	                .add(process)
	                .update(process)
	                .remove(zrUtil.curry(process, null))
	                .execute();

	            // Keep for diff.
	            this._featureNames = featureNames;

	            function process(newIndex, oldIndex) {
	                var featureName = featureNames[newIndex];
	                var oldName = featureNames[oldIndex];
	                var featureOpt = featureOpts[featureName];
	                var featureModel = new Model(featureOpt, toolboxModel, toolboxModel.ecModel);
	                var feature;

	                if (featureName && !oldName) { // Create
	                    if (isUserFeatureName(featureName)) {
	                        feature = {
	                            model: featureModel,
	                            onclick: featureModel.option.onclick,
	                            featureName: featureName
	                        };
	                    }
	                    else {
	                        var Feature = featureManager.get(featureName);
	                        if (!Feature) {
	                            return;
	                        }
	                        feature = new Feature(featureModel, ecModel, api);
	                    }
	                    features[featureName] = feature;
	                }
	                else {
	                    feature = features[oldName];
	                    // If feature does not exsit.
	                    if (!feature) {
	                        return;
	                    }
	                    feature.model = featureModel;
	                    feature.ecModel = ecModel;
	                    feature.api = api;
	                }

	                if (!featureName && oldName) {
	                    feature.dispose && feature.dispose(ecModel, api);
	                    return;
	                }

	                if (!featureModel.get('show') || feature.unusable) {
	                    feature.remove && feature.remove(ecModel, api);
	                    return;
	                }

	                createIconPaths(featureModel, feature, featureName);

	                featureModel.setIconStatus = function (iconName, status) {
	                    var option = this.option;
	                    var iconPaths = this.iconPaths;
	                    option.iconStatus = option.iconStatus || {};
	                    option.iconStatus[iconName] = status;
	                    // FIXME
	                    iconPaths[iconName] && iconPaths[iconName].trigger(status);
	                };

	                if (feature.render) {
	                    feature.render(featureModel, ecModel, api, payload);
	                }
	            }

	            function createIconPaths(featureModel, feature, featureName) {
	                var iconStyleModel = featureModel.getModel('iconStyle');

	                // If one feature has mutiple icon. they are orginaized as
	                // {
	                //     icon: {
	                //         foo: '',
	                //         bar: ''
	                //     },
	                //     title: {
	                //         foo: '',
	                //         bar: ''
	                //     }
	                // }
	                var icons = feature.getIcons ? feature.getIcons() : featureModel.get('icon');
	                var titles = featureModel.get('title') || {};
	                if (typeof icons === 'string') {
	                    var icon = icons;
	                    var title = titles;
	                    icons = {};
	                    titles = {};
	                    icons[featureName] = icon;
	                    titles[featureName] = title;
	                }
	                var iconPaths = featureModel.iconPaths = {};
	                zrUtil.each(icons, function (icon, iconName) {
	                    var normalStyle = iconStyleModel.getModel('normal').getItemStyle();
	                    var hoverStyle = iconStyleModel.getModel('emphasis').getItemStyle();

	                    var style = {
	                        x: -itemSize / 2,
	                        y: -itemSize / 2,
	                        width: itemSize,
	                        height: itemSize
	                    };
	                    var path = icon.indexOf('image://') === 0
	                        ? (
	                            style.image = icon.slice(8),
	                            new graphic.Image({style: style})
	                        )
	                        : graphic.makePath(
	                            icon.replace('path://', ''),
	                            {
	                                style: normalStyle,
	                                hoverStyle: hoverStyle,
	                                rectHover: true
	                            },
	                            style,
	                            'center'
	                        );

	                    graphic.setHoverStyle(path);

	                    if (toolboxModel.get('showTitle')) {
	                        path.__title = titles[iconName];
	                        path.on('mouseover', function () {
	                                // Should not reuse above hoverStyle, which might be modified.
	                                var hoverStyle = iconStyleModel.getModel('emphasis').getItemStyle();
	                                path.setStyle({
	                                    text: titles[iconName],
	                                    textPosition: hoverStyle.textPosition || 'bottom',
	                                    textFill: hoverStyle.fill || hoverStyle.stroke || '#000',
	                                    textAlign: hoverStyle.textAlign || 'center'
	                                });
	                            })
	                            .on('mouseout', function () {
	                                path.setStyle({
	                                    textFill: null
	                                });
	                            });
	                    }
	                    path.trigger(featureModel.get('iconStatus.' + iconName) || 'normal');

	                    group.add(path);
	                    path.on('click', zrUtil.bind(
	                        feature.onclick, feature, ecModel, api, iconName
	                    ));

	                    iconPaths[iconName] = path;
	                });
	            }

	            listComponentHelper.layout(group, toolboxModel, api);
	            // Render background after group is layout
	            // FIXME
	            listComponentHelper.addBackground(group, toolboxModel);

	            // Adjust icon title positions to avoid them out of screen
	            group.eachChild(function (icon) {
	                var titleText = icon.__title;
	                var hoverStyle = icon.hoverStyle;
	                // May be background element
	                if (hoverStyle && titleText) {
	                    var rect = textContain.getBoundingRect(
	                        titleText, hoverStyle.font
	                    );
	                    var offsetX = icon.position[0] + group.position[0];
	                    var offsetY = icon.position[1] + group.position[1] + itemSize;

	                    var needPutOnTop = false;
	                    if (offsetY + rect.height > api.getHeight()) {
	                        hoverStyle.textPosition = 'top';
	                        needPutOnTop = true;
	                    }
	                    var topOffset = needPutOnTop ? (-5 - rect.height) : (itemSize + 8);
	                    if (offsetX + rect.width /  2 > api.getWidth()) {
	                        hoverStyle.textPosition = ['100%', topOffset];
	                        hoverStyle.textAlign = 'right';
	                    }
	                    else if (offsetX - rect.width / 2 < 0) {
	                        hoverStyle.textPosition = [0, topOffset];
	                        hoverStyle.textAlign = 'left';
	                    }
	                }
	            });
	        },

	        updateView: function (toolboxModel, ecModel, api, payload) {
	            zrUtil.each(this._features, function (feature) {
	                feature.updateView && feature.updateView(feature.model, ecModel, api, payload);
	            });
	        },

	        updateLayout: function (toolboxModel, ecModel, api, payload) {
	            zrUtil.each(this._features, function (feature) {
	                feature.updateLayout && feature.updateLayout(feature.model, ecModel, api, payload);
	            });
	        },

	        remove: function (ecModel, api) {
	            zrUtil.each(this._features, function (feature) {
	                feature.remove && feature.remove(ecModel, api);
	            });
	            this.group.removeAll();
	        },

	        dispose: function (ecModel, api) {
	            zrUtil.each(this._features, function (feature) {
	                feature.dispose && feature.dispose(ecModel, api);
	            });
	        }
	    });

	    function isUserFeatureName(featureName) {
	        return featureName.indexOf('my') === 0;
	    }


	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(310)))

/***/ },
/* 415 */
/***/ function(module, exports, __webpack_require__) {

	

	    var env = __webpack_require__(2);

	    function SaveAsImage (model) {
	        this.model = model;
	    }

	    SaveAsImage.defaultOption = {
	        show: true,
	        icon: 'M4.7,22.9L29.3,45.5L54.7,23.4M4.6,43.6L4.6,58L53.8,58L53.8,43.6M29.2,45.1L29.2,0',
	        title: '保存为图片',
	        type: 'png',
	        // Default use option.backgroundColor
	        // backgroundColor: '#fff',
	        name: '',
	        excludeComponents: ['toolbox'],
	        pixelRatio: 1,
	        lang: ['右键另存为图片']
	    };

	    SaveAsImage.prototype.unusable = !env.canvasSupported;

	    var proto = SaveAsImage.prototype;

	    proto.onclick = function (ecModel, api) {
	        var model = this.model;
	        var title = model.get('name') || ecModel.get('title.0.text') || 'echarts';
	        var $a = document.createElement('a');
	        var type = model.get('type', true) || 'png';
	        $a.download = title + '.' + type;
	        $a.target = '_blank';
	        var url = api.getConnectedDataURL({
	            type: type,
	            backgroundColor: model.get('backgroundColor', true)
	                || ecModel.get('backgroundColor') || '#fff',
	            excludeComponents: model.get('excludeComponents'),
	            pixelRatio: model.get('pixelRatio')
	        });
	        $a.href = url;
	        // Chrome and Firefox
	        if (typeof MouseEvent === 'function' && !env.browser.ie && !env.browser.edge) {
	            var evt = new MouseEvent('click', {
	                view: window,
	                bubbles: true,
	                cancelable: false
	            });
	            $a.dispatchEvent(evt);
	        }
	        // IE
	        else {
	            var lang = model.get('lang');
	            var html = ''
	                + '<body style="margin:0;">'
	                + '<img src="' + url + '" style="max-width:100%;" title="' + ((lang && lang[0]) || '') + '" />'
	                + '</body>';
	            var tab = window.open();
	            tab.document.write(html);
	        }
	    };

	    __webpack_require__(357).register(
	        'saveAsImage', SaveAsImage
	    );

	    module.exports = SaveAsImage;


/***/ },
/* 416 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var zrUtil = __webpack_require__(4);

	    function MagicType(model) {
	        this.model = model;
	    }

	    MagicType.defaultOption = {
	        show: true,
	        type: [],
	        // Icon group
	        icon: {
	            line: 'M4.1,28.9h7.1l9.3-22l7.4,38l9.7-19.7l3,12.8h14.9M4.1,58h51.4',
	            bar: 'M6.7,22.9h10V48h-10V22.9zM24.9,13h10v35h-10V13zM43.2,2h10v46h-10V2zM3.1,58h53.7',
	            stack: 'M8.2,38.4l-8.4,4.1l30.6,15.3L60,42.5l-8.1-4.1l-21.5,11L8.2,38.4z M51.9,30l-8.1,4.2l-13.4,6.9l-13.9-6.9L8.2,30l-8.4,4.2l8.4,4.2l22.2,11l21.5-11l8.1-4.2L51.9,30z M51.9,21.7l-8.1,4.2L35.7,30l-5.3,2.8L24.9,30l-8.4-4.1l-8.3-4.2l-8.4,4.2L8.2,30l8.3,4.2l13.9,6.9l13.4-6.9l8.1-4.2l8.1-4.1L51.9,21.7zM30.4,2.2L-0.2,17.5l8.4,4.1l8.3,4.2l8.4,4.2l5.5,2.7l5.3-2.7l8.1-4.2l8.1-4.2l8.1-4.1L30.4,2.2z', // jshint ignore:line
	            tiled: 'M2.3,2.2h22.8V25H2.3V2.2z M35,2.2h22.8V25H35V2.2zM2.3,35h22.8v22.8H2.3V35z M35,35h22.8v22.8H35V35z'
	        },
	        title: {
	            line: '切换为折线图',
	            bar: '切换为柱状图',
	            stack: '切换为堆叠',
	            tiled: '切换为平铺'
	        },
	        option: {},
	        seriesIndex: {}
	    };

	    var proto = MagicType.prototype;

	    proto.getIcons = function () {
	        var model = this.model;
	        var availableIcons = model.get('icon');
	        var icons = {};
	        zrUtil.each(model.get('type'), function (type) {
	            if (availableIcons[type]) {
	                icons[type] = availableIcons[type];
	            }
	        });
	        return icons;
	    };

	    var seriesOptGenreator = {
	        'line': function (seriesType, seriesId, seriesModel, model) {
	            if (seriesType === 'bar') {
	                return zrUtil.merge({
	                    id: seriesId,
	                    type: 'line',
	                    // Preserve data related option
	                    data: seriesModel.get('data'),
	                    stack: seriesModel.get('stack'),
	                    markPoint: seriesModel.get('markPoint'),
	                    markLine: seriesModel.get('markLine')
	                }, model.get('option.line') || {}, true);
	            }
	        },
	        'bar': function (seriesType, seriesId, seriesModel, model) {
	            if (seriesType === 'line') {
	                return zrUtil.merge({
	                    id: seriesId,
	                    type: 'bar',
	                    // Preserve data related option
	                    data: seriesModel.get('data'),
	                    stack: seriesModel.get('stack'),
	                    markPoint: seriesModel.get('markPoint'),
	                    markLine: seriesModel.get('markLine')
	                }, model.get('option.bar') || {}, true);
	            }
	        },
	        'stack': function (seriesType, seriesId, seriesModel, model) {
	            if (seriesType === 'line' || seriesType === 'bar') {
	                return zrUtil.merge({
	                    id: seriesId,
	                    stack: '__ec_magicType_stack__'
	                }, model.get('option.stack') || {}, true);
	            }
	        },
	        'tiled': function (seriesType, seriesId, seriesModel, model) {
	            if (seriesType === 'line' || seriesType === 'bar') {
	                return zrUtil.merge({
	                    id: seriesId,
	                    stack: ''
	                }, model.get('option.tiled') || {}, true);
	            }
	        }
	    };

	    var radioTypes = [
	        ['line', 'bar'],
	        ['stack', 'tiled']
	    ];

	    proto.onclick = function (ecModel, api, type) {
	        var model = this.model;
	        var seriesIndex = model.get('seriesIndex.' + type);
	        // Not supported magicType
	        if (!seriesOptGenreator[type]) {
	            return;
	        }
	        var newOption = {
	            series: []
	        };
	        var generateNewSeriesTypes = function (seriesModel) {
	            var seriesType = seriesModel.subType;
	            var seriesId = seriesModel.id;
	            var newSeriesOpt = seriesOptGenreator[type](
	                seriesType, seriesId, seriesModel, model
	            );
	            if (newSeriesOpt) {
	                // PENDING If merge original option?
	                zrUtil.defaults(newSeriesOpt, seriesModel.option);
	                newOption.series.push(newSeriesOpt);
	            }
	            // Modify boundaryGap
	            var coordSys = seriesModel.coordinateSystem;
	            if (coordSys && coordSys.type === 'cartesian2d' && (type === 'line' || type === 'bar')) {
	                var categoryAxis = coordSys.getAxesByScale('ordinal')[0];
	                if (categoryAxis) {
	                    var axisDim = categoryAxis.dim;
	                    var axisType = axisDim + 'Axis';
	                    var axisModel = ecModel.queryComponents({
	                        mainType: axisType,
	                        index: seriesModel.get(name + 'Index'),
	                        id: seriesModel.get(name + 'Id')
	                    })[0];
	                    var axisIndex = axisModel.componentIndex;

	                    newOption[axisType] = newOption[axisType] || [];
	                    for (var i = 0; i <= axisIndex; i++) {
	                        newOption[axisType][axisIndex] = newOption[axisType][axisIndex] || {};
	                    }
	                    newOption[axisType][axisIndex].boundaryGap = type === 'bar' ? true : false;
	                }
	            }
	        };

	        zrUtil.each(radioTypes, function (radio) {
	            if (zrUtil.indexOf(radio, type) >= 0) {
	                zrUtil.each(radio, function (item) {
	                    model.setIconStatus(item, 'normal');
	                });
	            }
	        });

	        model.setIconStatus(type, 'emphasis');

	        ecModel.eachComponent(
	            {
	                mainType: 'series',
	                query: seriesIndex == null ? null : {
	                    seriesIndex: seriesIndex
	                }
	            }, generateNewSeriesTypes
	        );
	        api.dispatchAction({
	            type: 'changeMagicType',
	            currentType: type,
	            newOption: newOption
	        });
	    };

	    var echarts = __webpack_require__(1);
	    echarts.registerAction({
	        type: 'changeMagicType',
	        event: 'magicTypeChanged',
	        update: 'prepareAndUpdate'
	    }, function (payload, ecModel) {
	        ecModel.mergeOption(payload.newOption);
	    });

	    __webpack_require__(357).register('magicType', MagicType);

	    module.exports = MagicType;


/***/ },
/* 417 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @module echarts/component/toolbox/feature/DataView
	 */



	    var zrUtil = __webpack_require__(4);
	    var eventTool = __webpack_require__(88);


	    var BLOCK_SPLITER = new Array(60).join('-');
	    var ITEM_SPLITER = '\t';
	    /**
	     * Group series into two types
	     *  1. on category axis, like line, bar
	     *  2. others, like scatter, pie
	     * @param {module:echarts/model/Global} ecModel
	     * @return {Object}
	     * @inner
	     */
	    function groupSeries(ecModel) {
	        var seriesGroupByCategoryAxis = {};
	        var otherSeries = [];
	        var meta = [];
	        ecModel.eachRawSeries(function (seriesModel) {
	            var coordSys = seriesModel.coordinateSystem;

	            if (coordSys && (coordSys.type === 'cartesian2d' || coordSys.type === 'polar')) {
	                var baseAxis = coordSys.getBaseAxis();
	                if (baseAxis.type === 'category') {
	                    var key = baseAxis.dim + '_' + baseAxis.index;
	                    if (!seriesGroupByCategoryAxis[key]) {
	                        seriesGroupByCategoryAxis[key] = {
	                            categoryAxis: baseAxis,
	                            valueAxis: coordSys.getOtherAxis(baseAxis),
	                            series: []
	                        };
	                        meta.push({
	                            axisDim: baseAxis.dim,
	                            axisIndex: baseAxis.index
	                        });
	                    }
	                    seriesGroupByCategoryAxis[key].series.push(seriesModel);
	                }
	                else {
	                    otherSeries.push(seriesModel);
	                }
	            }
	            else {
	                otherSeries.push(seriesModel);
	            }
	        });

	        return {
	            seriesGroupByCategoryAxis: seriesGroupByCategoryAxis,
	            other: otherSeries,
	            meta: meta
	        };
	    }

	    /**
	     * Assemble content of series on cateogory axis
	     * @param {Array.<module:echarts/model/Series>} series
	     * @return {string}
	     * @inner
	     */
	    function assembleSeriesWithCategoryAxis(series) {
	        var tables = [];
	        zrUtil.each(series, function (group, key) {
	            var categoryAxis = group.categoryAxis;
	            var valueAxis = group.valueAxis;
	            var valueAxisDim = valueAxis.dim;

	            var headers = [' '].concat(zrUtil.map(group.series, function (series) {
	                return series.name;
	            }));
	            var columns = [categoryAxis.model.getCategories()];
	            zrUtil.each(group.series, function (series) {
	                columns.push(series.getRawData().mapArray(valueAxisDim, function (val) {
	                    return val;
	                }));
	            });
	            // Assemble table content
	            var lines = [headers.join(ITEM_SPLITER)];
	            for (var i = 0; i < columns[0].length; i++) {
	                var items = [];
	                for (var j = 0; j < columns.length; j++) {
	                    items.push(columns[j][i]);
	                }
	                lines.push(items.join(ITEM_SPLITER));
	            }
	            tables.push(lines.join('\n'));
	        });
	        return tables.join('\n\n' +  BLOCK_SPLITER + '\n\n');
	    }

	    /**
	     * Assemble content of other series
	     * @param {Array.<module:echarts/model/Series>} series
	     * @return {string}
	     * @inner
	     */
	    function assembleOtherSeries(series) {
	        return zrUtil.map(series, function (series) {
	            var data = series.getRawData();
	            var lines = [series.name];
	            var vals = [];
	            data.each(data.dimensions, function () {
	                var argLen = arguments.length;
	                var dataIndex = arguments[argLen - 1];
	                var name = data.getName(dataIndex);
	                for (var i = 0; i < argLen - 1; i++) {
	                    vals[i] = arguments[i];
	                }
	                lines.push((name ? (name + ITEM_SPLITER) : '') + vals.join(ITEM_SPLITER));
	            });
	            return lines.join('\n');
	        }).join('\n\n' + BLOCK_SPLITER + '\n\n');
	    }

	    /**
	     * @param {module:echarts/model/Global}
	     * @return {string}
	     * @inner
	     */
	    function getContentFromModel(ecModel) {

	        var result = groupSeries(ecModel);

	        return {
	            value: zrUtil.filter([
	                    assembleSeriesWithCategoryAxis(result.seriesGroupByCategoryAxis),
	                    assembleOtherSeries(result.other)
	                ], function (str) {
	                    return str.replace(/[\n\t\s]/g, '');
	                }).join('\n\n' + BLOCK_SPLITER + '\n\n'),

	            meta: result.meta
	        };
	    }


	    function trim(str) {
	        return str.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
	    }
	    /**
	     * If a block is tsv format
	     */
	    function isTSVFormat(block) {
	        // Simple method to find out if a block is tsv format
	        var firstLine = block.slice(0, block.indexOf('\n'));
	        if (firstLine.indexOf(ITEM_SPLITER) >= 0) {
	            return true;
	        }
	    }

	    var itemSplitRegex = new RegExp('[' + ITEM_SPLITER + ']+', 'g');
	    /**
	     * @param {string} tsv
	     * @return {Array.<Object>}
	     */
	    function parseTSVContents(tsv) {
	        var tsvLines = tsv.split(/\n+/g);
	        var headers = trim(tsvLines.shift()).split(itemSplitRegex);

	        var categories = [];
	        var series = zrUtil.map(headers, function (header) {
	            return {
	                name: header,
	                data: []
	            };
	        });
	        for (var i = 0; i < tsvLines.length; i++) {
	            var items = trim(tsvLines[i]).split(itemSplitRegex);
	            categories.push(items.shift());
	            for (var j = 0; j < items.length; j++) {
	                series[j] && (series[j].data[i] = items[j]);
	            }
	        }
	        return {
	            series: series,
	            categories: categories
	        };
	    }

	    /**
	     * @param {string} str
	     * @return {Array.<Object>}
	     * @inner
	     */
	    function parseListContents(str) {
	        var lines = str.split(/\n+/g);
	        var seriesName = trim(lines.shift());

	        var data = [];
	        for (var i = 0; i < lines.length; i++) {
	            var items = trim(lines[i]).split(itemSplitRegex);
	            var name = '';
	            var value;
	            var hasName = false;
	            if (isNaN(items[0])) { // First item is name
	                hasName = true;
	                name = items[0];
	                items = items.slice(1);
	                data[i] = {
	                    name: name,
	                    value: []
	                };
	                value = data[i].value;
	            }
	            else {
	                value = data[i] = [];
	            }
	            for (var j = 0; j < items.length; j++) {
	                value.push(+items[j]);
	            }
	            if (value.length === 1) {
	                hasName ? (data[i].value = value[0]) : (data[i] = value[0]);
	            }
	        }

	        return {
	            name: seriesName,
	            data: data
	        };
	    }

	    /**
	     * @param {string} str
	     * @param {Array.<Object>} blockMetaList
	     * @return {Object}
	     * @inner
	     */
	    function parseContents(str, blockMetaList) {
	        var blocks = str.split(new RegExp('\n*' + BLOCK_SPLITER + '\n*', 'g'));
	        var newOption = {
	            series: []
	        };
	        zrUtil.each(blocks, function (block, idx) {
	            if (isTSVFormat(block)) {
	                var result = parseTSVContents(block);
	                var blockMeta = blockMetaList[idx];
	                var axisKey = blockMeta.axisDim + 'Axis';

	                if (blockMeta) {
	                    newOption[axisKey] = newOption[axisKey] || [];
	                    newOption[axisKey][blockMeta.axisIndex] = {
	                        data: result.categories
	                    };
	                    newOption.series = newOption.series.concat(result.series);
	                }
	            }
	            else {
	                var result = parseListContents(block);
	                newOption.series.push(result);
	            }
	        });
	        return newOption;
	    }

	    /**
	     * @alias {module:echarts/component/toolbox/feature/DataView}
	     * @constructor
	     * @param {module:echarts/model/Model} model
	     */
	    function DataView(model) {

	        this._dom = null;

	        this.model = model;
	    }

	    DataView.defaultOption = {
	        show: true,
	        readOnly: false,
	        optionToContent: null,
	        contentToOption: null,

	        icon: 'M17.5,17.3H33 M17.5,17.3H33 M45.4,29.5h-28 M11.5,2v56H51V14.8L38.4,2H11.5z M38.4,2.2v12.7H51 M45.4,41.7h-28',
	        title: '数据视图',
	        lang: ['数据视图', '关闭', '刷新'],
	        backgroundColor: '#fff',
	        textColor: '#000',
	        textareaColor: '#fff',
	        textareaBorderColor: '#333',
	        buttonColor: '#c23531',
	        buttonTextColor: '#fff'
	    };

	    DataView.prototype.onclick = function (ecModel, api) {
	        var container = api.getDom();
	        var model = this.model;
	        if (this._dom) {
	            container.removeChild(this._dom);
	        }
	        var root = document.createElement('div');
	        root.style.cssText = 'position:absolute;left:5px;top:5px;bottom:5px;right:5px;';
	        root.style.backgroundColor = model.get('backgroundColor') || '#fff';

	        // Create elements
	        var header = document.createElement('h4');
	        var lang = model.get('lang') || [];
	        header.innerHTML = lang[0] || model.get('title');
	        header.style.cssText = 'margin: 10px 20px;';
	        header.style.color = model.get('textColor');

	        var viewMain = document.createElement('div');
	        var textarea = document.createElement('textarea');
	        viewMain.style.cssText = 'display:block;width:100%;overflow:auto;';

	        var optionToContent = model.get('optionToContent');
	        var contentToOption = model.get('contentToOption');
	        var result = getContentFromModel(ecModel);
	        if (typeof optionToContent === 'function') {
	            var htmlOrDom = optionToContent(api.getOption());
	            if (typeof htmlOrDom === 'string') {
	                viewMain.innerHTML = htmlOrDom;
	            }
	            else if (zrUtil.isDom(htmlOrDom)) {
	                viewMain.appendChild(htmlOrDom);
	            }
	        }
	        else {
	            // Use default textarea
	            viewMain.appendChild(textarea);
	            textarea.readOnly = model.get('readOnly');
	            textarea.style.cssText = 'width:100%;height:100%;font-family:monospace;font-size:14px;line-height:1.6rem;';
	            textarea.style.color = model.get('textColor');
	            textarea.style.borderColor = model.get('textareaBorderColor');
	            textarea.style.backgroundColor = model.get('textareaColor');
	            textarea.value = result.value;
	        }

	        var blockMetaList = result.meta;

	        var buttonContainer = document.createElement('div');
	        buttonContainer.style.cssText = 'position:absolute;bottom:0;left:0;right:0;';

	        var buttonStyle = 'float:right;margin-right:20px;border:none;'
	            + 'cursor:pointer;padding:2px 5px;font-size:12px;border-radius:3px';
	        var closeButton = document.createElement('div');
	        var refreshButton = document.createElement('div');

	        buttonStyle += ';background-color:' + model.get('buttonColor');
	        buttonStyle += ';color:' + model.get('buttonTextColor');

	        var self = this;

	        function close() {
	            container.removeChild(root);
	            self._dom = null;
	        }
	        eventTool.addEventListener(closeButton, 'click', close);

	        eventTool.addEventListener(refreshButton, 'click', function () {
	            var newOption;
	            try {
	                if (typeof contentToOption === 'function') {
	                    newOption = contentToOption(viewMain, api.getOption());
	                }
	                else {
	                    newOption = parseContents(textarea.value, blockMetaList);
	                }
	            }
	            catch (e) {
	                close();
	                throw new Error('Data view format error ' + e);
	            }
	            if (newOption) {
	                api.dispatchAction({
	                    type: 'changeDataView',
	                    newOption: newOption
	                });
	            }

	            close();
	        });

	        closeButton.innerHTML = lang[1];
	        refreshButton.innerHTML = lang[2];
	        refreshButton.style.cssText = buttonStyle;
	        closeButton.style.cssText = buttonStyle;

	        !model.get('readOnly') && buttonContainer.appendChild(refreshButton);
	        buttonContainer.appendChild(closeButton);

	        // http://stackoverflow.com/questions/6637341/use-tab-to-indent-in-textarea
	        eventTool.addEventListener(textarea, 'keydown', function (e) {
	            if ((e.keyCode || e.which) === 9) {
	                // get caret position/selection
	                var val = this.value;
	                var start = this.selectionStart;
	                var end = this.selectionEnd;

	                // set textarea value to: text before caret + tab + text after caret
	                this.value = val.substring(0, start) + ITEM_SPLITER + val.substring(end);

	                // put caret at right position again
	                this.selectionStart = this.selectionEnd = start + 1;

	                // prevent the focus lose
	                eventTool.stop(e);
	            }
	        });

	        root.appendChild(header);
	        root.appendChild(viewMain);
	        root.appendChild(buttonContainer);

	        viewMain.style.height = (container.clientHeight - 80) + 'px';

	        container.appendChild(root);
	        this._dom = root;
	    };

	    DataView.prototype.remove = function (ecModel, api) {
	        this._dom && api.getDom().removeChild(this._dom);
	    };

	    DataView.prototype.dispose = function (ecModel, api) {
	        this.remove(ecModel, api);
	    };

	    /**
	     * @inner
	     */
	    function tryMergeDataOption(newData, originalData) {
	        return zrUtil.map(newData, function (newVal, idx) {
	            var original = originalData && originalData[idx];
	            if (zrUtil.isObject(original) && !zrUtil.isArray(original)) {
	                if (zrUtil.isObject(newVal) && !zrUtil.isArray(newVal)) {
	                    newVal = newVal.value;
	                }
	                // Original data has option
	                return zrUtil.defaults({
	                    value: newVal
	                }, original);
	            }
	            else {
	                return newVal;
	            }
	        });
	    }

	    __webpack_require__(357).register('dataView', DataView);

	    __webpack_require__(1).registerAction({
	        type: 'changeDataView',
	        event: 'dataViewChanged',
	        update: 'prepareAndUpdate'
	    }, function (payload, ecModel) {
	        var newSeriesOptList = [];
	        zrUtil.each(payload.newOption.series, function (seriesOpt) {
	            var seriesModel = ecModel.getSeriesByName(seriesOpt.name)[0];
	            if (!seriesModel) {
	                // New created series
	                // Geuss the series type
	                newSeriesOptList.push(zrUtil.extend({
	                    // Default is scatter
	                    type: 'scatter'
	                }, seriesOpt));
	            }
	            else {
	                var originalData = seriesModel.get('data');
	                newSeriesOptList.push({
	                    name: seriesOpt.name,
	                    data: tryMergeDataOption(seriesOpt.data, originalData)
	                });
	            }
	        });

	        ecModel.mergeOption(zrUtil.defaults({
	            series: newSeriesOptList
	        }, payload.newOption));
	    });

	    module.exports = DataView;


/***/ },
/* 418 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var zrUtil = __webpack_require__(4);
	    var BrushController = __webpack_require__(245);
	    var BrushTargetManager = __webpack_require__(352);
	    var history = __webpack_require__(419);
	    var sliderMove = __webpack_require__(239);

	    var each = zrUtil.each;

	    // Use dataZoomSelect
	    __webpack_require__(420);

	    // Spectial component id start with \0ec\0, see echarts/model/Global.js~hasInnerId
	    var DATA_ZOOM_ID_BASE = '\0_ec_\0toolbox-dataZoom_';

	    function DataZoom(model, ecModel, api) {

	        /**
	         * @private
	         * @type {module:echarts/component/helper/BrushController}
	         */
	        (this._brushController = new BrushController(api.getZr()))
	            .on('brush', zrUtil.bind(this._onBrush, this))
	            .mount();

	        /**
	         * @private
	         * @type {boolean}
	         */
	        this._isZoomActive;
	    }

	    DataZoom.defaultOption = {
	        show: true,
	        // Icon group
	        icon: {
	            zoom: 'M0,13.5h26.9 M13.5,26.9V0 M32.1,13.5H58V58H13.5 V32.1',
	            back: 'M22,1.4L9.9,13.5l12.3,12.3 M10.3,13.5H54.9v44.6 H10.3v-26'
	        },
	        title: {
	            zoom: '区域缩放',
	            back: '区域缩放还原'
	        }
	    };

	    var proto = DataZoom.prototype;

	    proto.render = function (featureModel, ecModel, api, payload) {
	        this.model = featureModel;
	        this.ecModel = ecModel;
	        this.api = api;

	        updateZoomBtnStatus(featureModel, ecModel, this, payload, api);
	        updateBackBtnStatus(featureModel, ecModel);
	    };

	    proto.onclick = function (ecModel, api, type) {
	        handlers[type].call(this);
	    };

	    proto.remove = function (ecModel, api) {
	        this._brushController.unmount();
	    };

	    proto.dispose = function (ecModel, api) {
	        this._brushController.dispose();
	    };

	    /**
	     * @private
	     */
	    var handlers = {

	        zoom: function () {
	            var nextActive = !this._isZoomActive;

	            this.api.dispatchAction({
	                type: 'takeGlobalCursor',
	                key: 'dataZoomSelect',
	                dataZoomSelectActive: nextActive
	            });
	        },

	        back: function () {
	            this._dispatchZoomAction(history.pop(this.ecModel));
	        }
	    };

	    /**
	     * @private
	     */
	    proto._onBrush = function (areas, opt) {
	        if (!opt.isEnd || !areas.length) {
	            return;
	        }
	        var snapshot = {};
	        var ecModel = this.ecModel;

	        this._brushController.updateCovers([]); // remove cover

	        var brushTargetManager = new BrushTargetManager(
	            retrieveAxisSetting(this.model.option), ecModel, {include: ['grid']}
	        );
	        brushTargetManager.matchOutputRanges(areas, ecModel, function (area, coordRange, coordSys) {
	            if (coordSys.type !== 'cartesian2d') {
	                return;
	            }

	            var brushType = area.brushType;
	            if (brushType === 'rect') {
	                setBatch('x', coordSys, coordRange[0]);
	                setBatch('y', coordSys, coordRange[1]);
	            }
	            else {
	                setBatch(({lineX: 'x', lineY: 'y'})[brushType], coordSys, coordRange);
	            }
	        });

	        history.push(ecModel, snapshot);

	        this._dispatchZoomAction(snapshot);

	        function setBatch(dimName, coordSys, minMax) {
	            var axis = coordSys.getAxis(dimName);
	            var axisModel = axis.model;
	            var dataZoomModel = findDataZoom(dimName, axisModel, ecModel);

	            // Restrict range.
	            var minMaxSpan = dataZoomModel.findRepresentativeAxisProxy(axisModel).getMinMaxSpan();
	            if (minMaxSpan.minValueSpan != null || minMaxSpan.maxValueSpan != null) {
	                minMax = sliderMove(
	                    0, minMax.slice(), axis.scale.getExtent(), 0,
	                    minMaxSpan.minValueSpan, minMaxSpan.maxValueSpan
	                );
	            }

	            dataZoomModel && (snapshot[dataZoomModel.id] = {
	                dataZoomId: dataZoomModel.id,
	                startValue: minMax[0],
	                endValue: minMax[1]
	            });
	        }

	        function findDataZoom(dimName, axisModel, ecModel) {
	            var found;
	            ecModel.eachComponent({mainType: 'dataZoom', subType: 'select'}, function (dzModel) {
	                var has = dzModel.getAxisModel(dimName, axisModel.componentIndex);
	                has && (found = dzModel);
	            });
	            return found;
	        }
	    };

	    /**
	     * @private
	     */
	    proto._dispatchZoomAction = function (snapshot) {
	        var batch = [];

	        // Convert from hash map to array.
	        each(snapshot, function (batchItem, dataZoomId) {
	            batch.push(zrUtil.clone(batchItem));
	        });

	        batch.length && this.api.dispatchAction({
	            type: 'dataZoom',
	            from: this.uid,
	            batch: batch
	        });
	    };

	    function retrieveAxisSetting(option) {
	        var setting = {};
	        // Compatible with previous setting: null => all axis, false => no axis.
	        zrUtil.each(['xAxisIndex', 'yAxisIndex'], function (name) {
	            setting[name] = option[name];
	            setting[name] == null && (setting[name] = 'all');
	            (setting[name] === false || setting[name] === 'none') && (setting[name] = []);
	        });
	        return setting;
	    }

	    function updateBackBtnStatus(featureModel, ecModel) {
	        featureModel.setIconStatus(
	            'back',
	            history.count(ecModel) > 1 ? 'emphasis' : 'normal'
	        );
	    }

	    function updateZoomBtnStatus(featureModel, ecModel, view, payload, api) {
	        var zoomActive = view._isZoomActive;

	        if (payload && payload.type === 'takeGlobalCursor') {
	            zoomActive = payload.key === 'dataZoomSelect'
	                ? payload.dataZoomSelectActive : false;
	        }

	        view._isZoomActive = zoomActive;

	        featureModel.setIconStatus('zoom', zoomActive ? 'emphasis' : 'normal');

	        var brushTargetManager = new BrushTargetManager(
	            retrieveAxisSetting(featureModel.option), ecModel, {include: ['grid']}
	        );

	        view._brushController
	            .setPanels(brushTargetManager.makePanelOpts(api, function (targetInfo) {
	                return (targetInfo.xAxisDeclared && !targetInfo.yAxisDeclared)
	                    ? 'lineX'
	                    : (!targetInfo.xAxisDeclared && targetInfo.yAxisDeclared)
	                    ? 'lineY'
	                    : 'rect';
	            }))
	            .enableBrush(
	                zoomActive
	                ? {
	                    brushType: 'auto',
	                    brushStyle: {
	                        // FIXME user customized?
	                        lineWidth: 0,
	                        fill: 'rgba(0,0,0,0.2)'
	                    }
	                }
	                : false
	            );
	    }


	    __webpack_require__(357).register('dataZoom', DataZoom);


	    // Create special dataZoom option for select
	    __webpack_require__(1).registerPreprocessor(function (option) {
	        if (!option) {
	            return;
	        }

	        var dataZoomOpts = option.dataZoom || (option.dataZoom = []);
	        if (!zrUtil.isArray(dataZoomOpts)) {
	            option.dataZoom = dataZoomOpts = [dataZoomOpts];
	        }

	        var toolboxOpt = option.toolbox;
	        if (toolboxOpt) {
	            // Assume there is only one toolbox
	            if (zrUtil.isArray(toolboxOpt)) {
	                toolboxOpt = toolboxOpt[0];
	            }

	            if (toolboxOpt && toolboxOpt.feature) {
	                var dataZoomOpt = toolboxOpt.feature.dataZoom;
	                addForAxis('xAxis', dataZoomOpt);
	                addForAxis('yAxis', dataZoomOpt);
	            }
	        }

	        function addForAxis(axisName, dataZoomOpt) {
	            if (!dataZoomOpt) {
	                return;
	            }

	            // Try not to modify model, because it is not merged yet.
	            var axisIndicesName = axisName + 'Index';
	            var givenAxisIndices = dataZoomOpt[axisIndicesName];
	            if (givenAxisIndices != null
	                && givenAxisIndices != 'all'
	                && !zrUtil.isArray(givenAxisIndices)
	            ) {
	                givenAxisIndices = (givenAxisIndices === false || givenAxisIndices === 'none') ? [] : [givenAxisIndices];
	            }

	            forEachComponent(axisName, function (axisOpt, axisIndex) {
	                if (givenAxisIndices != null
	                    && givenAxisIndices != 'all'
	                    && zrUtil.indexOf(givenAxisIndices, axisIndex) === -1
	                ) {
	                    return;
	                }
	                var newOpt = {
	                    type: 'select',
	                    $fromToolbox: true,
	                    // Id for merge mapping.
	                    id: DATA_ZOOM_ID_BASE + axisName + axisIndex
	                };
	                // FIXME
	                // Only support one axis now.
	                newOpt[axisIndicesName] = axisIndex;
	                dataZoomOpts.push(newOpt);
	            });
	        }

	        function forEachComponent(mainType, cb) {
	            var opts = option[mainType];
	            if (!zrUtil.isArray(opts)) {
	                opts = opts ? [opts] : [];
	            }
	            each(opts, cb);
	        }
	    });

	    module.exports = DataZoom;


/***/ },
/* 419 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @file History manager.
	 */


	    var zrUtil = __webpack_require__(4);
	    var each = zrUtil.each;

	    var ATTR = '\0_ec_hist_store';

	    var history = {

	        /**
	         * @public
	         * @param {module:echarts/model/Global} ecModel
	         * @param {Object} newSnapshot {dataZoomId, batch: [payloadInfo, ...]}
	         */
	        push: function (ecModel, newSnapshot) {
	            var store = giveStore(ecModel);

	            // If previous dataZoom can not be found,
	            // complete an range with current range.
	            each(newSnapshot, function (batchItem, dataZoomId) {
	                var i = store.length - 1;
	                for (; i >= 0; i--) {
	                    var snapshot = store[i];
	                    if (snapshot[dataZoomId]) {
	                        break;
	                    }
	                }
	                if (i < 0) {
	                    // No origin range set, create one by current range.
	                    var dataZoomModel = ecModel.queryComponents(
	                        {mainType: 'dataZoom', subType: 'select', id: dataZoomId}
	                    )[0];
	                    if (dataZoomModel) {
	                        var percentRange = dataZoomModel.getPercentRange();
	                        store[0][dataZoomId] = {
	                            dataZoomId: dataZoomId,
	                            start: percentRange[0],
	                            end: percentRange[1]
	                        };
	                    }
	                }
	            });

	            store.push(newSnapshot);
	        },

	        /**
	         * @public
	         * @param {module:echarts/model/Global} ecModel
	         * @return {Object} snapshot
	         */
	        pop: function (ecModel) {
	            var store = giveStore(ecModel);
	            var head = store[store.length - 1];
	            store.length > 1 && store.pop();

	            // Find top for all dataZoom.
	            var snapshot = {};
	            each(head, function (batchItem, dataZoomId) {
	                for (var i = store.length - 1; i >= 0; i--) {
	                    var batchItem = store[i][dataZoomId];
	                    if (batchItem) {
	                        snapshot[dataZoomId] = batchItem;
	                        break;
	                    }
	                }
	            });

	            return snapshot;
	        },

	        /**
	         * @public
	         */
	        clear: function (ecModel) {
	            ecModel[ATTR] = null;
	        },

	        /**
	         * @public
	         * @param {module:echarts/model/Global} ecModel
	         * @return {number} records. always >= 1.
	         */
	        count: function (ecModel) {
	            return giveStore(ecModel).length;
	        }

	    };

	    /**
	     * [{key: dataZoomId, value: {dataZoomId, range}}, ...]
	     * History length of each dataZoom may be different.
	     * this._history[0] is used to store origin range.
	     * @type {Array.<Object>}
	     */
	    function giveStore(ecModel) {
	        var store = ecModel[ATTR];
	        if (!store) {
	            store = ecModel[ATTR] = [{}];
	        }
	        return store;
	    }

	    module.exports = history;



/***/ },
/* 420 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * DataZoom component entry
	 */


	    __webpack_require__(364);

	    __webpack_require__(365);
	    __webpack_require__(368);

	    __webpack_require__(421);
	    __webpack_require__(422);

	    __webpack_require__(374);
	    __webpack_require__(375);



/***/ },
/* 421 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * @file Data zoom model
	 */


	    var DataZoomModel = __webpack_require__(365);

	    module.exports = DataZoomModel.extend({

	        type: 'dataZoom.select'

	    });



/***/ },
/* 422 */
/***/ function(module, exports, __webpack_require__) {

	

	    module.exports = __webpack_require__(368).extend({

	        type: 'dataZoom.select'

	    });



/***/ },
/* 423 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';


	    var history = __webpack_require__(419);

	    function Restore(model) {
	        this.model = model;
	    }

	    Restore.defaultOption = {
	        show: true,
	        icon: 'M3.8,33.4 M47,18.9h9.8V8.7 M56.3,20.1 C52.1,9,40.5,0.6,26.8,2.1C12.6,3.7,1.6,16.2,2.1,30.6 M13,41.1H3.1v10.2 M3.7,39.9c4.2,11.1,15.8,19.5,29.5,18 c14.2-1.6,25.2-14.1,24.7-28.5',
	        title: '还原'
	    };

	    var proto = Restore.prototype;

	    proto.onclick = function (ecModel, api, type) {
	        history.clear(ecModel);

	        api.dispatchAction({
	            type: 'restore',
	            from: this.uid
	        });
	    };


	    __webpack_require__(357).register('restore', Restore);


	    __webpack_require__(1).registerAction(
	        {type: 'restore', event: 'restore', update: 'prepareAndUpdate'},
	        function (payload, ecModel) {
	            ecModel.resetOption('recreate');
	        }
	    );

	    module.exports = Restore;


/***/ },
/* 424 */
/***/ function(module, exports, __webpack_require__) {

	
	    __webpack_require__(425);
	    __webpack_require__(82).registerPainter('vml', __webpack_require__(427));


/***/ },
/* 425 */
/***/ function(module, exports, __webpack_require__) {

	// http://www.w3.org/TR/NOTE-VML
	// TODO Use proxy like svg instead of overwrite brush methods


	if (!__webpack_require__(2).canvasSupported) {
	    var vec2 = __webpack_require__(10);
	    var BoundingRect = __webpack_require__(9);
	    var CMD = __webpack_require__(36).CMD;
	    var colorTool = __webpack_require__(31);
	    var textContain = __webpack_require__(8);
	    var RectText = __webpack_require__(35);
	    var Displayable = __webpack_require__(21);
	    var ZImage = __webpack_require__(49);
	    var Text = __webpack_require__(50);
	    var Path = __webpack_require__(20);
	    var PathProxy = __webpack_require__(36);

	    var Gradient = __webpack_require__(66);

	    var vmlCore = __webpack_require__(426);

	    var round = Math.round;
	    var sqrt = Math.sqrt;
	    var abs = Math.abs;
	    var cos = Math.cos;
	    var sin = Math.sin;
	    var mathMax = Math.max;

	    var applyTransform = vec2.applyTransform;

	    var comma = ',';
	    var imageTransformPrefix = 'progid:DXImageTransform.Microsoft';

	    var Z = 21600;
	    var Z2 = Z / 2;

	    var ZLEVEL_BASE = 100000;
	    var Z_BASE = 1000;

	    var initRootElStyle = function (el) {
	        el.style.cssText = 'position:absolute;left:0;top:0;width:1px;height:1px;';
	        el.coordsize = Z + ','  + Z;
	        el.coordorigin = '0,0';
	    };

	    var encodeHtmlAttribute = function (s) {
	        return String(s).replace(/&/g, '&amp;').replace(/"/g, '&quot;');
	    };

	    var rgb2Str = function (r, g, b) {
	        return 'rgb(' + [r, g, b].join(',') + ')';
	    };

	    var append = function (parent, child) {
	        if (child && parent && child.parentNode !== parent) {
	            parent.appendChild(child);
	        }
	    };

	    var remove = function (parent, child) {
	        if (child && parent && child.parentNode === parent) {
	            parent.removeChild(child);
	        }
	    };

	    var getZIndex = function (zlevel, z, z2) {
	        // z 的取值范围为 [0, 1000]
	        return (parseFloat(zlevel) || 0) * ZLEVEL_BASE + (parseFloat(z) || 0) * Z_BASE + z2;
	    };

	    var parsePercent = function (value, maxValue) {
	        if (typeof value === 'string') {
	            if (value.lastIndexOf('%') >= 0) {
	                return parseFloat(value) / 100 * maxValue;
	            }
	            return parseFloat(value);
	        }
	        return value;
	    };

	    /***************************************************
	     * PATH
	     **************************************************/

	    var setColorAndOpacity = function (el, color, opacity) {
	        var colorArr = colorTool.parse(color);
	        opacity = +opacity;
	        if (isNaN(opacity)) {
	            opacity = 1;
	        }
	        if (colorArr) {
	            el.color = rgb2Str(colorArr[0], colorArr[1], colorArr[2]);
	            el.opacity = opacity * colorArr[3];
	        }
	    };

	    var getColorAndAlpha = function (color) {
	        var colorArr = colorTool.parse(color);
	        return [
	            rgb2Str(colorArr[0], colorArr[1], colorArr[2]),
	            colorArr[3]
	        ];
	    };

	    var updateFillNode = function (el, style, zrEl) {
	        // TODO pattern
	        var fill = style.fill;
	        if (fill != null) {
	            // Modified from excanvas
	            if (fill instanceof Gradient) {
	                var gradientType;
	                var angle = 0;
	                var focus = [0, 0];
	                // additional offset
	                var shift = 0;
	                // scale factor for offset
	                var expansion = 1;
	                var rect = zrEl.getBoundingRect();
	                var rectWidth = rect.width;
	                var rectHeight = rect.height;
	                if (fill.type === 'linear') {
	                    gradientType = 'gradient';
	                    var transform = zrEl.transform;
	                    var p0 = [fill.x * rectWidth, fill.y * rectHeight];
	                    var p1 = [fill.x2 * rectWidth, fill.y2 * rectHeight];
	                    if (transform) {
	                        applyTransform(p0, p0, transform);
	                        applyTransform(p1, p1, transform);
	                    }
	                    var dx = p1[0] - p0[0];
	                    var dy = p1[1] - p0[1];
	                    angle = Math.atan2(dx, dy) * 180 / Math.PI;
	                    // The angle should be a non-negative number.
	                    if (angle < 0) {
	                        angle += 360;
	                    }

	                    // Very small angles produce an unexpected result because they are
	                    // converted to a scientific notation string.
	                    if (angle < 1e-6) {
	                        angle = 0;
	                    }
	                }
	                else {
	                    gradientType = 'gradientradial';
	                    var p0 = [fill.x * rectWidth, fill.y * rectHeight];
	                    var transform = zrEl.transform;
	                    var scale = zrEl.scale;
	                    var width = rectWidth;
	                    var height = rectHeight;
	                    focus = [
	                        // Percent in bounding rect
	                        (p0[0] - rect.x) / width,
	                        (p0[1] - rect.y) / height
	                    ];
	                    if (transform) {
	                        applyTransform(p0, p0, transform);
	                    }

	                    width /= scale[0] * Z;
	                    height /= scale[1] * Z;
	                    var dimension = mathMax(width, height);
	                    shift = 2 * 0 / dimension;
	                    expansion = 2 * fill.r / dimension - shift;
	                }

	                // We need to sort the color stops in ascending order by offset,
	                // otherwise IE won't interpret it correctly.
	                var stops = fill.colorStops.slice();
	                stops.sort(function(cs1, cs2) {
	                    return cs1.offset - cs2.offset;
	                });

	                var length = stops.length;
	                // Color and alpha list of first and last stop
	                var colorAndAlphaList = [];
	                var colors = [];
	                for (var i = 0; i < length; i++) {
	                    var stop = stops[i];
	                    var colorAndAlpha = getColorAndAlpha(stop.color);
	                    colors.push(stop.offset * expansion + shift + ' ' + colorAndAlpha[0]);
	                    if (i === 0 || i === length - 1) {
	                        colorAndAlphaList.push(colorAndAlpha);
	                    }
	                }

	                if (length >= 2) {
	                    var color1 = colorAndAlphaList[0][0];
	                    var color2 = colorAndAlphaList[1][0];
	                    var opacity1 = colorAndAlphaList[0][1] * style.opacity;
	                    var opacity2 = colorAndAlphaList[1][1] * style.opacity;

	                    el.type = gradientType;
	                    el.method = 'none';
	                    el.focus = '100%';
	                    el.angle = angle;
	                    el.color = color1;
	                    el.color2 = color2;
	                    el.colors = colors.join(',');
	                    // When colors attribute is used, the meanings of opacity and o:opacity2
	                    // are reversed.
	                    el.opacity = opacity2;
	                    // FIXME g_o_:opacity ?
	                    el.opacity2 = opacity1;
	                }
	                if (gradientType === 'radial') {
	                    el.focusposition = focus.join(',');
	                }
	            }
	            else {
	                // FIXME Change from Gradient fill to color fill
	                setColorAndOpacity(el, fill, style.opacity);
	            }
	        }
	    };

	    var updateStrokeNode = function (el, style) {
	        // if (style.lineJoin != null) {
	        //     el.joinstyle = style.lineJoin;
	        // }
	        // if (style.miterLimit != null) {
	        //     el.miterlimit = style.miterLimit * Z;
	        // }
	        // if (style.lineCap != null) {
	        //     el.endcap = style.lineCap;
	        // }
	        if (style.lineDash != null) {
	            el.dashstyle = style.lineDash.join(' ');
	        }
	        if (style.stroke != null && !(style.stroke instanceof Gradient)) {
	            setColorAndOpacity(el, style.stroke, style.opacity);
	        }
	    };

	    var updateFillAndStroke = function (vmlEl, type, style, zrEl) {
	        var isFill = type == 'fill';
	        var el = vmlEl.getElementsByTagName(type)[0];
	        // Stroke must have lineWidth
	        if (style[type] != null && style[type] !== 'none' && (isFill || (!isFill && style.lineWidth))) {
	            vmlEl[isFill ? 'filled' : 'stroked'] = 'true';
	            // FIXME Remove before updating, or set `colors` will throw error
	            if (style[type] instanceof Gradient) {
	                remove(vmlEl, el);
	            }
	            if (!el) {
	                el = vmlCore.createNode(type);
	            }

	            isFill ? updateFillNode(el, style, zrEl) : updateStrokeNode(el, style);
	            append(vmlEl, el);
	        }
	        else {
	            vmlEl[isFill ? 'filled' : 'stroked'] = 'false';
	            remove(vmlEl, el);
	        }
	    };

	    var points = [[], [], []];
	    var pathDataToString = function (data, m) {
	        var M = CMD.M;
	        var C = CMD.C;
	        var L = CMD.L;
	        var A = CMD.A;
	        var Q = CMD.Q;

	        var str = [];
	        var nPoint;
	        var cmdStr;
	        var cmd;
	        var i;
	        var xi;
	        var yi;
	        for (i = 0; i < data.length;) {
	            cmd = data[i++];
	            cmdStr = '';
	            nPoint = 0;
	            switch (cmd) {
	                case M:
	                    cmdStr = ' m ';
	                    nPoint = 1;
	                    xi = data[i++];
	                    yi = data[i++];
	                    points[0][0] = xi;
	                    points[0][1] = yi;
	                    break;
	                case L:
	                    cmdStr = ' l ';
	                    nPoint = 1;
	                    xi = data[i++];
	                    yi = data[i++];
	                    points[0][0] = xi;
	                    points[0][1] = yi;
	                    break;
	                case Q:
	                case C:
	                    cmdStr = ' c ';
	                    nPoint = 3;
	                    var x1 = data[i++];
	                    var y1 = data[i++];
	                    var x2 = data[i++];
	                    var y2 = data[i++];
	                    var x3;
	                    var y3;
	                    if (cmd === Q) {
	                        // Convert quadratic to cubic using degree elevation
	                        x3 = x2;
	                        y3 = y2;
	                        x2 = (x2 + 2 * x1) / 3;
	                        y2 = (y2 + 2 * y1) / 3;
	                        x1 = (xi + 2 * x1) / 3;
	                        y1 = (yi + 2 * y1) / 3;
	                    }
	                    else {
	                        x3 = data[i++];
	                        y3 = data[i++];
	                    }
	                    points[0][0] = x1;
	                    points[0][1] = y1;
	                    points[1][0] = x2;
	                    points[1][1] = y2;
	                    points[2][0] = x3;
	                    points[2][1] = y3;

	                    xi = x3;
	                    yi = y3;
	                    break;
	                case A:
	                    var x = 0;
	                    var y = 0;
	                    var sx = 1;
	                    var sy = 1;
	                    var angle = 0;
	                    if (m) {
	                        // Extract SRT from matrix
	                        x = m[4];
	                        y = m[5];
	                        sx = sqrt(m[0] * m[0] + m[1] * m[1]);
	                        sy = sqrt(m[2] * m[2] + m[3] * m[3]);
	                        angle = Math.atan2(-m[1] / sy, m[0] / sx);
	                    }

	                    var cx = data[i++];
	                    var cy = data[i++];
	                    var rx = data[i++];
	                    var ry = data[i++];
	                    var startAngle = data[i++] + angle;
	                    var endAngle = data[i++] + startAngle + angle;
	                    // FIXME
	                    // var psi = data[i++];
	                    i++;
	                    var clockwise = data[i++];

	                    var x0 = cx + cos(startAngle) * rx;
	                    var y0 = cy + sin(startAngle) * ry;

	                    var x1 = cx + cos(endAngle) * rx;
	                    var y1 = cy + sin(endAngle) * ry;

	                    var type = clockwise ? ' wa ' : ' at ';
	                    if (Math.abs(x0 - x1) < 1e-4) {
	                        // IE won't render arches drawn counter clockwise if x0 == x1.
	                        if (Math.abs(endAngle - startAngle) > 1e-2) {
	                            // Offset x0 by 1/80 of a pixel. Use something
	                            // that can be represented in binary
	                            if (clockwise) {
	                                x0 += 270 / Z;
	                            }
	                        }
	                        else {
	                            // Avoid case draw full circle
	                            if (Math.abs(y0 - cy) < 1e-4) {
	                                if ((clockwise && x0 < cx) || (!clockwise && x0 > cx)) {
	                                    y1 -= 270 / Z;
	                                }
	                                else {
	                                    y1 += 270 / Z;
	                                }
	                            }
	                            else if ((clockwise && y0 < cy) || (!clockwise && y0 > cy)) {
	                                x1 += 270 / Z;
	                            }
	                            else {
	                                x1 -= 270 / Z;
	                            }
	                        }
	                    }
	                    str.push(
	                        type,
	                        round(((cx - rx) * sx + x) * Z - Z2), comma,
	                        round(((cy - ry) * sy + y) * Z - Z2), comma,
	                        round(((cx + rx) * sx + x) * Z - Z2), comma,
	                        round(((cy + ry) * sy + y) * Z - Z2), comma,
	                        round((x0 * sx + x) * Z - Z2), comma,
	                        round((y0 * sy + y) * Z - Z2), comma,
	                        round((x1 * sx + x) * Z - Z2), comma,
	                        round((y1 * sy + y) * Z - Z2)
	                    );

	                    xi = x1;
	                    yi = y1;
	                    break;
	                case CMD.R:
	                    var p0 = points[0];
	                    var p1 = points[1];
	                    // x0, y0
	                    p0[0] = data[i++];
	                    p0[1] = data[i++];
	                    // x1, y1
	                    p1[0] = p0[0] + data[i++];
	                    p1[1] = p0[1] + data[i++];

	                    if (m) {
	                        applyTransform(p0, p0, m);
	                        applyTransform(p1, p1, m);
	                    }

	                    p0[0] = round(p0[0] * Z - Z2);
	                    p1[0] = round(p1[0] * Z - Z2);
	                    p0[1] = round(p0[1] * Z - Z2);
	                    p1[1] = round(p1[1] * Z - Z2);
	                    str.push(
	                        // x0, y0
	                        ' m ', p0[0], comma, p0[1],
	                        // x1, y0
	                        ' l ', p1[0], comma, p0[1],
	                        // x1, y1
	                        ' l ', p1[0], comma, p1[1],
	                        // x0, y1
	                        ' l ', p0[0], comma, p1[1]
	                    );
	                    break;
	                case CMD.Z:
	                    // FIXME Update xi, yi
	                    str.push(' x ');
	            }

	            if (nPoint > 0) {
	                str.push(cmdStr);
	                for (var k = 0; k < nPoint; k++) {
	                    var p = points[k];

	                    m && applyTransform(p, p, m);
	                    // 不 round 会非常慢
	                    str.push(
	                        round(p[0] * Z - Z2), comma, round(p[1] * Z - Z2),
	                        k < nPoint - 1 ? comma : ''
	                    );
	                }
	            }
	        }

	        return str.join('');
	    };

	    // Rewrite the original path method
	    Path.prototype.brushVML = function (vmlRoot) {
	        var style = this.style;

	        var vmlEl = this._vmlEl;
	        if (!vmlEl) {
	            vmlEl = vmlCore.createNode('shape');
	            initRootElStyle(vmlEl);

	            this._vmlEl = vmlEl;
	        }

	        updateFillAndStroke(vmlEl, 'fill', style, this);
	        updateFillAndStroke(vmlEl, 'stroke', style, this);

	        var m = this.transform;
	        var needTransform = m != null;
	        var strokeEl = vmlEl.getElementsByTagName('stroke')[0];
	        if (strokeEl) {
	            var lineWidth = style.lineWidth;
	            // Get the line scale.
	            // Determinant of this.m_ means how much the area is enlarged by the
	            // transformation. So its square root can be used as a scale factor
	            // for width.
	            if (needTransform && !style.strokeNoScale) {
	                var det = m[0] * m[3] - m[1] * m[2];
	                lineWidth *= sqrt(abs(det));
	            }
	            strokeEl.weight = lineWidth + 'px';
	        }

	        var path = this.path || (this.path = new PathProxy());
	        if (this.__dirtyPath) {
	            path.beginPath();
	            this.buildPath(path, this.shape);
	            path.toStatic();
	            this.__dirtyPath = false;
	        }

	        vmlEl.path = pathDataToString(path.data, this.transform);

	        vmlEl.style.zIndex = getZIndex(this.zlevel, this.z, this.z2);

	        // Append to root
	        append(vmlRoot, vmlEl);

	        // Text
	        if (style.text != null) {
	            this.drawRectText(vmlRoot, this.getBoundingRect());
	        }
	        else {
	            this.removeRectText(vmlRoot);
	        }
	    };

	    Path.prototype.onRemove = function (vmlRoot) {
	        remove(vmlRoot, this._vmlEl);
	        this.removeRectText(vmlRoot);
	    };

	    Path.prototype.onAdd = function (vmlRoot) {
	        append(vmlRoot, this._vmlEl);
	        this.appendRectText(vmlRoot);
	    };

	    /***************************************************
	     * IMAGE
	     **************************************************/
	    var isImage = function (img) {
	        // FIXME img instanceof Image 如果 img 是一个字符串的时候，IE8 下会报错
	        return (typeof img === 'object') && img.tagName && img.tagName.toUpperCase() === 'IMG';
	        // return img instanceof Image;
	    };

	    // Rewrite the original path method
	    ZImage.prototype.brushVML = function (vmlRoot) {
	        var style = this.style;
	        var image = style.image;

	        // Image original width, height
	        var ow;
	        var oh;

	        if (isImage(image)) {
	            var src = image.src;
	            if (src === this._imageSrc) {
	                ow = this._imageWidth;
	                oh = this._imageHeight;
	            }
	            else {
	                var imageRuntimeStyle = image.runtimeStyle;
	                var oldRuntimeWidth = imageRuntimeStyle.width;
	                var oldRuntimeHeight = imageRuntimeStyle.height;
	                imageRuntimeStyle.width = 'auto';
	                imageRuntimeStyle.height = 'auto';

	                // get the original size
	                ow = image.width;
	                oh = image.height;

	                // and remove overides
	                imageRuntimeStyle.width = oldRuntimeWidth;
	                imageRuntimeStyle.height = oldRuntimeHeight;

	                // Caching image original width, height and src
	                this._imageSrc = src;
	                this._imageWidth = ow;
	                this._imageHeight = oh;
	            }
	            image = src;
	        }
	        else {
	            if (image === this._imageSrc) {
	                ow = this._imageWidth;
	                oh = this._imageHeight;
	            }
	        }
	        if (!image) {
	            return;
	        }

	        var x = style.x || 0;
	        var y = style.y || 0;

	        var dw = style.width;
	        var dh = style.height;

	        var sw = style.sWidth;
	        var sh = style.sHeight;
	        var sx = style.sx || 0;
	        var sy = style.sy || 0;

	        var hasCrop = sw && sh;

	        var vmlEl = this._vmlEl;
	        if (!vmlEl) {
	            // FIXME 使用 group 在 left, top 都不是 0 的时候就无法显示了。
	            // vmlEl = vmlCore.createNode('group');
	            vmlEl = vmlCore.doc.createElement('div');
	            initRootElStyle(vmlEl);

	            this._vmlEl = vmlEl;
	        }

	        var vmlElStyle = vmlEl.style;
	        var hasRotation = false;
	        var m;
	        var scaleX = 1;
	        var scaleY = 1;
	        if (this.transform) {
	            m = this.transform;
	            scaleX = sqrt(m[0] * m[0] + m[1] * m[1]);
	            scaleY = sqrt(m[2] * m[2] + m[3] * m[3]);

	            hasRotation = m[1] || m[2];
	        }
	        if (hasRotation) {
	            // If filters are necessary (rotation exists), create them
	            // filters are bog-slow, so only create them if abbsolutely necessary
	            // The following check doesn't account for skews (which don't exist
	            // in the canvas spec (yet) anyway.
	            // From excanvas
	            var p0 = [x, y];
	            var p1 = [x + dw, y];
	            var p2 = [x, y + dh];
	            var p3 = [x + dw, y + dh];
	            applyTransform(p0, p0, m);
	            applyTransform(p1, p1, m);
	            applyTransform(p2, p2, m);
	            applyTransform(p3, p3, m);

	            var maxX = mathMax(p0[0], p1[0], p2[0], p3[0]);
	            var maxY = mathMax(p0[1], p1[1], p2[1], p3[1]);

	            var transformFilter = [];
	            transformFilter.push('M11=', m[0] / scaleX, comma,
	                        'M12=', m[2] / scaleY, comma,
	                        'M21=', m[1] / scaleX, comma,
	                        'M22=', m[3] / scaleY, comma,
	                        'Dx=', round(x * scaleX + m[4]), comma,
	                        'Dy=', round(y * scaleY + m[5]));

	            vmlElStyle.padding = '0 ' + round(maxX) + 'px ' + round(maxY) + 'px 0';
	            // FIXME DXImageTransform 在 IE11 的兼容模式下不起作用
	            vmlElStyle.filter = imageTransformPrefix + '.Matrix('
	                + transformFilter.join('') + ', SizingMethod=clip)';

	        }
	        else {
	            if (m) {
	                x = x * scaleX + m[4];
	                y = y * scaleY + m[5];
	            }
	            vmlElStyle.filter = '';
	            vmlElStyle.left = round(x) + 'px';
	            vmlElStyle.top = round(y) + 'px';
	        }

	        var imageEl = this._imageEl;
	        var cropEl = this._cropEl;

	        if (!imageEl) {
	            imageEl = vmlCore.doc.createElement('div');
	            this._imageEl = imageEl;
	        }
	        var imageELStyle = imageEl.style;
	        if (hasCrop) {
	            // Needs know image original width and height
	            if (! (ow && oh)) {
	                var tmpImage = new Image();
	                var self = this;
	                tmpImage.onload = function () {
	                    tmpImage.onload = null;
	                    ow = tmpImage.width;
	                    oh = tmpImage.height;
	                    // Adjust image width and height to fit the ratio destinationSize / sourceSize
	                    imageELStyle.width = round(scaleX * ow * dw / sw) + 'px';
	                    imageELStyle.height = round(scaleY * oh * dh / sh) + 'px';

	                    // Caching image original width, height and src
	                    self._imageWidth = ow;
	                    self._imageHeight = oh;
	                    self._imageSrc = image;
	                };
	                tmpImage.src = image;
	            }
	            else {
	                imageELStyle.width = round(scaleX * ow * dw / sw) + 'px';
	                imageELStyle.height = round(scaleY * oh * dh / sh) + 'px';
	            }

	            if (! cropEl) {
	                cropEl = vmlCore.doc.createElement('div');
	                cropEl.style.overflow = 'hidden';
	                this._cropEl = cropEl;
	            }
	            var cropElStyle = cropEl.style;
	            cropElStyle.width = round((dw + sx * dw / sw) * scaleX);
	            cropElStyle.height = round((dh + sy * dh / sh) * scaleY);
	            cropElStyle.filter = imageTransformPrefix + '.Matrix(Dx='
	                    + (-sx * dw / sw * scaleX) + ',Dy=' + (-sy * dh / sh * scaleY) + ')';

	            if (! cropEl.parentNode) {
	                vmlEl.appendChild(cropEl);
	            }
	            if (imageEl.parentNode != cropEl) {
	                cropEl.appendChild(imageEl);
	            }
	        }
	        else {
	            imageELStyle.width = round(scaleX * dw) + 'px';
	            imageELStyle.height = round(scaleY * dh) + 'px';

	            vmlEl.appendChild(imageEl);

	            if (cropEl && cropEl.parentNode) {
	                vmlEl.removeChild(cropEl);
	                this._cropEl = null;
	            }
	        }

	        var filterStr = '';
	        var alpha = style.opacity;
	        if (alpha < 1) {
	            filterStr += '.Alpha(opacity=' + round(alpha * 100) + ') ';
	        }
	        filterStr += imageTransformPrefix + '.AlphaImageLoader(src=' + image + ', SizingMethod=scale)';

	        imageELStyle.filter = filterStr;

	        vmlEl.style.zIndex = getZIndex(this.zlevel, this.z, this.z2);

	        // Append to root
	        append(vmlRoot, vmlEl);

	        // Text
	        if (style.text != null) {
	            this.drawRectText(vmlRoot, this.getBoundingRect());
	        }
	    };

	    ZImage.prototype.onRemove = function (vmlRoot) {
	        remove(vmlRoot, this._vmlEl);

	        this._vmlEl = null;
	        this._cropEl = null;
	        this._imageEl = null;

	        this.removeRectText(vmlRoot);
	    };

	    ZImage.prototype.onAdd = function (vmlRoot) {
	        append(vmlRoot, this._vmlEl);
	        this.appendRectText(vmlRoot);
	    };


	    /***************************************************
	     * TEXT
	     **************************************************/

	    var DEFAULT_STYLE_NORMAL = 'normal';

	    var fontStyleCache = {};
	    var fontStyleCacheCount = 0;
	    var MAX_FONT_CACHE_SIZE = 100;
	    var fontEl = document.createElement('div');

	    var getFontStyle = function (fontString) {
	        var fontStyle = fontStyleCache[fontString];
	        if (!fontStyle) {
	            // Clear cache
	            if (fontStyleCacheCount > MAX_FONT_CACHE_SIZE) {
	                fontStyleCacheCount = 0;
	                fontStyleCache = {};
	            }

	            var style = fontEl.style;
	            var fontFamily;
	            try {
	                style.font = fontString;
	                fontFamily = style.fontFamily.split(',')[0];
	            }
	            catch (e) {
	            }

	            fontStyle = {
	                style: style.fontStyle || DEFAULT_STYLE_NORMAL,
	                variant: style.fontVariant || DEFAULT_STYLE_NORMAL,
	                weight: style.fontWeight || DEFAULT_STYLE_NORMAL,
	                size: parseFloat(style.fontSize || 12) | 0,
	                family: fontFamily || 'Microsoft YaHei'
	            };

	            fontStyleCache[fontString] = fontStyle;
	            fontStyleCacheCount++;
	        }
	        return fontStyle;
	    };

	    var textMeasureEl;
	    // Overwrite measure text method
	    textContain.measureText = function (text, textFont) {
	        var doc = vmlCore.doc;
	        if (!textMeasureEl) {
	            textMeasureEl = doc.createElement('div');
	            textMeasureEl.style.cssText = 'position:absolute;top:-20000px;left:0;'
	                + 'padding:0;margin:0;border:none;white-space:pre;';
	            vmlCore.doc.body.appendChild(textMeasureEl);
	        }

	        try {
	            textMeasureEl.style.font = textFont;
	        } catch (ex) {
	            // Ignore failures to set to invalid font.
	        }
	        textMeasureEl.innerHTML = '';
	        // Don't use innerHTML or innerText because they allow markup/whitespace.
	        textMeasureEl.appendChild(doc.createTextNode(text));
	        return {
	            width: textMeasureEl.offsetWidth
	        };
	    };

	    var tmpRect = new BoundingRect();

	    var drawRectText = function (vmlRoot, rect, textRect, fromTextEl) {

	        var style = this.style;
	        var text = style.text;
	        // Convert to string
	        text != null && (text += '');
	        if (!text) {
	            return;
	        }

	        var x;
	        var y;
	        var align = style.textAlign;
	        var fontStyle = getFontStyle(style.textFont);
	        // FIXME encodeHtmlAttribute ?
	        var font = fontStyle.style + ' ' + fontStyle.variant + ' ' + fontStyle.weight + ' '
	            + fontStyle.size + 'px "' + fontStyle.family + '"';

	        var baseline = style.textBaseline;
	        var verticalAlign = style.textVerticalAlign;

	        textRect = textRect || textContain.getBoundingRect(text, font, align, baseline);

	        // Transform rect to view space
	        var m = this.transform;
	        // Ignore transform for text in other element
	        if (m && !fromTextEl) {
	            tmpRect.copy(rect);
	            tmpRect.applyTransform(m);
	            rect = tmpRect;
	        }

	        if (!fromTextEl) {
	            var textPosition = style.textPosition;
	            var distance = style.textDistance;
	            // Text position represented by coord
	            if (textPosition instanceof Array) {
	                x = rect.x + parsePercent(textPosition[0], rect.width);
	                y = rect.y + parsePercent(textPosition[1], rect.height);

	                align = align || 'left';
	                baseline = baseline || 'top';
	            }
	            else {
	                var res = textContain.adjustTextPositionOnRect(
	                    textPosition, rect, textRect, distance
	                );
	                x = res.x;
	                y = res.y;

	                // Default align and baseline when has textPosition
	                align = align || res.textAlign;
	                baseline = baseline || res.textBaseline;
	            }
	        }
	        else {
	            x = rect.x;
	            y = rect.y;
	        }
	        if (verticalAlign) {
	            switch (verticalAlign) {
	                case 'middle':
	                    y -= textRect.height / 2;
	                    break;
	                case 'bottom':
	                    y -= textRect.height;
	                    break;
	                // 'top'
	            }
	            // Ignore baseline
	            baseline = 'top';
	        }

	        var fontSize = fontStyle.size;
	        // 1.75 is an arbitrary number, as there is no info about the text baseline
	        switch (baseline) {
	            case 'hanging':
	            case 'top':
	                y += fontSize / 1.75;
	                break;
	            case 'middle':
	                break;
	            default:
	            // case null:
	            // case 'alphabetic':
	            // case 'ideographic':
	            // case 'bottom':
	                y -= fontSize / 2.25;
	                break;
	        }
	        switch (align) {
	            case 'left':
	                break;
	            case 'center':
	                x -= textRect.width / 2;
	                break;
	            case 'right':
	                x -= textRect.width;
	                break;
	            // case 'end':
	                // align = elementStyle.direction == 'ltr' ? 'right' : 'left';
	                // break;
	            // case 'start':
	                // align = elementStyle.direction == 'rtl' ? 'right' : 'left';
	                // break;
	            // default:
	            //     align = 'left';
	        }

	        var createNode = vmlCore.createNode;

	        var textVmlEl = this._textVmlEl;
	        var pathEl;
	        var textPathEl;
	        var skewEl;
	        if (!textVmlEl) {
	            textVmlEl = createNode('line');
	            pathEl = createNode('path');
	            textPathEl = createNode('textpath');
	            skewEl = createNode('skew');

	            // FIXME Why here is not cammel case
	            // Align 'center' seems wrong
	            textPathEl.style['v-text-align'] = 'left';

	            initRootElStyle(textVmlEl);

	            pathEl.textpathok = true;
	            textPathEl.on = true;

	            textVmlEl.from = '0 0';
	            textVmlEl.to = '1000 0.05';

	            append(textVmlEl, skewEl);
	            append(textVmlEl, pathEl);
	            append(textVmlEl, textPathEl);

	            this._textVmlEl = textVmlEl;
	        }
	        else {
	            // 这里是在前面 appendChild 保证顺序的前提下
	            skewEl = textVmlEl.firstChild;
	            pathEl = skewEl.nextSibling;
	            textPathEl = pathEl.nextSibling;
	        }

	        var coords = [x, y];
	        var textVmlElStyle = textVmlEl.style;
	        // Ignore transform for text in other element
	        if (m && fromTextEl) {
	            applyTransform(coords, coords, m);

	            skewEl.on = true;

	            skewEl.matrix = m[0].toFixed(3) + comma + m[2].toFixed(3) + comma +
	            m[1].toFixed(3) + comma + m[3].toFixed(3) + ',0,0';

	            // Text position
	            skewEl.offset = (round(coords[0]) || 0) + ',' + (round(coords[1]) || 0);
	            // Left top point as origin
	            skewEl.origin = '0 0';

	            textVmlElStyle.left = '0px';
	            textVmlElStyle.top = '0px';
	        }
	        else {
	            skewEl.on = false;
	            textVmlElStyle.left = round(x) + 'px';
	            textVmlElStyle.top = round(y) + 'px';
	        }

	        textPathEl.string = encodeHtmlAttribute(text);
	        // TODO
	        try {
	            textPathEl.style.font = font;
	        }
	        // Error font format
	        catch (e) {}

	        updateFillAndStroke(textVmlEl, 'fill', {
	            fill: fromTextEl ? style.fill : style.textFill,
	            opacity: style.opacity
	        }, this);
	        updateFillAndStroke(textVmlEl, 'stroke', {
	            stroke: fromTextEl ? style.stroke : style.textStroke,
	            opacity: style.opacity,
	            lineDash: style.lineDash
	        }, this);

	        textVmlEl.style.zIndex = getZIndex(this.zlevel, this.z, this.z2);

	        // Attached to root
	        append(vmlRoot, textVmlEl);
	    };

	    var removeRectText = function (vmlRoot) {
	        remove(vmlRoot, this._textVmlEl);
	        this._textVmlEl = null;
	    };

	    var appendRectText = function (vmlRoot) {
	        append(vmlRoot, this._textVmlEl);
	    };

	    var list = [RectText, Displayable, ZImage, Path, Text];

	    // In case Displayable has been mixed in RectText
	    for (var i = 0; i < list.length; i++) {
	        var proto = list[i].prototype;
	        proto.drawRectText = drawRectText;
	        proto.removeRectText = removeRectText;
	        proto.appendRectText = appendRectText;
	    }

	    Text.prototype.brushVML = function (vmlRoot) {
	        var style = this.style;
	        if (style.text != null) {
	            this.drawRectText(vmlRoot, {
	                x: style.x || 0, y: style.y || 0,
	                width: 0, height: 0
	            }, this.getBoundingRect(), true);
	        }
	        else {
	            this.removeRectText(vmlRoot);
	        }
	    };

	    Text.prototype.onRemove = function (vmlRoot) {
	        this.removeRectText(vmlRoot);
	    };

	    Text.prototype.onAdd = function (vmlRoot) {
	        this.appendRectText(vmlRoot);
	    };
	}


/***/ },
/* 426 */
/***/ function(module, exports, __webpack_require__) {

	

	if (!__webpack_require__(2).canvasSupported) {
	    var urn = 'urn:schemas-microsoft-com:vml';

	    var createNode;
	    var win = window;
	    var doc = win.document;

	    var vmlInited = false;

	    try {
	        !doc.namespaces.zrvml && doc.namespaces.add('zrvml', urn);
	        createNode = function (tagName) {
	            return doc.createElement('<zrvml:' + tagName + ' class="zrvml">');
	        };
	    }
	    catch (e) {
	        createNode = function (tagName) {
	            return doc.createElement('<' + tagName + ' xmlns="' + urn + '" class="zrvml">');
	        };
	    }

	    // From raphael
	    var initVML = function () {
	        if (vmlInited) {
	            return;
	        }
	        vmlInited = true;

	        var styleSheets = doc.styleSheets;
	        if (styleSheets.length < 31) {
	            doc.createStyleSheet().addRule('.zrvml', 'behavior:url(#default#VML)');
	        }
	        else {
	            // http://msdn.microsoft.com/en-us/library/ms531194%28VS.85%29.aspx
	            styleSheets[0].addRule('.zrvml', 'behavior:url(#default#VML)');
	        }
	    };

	    // Not useing return to avoid error when converting to CommonJS module
	    module.exports = {
	        doc: doc,
	        initVML: initVML,
	        createNode: createNode
	    };
	}


/***/ },
/* 427 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * VML Painter.
	 *
	 * @module zrender/vml/Painter
	 */



	    var zrLog = __webpack_require__(33);
	    var vmlCore = __webpack_require__(426);

	    function parseInt10(val) {
	        return parseInt(val, 10);
	    }

	    /**
	     * @alias module:zrender/vml/Painter
	     */
	    function VMLPainter(root, storage) {

	        vmlCore.initVML();

	        this.root = root;

	        this.storage = storage;

	        var vmlViewport = document.createElement('div');

	        var vmlRoot = document.createElement('div');

	        vmlViewport.style.cssText = 'display:inline-block;overflow:hidden;position:relative;width:300px;height:150px;';

	        vmlRoot.style.cssText = 'position:absolute;left:0;top:0;';

	        root.appendChild(vmlViewport);

	        this._vmlRoot = vmlRoot;
	        this._vmlViewport = vmlViewport;

	        this.resize();

	        // Modify storage
	        var oldDelFromStorage = storage.delFromStorage;
	        var oldAddToStorage = storage.addToStorage;
	        storage.delFromStorage = function (el) {
	            oldDelFromStorage.call(storage, el);

	            if (el) {
	                el.onRemove && el.onRemove(vmlRoot);
	            }
	        };

	        storage.addToStorage = function (el) {
	            // Displayable already has a vml node
	            el.onAdd && el.onAdd(vmlRoot);

	            oldAddToStorage.call(storage, el);
	        };

	        this._firstPaint = true;
	    }

	    VMLPainter.prototype = {

	        constructor: VMLPainter,

	        /**
	         * @return {HTMLDivElement}
	         */
	        getViewportRoot: function () {
	            return this._vmlViewport;
	        },

	        /**
	         * 刷新
	         */
	        refresh: function () {

	            var list = this.storage.getDisplayList(true, true);

	            this._paintList(list);
	        },

	        _paintList: function (list) {
	            var vmlRoot = this._vmlRoot;
	            for (var i = 0; i < list.length; i++) {
	                var el = list[i];
	                if (el.invisible || el.ignore) {
	                    if (!el.__alreadyNotVisible) {
	                        el.onRemove(vmlRoot);
	                    }
	                    // Set as already invisible
	                    el.__alreadyNotVisible = true;
	                }
	                else {
	                    if (el.__alreadyNotVisible) {
	                        el.onAdd(vmlRoot);
	                    }
	                    el.__alreadyNotVisible = false;
	                    if (el.__dirty) {
	                        el.beforeBrush && el.beforeBrush();
	                        (el.brushVML || el.brush).call(el, vmlRoot);
	                        el.afterBrush && el.afterBrush();
	                    }
	                }
	                el.__dirty = false;
	            }

	            if (this._firstPaint) {
	                // Detached from document at first time
	                // to avoid page refreshing too many times

	                // FIXME 如果每次都先 removeChild 可能会导致一些填充和描边的效果改变
	                this._vmlViewport.appendChild(vmlRoot);
	                this._firstPaint = false;
	            }
	        },

	        resize: function (width, height) {
	            var width = width == null ? this._getWidth() : width;
	            var height = height == null ? this._getHeight() : height;

	            if (this._width != width || this._height != height) {
	                this._width = width;
	                this._height = height;

	                var vmlViewportStyle = this._vmlViewport.style;
	                vmlViewportStyle.width = width + 'px';
	                vmlViewportStyle.height = height + 'px';
	            }
	        },

	        dispose: function () {
	            this.root.innerHTML = '';

	            this._vmlRoot =
	            this._vmlViewport =
	            this.storage = null;
	        },

	        getWidth: function () {
	            return this._width;
	        },

	        getHeight: function () {
	            return this._height;
	        },

	        clear: function () {
	            if (this._vmlViewport) {
	                this.root.removeChild(this._vmlViewport);
	            }
	        },

	        _getWidth: function () {
	            var root = this.root;
	            var stl = root.currentStyle;

	            return ((root.clientWidth || parseInt10(stl.width))
	                    - parseInt10(stl.paddingLeft)
	                    - parseInt10(stl.paddingRight)) | 0;
	        },

	        _getHeight: function () {
	            var root = this.root;
	            var stl = root.currentStyle;

	            return ((root.clientHeight || parseInt10(stl.height))
	                    - parseInt10(stl.paddingTop)
	                    - parseInt10(stl.paddingBottom)) | 0;
	        }
	    };

	    // Not supported methods
	    function createMethodNotSupport(method) {
	        return function () {
	            zrLog('In IE8.0 VML mode painter not support method "' + method + '"');
	        };
	    }

	    var notSupportedMethods = [
	        'getLayer', 'insertLayer', 'eachLayer', 'eachBuiltinLayer', 'eachOtherLayer', 'getLayers',
	        'modLayer', 'delLayer', 'clearLayer', 'toDataURL', 'pathToImage'
	    ];

	    for (var i = 0; i < notSupportedMethods.length; i++) {
	        var name = notSupportedMethods[i];
	        VMLPainter.prototype[name] = createMethodNotSupport(name);
	    }

	    module.exports = VMLPainter;


/***/ }
/******/ ])
});
;