(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__(192);
	__webpack_require__(204);
	__webpack_require__(225);
	__webpack_require__(229);
	__webpack_require__(233);
	__webpack_require__(250);
	__webpack_require__(256);
	__webpack_require__(263);
	__webpack_require__(269);
	__webpack_require__(273);
	__webpack_require__(282);
	__webpack_require__(286);
	__webpack_require__(289);
	__webpack_require__(312);

	__webpack_require__(318);
	__webpack_require__(319);
	__webpack_require__(320);
	__webpack_require__(326);
	__webpack_require__(297);
	__webpack_require__(330);
	__webpack_require__(343);
	__webpack_require__(234);
	__webpack_require__(290);
	__webpack_require__(346);
	__webpack_require__(357);

	__webpack_require__(361);

	__webpack_require__(362);
	__webpack_require__(375);

	__webpack_require__(390);
	__webpack_require__(396);
	__webpack_require__(399);

	__webpack_require__(402);
	__webpack_require__(411);

	__webpack_require__(423);


/***/ },
/* 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.0',
	        dependencies: {
	            zrender: '3.5.0'
	        }
	    };

	    function enableConnect(chart) {
	        var STATUS_PENDING = 0;
	        var STATUS_UPDATING = 1;
	        var STATUS_UPDATED = 2;
	        var STATUS_KEY = '__connectUpdateStatus';

	        function updateConnectedChartsStatus(charts, status) {
	            for (var i = 0; i < charts.length; i++) {
	                var otherChart = charts[i];
	                otherChart[STATUS_KEY] = status;
	            }
	        }

	        zrUtil.each(eventActionMap, function (actionType, eventType) {
	            chart._messageCenter.on(eventType, function (event) {
	                if (connectedGroups[chart.group] && chart[STATUS_KEY] !== STATUS_PENDING) {
	                    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);
	    };

	    /**
	     * 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]
	         * @return {string}
	         */
	        getFormattedLabel: function (dataIndex, status, dataType, dimIndex) {
	            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(['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) {

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



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

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

	    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) {
	                // var rect = this.getBoundingRect();
	                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',

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

	            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.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.0';

	    /**
	     * 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.msRequestAnimationFrame
	                                    || 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 () {
	            if (true) {
	                if (this._interval == null) {
	                    throw new Error('`nice` should be called firstly' );
	                }
	            }
	            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();
	        },

	        /**
	         * @return {Array.<number>}
	         */
	        getTicks: function () {
	            if (true) {
	                if (this._interval == null) {
	                    throw new Error('`nice` should be called firstly' );
	                }
	            }
	            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 = numberUtil.getPrecisionSafe(interval) + 2;
	        // 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;
	    };

	    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);
	                    // coordDim === 'value' && valueCandidate == null && (valueCandidate = resultDimIdx);
	                }
	            });
	        });

	        // 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);
	                // coordDim === 'value' && valueCandidate == null && (valueCandidate = resultDimIdx);
	                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(
	                // Ensure At least one value dim.
	                // (dataDimNameMap.get('value') == null
	                //     && (valueCandidate == null || valueCandidate === resultDimIdx)
	                //     // Try to set as 'value' only if coordDim is not set as 'extra'.
	                //     && coordDim == null
	                // )
	                // ? 'value'
	                // :
	                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,

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

	        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;

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

	        // 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) {

	        var gridRect = layout.getLayoutRect(
	            gridModel.getBoxLayoutParams(), {
	                width: api.getWidth(),
	                height: api.getHeight()
	            });

	        this._rect = gridRect;

	        var axesList = this._axesList;

	        adjustAxes();

	        // Minus label size
	        if (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;
	            // Postpone `resize` to `update`.
	            // grid.resize(gridModel, api);

	            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);
	            if (!coordSys
	                || seriesTooltipTrigger === 'none'
	                || seriesTooltipTrigger === false
	                || seriesTooltipTrigger === 'item'
	                || 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,

	            // 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 && isHorizontal) {
	            el.setShape('r', itemStyleModel.get('barBorderRadius') || 0);
	        }

	        el.useStyle(zrUtil.defaults(
	            {
	                fill: color,
	                opacity: opacity
	            },
	            itemStyleModel.getBarItemStyle()
	        ));

	        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 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);
	            var sum = data.getSum('value');
	            // FIXME toFixed?
	            //
	            // 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;
	        },

	        _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,

	            // If still show when all data zero.
	            stillShowZeroSum: true,

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

	        // 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,

	            // 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];
	                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
	                // FIXME precision
	                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 = -1;
	                var axesTicksPoints = zrUtil.map(indicatorAxes, function (indicatorAxis, idx) {
	                    var ticksCoords = indicatorAxis.getTicksCoords();
	                    realSplitNumber = Math.max(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__(180);

	    __webpack_require__(186);

	    __webpack_require__(171);

	    echarts.registerLayout(__webpack_require__(188));

	    echarts.registerVisual(__webpack_require__(189));

	    echarts.registerProcessor(PRIORITY.PROCESSOR.STATISTIC, __webpack_require__(190));

	    echarts.registerPreprocessor(__webpack_require__(191));

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

	    /**
	     * [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__) {

	

	    // var zrUtil = require('zrender/lib/core/util');
	    var graphic = __webpack_require__(18);

	    var MapDraw = __webpack_require__(181);

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


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

	/**
	 * @module echarts/component/helper/MapDraw
	 */


	    var RoamController = __webpack_require__(182);
	    var roamHelper = __webpack_require__(184);
	    var cursorHelper = __webpack_require__(185);
	    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;


/***/ },
/* 182 */
/***/ 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__(183);

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


/***/ },
/* 183 */
/***/ 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;


/***/ },
/* 184 */
/***/ 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;


/***/ },
/* 185 */
/***/ 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;


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

	

	    var zrUtil = __webpack_require__(4);
	    var roamHelper = __webpack_require__(187);

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


/***/ },
/* 187 */
/***/ 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;


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


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


/***/ },
/* 190 */
/***/ 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];
	            }
	        });
	    };


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


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

	

	    var echarts = __webpack_require__(1);

	    __webpack_require__(193);
	    __webpack_require__(197);
	    __webpack_require__(200);

	    echarts.registerVisual(__webpack_require__(201));

	    echarts.registerLayout(__webpack_require__(203));


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

	

	    var SeriesModel = __webpack_require__(78);
	    var Tree = __webpack_require__(194);
	    var zrUtil = __webpack_require__(4);
	    var Model = __webpack_require__(12);
	    var formatUtil = __webpack_require__(6);
	    var helper = __webpack_require__(196);
	    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', ...
	                    textStyle: {
	                        color: '#fff',
	                        ellipsis: true
	                    }
	                }
	            },
	            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) {
	            var rootName = option.name;
	            rootName == null && (rootName = option.name);

	            // Create a virtual root.
	            var root = {name: rootName, 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;
	    }



/***/ },
/* 194 */
/***/ 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__(195);
	    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;


/***/ },
/* 195 */
/***/ 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;


/***/ },
/* 196 */
/***/ 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;


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

	 

	    var zrUtil = __webpack_require__(4);
	    var graphic = __webpack_require__(18);
	    var DataDiffer = __webpack_require__(99);
	    var helper = __webpack_require__(196);
	    var Breadcrumb = __webpack_require__(198);
	    var RoamController = __webpack_require__(182);
	    var BoundingRect = __webpack_require__(9);
	    var matrix = __webpack_require__(11);
	    var animationUtil = __webpack_require__(199);
	    var bind = zrUtil.bind;
	    var Group = graphic.Group;
	    var Rect = graphic.Rect;
	    var each = zrUtil.each;

	    var DRAG_THRESHOLD = 3;
	    var PATH_LABEL_NORMAL = ['label', 'normal'];
	    var PATH_LABEL_EMPHASIS = ['label', '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;
	        }

	        var thisLayout = thisNode.getLayout();

	        if (!thisLayout || !thisLayout.isInView) {
	            return;
	        }

	        var thisWidth = thisLayout.width;
	        var thisHeight = thisLayout.height;
	        var thisInvisible = thisLayout.invisible;

	        var thisRawIndex = thisNode.getRawIndex();
	        var oldRawIndex = oldNode && oldNode.getRawIndex();

	        // 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);
	        if (bg) {
	            bg.setShape({x: 0, y: 0, width: thisWidth, height: thisHeight});
	            updateStyle(bg, function () {
	                bg.setStyle('fill', thisNode.getVisual('borderColor', true));
	            });
	            group.add(bg);
	        }

	        var thisViewChildren = thisNode.viewChildren;

	        // No children, render content.
	        if (!thisViewChildren || !thisViewChildren.length) {
	            var content = giveGraphic('content', Rect, depth, Z_CONTENT);
	            content && renderContent(group);
	        }

	        return group;

	        // ----------------------------
	        // | Procedures in renderNode |
	        // ----------------------------

	        function renderContent(group) {
	            // For tooltip.
	            content.dataIndex = thisNode.dataIndex;
	            content.seriesIndex = seriesModel.seriesIndex;

	            var borderWidth = thisLayout.borderWidth;
	            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 = thisNode.getModel('itemStyle.emphasis').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, contentWidth, contentHeight) {
	            var nodeModel = thisNode.getModel();
	            var text = nodeModel.get('name');
	            if (thisLayout.isLeafRoot) {
	                var iconChar = seriesModel.get('drillDownIcon', true);
	                text = iconChar ? iconChar + ' ' + text : text;
	            }

	            setText(
	                text, normalStyle, nodeModel, PATH_LABEL_NORMAL,
	                visualColor, contentWidth, contentHeight
	            );
	            setText(
	                text, emphasisStyle, nodeModel, PATH_LABEL_EMPHASIS,
	                visualColor, contentWidth, contentHeight
	            );
	        }

	        function setText(text, style, nodeModel, labelPath, visualColor, contentWidth, contentHeight) {
	            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');

	            var textRect = labelTextStyleModel.getTextRect(text);
	            if (!labelModel.getShallow('show') || textRect.height > contentHeight) {
	                style.text = '';
	            }
	            else if (textRect.width > contentWidth) {
	                style.text = labelTextStyleModel.get('ellipsis')
	                    ? labelTextStyleModel.truncateText(
	                        text, contentWidth, 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;
	    }



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

	 

	    var graphic = __webpack_require__(18);
	    var layout = __webpack_require__(71);
	    var zrUtil = __webpack_require__(4);
	    var helper = __webpack_require__(196);

	    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;


/***/ },
/* 199 */
/***/ 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};


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

	/**
	 * @file Treemap action
	 */


	    var echarts = __webpack_require__(1);
	    var helper = __webpack_require__(196);

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



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

	

	    var VisualMapping = __webpack_require__(202);
	    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;
	    }



/***/ },
/* 202 */
/***/ 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;



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

	

	    var zrUtil = __webpack_require__(4);
	    var numberUtil = __webpack_require__(7);
	    var layout = __webpack_require__(71);
	    var helper = __webpack_require__(196);
	    var BoundingRect = __webpack_require__(9);
	    var helper = __webpack_require__(196);

	    var mathMax = Math.max;
	    var mathMin = Math.min;
	    var parsePercent = numberUtil.parsePercent;
	    var retrieveValue = zrUtil.retrieve;
	    var each = zrUtil.each;

	    /**
	     * @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},
	                        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 itemStyleModel = node.getModel('itemStyle.normal');
	        var borderWidth = itemStyleModel.get('borderWidth');
	        var halfGapWidth = itemStyleModel.get('gapWidth') / 2;
	        var layoutOffset = borderWidth - halfGapWidth;
	        var nodeModel = node.getModel();

	        node.setLayout({borderWidth: borderWidth}, true);

	        width = mathMax(width - 2 * layoutOffset, 0);
	        height = mathMax(height - 2 * layoutOffset, 0);

	        var totalArea = width * height;
	        var viewChildren = initChildren(
	            node, nodeModel, totalArea, options, hideChildren, depth
	        );

	        if (!viewChildren.length) {
	            return;
	        }

	        var rect = {x: layoutOffset, y: layoutOffset, 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;

	            var borderWidth = parent.getModel('itemStyle.normal').get('borderWidth');

	            if (isFinite(borderWidth)) {
	                // Considering border, suppose aspect ratio is 1.
	                area += 4 * borderWidth * borderWidth + 4 * borderWidth * 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);
	        });
	    }

	    module.exports = update;


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

	

	    var echarts = __webpack_require__(1);
	    var zrUtil = __webpack_require__(4);

	    __webpack_require__(205);
	    __webpack_require__(208);

	    __webpack_require__(213);

	    echarts.registerProcessor(__webpack_require__(214));

	    echarts.registerVisual(zrUtil.curry(
	        __webpack_require__(121), 'graph', 'circle', null
	    ));
	    echarts.registerVisual(__webpack_require__(215));
	    echarts.registerVisual(__webpack_require__(216));

	    echarts.registerLayout(__webpack_require__(217));
	    echarts.registerLayout(__webpack_require__(220));
	    echarts.registerLayout(__webpack_require__(222));

	    // Graph view coordinate system
	    echarts.registerCoordinateSystem('graphView', {
	        create: __webpack_require__(224)
	    });


/***/ },
/* 205 */
/***/ 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__(206);

	    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,

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


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

	

	    var List = __webpack_require__(98);
	    var Graph = __webpack_require__(207);
	    var linkList = __webpack_require__(195);
	    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;
	    };


/***/ },
/* 207 */
/***/ 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)]) {
	            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;


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

	


	    var SymbolDraw = __webpack_require__(116);
	    var LineDraw = __webpack_require__(209);
	    var RoamController = __webpack_require__(182);
	    var roamHelper = __webpack_require__(184);
	    var cursorHelper = __webpack_require__(185);

	    var graphic = __webpack_require__(18);
	    var adjustEdge = __webpack_require__(212);
	    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();
	        }
	    });


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

	/**
	 * @module echarts/chart/helper/LineDraw
	 */


	    var graphic = __webpack_require__(18);
	    var LineGroup = __webpack_require__(210);


	    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;


/***/ },
/* 210 */
/***/ 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__(211);
	    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;


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


/***/ },
/* 212 */
/***/ 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]);
	            }
	        });
	    };


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

	

	    var echarts = __webpack_require__(1);
	    var roamHelper = __webpack_require__(187);

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



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


/***/ },
/* 215 */
/***/ 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')
	                            );
	                        }
	                    }
	                });
	            }
	        });
	    };


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


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

	

	    var simpleLayoutHelper = __webpack_require__(218);
	    var simpleLayoutEdge = __webpack_require__(219);

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



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

	

	    var simpleLayoutEdge = __webpack_require__(219);

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


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


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

	
	    var circularLayoutHelper = __webpack_require__(221);
	    module.exports = function (ecModel) {
	        ecModel.eachSeriesByType('graph', function (seriesModel) {
	            if (seriesModel.get('layout') === 'circular') {
	                circularLayoutHelper(seriesModel);
	            }
	        });
	    };


/***/ },
/* 221 */
/***/ 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]);
	        });
	    };


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

	

	    var forceHelper = __webpack_require__(223);
	    var numberUtil = __webpack_require__(7);
	    var simpleLayoutHelper = __webpack_require__(218);
	    var circularLayoutHelper = __webpack_require__(221);
	    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,
	                        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;
	            }
	        });
	    };


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


/***/ },
/* 224 */
/***/ 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;
	    };


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

	
	    __webpack_require__(226);
	    __webpack_require__(227);


/***/ },
/* 226 */
/***/ 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;


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

	

	    var PointerPath = __webpack_require__(228);

	    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;


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


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

	

	    var zrUtil = __webpack_require__(4);
	    var echarts = __webpack_require__(1);

	    __webpack_require__(230);
	    __webpack_require__(231);

	    echarts.registerVisual(zrUtil.curry(__webpack_require__(151), 'funnel'));
	    echarts.registerLayout(__webpack_require__(232));

	    echarts.registerProcessor(zrUtil.curry(__webpack_require__(154), 'funnel'));


/***/ },
/* 230 */
/***/ 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;



/***/ },
/* 231 */
/***/ 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;


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



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

	

	    var echarts = __webpack_require__(1);

	    __webpack_require__(234);

	    __webpack_require__(247);
	    __webpack_require__(248);

	    echarts.registerVisual(__webpack_require__(249));



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

	

	    __webpack_require__(235);
	    __webpack_require__(239);
	    __webpack_require__(241);

	    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__(246)
	    );



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

	/**
	 * Parallel coordinate system creater.
	 */


	    var Parallel = __webpack_require__(236);

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



/***/ },
/* 236 */
/***/ 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__(237);
	    var graphic = __webpack_require__(18);
	    var matrix = __webpack_require__(11);
	    var numberUtil = __webpack_require__(7);
	    var sliderMove = __webpack_require__(238);

	    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;


/***/ },
/* 237 */
/***/ 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;


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


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

	

	    var zrUtil = __webpack_require__(4);
	    var Component = __webpack_require__(69);

	    __webpack_require__(240);

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

	    });



/***/ },
/* 240 */
/***/ 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;


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

	

	    __webpack_require__(235);
	    __webpack_require__(242);
	    __webpack_require__(243);



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

	    });


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

	

	    var zrUtil = __webpack_require__(4);
	    var AxisBuilder = __webpack_require__(135);
	    var BrushController = __webpack_require__(244);
	    var brushHelper = __webpack_require__(245);
	    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;


/***/ },
/* 244 */
/***/ 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__(183);
	    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;


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

	

	    var cursorHelper = __webpack_require__(185);
	    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;



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



/***/ },
/* 247 */
/***/ 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;
	    }


/***/ },
/* 248 */
/***/ 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;


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


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

	

	    var echarts = __webpack_require__(1);

	    __webpack_require__(251);
	    __webpack_require__(252);
	    echarts.registerLayout(__webpack_require__(253));
	    echarts.registerVisual(__webpack_require__(255));


/***/ },
/* 251 */
/***/ 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__(206);
	    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;



/***/ },
/* 252 */
/***/ 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;
	    }



/***/ },
/* 253 */
/***/ 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__(254);
	    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();
	    }



/***/ },
/* 254 */
/***/ 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;


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

	/**
	 * @file Visual encoding for sankey view
	 * @author  Deqing Li(annong035@gmail.com)
	 */


	    var VisualMapping = __webpack_require__(202);
	    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);
	                }
	            });

	        });
	    };



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

	

	    var echarts = __webpack_require__(1);

	    __webpack_require__(257);
	    __webpack_require__(260);

	    echarts.registerVisual(__webpack_require__(261));
	    echarts.registerLayout(__webpack_require__(262));



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

	'use strict';


	    var zrUtil = __webpack_require__(4);
	    var SeriesModel = __webpack_require__(78);
	    var whiskerBoxCommon = __webpack_require__(258);

	    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;



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

	'use strict';


	    var List = __webpack_require__(98);
	    var completeDimensions = __webpack_require__(110);
	    var WhiskerBoxDraw = __webpack_require__(259);
	    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
	    };


/***/ },
/* 259 */
/***/ 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;


/***/ },
/* 260 */
/***/ 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__(258);

	    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;



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

	    };


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



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

	

	    var echarts = __webpack_require__(1);

	    __webpack_require__(264);
	    __webpack_require__(265);

	    echarts.registerPreprocessor(
	        __webpack_require__(266)
	    );

	    echarts.registerVisual(__webpack_require__(267));
	    echarts.registerLayout(__webpack_require__(268));



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

	'use strict';


	    var zrUtil = __webpack_require__(4);
	    var SeriesModel = __webpack_require__(78);
	    var whiskerBoxCommon = __webpack_require__(258);

	    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;



/***/ },
/* 265 */
/***/ 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__(258);

	    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;



/***/ },
/* 266 */
/***/ 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';
	            }
	        });
	    };



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

	    };


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



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

	

	    var zrUtil = __webpack_require__(4);
	    var echarts = __webpack_require__(1);

	    __webpack_require__(270);
	    __webpack_require__(271);

	    echarts.registerVisual(zrUtil.curry(
	        __webpack_require__(121), 'effectScatter', 'circle', null
	    ));
	    echarts.registerLayout(zrUtil.curry(
	        __webpack_require__(122), 'effectScatter'
	    ));


/***/ },
/* 270 */
/***/ 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
	            //     }
	            // }
	        }

	    });


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

	

	    var SymbolDraw = __webpack_require__(116);
	    var EffectSymbol = __webpack_require__(272);

	    __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 () {}
	    });


/***/ },
/* 272 */
/***/ 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;


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

	

	    __webpack_require__(274);
	    __webpack_require__(275);

	    var echarts = __webpack_require__(1);
	    echarts.registerLayout(
	        __webpack_require__(280)
	    );
	    echarts.registerVisual(
	        __webpack_require__(281)
	    );


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


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

	

	    var LineDraw = __webpack_require__(209);
	    var EffectLine = __webpack_require__(276);
	    var Line = __webpack_require__(210);
	    var Polyline = __webpack_require__(277);
	    var EffectPolyline = __webpack_require__(278);
	    var LargeLineDraw = __webpack_require__(279);

	    __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 () {}
	    });


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

	/**
	 * Provide effect for line
	 * @module echarts/chart/helper/EffectLine
	 */


	    var graphic = __webpack_require__(18);
	    var Line = __webpack_require__(210);
	    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;


/***/ },
/* 277 */
/***/ 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;


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

	/**
	 * Provide effect for line
	 * @module echarts/chart/helper/EffectLine
	 */


	    var Polyline = __webpack_require__(277);
	    var zrUtil = __webpack_require__(4);
	    var EffectLine = __webpack_require__(276);
	    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;


/***/ },
/* 279 */
/***/ 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;


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


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


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

	

	    __webpack_require__(283);
	    __webpack_require__(284);


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


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

	

	    var graphic = __webpack_require__(18);
	    var HeatmapLayer = __webpack_require__(285);
	    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);
	        }
	    });



/***/ },
/* 285 */
/***/ 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;



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

	

	    var zrUtil = __webpack_require__(4);

	    __webpack_require__(125);

	    __webpack_require__(287);
	    __webpack_require__(288);

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


/***/ },
/* 287 */
/***/ 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,
	            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;


/***/ },
/* 288 */
/***/ 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 boundingLength = output.boundingLength = symbolBoundingData != null
	            ? valueAxis.toGlobalCoord(valueAxis.dataToCoord(valueAxis.scale.parse(symbolBoundingData))) - zeroPx
	            : symbolRepeat
	            ? opt.coordSysExtent[valueDim.index][1 - +(layout[valueDim.wh] <= 0)] - zeroPx
	            : layout[valueDim.wh];

	        if (symbolRepeat) {
	            output.repeatCutLength = layout[valueDim.wh];
	        }

	        output.pxSign = boundingLength > 0 ? 1 : boundingLength < 0 ? -1 : 0;
	    }

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

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

	            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;


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

	

	    var echarts = __webpack_require__(1);
	    var zrUtil = __webpack_require__(4);

	    __webpack_require__(290);

	    __webpack_require__(307);

	    __webpack_require__(308);

	    echarts.registerLayout(__webpack_require__(310));

	    echarts.registerVisual(__webpack_require__(311));

	    echarts.registerProcessor(
	        zrUtil.curry(__webpack_require__(154), 'themeRiver')
	    );


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

	

	    __webpack_require__(291);
	    __webpack_require__(294);
	    __webpack_require__(296);
	    __webpack_require__(297);

	    __webpack_require__(306);

	    var echarts = __webpack_require__(1);

	    echarts.extendComponentView({
	        type: 'single'
	    });



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

	/**
	 * Single coordinate system creator.
	 */


	    var Single = __webpack_require__(292);

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


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

	/**
	 * Single coordinates system.
	 */


	    var SingleAxis = __webpack_require__(293);
	    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;



/***/ },
/* 293 */
/***/ 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;


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

	

	    var AxisBuilder = __webpack_require__(135);
	    var zrUtil =  __webpack_require__(4);
	    var graphic = __webpack_require__(18);
	    var singleAxisHelper = __webpack_require__(295);
	    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;



/***/ },
/* 295 */
/***/ 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;



/***/ },
/* 296 */
/***/ 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;


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

	

	    var echarts = __webpack_require__(1);
	    var axisPointerModelHelper = __webpack_require__(137);
	    var axisTrigger = __webpack_require__(298);
	    var zrUtil = __webpack_require__(4);

	    __webpack_require__(300);
	    __webpack_require__(301);

	    // 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__(303);

	    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'
	    }, function (payload, ecModel, api) {
	        var outputFinder = axisTrigger(
	            ecModel.getComponent('axisPointer').coordSysAxesInfo,
	            payload.currTrigger,
	            [payload.x, payload.y],
	            payload,
	            payload.dispatchAction || zrUtil.bind(api.dispatchAction, api),
	            ecModel,
	            api,
	            payload.tooltipOption
	        );

	        return outputFinder;
	    });



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

	

	    var zrUtil = __webpack_require__(4);
	    var modelUtil = __webpack_require__(5);
	    var modelHelper = __webpack_require__(137);
	    var findPointFromSeries = __webpack_require__(299);

	    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 {string} [currTrigger] 'click' | 'mousemove' | 'leave'
	     * @param {Array.<number>} [point] x and y, which are mandatory, specify a point to
	     *              tigger axisPointer and tooltip.
	     * @param {Object} [finder] {
	     *                  seriesIndex, dataIndex,
	     *                  axesInfo: [{
	     *                      axisDim: 'x'|'y'|'angle'|..., axisIndex: ..., value: ...
	     *                  }, ...]
	     *              }
	     *              These properties, which are optional, restrict target axes.
	     * @param {Function} dispatchAction
	     * @param {module:echarts/ExtensionAPI} api
	     * @param {Object} [tooltipOption]
	     * @return {Object} content of event obj for echarts.connect.
	     */
	    function axisTrigger(
	        coordSysAxesInfo, currTrigger, point, finder, dispatchAction,
	        ecModel, api, tooltipOption
	    ) {
	        finder = finder || {};
	        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, tooltipOption, 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, tooltipOption, 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: tooltipOption,
	            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;


/***/ },
/* 299 */
/***/ 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};
	    };




/***/ },
/* 300 */
/***/ 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;



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

	

	    var globalListener = __webpack_require__(302);

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

	    });



/***/ },
/* 302 */
/***/ 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;


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

	'use strict';


	    var graphic = __webpack_require__(18);
	    var BaseAxisPointer = __webpack_require__(304);
	    var viewHelper = __webpack_require__(305);
	    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;


/***/ },
/* 304 */
/***/ 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;


/***/ },
/* 305 */
/***/ 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;


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

	'use strict';


	    var graphic = __webpack_require__(18);
	    var BaseAxisPointer = __webpack_require__(304);
	    var viewHelper = __webpack_require__(305);
	    var singleAxisHelper = __webpack_require__(295);
	    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;


/***/ },
/* 307 */
/***/ 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__(254);

	    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;



/***/ },
/* 308 */
/***/ 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__(309)))

/***/ },
/* 309 */
/***/ 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; };


/***/ },
/* 310 */
/***/ 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;
	    }



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



/***/ },
/* 312 */
/***/ 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__(313),
	        geo: __webpack_require__(314),
	        singleAxis: __webpack_require__(315),
	        polar: __webpack_require__(316),
	        calendar: __webpack_require__(317)
	    };

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


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

	        el.styleEmphasis !== false && graphicUtil.setHoverStyle(el, el.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(prepareCustoms[coordSys.type], 'This coordSys does not support custom series.');
	        }

	        var prepareResult = 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;
	    }




/***/ },
/* 313 */
/***/ 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;


/***/ },
/* 314 */
/***/ 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;


/***/ },
/* 315 */
/***/ 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;


/***/ },
/* 316 */
/***/ 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;


/***/ },
/* 317 */
/***/ 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;


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



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

	

	    __webpack_require__(124);

	    __webpack_require__(303);

	    __webpack_require__(297);



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

	/**
	 * Legend component entry file8
	 */


	    __webpack_require__(321);
	    __webpack_require__(322);
	    __webpack_require__(323);

	    var echarts = __webpack_require__(1);
	    // Series Filter
	    echarts.registerProcessor(__webpack_require__(325));


/***/ },
/* 321 */
/***/ 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;


/***/ },
/* 322 */
/***/ 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')
	    );


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

	

	    var zrUtil = __webpack_require__(4);
	    var symbolCreator = __webpack_require__(111);
	    var graphic = __webpack_require__(18);
	    var listComponentHelper = __webpack_require__(324);

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


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


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


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

	// FIXME Better way to pack data in graphic element


	    __webpack_require__(297);

	    __webpack_require__(327);

	    __webpack_require__(328);


	    // 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 () {}
	    );


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


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

	

	    var TooltipContent = __webpack_require__(329);
	    var zrUtil = __webpack_require__(4);
	    var formatUtil = __webpack_require__(6);
	    var numberUtil = __webpack_require__(7);
	    var graphic = __webpack_require__(18);
	    var findPointFromSeries = __webpack_require__(299);
	    var layoutUtil = __webpack_require__(71);
	    var env = __webpack_require__(2);
	    var Model = __webpack_require__(12);
	    var globalListener = __webpack_require__(302);
	    var axisHelper = __webpack_require__(101);
	    var axisPointerViewHelper = __webpack_require__(305);

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

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



/***/ },
/* 329 */
/***/ 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;


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

	'use strict';


	    var zrUtil = __webpack_require__(4);

	    __webpack_require__(331);
	    __webpack_require__(337);
	    __webpack_require__(339);
	    __webpack_require__(297);

	    __webpack_require__(341);

	    // For reducing size of echarts.min, barLayoutPolar is required by polar.
	    __webpack_require__(1).registerLayout(zrUtil.curry(__webpack_require__(342), 'bar'));

	    // Polar view
	    __webpack_require__(1).extendComponentView({
	        type: 'polar'
	    });


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

	// TODO Axis scale


	    var Polar = __webpack_require__(332);
	    var numberUtil = __webpack_require__(7);
	    var zrUtil = __webpack_require__(4);

	    var axisHelper = __webpack_require__(101);
	    var niceScaleExtent = axisHelper.niceScaleExtent;

	    // 依赖 PolarModel 做预处理
	    __webpack_require__(335);

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


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

	'use strict';
	/**
	 * @module echarts/coord/polar/Polar
	 */


	    var RadiusAxis = __webpack_require__(333);
	    var AngleAxis = __webpack_require__(334);

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


/***/ },
/* 333 */
/***/ 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;


/***/ },
/* 334 */
/***/ 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;


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

	'use strict';


	    __webpack_require__(336);

	    __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%'
	        }
	    });


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



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

	'use strict';


	    __webpack_require__(331);

	    __webpack_require__(338);


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


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

	

	    __webpack_require__(331);

	    __webpack_require__(340);


/***/ },
/* 340 */
/***/ 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
	        };
	    }


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

	'use strict';


	    var formatUtil = __webpack_require__(6);
	    var BaseAxisPointer = __webpack_require__(304);
	    var graphic = __webpack_require__(18);
	    var viewHelper = __webpack_require__(305);
	    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;


/***/ },
/* 342 */
/***/ 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;



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

	

	    __webpack_require__(344);

	    __webpack_require__(171);

	    __webpack_require__(345);

	    __webpack_require__(186);

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


/***/ },
/* 344 */
/***/ 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;


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

	'use strict';


	    var MapDraw = __webpack_require__(181);

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

	    });


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

	/**
	 * Brush component entry
	 */


	    __webpack_require__(1).registerPreprocessor(
	        __webpack_require__(347)
	    );

	    __webpack_require__(348);
	    __webpack_require__(352);
	    __webpack_require__(353);
	    __webpack_require__(354);

	    __webpack_require__(355);



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



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

	/**
	 * @file Brush visual coding.
	 */


	    var echarts = __webpack_require__(1);
	    var visualSolution = __webpack_require__(349);
	    var zrUtil = __webpack_require__(4);
	    var BoundingRect = __webpack_require__(9);
	    var selector = __webpack_require__(350);
	    var throttle = __webpack_require__(81);
	    var BrushTargetManager = __webpack_require__(351);

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



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

	/**
	 * @file Visual solution, for consistent option specification.
	 */


	    var zrUtil = __webpack_require__(4);
	    var VisualMapping = __webpack_require__(202);
	    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;



/***/ },
/* 350 */
/***/ 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;



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

	

	    var zrUtil = __webpack_require__(4);
	    var graphic = __webpack_require__(18);
	    var modelUtil = __webpack_require__(5);
	    var brushHelper = __webpack_require__(245);

	    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;


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

	/**
	 * @file Brush model
	 */


	    var echarts = __webpack_require__(1);
	    var zrUtil = __webpack_require__(4);
	    var visualSolution = __webpack_require__(349);
	    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;



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

	

	    var zrUtil = __webpack_require__(4);
	    var BrushController = __webpack_require__(244);
	    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());
	    }



/***/ },
/* 354 */
/***/ 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 () {}
	    );


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

	'use strict';


	    var featureManager = __webpack_require__(356);
	    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;


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

	'use strict';


	    var features = {};

	    module.exports = {
	        register: function (name, ctor) {
	            features[name] = ctor;
	        },

	        get: function (name) {
	            return features[name];
	        }
	    };


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

	'use strict';
	/**
	 * @file calendar.js
	 * @author dxh
	 */



	    __webpack_require__(358);
	    __webpack_require__(359);
	    __webpack_require__(360);




/***/ },
/* 358 */
/***/ 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;



/***/ },
/* 359 */
/***/ 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;




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



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


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

	/**
	 * DataZoom component entry
	 */


	    __webpack_require__(363);

	    __webpack_require__(364);
	    __webpack_require__(367);

	    __webpack_require__(368);
	    __webpack_require__(369);

	    __webpack_require__(370);
	    __webpack_require__(371);

	    __webpack_require__(373);
	    __webpack_require__(374);



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

	

	    __webpack_require__(69).registerSubTypeDefaulter('dataZoom', function (option) {
	        // Default 'slider' when no type specified.
	        return 'slider';
	    });



/***/ },
/* 364 */
/***/ 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__(365);
	    var AxisProxy = __webpack_require__(366);
	    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;



/***/ },
/* 365 */
/***/ 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;


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

	/**
	 * @file Axis operator
	 */


	    var zrUtil = __webpack_require__(4);
	    var numberUtil = __webpack_require__(7);
	    var helper = __webpack_require__(365);
	    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;



/***/ },
/* 367 */
/***/ 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;
	        }

	    });



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

	/**
	 * @file Data zoom model
	 */


	    var DataZoomModel = __webpack_require__(364);

	    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;



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

	

	    var zrUtil = __webpack_require__(4);
	    var graphic = __webpack_require__(18);
	    var throttle = __webpack_require__(81);
	    var DataZoomView = __webpack_require__(367);
	    var Rect = graphic.Rect;
	    var numberUtil = __webpack_require__(7);
	    var linearMap = numberUtil.linearMap;
	    var layout = __webpack_require__(71);
	    var sliderMove = __webpack_require__(238);
	    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;



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

	/**
	 * @file Data zoom model
	 */


	    module.exports = __webpack_require__(364).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
	        }
	    });


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

	

	    var DataZoomView = __webpack_require__(367);
	    var zrUtil = __webpack_require__(4);
	    var sliderMove = __webpack_require__(238);
	    var roams = __webpack_require__(372);
	    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.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;


/***/ },
/* 372 */
/***/ 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__(182);
	    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);
	            }
	            record.controller.enable(
	                dataZoomInfo.disabled ? false : dataZoomInfo.zoomLock ? 'move' : true,
	                dataZoomInfo.roamControllerOpt
	            );

	            // Consider resize, area should be always updated.
	            record.controller.setPointerChecker(dataZoomInfo.containsPoint);

	            // Update throttle.
	            throttle.createOrUpdate(
	                record,
	                'dispatchAction',
	                dataZoomInfo.throttleRate,
	                'fixRate'
	            );

	            // Update reference of dataZoom.
	            !(record.dataZoomInfos[theDataZoomId]) && record.count++;
	            record.dataZoomInfos[theDataZoomId] = dataZoomInfo;
	        },

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

	    module.exports = roams;



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




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

	/**
	 * @file Data zoom action
	 */


	    var zrUtil = __webpack_require__(4);
	    var helper = __webpack_require__(365);
	    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
	            });
	        });

	    });



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

	/**
	 * visualMap component entry
	 */


	    __webpack_require__(376);
	    __webpack_require__(387);



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

	/**
	 * DataZoom component entry
	 */


	    __webpack_require__(1).registerPreprocessor(
	        __webpack_require__(377)
	    );

	    __webpack_require__(378);
	    __webpack_require__(379);
	    __webpack_require__(380);
	    __webpack_require__(383);
	    __webpack_require__(386);



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



/***/ },
/* 378 */
/***/ 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';
	    });



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

	/**
	 * @file Data range visual coding.
	 */


	    var echarts = __webpack_require__(1);
	    var visualSolution = __webpack_require__(349);
	    var VisualMapping = __webpack_require__(202);
	    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;
	        }
	    }




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

	/**
	 * @file Data zoom model
	 */


	    var VisualMapModel = __webpack_require__(381);
	    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;



/***/ },
/* 381 */
/***/ 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__(382);
	    var VisualMapping = __webpack_require__(202);
	    var visualSolution = __webpack_require__(349);
	    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;



/***/ },
/* 382 */
/***/ 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;




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

	

	    var VisualMapView = __webpack_require__(384);
	    var graphic = __webpack_require__(18);
	    var zrUtil = __webpack_require__(4);
	    var numberUtil = __webpack_require__(7);
	    var sliderMove = __webpack_require__(238);
	    var LinearGradient = __webpack_require__(65);
	    var helper = __webpack_require__(385);
	    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;



/***/ },
/* 384 */
/***/ 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__(202);

	    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

	    });



/***/ },
/* 385 */
/***/ 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;



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

	    });



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

	/**
	 * DataZoom component entry
	 */


	    __webpack_require__(1).registerPreprocessor(
	        __webpack_require__(377)
	    );

	    __webpack_require__(378);
	    __webpack_require__(379);
	    __webpack_require__(388);
	    __webpack_require__(389);
	    __webpack_require__(386);



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

	

	    var VisualMapModel = __webpack_require__(381);
	    var zrUtil = __webpack_require__(4);
	    var VisualMapping = __webpack_require__(202);
	    var visualDefault = __webpack_require__(382);
	    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;


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

	

	    var VisualMapView = __webpack_require__(384);
	    var zrUtil = __webpack_require__(4);
	    var graphic = __webpack_require__(18);
	    var symbolCreators = __webpack_require__(111);
	    var layout = __webpack_require__(71);
	    var helper = __webpack_require__(385);

	    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;



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

	// HINT Markpoint can't be used too much


	    __webpack_require__(391);
	    __webpack_require__(393);

	    __webpack_require__(1).registerPreprocessor(function (opt) {
	        // Make sure markPoint component is enabled
	        opt.markPoint = opt.markPoint || {};
	    });


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

	

	    module.exports = __webpack_require__(392).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
	                }
	            }
	        }
	    });


/***/ },
/* 392 */
/***/ 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;


/***/ },
/* 393 */
/***/ 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__(394);

	    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__(395).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.name).updateLayout(mpModel);
	                }
	            }, this);
	        },

	        renderSeries: function (seriesModel, mpModel, ecModel, api) {
	            var coordSys = seriesModel.coordinateSystem;
	            var seriesName = seriesModel.name;
	            var seriesData = seriesModel.getData();

	            var symbolDrawMap = this.markerGroupMap;
	            var symbolDraw = symbolDrawMap.get(seriesName)
	                || symbolDrawMap.set(seriesName, 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;
	    }



/***/ },
/* 394 */
/***/ 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
	    };


/***/ },
/* 395 */
/***/ 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 () {}
	    });


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

	

	    __webpack_require__(397);
	    __webpack_require__(398);

	    __webpack_require__(1).registerPreprocessor(function (opt) {
	        // Make sure markLine component is enabled
	        opt.markLine = opt.markLine || {};
	    });


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

	

	    module.exports = __webpack_require__(392).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'
	        }
	    });


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

	

	    var zrUtil = __webpack_require__(4);
	    var List = __webpack_require__(98);
	    var numberUtil = __webpack_require__(7);

	    var markerHelper = __webpack_require__(394);

	    var LineDraw = __webpack_require__(209);

	    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__(395).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.name).updateLayout();

	                }
	            }, this);
	        },

	        renderSeries: function (seriesModel, mlModel, ecModel, api) {
	            var coordSys = seriesModel.coordinateSystem;
	            var seriesName = seriesModel.name;
	            var seriesData = seriesModel.getData();

	            var lineDrawMap = this.markerGroupMap;
	            var lineDraw = lineDrawMap.get(seriesName)
	                || lineDrawMap.set(seriesName, 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
	        };
	    }


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

	

	    __webpack_require__(400);
	    __webpack_require__(401);

	    __webpack_require__(1).registerPreprocessor(function (opt) {
	        // Make sure markArea component is enabled
	        opt.markArea = opt.markArea || {};
	    });


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

	

	    module.exports = __webpack_require__(392).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
	                }
	            }
	        }
	    });


/***/ },
/* 401 */
/***/ 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__(394);

	    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__(395).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;
	    }


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

	/**
	 * DataZoom component entry
	 */


	    var echarts = __webpack_require__(1);

	    echarts.registerPreprocessor(__webpack_require__(403));

	    __webpack_require__(404);
	    __webpack_require__(405);
	    __webpack_require__(406);
	    __webpack_require__(408);



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



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

	

	    __webpack_require__(69).registerSubTypeDefaulter('timeline', function () {
	        // Only slider now.
	        return 'slider';
	    });



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



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

	/**
	 * @file Silder timeline model
	 */


	    var TimelineModel = __webpack_require__(407);
	    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;


/***/ },
/* 407 */
/***/ 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;


/***/ },
/* 408 */
/***/ 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__(409);
	    var TimelineAxis = __webpack_require__(410);
	    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];
	            }

	            // FIXME
	            // 暂没有实现用户传入
	            // var labelAlign = timelineModel.get('label.normal.textStyle.align');
	            // var labelBaseline = timelineModel.get('label.normal.textStyle.baseline');
	            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: labelAlignMap[orient],
	                labelBaseline: 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)
	            );
	        }
	    }



/***/ },
/* 409 */
/***/ 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'
	    });



/***/ },
/* 410 */
/***/ 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;


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

	

	    __webpack_require__(412);
	    __webpack_require__(413);

	    __webpack_require__(414);
	    __webpack_require__(415);
	    __webpack_require__(416);
	    __webpack_require__(417);
	    __webpack_require__(422);


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

	

	    var featureManager = __webpack_require__(356);
	    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;


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

	/* WEBPACK VAR INJECTION */(function(process) {

	    var featureManager = __webpack_require__(356);
	    var zrUtil = __webpack_require__(4);
	    var graphic = __webpack_require__(18);
	    var Model = __webpack_require__(12);
	    var DataDiffer = __webpack_require__(99);
	    var listComponentHelper = __webpack_require__(324);
	    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__(309)))

/***/ },
/* 414 */
/***/ 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__(356).register(
	        'saveAsImage', SaveAsImage
	    );

	    module.exports = SaveAsImage;


/***/ },
/* 415 */
/***/ 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__(356).register('magicType', MagicType);

	    module.exports = MagicType;


/***/ },
/* 416 */
/***/ 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__(356).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;


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

	'use strict';


	    var zrUtil = __webpack_require__(4);
	    var BrushController = __webpack_require__(244);
	    var BrushTargetManager = __webpack_require__(351);
	    var history = __webpack_require__(418);
	    var sliderMove = __webpack_require__(238);

	    var each = zrUtil.each;

	    // Use dataZoomSelect
	    __webpack_require__(419);

	    // 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__(356).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;


/***/ },
/* 418 */
/***/ 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;



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

	/**
	 * DataZoom component entry
	 */


	    __webpack_require__(363);

	    __webpack_require__(364);
	    __webpack_require__(367);

	    __webpack_require__(420);
	    __webpack_require__(421);

	    __webpack_require__(373);
	    __webpack_require__(374);



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

	/**
	 * @file Data zoom model
	 */


	    var DataZoomModel = __webpack_require__(364);

	    module.exports = DataZoomModel.extend({

	        type: 'dataZoom.select'

	    });



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

	

	    module.exports = __webpack_require__(367).extend({

	        type: 'dataZoom.select'

	    });



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

	'use strict';


	    var history = __webpack_require__(418);

	    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__(356).register('restore', Restore);


	    __webpack_require__(1).registerAction(
	        {type: 'restore', event: 'restore', update: 'prepareAndUpdate'},
	        function (payload, ecModel) {
	            ecModel.resetOption('recreate');
	        }
	    );

	    module.exports = Restore;


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

	
	    __webpack_require__(424);
	    __webpack_require__(82).registerPainter('vml', __webpack_require__(426));


/***/ },
/* 424 */
/***/ 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__(425);

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


/***/ },
/* 425 */
/***/ 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
	    };
	}


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

	/**
	 * VML Painter.
	 *
	 * @module zrender/vml/Painter
	 */



	    var zrLog = __webpack_require__(33);
	    var vmlCore = __webpack_require__(425);

	    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;


/***/ }
/******/ ])
});
;