(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD. Register as an anonymous module.
        define([], factory);
    } else if (typeof module === 'object' && module.exports) {
        // Node. Does not work with strict CommonJS, but
        // only CommonJS-like environments that support module.exports,
        // like Node.
        module.exports = factory();
    } else {
        // Browser globals (root is window)
        root.echarts = factory();
    }
}(this, function () {
var require, define;
(function () {
    var mods = {};

    define = function (id, deps, factory) {
        // In case like
        // define('echarts/model/globalDefault', {...});
        if (arguments.length === 2) {
            factory = deps;
            deps = [];
            if (typeof factory !== 'function') {
                var configObj = factory;
                factory = function () { return configObj; };
            }
        }
        mods[id] = {
            id: id,
            deps: deps,
            factory: factory,
            defined: 0,
            exports: {},
            require: createRequire(id)
        };
    };

    require = createRequire('');

    function normalize(id, baseId) {
        if (!baseId) {
            return id;
        }

        if (id.indexOf('.') === 0) {
            var basePath = baseId.split('/');
            var namePath = id.split('/');
            var baseLen = basePath.length - 1;
            var nameLen = namePath.length;
            var cutBaseTerms = 0;
            var cutNameTerms = 0;

            pathLoop: for (var i = 0; i < nameLen; i++) {
                switch (namePath[i]) {
                    case '..':
                        if (cutBaseTerms < baseLen) {
                            cutBaseTerms++;
                            cutNameTerms++;
                        }
                        else {
                            break pathLoop;
                        }
                        break;
                    case '.':
                        cutNameTerms++;
                        break;
                    default:
                        break pathLoop;
                }
            }

            basePath.length = baseLen - cutBaseTerms;
            namePath = namePath.slice(cutNameTerms);

            return basePath.concat(namePath).join('/');
        }

        return id;
    }

    function createRequire(baseId) {
        var cacheMods = {};

        function localRequire(id, callback) {
            if (typeof id === 'string') {
                var exports = cacheMods[id];
                if (!exports) {
                    exports = getModExports(normalize(id, baseId));
                    cacheMods[id] = exports;
                }

                return exports;
            }
            else if (id instanceof Array) {
                callback = callback || function () {};
                callback.apply(this, getModsExports(id, callback, baseId));
            }
        };

        return localRequire;
    }

    function getModsExports(ids, factory, baseId) {
        var es = [];
        var mod = mods[baseId];

        for (var i = 0, l = Math.min(ids.length, factory.length); i < l; i++) {
            var id = normalize(ids[i], baseId);
            var arg;
            switch (id) {
                case 'require':
                    arg = (mod && mod.require) || require;
                    break;
                case 'exports':
                    arg = mod.exports;
                    break;
                case 'module':
                    arg = mod;
                    break;
                default:
                    arg = getModExports(id);
            }
            es.push(arg);
        }

        return es;
    }

    function getModExports(id) {
        var mod = mods[id];
        if (!mod) {
            throw new Error('No ' + id);
        }

        if (!mod.defined) {
            var factory = mod.factory;
            var factoryReturn = factory.apply(
                this,
                getModsExports(mod.deps || [], factory, id)
            );
            if (typeof factoryReturn !== 'undefined') {
                mod.exports = factoryReturn;
            }
            mod.defined = 1;
        }

        return mod.exports;
    }
}());


define('zrender/graphic/Gradient',['require'],function (require) {

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

    return Gradient;
});
/**
 */
define('zrender/core/util',['require','../graphic/Gradient'],function(require) {
    var Gradient = require('../graphic/Gradient');
    // 用于处理merge时无法遍历Date等对象的问题
    var BUILTIN_OBJECT = {
        '[object Function]': 1,
        '[object RegExp]': 1,
        '[object Date]': 1,
        '[object Error]': 1,
        '[object CanvasGradient]': 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;

    /**
     * @param {*} source
     * @return {*} 拷贝后的新对象
     */
    function clone(source) {
        if (typeof source == 'object' && source !== null) {
            var result = source;
            if (source instanceof Array) {
                result = [];
                for (var i = 0, len = source.length; i < len; i++) {
                    result[i] = clone(source[i]);
                }
            }
            else if (
                !isBuildInObject(source)
                // 是否为 dom 对象
                && !isDom(source)
            ) {
                result = {};
                for (var key in source) {
                    if (source.hasOwnProperty(key)) {
                        result[key] = clone(source[key]);
                    }
                }
            }

            return result;
        }

        return source;
    }

    /**
     * @param {Object=} target
     * @param {Object=} source
     * @param {boolean} [overwrite=false]
     */
    function merge(target, source, overwrite) {
        if (!target) { // Might be null/undefined
            return;
        }
        if (!source) { // Might be null/undefined
            return 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)
                    && !isBuildInObject(sourceProp)
                    && !isBuildInObject(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
     */
    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]
     */
    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
     */
    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;
    }

    /**
     * 构造类继承关系
     *
     * @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;
    }

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

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

    /**
     * 数组或对象遍历
     * @memberOf module:zrender/tool/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/tool/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/tool/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/tool/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/tool/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/tool/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/tool/util
     * @param {Function} func
     * @param {...}
     * @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/tool/util
     * @param {*} value
     * @return {boolean}
     */
    function isArray(value) {
        return objToString.call(value) === '[object Array]';
    }

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

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

    /**
     * @memberOf module:zrender/tool/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/tool/util
     * @param {*} value
     * @return {boolean}
     */
    function isBuildInObject(value) {
        return !!BUILTIN_OBJECT[objToString.call(value)]
            || (value instanceof Gradient);
    }

    /**
     * @memberOf module:zrender/tool/util
     * @param {*} value
     * @return {boolean}
     */
    function isDom(value) {
        return value && value.nodeType === 1
               && typeof(value.nodeName) == 'string';
    }

    /**
     * If value1 is not null, then return value1, otherwise judget rest of values.
     * @param  {*...} values
     * @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/tool/util
     * @param {Array} arr
     * @param {number} startIndex
     * @param {number} endIndex
     * @return {Array}
     */
    function slice() {
        return Function.call.apply(nativeSlice, arguments);
    }

    /**
     * @param {boolean} condition
     * @param {string} message
     */
    function assert(condition, message) {
        if (!condition) {
            throw new Error(message);
        }
    }

    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,
        isBuildInObject: isBuildInObject,
        isDom: isDom,
        retrieve: retrieve,
        assert: assert,
        noop: function () {}
    };
    return util;
});

define('echarts/util/clazz',['require','zrender/core/util'],function (require) {

    var zrUtil = require('zrender/core/util');

    var clazz = {};

    var TYPE_DELIMITER = '.';
    var IS_CONTAINER = '___EC__COMPONENT__CONTAINER___';
    /**
     * @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
     */
    clazz.enableClassExtend = function (RootClass, preConstruct) {
        RootClass.extend = function (proto) {
            var ExtendedClass = function () {
                preConstruct && preConstruct.apply(this, arguments);
                RootClass.apply(this, arguments);
            };

            zrUtil.extend(ExtendedClass.prototype, zrUtil.extend({
                $superCall: function (methodName) {
                    var args = zrUtil.slice(arguments, 1);
                    return findSuperMethod(this, methodName).apply(this, args);
                },
                $superApply: function (methodName, args) {
                    return findSuperMethod(this, methodName).apply(this, args);
                }
            }, proto));

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

            return ExtendedClass;
        };
    };

    // Find the first method that different with given metod.
    // If only use closure to implements $superApply and $supperCall,
    // Consider this case:
    // class A has method f,
    // class B inherits class A, overrides method f, f call this.$superApply('f'),
    // class C inherits class B, do not overrides method f,
    // then when method of class C is called, dead loop occured.
    function findSuperMethod(context, methodName) {
        var SuperClass = context.constructor;
        var thisMethod = context[methodName];
        var method;

        while (
            (SuperClass = SuperClass.$superClass)
            && (method = SuperClass.prototype[methodName])
            && method === thisMethod
        ) {/*jshint noempty:false */}

        return method;
    }

    /**
     * @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) {
                componentType = parseClassType(componentType);

                if (!componentType.sub) {
                    if (storage[componentType.main]) {
                        throw new Error(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 (componentTypeMain, subType, throwWhenNotFound) {
            var Clazz = storage[componentTypeMain];

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

            if (throwWhenNotFound && !Clazz) {
                throw new Error(
                    'Component ' + componentTypeMain + '.' + (subType || '') + ' not exists'
                );
            }

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

    return clazz;
});
// TODO Parse shadow style
// TODO Only shallow path support
define('echarts/model/mixin/makeStyleMapper',['require','zrender/core/util'],function (require) {
    var zrUtil = require('zrender/core/util');

    return function (properties) {
        // Normalize
        for (var i = 0; i < properties.length; i++) {
            if (!properties[i][1]) {
               properties[i][1] = properties[i][0];
            }
        }
        return function (excludes) {
            var style = {};
            for (var i = 0; i < properties.length; i++) {
                var propName = properties[i][1];
                if (excludes && zrUtil.indexOf(excludes, propName) >= 0) {
                    continue;
                }
                var val = this.getShallow(propName);
                if (val != null) {
                    style[properties[i][0]] = val;
                }
            }
            return style;
        }
    }
});
define('echarts/model/mixin/lineStyle',['require','./makeStyleMapper'],function (require) {
    var getLineStyle = require('./makeStyleMapper')(
        [
            ['lineWidth', 'width'],
            ['stroke', 'color'],
            ['opacity'],
            ['shadowBlur'],
            ['shadowOffsetX'],
            ['shadowOffsetY'],
            ['shadowColor']
        ]
    );
    return {
        getLineStyle: function (excludes) {
            var style = getLineStyle.call(this, excludes);
            var lineDash = this.getLineDash();
            lineDash && (style.lineDash = lineDash);
            return style;
        },

        getLineDash: function () {
            var lineType = this.get('type');
            return (lineType === 'solid' || lineType == null) ? null
                : (lineType === 'dashed' ? [5, 5] : [1, 1]);
        }
    };
});
define('echarts/model/mixin/areaStyle',['require','./makeStyleMapper'],function (require) {
    return {
        getAreaStyle: require('./makeStyleMapper')(
            [
                ['fill', 'color'],
                ['shadowBlur'],
                ['shadowOffsetX'],
                ['shadowOffsetY'],
                ['opacity'],
                ['shadowColor']
            ]
        )
    };
});
define('zrender/core/vector',[],function () {
    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);
            out[0] = x || 0;
            out[1] = y || 0;
            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;

    return vector;
});

define('zrender/core/matrix',[],function () {
    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;
        }
    };

    return matrix;
});

/**
 * @module echarts/core/BoundingRect
 */
define('zrender/core/BoundingRect',['require','./vector','./matrix'],function(require) {


    var vec2 = require('./vector');
    var matrix = require('./matrix');

    var v2ApplyTransform = vec2.applyTransform;
    var mathMin = Math.min;
    var mathAbs = Math.abs;
    var mathMax = Math.max;
    /**
     * @alias module:echarts/core/BoundingRect
     */
    function BoundingRect(x, y, width, 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 min = [];
            var max = [];
            return function (m) {
                // In case usage like this
                // el.getBoundingRect().applyTransform(el.transform)
                // And element has no transform
                if (!m) {
                    return;
                }
                min[0] = this.x;
                min[1] = this.y;
                max[0] = this.x + this.width;
                max[1] = this.y + this.height;

                v2ApplyTransform(min, min, m);
                v2ApplyTransform(max, max, m);

                this.x = mathMin(min[0], max[0]);
                this.y = mathMin(min[1], max[1]);
                this.width = mathAbs(max[0] - min[0]);
                this.height = mathAbs(max[1] - min[1]);
            };
        })(),

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

    return BoundingRect;
});
define('zrender/contain/text',['require','../core/util','../core/BoundingRect'],function (require) {

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

    var util = require('../core/util');
    var BoundingRect = require('../core/BoundingRect');

    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 halfHeight = height / 2 - textHeight / 2;

        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;
                textAlign = 'center';
                break;
            case 'bottom':
                x += width / 2;
                y += height + distance;
                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;
                textAlign = 'center';
                break;
            case 'insideBottom':
                x += width / 2;
                y += height - textHeight - distance;
                textAlign = 'center';
                break;
            case 'insideTopLeft':
                x += distance;
                y += distance;
                textAlign = 'left';
                break;
            case 'insideTopRight':
                x += width - distance;
                y += distance;
                textAlign = 'right';
                break;
            case 'insideBottomLeft':
                x += distance;
                y += height - textHeight - distance;
                break;
            case 'insideBottomRight':
                x += width - distance;
                y += height - textHeight - distance;
                textAlign = 'right';
                break;
        }

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

    /**
     * Show ellipsis if overflow.
     *
     * @param  {string} text
     * @param  {string} textFont
     * @param  {string} containerWidth
     * @param  {Object} [options]
     * @param  {number} [options.ellipsis='...']
     * @param  {number} [options.maxIterations=3]
     * @param  {number} [options.minCharacters=3]
     * @return {string}
     */
    function textEllipsis(text, textFont, containerWidth, options) {
        if (!containerWidth) {
            return '';
        }

        options = util.defaults({
            ellipsis: '...',
            minCharacters: 3,
            maxIterations: 3,
            cnCharWidth: getTextWidth('国', textFont),
            // FIXME
            // 未考虑非等宽字体
            ascCharWidth: getTextWidth('a', textFont)
        }, options, true);

        containerWidth -= getTextWidth(options.ellipsis);

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

        for (var i = 0, len = textLines.length; i < len; i++) {
            textLines[i] = textLineTruncate(
                textLines[i], textFont, containerWidth, options
            );
        }

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

    function textLineTruncate(text, textFont, containerWidth, options) {
        // FIXME
        // 粗糙得写的，尚未考虑性能和各种语言、字体的效果。
        for (var i = 0;; i++) {
            var lineWidth = getTextWidth(text, textFont);

            if (lineWidth < containerWidth || i >= options.maxIterations) {
                text += options.ellipsis;
                break;
            }

            var subLength = i === 0
                ? estimateLength(text, containerWidth, options)
                : Math.floor(text.length * containerWidth / lineWidth);

            if (subLength < options.minCharacters) {
                text = '';
                break;
            }

            text = text.substr(0, subLength);
        }

        return text;
    }

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

    var textContain = {

        getWidth: getTextWidth,

        getBoundingRect: getTextRect,

        adjustTextPositionOnRect: adjustTextPositionOnRect,

        ellipsis: textEllipsis,

        measureText: function (text, textFont) {
            var ctx = util.getContext();
            ctx.font = textFont;
            return ctx.measureText(text);
        }
    };

    return textContain;
});
define('echarts/model/mixin/textStyle',['require','zrender/contain/text'],function (require) {

    var textContain = require('zrender/contain/text');

    function getShallow(model, path) {
        return model && model.getShallow(path);
    }

    return {
        /**
         * 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 () {
            var ecModel = this.ecModel;
            var gTextStyleModel = ecModel && ecModel.getModel('textStyle');
            return [
                // FIXME in node-canvas fontWeight is before fontStyle
                this.getShallow('fontStyle') || getShallow(gTextStyleModel, 'fontStyle'),
                this.getShallow('fontWeight') || getShallow(gTextStyleModel, 'fontWeight'),
                (this.getShallow('fontSize') || getShallow(gTextStyleModel, 'fontSize') || 12) + 'px',
                this.getShallow('fontFamily') || getShallow(gTextStyleModel, 'fontFamily') || 'sans-serif'
            ].join(' ');
        },

        getTextRect: function (text) {
            var textStyle = this.get('textStyle') || {};
            return textContain.getBoundingRect(
                text,
                this.getFont(),
                textStyle.align,
                textStyle.baseline
            );
        },

        ellipsis: function (text, containerWidth, options) {
            return textContain.ellipsis(
                text, this.getFont(), containerWidth, options
            );
        }
    };
});
define('echarts/model/mixin/itemStyle',['require','./makeStyleMapper'],function (require) {
    return {
        getItemStyle: require('./makeStyleMapper')(
            [
                ['fill', 'color'],
                ['stroke', 'borderColor'],
                ['lineWidth', 'borderWidth'],
                ['opacity'],
                ['shadowBlur'],
                ['shadowOffsetX'],
                ['shadowOffsetY'],
                ['shadowColor']
            ]
        )
    };
});
/**
 * @module echarts/model/Model
 */
define('echarts/model/Model',['require','zrender/core/util','../util/clazz','./mixin/lineStyle','./mixin/areaStyle','./mixin/textStyle','./mixin/itemStyle'],function (require) {

    var zrUtil = require('zrender/core/util');
    var clazzUtil = require('../util/clazz');

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

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

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

        this.init.apply(this, arguments);
    }

    Model.prototype = {

        constructor: Model,

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

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

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

            if (typeof path === 'string') {
                path = path.split('.');
            }

            var obj = this.option;
            var parentModel = this.parentModel;
            for (var i = 0; i < path.length; i++) {
                // obj could be number/string/... (like 0)
                obj = (obj && typeof obj === 'object') ? obj[path[i]] : null;
                if (obj == null) {
                    break;
                }
            }
            if (obj == null && parentModel && !ignoreParent) {
                obj = parentModel.get(path);
            }
            return obj;
        },

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

        /**
         * @param {string} path
         * @param {module:echarts/model/Model} [parentModel]
         * @return {module:echarts/model/Model}
         */
        getModel: function (path, parentModel) {
            var obj = this.get(path, true);
            var thisParentModel = this.parentModel;
            var model = new Model(
                obj, parentModel || (thisParentModel && thisParentModel.getModel(path)),
                this.ecModel
            );
            return model;
        },

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

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

    var mixin = zrUtil.mixin;
    mixin(Model, require('./mixin/lineStyle'));
    mixin(Model, require('./mixin/areaStyle'));
    mixin(Model, require('./mixin/textStyle'));
    mixin(Model, require('./mixin/itemStyle'));

    return Model;
});
define('echarts/util/component',['require','zrender/core/util','./clazz'],function(require) {

    var zrUtil = require('zrender/core/util');
    var clazz = require('./clazz');

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

    return componentUtil;
});
/**
 * 数值处理模块
 * @module echarts/util/number
 */

define('echarts/util/number',['require','zrender/core/util'],function (require) {

    var zrUtil = require('zrender/core/util');
    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) {

        if (zrUtil.isArray(val)) {
            return zrUtil.map(val, function (v) {
                return number.linearMap(v, domain, range, clamp);
            });
        }

        var sub = domain[1] - domain[0];

        if (sub === 0) {
            return (range[0] + range[1]) / 2;
        }
        var t = (val - domain[0]) / sub;

        if (clamp) {
            t = Math.min(Math.max(t, 0), 1);
        }

        return t * (range[1] - range[0]) + 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;
    };

    /**
     * Fix rounding error of float numbers
     * @param {number} x
     * @return {number}
     */
    number.round = function (x) {
        // PENDING
        return +(+x).toFixed(12);
    };

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

    /**
     * Get precision
     * @param {number} val
     */
    number.getPrecision = function (val) {
        // 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 {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);
        return Math.max(
            -dataQuantity + sizeQuantity,
            0
        );
    };

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

    /**
     * @param {string|Date|number} value
     * @return {number} timestamp
     */
    number.parseDate = function (value) {
        return value instanceof Date
            ? value
            : new Date(typeof value === 'string' ? value.replace(/-/g, '/') : value);
    };

    return number;
});
define('echarts/util/format',['require','zrender/core/util'],function (require) {

    var zrUtil = require('zrender/core/util');
    /**
     * 每三位默认加,格式化
     * @type {string|number} x
     */
    function addCommas(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
     * @return {string} str
     */
    function toCamelCase(str) {
        return str.toLowerCase().replace(/-(.)/g, function(match, group1) {
            return group1.toUpperCase();
        });
    }

    /**
     * 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
     */
    function normalizeCssArray(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;
    }

    function encodeHTML(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'];

    function wrapVar(varName, seriesIdx) {
        return '{' + varName + (seriesIdx == null ? '' : seriesIdx) + '}';
    }
    /**
     * Template formatter
     * @param  {string} tpl
     * @param  {Array.<Object>|Object} paramsList
     * @return {string}
     */
    function formatTpl(tpl, paramsList) {
        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];
            tpl = tpl.replace(wrapVar(alias),  wrapVar(alias, 0));
        }
        for (var seriesIdx = 0; seriesIdx < seriesLen; seriesIdx++) {
            for (var k = 0; k < $vars.length; k++) {
                tpl = tpl.replace(
                    wrapVar(TPL_VAR_ALIAS[k], seriesIdx),
                    paramsList[seriesIdx][$vars[k]]
                );
            }
        }

        return tpl;
    }

    return {

        normalizeCssArray: normalizeCssArray,

        addCommas: addCommas,

        toCamelCase: toCamelCase,

        encodeHTML: encodeHTML,

        formatTpl: formatTpl
    };
});
// Layout helpers for each component positioning
define('echarts/util/layout',['require','zrender/core/util','zrender/core/BoundingRect','./number','./format'],function(require) {


    var zrUtil = require('zrender/core/util');
    var BoundingRect = require('zrender/core/BoundingRect');
    var numberUtil = require('./number');
    var formatUtil = require('./format');
    var parsePercent = numberUtil.parsePercent;
    var each = zrUtil.each;

    var layout = {};

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

        var rect = new BoundingRect(left + margin[3], top + margin[0], width, height);
        rect.margin = margin;
        return rect;
    };

    /**
     * Position group of component in viewport
     *  Group position is specified by either
     *  {left, top}, {right, bottom}
     *  If all properties exists, right and bottom will be igonred.
     *
     * @param {module:zrender/container/Group} group
     * @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
     */
    layout.positionGroup = function (
        group, positionInfo, containerRect, margin
    ) {
        var groupRect = group.getBoundingRect();

        positionInfo = zrUtil.extend(zrUtil.clone(positionInfo), {
            width: groupRect.width,
            height: groupRect.height
        });

        positionInfo = layout.getLayoutRect(
            positionInfo, containerRect, margin
        );

        group.position = [
            positionInfo.x - groupRect.x,
            positionInfo.y - groupRect.y
        ];
    };

    /**
     * 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} [opt]
     * @param {boolean} [opt.ignoreSize=false] Some component must has width and height.
     */
    layout.mergeLayoutParam = function (targetOption, newOption, opt) {
        opt = opt || {};
        var hNames = ['width', 'left', 'right']; // Order by priority.
        var vNames = ['height', 'top', 'bottom']; // Order by priority.
        var hResult = merge(hNames);
        var vResult = merge(vNames);

        copy(hNames, targetOption, hResult);
        copy(vNames, targetOption, vResult);

        function merge(names) {
            var newParams = {};
            var newValueCount = 0;
            var merged = {};
            var mergedValueCount = 0;
            var enoughParamNumber = opt.ignoreSize ? 1 : 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++;
            });

            // 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;
            }
            else if (mergedValueCount < enoughParamNumber) {
                // In common way, 'auto' means auto calculate by left/right
                // or top/bottom. But Some components may auto calculate by
                // other way (like dataZoom auto by coordnate system). In
                // that case we can set defualtOption 'auto', and if
                // mergedValueCount litter than enoughParamNumber, 'auto'
                // will filtered by priority and returned.
                var autoCount = 0;
                each(names, function (name) {
                    if (merged[name] === 'auto') {
                        autoCount < enoughParamNumber - mergedValueCount
                            ? autoCount++
                            : (merged[name] = null);
                    }
                });
                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.
                // When 'ignoreSize', enoughParamNumber is 1 and those will not happen.
                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) {
        var params = {};
        source && each(
            ['left', 'right', 'top', 'bottom', 'width', 'height'],
            function (name) {
                source.hasOwnProperty(name) && (params[name] = source[name]);
            }
        );
        return params;
    };

    return layout;
});
define('echarts/model/mixin/boxLayout',['require'],function (require) {

    return {
        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')
            };
        }
    };
});
/**
 * Component model
 *
 * @module echarts/model/Component
 */
define('echarts/model/Component',['require','./Model','zrender/core/util','../util/component','../util/clazz','../util/layout','./mixin/boxLayout'],function(require) {

    var Model = require('./Model');
    var zrUtil = require('zrender/core/util');
    var arrayPush = Array.prototype.push;
    var componentUtil = require('../util/component');
    var clazzUtil = require('../util/clazz');
    var layout = require('../util/layout');

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


        init: function (option, parentModel, ecModel, extraOpt) {
            this.mergeDefaultAndTheme(this.option, this.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) {
            zrUtil.merge(this.option, option, true);

            var layoutMode = this.layoutMode;
            if (layoutMode) {
                layout.mergeLayoutParam(this.option, option, layoutMode);
            }
        },

        getDefaultOption: function () {
            if (!this.hasOwnProperty('__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);
                }
                this.__defaultOption = defaultOption;
            }
            return this.__defaultOption;
        }

    });

    // 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, require('./mixin/boxLayout'));

    return ComponentModel;
});
define('echarts/model/globalDefault',[],function () {
    var platform = '';
    // Navigator not exists in node
    if (typeof navigator !== 'undefined') {
        platform = navigator.platform || '';
    }
    return {
        // 全图默认背景
        // 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', '#314656', '#61a0a8', '#dd8668', '#91c7ae', '#6e7074', '#61a0a8', '#bda29a', '#44525d', '#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'
        },
        // 主题，默认标志图形类型列表
        // symbolList: [
        //     'circle', 'rectangle', 'triangle', 'diamond',
        //     'emptyCircle', 'emptyRectangle', 'emptyTriangle', 'emptyDiamond'
        // ],
        animation: true,                // 过渡动画是否开启
        animationThreshold: 2000,       // 动画元素阀值，产生的图形原素超过2000不出动画
        animationDuration: 1000,        // 过渡动画参数：进入
        animationDurationUpdate: 300,   // 过渡动画参数：更新
        animationEasing: 'exponentialOut',    //BounceOut
        animationEasingUpdate: 'cubicOut'
    };
});
/**
 * ECharts global model
 *
 * @module {echarts/model/Global}
 *
 */

define('echarts/model/Global',['require','zrender/core/util','./Model','./Component','./globalDefault'],function (require) {

    var zrUtil = require('zrender/core/util');
    var Model = require('./Model');
    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 = require('./Component');

    var globalDefault = require('./globalDefault');

    /**
     * @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) {
            this._optionManager.setOption(option, optionPreprocessorFuncs);

            this.resetOption();
        },

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

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

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

                newCptOptionList
                    ? handleNew.call(this, mainType, newCptOptionList, dependencies)
                    : handleNoNew.call(this, mainType);

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

            function handleNoNew(mainType) {
                // Possible when using removeEdgeAndAdd in topologicalTravel
                // and ComponentModel.getAllClassMainTypes
                each(componentsMap[mainType], function (cpt) {
                    cpt.mergeOption({}, this);
                }, this);
            }

            function handleNew(mainType, newCptOptionList, dependencies) {
                // Normalize
                if (!(zrUtil.isArray(newCptOptionList))) {
                    newCptOptionList = [newCptOptionList];
                }
                if (!componentsMap[mainType]) {
                    componentsMap[mainType] = [];
                }

                var existComponents = mappingToExists(
                    componentsMap[mainType], newCptOptionList
                );

                var keyInfoList = makeKeyInfo(
                    mainType, newCptOptionList, existComponents
                );

                var dependentModels = getComponentsByTypes(
                    componentsMap, dependencies
                );

                option[mainType] = [];

                each(newCptOptionList, function (newCptOption, index) {
                    if (!isObject(newCptOption)) {
                        return;
                    }

                    var componentModel = existComponents[index];

                    var ComponentModelClass = ComponentModel.getClass(
                        mainType, keyInfoList[index].subType, true
                    );

                    if (componentModel && componentModel instanceof ComponentModelClass) {
                        componentModel.mergeOption(newCptOption, this);
                    }
                    else {
                        // PENDING Global as parent ?
                        componentModel = new ComponentModelClass(
                            newCptOption, this, this,
                            zrUtil.extend(
                                {
                                    dependentModels: dependentModels,
                                    componentIndex: index
                                },
                                keyInfoList[index]
                            )
                        );
                        componentsMap[mainType][index] = componentModel;
                    }

                    // Keep option
                    option[mainType][index] = componentModel.option;
                }, this);
            }
        },

        /**
         * @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[mainType];
            if (list) {
                return list[idx || 0];
            }
        },

        /**
         * @param {Object} condition
         * @param {string} condition.mainType
         * @param {string} [condition.subType] If ignore, only query by mainType
         * @param {number} [condition.index] Either input index or id or name.
         * @param {string} [condition.id] Either input index or id or name.
         * @param {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[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);
                });
            }

            return filterBySubType(result, condition);
        },

        /**
         * The interface is different from queryComponents,
         * which is convenient for inner usage.
         *
         * @usage
         * findComponents(
         *     {mainType: 'dataZoom', query: {dataZoomId: 'abc'}},
         *     function (model, index) {...}
         * );
         *
         * findComponents(
         *     {mainType: 'series', subType: 'pie', query: {seriesName: 'uio'}},
         *     function (model, index) {...}
         * );
         *
         * 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[mainType];

            return doFilter(filterBySubType(result, condition));

            function getQueryCond(q) {
                var indexAttr = mainType + 'Index';
                var idAttr = mainType + 'Id';
                var nameAttr = mainType + 'Name';
                return q && (
                        q.hasOwnProperty(indexAttr)
                        || q.hasOwnProperty(idAttr)
                        || q.hasOwnProperty(nameAttr)
                    )
                    ? {
                        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;
                each(componentsMap, function (components, componentType) {
                    each(components, function (component, index) {
                        cb.call(context, componentType, component, index);
                    });
                });
            }
            else if (zrUtil.isString(mainType)) {
                each(componentsMap[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.series;
            return filter(series, function (oneSeries) {
                return oneSeries.name === name;
            });
        },

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

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

        /**
         * @return {Array.<module:echarts/model/Series>}
         */
        getSeries: function () {
            return this._componentsMap.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.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.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.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;
        },

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

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

            this._seriesIndices = createSeriesIndices(componentsMap.series);

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

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

    });

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

    function initBase(baseOption) {
        baseOption = baseOption;

        this.option = {};

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

        /**
         * 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[type] || []).slice();
        });

        return ret;
    }

    /**
     * @inner
     */
    function mappingToExists(existComponents, newComponentOptionList) {
        existComponents = (existComponents || []).slice();
        var result = [];

        // Mapping by id if specified.
        each(newComponentOptionList, function (componentOption, index) {
            if (!isObject(componentOption) || !componentOption.id) {
                return;
            }
            for (var i = 0, len = existComponents.length; i < len; i++) {
                if (existComponents[i].id === componentOption.id) {
                    result[index] = existComponents.splice(i, 1)[0];
                    return;
                }
            }
        });

        // Mapping by name if specified.
        each(newComponentOptionList, function (componentOption, index) {
            if (!isObject(componentOption)
                || !componentOption.name
                || hasInnerId(componentOption)
            ) {
                return;
            }
            for (var i = 0, len = existComponents.length; i < len; i++) {
                if (existComponents[i].name === componentOption.name) {
                    result[index] = existComponents.splice(i, 1)[0];
                    return;
                }
            }
        });

        // Otherwise mapping by index.
        each(newComponentOptionList, function (componentOption, index) {
            if (!result[index]
                && existComponents[index]
                && !hasInnerId(componentOption)
            ) {
                result[index] = existComponents[index];
            }
        });

        return result;
    }

    /**
     * @inner
     */
    function makeKeyInfo(mainType, newCptOptionList, existComponents) {
        // 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 when setOption are called in
        // no-merge mode, new model is able to replace old model, and
        // new view instance are able to mapped to old instance.
        // So we generate id by name and type.

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

        // raw option should not be modified. for example, xxx.name might
        // be rendered, so default name ('') should not be replaced by
        // generated name. So we use keyInfoList wrap key info.
        var keyInfoList = [];

        // We use a prefix when generating name or id to prevent
        // user using the generated name or id directly.
        var prefix = '\0';

        // Ensure that each id is distinct.
        var idSet = {};

        // key: name, value: count by single name.
        var nameCount = {};

        // Complete subType
        each(newCptOptionList, function (opt, index) {
            if (!isObject(opt)) {
                return;
            }
            var existCpt = existComponents[index];
            var subType = determineSubType(mainType, opt, existCpt);
            var item = {mainType: mainType, subType: subType};
            keyInfoList[index] = item;
        });

        function eachOpt(cb) {
            each(newCptOptionList, function (opt, index) {
                if (!isObject(opt)) {
                    return;
                }
                var existCpt = existComponents[index];
                var item = keyInfoList[index];
                var fullType = mainType + '.' + item.subType;
                cb(item, opt, existCpt, fullType);
            });
        }

        // Make name
        eachOpt(function (item, opt, existCpt, fullType) {
            item.name = existCpt
                ? existCpt.name
                : opt.name != null
                ? opt.name
                : prefix + '-';
            // init nameCount
            nameCount[item.name] = 0;
        });

        // Make id
        eachOpt(function (item, opt, existCpt, fullType) {
            var itemName = item.name;

            item.id = existCpt
                ? existCpt.id
                : opt.id != null
                ? opt.id
                // (1) Using delimiter to escapse dulipcation.
                // (2) Using type tu ensure that view with different
                //     type will not be mapped.
                // (3) Consider this situatoin:
                //      optionA: [{name: 'a'}, {name: 'a'}, {..}]
                //      optionB [{..}, {name: 'a'}, {name: 'a'}]
                //     Using nameCount to ensure that series with
                //     the same name between optionA and optionB
                //     can be mapped.
                : prefix + [fullType, itemName, nameCount[itemName]++].join('|');

            if (idSet[item.id]) {
                // FIXME
                // how to throw
                throw new Error('id duplicates: ' + item.id);
            }
            idSet[item.id] = 1;
        });

        return keyInfoList;
    }

    /**
     * @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 hasInnerId(componentOption) {
        return componentOption.id
            // FIXME
            // Where to put this constant.
            && (componentOption.id + '').indexOf('\0_ec_\0') === 0;
    }

    /**
     * @inner
     */
    function assertSeriesInitialized(ecModel) {
        // Components that use _seriesIndices should depends on series component,
        // which make sure that their initialization is after series.
        if (!ecModel._seriesIndices) {
            // FIXME
            // 验证和提示怎么写
            throw new Error('Series is not initialized. Please depends sereis.');
        }
    }

    return GlobalModel;
});
define('echarts/ExtensionAPI',['require','zrender/core/util'],function(require) {



    var zrUtil = require('zrender/core/util');

    var echartsAPIList = [
        'getDom', 'getZr', 'getWidth', 'getHeight', 'dispatchAction',
        'on', 'off', 'getDataURL', 'getConnectedDataURL'
    ];

    function ExtensionAPI(chartInstance) {
        zrUtil.each(echartsAPIList, function (name) {
            this[name] = zrUtil.bind(chartInstance[name], chartInstance);
        }, this);
    }

    return ExtensionAPI;
});
define('echarts/CoordinateSystem',['require'],function(require) {



    // var zrUtil = require('zrender/core/util');
    var coordinateSystemCreators = {};

    function CoordinateSystemManager() {

        this._coordinateSystems = {};

        this._coordinateSystemsList = [];
    }

    CoordinateSystemManager.prototype = {

        constructor: CoordinateSystemManager,

        update: function (ecModel, api) {
            var coordinateSystems = {};
            for (var type in coordinateSystemCreators) {
                coordinateSystems[type] = coordinateSystemCreators[type].create(ecModel, api);
            }

            this._coordinateSystems = coordinateSystems;
        },

        get: function (type, idx) {
            var list = this._coordinateSystems[type];
            if (list) {
                return list[idx || 0];
            }
        }
    };

    CoordinateSystemManager.register = function (type, coordinateSystemCreator) {
        coordinateSystemCreators[type] = coordinateSystemCreator;
    };

    return CoordinateSystemManager;
});
/**
 * ECharts option manager
 *
 * @module {echarts/model/OptionManager}
 */

define('echarts/model/OptionManager',['require','zrender/core/util'],function (require) {

    var zrUtil = require('zrender/core/util');
    var each = zrUtil.each;
    var clone = zrUtil.clone;
    var map = zrUtil.map;

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

    // 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中没有设置，则进行警告。

            this._optionBackup = parseRawOption.call(
                this, rawOption, optionPreprocessorFuncs
            );
        },

        /**
         * @return {Object}
         */
        mountOption: function () {
            var optionBackup = this._optionBackup;

            // FIXME
            // 如果没有reset功能则不clone。

            this._timelineOptions = map(optionBackup.timelineOptions, clone);
            this._mediaList = map(optionBackup.mediaList, clone);
            this._mediaDefault = clone(optionBackup.mediaDefault);
            this._currentMediaIndices = [];

            return clone(optionBackup.baseOption);
        },

        /**
         * @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) {
        var timelineOptions = [];
        var mediaList = [];
        var mediaDefault;
        var baseOption;

        // Compatible with ec2.
        var timelineOpt = rawOption.timeline;

        // For timeline
        if (timelineOpt || rawOption.options) {
            baseOption = rawOption.baseOption || {};
            timelineOptions = (rawOption.options || []).slice();
        }
        // For media query
        if (rawOption.media) {
            baseOption = rawOption.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);
                });
            }
        );

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

    return OptionManager;
});
define('echarts/util/model',['require','./format','./number','zrender/core/util','../model/Model'],function(require) {

    var formatUtil = require('./format');
    var nubmerUtil = require('./number');
    var zrUtil = require('zrender/core/util');

    var Model = require('../model/Model');

    var AXIS_DIMS = ['x', 'y', 'z', 'radius', 'angle'];

    var modelUtil = {};

    /**
     * Create "each" method to iterate names.
     *
     * @pubilc
     * @param  {Array.<string>} names
     * @param  {Array.<string>=} attrs
     * @return {Function}
     */
    modelUtil.createNameEach = function (names, attrs) {
        names = names.slice();
        var capitalNames = zrUtil.map(names, modelUtil.capitalFirst);
        attrs = (attrs || []).slice();
        var capitalAttrs = zrUtil.map(attrs, modelUtil.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);
            });
        };
    };

    /**
     * @public
     */
    modelUtil.capitalFirst = function (str) {
        return str ? str.charAt(0).toUpperCase() + str.substr(1) : str;
    };

    /**
     * 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
     */
    modelUtil.eachAxisDim = modelUtil.createNameEach(AXIS_DIMS, ['axisIndex', 'axis', 'index']);

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

    /**
     * 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: {}}
     */
    modelUtil.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;
                });
            });
        }
    };

    /**
     * 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
            zrUtil.each(subOpts, function (subOptName) {
                var val = zrUtil.retrieve(emphasisOpt[subOptName], normalOpt[subOptName]);
                if (val != null) {
                    emphasisOpt[subOptName] = val;
                }
            });
        }
    };

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

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

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

    /**
     * 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' && !isFinite(value) && 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
    };

    modelUtil.dataFormatMixin = {
        /**
         * Get params for formatter
         * @param {number} dataIndex
         * @return {Object}
         */
        getDataParams: function (dataIndex) {
            var data = this.getData();

            var seriesIndex = this.seriesIndex;
            var seriesName = this.name;

            var rawValue = this.getRawValue(dataIndex);
            var rawDataIndex = data.getRawIndex(dataIndex);
            var name = data.getName(dataIndex, true);

            // Data may not exists in the option given by user
            var rawDataArray = this.getRawDataArray();
            var itemOpt = rawDataArray && rawDataArray[rawDataIndex];

            return {
                seriesIndex: seriesIndex,
                seriesName: seriesName,
                name: name,
                dataIndex: rawDataIndex,
                data: itemOpt,
                value: rawValue,

                // 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 {Function|string} [formatter] Default use the `itemStyle[status].label.formatter`
         * @return {string}
         */
        getFormattedLabel: function (dataIndex, status, formatter) {
            status = status || 'normal';
            var data = this.getData();
            var itemModel = data.getItemModel(dataIndex);

            var params = this.getDataParams(dataIndex);
            if (!formatter) {
                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
         * @return {Object}
         */
        getRawValue: function (idx) {
            var itemModel = this.getData().getItemModel(idx);
            if (itemModel && itemModel.option) {
                var dataItem = itemModel.option;
                return (zrUtil.isObject(dataItem) && !zrUtil.isArray(dataItem))
                    ? dataItem.value : dataItem;
            }
        }
    };

    return modelUtil;
});
define('echarts/model/Series',['require','zrender/core/util','../util/format','../util/model','./Component'],function(require) {



    var zrUtil = require('zrender/core/util');
    var formatUtil = require('../util/format');
    var modelUtil = require('../util/model');
    var ComponentModel = require('./Component');

    var encodeHTML = formatUtil.encodeHTML;
    var addCommas = formatUtil.addCommas;

    var SeriesModel = ComponentModel.extend({

        type: 'series',

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

        init: function (option, parentModel, ecModel, extraOpt) {

            /**
             * @type {number}
             * @readOnly
             */
            this.seriesIndex = this.componentIndex;

            this.mergeDefaultAndTheme(option, ecModel);

            /**
             * @type {module:echarts/data/List|module:echarts/data/Tree|module:echarts/data/Graph}
             * @private
             */
            this._dataBeforeProcessed = this.getInitialData(option, ecModel);

            // When using module:echarts/data/Tree or module:echarts/data/Graph,
            // cloneShallow will cause this._data.graph.data pointing to new data list.
            // Wo we make this._dataBeforeProcessed first, and then make this._data.
            this._data = this._dataBeforeProcessed.cloneShallow();
        },

        /**
         * Util for merge default and theme to option
         * @param  {Object} option
         * @param  {module:echarts/model/Global} ecModel
         */
        mergeDefaultAndTheme: function (option, ecModel) {
            zrUtil.merge(
                option,
                ecModel.getTheme().get(this.subType)
            );
            zrUtil.merge(option, this.getDefaultOption());

            // Default label emphasis `position` and `show`
            modelUtil.defaultEmphasis(
                option.label, ['position', 'show', 'textStyle', 'distance', 'formatter']
            );
        },

        mergeOption: function (newSeriesOption, ecModel) {
            newSeriesOption = zrUtil.merge(this.option, newSeriesOption, true);

            var data = this.getInitialData(newSeriesOption, ecModel);
            // TODO Merge data?
            if (data) {
                this._data = data;
                this._dataBeforeProcessed = data.cloneShallow();
            }
            // FIXME
            // Default label emphasis `position` and `show`
            // Do it after option is merged. In case newSeriesOption only
            // set the value in emphasis
            // modelUtil.defaultNormalEmphasis(this.option.label);
        },

        /**
         * Init a data structure from data related option in series
         * Must be overwritten
         */
        getInitialData: function () {},

        /**
         * @return {module:echarts/data/List}
         */
        getData: function () {
            return this._data;
        },

        /**
         * @param {module:echarts/data/List} data
         */
        setData: function (data) {
            this._data = data;
        },

        /**
         * Get data before processed
         * @return {module:echarts/data/List}
         */
        getRawData: function () {
            return this._dataBeforeProcessed;
        },

        /**
         * Get raw data array given by user
         * @return {Array.<Object>}
         */
        getRawDataArray: function () {
            return this.option.data;
        },

        /**
         * Get dimensions on the given axis.
         * @param {string} axisDim
         * @return {Array.<string>} dimensions on the axis.
         */
        getDimensionsOnAxis: function (axisDim) {
            return [axisDim]; // Retunr axisDim default.
        },

        // FIXME
        /**
         * Default tooltip formatter
         *
         * @param {number} dataIndex
         * @param {boolean} [mutipleSeries=false]
         */
        formatTooltip: function (dataIndex, mutipleSeries) {
            var data = this._data;
            var value = this.getRawValue(dataIndex);
            var formattedValue = zrUtil.isArray(value)
                ? zrUtil.map(value, addCommas).join(', ') : addCommas(value);
            var name = data.getName(dataIndex);

            return !mutipleSeries
                ? (encodeHTML(this.name) + '<br />'
                    + (name
                        ? encodeHTML(name) + ' : ' + formattedValue
                        : formattedValue)
                  )
                : (encodeHTML(this.name) + ' : ' + formattedValue);
        },

        restoreData: function () {
            this._data = this._dataBeforeProcessed.cloneShallow();
        }
    });

    zrUtil.mixin(SeriesModel, modelUtil.dataFormatMixin);

    return SeriesModel;
});
/**
 * zrender: 生成唯一id
 *
 * @author errorrik (errorrik@gmail.com)
 */

define(
    'zrender/core/guid',[],function() {
        var idStart = 0x0907;

        return function () {
            return 'zr_' + (idStart++);
        };
    }
);

/**
 * 事件扩展
 * @module zrender/mixin/Eventful
 * @author Kener (@Kener-林峰, kener.linfeng@gmail.com)
 *         pissang (https://www.github.com/pissang)
 */
define('zrender/mixin/Eventful',['require','../core/util'],function (require) {

    var arrySlice = Array.prototype.slice;
    var zrUtil = require('../core/util');
    var indexOf = zrUtil.indexOf;

    /**
     * 事件分发器
     * @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] = [];
            }

            if (indexOf(_h[event], event) >= 0) {
                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] = [];
            }

            _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#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
     */

    return Eventful;
});

/**
 * 提供变换扩展
 * @module zrender/mixin/Transformable
 * @author pissang (https://www.github.com/pissang)
 */
define('zrender/mixin/Transformable',['require','../core/matrix','../core/vector'],function (require) {



    var matrix = require('../core/matrix');
    var vector = require('../core/vector');
    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) {
        m = m || [];
        mIdentity(m);

        var origin = this.origin;

        var scale = this.scale;
        var rotation = this.rotation;
        var position = this.position;
        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;
    };
    /**
     * 将自己的transform应用到context上
     * @param {Context2D} ctx
     */
    transformableProto.setTransform = function (ctx) {
        var m = this.transform;
        if (m) {
            ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]);
        }
    };

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

    /**
     * 变换坐标位置到 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;
    };

    return Transformable;
});

/**
 * 缓动代码来自 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
 */
define('zrender/animation/easing',[],function () {
    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;
        }
    }

    return easing;
});


/**
 * 动画主控制器
 * @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
 */
define('zrender/animation/Clip',['require','./easing'],function(require) {

    var easingFuncs = require('./easing');

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

    Clip.prototype = {

        constructor: Clip,

        step: function (time) {
            // Set startTime on first step, or _startTime may has milleseconds different between clips
            // PENDING
            if (!this._initialized) {
                this._startTime = new Date().getTime() + this._delay;
                this._initialized = true;
            }

            var percent = (time - this._startTime) / 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();
                    // 重新开始周期
                    // 抛出而不是直接调用事件直到 stage.update 后再统一调用这些事件
                    return 'restart';
                }

                // 动画完成将这个控制器标识为待删除
                // 在Animation.update中进行批量删除
                this._needsRemove = true;
                return 'destroy';
            }

            return null;
        },

        restart: function() {
            var time = new Date().getTime();
            var remainder = (time - this._startTime) % this._life;
            this._startTime = new Date().getTime() - remainder + this.gap;

            this._needsRemove = false;
        },

        fire: function(eventType, arg) {
            eventType = 'on' + eventType;
            if (this[eventType]) {
                this[eventType](this._target, arg);
            }
        }
    };

    return Clip;
});

/**
 * @module zrender/tool/color
 */
define('zrender/tool/color',['require'],function(require) {

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

    /**
     * @param {string} colorStr
     * @return {Array.<number>}
     * @memberOf module:zrender/util/color
     */
    function parse(colorStr) {
        if (!colorStr) {
            return;
        }
        // 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) {
            return kCSSColorTable[str].slice();  // dup.
        }

        // #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)) {
                    return;  // Covers NaN.
                }
                return [
                    ((iv & 0xf00) >> 4) | ((iv & 0xf00) >> 8),
                    (iv & 0xf0) | ((iv & 0xf0) >> 4),
                    (iv & 0xf) | ((iv & 0xf) << 4),
                    1
                ];
            }
            else if (str.length === 7) {
                var iv = parseInt(str.substr(1), 16);  // TODO(deanm): Stricter parsing.
                if (!(iv >= 0 && iv <= 0xffffff)) {
                    return;  // Covers NaN.
                }
                return [
                    (iv & 0xff0000) >> 16,
                    (iv & 0xff00) >> 8,
                    iv & 0xff,
                    1
                ];
            }

            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) {
                        return;
                    }
                    alpha = parseCssFloat(params.pop()); // jshint ignore:line
                // Fall through.
                case 'rgb':
                    if (params.length !== 3) {
                        return;
                    }
                    return [
                        parseCssInt(params[0]),
                        parseCssInt(params[1]),
                        parseCssInt(params[2]),
                        alpha
                    ];
                case 'hsla':
                    if (params.length !== 4) {
                        return;
                    }
                    params[3] = parseCssFloat(params[3]);
                    return hsla2rgba(params);
                case 'hsl':
                    if (params.length !== 3) {
                        return;
                    }
                    return hsla2rgba(params);
                default:
                    return;
            }
        }

        return;
    }

    /**
     * @param {Array.<number>} hsla
     * @return {Array.<number>} rgba
     */
    function hsla2rgba(hsla) {
        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;

        var rgba = [
            clampCssByte(cssHueToRgb(m1, m2, h + 1 / 3) * 255),
            clampCssByte(cssHueToRgb(m1, m2, h) * 255),
            clampCssByte(cssHueToRgb(m1, m2, h - 1 / 3) * 255)
        ];

        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>}
     */
    function fastMapToColor(normalizedValue, colors, out) {
        if (!(colors && colors.length)
            || !(normalizedValue >= 0 && normalizedValue <= 1)
        ) {
            return;
        }
        out = out || [0, 0, 0, 0];
        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] = clampCssByte(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 {Array<number>} interval  Array length === 2,
     *                                  each item is normalized value ([0, 1]).
     * @param {Array.<string>} colors Color list.
     * @return {Array.<Object>} colors corresponding to the interval,
     *                          each item is {color: 'xxx', offset: ...}
     *                          where offset is between 0 and 1.
     * @memberOf module:zrender/util/color
     */
    function mapIntervalToColor(interval, colors) {
        if (interval.length !== 2 || interval[1] < interval[0]) {
            return;
        }

        var info0 = mapToColor(interval[0], colors, true);
        var info1 = mapToColor(interval[1], colors, true);

        var result = [{color: info0.color, offset: 0}];

        var during = info1.value - info0.value;
        var start = Math.max(info0.value, info0.rightIndex);
        var end = Math.min(info1.value, info1.leftIndex);

        for (var i = start; during > 0 && i <= end; i++) {
            result.push({
                color: colors[i],
                offset: (i - info0.value) / during
            });
        }
        result.push({color: info1.color, offset: 1});

        return result;
    }

    /**
     * @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.<string>} colors Color list.
     * @param {string} type 'rgba', 'hsva', ...
     * @return {string} Result color.
     */
    function stringify(arrColor, type) {
        if (type === 'rgb' || type === 'hsv' || type === 'hsl') {
            arrColor = arrColor.slice(0, 3);
        }
        return type + '(' + arrColor.join(',') + ')';
    }

    return {
        parse: parse,
        lift: lift,
        toHex: toHex,
        fastMapToColor: fastMapToColor,
        mapToColor: mapToColor,
        mapIntervalToColor: mapIntervalToColor,
        modifyHSL: modifyHSL,
        modifyAlpha: modifyAlpha,
        stringify: stringify
    };
});


/**
 * @module echarts/animation/Animator
 */
define('zrender/animation/Animator',['require','./Clip','../tool/color','../core/util'],function (require) {

    var Clip = require('./Clip');
    var color = require('../tool/color');
    var util = require('../core/util');
    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 = 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
                    );
                }
            }
        }
    }

    function fillArr(arr0, arr1, arrDim) {
        var arr0Len = arr0.length;
        var arr1Len = arr1.length;
        if (arr0Len === arr1Len) {
            return;
        }
        // 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])
                );
            }
        }
    }

    /**
     * @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 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
                && isArrayLike(firstVal[0])
            )
            ? 2 : 1;
        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;
        }

        if (isValueArray) {
            var lastValue = kfValues[trackLen - 1];
            // Polyfill array
            for (var i = 0; i < trackLen - 1; i++) {
                fillArr(kfValues[i], lastValue, arrDim);
            }
            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;
            if (percent < lastFramePercent) {
                // Start from next key
                start = Math.min(lastFrame + 1, trackLen - 1);
                for (frame = start; frame >= 0; frame--) {
                    if (kfPercents[frame] <= percent) {
                        break;
                    }
                }
                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 (!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;
        },

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

    return Animator;
});
define('zrender/config',[],function () {
    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
    };
    return config;
});


define(
    'zrender/core/log',['require','../config'],function (require) {
        var config = require('../config');

        /**
         * @exports zrender/tool/log
         * @author Kener (@Kener-林峰, kener.linfeng@gmail.com)
         */
        return 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;
        };
        */
    }
);

/**
 * @module zrender/mixin/Animatable
 */
define('zrender/mixin/Animatable',['require','../animation/Animator','../core/util','../core/log'],function(require) {



    var Animator = require('../animation/Animator');
    var util = require('../core/util');
    var isString = util.isString;
    var isFunction = util.isFunction;
    var isObject = util.isObject;
    var log = require('../core/log');

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

    return Animatable;
});
/**
 * @module zrender/Element
 */
define('zrender/Element',['require','./core/guid','./mixin/Eventful','./mixin/Transformable','./mixin/Animatable','./core/util'],function(require) {


    var guid = require('./core/guid');
    var Eventful = require('./mixin/Eventful');
    var Transformable = require('./mixin/Transformable');
    var Animatable = require('./mixin/Animatable');
    var zrUtil = require('./core/util');

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

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

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

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

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

    return Element;
});
/**
 * Group是一个容器，可以插入子节点，Group的变换也会被应用到子节点上
 * @module zrender/graphic/Group
 * @example
 *     var Group = require('zrender/container/Group');
 *     var Circle = require('zrender/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);
 */
define('zrender/container/Group',['require','../core/util','../Element','../core/BoundingRect'],function (require) {

    var zrUtil = require('../core/util');
    var Element = require('../Element');
    var BoundingRect = require('../core/BoundingRect');

    /**
     * @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) {
            this[key] = opts[key];
        }

        this._children = [];

        this.__storage = null;

        this.__dirty = true;
    };

    Group.prototype = {

        constructor: Group,

        /**
         * @type {string}
         */
        type: 'group',

        /**
         * @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.addToMap(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.delFromMap(child.id);

                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.delFromMap(child.id);
                    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.addToMap(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.delFromMap(child.id);
                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
            // TODO Transform
            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);
                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);

    return Group;
});
define('echarts/view/Component',['require','zrender/container/Group','../util/component','../util/clazz'],function (require) {

    var Group = require('zrender/container/Group');
    var componentUtil = require('../util/component');
    var clazzUtil = require('../util/clazz');

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

    return Component;
});
define('echarts/view/Chart',['require','zrender/container/Group','../util/component','../util/clazz'],function (require) {

    var Group = require('zrender/container/Group');
    var componentUtil = require('../util/component');
    var clazzUtil = require('../util/clazz');

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

    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) {
        if (payload.dataIndex != null) {
            var el = data.getItemGraphicEl(payload.dataIndex);
            elSetState(el, state);
        }
        else if (payload.name) {
            var dataIndex = data.indexOfName(payload.name);
            var el = data.getItemGraphicEl(dataIndex);
            elSetState(el, state);
        }
        else {
            data.eachItemGraphicEl(function (el) {
                elSetState(el, state);
            });
        }
    }

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

    // Add capability of registerClass, getClass, hasClass, registerSubTypeDefaulter and so on.
    clazzUtil.enableClassManagement(Chart, {registerWhenExtend: true});

    return Chart;
});
/**
 * @module zrender/graphic/Style
 */

define('zrender/graphic/Style',['require'],function (require) {

    var STYLE_LIST_COMMON = [
        'lineCap', 'lineJoin', 'miterLimit',
        'shadowBlur', 'shadowOffsetX', 'shadowOffsetY', 'shadowColor'
    ];

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

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

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

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

        /**
         * @type {number}
         */
        textDistance: 5,

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

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

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

        /**
         * @param {CanvasRenderingContext2D} ctx
         */
        bind: function (ctx, el) {
            var fill = this.fill;
            var stroke = this.stroke;
            for (var i = 0; i < STYLE_LIST_COMMON.length; i++) {
                var styleName = STYLE_LIST_COMMON[i];

                if (this[styleName] != null) {
                    ctx[styleName] = this[styleName];
                }
            }
            if (stroke != null) {
                var lineWidth = this.lineWidth;
                ctx.lineWidth = lineWidth / (
                    (this.strokeNoScale && el && el.getLineScale) ? el.getLineScale() : 1
                );
            }
            if (fill != null) {
                 // Use canvas gradient if has
                ctx.fillStyle = fill.canvasGradient ? fill.canvasGradient : fill;
            }
            if (stroke != null) {
                 // Use canvas gradient if has
                ctx.strokeStyle = stroke.canvasGradient ? stroke.canvasGradient : stroke;
            }
            this.opacity != null && (ctx.globalAlpha = this.opacity);
        },

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

    var styleProto = Style.prototype;
    var name;
    var i;
    for (i = 0; i < STYLE_LIST_COMMON.length; i++) {
        name = STYLE_LIST_COMMON[i];
        if (!(name in styleProto)) {
            styleProto[name] = null;
        }
    }

    return Style;
});
/**
 * Mixin for drawing text in a element bounding rect
 * @module zrender/mixin/RectText
 */

define('zrender/graphic/mixin/RectText',['require','../../contain/text','../../core/BoundingRect'],function (require) {

    var textContain = require('../../contain/text');
    var BoundingRect = require('../../core/BoundingRect');

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

    function setTransform(ctx, m) {
        ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]);
    }

    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;
            }
            var x;
            var y;
            var textPosition = style.textPosition;
            var distance = style.textDistance;
            var align = style.textAlign;
            var font = style.textFont || style.font;
            var baseline = style.textBaseline;

            textRect = textRect || textContain.getBoundingRect(text, font, align, baseline);

            // Transform rect to view space
            var transform = this.transform;
            var invTransform = this.invTransform;
            if (transform) {
                tmpRect.copy(rect);
                tmpRect.applyTransform(transform);
                rect = tmpRect;
                // Transform back
                setTransform(ctx, invTransform);
            }

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

            ctx.textAlign = align;
            ctx.textBaseline = baseline;

            var textFill = style.textFill;
            var textStroke = style.textStroke;
            textFill && (ctx.fillStyle = textFill);
            textStroke && (ctx.strokeStyle = textStroke);
            ctx.font = font;

            // Text shadow
            ctx.shadowColor = style.textShadowColor;
            ctx.shadowBlur = style.textShadowBlur;
            ctx.shadowOffsetX = style.textShadowOffsetX;
            ctx.shadowOffsetY = style.textShadowOffsetY;

            var textLines = text.split('\n');
            for (var i = 0; i < textLines.length; i++) {
                textFill && ctx.fillText(textLines[i], x, y);
                textStroke && ctx.strokeText(textLines[i], x, y);
                y += textRect.lineHeight;
            }

            // Transform again
            transform && setTransform(ctx, transform);
        }
    };

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

define('zrender/graphic/Displayable',['require','../core/util','./Style','../Element','./mixin/RectText'],function (require) {

    var zrUtil = require('../core/util');

    var Style = require('./Style');

    var Element = require('../Element');
    var RectText = require('./mixin/RectText');
    // 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,

        beforeBrush: function (ctx) {},

        afterBrush: function (ctx) {},

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

        /**
         * 获取最小包围盒
         * @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();
            return this;
        }
    };

    zrUtil.inherits(Displayable, Element);

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

    return Displayable;
});
/**
 * 曲线辅助模块
 * @module zrender/core/curve
 * @author pissang(https://www.github.com/pissang)
 */
define('zrender/core/curve',['require','./vector'],function(require) {



    var vec2 = require('./vector');
    var v2Create = vec2.create;
    var v2DistSquare = vec2.distSquare;
    var mathPow = Math.pow;
    var mathSqrt = Math.sqrt;

    var EPSILON = 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) {
                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) {
                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);
    }

    return {

        cubicAt: cubicAt,

        cubicDerivativeAt: cubicDerivativeAt,

        cubicRootAt: cubicRootAt,

        cubicExtrema: cubicExtrema,

        cubicSubdivide: cubicSubdivide,

        cubicProjectPoint: cubicProjectPoint,

        quadraticAt: quadraticAt,

        quadraticDerivativeAt: quadraticDerivativeAt,

        quadraticRootAt: quadraticRootAt,

        quadraticExtremum: quadraticExtremum,

        quadraticSubdivide: quadraticSubdivide,

        quadraticProjectPoint: quadraticProjectPoint
    };
});
/**
 * @author Yi Shen(https://github.com/pissang)
 */
define('zrender/core/bbox',['require','./vector','./curve'],function (require) {

    var vec2 = require('./vector');
    var curve = require('./curve');

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

    /**
     * 从三阶贝塞尔曲线(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 xDim = [];
        var yDim = [];
        var cubicExtrema = curve.cubicExtrema;
        var cubicAt = curve.cubicAt;
        var left, right, top, bottom;
        var i;
        var n = cubicExtrema(x0, x1, x2, x3, xDim);

        for (i = 0; i < n; i++) {
            xDim[i] = cubicAt(x0, x1, x2, x3, xDim[i]);
        }
        n = cubicExtrema(y0, y1, y2, y3, yDim);
        for (i = 0; i < n; i++) {
            yDim[i] = cubicAt(y0, y1, y2, y3, yDim[i]);
        }

        xDim.push(x0, x3);
        yDim.push(y0, y3);

        left = mathMin.apply(null, xDim);
        right = mathMax.apply(null, xDim);
        top = mathMin.apply(null, yDim);
        bottom = mathMax.apply(null, yDim);

        min[0] = left;
        min[1] = top;
        max[0] = right;
        max[1] = bottom;
    };

    /**
     * 从二阶贝塞尔曲线(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;

        if (Math.abs(startAngle - endAngle) % PI2 < 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);
            }
        }
    };

    return bbox;
});

/**
 * Path 代理，可以在`buildPath`中用于替代`ctx`, 会保存每个path操作的命令到pathCommands属性中
 * 可以用于 isInsidePath 判断以及获取boundingRect
 *
 * @module zrender/core/PathProxy
 * @author Yi Shen (http://www.github.com/pissang)
 */

 // TODO getTotalLength, getPointAtLength
define('zrender/core/PathProxy',['require','./curve','./vector','./bbox','./BoundingRect'],function (require) {

    var curve = require('./curve');
    var vec2 = require('./vector');
    var bbox = require('./bbox');
    var BoundingRect = require('./BoundingRect');

    var CMD = {
        M: 1,
        L: 2,
        C: 3,
        Q: 4,
        A: 5,
        Z: 6,
        // Rect
        R: 7
    };

    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 hasTypedArray = typeof Float32Array != 'undefined';

    /**
     * @alias module:zrender/core/PathProxy
     * @constructor
     */
    var PathProxy = function () {

        /**
         * Path data. Stored as flat array
         * @type {Array.<Object>}
         */
        this.data = [];

        this._len = 0;

        this._ctx = null;

        this._xi = 0;
        this._yi = 0;

        this._x0 = 0;
        this._y0 = 0;
    };

    /**
     * 快速计算Path包围盒（并不是最小包围盒）
     * @return {Object}
     */
    PathProxy.prototype = {

        constructor: PathProxy,

        _lineDash: null,

        _dashOffset: 0,

        _dashIdx: 0,

        _dashSum: 0,

        getContext: function () {
            return this._ctx;
        },

        /**
         * @param  {CanvasRenderingContext2D} ctx
         * @return {module:zrender/core/PathProxy}
         */
        beginPath: function (ctx) {
            this._ctx = ctx;

            ctx && ctx.beginPath();

            // Reset
            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) {
            this.addData(CMD.L, x, y);
            if (this._ctx) {
                this._needsDash() ? this._dashedLineTo(x, y)
                    : this._ctx.lineTo(x, y);
            }
            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._xi = 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) {
            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)) {
                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)) {
                    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
         * @return {[type]} [description]
         */
        toStatic: function () {
            this.data.length = this._len;
            if (hasTypedArray && (this.data instanceof Array)) {
                this.data = new Float32Array(this.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;
            for (var i = 0; i < this._len;) {
                var cmd = d[i++];
                switch (cmd) {
                    case CMD.M:
                        ctx.moveTo(d[i++], d[i++]);
                        break;
                    case CMD.L:
                        ctx.lineTo(d[i++], d[i++]);
                        break;
                    case CMD.C:
                        ctx.bezierCurveTo(
                            d[i++], d[i++], d[i++], d[i++], d[i++], d[i++]
                        );
                        break;
                    case CMD.Q:
                        ctx.quadraticCurveTo(d[i++], d[i++], d[i++], d[i++]);
                        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;
                        if (isEllipse) {
                            ctx.translate(cx, cy);
                            ctx.rotate(psi);
                            ctx.scale(scaleX, scaleY);
                            ctx.arc(0, 0, r, theta, theta + dTheta, 1 - fs);
                            ctx.scale(1 / scaleX, 1 / scaleY);
                            ctx.rotate(-psi);
                            ctx.translate(-cx, -cy);
                        }
                        else {
                            ctx.arc(cx, cy, r, theta, theta + dTheta, 1 - fs);
                        }
                        break;
                    case CMD.R:
                        ctx.rect(d[i++], d[i++], d[i++], d[i++]);
                        break;
                    case CMD.Z:
                        ctx.closePath();
                }
            }
        }
    };

    PathProxy.CMD = CMD;

    return PathProxy;
});
define('zrender/contain/line',[],function () {
    return {
        /**
         * 线段包含判断
         * @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;
        }
    };
});
define('zrender/contain/cubic',['require','../core/curve'],function (require) {

    var curve = require('../core/curve');

    return {
        /**
         * 三次贝塞尔曲线描边包含判断
         * @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;
        }
    };
});
define('zrender/contain/quadratic',['require','../core/curve'],function (require) {

    var curve = require('../core/curve');

    return {
        /**
         * 二次贝塞尔曲线描边包含判断
         * @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;
        }
    };
});
define('zrender/contain/util',['require'],function (require) {

    var PI2 = Math.PI * 2;
    return {
        normalizeRadian: function(angle) {
            angle %= PI2;
            if (angle < 0) {
                angle += PI2;
            }
            return angle;
        }
    };
});
define('zrender/contain/arc',['require','./util'],function (require) {

    var normalizeRadian = require('./util').normalizeRadian;
    var PI2 = Math.PI * 2;

    return {
        /**
         * 圆弧描边包含判断
         * @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);
        }
    };
});
define('zrender/contain/windingLine',[],function () {
    return function windingLine(x0, y0, x1, y1, x, y) {
        if ((y > y0 && y > y1) || (y < y0 && y < y1)) {
            return 0;
        }
        if (y1 === y0) {
            return 0;
        }
        var dir = y1 < y0 ? 1 : -1;
        var t = (y - y0) / (y1 - y0);
        var x_ = t * (x1 - x0) + x0;

        return x_ > x ? dir : 0;
    };
});
define('zrender/contain/path',['require','../core/PathProxy','./line','./cubic','./quadratic','./arc','./util','../core/curve','./windingLine'],function (require) {



    var CMD = require('../core/PathProxy').CMD;
    var line = require('./line');
    var cubic = require('./cubic');
    var quadratic = require('./quadratic');
    var arc = require('./arc');
    var normalizeRadian = require('./util').normalizeRadian;
    var curve = require('../core/curve');

    var windingLine = require('./windingLine');

    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];
                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 ? 1 : -1;
                    }
                    else if (t < extrema[1]) {
                        w += y1_ < y0_ ? 1 : -1;
                    }
                    else {
                        w += y3 < y1_ ? 1 : -1;
                    }
                }
                else {
                    // 分成两段单调函数
                    if (t < extrema[0]) {
                        w += y0_ < y0 ? 1 : -1;
                    }
                    else {
                        w += y3 < y0_ ? 1 : -1;
                    }
                }
            }
            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++) {
                    var x_ = curve.quadraticAt(x0, x1, x2, roots[i]);
                    if (x_ > x) {
                        continue;
                    }
                    if (roots[i] < t) {
                        w += y_ < y0 ? 1 : -1;
                    }
                    else {
                        w += y2 < y_ ? 1 : -1;
                    }
                }
                return w;
            }
            else {
                var x_ = curve.quadraticAt(x0, x1, x2, roots[0]);
                if (x_ > x) {
                    return 0;
                }
                return y2 < y0 ? 1 : -1;
            }
        }
    }

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

        if (Math.abs(startAngle - endAngle) % 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, x1, y1, 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 包含
                        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;
    }

    return {
        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);
        }
    };
});
/**
 * Path element
 * @module zrender/graphic/Path
 */

define('zrender/graphic/Path',['require','./Displayable','../core/util','../core/PathProxy','../contain/path','./Gradient'],function (require) {

    var Displayable = require('./Displayable');
    var zrUtil = require('../core/util');
    var PathProxy = require('../core/PathProxy');
    var pathContain = require('../contain/path');

    var Gradient = require('./Gradient');

    function pathHasFill(style) {
        var fill = style.fill;
        return fill != null && fill !== 'none';
    }

    function pathHasStroke(style) {
        var stroke = style.stroke;
        return stroke != null && stroke !== 'none' && style.lineWidth > 0;
    }

    var abs = Math.abs;

    /**
     * @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 = new PathProxy();
    }

    Path.prototype = {

        constructor: Path,

        type: 'path',

        __dirtyPath: true,

        strokeContainThreshold: 5,

        brush: function (ctx) {
            ctx.save();

            var style = this.style;
            var path = this.path;
            var hasStroke = pathHasStroke(style);
            var hasFill = pathHasFill(style);

            if (this.__dirtyPath) {
                // Update gradient because bounding rect may changed
                if (hasFill && (style.fill instanceof Gradient)) {
                    style.fill.updateCanvasGradient(this, ctx);
                }
                if (hasStroke && (style.stroke instanceof Gradient)) {
                    style.stroke.updateCanvasGradient(this, ctx);
                }
            }

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

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

            var ctxLineDash = !!ctx.setLineDash;

            // 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 = this.path.beginPath(ctx);

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

                this.buildPath(path, this.shape);

                // Clear path dirty flag
                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);

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

            ctx.restore();
        },

        buildPath: function (ctx, shapeCfg) {},

        getBoundingRect: function () {
            var rect = this._rect;
            var style = this.style;
            if (!rect) {
                var path = this.path;
                if (this.__dirtyPath) {
                    path.beginPath();
                    this.buildPath(path, this.shape);
                }
                rect = path.getBoundingRect();
            }
            /**
             * Needs update rect with stroke lineWidth when
             * 1. Element changes scale or lineWidth
             * 2. First create rect
             */
            if (pathHasStroke(style) && (this.__dirty || !this._rect)) {
                var rectWithStroke = this._rectWithStroke
                    || (this._rectWithStroke = rect.clone());
                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;
                w = Math.max(w, this.strokeContainThreshold);
                // 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 rectWithStroke;
            }
            this._rect = rect;
            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 (pathHasStroke(style)) {
                    var lineWidth = style.lineWidth;
                    var lineScale = style.strokeNoScale ? this.getLineScale() : 1;
                    // Line scale can't be 0;
                    if (lineScale < 1e-10) {
                        return false;
                    }
                    lineWidth = Math.max(lineWidth, this.strokeContainThreshold);
                    if (pathContain.containStroke(
                        pathData, lineWidth / lineScale, x, y
                    )) {
                        return true;
                    }
                }
                if (pathHasFill(style)) {
                    return pathContain.contain(pathData, x, y);
                }
            }
            return false;
        },

        /**
         * @param  {boolean} dirtyPath
         */
        dirty: function (dirtyPath) {
            if (arguments.length ===0) {
                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);
            }
            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) {
                        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);

    return Path;
});
define('zrender/tool/transformPath',['require','../core/PathProxy','../core/vector'],function (require) {

    var CMD = require('../core/PathProxy').CMD;
    var vec2 = require('../core/vector');
    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, j, k;

        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);
                    var clockwise = data[i + 7];
                    // cx
                    data[i++] += x;
                    // cy
                    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];
            }
        }
    }

    return transformPath;
});
define('zrender/tool/path',['require','../graphic/Path','../core/PathProxy','./transformPath','../core/matrix'],function (require) {

    var Path = require('../graphic/Path');
    var PathProxy = require('../core/PathProxy');
    var transformPath = require('./transformPath');
    var matrix = require('../core/matrix');

    // 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('|');
        var ca = [];
        // 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);
        var transform;
        opts = opts || {};
        opts.buildPath = function (path) {
            path.setData(pathProxy.data);
            transform && transformPath(path, transform);
            // Svg and vml renderer don't have context
            var ctx = path.getContext();
            if (ctx) {
                path.rebuildPath(ctx);
            }
        };

        opts.applyTransform = function (m) {
            if (!transform) {
                transform = matrix.create();
            }
            matrix.mul(transform, m, transform);
        };

        return opts;
    }

    return {
        /**
         * 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;
            var pathEl;
            var i;
            for (i = 0; i < len; i++) {
                pathEl = pathEls[i];
                if (pathEl.__dirty) {
                    pathEl.buildPath(pathEl.path, pathEl.shape);
                }
                pathList.push(pathEl.path);
            }

            var pathBundle = new Path(opts);
            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;
        }
    };
});
define('zrender/graphic/helper/roundRect',['require'],function (require) {

    return {
        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;

            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);
        }
    }
});
// Simple LRU cache use doubly linked list
// @module zrender/core/LRU
define('zrender/core/LRU',['require'],function(require) {

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

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

    var LRUProto = LRU.prototype;

    /**
     * @param  {string} key
     * @param  {} value
     */
    LRUProto.put = function(key, value) {
        var list = this._list;
        var map = this._map;
        if (map[key] == null) {
            var len = list.len();
            if (len >= this._maxSize && len > 0) {
                // Remove the least recently used
                var leastUsedEntry = list.head;
                list.remove(leastUsedEntry);
                delete map[leastUsedEntry.key];
            }

            var entry = list.insert(value);
            entry.key = key;
            map[key] = entry;
        }
    };

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

    return LRU;
});
/**
 * Image element
 * @module zrender/graphic/Image
 */

define('zrender/graphic/Image',['require','./Displayable','../core/BoundingRect','../core/util','./helper/roundRect','../core/LRU'],function (require) {

    var Displayable = require('./Displayable');
    var BoundingRect = require('../core/BoundingRect');
    var zrUtil = require('../core/util');
    var roundRectHelper = require('./helper/roundRect');

    var LRU = require('../core/LRU');
    var globalImageCache = new LRU(50);
    /**
     * @alias zrender/graphic/Image
     * @extends module:zrender/graphic/Displayable
     * @constructor
     * @param {Object} opts
     */
    var ZImage = function (opts) {
        Displayable.call(this, opts);
    };

    ZImage.prototype = {

        constructor: ZImage,

        type: 'image',

        brush: function (ctx) {
            var style = this.style;
            var src = style.image;
            var image;
            // 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 width = style.width || image.width;
                var height = style.height || image.height;
                var x = style.x || 0;
                var y = style.y || 0;
                // 图片加载失败
                if (!image.width || !image.height) {
                    return;
                }

                ctx.save();

                style.bind(ctx);

                // 设置transform
                this.setTransform(ctx);

                if (style.r) {
                    // Border radius clipping
                    // FIXME
                    ctx.beginPath();
                    roundRectHelper.buildPath(ctx, style);
                    ctx.clip();
                }

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

                // 如果没设置宽和高的话自动根据图片宽高设置
                if (style.width == null) {
                    style.width = width;
                }
                if (style.height == null) {
                    style.height = height;
                }

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

                ctx.restore();
            }
        },

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

    return ZImage;
});
/**
 * Text element
 * @module zrender/graphic/Text
 *
 * TODO Wrapping
 */

define('zrender/graphic/Text',['require','./Displayable','../core/util','../contain/text'],function (require) {

    var Displayable = require('./Displayable');
    var zrUtil = require('../core/util');
    var textContain = require('../contain/text');

    /**
     * @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) {
            var style = this.style;
            var x = style.x || 0;
            var y = style.y || 0;
            // Convert to string
            var text = style.text;
            var textFill = style.fill;
            var textStroke = style.stroke;

            // Convert to string
            text != null && (text += '');

            if (text) {
                ctx.save();

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

                textFill && (ctx.fillStyle = textFill);
                textStroke && (ctx.strokeStyle = textStroke);

                ctx.font = style.textFont || style.font;
                ctx.textAlign = style.textAlign;
                ctx.textBaseline = style.textBaseline;

                var lineHeight = textContain.measureText('国', ctx.font).width;

                var textLines = text.split('\n');
                for (var i = 0; i < textLines.length; i++) {
                    textFill && ctx.fillText(textLines[i], x, y);
                    textStroke && ctx.strokeText(textLines[i], x, y);
                    y += lineHeight;
                }

                ctx.restore();
            }
        },

        getBoundingRect: function () {
            if (!this._rect) {
                var style = this.style;
                var rect = textContain.getBoundingRect(
                    style.text + '', style.textFont, style.textAlign, style.textBaseline
                );
                rect.x += style.x || 0;
                rect.y += style.y || 0;
                this._rect = rect;
            }
            return this._rect;
        }
    };

    zrUtil.inherits(Text, Displayable);

    return Text;
});
/**
 * 圆形
 * @module zrender/shape/Circle
 */

define('zrender/graphic/shape/Circle',['require','../Path'],function (require) {


    return require('../Path').extend({

        type: 'circle',

        shape: {
            cx: 0,
            cy: 0,
            r: 0
        },

        buildPath : function (ctx, shape) {
            // 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);
            return;
        }
    });
});

/**
 * 扇形
 * @module zrender/graphic/shape/Sector
 */

// FIXME clockwise seems wrong
define('zrender/graphic/shape/Sector',['require','../Path'],function (require) {

    return require('../Path').extend({

        type: 'sector',

        shape: {

            cx: 0,

            cy: 0,

            r0: 0,

            r: 0,

            startAngle: 0,

            endAngle: Math.PI * 2,

            clockwise: true
        },

        buildPath: function (ctx, shape) {

            var x = shape.cx;   // 圆心x
            var y = shape.cy;   // 圆心y
            var r0 = shape.r0 || 0;     // 形内半径[0,r)
            var r = shape.r;            // 扇形外半径(0,r]
            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();
        }
    });
});

/**
 * 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)
 */
define('zrender/graphic/helper/smoothSpline',['require','../../core/vector'],function (require) {
    var vec2 = require('../../core/vector');

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

/**
 * 贝塞尔平滑曲线
 * @module zrender/shape/util/smoothBezier
 * @author pissang (https://www.github.com/pissang)
 *         Kener (@Kener-林峰, kener.linfeng@gmail.com)
 *         errorrik (errorrik@gmail.com)
 */
define('zrender/graphic/helper/smoothBezier',['require','../../core/vector'],function (require) {

    var vec2 = require('../../core/vector');
    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} 计算出来的控制点数组
     */
    return 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;
    };
});

define('zrender/graphic/helper/poly',['require','./smoothSpline','./smoothBezier'],function (require) {

    var smoothSpline = require('./smoothSpline');
    var smoothBezier = require('./smoothBezier');

    return {
        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();
            }
        }
    }
});
/**
 * 多边形
 * @module zrender/shape/Polygon
 */
define('zrender/graphic/shape/Polygon',['require','../helper/poly','../Path'],function (require) {

    var polyHelper = require('../helper/poly');

    return require('../Path').extend({

        type: 'polygon',

        shape: {
            points: null,

            smooth: false,

            smoothConstraint: null
        },

        buildPath: function (ctx, shape) {
            polyHelper.buildPath(ctx, shape, true);
        }
    });
});
/**
 * @module zrender/graphic/shape/Polyline
 */
define('zrender/graphic/shape/Polyline',['require','../helper/poly','../Path'],function (require) {

    var polyHelper = require('../helper/poly');

    return require('../Path').extend({

        type: 'polyline',

        shape: {
            points: null,

            smooth: false,

            smoothConstraint: null
        },

        style: {
            stroke: '#000',

            fill: null
        },

        buildPath: function (ctx, shape) {
            polyHelper.buildPath(ctx, shape, false);
        }
    });
});
/**
 * 矩形
 * @module zrender/graphic/shape/Rect
 */

define('zrender/graphic/shape/Rect',['require','../helper/roundRect','../Path'],function (require) {
    var roundRectHelper = require('../helper/roundRect');

    return require('../Path').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;
        }
    });
});

/**
 * 直线
 * @module zrender/graphic/shape/Line
 */
define('zrender/graphic/shape/Line',['require','../Path'],function (require) {
    return require('../Path').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
            ];
        }
    });
});

/**
 * 贝塞尔曲线
 * @module zrender/shape/BezierCurve
 */
define('zrender/graphic/shape/BezierCurve',['require','../../core/curve','../Path'],function (require) {


    var curveTool = require('../../core/curve');
    var quadraticSubdivide = curveTool.quadraticSubdivide;
    var cubicSubdivide = curveTool.cubicSubdivide;
    var quadraticAt = curveTool.quadraticAt;
    var cubicAt = curveTool.cubicAt;

    var out = [];
    return require('../Path').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} percent
         * @return {Array.<number>}
         */
        pointAt: function (p) {
            var shape = this.shape;
            var cpx2 = shape.cpx2;
            var cpy2 = shape.cpy2;
            if (cpx2 === null || cpy2 === null) {
                return [
                    quadraticAt(shape.x1, shape.cpx1, shape.x2, p),
                    quadraticAt(shape.y1, shape.cpy1, shape.y2, p)
                ];
            }
            else {
                return [
                    cubicAt(shape.x1, shape.cpx1, shape.cpx1, shape.x2, p),
                    cubicAt(shape.y1, shape.cpy1, shape.cpy1, shape.y2, p)
                ];
            }
        }
    });
});

/**
 * 圆弧
 * @module zrender/graphic/shape/Arc
 */
 define('zrender/graphic/shape/Arc',['require','../Path'],function (require) {

    return require('../Path').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 = shape.r;
            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);
        }
    })
});
define('zrender/graphic/LinearGradient',['require','../core/util','./Gradient'],function(require) {


    var zrUtil = require('../core/util');

    var Gradient = require('./Gradient');

    /**
     * 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
     */
    var LinearGradient = function (x, y, x2, y2, colorStops) {
        this.x = x == null ? 0 : x;

        this.y = y == null ? 0 : y;

        this.x2 = x2 == null ? 1 : x2;

        this.y2 = y2 == null ? 0 : y2;

        Gradient.call(this, colorStops);
    };

    LinearGradient.prototype = {

        constructor: LinearGradient,

        type: 'linear',

        updateCanvasGradient: function (shape, ctx) {
            var rect = shape.getBoundingRect();
            // var size =
            var x = this.x * rect.width + rect.x;
            var x2 = this.x2 * rect.width + rect.x;
            var y = this.y * rect.height + rect.y;
            var y2 = this.y2 * rect.height + rect.y;

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

            var colorStops = this.colorStops;
            for (var i = 0; i < colorStops.length; i++) {
                canvasGradient.addColorStop(
                    colorStops[i].offset, colorStops[i].color
                );
            }

            this.canvasGradient = canvasGradient;
        }

    };

    zrUtil.inherits(LinearGradient, Gradient);

    return LinearGradient;
});
define('zrender/graphic/RadialGradient',['require','../core/util','./Gradient'],function(require) {


    var zrUtil = require('../core/util');

    var Gradient = require('./Gradient');

    /**
     * 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]
     */
    var RadialGradient = function (x, y, r, colorStops) {
        this.x = x == null ? 0.5 : x;

        this.y = y == null ? 0.5 : y;

        this.r = r == null ? 0.5 : r;

        Gradient.call(this, colorStops);
    };

    RadialGradient.prototype = {

        constructor: RadialGradient,

        type: 'radial',

        updateCanvasGradient: function (shape, ctx) {
            var rect = shape.getBoundingRect();

            var width = rect.width;
            var height = rect.height;
            var min = Math.min(width, height);
            // var max = Math.max(width, height);

            var x = this.x * width + rect.x;
            var y = this.y * height + rect.y;
            var r = this.r * min;

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

            var colorStops = this.colorStops;
            for (var i = 0; i < colorStops.length; i++) {
                canvasGradient.addColorStop(
                    colorStops[i].offset, colorStops[i].color
                );
            }

            this.canvasGradient = canvasGradient;
        }
    };

    zrUtil.inherits(RadialGradient, Gradient);

    return RadialGradient;
});
define('echarts/util/graphic',['require','zrender/core/util','zrender/tool/path','zrender/graphic/Path','zrender/tool/color','zrender/core/matrix','zrender/core/vector','zrender/graphic/Gradient','zrender/container/Group','zrender/graphic/Image','zrender/graphic/Text','zrender/graphic/shape/Circle','zrender/graphic/shape/Sector','zrender/graphic/shape/Polygon','zrender/graphic/shape/Polyline','zrender/graphic/shape/Rect','zrender/graphic/shape/Line','zrender/graphic/shape/BezierCurve','zrender/graphic/shape/Arc','zrender/graphic/LinearGradient','zrender/graphic/RadialGradient'],function(require) {



    var zrUtil = require('zrender/core/util');

    var pathTool = require('zrender/tool/path');
    var round = Math.round;
    var Path = require('zrender/graphic/Path');
    var colorTool = require('zrender/tool/color');
    var matrix = require('zrender/core/matrix');
    var vector = require('zrender/core/vector');
    var Gradient = require('zrender/graphic/Gradient');

    var graphic = {};

    graphic.Group = require('zrender/container/Group');

    graphic.Image = require('zrender/graphic/Image');

    graphic.Text = require('zrender/graphic/Text');

    graphic.Circle = require('zrender/graphic/shape/Circle');

    graphic.Sector = require('zrender/graphic/shape/Sector');

    graphic.Polygon = require('zrender/graphic/shape/Polygon');

    graphic.Polyline = require('zrender/graphic/shape/Polyline');

    graphic.Rect = require('zrender/graphic/shape/Rect');

    graphic.Line = require('zrender/graphic/shape/Line');

    graphic.BezierCurve = require('zrender/graphic/shape/BezierCurve');

    graphic.Arc = require('zrender/graphic/shape/Arc');

    graphic.LinearGradient = require('zrender/graphic/LinearGradient');

    graphic.RadialGradient = require('zrender/graphic/RadialGradient');

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

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

    /**
     * @private
     */
    function doSingleEnterHover(el) {
        if (el.__isHover) {
            return;
        }
        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
                || (fill instanceof Gradient ? fill : colorTool.lift(fill, -0.1));
            hoverStyle.stroke = hoverStyle.stroke
                || (stroke instanceof Gradient ? stroke : colorTool.lift(stroke, -0.1));

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

            el.__normalStl = normalStyle;

            el.__hoverStlDirty = false;
        }
        el.setStyle(el.__hoverStl);
        el.z2 += 1;

        el.__isHover = true;
    }

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

        var normalStl = el.__normalStl;
        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;
    }

    /**
     * @inner
     */
    function onElementMouseOver() {
        // Only if element is not in emphasis status
        !this.__isEmphasis && doEnterHover(this);
    }

    /**
     * @inner
     */
    function onElementMouseOut() {
        // 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
     * @param {module:zrender/Element} el
     * @param {Object} [hoverStyle]
     */
    graphic.setHoverStyle = function (el, hoverStyle) {
        hoverStyle = hoverStyle || {};
        el.type === 'group'
            ? el.traverse(function (child) {
                if (child.type !== 'group') {
                    setElementHoverStl(child, hoverStyle);
                }
            })
            : setElementHoverStl(el, hoverStyle);
        // Remove previous bound handlers
        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 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,
            textFill: textStyleModel.getTextColor() || labelColor
        });
    };

    function animateOrSetProps(isUpdate, el, props, animatableModel, cb) {
        var postfix = isUpdate ? 'Update' : '';
        var duration = animatableModel
            && animatableModel.getShallow('animationDuration' + postfix);
        var animationEasing = animatableModel
            && animatableModel.getShallow('animationEasing' + postfix);

        animatableModel && animatableModel.getShallow('animation')
            ? el.animateTo(props, duration, animationEasing, cb)
            : (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 {Function} cb
     */
    graphic.updateProps = zrUtil.curry(animateOrSetProps, true);

    /**
     * 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 {Function} cb
     */
    graphic.initProps = zrUtil.curry(animateOrSetProps, false);

    /**
     * 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>} vertex [x, y]
     * @param {Array.<number>} transform Transform matrix: like [1, 0, 0, 1, 0, 0]
     * @param {boolean=} invert Whether use invert matrix.
     * @return {Array.<number>} [x, y]
     */
    graphic.applyTransform = function (vertex, transform, invert) {
        if (invert) {
            transform = matrix.invert([], transform);
        }
        return vector.applyTransform([], vertex, 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');
    };

    return graphic;
});
/**
 * echarts设备环境识别
 *
 * @desc echarts基于Canvas，纯Javascript图表库，提供直观，生动，可交互，可个性化定制的数据统计图表。
 * @author firede[firede@firede.us]
 * @desc thanks zepto.
 */
define('zrender/core/env',[],function() {

    if (typeof navigator === 'undefined') {
        // In node
        return {
            browser: {},
            os: {},
            node: true,
            // Assume canvas is supported
            canvasSupported: true
        }
    }
    // Zepto.js
    // (c) 2010-2013 Thomas Fuchs
    // Zepto.js may be freely distributed under the MIT license.

    function detect(ua) {
        var os = this.os = {};
        var browser = this.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 ie = ua.match(/MSIE ([\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.]+)/);

        // 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 (ie) browser.ie = true, browser.version = ie[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];

        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 || blackberry || bb10 ||
            (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
        };
    }

    return detect(navigator.userAgent);
});
/**
 * 事件辅助类
 * @module zrender/core/event
 * @author Kener (@Kener-林峰, kener.linfeng@gmail.com)
 */
define('zrender/core/event',['require','../mixin/Eventful'],function(require) {



    var Eventful = require('../mixin/Eventful');

    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};
    }
    /**
     * 如果存在第三方嵌入的一些dom触发的事件，或touch事件，需要转换一下事件坐标
     */
    function normalizeEvent(el, e) {

        e = e || window.event;

        if (e.zrX != null) {
            return e;
        }

        var eventType = e.type;
        var isTouch = eventType && eventType.indexOf('touch') >= 0;

        if (!isTouch) {
            // https://gist.github.com/electricg/4435259
            var mouseX = 0;
            var mouseY = 0;

            if (e.pageX || e.pageY) {
                mouseX = e.pageX;
                mouseY = e.pageY;
            }
            else {
                mouseX = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
                mouseY = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
            }

            var box = getBoundingClientRect(el);
            var top = box.top + (window.pageYOffset || el.scrollTop) - (el.clientTop || 0);
            var left = box.left + (window.pageXOffset || el.scrollLeft) - (el.clientLeft || 0);
            e.zrX = mouseX - left;
            e.zrY = mouseY - top;
            e.zrDelta = (e.wheelDelta) ? e.wheelDelta / 120 : -(e.detail || 0) / 3;
        }
        else {
            var touch = eventType != 'touchend'
                            ? e.targetTouches[0]
                            : e.changedTouches[0];
            if (touch) {
                var rBounding = getBoundingClientRect(el);
                // touch事件坐标是全屏的~
                e.zrX = touch.clientX - rBounding.left;
                e.zrY = touch.clientY - rBounding.top;
            }
        }

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

    /**
     * 停止冒泡和阻止默认行为
     * @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;
        };

    return {
        normalizeEvent: normalizeEvent,
        addEventListener: addEventListener,
        removeEventListener: removeEventListener,

        stop: stop,
        // 做向上兼容
        Dispatcher: Eventful
    };
});

// TODO Draggable for group
// FIXME Draggable on element which has parent rotation or scale
define('zrender/mixin/Draggable',['require'],function (require) {
    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._dispatchProxy(draggingTarget, '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._dispatchProxy(draggingTarget, 'drag', e.event);

                var dropTarget = this._findHover(x, y, draggingTarget);
                var lastDropTarget = this._dropTarget;
                this._dropTarget = dropTarget;

                if (draggingTarget !== dropTarget) {
                    if (lastDropTarget && dropTarget !== lastDropTarget) {
                        this._dispatchProxy(lastDropTarget, 'dragleave', e.event);
                    }
                    if (dropTarget && dropTarget !== lastDropTarget) {
                        this._dispatchProxy(dropTarget, 'dragenter', e.event);
                    }
                }
            }
        },

        _dragEnd: function (e) {
            var draggingTarget = this._draggingTarget;

            if (draggingTarget) {
                draggingTarget.dragging = false;
            }

            this._dispatchProxy(draggingTarget, 'dragend', e.event);

            if (this._dropTarget) {
                this._dispatchProxy(this._dropTarget, 'drop', e.event);
            }

            this._draggingTarget = null;
            this._dropTarget = null;
        }

    };

    return Draggable;
});
/**
 * Only implements needed gestures for mobile.
 */
define('zrender/core/GestureMgr',['require'],function(require) {



    var GestureMgr = function () {

        /**
         * @private
         * @type {Array.<Object>}
         */
        this._track = [];
    };

    GestureMgr.prototype = {

        constructor: GestureMgr,

        recognize: function (event, target) {
            this._doTrack(event, target);
            return this._recognize(event);
        },

        clear: function () {
            this._track.length = 0;
            return this;
        },

        _doTrack: function (event, target) {
            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];
                trackItem.points.push([touch.clientX, touch.clientY]);
                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.
    };

    return GestureMgr;
});

/**
 * Handler控制模块
 * @module zrender/Handler
 * @author Kener (@Kener-林峰, kener.linfeng@gmail.com)
 *         errorrik (errorrik@gmail.com)
 *         pissang (shenyi.914@gmail.com)
 */
define('zrender/Handler',['require','./core/env','./core/event','./core/util','./mixin/Draggable','./core/GestureMgr','./mixin/Eventful'],function (require) {



    var env = require('./core/env');
    var eventTool = require('./core/event');
    var util = require('./core/util');
    var Draggable = require('./mixin/Draggable');
    var GestureMgr = require('./core/GestureMgr');

    var Eventful = require('./mixin/Eventful');

    var domHandlerNames = [
        'click', 'dblclick',
        'mousewheel', 'mousemove', 'mouseout', 'mouseup', 'mousedown'
    ];

    var touchHandlerNames = [
        'touchstart', 'touchend', 'touchmove'
    ];

    var TOUCH_CLICK_DELAY = 300;

    // touch指尖错觉的尝试偏移量配置
    // var MOBILE_TOUCH_OFFSETS = [
    //     { x: 10 },
    //     { x: -20 },
    //     { x: 10, y: 10 },
    //     { y: -20 }
    // ];

    var addEventListener = eventTool.addEventListener;
    var removeEventListener = eventTool.removeEventListener;
    var normalizeEvent = eventTool.normalizeEvent;

    function proxyEventName(name) {
        return '_' + name + 'Handler';
    }

    function makeEventPacket(eveType, target, event) {
        return {
            type: eveType,
            event: event,
            target: target,
            cancelBubble: false,
            offsetX: event.zrX,
            offsetY: event.zrY,
            gestureEvent: event.gestureEvent,
            pinchX: event.pinchX,
            pinchY: event.pinchY,
            pinchScale: event.pinchScale,
            wheelDelta: event.zrDelta
        };
    }

    var domHandlers = {
        /**
         * Mouse move handler
         * @inner
         * @param {Event} event
         */
        mousemove: function (event) {
            event = normalizeEvent(this.root, event);

            var x = event.zrX;
            var y = event.zrY;

            var hovered = this._findHover(x, y, null);
            var lastHovered = this._hovered;

            this._hovered = hovered;

            this.root.style.cursor = hovered ? hovered.cursor : this._defaultCursorStyle;
            // Mouse out on previous hovered element
            if (lastHovered && hovered !== lastHovered && lastHovered.__zr) {
                this._dispatchProxy(lastHovered, 'mouseout', event);
            }

            // Mouse moving on one element
            this._dispatchProxy(hovered, 'mousemove', event);

            // Mouse over on a new element
            if (hovered && hovered !== lastHovered) {
                this._dispatchProxy(hovered, 'mouseover', event);
            }
        },

        /**
         * Mouse out handler
         * @inner
         * @param {Event} event
         */
        mouseout: function (event) {
            event = normalizeEvent(this.root, event);

            var element = event.toElement || event.relatedTarget;
            if (element != this.root) {
                while (element && element.nodeType != 9) {
                    // 忽略包含在root中的dom引起的mouseOut
                    if (element === this.root) {
                        return;
                    }

                    element = element.parentNode;
                }
            }

            this._dispatchProxy(this._hovered, 'mouseout', event);

            this.trigger('globalout', {
                event: event
            });
        },

        /**
         * Touch开始响应函数
         * @inner
         * @param {Event} event
         */
        touchstart: function (event) {
            // FIXME
            // 移动端可能需要default行为，例如静态图表时。
            // eventTool.stop(event);// 阻止浏览器默认事件，重要
            event = normalizeEvent(this.root, event);

            this._lastTouchMoment = new Date();

            processGesture(this, event, 'start');

            // 平板补充一次findHover
            // this._mobileFindFixed(event);
            // Trigger mousemove and mousedown
            this._mousemoveHandler(event);

            this._mousedownHandler(event);
        },

        /**
         * Touch移动响应函数
         * @inner
         * @param {Event} event
         */
        touchmove: function (event) {
            // eventTool.stop(event);// 阻止浏览器默认事件，重要
            event = normalizeEvent(this.root, event);

            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.
            this._mousemoveHandler(event);
        },

        /**
         * Touch结束响应函数
         * @inner
         * @param {Event} event
         */
        touchend: function (event) {
            // eventTool.stop(event);// 阻止浏览器默认事件，重要
            event = normalizeEvent(this.root, event);

            processGesture(this, event, 'end');

            this._mouseupHandler(event);

            // 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) {
                // this._mobileFindFixed(event);
                this._clickHandler(event);
            }
        }
    };

    // Common handlers
    util.each(['click', 'mousedown', 'mouseup', 'mousewheel', 'dblclick'], function (name) {
        domHandlers[name] = function (event) {
            event = normalizeEvent(this.root, 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, null);
            this._dispatchProxy(hovered, name, event);
        };
    });

    function processGesture(zrHandler, event, stage) {
        var gestureMgr = zrHandler._gestureMgr;

        stage === 'start' && gestureMgr.clear();

        var gestureInfo = gestureMgr.recognize(
            event,
            zrHandler._findHover(event.zrX, event.zrY, null)
        );

        stage === 'end' && gestureMgr.clear();

        if (gestureInfo) {
            // eventTool.stop(event);
            var type = gestureInfo.type;
            event.gestureEvent = type;

            zrHandler._dispatchProxy(gestureInfo.target, type, gestureInfo.event);
        }
    }

    /**
     * 为控制类实例初始化dom 事件处理函数
     *
     * @inner
     * @param {module:zrender/Handler} instance 控制类实例
     */
    function initDomHandler(instance) {
        var handlerNames = domHandlerNames.concat(touchHandlerNames);
        var len = handlerNames.length;
        while (len--) {
            var name = handlerNames[len];
            instance[proxyEventName(name)] = util.bind(domHandlers[name], instance);
        }
    }

    /**
     * @alias module:zrender/Handler
     * @constructor
     * @extends module:zrender/mixin/Eventful
     * @param {HTMLElement} root 绘图区域
     * @param {module:zrender/Storage} storage Storage实例
     * @param {module:zrender/Painter} painter Painter实例
     */
    var Handler = function(root, storage, painter) {
        Eventful.call(this);

        this.root = root;
        this.storage = storage;
        this.painter = painter;

        /**
         * @private
         */
        this._hovered;
        /**
         * @private
         */
        this._lastTouchMoment;
        /**
         * @private
         */
        this._lastX;
        /**
         * @private
         */
        this._lastY;
        /**
         * @private
         */
        this._defaultCursorStyle = 'default'
        /**
         * @private
         */
        this._gestureMgr = new GestureMgr();

        initDomHandler(this);

        if (env.os.tablet || env.os.phone) {
            // mobile支持
            // mobile的click/move/up/down自己模拟
            util.each(touchHandlerNames, function (name) {
                addEventListener(root, name, this[proxyEventName(name)]);
            }, this);

            addEventListener(root, 'mouseout', this._mouseoutHandler);
        }
        else {
            util.each(domHandlerNames, function (name) {
                addEventListener(root, name, this[proxyEventName(name)]);
            }, this);
            // Firefox
            addEventListener(root, 'DOMMouseScroll', this._mousewheelHandler);
        }

        Draggable.call(this);
    };

    Handler.prototype = {

        constructor: Handler,

        /**
         * Resize
         */
        resize: function (event) {
            this._hovered = null;
        },

        /**
         * Dispatch event
         * @param {string} eventName
         * @param {event=} eventArgs
         */
        dispatch: function (eventName, eventArgs) {
            var handler = this[proxyEventName(eventName)];
            handler && handler(eventArgs);
        },

        /**
         * Dispose
         */
        dispose: function () {
            var root = this.root;

            var handlerNames = domHandlerNames.concat(touchHandlerNames);

            for (var i = 0; i < handlerNames.length; i++) {
                var name = handlerNames[i];
                removeEventListener(root, name, this[proxyEventName(name)]);
            }

            // Firefox
            removeEventListener(root, 'DOMMouseScroll', this._mousewheelHandler);

            this.root =
            this.storage =
            this.painter = null;
        },

        /**
         * 设置默认的cursor style
         * @param {string} cursorStyle 例如 crosshair
         */
        setDefaultCursorStyle: function (cursorStyle) {
            this._defaultCursorStyle = cursorStyle;
        },

        /**
         * 事件分发代理
         *
         * @private
         * @param {Object} targetEl 目标图形元素
         * @param {string} eventName 事件名称
         * @param {Object} event 事件对象
         */
        _dispatchProxy: function (targetEl, eventName, event) {
            var eventHandler = 'on' + eventName;
            var eventPacket = makeEventPacket(eventName, targetEl, event);

            var el = targetEl;

            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
         * @method
         */
        _findHover: function(x, y, exclude) {
            var list = this.storage.getDisplayList();
            for (var i = list.length - 1; i >= 0 ; i--) {
                if (!list[i].silent
                 && list[i] !== exclude
                 && isHover(list[i], x, y)) {
                    return list[i];
                }
            }
        }
    };

    function isHover(displayable, x, y) {
        if (displayable[displayable.rectHover ? 'rectContain' : 'contain'](x, y)) {
            var p = displayable.parent;
            while (p) {
                if (p.clipPath && !p.clipPath.contain(x, y))  {
                    // Clipped by parents
                    return false;
                }
                p = p.parent;
            }
            return true;
        }

        return false;
    }

    util.mixin(Handler, Eventful);
    util.mixin(Handler, Draggable);

    return Handler;
});

/**
 * Storage内容仓库模块
 * @module zrender/Storage
 * @author Kener (@Kener-林峰, kener.linfeng@gmail.com)
 * @author errorrik (errorrik@gmail.com)
 * @author pissang (https://github.com/pissang/)
 */
define('zrender/Storage',['require','./core/util','./container/Group'],function (require) {



    var util = require('./core/util');

    var Group = require('./container/Group');

    function shapeCompareFunc(a, b) {
        if (a.zlevel === b.zlevel) {
            if (a.z === b.z) {
                if (a.z2 === b.z2) {
                    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 () {
        // 所有常规形状，id索引的map
        this._elements = {};

        this._roots = [];

        this._displayList = [];

        this._displayListLen = 0;
    };

    Storage.prototype = {

        constructor: Storage,

        /**
         * 返回所有图形的绘制队列
         * @param  {boolean} [update=false] 是否在返回前更新该数组
         * 详见{@link module:zrender/graphic/Displayable.prototype.updateDisplayList}
         * @return {Array.<module:zrender/graphic/Displayable>}
         */
        getDisplayList: function (update) {
            if (update) {
                this.updateDisplayList();
            }
            return this._displayList;
        },

        /**
         * 更新图形的绘制队列。
         * 每次绘制前都会调用，该方法会先深度优先遍历整个树，更新所有Group和Shape的变换并且把所有可见的Shape保存到数组中，
         * 最后根据绘制的优先级（zlevel > z > 插入顺序）排序得到绘制队列
         */
        updateDisplayList: function () {
            this._displayListLen = 0;
            var roots = this._roots;
            var displayList = this._displayList;
            for (var i = 0, len = roots.length; i < len; i++) {
                var root = roots[i];
                this._updateAndAddDisplayable(root);
            }
            displayList.length = this._displayListLen;

            for (var i = 0, len = displayList.length; i < len; i++) {
                displayList[i].__renderidx = i;
            }

            displayList.sort(shapeCompareFunc);
        },

        _updateAndAddDisplayable: function (el, clipPaths) {

            if (el.ignore) {
                return;
            }

            el.beforeUpdate();

            el.update();

            el.afterUpdate();

            var clipPath = el.clipPath;
            if (clipPath) {
                // clipPath 的变换是基于 group 的变换
                clipPath.parent = el;
                clipPath.updateTransform();

                // FIXME 效率影响
                if (clipPaths) {
                    clipPaths = clipPaths.slice();
                    clipPaths.push(clipPath);
                }
                else {
                    clipPaths = [clipPath];
                }
            }

            if (el.type == 'group') {
                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 ?
                    child.__dirty = el.__dirty || child.__dirty;

                    this._updateAndAddDisplayable(child, clipPaths);
                }

                // 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) {
            // Element has been added
            if (this._elements[el.id]) {
                return;
            }

            if (el instanceof Group) {
                el.addChildrenToStorage(this);
            }

            this.addToMap(el);
            this._roots.push(el);
        },

        /**
         * 删除指定的图形(Shape)或者组(Group)
         * @param {string|Array.<string>} [elId] 如果为空清空整个Storage
         */
        delRoot: function (elId) {
            if (elId == null) {
                // 不指定elId清空
                for (var i = 0; i < this._roots.length; i++) {
                    var root = this._roots[i];
                    if (root instanceof Group) {
                        root.delChildrenFromStorage(this);
                    }
                }

                this._elements = {};
                this._roots = [];
                this._displayList = [];
                this._displayListLen = 0;

                return;
            }

            if (elId instanceof Array) {
                for (var i = 0, l = elId.length; i < l; i++) {
                    this.delRoot(elId[i]);
                }
                return;
            }

            var el;
            if (typeof(elId) == 'string') {
                el = this._elements[elId];
            }
            else {
                el = elId;
            }

            var idx = util.indexOf(this._roots, el);
            if (idx >= 0) {
                this.delFromMap(el.id);
                this._roots.splice(idx, 1);
                if (el instanceof Group) {
                    el.delChildrenFromStorage(this);
                }
            }
        },

        addToMap: function (el) {
            if (el instanceof Group) {
                el.__storage = this;
            }
            el.dirty();

            this._elements[el.id] = el;

            return this;
        },

        get: function (elId) {
            return this._elements[elId];
        },

        delFromMap: function (elId) {
            var elements = this._elements;
            var el = elements[elId];
            if (el) {
                delete elements[elId];
                if (el instanceof Group) {
                    el.__storage = null;
                }
            }

            return this;
        },

        /**
         * 清空并且释放Storage
         */
        dispose: function () {
            this._elements =
            this._renderList =
            this._roots = null;
        }
    };

    return Storage;
});

/**
 * 动画主类, 调度和管理所有动画控制器
 *
 * @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
define('zrender/animation/Animation',['require','../core/util','../core/event','./Animator'],function(require) {



    var util = require('../core/util');
    var Dispatcher = require('../core/event').Dispatcher;

    var requestAnimationFrame = (typeof window !== 'undefined' &&
                                    (window.requestAnimationFrame
                                    || window.msRequestAnimationFrame
                                    || window.mozRequestAnimationFrame
                                    || window.webkitRequestAnimationFrame))
                                || function (func) {
                                    setTimeout(func, 16);
                                };

    var Animator = require('./Animator');
    /**
     * @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 = 0;

        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();
            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);
                // 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();
            }
        },
        /**
         * 开始运行动画
         */
        start: function () {
            var self = this;

            this._running = true;

            function step() {
                if (self._running) {

                    requestAnimationFrame(step);

                    self._update();
                }
            }

            this._time = new Date().getTime();
            requestAnimationFrame(step);
        },
        /**
         * 停止运行动画
         */
        stop: function () {
            this._running = 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}
         */
        animate: function (target, options) {
            options = options || {};
            var animator = new Animator(
                target,
                options.loop,
                options.getter,
                options.setter
            );

            return animator;
        }
    };

    util.mixin(Animation, Dispatcher);

    return Animation;
});

/**
 * @module zrender/Layer
 * @author pissang(https://www.github.com/pissang)
 */
define('zrender/Layer',['require','./core/util','./config'],function (require) {

    var util = require('./core/util');
    var config = require('./config');

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

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

            var dpr = this.dpr;
            if (dpr != 1) {
                this.ctx.scale(dpr, 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 (dpr != 1) {
                this.ctx.scale(dpr, 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 haveClearColor = 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 / dpr, height / dpr);
            if (haveClearColor) {
                ctx.save();
                ctx.fillStyle = this.clearColor;
                ctx.fillRect(0, 0, width / dpr, height / dpr);
                ctx.restore();
            }

            if (haveMotionBLur) {
                var domBack = this.domBack;
                ctx.save();
                ctx.globalAlpha = lastFrameAlpha;
                ctx.drawImage(domBack, 0, 0, width / dpr, height / dpr);
                ctx.restore();
            }
        }
    };

    return Layer;
});
/**
 * Default canvas painter
 * @module zrender/Painter
 * @author Kener (@Kener-林峰, kener.linfeng@gmail.com)
 *         errorrik (errorrik@gmail.com)
 *         pissang (https://www.github.com/pissang)
 */
 define('zrender/Painter',['require','./config','./core/util','./core/log','./core/BoundingRect','./Layer','./graphic/Image'],function (require) {


    var config = require('./config');
    var util = require('./core/util');
    var log = require('./core/log');
    var BoundingRect = require('./core/BoundingRect');

    var Layer = require('./Layer');

    function parseInt10(val) {
        return parseInt(val, 10);
    }

    function isLayerValid(layer) {
        if (!layer) {
            return false;
        }

        if (layer.isBuildin) {
            return true;
        }

        if (typeof(layer.resize) !== 'function'
            || typeof(layer.refresh) !== 'function'
        ) {
            return false;
        }

        return true;
    }

    function preProcessLayer(layer) {
        layer.__unusedCount++;
    }

    function postProcessLayer(layer) {
        layer.__dirty = false;
        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 || (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];
            var m;
            if (clipPath.transform) {
                m = clipPath.transform;
                ctx.transform(
                    m[0], m[1],
                    m[2], m[3],
                    m[4], m[5]
                );
            }
            var path = clipPath.path;
            path.beginPath(ctx);
            clipPath.buildPath(path, clipPath.shape);
            ctx.clip();
            // Transform back
            if (clipPath.transform) {
                m = clipPath.invTransform;
                ctx.transform(
                    m[0], m[1],
                    m[2], m[3],
                    m[4], m[5]
                );
            }
        }
    }

    /**
     * @alias module:zrender/Painter
     * @constructor
     * @param {HTMLElement} root 绘图容器
     * @param {module:zrender/Storage} storage
     * @param {Ojbect} opts
     */
    var Painter = function (root, storage, opts) {
        var singleCanvas = !root.nodeName // In node ?
            || root.nodeName.toUpperCase() === 'CANVAS';

        opts = opts || {};

        /**
         * @type {number}
         */
        this.dpr = opts.devicePixelRatio || config.devicePixelRatio;
        /**
         * @type {boolean}
         * @private
         */
        this._singleCanvas = singleCanvas;
        /**
         * 绘图容器
         * @type {HTMLElement}
         */
        this.root = root;

        var rootStyle = root.style;

        // In node environment using node-canvas
        if (rootStyle) {
            rootStyle['-webkit-tap-highlight-color'] = 'transparent';
            rootStyle['-webkit-user-select'] = 'none';
            rootStyle['user-select'] = 'none';
            rootStyle['-webkit-touch-callout'] = 'none';

            root.innerHTML = '';
        }

        /**
         * @type {module:zrender/Storage}
         */
        this.storage = storage;

        if (!singleCanvas) {
            var width = this._getWidth();
            var height = this._getHeight();
            this._width = width;
            this._height = height;

            var domRoot = document.createElement('div');
            this._domRoot = domRoot;
            var domRootStyle = domRoot.style;

            // domRoot.onselectstart = returnFalse; // 避免页面选中的尴尬
            domRootStyle.position = 'relative';
            domRootStyle.overflow = 'hidden';
            domRootStyle.width = this._width + 'px';
            domRootStyle.height = this._height + 'px';
            root.appendChild(domRoot);

            /**
             * @type {Object.<key, module:zrender/Layer>}
             * @private
             */
            this._layers = {};
            /**
             * @type {Array.<number>}
             * @private
             */
            this._zlevelList = [];
        }
        else {
            // 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);
            this._layers = {
                0: mainLayer
            };
            this._zlevelList = [0];
        }

        this._layerConfig = {};

        this.pathToImage = this._createPathToImage();
    };

    Painter.prototype = {

        constructor: Painter,

        /**
         * If painter use a single canvas
         * @return {boolean}
         */
        isSingleCanvas: function () {
            return this._singleCanvas;
        },
        /**
         * @return {HTMLDivElement}
         */
        getViewportRoot: function () {
            return this._singleCanvas ? this._layers[0].dom : 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.isBuildin && layer.refresh) {
                    layer.refresh();
                }
            }

            return this;
        },

        _paintList: function (list, paintAll) {

            if (paintAll == null) {
                paintAll = false;
            }

            this._updateLayerStatus(list);

            var currentLayer;
            var currentZLevel;
            var ctx;

            var viewWidth = this._width;
            var viewHeight = this._height;

            this.eachBuildinLayer(preProcessLayer);

            // var invTransform = [];
            var prevElClipPaths = null;

            for (var i = 0, l = list.length; i < l; i++) {
                var el = list[i];
                var elZLevel = this._singleCanvas ? 0 : el.zlevel;
                // Change draw layer
                if (currentZLevel !== elZLevel) {
                    // Only 0 zlevel if only has one canvas
                    currentZLevel = elZLevel;
                    currentLayer = this.getLayer(currentZLevel);

                    if (!currentLayer.isBuildin) {
                        log(
                            'ZLevel ' + currentZLevel
                            + ' has been used by unkown layer ' + currentLayer.id
                        );
                    }

                    ctx = currentLayer.ctx;

                    // Reset the count
                    currentLayer.__unusedCount = 0;

                    if (currentLayer.__dirty || paintAll) {
                        currentLayer.clear();
                    }
                }

                if (
                    (currentLayer.__dirty || paintAll)
                    // 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
                    && el.scale[0] && el.scale[1]
                    // Ignore culled element
                    && !(el.culling && isDisplayableCulled(el, viewWidth, viewHeight))
                ) {
                    var clipPaths = el.__clipPaths;

                    // Optimize when clipping on group with several elements
                    if (isClipPathChanged(clipPaths, prevElClipPaths)) {
                        // If has previous clipping state, restore from it
                        if (prevElClipPaths) {
                            ctx.restore();
                        }
                        // New clipping state
                        if (clipPaths) {
                            ctx.save();
                            doClip(clipPaths, ctx);
                        }
                        prevElClipPaths = clipPaths;
                    }
                    // TODO Use events ?
                    el.beforeBrush && el.beforeBrush(ctx);
                    el.brush(ctx, false);
                    el.afterBrush && el.afterBrush(ctx);
                }

                el.__dirty = false;
            }

            // If still has clipping state
            if (prevElClipPaths) {
                ctx.restore();
            }

            this.eachBuildinLayer(postProcessLayer);
        },

        /**
         * 获取 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.isBuildin = 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);

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

            layersMap[zlevel] = layer;
        },

        // 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
        eachBuildinLayer: 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.isBuildin) {
                    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.isBuildin) {
                    cb.call(context, layer, z);
                }
            }
        },

        /**
         * 获取所有已创建的层
         * @param {Array.<module:zrender/Layer>} [prevLayer]
         */
        getLayers: function () {
            return this._layers;
        },

        _updateLayerStatus: function (list) {

            var layers = this._layers;

            var elCounts = {};

            this.eachBuildinLayer(function (layer, z) {
                elCounts[z] = layer.elCount;
                layer.elCount = 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];
                if (layer) {
                    layer.elCount++;
                    // 已经被标记为需要刷新
                    if (layer.__dirty) {
                        continue;
                    }
                    layer.__dirty = el.__dirty;
                }
            }

            // 层中的元素数量有发生变化
            this.eachBuildinLayer(function (layer, z) {
                if (elCounts[z] !== layer.elCount) {
                    layer.__dirty = true;
                }
            });
        },

        /**
         * 清除hover层外所有内容
         */
        clear: function () {
            this.eachBuildinLayer(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';

            width = width || this._getWidth();
            height = height || this._getHeight();

            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) {
                    this._layers[id].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();

            var ctx = imageLayer.ctx;
            imageLayer.clearColor = opts.backgroundColor;
            imageLayer.clear();

            var displayList = this.storage.getDisplayList(true);

            for (var i = 0; i < displayList.length; i++) {
                var el = displayList[i];
                if (!el.invisible) {
                    el.beforeBrush && el.beforeBrush(ctx);
                    // TODO Check image cross origin
                    el.brush(ctx, false);
                    el.afterBrush && el.afterBrush(ctx);
                }
            }

            return imageLayer.dom;
        },
        /**
         * 获取绘图区域宽度
         */
        getWidth: function () {
            return this._width;
        },

        /**
         * 获取绘图区域高度
         */
        getHeight: function () {
            return this._height;
        },

        _getWidth: function () {
            var root = this.root;
            var stl = document.defaultView.getComputedStyle(root);

            // FIXME Better way to get the width and height when element has not been append to the document
            return ((root.clientWidth || parseInt10(stl.width) || parseInt10(root.style.width))
                    - (parseInt10(stl.paddingLeft) || 0)
                    - (parseInt10(stl.paddingRight) || 0)) | 0;
        },

        _getHeight: function () {
            var root = this.root;
            var stl = document.defaultView.getComputedStyle(root);

            return ((root.clientHeight || parseInt10(stl.height) || parseInt10(root.style.height))
                    - (parseInt10(stl.paddingTop) || 0)
                    - (parseInt10(stl.paddingBottom) || 0)) | 0;
        },

        _pathToImage: function (id, path, width, height, dpr) {
            var canvas = document.createElement('canvas');
            var ctx = canvas.getContext('2d');

            canvas.width = width * dpr;
            canvas.height = height * dpr;

            ctx.clearRect(0, 0, width * dpr, height * dpr);

            var pathTransform = {
                position : path.position,
                rotation : path.rotation,
                scale : path.scale
            };
            path.position = [0, 0, 0];
            path.rotation = 0;
            path.scale = [1, 1];
            if (path) {
                path.brush(ctx);
            }

            var ImageShape = require('./graphic/Image');
            var imgShape = new ImageShape({
                id : id,
                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;
        },

        _createPathToImage: function () {
            var me = this;

            return function (id, e, width, height) {
                return me._pathToImage(
                    id, e, width, height, me.dpr
                );
            };
        }
    };

    return Painter;
});

/*!
 * 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
define('zrender/zrender',['require','./core/guid','./core/env','./Handler','./Storage','./animation/Animation','./Painter'],function(require) {
    var guid = require('./core/guid');
    var env = require('./core/env');

    var Handler = require('./Handler');
    var Storage = require('./Storage');
    var Animation = require('./animation/Animation');

    var useVML = !env.canvasSupported;

    var painterCtors = {
        canvas: require('./Painter')
    };

    var instances = {};    // ZRender实例map索引

    var zrender = {};
    /**
     * @type {string}
     */
    zrender.version = '3.0.0';

    /**
     * @param {HTMLElement} dom
     * @param {Object} opts
     * @param {string} [opts.renderer='canvas'] 'canvas' or 'svg'
     * @param {number} [opts.devicePixelRatio]
     * @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) {
                instances[key].dispose();
            }
            instances = {};
        }

        return zrender;
    };

    /**
     * 获取zrender实例
     * @param {string} id ZRender对象索引
     * @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]
     */
    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;
        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;
        // VML 下为了性能可能会直接操作 VMLRoot 的位置
        // 因此鼠标的相对位置应该是相对于 VMLRoot
        // PENDING
        if (!env.node) {
            this.handler = new Handler(painter.getViewportRoot(), storage, painter);
        }

        /**
         * @type {module:zrender/animation/Animation}
         */
        this.animation = new Animation({
            stage: {
                update: function () {
                    if (self._needsRefresh) {
                        self.refreshImmediately();
                    }
                }
            }
        });
        this.animation.start();

        /**
         * @type {boolean}
         * @private
         */
        this._needsRefresh;

        // 修改 storage.delFromMap, 每次删除元素之前删除动画
        // FIXME 有点ugly
        var oldDelFromMap = storage.delFromMap;
        var oldAddToMap = storage.addToMap;

        storage.delFromMap = function (elId) {
            var el = storage.get(elId);

            oldDelFromMap.call(storage, elId);

            el && el.removeSelfFromZr(self);
        };

        storage.addToMap = function (el) {
            oldAddToMap.call(storage, el);

            el.addSelfToZr(self);
        };
    };

    ZRender.prototype = {

        constructor: ZRender,
        /**
         * 获取实例唯一标识
         * @return {string}
         */
        getId: function () {
            return this.id;
        },

        /**
         * 添加元素
         * @param  {string|module:zrender/Element} el
         */
        add: function (el) {
            this.storage.addRoot(el);
            this._needsRefresh = true;
        },

        /**
         * 删除元素
         * @param  {string|module:zrender/Element} el
         */
        remove: function (el) {
            this.storage.delRoot(el);
            this._needsRefresh = true;
        },

        /**
         * 修改指定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) {
            this.painter.configLayer(zLevel, config);
            this._needsRefresh = true;
        },

        /**
         * 视图更新
         */
        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;
        },

        /**
         * 标记视图在浏览器下一帧需要绘制
         */
        refresh: function() {
            this._needsRefresh = true;
        },

        /**
         * 调整视图大小
         */
        resize: function() {
            this.painter.resize();
            this.handler && this.handler.resize();
        },

        /**
         * 停止所有动画
         */
        clearAnimation: function () {
            this.animation.clear();
        },

        /**
         * 获取视图宽度
         */
        getWidth: function() {
            return this.painter.getWidth();
        },

        /**
         * 获取视图高度
         */
        getHeight: function() {
            return this.painter.getHeight();
        },

        /**
         * 图像导出
         * @param {string} type
         * @param {string} [backgroundColor='#fff'] 背景色
         * @return {string} 图片的Base64 url
         */
        toDataURL: function(type, backgroundColor, args) {
            return this.painter.toDataURL(type, backgroundColor, args);
        },

        /**
         * 将常规shape转成image shape
         * @param {module:zrender/shape/Base} e
         * @param {number} width
         * @param {number} height
         */
        pathToImage: function(e, width, height) {
            var id = guid();
            return this.painter.pathToImage(id, e, width, height);
        },

        /**
         * 设置默认的cursor style
         * @param {string} cursorStyle 例如 crosshair
         */
        setDefaultCursorStyle: function (cursorStyle) {
            this.handler.setDefaultCursorStyle(cursorStyle);
        },

        /**
         * 事件绑定
         *
         * @param {string} eventName 事件名称
         * @param {Function} eventHandler 响应函数
         * @param {Object} [context] 响应函数
         */
        on: function(eventName, eventHandler, context) {
            this.handler && this.handler.on(eventName, eventHandler, context);
        },

        /**
         * 事件解绑定，参数为空则解绑所有自定义事件
         *
         * @param {string} eventName 事件名称
         * @param {Function} eventHandler 响应函数
         */
        off: function(eventName, eventHandler) {
            this.handler && this.handler.off(eventName, eventHandler);
        },

        /**
         * 事件触发
         *
         * @param {string} eventName 事件名称，resize，hover，drag，etc
         * @param {event=} event event dom事件对象
         */
        trigger: function (eventName, event) {
            this.handler && this.handler.trigger(eventName, event);
        },


        /**
         * 清除当前ZRender下所有类图的数据和显示，clear后MVC和已绑定事件均还存在在，ZRender可用
         */
        clear: function () {
            this.storage.delRoot();
            this.painter.clear();
        },

        /**
         * 释放当前ZR实例（删除包括dom，数据、显示和事件绑定），dispose后ZR不可用
         */
        dispose: function () {
            this.animation.stop();

            this.clear();
            this.storage.dispose();
            this.painter.dispose();
            this.handler && this.handler.dispose();

            this.animation =
            this.storage =
            this.painter =
            this.handler = null;

            delInstance(this.id);
        }
    };

    return zrender;
});

define('zrender', ['zrender/zrender'], function (main) { return main; });

define('echarts/loading/default',['require','../util/graphic','zrender/core/util'],function (require) {

    var graphic = require('../util/graphic');
    var zrUtil = require('zrender/core/util');
    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}
     */
    return 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;
    };
});
define('echarts/visual/seriesColor',['require','zrender/graphic/Gradient'],function (require) {
    var Gradient = require('zrender/graphic/Gradient');
    return function (seriesType, styleType, ecModel) {
        function encodeColor(seriesModel) {
            var colorAccessPath = [styleType, 'normal', 'color'];
            var colorList = ecModel.get('color');
            var data = seriesModel.getData();
            var color = seriesModel.get(colorAccessPath) // Set in itemStyle
                || colorList[seriesModel.seriesIndex % colorList.length];  // 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))
                        );
                    });
                }

                data.each(function (idx) {
                    var itemModel = data.getItemModel(idx);
                    var color = itemModel.get(colorAccessPath, true);
                    if (color != null) {
                        data.setItemVisual(idx, 'color', color);
                    }
                });
            }
        }
        seriesType ? ecModel.eachSeriesByType(seriesType, encodeColor)
            : ecModel.eachSeries(encodeColor);
    };
});
define('echarts/preprocessor/helper/compatStyle',['require','zrender/core/util'],function (require) {

    var zrUtil = require('zrender/core/util');

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

    return function (seriesOpt) {
        compatItemStyle(seriesOpt);
        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]);
                    }
                }
            }
        }
    };
});
// Compatitable with 2.0
define('echarts/preprocessor/backwardCompat',['require','zrender/core/util','./helper/compatStyle'],function (require) {

    var zrUtil = require('zrender/core/util');
    var compatStyle = require('./helper/compatStyle');

    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;

    return 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);
                });
            }
        });
    };
});
/*!
 * ECharts, a javascript interactive chart library.
 *
 * Copyright (c) 2015, Baidu Inc.
 * All rights reserved.
 *
 * LICENSE
 * https://github.com/ecomfe/echarts/blob/master/LICENSE.txt
 */

/**
 * @module echarts
 */
define('echarts/echarts',['require','./model/Global','./ExtensionAPI','./CoordinateSystem','./model/OptionManager','./model/Component','./model/Series','./view/Component','./view/Chart','./util/graphic','zrender','zrender/core/util','zrender/tool/color','zrender/core/env','zrender/mixin/Eventful','./loading/default','./visual/seriesColor','./preprocessor/backwardCompat','echarts/util/graphic','echarts/util/number','echarts/util/format'],function (require) {

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

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

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

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

    var each = zrUtil.each;

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

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

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

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

        // Get theme by name
        if (typeof theme === 'string') {
            theme = themeStorage[theme];
        }
        /**
         * @type {Object}
         * @private
         */
        this._theme = zrUtil.clone(theme);

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

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

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

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

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

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

        Eventful.call(this);

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

        // Init mouse events
        this._initEvents();

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

    var echartsProto = ECharts.prototype;

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

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

    /**
     * @param {Object} option
     * @param {boolean} notMerge
     * @param {boolean} [notRefreshImmediately=false] Useful when setOption frequently.
     */
    echartsProto.setOption = function (option, notMerge, notRefreshImmediately) {

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

        this._model.setOption(option, optionPreprocessorFuncs);

        updateMethods.prepareAndUpdate.call(this);

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

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

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

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

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

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

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

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

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


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

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

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

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

    var updateMethods = {

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

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

            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.

            processData.call(this, ecModel);

            stackSeriesData.call(this, ecModel);

            this._coordinateSystem.update(ecModel, this._api);

            doLayout.call(this, ecModel, payload);

            doVisualCoding.call(this, ecModel, payload);

            doRender.call(this, ecModel, payload);

            // Set background
            var backgroundColor = ecModel.get('backgroundColor');
            // In IE8
            if (!env.canvasSupported) {
                var colorArr = colorTool.parse(backgroundColor);
                backgroundColor = colorTool.stringify(colorArr, 'rgb');
                if (colorArr[3] === 0) {
                    backgroundColor = 'transparent';
                }
            }

            var painter = this._zr.painter;
            // TODO all use clearColor ?
            if (painter.isSingleCanvas && painter.isSingleCanvas()) {
                this._zr.configLayer(0, {
                    clearColor: backgroundColor
                });
            }
            else {
                backgroundColor = backgroundColor || 'transparent';
                this._dom.style.backgroundColor = backgroundColor;
            }

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

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

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

            doLayout.call(this, ecModel, payload);

            doVisualCoding.call(this, ecModel, payload);

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

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

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

            doVisualCoding.call(this, ecModel, payload);

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

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

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

            doLayout.call(this, ecModel, payload);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        zr.painter.clear();
        zr.add(el);
    };

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

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

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

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

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

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

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

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

    /**
     * Register event
     * @method
     */
    echartsProto.on = registerEventWithLowercaseName;

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

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

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

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

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

    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    var MOUSE_EVENT_NAMES = [
        'click', 'dblclick', 'mouseover', 'mouseout', 'globalout'
    ];
    /**
     * @private
     */
    echartsProto._initEvents = function () {
        var zr = this._zr;
        each(MOUSE_EVENT_NAMES, function (eveName) {
            zr.on(eveName, function (e) {
                var ecModel = this.getModel();
                var el = e.target;
                if (el && el.dataIndex != null) {
                    var hostModel = el.hostModel || ecModel.getSeriesByIndex(el.seriesIndex);
                    var params = hostModel && hostModel.getDataParams(el.dataIndex) || {};
                    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;
    };
    /**
     * Dispose instance
     */
    echartsProto.dispose = function () {
        this._disposed = true;
        var api = this._api;
        var ecModel = this._model;

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

        this._zr.dispose();

        instances[this.id] = null;
    };

    zrUtil.mixin(ECharts, Eventful);

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

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

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

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

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

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


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

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

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

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

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

        // Connecting
        zrUtil.each(eventActionMap, function (actionType, eventType) {
            // FIXME
            chart._messageCenter.on(eventType, function (event) {
                if (connectedGroups[chart.group]) {
                    chart.__connectedActionDispatching = true;
                    for (var id in instances) {
                        var action = chart.makeActionFromEvent(event);
                        var otherChart = instances[id];
                        if (otherChart !== chart && otherChart.group === chart.group) {
                            if (!otherChart.__connectedActionDispatching) {
                                otherChart.dispatchAction(action);
                            }
                        }
                    }
                    chart.__connectedActionDispatching = false;
                }
            });
        });

        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 || groupIdBase++;
            zrUtil.each(charts, function (chart) {
                chart.group = groupId;
            });
        }
        connectedGroups[groupId] = true;
        return groupId;
    };

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

    echarts.graphic = require('echarts/util/graphic');
    echarts.number = require('echarts/util/number');
    echarts.format = require('echarts/util/format');

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

    return echarts;
});
define('echarts', ['echarts/echarts'], function (main) { return main; });

define('echarts/data/DataDiffer',['require'],function(require) {


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

            initIndexMap(oldArr, oldDataIndexMap, oldKeyGetter);
            initIndexMap(newArr, newDataIndexMap, 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 = oldKeyGetter(oldArr[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 key in newDataIndexMap) {
                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 i = 0, len = idx.length; i < len; i++) {
                            this._add && this._add(idx[i]);
                        }
                    }
                }
            }
        }
    };

    function initIndexMap(arr, map, keyGetter) {
        for (var i = 0; i < arr.length; i++) {
            var key = keyGetter(arr[i]);
            var existence = map[key];
            if (existence == null) {
                map[key] = i;
            }
            else {
                if (!existence.length) {
                    map[key] = existence = [existence];
                }
                existence.push(i);
            }
        }
    }

    return DataDiffer;
});
/**
 * List for data storage
 * @module echarts/data/List
 */
define('echarts/data/List',['require','../model/Model','./DataDiffer','zrender/core/util','../util/model'],function (require) {

    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 = require('../model/Model');
    var DataDiffer = require('./DataDiffer');

    var zrUtil = require('zrender/core/util');
    var modelUtil = require('../util/model');
    var isObject = zrUtil.isObject;

    var IMMUTABLE_PROPERTIES = [
        'stackedOn', '_nameList', '_idList', '_rawData'
    ];

    var transferImmuProperties = function (a, b, wrappedMethod) {
        zrUtil.each(IMMUTABLE_PROPERTIES.concat(wrappedMethod || []), function (propName) {
            if (b.hasOwnProperty(propName)) {
                a[propName] = b[propName];
            }
        });
    };

    /**
     * @constructor
     * @alias module:echarts/data/List
     *
     * @param {Array.<string>} dimensions
     *        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,
                    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';
            }
            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;

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

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

    var listProto = List.prototype;

    listProto.type = 'list';

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

        this._rawData = data;

        // Clear
        var storage = this._storage = {};
        var indices = this.indices = [];

        var dimensions = this.dimensions;
        var size = data.length;
        var dimensionInfoMap = this._dimensionInfos;

        var idList = [];
        var nameRepeatCount = {};

        nameList = nameList || [];

        // Init storage
        for (var i = 0; i < dimensions.length; i++) {
            var dimInfo = dimensionInfoMap[dimensions[i]];
            var DataCtor = dataCtors[dimInfo.type];
            storage[dimensions[i]] = new DataCtor(size);
        }

        // Default dim value getter
        dimValueGetter = dimValueGetter || function (dataItem, dimName, dataIndex, dimIndex) {
            var value = modelUtil.getDataItemValue(dataItem);
            return modelUtil.converDataValue(
                zrUtil.isArray(value)
                    ? value[dimIndex]
                    // If value is a single number or something else not array.
                    : value,
                dimensionInfoMap[dimName]
            );
        };

        for (var idx = 0; idx < data.length; idx++) {
            var dataItem = data[idx];
            // 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[idx] = dimValueGetter(dataItem, dim, idx, k);
            }

            indices.push(idx);
        }

        // Use the name in option and create id
        for (var i = 0; i < data.length; i++) {
            var id = '';
            if (!nameList[i]) {
                nameList[i] = data[i].name;
                // Try using the id in option
                id = data[i].id;
            }
            var name = nameList[i] || '';
            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
     * @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];

        var value = storage[dim] && storage[dim][dataIndex];
        var dimensionInfo = this._dimensionInfos[dim];
        // FIXME ordinal data type is not stackable
        if (stack && 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
     */
    listProto.getDataExtent = function (dim, stack) {
        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);
                //     console.log(value);
                // }
                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 of nearest value
     * @param {string|Array.<string>} dim
     * @param {number} value
     * @param {boolean} stack If given value is after stacked
     * @return {number}
     */
    listProto.indexOfNearest = function (dim, value, stack) {
        if (!zrUtil.isArray(dim)) {
            dim = dim ? [dim] : [];
        }
        var storage = this._storage;
        var dimData = storage[dim];

        if (dimData) {
            var minDist = Number.MAX_VALUE;
            var nearestIdx = -1;
            for (var j = 0, lenj = dim.length; j < lenj; j++) {
                for (var i = 0, len = this.count(); i < len; i++) {
                    var dist = Math.abs(this.get(dim[j], i, stack) - value);
                    if (dist <= minDist) {
                        minDist = dist;
                        nearestIdx = i;
                    }
                }
            }
            return nearestIdx;
        }
        return -1;
    };

    /**
     * Get raw data index
     * @param {number} idx
     * @return {number}
     */
    listProto.getRawIndex = function (idx) {
        var rawIdx = this.indices[idx];
        return rawIdx == null ? -1 : rawIdx;
    };

    /**
     * @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 (dimensions, cb, stack, context) {
        if (typeof dimensions === 'function') {
            context = stack;
            stack = cb;
            cb = dimensions;
            dimensions = [];
        }

        dimensions = zrUtil.map(
            normalizeDimensions(dimensions), this.getDimension, this
        );

        var value = [];
        var dimSize = dimensions.length;
        var indices = this.indices;

        context = context || this;

        for (var i = 0; i < indices.length; i++) {
            if (dimSize === 0) {
                cb.call(context, i);
            }
            // Simple optimization
            else if (dimSize === 1) {
                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);
                }
                // 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 === 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;
    };

    /**
     * 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 allDimensions = this.dimensions;
        var list = new List(
            zrUtil.map(allDimensions, this.getDimensionInfo, this),
            this.hostModel
        );

        // Following properties are all immutable.
        // So we can reference to the same value
        var indices = list.indices = this.indices;

        // FIXME If needs stackedOn, value may already been stacked
        transferImmuProperties(list, this, this._wrappedMethods);

        var storage = list._storage = {};
        var thisStorage = this._storage;

        // Init storage
        for (var i = 0; i < allDimensions.length; i++) {
            var dim = allDimensions[i];
            var dimStore = thisStorage[dim];
            if (zrUtil.indexOf(dimensions, dim) >= 0) {
                storage[dim] = new dimStore.constructor(
                    thisStorage[dim].length
                );
            }
            else {
                // Direct copy for other dimensions
                storage[dim] = thisStorage[dim];
            }
        }

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

        return list;
    };

    var temporaryModel = new Model(null);
    // Since temporate model is shared by all data items. So we must make sure it can't be write.
    // PENDING may cause any performance problem?
    // if (Object.freeze) {
    //     Object.freeze(temporaryModel);
    // }
    /**
     * Get model of one data item.
     * It will create a temporary model if value on idx is not an option.
     *
     * @param {number} idx
     * @param {boolean} [createNew=false]
     */
    // FIXME Model proxy ?
    listProto.getItemModel = function (idx, createNew) {
        var model;
        var hostModel = this.hostModel;
        idx = this.indices[idx];
        // Use a temporary model proxy
        // FIXME Create a new one may cause memory leak
        if (createNew) {
            model = new Model(null, hostModel);
        }
        else {
            model = temporaryModel;
        }
        // FIXME If return null when idx not exists
        model.option = this._rawData[idx];
        model.parentModel = hostModel;
        model.ecModel = hostModel.ecModel;
        return model;
    };

    /**
     * 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;
        return new DataDiffer(
            otherList ? otherList.indices : [], this.indices, function (idx) {
                return otherIdList[idx] || (idx + '');
            }, function (idx) {
                return idList[idx] || (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;
    };

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

    /**
     * Get visual property of single data item
     * @param {number} idx
     * @param {string} key
     * @param {boolean} ignoreParent
     */
    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;
    };

    var setItemDataAndSeriesIndex = function (child) {
        child.seriesIndex = this.seriesIndex;
        child.dataIndex = this.dataIndex;
    };
    /**
     * 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.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;

        transferImmuProperties(list, this, this._wrappedMethods);

        list.indices = this.indices.slice();

        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.call(this, res);
        };
    };

    return List;
});
/**
 * Complete dimensions by data (guess dimension).
 */
define('echarts/data/helper/completeDimensions',['require','zrender/core/util'],function (require) {

    var zrUtil = require('zrender/core/util');

    function completeDimensions(dimensions, data, defaultNames) {
        var value0 = retrieveValue(data[0]);
        var dimSize = zrUtil.isArray(value0) && value0.length || 1;

        defaultNames = defaultNames || [];
        for (var i = 0; i < dimSize; i++) {
            if (!dimensions[i]) {
                var name = defaultNames[i] || ('extra' + (i - defaultNames.length));
                dimensions[i] = guessOrdinal(data, i)
                    ? {type: 'ordinal', name: name}
                    : name;
            }
        }

        return dimensions;
    }

    // The rule should not be complex, otherwise user might not
    // be able to known where the data is wrong.
    function guessOrdinal(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];
            if (value != null && isFinite(value)) {
                return false;
            }
            else if (zrUtil.isString(value) && value !== '-') {
                return true;
            }
        }
        return false;
    }

    function retrieveValue(o) {
        return zrUtil.isArray(o) ? o : zrUtil.isObject(o) ? o.value: o;
    }

    return completeDimensions;

});
define('echarts/chart/helper/createListFromArray',['require','../../data/List','../../data/helper/completeDimensions','zrender/core/util','../../util/model'],function(require) {


    var List = require('../../data/List');
    var completeDimensions = require('../../data/helper/completeDimensions');
    var zrUtil = require('zrender/core/util');
    var modelUtil = require('../../util/model');
    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 || [];

        var result = creaters[seriesModel.get('coordinateSystem')](
            data, seriesModel, ecModel
        );
        var dimensions = result.dimensions;
        var categoryAxisModel = result.categoryAxisModel;

        var categoryDimIndex = dimensions[0].type === 'ordinal' ? 0
            : (dimensions[1].type === 'ordinal' ? 1 : -1);

        var list = new List(dimensions, seriesModel);

        var nameList = createNameList(result, data);

        var dimValueGetter = (categoryAxisModel && ifNeedCompleteOrdinalData(data))
            ? function (itemOpt, dimName, dataIndex, dimIndex) {
                // Use dataIndex as ordinal value in categoryAxis
                return dimIndex === categoryDimIndex
                    ? dataIndex
                    : converDataValue(getDataItemValue(itemOpt), dimensions[dimIndex]);
            }
            : function (itemOpt, dimName, dataIndex, dimIndex) {
                var val = getDataItemValue(itemOpt);
                return converDataValue(val && val[dimIndex], dimensions[dimIndex]);
            };

        list.initData(data, nameList, dimValueGetter);

        return list;
    }

    function isStackable(axisType) {
        return axisType !== 'category' && axisType !== 'time';
    }
    /**
     * Creaters for each coord system.
     * @return {Object} {dimensions, categoryAxisModel};
     */
    var creaters = {

        cartesian2d: function (data, seriesModel, ecModel) {
            var xAxisModel = ecModel.getComponent('xAxis', seriesModel.get('xAxisIndex'));
            var yAxisModel = ecModel.getComponent('yAxis', seriesModel.get('yAxisIndex'));
            var xAxisType = xAxisModel.get('type');
            var yAxisType = yAxisModel.get('type');
            var isYAxisCategory = yAxisType === 'category';
            var isXAxisCategory = xAxisType === 'category';

            var dimensions = [{
                name: 'x',
                type: isXAxisCategory ? 'ordinal' : 'float',
                stackable: isStackable(xAxisType)
            }, {
                name: 'y',
                // If two category axes
                type: isYAxisCategory ? 'ordinal' : 'float',
                stackable: isStackable(yAxisType)
            }];

            completeDimensions(dimensions, data, ['x', 'y', 'z']);

            return {
                dimensions: dimensions,
                categoryAxisModel: isXAxisCategory ? xAxisModel
                    : (isYAxisCategory ? yAxisModel : null)
            };
        },

        polar: function (data, seriesModel, ecModel) {
            var polarIndex = seriesModel.get('polarIndex') || 0;

            var axisFinder = function (axisModel) {
                return axisModel.get('polarIndex') === polarIndex;
            };

            var angleAxisModel = ecModel.findComponents({
                mainType: 'angleAxis', filter: axisFinder
            })[0];
            var radiusAxisModel = ecModel.findComponents({
                mainType: 'radiusAxis', filter: axisFinder
            })[0];

            var isRadiusAxisCategory = radiusAxisModel.get('type') === 'category';
            var isAngleAxisCategory = angleAxisModel.get('type') === 'category';
            var dimensions = [{
                name: 'radius',
                type: isRadiusAxisCategory ? 'ordinal' : 'float',
                stackable: isStackable(radiusAxisModel.get('type'))
            }, {
                name: 'angle',
                type: isAngleAxisCategory ? 'ordinal' : 'float',
                stackable: isStackable(angleAxisModel.get('type'))
            }];

            completeDimensions(dimensions, data, ['radius', 'angle', 'value']);

            return {
                dimensions: dimensions,
                categoryAxisModel: isAngleAxisCategory ? angleAxisModel
                    : (isRadiusAxisCategory ? radiusAxisModel : null)
            };
        },

        geo: function (data, seriesModel, ecModel) {
            // TODO Region
            // 多个散点图系列在同一个地区的时候
            return {
                dimensions: completeDimensions([
                    {name: 'lng'},
                    {name: 'lat'}
                ], data, ['lng', 'lat', 'value'])
            };
        }
    };

    function createNameList(result, data) {
        var nameList = [];

        if (result.categoryAxisModel) {
            // FIXME Two category axis
            var categories = result.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][0]];
                    }
                }
                else {
                    nameList = categories.slice(0);
                }
            }
        }

        return nameList;
    }

    return createListFromArray;

});
define('echarts/chart/line/LineSeries',['require','../helper/createListFromArray','../../model/Series'],function(require) {



    var createListFromArray = require('../helper/createListFromArray');
    var SeriesModel = require('../../model/Series');

    return SeriesModel.extend({

        type: 'series.line',

        dependencies: ['grid', 'polar'],

        getInitialData: function (option, ecModel) {
            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: {
                    // show: false,
                    position: 'top'
                    // formatter: 标签文本格式器，同Tooltip.formatter，不支持异步回调
                    // position: 默认自适应，水平布局为'top'，垂直布局为'right'，可选为
                    //           'inside'|'left'|'right'|'top'|'bottom'
                    // textStyle: null      // 默认使用全局文本样式，详见TEXTSTYLE
                },
                emphasis: {
                    // show: false,
                    position: 'top'
                    // formatter: 标签文本格式器，同Tooltip.formatter，不支持异步回调
                    // position: 默认自适应，水平布局为'top'，垂直布局为'right'，可选为
                    //           'inside'|'left'|'right'|'top'|'bottom'
                    // textStyle: null      // 默认使用全局文本样式，详见TEXTSTYLE
                }
            },
            // itemStyle: {
            //     normal: {
            //         // color: 各异
            //     },
            //     emphasis: {
            //         // color: 各异,
            //     }
            // },
            lineStyle: {
                normal: {
                    width: 2,
                    type: 'solid'
                }
            },
            // areaStyle: {
            // },
            // smooth: false,
            // 拐点图形类型
            symbol: 'emptyCircle',
            // 拐点图形大小
            symbolSize: 4,
            // 拐点图形旋转控制
            // symbolRotate: null,

            // 是否显示 symbol, 只有在 tooltip hover 的时候显示
            showSymbol: true,
            // 标志图形默认只有主轴显示（随主轴标签间隔隐藏策略）
            // showAllSymbol: false

            animationEasing: 'linear'
        }
    });
});
// Symbol factory
define('echarts/util/symbol',['require','./graphic','zrender/core/BoundingRect'],function(require) {



    var graphic = require('./graphic');
    var BoundingRect = require('zrender/core/BoundingRect');

    /**
     * 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) {
        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.textBaseline = 'middle';
            }
        },

        buildPath: function (ctx, shape) {
            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);
            }
        }
    });

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

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

    return symbolUtil;
});
/**
 * @module echarts/chart/helper/Symbol
 */
define('echarts/chart/helper/Symbol',['require','zrender/core/util','../../util/symbol','../../util/graphic','../../util/number'],function (require) {

    var zrUtil = require('zrender/core/util');
    var symbolUtil = require('../../util/symbol');
    var graphic = require('../../util/graphic');
    var numberUtil = require('../../util/number');

    function normalizeSymbolSize(symbolSize) {
        if (!zrUtil.isArray(symbolSize)) {
            symbolSize = [+symbolSize, +symbolSize];
        }
        return symbolSize;
    }

    /**
     * @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) {
        graphic.Group.call(this);

        this.updateData(data, idx);
    }

    var symbolProto = Symbol.prototype;

    function driftSymbol(dx, dy) {
        this.parent.drift(dx, dy);
    }

    symbolProto._createSymbol = function (symbolType, data, idx) {
        // 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
        );

        symbolPath.attr({
            style: {
                strokeNoScale: true
            },
            z2: 100,
            scale: [0, 0]
        });
        // Rewrite drift method
        symbolPath.drift = driftSymbol;

        var size = normalizeSymbolSize(data.getItemVisual(idx, 'symbolSize'));

        graphic.initProps(symbolPath, {
            scale: size
        }, seriesModel);

        this._symbolType = symbolType;

        this.add(symbolPath);
    };

    /**
     * Stop animation
     * @param {boolean} toLastFrame
     */
    symbolProto.stopSymbolAnimation = function (toLastFrame) {
        this.childAt(0).stopAnimation(toLastFrame);
    };

    /**
     * Get scale(aka, current symbol size).
     * Including the change caused by animation
     * @param {Array.<number>} toLastFrame
     */
    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) {
        var symbolType = data.getItemVisual(idx, 'symbol') || 'circle';
        var seriesModel = data.hostModel;
        var symbolSize = normalizeSymbolSize(data.getItemVisual(idx, 'symbolSize'));
        if (symbolType !== this._symbolType) {
            this._createSymbol(symbolType, data, idx);
        }
        else {
            var symbolPath = this.childAt(0);
            graphic.updateProps(symbolPath, {
                scale: symbolSize
            }, seriesModel);
        }
        this._updateCommon(data, idx, symbolSize);

        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) {
        var symbolPath = this.childAt(0);
        var seriesModel = data.hostModel;
        var itemModel = data.getItemModel(idx);
        var normalItemStyleModel = itemModel.getModel(normalStyleAccessPath);
        var color = data.getItemVisual(idx, 'color');

        var hoverStyle = itemModel.getModel(emphasisStyleAccessPath).getItemStyle();

        symbolPath.rotation = itemModel.getShallow('symbolRotate') * Math.PI / 180 || 0;

        var symbolOffset = itemModel.getShallow('symbolOffset');
        if (symbolOffset) {
            var pos = symbolPath.position;
            pos[0] = numberUtil.parsePercent(symbolOffset[0], symbolSize[0]);
            pos[1] = numberUtil.parsePercent(symbolOffset[1], symbolSize[1]);
        }

        symbolPath.setColor(color);

        zrUtil.extend(
            symbolPath.style,
            // Color must be excluded.
            // Because symbol provide setColor individually to set fill and stroke
            normalItemStyleModel.getItemStyle(['color'])
        );

        var labelModel = itemModel.getModel(normalLabelAccessPath);
        var hoverLabelModel = itemModel.getModel(emphasisLabelAccessPath);
        var lastDim = data.dimensions[data.dimensions.length - 1];
        var labelText = seriesModel.getFormattedLabel(idx, 'normal')
                    || data.get(lastDim, idx);
        var elStyle = symbolPath.style;

        if (labelModel.get('show')) {
            graphic.setText(elStyle, labelModel, color);
            elStyle.text = labelText;
        }
        else {
            elStyle.text = '';
        }
        if (hoverLabelModel.getShallow('show')) {
            graphic.setText(hoverStyle, hoverLabelModel, color);
            hoverStyle.text = labelText;
        }
        else {
            hoverStyle.text = '';
        }

        graphic.setHoverStyle(symbolPath, hoverStyle);

        var size = normalizeSymbolSize(data.getItemVisual(idx, 'symbolSize'));

        symbolPath.off('mouseover')
            .off('mouseout')
            .off('emphasis')
            .off('normal');
        if (itemModel.getShallow('hoverAnimation')) {
            var onEmphasis = function() {
                var ratio = size[1] / size[0];
                this.animateTo({
                    scale: [
                        Math.max(size[0] * 1.1, size[0] + 3),
                        Math.max(size[1] * 1.1, size[1] + 3 * ratio)
                    ]
                }, 400, 'elasticOut');
            };
            var onNormal = function() {
                this.animateTo({
                    scale: size
                }, 400, 'elasticOut');
            };
            symbolPath.on('mouseover', onEmphasis)
                .on('mouseout', onNormal)
                .on('emphasis', onEmphasis)
                .on('normal', onNormal);
        }
    };

    symbolProto.fadeOut = function (cb) {
        var symbolPath = this.childAt(0);
        // Not show text when animating
        symbolPath.style.text = '';
        graphic.updateProps(symbolPath, {
            scale: [0, 0]
        }, this._seriesModel, cb);
    };

    zrUtil.inherits(Symbol, graphic.Group);

    return Symbol;
});
/**
 * @module echarts/chart/helper/SymbolDraw
 */
define('echarts/chart/helper/SymbolDraw',['require','../../util/graphic','./Symbol'],function (require) {

    var graphic = require('../../util/graphic');
    var Symbol = require('./Symbol');

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

        data.diff(oldData)
            .add(function (newIdx) {
                var point = data.getItemLayout(newIdx);
                if (symbolNeedsDraw(data, newIdx, isIgnore)) {
                    var symbolEl = new SymbolCtor(data, newIdx);
                    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);
                    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) {
                el.attr('position', data.getItemLayout(idx));
            });
        }
    };

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

    return SymbolDraw;
});
// Hirschberg's algorithm
// http://en.wikipedia.org/wiki/Hirschberg%27s_algorithm

/**
 * @module zrender/core/arrayDiff
 * @author Yi Shen
 */
define('zrender/core/arrayDiff',['require'],function (require) {

    function defaultCompareFunc(a, b) {
        return a === b;
    }

    function createItem(cmd, idx, idx1) {
        var res = {
            // cmd explanation
            // '=': not change
            // '^': replace with a new item in second array. Unused temporary
            // '+': add a new item of second array
            // '-': del item in first array
            cmd: cmd,
            // Value index, use index in the first array
            // Except '+'. Adding a new item needs value in the second array
            idx: idx
        };
        // Replace need to know both two indices
        // if (cmd === '^') {
        //     res.idx1 = idx1;
        // }

        if (cmd === '=') {
            res.idx1 = idx1;
        }
        return res;
    };

    function append(out, cmd, idx, idx1) {
        out.push(createItem(cmd, idx, idx1));
    }

    var abs = Math.abs;
    // Needleman-Wunsch score
    function score(arr0, arr1, i0, i1, j0, j1, equal, memo) {
        var last;
        var invM = i0 > i1;
        var invN = j0 > j1;
        var m = abs(i1 - i0);
        var n = abs(j1 - j0);
        var i;
        var j;
        for (i = 0; i <= m; i++) {
            for (j = 0; j <= n; j++) {
                if (i === 0) {
                    memo[j] = j;
                }
                else if (j === 0) {
                    last = memo[j];
                    memo[j] = i;
                }
                else {
                    // memo[i-1][j-1] + same(arr0[i-1], arr1[j-1]) ? 0 : 1
                    // Retained or replace
                    var val0 = arr0[invM ? (i0 - i) : (i - 1 + i0)];
                    var val1 = arr1[invN ? (j0 - j) : (j - 1 + j0)];
                    // Because replace is add after remove actually
                    // It has a higher score than removing or adding
                    // TODO custom score function
                    var score0 = last + (equal(val0, val1) ? 0 : 2);
                    // memo[i-1][j] + 1
                    // Remove arr0[i-1]
                    var score1 = memo[j] + 1;
                    // memo[i][j-1] + 1
                    // Add arr1[j-1]
                    var score2 = memo[j - 1] + 1;

                    last = memo[j];
                    memo[j] = score0 < score1 ? score0 : score1;
                    score2 < memo[j] && (memo[j] = score2);
                    // Math min of three parameters seems slow
                    // memo[j] = Math.min(score0, score1, score2);
                }
            }
        }

        return memo;
    }

    function hirschberg(arr0, arr1, i0, i1, j0, j1, equal, score0, score1) {
        var out = [];
        var len0 = i1 - i0;
        var len1 = j1 - j0;
        var i;
        var j;
        if (! len0) {
            for (j = 0; j < len1; j++) {
                append(out, '+', j + j0);
            }
        }
        else if (! len1) {
            for (i = 0; i < len0; i++) {
                append(out, '-', i + i0);
            }
        }
        else if (len0 === 1) {
            var a = arr0[i0];
            var matched = false;
            for (j = 0; j < len1; j++) {
                if (equal(a, arr1[j + j0]) && ! matched) {
                    matched = true;
                    // Equal and update use the index in first array
                    append(out, '=', i0, j + j0);
                }
                else {
                    // if (j === len1 - 1 && ! matched) {
                    //     append(out, '^', i0, j + j0);
                    // }
                    // else {
                    append(out, '+', j + j0);
                    // }
                }
            }
            if (! matched) {
                append(out, '-', i0);
            }
        }
        else if (len1 === 1) {
            var b = arr1[j0];
            var matched = false;
            for (i = 0; i < len0; i++) {
                if (equal(b, arr0[i + i0]) && ! matched) {
                    matched = true;
                    append(out, '=', i + i0, j0);
                }
                else {
                    // if (i === len0 - 1 && ! matched) {
                    //     append(out, '^', i + i0, j0);
                    // }
                    // else {
                    append(out, '-', i + i0);
                    // }
                }
            }
            if (! matched) {
                append(out, '+', j0);
            }
        }
        else {
            var imid = ((len0 / 2) | 0) + i0;

            score(arr0, arr1, i0, imid, j0, j1, equal, score0);
            score(arr0, arr1, i1, imid + 1, j1, j0, equal, score1);

            var min = Infinity;
            var jmid = 0;
            var sum;
            for (j = 0; j <= len1; j++) {
                sum = score0[j] + score1[len1 - j];
                if (sum < min) {
                    min = sum;
                    jmid = j;
                }
            }
            jmid += j0;

            out = hirschberg(arr0, arr1, i0, imid, j0, jmid, equal, score0, score1);
            var out1 = hirschberg(arr0, arr1, imid, i1, jmid, j1, equal, score0, score1);
            // Concat
            for (i = 0; i < out1.length; i++) {
                out.push(out1[i]);
            }
        }
        return out;
    }

    function arrayDiff(arr0, arr1, equal) {
        equal = equal || defaultCompareFunc;
        // Remove the common head and tail
        var i;
        var j;
        var len0 = arr0.length;
        var len1 = arr1.length;
        var lenMin = Math.min(len0, len1);
        var head = [];
        for (i = 0; i < lenMin; i++) {
            if (! equal(arr0[i], arr1[i])) {
                break;
            }
            append(head, '=', i, i);
        }

        for (j = 0; j < lenMin; j++) {
            if (! equal(arr0[len0 - j - 1], arr1[len1 - j - 1])) {
                break;
            }
        }

        if (len0 - j >= i || len1 - j >= i) {
            var middle = hirschberg(arr0, arr1, i, len0 - j, i, len1 - j, equal, [], []);
            for (i = 0; i < middle.length; i++) {
                head.push(middle[i]);
            }
            for (i = 0; i < j; i++) {
                append(head, '=', len0 - j + i, len1 - j + i);
            }
        }
        return head;
    }

    return arrayDiff;
});
define('echarts/chart/line/lineAnimationDiff',['require','zrender/core/arrayDiff'],function (require) {

    var arrayDiff = require('zrender/core/arrayDiff');

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

    return function (
        oldData, newData,
        oldStackedOnPoints, newStackedOnPoints,
        oldCoordSys, newCoordSys
    ) {

        var newIdList = newData.mapArray(newData.getId);
        var oldIdList = oldData.mapArray(oldData.getId);

        var currPoints = [];
        var nextPoints = [];
        // Points for stacking base line
        var currStackedPoints = [];
        var nextStackedPoints = [];

        var status = [];
        var sortedIndices = [];
        var rawIndices = [];

        // FIXME One data ?
        var diff = arrayDiff(oldIdList, newIdList);

        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 '=':
                    currPoints.push(oldData.getItemLayout(diffItem.idx));
                    nextPoints.push(newData.getItemLayout(diffItem.idx1));

                    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
        };
    };
});
// Poly path support NaN point
define('echarts/chart/line/poly',['require','zrender/graphic/Path','zrender/core/vector'],function (require) {

    var Path = require('zrender/graphic/Path');
    var vec2 = require('zrender/core/vector');

    var mathMin = Math.min;
    var mathMax = Math.max;
    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 drawSegment(
        ctx, points, start, allLen, segLen,
        dir, smoothMin, smoothMax, smooth
    ) {
        var idx = start;
        for (var k = 0; k < segLen; k++) {
            var p = points[idx];
            if (idx >= allLen || idx < 0 || isNaN(p[0]) || isNaN(p[1])) {
                break;
            }

            if (idx === start) {
                ctx[dir > 0 ? 'moveTo' : 'lineTo'](p[0], p[1]);
                v2Copy(cp0, p);
            }
            else {
                if (smooth > 0) {
                    var prevIdx = idx - dir;
                    var nextIdx = idx + dir;
                    if (dir > 0) {
                        prevIdx = mathMax(prevIdx, start);
                        nextIdx = mathMin(nextIdx, allLen - 1);
                    }
                    else {
                        nextIdx = mathMax(nextIdx, 0);
                        prevIdx = mathMin(prevIdx, start);
                    }
                    var prevP = points[prevIdx];
                    var nextP = points[nextIdx];
                    // If next data is null
                    if (isNaN(nextP[0]) || isNaN(nextP[1])) {
                        nextP = p;
                    }

                    vec2.sub(v, nextP, prevP);

                    scaleAndAdd(cp1, p, v, -smooth / 2);

                    // 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 / 2);
                }
                else {
                    ctx.lineTo(p[0], p[1]);
                }
            }

            idx += dir;
        }

        return k;
    }

    function getBoundingBox(points) {
        var ptMin = [Infinity, Infinity];
        var ptMax = [-Infinity, -Infinity];
        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: ptMin,
            max: ptMax
        };
    }

    return {

        Polyline: Path.extend({

            type: 'ec-polyline',

            shape: {
                points: [],

                smooth: 0
            },

            style: {
                fill: null,

                stroke: '#000',

                smooth: 0
            },

            buildPath: function (ctx, shape) {
                var points = shape.points;

                var i = 0;
                var len = points.length;

                var result = getBoundingBox(points);

                while (i < len) {
                    i += drawSegment(
                        ctx, points, i, len, len,
                        1, result.min, result.max, shape.smooth
                    ) + 1;
                }
            }
        }),

        Polygon: Path.extend({

            type: 'ec-polygon',

            shape: {
                points: [],
                // Offset between stacked base points and points
                stackedOnPoints: [],
                smooth: 0,
                stackedOnSmooth: 0
            },

            buildPath: function (ctx, shape) {
                var points = shape.points;
                var stackedOnPoints = shape.stackedOnPoints;

                var i = 0;
                var len = points.length;
                var bbox = getBoundingBox(points);
                var stackedOnBBox = getBoundingBox(stackedOnPoints);
                while (i < len) {
                    var k = drawSegment(
                        ctx, points, i, len, len,
                        1, bbox.min, bbox.max, shape.smooth
                    );
                    drawSegment(
                        ctx, stackedOnPoints, i + k - 1, len, k,
                        -1, stackedOnBBox.min, stackedOnBBox.max, shape.stackedOnSmooth
                    );
                    i += k + 1;

                    ctx.closePath();
                }
            }
        })
    };
});
define('echarts/chart/line/LineView',['require','zrender/core/util','../helper/SymbolDraw','../helper/Symbol','./lineAnimationDiff','../../util/graphic','./poly','../../view/Chart'],function(require) {



    var zrUtil = require('zrender/core/util');
    var SymbolDraw = require('../helper/SymbolDraw');
    var Symbol = require('../helper/Symbol');
    var lineAnimationDiff = require('./lineAnimationDiff');
    var graphic = require('../../util/graphic');

    var polyHelper = require('./poly');

    var ChartView = require('../../view/Chart');

    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 queryDataIndex(data, payload) {
        if (payload.dataIndex != null) {
            return payload.dataIndex;
        }
        else if (payload.name != null) {
            return data.indexOfName(payload.name);
        }
    }

    function createGridClipShape(cartesian, hasAnimation, seriesModel) {
        var xExtent = getAxisExtentWithGap(cartesian.getAxis('x'));
        var yExtent = getAxisExtentWithGap(cartesian.getAxis('y'));
        var isHorizontal = cartesian.getBaseAxis().isHorizontal();

        var x = xExtent[0];
        var y = yExtent[0];
        var width = xExtent[1] - x;
        var height = yExtent[1] - y;
        // Expand clip shape to avoid line value exceeds axis
        if (!seriesModel.get('clipOverflow')) {
            if (isHorizontal) {
                y -= height;
                height *= 3;
            }
            else {
                x -= width;
                width *= 3;
            }
        }
        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);
    }

    return ChartView.extend({

        type: 'line',

        init: function () {
            var lineGroup = new graphic.Group();

            var symbolDraw = new SymbolDraw();
            this.group.add(symbolDraw.group);
            this.group.add(lineGroup);

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

            // Initialization animation or coordinate system changed
            if (
                !(polyline
                && prevCoordSys.type === coordSys.type)
            ) {
                showSymbol && symbolDraw.updateData(data, isSymbolIgnore);

                polyline = this._newPolyline(group, points, coordSys, hasAnimation);
                if (isAreaChart) {
                    polygon = this._newPolygon(
                        group, points,
                        stackedOnPoints,
                        coordSys, hasAnimation
                    );
                }
                lineGroup.setClipPath(createClipShape(coordSys, true, seriesModel));
            }
            else {
                // Update clipPath
                if (hasAnimation) {
                    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
                        );
                    }
                    else {
                        polyline.setShape({
                            points: points
                        });
                        polygon && polygon.setShape({
                            points: points,
                            stackedOnPoints: stackedOnPoints
                        });
                    }
                }
                // Add back
                group.add(lineGroup);
            }

            polyline.setStyle(zrUtil.defaults(
                // Use color in lineStyle first
                lineStyleModel.getLineStyle(),
                {
                    stroke: data.getVisual('color'),
                    lineJoin: 'bevel'
                }
            ));

            var smooth = seriesModel.get('smooth');
            smooth = getSmooth(seriesModel.get('smooth'));
            polyline.shape.smooth = smooth;

            if (polygon) {
                var polygonShape = polygon.shape;
                var stackedOn = data.stackedOn;
                var stackedOnSmooth = 0;

                polygon.style.opacity = 0.7;
                polygon.setStyle(zrUtil.defaults(
                    areaStyleModel.getAreaStyle(),
                    {
                        fill: data.getVisual('color'),
                        lineJoin: 'bevel'
                    }
                ));
                polygonShape.smooth = smooth;

                if (stackedOn) {
                    var stackedOnSeries = stackedOn.hostModel;
                    stackedOnSmooth = getSmooth(stackedOnSeries.get('smooth'));
                }

                polygonShape.stackedOnSmooth = stackedOnSmooth;
            }

            this._data = data;
            // Save the coordinate system for transition animation when data changed
            this._coordSys = coordSys;
            this._stackedOnPoints = stackedOnPoints;
            this._points = points;
        },

        highlight: function (seriesModel, ecModel, api, payload) {
            var data = seriesModel.getData();
            var dataIndex = queryDataIndex(data, payload);

            if (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);
                    symbol = new Symbol(data, dataIndex, api);
                    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 = 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 {
                // 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 (group, points) {
            var polyline = this._polyline;
            // Remove previous created polyline
            if (polyline) {
                group.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 (group, points, stackedOnPoints) {
            var polygon = this._polygon;
            // Remove previous created polygon
            if (polygon) {
                group.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) {
            var polyline = this._polyline;
            var polygon = this._polygon;
            var seriesModel = data.hostModel;

            var diff = lineAnimationDiff(
                this._data, data,
                this._stackedOnPoints, stackedOnPoints,
                this._coordSys, coordSys
            );
            polyline.shape.points = diff.current;

            graphic.updateProps(polyline, {
                shape: {
                    points: diff.next
                }
            }, seriesModel);

            if (polygon) {
                polygon.setShape({
                    points: diff.current,
                    stackedOnPoints: diff.stackedOnCurrent
                });
                graphic.updateProps(polygon, {
                    shape: {
                        points: diff.next,
                        stackedOnPoints: diff.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;
            group.remove(this._lineGroup);
            this._symbolDraw.remove(true);
        }
    });
});
define('echarts/visual/symbol',['require'],function (require) {

    function isSymbolNone(symbolType) {
        return symbolType === 'none';
    }

    return 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.get('symbol', true);
                    var itemSymbolSize = itemModel.get('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);
                    }
                });
            }
        });
    };
});
define('echarts/layout/points',['require'],function (require) {

    return function (seriesType, ecModel, api) {
        ecModel.eachSeriesByType(seriesType, function (seriesModel) {
            var data = seriesModel.getData();
            var coordSys = seriesModel.coordinateSystem;

            var dims = coordSys.dimensions;
            data.each(dims, function (x, y, idx) {
                var point;
                if (!isNaN(x) && !isNaN(y)) {
                    point = coordSys.dataToPoint([x, y]);
                }
                else {
                    // Also {Array.<number>}, not undefined to avoid if...else... statement
                    point = [NaN, NaN];
                }

                data.setItemLayout(idx, point);
            }, true);
        });
    };
});
define('echarts/chart/line',['require','zrender/core/util','../echarts','./line/LineSeries','./line/LineView','../visual/symbol','../layout/points'],function (require) {

    var zrUtil = require('zrender/core/util');
    var echarts = require('../echarts');

    require('./line/LineSeries');
    require('./line/LineView');

    echarts.registerVisualCoding('chart', zrUtil.curry(
        require('../visual/symbol'), 'line', 'circle', 'line'
    ));
    echarts.registerLayout(zrUtil.curry(
        require('../layout/points'), 'line'
    ));
});
/**
 * // Scale class management
 * @module echarts/scale/Scale
 */
define('echarts/scale/Scale',['require','../util/clazz'],function (require) {

    var clazzUtil = require('../util/clazz');

    function Scale() {
        /**
         * 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;

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

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

    clazzUtil.enableClassExtend(Scale);
    clazzUtil.enableClassManagement(Scale, {
        registerWhenExtend: true
    });

    return Scale;
});
/**
 * Linear continuous scale
 * @module echarts/coord/scale/Ordinal
 *
 * http://en.wikipedia.org/wiki/Level_of_measurement
 */

// FIXME only one data
define('echarts/scale/Ordinal',['require','zrender/core/util','./Scale'],function (require) {

    var zrUtil = require('zrender/core/util');
    var Scale = require('./Scale');

    var scaleProto = Scale.prototype;

    var OrdinalScale = Scale.extend({

        type: 'ordinal',

        init: function (data, extent) {
            this._data = data;
            this._extent = extent || [0, data.length - 1];
        },

        contain: function (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) {
            if (typeof val === 'string') { // Is string
                val = zrUtil.indexOf(this._data, val);
            }
            return scaleProto.normalize.call(this, 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;
        },

        niceTicks: zrUtil.noop,
        niceExtent: zrUtil.noop
    });

    /**
     * @return {module:echarts/scale/Time}
     */
    OrdinalScale.create = function () {
        return new OrdinalScale();
    };

    return OrdinalScale;
});
/**
 * Interval scale
 * @module echarts/scale/Interval
 */

define('echarts/scale/Interval',['require','../util/number','../util/format','./Scale'],function (require) {

    var numberUtil = require('../util/number');
    var formatUtil = require('../util/format');
    var Scale = require('./Scale');

    var mathFloor = Math.floor;
    var mathCeil = Math.ceil;
    /**
     * @alias module:echarts/coord/scale/Interval
     * @constructor
     */
    var IntervalScale = Scale.extend({

        type: 'interval',

        _interval: 0,

        setExtent: function (start, end) {
            var thisExtent = this._extent;
            if (!isNaN(start)) {
                thisExtent[0] = start;
            }
            if (!isNaN(end)) {
                thisExtent[1] = 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 (!this._interval) {
                this.niceTicks();
            }
            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 (!this._interval) {
                this.niceTicks();
            }
            var interval = this._interval;
            var extent = this._extent;
            var ticks = [];

            // Consider this case: using dataZoom toolbox, zoom and zoom.
            var safeLimit = 10000;

            if (interval) {
                var niceExtent = this._niceExtent;
                if (extent[0] < niceExtent[0]) {
                    ticks.push(extent[0]);
                }
                var tick = niceExtent[0];
                while (tick <= niceExtent[1]) {
                    ticks.push(tick);
                    // Avoid rounding error
                    tick = numberUtil.round(tick + interval);
                    if (ticks.length > safeLimit) {
                        return [];
                    }
                }
                if (extent[1] > niceExtent[1]) {
                    ticks.push(extent[1]);
                }
            }

            return ticks;
        },

        /**
         * @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} n
         * @return {number}
         */
        getLabel: function (data) {
            return formatUtil.addCommas(data);
        },

        /**
         * Update interval and extent of intervals for nice ticks
         * Algorithm from d3.js
         * @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;
            }

            // Figure out step quantity, for example 0.1, 1, 10, 100
            var interval = Math.pow(10, Math.floor(Math.log(span / approxTickNum) / Math.LN10));
            var err = approxTickNum / span * interval;

            // Filter ticks to get closer to the desired count.
            if (err <= 0.15) {
                interval *= 10;
            }
            else if (err <= 0.3) {
                interval *= 5;
            }
            else if (err <= 0.5) {
                interval *= 3;
            }
            else if (err <= 0.75) {
                interval *= 2;
            }

            var niceExtent = [
                numberUtil.round(mathCeil(extent[0] / interval) * interval),
                numberUtil.round(mathFloor(extent[1] / interval) * interval)
            ];

            this._interval = interval;
            this._niceExtent = niceExtent;
        },

        /**
         * Nice extent.
         * @param {number} [approxTickNum = 10] Given approx tick number
         * @param {boolean} [fixMin=false]
         * @param {boolean} [fixMax=false]
         */
        niceExtent: function (approxTickNum, fixMin, fixMax) {
            var extent = this._extent;
            // If extent start and end are same, expand them
            if (extent[0] === extent[1]) {
                // Expand extent
                var expandSize = extent[0] / 2 || 1;
                extent[0] -= expandSize;
                extent[1] += expandSize;
            }
            // If there are no data and extent are [Infinity, -Infinity]
            if (extent[1] === -Infinity && extent[0] === Infinity) {
                extent[1] = 1;
                extent[0] = -1;
                this._niceExtent = [-1, 1];
                this._interval = 0.5;
                return;
            }

            this.niceTicks(approxTickNum, fixMin, fixMax);

            // var extent = this._extent;
            var interval = this._interval;

            if (!fixMin) {
                extent[0] = numberUtil.round(mathFloor(extent[0] / interval) * interval);
            }
            if (!fixMax) {
                extent[1] = numberUtil.round(mathCeil(extent[1] / interval) * interval);
            }
        }
    });

    /**
     * @return {module:echarts/scale/Time}
     */
    IntervalScale.create = function () {
        return new IntervalScale();
    };

    return IntervalScale;
});
/**
 * Interval scale
 * @module echarts/coord/scale/Time
 */

define('echarts/scale/Time',['require','zrender/core/util','../util/number','./Interval'],function (require) {

    var zrUtil = require('zrender/core/util');
    var numberUtil = require('../util/number');

    var IntervalScale = require('./Interval');

    var intervalScaleProto = IntervalScale.prototype;

    var mathCeil = Math.ceil;
    var mathFloor = Math.floor;

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

    /**
     * @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
     * @inner
     */
    var format = function (tpl, value) {
        if (tpl === 'week'
            || tpl === 'month'
            || tpl === 'quarter'
            || tpl === 'half-year'
            || tpl === 'year'
        ) {
            tpl = 'MM-dd\nyyyy';
        }

        var date = numberUtil.parseDate(value);
        var y = date.getFullYear();
        var M = date.getMonth() + 1;
        var d = date.getDate();
        var h = date.getHours();
        var m = date.getMinutes();
        var s = date.getSeconds();

        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;
    };
    /**
     * @alias module:echarts/coord/scale/Time
     * @constructor
     */
    var TimeScale = IntervalScale.extend({
        type: 'time',

        // Overwrite
        getLabel: function (val) {
            var stepLvl = this._stepLvl;

            var date = new Date(val);

            return format(stepLvl[0], date);
        },

        // Overwrite
        niceTicks: function (approxTickNum) {
            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];

            var niceExtent = [
                mathCeil(extent[0] / interval) * interval,
                mathFloor(extent[1] / interval) * interval
            ];

            this._stepLvl = level;
            // Interval will be used in getTicks
            this._interval = interval;
            this._niceExtent = niceExtent;
        }
    });

    zrUtil.each(['contain', 'normalize'], function (methodName) {
        TimeScale.prototype[methodName] = function (val) {
            val = +numberUtil.parseDate(val);
            return intervalScaleProto[methodName].call(this, val);
        };
    });

    // Steps from d3
    var scaleLevels = [
        // Format       step    interval
        ['hh:mm:ss',    1,      1000],           // 1s
        ['hh:mm:ss',    5,      1000 * 5],       // 5s
        ['hh:mm:ss',    10,     1000 * 10],      // 10s
        ['hh:mm:ss',    15,     1000 * 15],      // 15s
        ['hh:mm:ss',    30,     1000 * 30],      // 30s
        ['hh:mm\nMM-dd',1,      60000],          // 1m
        ['hh:mm\nMM-dd',5,      60000 * 5],      // 5m
        ['hh:mm\nMM-dd',10,     60000 * 10],     // 10m
        ['hh:mm\nMM-dd',15,     60000 * 15],     // 15m
        ['hh:mm\nMM-dd',30,     60000 * 30],     // 30m
        ['hh:mm\nMM-dd',1,      3600000],        // 1h
        ['hh:mm\nMM-dd',2,      3600000 * 2],    // 2h
        ['hh:mm\nMM-dd',6,      3600000 * 6],    // 6h
        ['hh:mm\nMM-dd',12,     3600000 * 12],   // 12h
        ['MM-dd\nyyyy', 1,      3600000 * 24],   // 1d
        ['week',        7,      3600000 * 24 * 7],        // 7d
        ['month',       1,      3600000 * 24 * 31],       // 1M
        ['quarter',     3,      3600000 * 24 * 380 / 4],  // 3M
        ['half-year',   6,      3600000 * 24 * 380 / 2],  // 6M
        ['year',        1,      3600000 * 24 * 380]       // 1Y
    ];

    /**
     * @return {module:echarts/scale/Time}
     */
    TimeScale.create = function () {
        return new TimeScale();
    };

    return TimeScale;
});
/**
 * Log scale
 * @module echarts/scale/Log
 */
define('echarts/scale/Log',['require','zrender/core/util','./Scale','../util/number','./Interval'],function (require) {

    var zrUtil = require('zrender/core/util');
    var Scale = require('./Scale');
    var numberUtil = require('../util/number');

    // Use some method of IntervalScale
    var IntervalScale = require('./Interval');

    var scaleProto = Scale.prototype;
    var intervalScaleProto = IntervalScale.prototype;

    var mathFloor = Math.floor;
    var mathCeil = Math.ceil;
    var mathPow = Math.pow;

    var LOG_BASE = 10;
    var mathLog = Math.log;

    var LogScale = Scale.extend({

        type: 'log',

        /**
         * @return {Array.<number>}
         */
        getTicks: function () {
            return zrUtil.map(intervalScaleProto.getTicks.call(this), function (val) {
                return numberUtil.round(mathPow(LOG_BASE, val));
            });
        },

        /**
         * @param {number} val
         * @return {string}
         */
        getLabel: intervalScaleProto.getLabel,

        /**
         * @param  {number} val
         * @return {number}
         */
        scale: function (val) {
            val = scaleProto.scale.call(this, val);
            return mathPow(LOG_BASE, val);
        },

        /**
         * @param {number} start
         * @param {number} end
         */
        setExtent: function (start, end) {
            start = mathLog(start) / mathLog(LOG_BASE);
            end = mathLog(end) / mathLog(LOG_BASE);
            intervalScaleProto.setExtent.call(this, start, end);
        },

        /**
         * @return {number} end
         */
        getExtent: function () {
            var extent = scaleProto.getExtent.call(this);
            extent[0] = mathPow(LOG_BASE, extent[0]);
            extent[1] = mathPow(LOG_BASE, extent[1]);
            return extent;
        },

        /**
         * @param  {Array.<number>} extent
         */
        unionExtent: function (extent) {
            extent[0] = mathLog(extent[0]) / mathLog(LOG_BASE);
            extent[1] = mathLog(extent[1]) / mathLog(LOG_BASE);
            scaleProto.unionExtent.call(this, extent);
        },

        /**
         * 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 = mathPow(10, mathFloor(mathLog(span / approxTickNum) / Math.LN10));
            var err = approxTickNum / span * interval;

            // Filter ticks to get closer to the desired count.
            if (err <= 0.5) {
                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.
         * @param {number} [approxTickNum = 10] Given approx tick number
         * @param {boolean} [fixMin=false]
         * @param {boolean} [fixMax=false]
         */
        niceExtent: intervalScaleProto.niceExtent
    });

    zrUtil.each(['contain', 'normalize'], function (methodName) {
        LogScale.prototype[methodName] = function (val) {
            val = mathLog(val) / mathLog(LOG_BASE);
            return scaleProto[methodName].call(this, val);
        };
    });

    LogScale.create = function () {
        return new LogScale();
    };

    return LogScale;
});
define('echarts/coord/axisHelper',['require','../scale/Ordinal','../scale/Interval','../scale/Time','../scale/Log','../scale/Scale','../util/number','zrender/core/util','zrender/contain/text'],function (require) {

    var OrdinalScale = require('../scale/Ordinal');
    var IntervalScale = require('../scale/Interval');
    require('../scale/Time');
    require('../scale/Log');
    var Scale = require('../scale/Scale');

    var numberUtil = require('../util/number');
    var zrUtil = require('zrender/core/util');
    var textContain = require('zrender/contain/text');
    var axisHelper = {};

    axisHelper.niceScaleExtent = function (axis, model) {
        var scale = axis.scale;
        if (scale.type === 'ordinal') {
            return;
        }
        var min = model.get('min');
        var max = model.get('max');
        var boundaryGap = model.get('boundaryGap');
        if (!zrUtil.isArray(boundaryGap)) {
            boundaryGap = [boundaryGap || 0, boundaryGap || 0];
        }
        boundaryGap[0] = numberUtil.parsePercent(boundaryGap[0], 1);
        boundaryGap[1] = numberUtil.parsePercent(boundaryGap[1], 1);
        var originalExtent = scale.getExtent();
        var span = originalExtent[1] - originalExtent[0];
        var fixMin = true;
        var fixMax = true;
        // Add boundary gap
        if (min == null) {
            min = originalExtent[0] - boundaryGap[0] * span;
            fixMin = false;
        }
        if (max == null) {
            max = originalExtent[1] + boundaryGap[1] * span;
            fixMax = false;
        }
        // TODO Only one data
        if (min === 'dataMin') {
            min = originalExtent[0];
        }
        if (max === 'dataMax') {
            max = originalExtent[1];
        }
        scale.setExtent(min, max);
        scale.niceExtent(model.get('splitNumber'), fixMin, fixMax);

        // 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];
        var optMin = axis.model.get('min');
        var optMax = axis.model.get('max');
        if (!isNaN(optMin)) {
            min = Math.min(optMin, min);
        }
        if (!isNaN(optMax)) {
            max = Math.max(optMax, max);
        }
        return !((min > 0 && max > 0) || (min < 0 && max < 0))
            || axisHelper.ifAxisNeedsCrossZero(axis);
    };

    /**
     * Check if the axis scale needs include data 0
     */
    axisHelper.ifAxisNeedsCrossZero = function (axis) {
        return !axis.model.get('scale');
    };

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

        for (var i = 0; i < tickCoords.length; i++) {
            var tickCoord = tickCoords[i];
            var rect = textContain.getBoundingRect(
                labels[i], font, 'center', 'top'
            );
            rect[isAxisHorizontal ? 'x' : 'y'] += tickCoord;
            rect[isAxisHorizontal ? 'width' : 'height'] *= 1.5;
            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;
            }
        }

        return autoLabelInterval;
    };

    /**
     * @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);
                };
            })(labelFormatter);
            return zrUtil.map(labels, labelFormatter);
        }
        else if (typeof labelFormatter === 'function') {
            return zrUtil.map(ticks, function (tick, idx) {
                return labelFormatter(
                    axis.type === 'category' ? scale.getLabel(tick) : tick,
                    idx
                );
            }, this);
        }
        else {
            return labels;
        }
    };

    return axisHelper;
});
/**
 * Cartesian coordinate system
 * @module  echarts/coord/Cartesian
 *
 */
define('echarts/coord/cartesian/Cartesian',['require','zrender/core/util'],function (require) {



    var zrUtil = require('zrender/core/util');

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

    return Cartesian;
});
define('echarts/coord/cartesian/Cartesian2D',['require','zrender/core/util','./Cartesian'],function(require) {



    var zrUtil = require('zrender/core/util');
    var Cartesian = require('./Cartesian');

    function Cartesian2D(name) {

        Cartesian.call(this, name);

        /**
         * @type {Array.<string>}
         * @readOnly
         */
        this.dimensions = ['x', 'y'];
    }

    Cartesian2D.prototype = {

        constructor: Cartesian2D,

        type: 'cartesian2d',

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

    return Cartesian2D;
});
define('echarts/coord/Axis',['require','../util/number','zrender/core/util'],function (require) {

    var numberUtil = require('../util/number');
    var linearMap = numberUtil.linearMap;
    var zrUtil = require('zrender/core/util');

    function fixExtentWithBands(extent, nTick) {
        var size = extent[1] - extent[0];
        var len = nTick;
        var margin = size / len / 2;
        extent[0] += margin;
        extent[1] -= margin;
    }
    /**
     * @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;
    };

    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 () {
            var ret = this._extent.slice();
            return ret;
        },

        /**
         * 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) {
            data = this.scale.normalize(data);
            var extent = this.getExtent();
            var scale = this.scale;
            if (this.onBand && scale.type === 'ordinal') {
                fixExtentWithBands(extent, scale.count());
            }

            return linearMap(data, [0, 1], 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.getExtent();

            if (this.onBand) {
                fixExtentWithBands(extent, this.scale.count());
            }

            var t = linearMap(coord, extent, [0, 1], clamp);

            return this.scale.scale(t);
        },
        /**
         * @return {Array.<number>}
         */
        getTicksCoords: function () {
            if (this.onBand) {
                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 () {
            if (this.onBand) {
                var bands = this.getBands();
                var coords = [];
                var band;
                for (var i = 0; i < bands.length; i++) {
                    band = bands[i];
                    coords.push((band[0] + band[1]) / 2);
                }
                return coords;
            }
            else {
                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);

            var size = Math.abs(axisExtent[1] - axisExtent[0]);

            return Math.abs(size) / len;
        }
    };

    return Axis;
});
/**
 * Helper function for axisLabelInterval calculation
 */

define('echarts/coord/cartesian/axisLabelInterval',['require','zrender/core/util','../axisHelper'],function(require) {


    var zrUtil = require('zrender/core/util');
    var axisHelper = require('../axisHelper');

    return function (axis) {
        var axisModel = axis.model;
        var labelModel = axisModel.getModel('axisLabel');
        var labelInterval = labelModel.get('interval');
        if (!(axis.type === 'category' && labelInterval === 'auto')) {
            return labelInterval === 'auto' ? 0 : labelInterval;
        }

        return axisHelper.getAxisLabelInterval(
            zrUtil.map(axis.scale.getTicks(), axis.dataToCoord, axis),
            axisModel.getFormattedLabels(),
            labelModel.getModel('textStyle').getFont(),
            axis.isHorizontal()
        );
    };
});
define('echarts/coord/cartesian/Axis2D',['require','zrender/core/util','../Axis','./axisLabelInterval'],function (require) {

    var zrUtil = require('zrender/core/util');
    var Axis = require('../Axis');
    var axisLabelInterval = require('./axisLabelInterval');

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

        getGlobalExtent: function () {
            var ret = this.getExtent();
            ret[0] = this.toGlobalCoord(ret[0]);
            ret[1] = this.toGlobalCoord(ret[1]);
            return ret;
        },

        /**
         * @return {number}
         */
        getLabelInterval: function () {
            var labelInterval = this._labelInterval;
            if (!labelInterval) {
                labelInterval = this._labelInterval = axisLabelInterval(this);
            }
            return labelInterval;
        },

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

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

    return Axis2D;
});
define('echarts/coord/axisDefault',['require','zrender/core/util'],function (require) {

    var zrUtil = require('zrender/core/util');

    var defaultOption = {
        show: true,
        zlevel: 0,                  // 一级层叠
        z: 0,                       // 二级层叠
        // 反向坐标轴
        inverse: false,
        // 坐标轴名字，默认为空
        name: '',
        // 坐标轴名字位置，支持'start' | 'middle' | 'end'
        nameLocation: 'end',
        // 坐标轴文字样式，默认取全局样式
        nameTextStyle: {},
        // 文字与轴线距离
        nameGap: 15,
        // 坐标轴线
        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: {
                color: '#333',
                width: 1
            }
        },
        // 坐标轴文本标签，详见axis.axisLabel
        axisLabel: {
            show: true,
            // 控制文本标签是否在grid里
            inside: false,
            rotate: 0,
            margin: 8,
            // formatter: null,
            // 其余属性默认使用全局文本样式，详见TEXTSTYLE
            textStyle: {
                color: '#333',
                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,
        // 坐标轴小标记
        axisTick: {
            interval: 'auto'
        },
        // 坐标轴文本标签，详见axis.axisLabel
        axisLabel: {
            interval: 'auto'
        }
    }, defaultOption);

    var valueAxis = zrUtil.defaults({
        // 数值起始和结束两端空白策略
        boundaryGap: [0, 0],
        // 最小值, 设置成 'dataMin' 则从数据中计算最小值
        // min: null,
        // 最大值，设置成 'dataMax' 则从数据中计算最大值
        // max: null,
        // 脱离0值比例，放大聚焦到最终_min，_max区间
        // scale: false,
        // 分割段数，默认为5
        splitNumber: 5
    }, defaultOption);

    // FIXME
    var timeAxis = zrUtil.defaults({
        scale: true,
        min: 'dataMin',
        max: 'dataMax'
    }, valueAxis);
    var logAxis = zrUtil.defaults({}, valueAxis);
    logAxis.scale = true;

    return {
        categoryAxis: categoryAxis,
        valueAxis: valueAxis,
        timeAxis: timeAxis,
        logAxis: logAxis
    };
});
define('echarts/coord/axisModelCreator',['require','./axisDefault','zrender/core/util','../model/Component'],function (require) {

    var axisDefault = require('./axisDefault');
    var zrUtil = require('zrender/core/util');
    var ComponentModel = require('../model/Component');

    // 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]
     */
    return function (axisName, BaseAxisModelClass, axisTypeDefaulter, extraDefaultOption) {

        zrUtil.each(AXIS_TYPES, function (axisType) {

            BaseAxisModelClass.extend({

                type: axisName + 'Axis.' + axisType,

                mergeDefaultAndTheme: function (option, ecModel) {
                    var themeModel = ecModel.getTheme();
                    zrUtil.merge(option, themeModel.get(axisType + 'Axis'));
                    zrUtil.merge(option, this.getDefaultOption());

                    option.type = axisTypeDefaulter(axisName, option);
                },

                defaultOption: zrUtil.mergeAll(
                    [
                        {},
                        axisDefault[axisType + 'Axis'],
                        extraDefaultOption
                    ],
                    true
                )
            });
        });

        ComponentModel.registerSubTypeDefaulter(
            axisName + 'Axis',
            zrUtil.curry(axisTypeDefaulter, axisName)
        );
    };
});
define('echarts/coord/axisModelCommonMixin',['require','zrender/core/util','./axisHelper'],function (require) {

    var zrUtil = require('zrender/core/util');
    var axisHelper = require('./axisHelper');

    function getName(obj) {
        if (zrUtil.isObject(obj) && obj.value != null) {
            return obj.value;
        }
        else {
            return obj;
        }
    }
    /**
     * Get categories
     */
    function getCategories() {
        return this.get('type') === 'category'
            && zrUtil.map(this.get('data'), getName);
    }

    /**
     * Format labels
     * @return {Array.<string>}
     */
    function getFormattedLabels() {
        return axisHelper.getFormattedLabels(
            this.axis,
            this.get('axisLabel.formatter')
        );
    }

    return {

        getFormattedLabels: getFormattedLabels,

        getCategories: getCategories
    };
});
define('echarts/coord/cartesian/AxisModel',['require','../../model/Component','zrender/core/util','../axisModelCreator','../axisModelCommonMixin'],function(require) {



    var ComponentModel = require('../../model/Component');
    var zrUtil = require('zrender/core/util');
    var axisModelCreator = require('../axisModelCreator');

    var AxisModel = ComponentModel.extend({

        type: 'cartesian2dAxis',

        /**
         * @type {module:echarts/coord/cartesian/Axis2D}
         */
        axis: null,

        /**
         * @public
         * @param {boolean} needs Whether axis needs cross zero.
         */
        setNeedsCrossZero: function (needs) {
            this.option.scale = !needs;
        },

        /**
         * @public
         * @param {number} min
         */
        setMin: function (min) {
            this.option.min = min;
        },

        /**
         * @public
         * @param {number} max
         */
        setMax: function (max) {
            this.option.max = max;
        }
    });

    function getAxisType(axisDim, option) {
        // Default axis with data is category axis
        return option.type || (option.data ? 'category' : 'value');
    }

    zrUtil.merge(AxisModel.prototype, require('../axisModelCommonMixin'));

    var extraOption = {
        gridIndex: 0
    };

    axisModelCreator('x', AxisModel, getAxisType, extraOption);
    axisModelCreator('y', AxisModel, getAxisType, extraOption);

    return AxisModel;
});
// Grid 是在有直角坐标系的时候必须要存在的
// 所以这里也要被 Cartesian2D 依赖
define('echarts/coord/cartesian/GridModel',['require','./AxisModel','../../model/Component'],function(require) {



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

    return 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'
        }
    });
});
/**
 * Grid is a region which contains at most 4 cartesian systems
 *
 * TODO Default cartesian
 */
define('echarts/coord/cartesian/Grid',['require','exports','module','../../util/layout','../../coord/axisHelper','zrender/core/util','./Cartesian2D','./Axis2D','./GridModel','../../CoordinateSystem'],function(require, factory) {

    var layout = require('../../util/layout');
    var axisHelper = require('../../coord/axisHelper');

    var zrUtil = require('zrender/core/util');
    var Cartesian2D = require('./Cartesian2D');
    var Axis2D = require('./Axis2D');

    var each = zrUtil.each;

    var ifAxisCrossZero = axisHelper.ifAxisCrossZero;
    var ifAxisNeedsCrossZero = axisHelper.ifAxisNeedsCrossZero;
    var niceScaleExtent = axisHelper.niceScaleExtent;

    // 依赖 GridModel, AxisModel 做预处理
    require('./GridModel');

    /**
     * Check if the axis is used in the specified grid
     * @inner
     */
    function isAxisUsedInTheGrid(axisModel, gridModel, ecModel) {
        return ecModel.getComponent('grid', axisModel.get('gridIndex')) === gridModel;
    }

    function getLabelUnionRect(axis) {
        var axisModel = axis.model;
        var labels = axisModel.getFormattedLabels();
        var rect;
        for (var i = 0; i < labels.length; i++) {
            if (!axis.isLabelIgnored(i)) {
                var singleRect = axisModel.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);
    }

    var gridProto = Grid.prototype;

    gridProto.type = 'grid';

    gridProto.getRect = function () {
        return this._rect;
    };

    /**
     * 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 {number} [axisIndex]
     */
    gridProto.getAxis = function (axisType, axisIndex) {
        if (axisIndex != null) {
            var key = axisType + axisIndex;
            return this._axesMap[key];
        }
        else {
            // Find first axis with axisType
            var axesList = this._axesList;
            for (var i = 0; i < axesList.length; i++) {
                if (axesList[i].dim === axisType) {
                    return axesList[i];
                }
            }
        }
    };

    gridProto.getCartesian = function (xAxisIndex, yAxisIndex) {
        var key = 'x' + xAxisIndex + 'y' + yAxisIndex;
        return this._coordsMap[key];
    };

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

        ecModel.eachComponent('xAxis', createAxisCreator('x'), this);

        ecModel.eachComponent('yAxis', createAxisCreator('y'), this);

        if (!axesCount.x || !axesCount.y) {
            // api.log('Grid must has at least one x axis and one y axis');
            // Roll back
            this._axesMap = {};
            this._axesList = [];
            return;
        }

        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;

                this._coordsMap[key] = cartesian;
                this._coordsList.push(cartesian);

                cartesian.addAxis(xAxis);
                cartesian.addAxis(yAxis);
            }, this);
        }, this);

        this._updateCartesianFromSeries(ecModel, gridModel);

        function ifAxisCanNotOnZero(otherAxisDim) {
            var axes = axesMap[otherAxisDim];
            return (axes[0] && (axes[0].type === 'category' || !ifAxisCrossZero(axes[0])))
                || (axes[1] && (axes[1].type === 'category' || !ifAxisCrossZero(axes[1])));
        }

        // 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;
            }
            if (ifAxisNeedsCrossZero(xAxis)) {
                xAxis.scale.unionExtent([0, 0]);
            }
            niceScaleExtent(xAxis, xAxis.model);
        }, this);

        each(axesMap.y, function (yAxis) {
            if (ifAxisCanNotOnZero('x')) {
                yAxis.onZero = false;
            }
            if (ifAxisNeedsCrossZero(yAxis)) {
                yAxis.scale.unionExtent([0, 0]);
            }
            niceScaleExtent(yAxis, yAxis.model);
        }, 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;

                // Index of axis, can be used as key
                axis.index = idx;

                this._axesList.push(axis);
                this._axesMap[axisType + idx] = axis;

                axesMap[axisType][idx] = axis;
                axesCount[axisType]++;
            };
        }
    };

    /**
     * Update cartesian properties from series
     * @param  {module:echarts/model/Option} option
     * @private
     */
    gridProto._updateCartesianFromSeries = function (ecModel, gridModel) {
        ecModel.eachSeries(function (seriesModel) {
            if (seriesModel.get('coordinateSystem') === 'cartesian2d') {
                var xAxisIndex = seriesModel.get('xAxisIndex');
                var yAxisIndex = seriesModel.get('yAxisIndex');

                var xAxisModel = ecModel.getComponent('xAxis', xAxisIndex);
                var yAxisModel = ecModel.getComponent('yAxis', yAxisIndex);

                if (!isAxisUsedInTheGrid(xAxisModel, gridModel, ecModel)
                    || !isAxisUsedInTheGrid(yAxisModel, gridModel, ecModel)
                 ) {
                    return;
                }

                var cartesian = this.getCartesian(xAxisIndex, yAxisIndex);

                var data = seriesModel.getData();
                if (data.type === 'list') {
                    unionExtent(data, cartesian.getAxis('x'), 'x', seriesModel);
                    unionExtent(data, cartesian.getAxis('y'), 'y', seriesModel);
                }
            }
        }, this);

        function unionExtent(data, axis, axisDim, seriesModel) {
            each(seriesModel.getDimensionsOnAxis(axisDim), function (dim) {
                axis.scale.unionExtent(data.getDataExtent(
                    dim, axis.scale.type !== 'ordinal'
                ));
            });
        }
    };

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

    Grid.create = function (ecModel, api) {
        var grids = [];
        ecModel.eachComponent('grid', function (gridModel, idx) {
            var grid = new Grid(gridModel, ecModel, api);
            grid.name = 'grid_' + idx;
            grid.resize(gridModel, api);

            gridModel.coordinateSystem = grid;

            grids.push(grid);
        });

        // Inject the coordinateSystems into seriesModel
        ecModel.eachSeries(function (seriesModel) {
            if (seriesModel.get('coordinateSystem') !== 'cartesian2d') {
                return;
            }
            var xAxisIndex = seriesModel.get('xAxisIndex');
            // TODO Validate
            var xAxisModel = ecModel.getComponent('xAxis', xAxisIndex);
            var grid = grids[xAxisModel.get('gridIndex')];
            seriesModel.coordinateSystem = grid.getCartesian(
                xAxisIndex, seriesModel.get('yAxisIndex')
            );
        });

        return grids;
    };

    require('../../CoordinateSystem').register('grid', Grid);

    return Grid;
});
define('echarts/chart/bar/BarSeries',['require','../../model/Series','../helper/createListFromArray'],function(require) {



    var SeriesModel = require('../../model/Series');
    var createListFromArray = require('../helper/createListFromArray');

    return SeriesModel.extend({

        type: 'series.bar',

        dependencies: ['grid', 'polar'],

        getInitialData: function (option, ecModel) {
            return createListFromArray(option.data, this, ecModel);
        },

        defaultOption: {
            zlevel: 0,                  // 一级层叠
            z: 2,                       // 二级层叠
            coordinateSystem: 'cartesian2d',
            legendHoverLink: true,
            // stack: null

            // Cartesian coordinate system
            xAxisIndex: 0,
            yAxisIndex: 0,

            // 最小高度改为0
            barMinHeight: 0,

            // barMaxWidth: null,
            // 默认自适应
            // barWidth: null,
            // 柱间距离，默认为柱形宽度的30%，可设固定值
            barGap: '30%',
            // 类目间柱形距离，默认为类目间距的20%，可设固定值
            barCategoryGap: '20%',
            // label: {
            //     normal: {
            //         show: false
            //         formatter: 标签文本格式器，同Tooltip.formatter，不支持异步回调

            //         // 默认自适应，水平布局为'top'，垂直布局为'right'，可选为
            //         //           'inside' | 'insideleft' | 'insideTop' | 'insideRight' | 'insideBottom' |
            //         //           'outside' |'left' | 'right'|'top'|'bottom'
            //         position:

            //         textStyle: null      // 默认使用全局文本样式，详见TEXTSTYLE
            //     }
            // },
            itemStyle: {
                normal: {
                    // color: '各异',
                    // 柱条边线
                    barBorderColor: '#fff',
                    // 柱条边线线宽，单位px，默认为1
                    barBorderWidth: 0
                },
                emphasis: {
                    // color: '各异',
                    // 柱条边线
                    barBorderColor: '#fff',
                    // 柱条边线线宽，单位px，默认为1
                    barBorderWidth: 0
                }
            }
        }
    });
});
define('echarts/chart/bar/barItemStyle',['require','../../model/mixin/makeStyleMapper'],function (require) {
    return {
        getBarItemStyle: require('../../model/mixin/makeStyleMapper')(
            [
                ['fill', 'color'],
                ['stroke', 'barBorderColor'],
                ['lineWidth', 'barBorderWidth'],
                ['opacity'],
                ['shadowBlur'],
                ['shadowOffsetX'],
                ['shadowOffsetY'],
                ['shadowColor']
            ]
        )
    };
});
define('echarts/chart/bar/BarView',['require','zrender/core/util','../../util/graphic','../../model/Model','./barItemStyle','../../echarts'],function (require) {



    var zrUtil = require('zrender/core/util');
    var graphic = require('../../util/graphic');

    zrUtil.extend(require('../../model/Model').prototype, require('./barItemStyle'));

    function fixLayoutWithLineWidth(layout, lineWidth) {
        var signX = layout.width > 0 ? 1 : -1;
        var signY = layout.height > 0 ? 1 : -1;
        layout.x += signX * lineWidth / 2;
        layout.y += signY * lineWidth / 2;
        layout.width -= signX * lineWidth;
        layout.height -= signY * lineWidth;
    }

    return require('../../echarts').extendChartView({

        type: 'bar',

        render: function (seriesModel, ecModel, api) {
            var coordinateSystemType = seriesModel.get('coordinateSystem');

            if (coordinateSystemType === 'cartesian2d') {
                this._renderOnCartesian(seriesModel, ecModel, api);
            }

            return this.group;
        },

        _renderOnCartesian: 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 enableAnimation = seriesModel.get('animation');

            var barBorderWidthQuery = ['itemStyle', 'normal', 'barBorderWidth'];

            function createRect(dataIndex, isUpdate) {
                var layout = data.getItemLayout(dataIndex);
                var lineWidth = data.getItemModel(dataIndex).get(barBorderWidthQuery) || 0;
                fixLayoutWithLineWidth(layout, lineWidth);

                var rect = new graphic.Rect({
                    shape: zrUtil.extend({}, layout)
                });
                // Animation
                if (enableAnimation) {
                    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
                    }, seriesModel);
                }
                return rect;
            }
            data.diff(oldData)
                .add(function (dataIndex) {
                    // 空数据
                    if (!data.hasValue(dataIndex)) {
                        return;
                    }

                    var rect = createRect(dataIndex);

                    data.setItemGraphicEl(dataIndex, rect);

                    group.add(rect);

                })
                .update(function (newIndex, oldIndex) {
                    var rect = oldData.getItemGraphicEl(oldIndex);
                    // 空数据
                    if (!data.hasValue(newIndex)) {
                        group.remove(rect);
                        return;
                    }
                    if (!rect) {
                        rect = createRect(newIndex, true);
                    }

                    var layout = data.getItemLayout(newIndex);
                    var lineWidth = data.getItemModel(newIndex).get(barBorderWidthQuery) || 0;
                    fixLayoutWithLineWidth(layout, lineWidth);

                    graphic.updateProps(rect, {
                        shape: layout
                    }, seriesModel);

                    data.setItemGraphicEl(newIndex, rect);

                    // Add back
                    group.add(rect);
                })
                .remove(function (idx) {
                    var rect = oldData.getItemGraphicEl(idx);
                    if (rect) {
                        // Not show text when animating
                        rect.style.text = '';
                        graphic.updateProps(rect, {
                            shape: {
                                width: 0
                            }
                        }, seriesModel, function () {
                            group.remove(rect);
                        });
                    }
                })
                .execute();

            this._updateStyle(seriesModel, data, isHorizontal);

            this._data = data;
        },

        _updateStyle: function (seriesModel, data, isHorizontal) {
            function setLabel(style, model, color, labelText, labelPositionOutside) {
                graphic.setText(style, model, color);
                style.text = labelText;
                if (style.textPosition === 'outside') {
                    style.textPosition = labelPositionOutside;
                }
            }

            data.eachItemGraphicEl(function (rect, idx) {
                var itemModel = data.getItemModel(idx);
                var labelModel = itemModel.getModel('label.normal');
                var color = data.getItemVisual(idx, 'color');
                var layout = data.getItemLayout(idx);

                var hoverStyle = itemModel.getModel('itemStyle.emphasis').getItemStyle();

                rect.setStyle(zrUtil.defaults(
                    {
                        fill: color
                    },
                    itemModel.getModel('itemStyle.normal').getBarItemStyle()
                ));

                var labelPositionOutside = isHorizontal
                    ? (layout.height > 0 ? 'bottom' : 'top')
                    : (layout.width > 0 ? 'left' : 'right');

                var labelModel = itemModel.getModel('label.normal');
                var hoverLabelModel = itemModel.getModel('label.emphasis');
                var rectStyle = rect.style;
                if (labelModel.get('show')) {
                    setLabel(
                        rectStyle, labelModel, color,
                        seriesModel.getFormattedLabel(idx, 'normal') || seriesModel.getRawValue(idx),
                        labelPositionOutside
                    );
                }
                else {
                    rectStyle.text = '';
                }
                if (hoverLabelModel.get('show')) {
                    setLabel(
                        hoverStyle, hoverLabelModel, color,
                        seriesModel.getFormattedLabel(idx, 'emphasis') || seriesModel.getRawValue(idx),
                        labelPositionOutside
                    );
                }
                else {
                    hoverStyle.text = '';
                }
                graphic.setHoverStyle(rect, hoverStyle);
            });
        },

        remove: function (ecModel, api) {
            var group = this.group;
            if (ecModel.get('animation')) {
                if (this._data) {
                    this._data.eachItemGraphicEl(function (el) {
                        // Not show text when animating
                        el.style.text = '';
                        graphic.updateProps(el, {
                            shape: {
                                width: 0
                            }
                        }, ecModel, function () {
                            group.remove(el);
                        });
                    });
                }
            }
            else {
                group.removeAll();
            }
        }
    });
});
define('echarts/layout/barGrid',['require','zrender/core/util','../util/number'],function(require) {



    var zrUtil = require('zrender/core/util');
    var numberUtil = require('../util/number');
    var parsePercent = numberUtil.parsePercent;

    function getSeriesStackId(seriesModel) {
        return seriesModel.get('stack') || '__ec_stack_' + seriesModel.seriesIndex;
    }

    function calBarWidthAndOffset(barSeries, api) {
        // Columns info on each category axis. Key is cartesian name
        var columnsMap = {};

        zrUtil.each(barSeries, function (seriesModel, idx) {
            var cartesian = seriesModel.coordinateSystem;

            var baseAxis = cartesian.getBaseAxis();

            var columnsOnAxis = columnsMap[baseAxis.index] || {
                remainedWidth: baseAxis.getBandWidth(),
                autoWidthCount: 0,
                categoryGap: '20%',
                gap: '30%',
                axis: baseAxis,
                stacks: {}
            };
            var stacks = columnsOnAxis.stacks;
            columnsMap[baseAxis.index] = columnsOnAxis;

            var stackId = getSeriesStackId(seriesModel);

            if (!stacks[stackId]) {
                columnsOnAxis.autoWidthCount++;
            }
            stacks[stackId] = stacks[stackId] || {
                width: 0,
                maxWidth: 0
            };

            var barWidth = seriesModel.get('barWidth');
            var barMaxWidth = seriesModel.get('barMaxWidth');
            var barGap = seriesModel.get('barGap');
            var barCategoryGap = seriesModel.get('barCategoryGap');
            // TODO
            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 baseAxis = columnsOnAxis.axis;
            var bandWidth = baseAxis.getBandWidth();
            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 (!column.width && maxWidth && maxWidth < autoWidth) {
                    maxWidth = Math.min(maxWidth, remainedWidth);
                    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 = {};

        ecModel.eachSeriesByType(seriesType, function (seriesModel) {

            var data = seriesModel.getData();
            var cartesian = seriesModel.coordinateSystem;
            var baseAxis = cartesian.getBaseAxis();

            var stackId = getSeriesStackId(seriesModel);
            var columnLayoutInfo = barWidthAndOffset[baseAxis.index][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] || [];

            data.each(valueAxis.dim, function (value, idx) {
                // 空数据
                if (isNaN(value)) {
                    return;
                }
                if (!lastStackCoords[stackId][idx]) {
                    lastStackCoords[stackId][idx] = {
                        // Positive stack
                        p: valueAxisStart,
                        // Negative stack
                        n: valueAxisStart
                    };
                }
                var sign = value >= 0 ? 'p' : 'n';
                var coord = coords[idx];
                var lastCoord = lastStackCoords[stackId][idx][sign];
                var x, y, width, height;
                if (valueAxis.isHorizontal()) {
                    x = lastCoord;
                    y = coord[1] + columnOffset;
                    width = coord[0] - lastCoord;
                    height = columnWidth;

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

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

    return barLayoutGrid;
});
define('echarts/chart/bar',['require','zrender/core/util','../coord/cartesian/Grid','./bar/BarSeries','./bar/BarView','../layout/barGrid','../echarts'],function (require) {

    var zrUtil = require('zrender/core/util');

    require('../coord/cartesian/Grid');

    require('./bar/BarSeries');
    require('./bar/BarView');

    var barLayoutGrid = require('../layout/barGrid');
    var echarts = require('../echarts');

    echarts.registerLayout(zrUtil.curry(barLayoutGrid, 'bar'));
    // Visual coding for legend
    echarts.registerVisualCoding('chart', function (ecModel) {
        ecModel.eachSeriesByType('bar', function (seriesModel) {
            var data = seriesModel.getData();
            data.setVisual('legendSymbol', 'roundRect');
        });
    });
});
define('echarts/component/axis/AxisBuilder',['require','zrender/core/util','../../util/graphic','../../model/Model','../../util/number'],function (require) {

    var zrUtil = require('zrender/core/util');
    var graphic = require('../../util/graphic');
    var Model = require('../../model/Model');
    var numberUtil = require('../../util/number');
    var remRadian = numberUtil.remRadian;
    var isRadianAroundZero = numberUtil.isRadianAroundZero;

    var PI = Math.PI;

    /**
     * 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.axisName] default get from axisModel.
     * @param {number} [opt.labelRotation] 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.silent=true]
     */
    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({
            position: opt.position.slice(),
            rotation: opt.rotation
        });
    };

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

            this.group.add(new graphic.Line({
                shape: {
                    x1: extent[0],
                    y1: 0,
                    x2: extent[1],
                    y2: 0
                },
                style: zrUtil.extend(
                    {lineCap: 'round'},
                    axisModel.getModel('axisLine.lineStyle').getLineStyle()
                ),
                strokeContainThreshold: opt.strokeContainThreshold,
                silent: !!opt.silent,
                z2: 1
            }));
        },

        /**
         * @private
         */
        axisTick: function () {
            var axisModel = this.axisModel;

            if (!axisModel.get('axisTick.show')) {
                return;
            }

            var axis = axisModel.axis;
            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();
            var tickLines = [];

            for (var i = 0; i < ticksCoords.length; i++) {
                // Only ordinal scale support tick interval
                if (ifIgnoreOnTick(axis, i, tickInterval)) {
                     continue;
                }

                var tickCoord = ticksCoords[i];

                // Tick line
                tickLines.push(new graphic.Line(graphic.subPixelOptimizeLine({
                    shape: {
                        x1: tickCoord,
                        y1: 0,
                        x2: tickCoord,
                        y2: opt.tickDirection * tickLen
                    },
                    style: {
                        lineWidth: lineStyleModel.get('width')
                    },
                    silent: true
                })));
            }

            this.group.add(graphic.mergePath(tickLines, {
                style: lineStyleModel.getLineStyle(),
                silent: true
            }));
        },

        /**
         * @param {module:echarts/coord/cartesian/AxisModel} axisModel
         * @param {module:echarts/coord/cartesian/GridModel} gridModel
         * @private
         */
        axisLabel: function () {
            var axisModel = this.axisModel;

            if (!axisModel.get('axisLabel.show')) {
                return;
            }

            var opt = this.opt;
            var axis = axisModel.axis;
            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 = opt.labelRotation;
            if (labelRotation == null) {
                labelRotation = labelModel.get('rotate') || 0;
            }
            // To radian.
            labelRotation = labelRotation * PI / 180;

            var labelLayout = innerTextLayout(opt, labelRotation, opt.labelDirection);
            var categoryData = axisModel.get('data');

            var textEls = [];
            for (var i = 0; i < ticks.length; i++) {
                if (ifIgnoreOnTick(axis, i, opt.labelInterval)) {
                     continue;
                }

                var itemTextStyleModel = textStyleModel;
                if (categoryData && categoryData[i] && categoryData[i].textStyle) {
                    itemTextStyleModel = new Model(
                        categoryData[i].textStyle, textStyleModel, axisModel.ecModel
                    );
                }

                var tickCoord = axis.dataToCoord(ticks[i]);
                var pos = [
                    tickCoord,
                    opt.labelOffset + opt.labelDirection * labelMargin
                ];

                var textEl = new graphic.Text({
                    style: {
                        text: labels[i],
                        textAlign: itemTextStyleModel.get('align', true) || labelLayout.textAlign,
                        textBaseline: itemTextStyleModel.get('baseline', true) || labelLayout.textBaseline,
                        textFont: itemTextStyleModel.getFont(),
                        fill: itemTextStyleModel.getTextColor()
                    },
                    position: pos,
                    rotation: labelLayout.rotation,
                    silent: true,
                    z2: 10
                });
                textEls.push(textEl);
                this.group.add(textEl);
            }

            function isTwoLabelOverlapped(current, next) {
                var firstRect = current && current.getBoundingRect().clone();
                var nextRect = next && next.getBoundingRect().clone();
                if (firstRect && nextRect) {
                    firstRect.applyTransform(current.getLocalTransform());
                    nextRect.applyTransform(next.getLocalTransform());
                    return firstRect.intersect(nextRect);
                }
            }
            if (axis.type !== 'category') {
                // 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
                if (axisModel.get('min')) {
                    var firstLabel = textEls[0];
                    var nextLabel = textEls[1];
                    if (isTwoLabelOverlapped(firstLabel, nextLabel)) {
                        firstLabel.ignore = true;
                    }
                }
                if (axisModel.get('max')) {
                    var lastLabel = textEls[textEls.length - 1];
                    var prevLabel = textEls[textEls.length - 2];
                    if (isTwoLabelOverlapped(prevLabel, lastLabel)) {
                        lastLabel.ignore = true;
                    }
                }
            }
        },

        /**
         * @private
         */
        axisName: function () {
            var opt = this.opt;
            var axisModel = this.axisModel;

            var name = this.opt.axisName;
            // If name is '', do not get name from axisMode.
            if (name == null) {
                name = 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;

            if (nameLocation === 'middle') {
                labelLayout = innerTextLayout(opt, opt.rotation, nameDirection);
            }
            else {
                labelLayout = endTextLayout(opt, nameLocation, extent);
            }

            this.group.add(new graphic.Text({
                style: {
                    text: name,
                    textFont: textStyleModel.getFont(),
                    fill: textStyleModel.getTextColor()
                        || axisModel.get('axisLine.lineStyle.color'),
                    textAlign: labelLayout.textAlign,
                    textBaseline: labelLayout.textBaseline
                },
                position: pos,
                rotation: labelLayout.rotation,
                silent: true,
                z2: 1
            }));
        }

    };

    /**
     * @inner
     */
    function innerTextLayout(opt, textRotation, direction) {
        var rotationDiff = remRadian(textRotation - opt.rotation);
        var textAlign;
        var textBaseline;

        if (isRadianAroundZero(rotationDiff)) { // Label is parallel with axis line.
            textBaseline = direction > 0 ? 'top' : 'bottom';
            textAlign = 'center';
        }
        else if (isRadianAroundZero(rotationDiff - PI)) { // Label is inverse parallel with axis line.
            textBaseline = direction > 0 ? 'bottom' : 'top';
            textAlign = 'center';
        }
        else {
            textBaseline = 'middle';

            if (rotationDiff > 0 && rotationDiff < PI) {
                textAlign = direction > 0 ? 'right' : 'left';
            }
            else {
                textAlign = direction > 0 ? 'left' : 'right';
            }
        }

        return {
            rotation: rotationDiff,
            textAlign: textAlign,
            textBaseline: textBaseline
        };
    }

    /**
     * @inner
     */
    function endTextLayout(opt, textPosition, extent) {
        var rotationDiff = remRadian(-opt.rotation);
        var textAlign;
        var textBaseline;
        var inverse = extent[0] > extent[1];
        var onLeft = (textPosition === 'start' && !inverse)
            || (textPosition !== 'start' && inverse);

        if (isRadianAroundZero(rotationDiff - PI / 2)) {
            textBaseline = onLeft ? 'bottom' : 'top';
            textAlign = 'center';
        }
        else if (isRadianAroundZero(rotationDiff - PI * 1.5)) {
            textBaseline = onLeft ? 'top' : 'bottom';
            textAlign = 'center';
        }
        else {
            textBaseline = 'middle';
            if (rotationDiff < PI * 1.5 && rotationDiff > PI / 2) {
                textAlign = onLeft ? 'left' : 'right';
            }
            else {
                textAlign = onLeft ? 'right' : 'left';
            }
        }

        return {
            rotation: rotationDiff,
            textAlign: textAlign,
            textBaseline: textBaseline
        };
    }

    /**
     * @static
     */
    var ifIgnoreOnTick = AxisBuilder.ifIgnoreOnTick = function (axis, i, interval) {
        return axis.scale.type === 'ordinal'
            && (typeof interval === 'function')
                && !interval(i, axis.scale.getLabel(i))
                || 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;
    };

    return AxisBuilder;

});
define('echarts/component/axis/AxisView',['require','zrender/core/util','../../util/graphic','./AxisBuilder','../../echarts'],function (require) {

    var zrUtil = require('zrender/core/util');
    var graphic = require('../../util/graphic');
    var AxisBuilder = require('./AxisBuilder');
    var ifIgnoreOnTick = AxisBuilder.ifIgnoreOnTick;
    var getInterval = AxisBuilder.getInterval;

    var axisBuilderAttrs = [
        'axisLine', 'axisLabel', 'axisTick', 'axisName'
    ];
    var selfBuilderAttrs = [
        'splitLine', 'splitArea'
    ];

    var AxisView = require('../../echarts').extendComponentView({

        type: 'axis',

        render: function (axisModel, ecModel) {

            this.group.removeAll();

            if (!axisModel.get('show')) {
                return;
            }

            var gridModel = ecModel.getComponent('grid', axisModel.get('gridIndex'));

            var layout = layoutAxis(gridModel, axisModel);

            var axisBuilder = new AxisBuilder(axisModel, layout);

            zrUtil.each(axisBuilderAttrs, axisBuilder.add, axisBuilder);

            this.group.add(axisBuilder.getGroup());

            zrUtil.each(selfBuilderAttrs, function (name) {
                if (axisModel.get(name +'.show')) {
                    this['_' + name](axisModel, gridModel, layout.labelInterval);
                }
            }, this);
        },

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

            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 = gridModel.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
                })));
            }

            // 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: {
                        stroke: lineColors[i % lineColors.length],
                        lineDash: lineStyleModel.getLineDash(),
                        lineWidth: lineWidth
                    },
                    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;

            var splitAreaModel = axisModel.getModel('splitArea');
            var areaColors = splitAreaModel.get('areaStyle.color');

            var gridRect = gridModel.coordinateSystem.getRect();
            var ticksCoords = axis.getTicksCoords();

            var prevX = ticksCoords[0];
            var prevY = ticksCoords[0];

            var splitAreaRects = [];
            var count = 0;

            var areaInterval = getInterval(splitAreaModel, labelInterval);

            areaColors = areaColors instanceof Array ? 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;
                splitAreaRects[colorIndex] = splitAreaRects[colorIndex] || [];
                splitAreaRects[colorIndex].push(new graphic.Rect({
                    shape: {
                        x: x,
                        y: y,
                        width: width,
                        height: height
                    },
                    silent: true
                }));

                prevX = x + width;
                prevY = y + height;
            }

            // Simple optimization
            // Batching the rects if color are the same
            for (var i = 0; i < splitAreaRects.length; i++) {
                this.group.add(graphic.mergePath(splitAreaRects[i], {
                    style: {
                        fill: areaColors[i % areaColors.length]
                    },
                    silent: true
                }));
            }
        }
    });

    AxisView.extend({
        type: 'xAxis'
    });
    AxisView.extend({
        type: 'yAxis'
    });

    /**
     * @inner
     */
    function layoutAxis(gridModel, axisModel) {
        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 posMap = {
            x: {top: rectBound[2], bottom: rectBound[3]},
            y: {left: rectBound[0], right: rectBound[1]}
        };
        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
        var r = {x: 0, y: 1};
        layout.rotation = Math.PI / 2 * r[axisDim];

        // 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];
        if (axis.onZero) {
            layout.labelOffset = posMap[axisDim][rawAxisPosition] - posMap[axisDim].onZero;
        }

        if (axisModel.getModel('axisTick').get('inside')) {
            layout.tickDirection = -layout.tickDirection;
        }
        if (axisModel.getModel('axisLabel').get('inside')) {
            layout.labelDirection = -layout.labelDirection;
        }

        // Special label rotation
        var labelRotation = axisModel.getModel('axisLabel').get('rotate');
        layout.labelRotation = axisPosition === 'top' ? -labelRotation : labelRotation;

        // label interval when auto mode.
        layout.labelInterval = axis.getLabelInterval();

        // Over splitLine and splitArea
        layout.z2 = 1;

        return layout;
    }
});
// TODO boundaryGap
define('echarts/component/axis',['require','../coord/cartesian/AxisModel','./axis/AxisView'],function(require) {


    require('../coord/cartesian/AxisModel');

    require('./axis/AxisView');
});
define('echarts/component/grid',['require','../util/graphic','zrender/core/util','../coord/cartesian/Grid','./axis','../echarts'],function(require) {


    var graphic = require('../util/graphic');
    var zrUtil = require('zrender/core/util');

    require('../coord/cartesian/Grid');

    require('./axis');

    // Grid view
    require('../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
                }));
            }
        }
    });
});
/**
 * 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
 */
define('echarts/chart/helper/dataSelectableMixin',['require','zrender/core/util'],function (require) {

    var zrUtil = require('zrender/core/util');

    return {

        updateSelectedMap: function () {
            var option = this.option;
            this._dataOptMap = zrUtil.reduce(option.data, function (dataOptMap, dataOpt) {
                dataOptMap[dataOpt.name] = dataOpt;
                return dataOptMap;
            }, {});
        },
        /**
         * @param {string} name
         */
        // PENGING If selectedMode is null ?
        select: function (name) {
            var dataOptMap = this._dataOptMap;
            var dataOpt = dataOptMap[name];
            var selectedMode = this.get('selectedMode');
            if (selectedMode === 'single') {
                zrUtil.each(dataOptMap, function (dataOpt) {
                    dataOpt.selected = false;
                });
            }
            dataOpt && (dataOpt.selected = true);
        },

        /**
         * @param {string} name
         */
        unSelect: function (name) {
            var dataOpt = this._dataOptMap[name];
            // var selectedMode = this.get('selectedMode');
            // selectedMode !== 'single' && dataOpt && (dataOpt.selected = false);
            dataOpt && (dataOpt.selected = false);
        },

        /**
         * @param {string} name
         */
        toggleSelected: function (name) {
            var dataOpt = this._dataOptMap[name];
            if (dataOpt != null) {
                this[dataOpt.selected ? 'unSelect' : 'select'](name);
                return dataOpt.selected;
            }
        },

        /**
         * @param {string} name
         */
        isSelected: function (name) {
            var dataOpt = this._dataOptMap[name];
            return dataOpt && dataOpt.selected;
        }
    };
});
define('echarts/chart/pie/PieSeries',['require','../../data/List','zrender/core/util','../../util/model','../../data/helper/completeDimensions','../helper/dataSelectableMixin','../../echarts'],function(require) {



    var List = require('../../data/List');
    var zrUtil = require('zrender/core/util');
    var modelUtil = require('../../util/model');
    var completeDimensions = require('../../data/helper/completeDimensions');

    var dataSelectableMixin = require('../helper/dataSelectableMixin');

    var PieSeries = require('../../echarts').extendSeriesModel({

        type: 'series.pie',

        // Overwrite
        init: function (option) {
            this.$superApply('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._dataBeforeProcessed;
            };

            this.updateSelectedMap();

            this._defaultLabelLine(option);
        },

        // Overwrite
        mergeOption: function (newOption) {
            this.$superCall('mergeOption', newOption);
            this.updateSelectedMap();
        },

        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._data;
            var params = this.$superCall('getDataParams', dataIndex);
            // FIXME toFixed?
            params.percent = +(data.get('value', dataIndex) / data.getSum('value') * 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,

            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: 20,
                    // 引导线两段中的第二段长度
                    length2: 5,
                    smooth: false,
                    lineStyle: {
                        // color: 各异,
                        width: 1,
                        type: 'solid'
                    }
                }
            },
            itemStyle: {
                normal: {
                    // color: 各异,
                    borderColor: 'rgba(0,0,0,0)',
                    borderWidth: 1
                },
                emphasis: {
                    // color: 各异,
                    borderColor: 'rgba(0,0,0,0)',
                    borderWidth: 1
                }
            },

            animationEasing: 'cubicOut',

            data: []
        }
    });

    zrUtil.mixin(PieSeries, dataSelectableMixin);

    return PieSeries;
});
define('echarts/chart/pie/PieView',['require','../../util/graphic','zrender/core/util','../../view/Chart'],function (require) {

    var graphic = require('../../util/graphic');
    var zrUtil = require('zrender/core/util');

    /**
     * @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) {
        var textStyleModel = labelModel.getModel('textStyle');
        var position = labelModel.get('position');
        var isLabelInside = position === 'inside' || position === 'inner';
        return {
            fill: textStyleModel.getTextColor()
                || (isLabelInside ? '#fff' : data.getItemVisual(idx, 'color')),
            textFont: textStyleModel.getFont(),
            text: 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);
            sector.shape.endAngle = layout.startAngle;
            graphic.updateProps(sector, {
                shape: {
                    endAngle: layout.endAngle
                }
            }, seriesModel);
        }
        else {
            graphic.updateProps(sector, {
                shape: sectorShape
            }, seriesModel);
        }

        // Update common style
        var itemStyleModel = itemModel.getModel('itemStyle');
        var visualColor = data.getItemVisual(idx, 'color');

        sector.setStyle(
            zrUtil.defaults(
                {
                    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')) {
            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);

        graphic.updateProps(labelText, {
            style: {
                x: labelLayout.x,
                y: labelLayout.y
            }
        }, seriesModel);
        labelText.attr({
            style: {
                textAlign: labelLayout.textAlign,
                textBaseline: labelLayout.textBaseline,
                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();

        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 = require('../../view/Chart').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 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);
                    if (isFirstRender) {
                        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) {
                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;
        },

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

    return Pie;
});
define('echarts/action/createDataSelectAction',['require','../echarts','zrender/core/util'],function (require) {
    var echarts = require('../echarts');
    var zrUtil = require('zrender/core/util');
    return 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
                };
            });
        });
    };
});
// Pick color from palette for each data item
define('echarts/visual/dataColor',['require'],function (require) {

    return function (seriesType, ecModel) {
        ecModel.eachSeriesByType(seriesType, function (seriesModel) {
            var colorList = seriesModel.get('color');
            var dataAll = seriesModel.getRawData();
            if (!ecModel.isSeriesFiltered(seriesModel)) {
                var data = seriesModel.getData();
                data.each(function (idx) {
                    var itemModel = data.getItemModel(idx);
                    var rawIdx = data.getRawIndex(idx);
                    // If series.itemStyle.normal.color is a function. itemVisual may be encoded
                    if (!data.getItemVisual(idx, 'color', true)) {
                        var color = itemModel.get('itemStyle.normal.color')
                            || colorList[rawIdx % colorList.length];
                        // Legend may use the visual info in data before processed
                        dataAll.setItemVisual(rawIdx, 'color', color);
                        data.setItemVisual(idx, 'color', color);
                    }
                });
            }
        });
    };
});
// FIXME emphasis label position is not same with normal label position
define('echarts/chart/pie/labelLayout',['require','zrender/contain/text'],function (require) {



    var textContain = require('zrender/contain/text');

    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 deltaX;
        //     var deltaY;
        //     var length;
        //     var lastDeltaX = dir > 0
        //         ? isDownList                // 右侧
        //             ? Number.MAX_VALUE      // 下
        //             : 0                     // 上
        //         : isDownList                // 左侧
        //             ? Number.MAX_VALUE      // 下
        //             : 0;                    // 上

        //     for (var i = 0, l = list.length; i < l; i++) {
        //         deltaY = Math.abs(list[i].y - cy);
        //         length = list[i].length;
        //         deltaX = (deltaY < r + length)
        //             ? Math.sqrt(
        //                   (r + length + 20) * (r + length + 20)
        //                   - Math.pow(list[i].y - cy, 2)
        //               )
        //             : 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(downList, true, cx, cy, r, dir);
        // changeX(upList, false, 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(leftList, cx, cy, r, -1, viewWidth, viewHeight);
        adjustSingleSide(rightList, cx, cy, r, 1, viewWidth, viewHeight);

        for (var i = 0; i < labelLayoutList.length; i++) {
            var linePoints = labelLayoutList[i].linePoints;
            if (linePoints) {
                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;
            }
        }
    }

    return 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');
            var labelPosition = labelModel.get('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;

            if (labelPosition === 'center') {
                textX = layout.cx;
                textY = layout.cy;
                textAlign = 'center';
            }
            else {
                var isLabelInside = labelPosition === 'inside' || labelPosition === 'inner';
                var x1 = (isLabelInside ? layout.r / 2 * dx : layout.r * dx) + cx;
                var y1 = (isLabelInside ? layout.r / 2 * dy : layout.r * dy) + cy;

                // For roseType
                labelLineLen += r - layout.r;

                textX = x1 + dx * 3;
                textY = y1 + dy * 3;

                if (!isLabelInside) {
                    var x2 = x1 + dx * labelLineLen;
                    var y2 = y1 + dy * labelLineLen;
                    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 textBaseline = 'middle';
            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, textBaseline
            );
            hasLabelRotate = !!labelRotate;
            layout.label = {
                x: textX,
                y: textY,
                height: textRect.height,
                length: labelLineLen,
                length2: labelLineLen2,
                linePoints: linePoints,
                textAlign: textAlign,
                textBaseline: textBaseline,
                font: font,
                rotation: labelRotate
            };

            labelLayoutList.push(layout.label);
        });
        if (!hasLabelRotate && seriesModel.get('avoidLabelOverlap')) {
            avoidOverlap(labelLayoutList, cx, cy, r, viewWidth, viewHeight);
        }
    };
});
// TODO minAngle

define('echarts/chart/pie/pieLayout',['require','../../util/number','./labelLayout','zrender/core/util'],function (require) {

    var numberUtil = require('../../util/number');
    var parsePercent = numberUtil.parsePercent;
    var labelLayout = require('./labelLayout');
    var zrUtil = require('zrender/core/util');

    var PI2 = Math.PI * 2;
    var RADIAN = Math.PI / 180;

    return function (seriesType, ecModel, api) {
        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 sum = data.getSum('value');
            if (sum === 0) {
                sum = data.count();
            }
            var unitRadian = Math.PI / sum * 2;

            var clockwise = seriesModel.get('clockwise');

            var roseType = seriesModel.get('roseType');

            // [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;
                // FIXME 兼容 2.0 但是 roseType 是 area 的时候才是这样？
                if (roseType !== 'area') {
                    angle = sum === 0 ? unitRadian : (value * unitRadian);
                }
                else {
                    angle = PI2 / (data.count() || 1);
                }

                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) {
                // Average the angle if rest angle is not enough after all angles is
                // Constrained by minAngle
                if (restAngle <= 1e-3) {
                    var angle = PI2 / data.count();
                    data.each(function (idx) {
                        var layout = data.getItemLayout(idx);
                        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) {
                        var layout = data.getItemLayout(idx);
                        var angle = layout.angle === minAngle
                            ? minAngle : value * unitRadian;
                        layout.startAngle = currentAngle;
                        layout.endAngle = currentAngle + dir * angle;
                        currentAngle += angle;
                    });
                }
            }

            labelLayout(seriesModel, r, width, height);
        });
    };
});
define('echarts/processor/dataFilter',[],function () {
    return 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);
    };
});
define('echarts/chart/pie',['require','zrender/core/util','../echarts','./pie/PieSeries','./pie/PieView','../action/createDataSelectAction','../visual/dataColor','./pie/pieLayout','../processor/dataFilter'],function (require) {

    var zrUtil = require('zrender/core/util');
    var echarts = require('../echarts');

    require('./pie/PieSeries');
    require('./pie/PieView');

    require('../action/createDataSelectAction')('pie', [{
        type: 'pieToggleSelect',
        event: 'pieselectchanged',
        method: 'toggleSelected'
    }, {
        type: 'pieSelect',
        event: 'pieselected',
        method: 'select'
    }, {
        type: 'pieUnSelect',
        event: 'pieunselected',
        method: 'unSelect'
    }]);

    echarts.registerVisualCoding(
        'chart',  zrUtil.curry(require('../visual/dataColor'), 'pie')
    );

    echarts.registerLayout(zrUtil.curry(
        require('./pie/pieLayout'), 'pie'
    ));

    echarts.registerProcessor(
        'filter', zrUtil.curry(require('../processor/dataFilter'), 'pie')
    );
});
define('echarts/chart/scatter/ScatterSeries',['require','../helper/createListFromArray','../../model/Series'],function (require) {



    var createListFromArray = require('../helper/createListFromArray');
    var SeriesModel = require('../../model/Series');

    return SeriesModel.extend({

        type: 'series.scatter',

        dependencies: ['grid', 'polar'],

        getInitialData: function (option, ecModel) {
            var list = createListFromArray(option.data, this, ecModel);
            return list;
        },

        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: 各异
                }
            }
        }
    });
});
define('echarts/chart/helper/LargeSymbolDraw',['require','../../util/graphic','../../util/symbol','zrender/core/util'],function (require) {

    var graphic = require('../../util/graphic');
    var symbolUtil = require('../../util/symbol');
    var zrUtil = require('zrender/core/util');

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

    function LargeSymbolDraw() {
        this.group = new graphic.Group();

        this._symbolEl = new LargeSymbolPath({
            silent: true
        });
    }

    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 (!zrUtil.isArray(size)) {
                        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.setStyle(
            seriesModel.getModel('itemStyle.normal').getItemStyle(['color'])
        );

        var visualColor = data.getVisual('color');
        if (visualColor) {
            symbolEl.setColor(visualColor);
        }

        // Add back
        this.group.add(this._symbolEl);
    };

    largeSymbolProto.updateLayout = function (seriesModel) {
        var data = seriesModel.getData();
        this._symbolEl.setShape({
            points: data.mapArray(data.getItemLayout)
        });
    };

    largeSymbolProto.remove = function () {
        this.group.removeAll();
    };

    return LargeSymbolDraw;
});
define('echarts/chart/scatter/ScatterView',['require','../helper/SymbolDraw','../helper/LargeSymbolDraw','../../echarts'],function (require) {

    var SymbolDraw = require('../helper/SymbolDraw');
    var LargeSymbolDraw = require('../helper/LargeSymbolDraw');

    require('../../echarts').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 () {
            this._symbolDraw.updateLayout();
        },

        remove: function (ecModel, api) {
            this._symbolDraw && this._symbolDraw.remove(api, true);
        }
    });
});
define('echarts/chart/scatter',['require','zrender/core/util','../echarts','./scatter/ScatterSeries','./scatter/ScatterView','../visual/symbol','../layout/points'],function (require) {

    var zrUtil = require('zrender/core/util');
    var echarts = require('../echarts');

    require('./scatter/ScatterSeries');
    require('./scatter/ScatterView');

    echarts.registerVisualCoding('chart', zrUtil.curry(
        require('../visual/symbol'), 'scatter', 'circle', null
    ));
    echarts.registerLayout(zrUtil.curry(
        require('../layout/points'), 'scatter'
    ));
});
define('echarts/component/tooltip/TooltipModel',['require','../../echarts'],function (require) {

    require('../../echarts').extendComponentModel({

        type: 'tooltip',

        defaultOption: {
            zlevel: 0,

            z: 8,

            show: true,

            // tooltip主体内容
            showContent: true,

            // 触发类型，默认数据触发，见下图，可选为：'item' ¦ 'axis'
            trigger: 'item',

            // 触发条件，支持 'click' | 'mousemove'
            triggerOn: 'mousemove',

            // 是否永远显示 content
            alwaysShowContent: false,

            // 位置 {Array} | {Function}
            // position: null

            // 内容格式器：{string}（Template） ¦ {Function}
            // formatter: null

            // 隐藏延迟，单位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,

            // 坐标轴指示器，坐标轴触发有效
            axisPointer: {
                // 默认为直线
                // 可选为：'line' | 'shadow' | 'cross'
                type: 'line',

                // type 为 line 的时候有效，指定 tooltip line 所在的轴，可选
                // 可选 'x' | 'y' | 'angle' | 'radius' | 'auto'
                // 默认 'auto'，会选择类型为 cateogry 的轴，对于双数值轴，笛卡尔坐标系会默认选择 x 轴
                // 极坐标系会默认选择 angle 轴
                axis: 'auto',

                animation: true,
                animationDurationUpdate: 200,
                animationEasingUpdate: 'exponentialOut',

                // 直线指示器样式设置
                lineStyle: {
                    color: '#555',
                    width: 1,
                    type: 'solid'
                },

                crossStyle: {
                    color: '#555',
                    width: 1,
                    type: 'dashed',

                    // TODO formatter
                    textStyle: {}
                },

                // 阴影指示器样式设置
                shadowStyle: {
                    color: 'rgba(150,150,150,0.3)'
                }
            },
            textStyle: {
                color: '#fff',
                fontSize: 14
            }
        }
    });
});
/**
 * @module echarts/component/tooltip/TooltipContent
 */
define('echarts/component/tooltip/TooltipContent',['require','zrender/core/util','zrender/tool/color','zrender/core/event','../../util/format'],function (require) {

    var zrUtil = require('zrender/core/util');
    var zrColor = require('zrender/tool/color');
    var eventUtil = require('zrender/core/event');
    var formatUtil = require('../../util/format');
    var each = zrUtil.each;
    var toCamelCase = formatUtil.toCamelCase;

    var vendors = ['', '-webkit-', '-moz-', '-o-'];

    var gCssText = 'position:absolute;display:block;border-style:solid;white-space:nowrap;';

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

        tooltipModel = 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
        transitionDuration &&
            cssText.push(assembleTransition(transitionDuration));

        if (backgroundColor) {
            // for ie
            cssText.push(
                'background-Color:' + zrColor.toHex(backgroundColor)
            );
            cssText.push('filter:alpha(opacity=70)');
            cssText.push('background-Color:' + backgroundColor);
        }

        // 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 = 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) {
            if (!self.enterable) {
                // Try trigger zrender event to avoid mouse
                // in and out shape too frequently
                var handler = zr.handler;
                eventUtil.normalizeEvent(container, e);
                handler.dispatch('mousemove', e);
            }
        };
        el.onmouseleave = function () {
            if (self.enterable) {
                if (self._show) {
                    self.hideLater(self._hideDelay);
                }
            }
            self._inContent = false;
        };

        compromiseMobile(el, container);
    }

    function compromiseMobile(tooltipContentEl, container) {
        // Prevent default behavior on mobile. For example,
        // defuault pinch gesture will cause browser zoom.
        // We do not preventing event on tooltip contnet el,
        // because user may need customization in tooltip el.
        eventUtil.addEventListener(container, 'touchstart', preventDefault);
        eventUtil.addEventListener(container, 'touchmove', preventDefault);
        eventUtil.addEventListener(container, 'touchend', preventDefault);

        function preventDefault(e) {
            if (contains(e.target)) {
                e.preventDefault();
            }
        }

        function contains(targetEl) {
            while (targetEl && targetEl !== container) {
                if (targetEl === tooltipContentEl) {
                    return true;
                }
                targetEl = targetEl.parentNode;
            }
        }
    }

    TooltipContent.prototype = {

        constructor: TooltipContent,

        enterable: true,

        /**
         * Update when tooltip is rendered
         */
        update: function () {
            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);

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

            this._show = true;
        },

        setContent: function (content) {
            var el = this.el;
            el.innerHTML = content;
            el.style.display = content ? 'block' : 'none';
        },

        moveTo: function (x, y) {
            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;
        },

        // showLater: function ()

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

    return TooltipContent;
});
define('echarts/component/tooltip/TooltipView',['require','./TooltipContent','../../util/graphic','zrender/core/util','../../util/format','../../util/number','../../echarts'],function (require) {

    var TooltipContent = require('./TooltipContent');
    var graphic = require('../../util/graphic');
    var zrUtil = require('zrender/core/util');
    var formatUtil = require('../../util/format');
    var numberUtil = require('../../util/number');
    var parsePercent = numberUtil.parsePercent;

    function dataEqual(a, b) {
        if (!a || !b) {
            return false;
        }
        var round = numberUtil.round;
        return round(a[0]) === round(b[0])
            && round(a[1]) === round(b[1]);
    }
    /**
     * @inner
     */
    function makeLineShape(x1, y1, x2, y2) {
        return {
            x1: x1,
            y1: y1,
            x2: x2,
            y2: y2
        };
    }

    /**
     * @inner
     */
    function makeRectShape(x, y, width, height) {
        return {
            x: x,
            y: y,
            width: width,
            height: height
        };
    }

    /**
     * @inner
     */
    function makeSectorShape(cx, cy, r0, r, startAngle, endAngle) {
        return {
            cx: cx,
            cy: cy,
            r0: r0,
            r: r,
            startAngle: startAngle,
            endAngle: endAngle,
            clockwise: true
        };
    }

    function refixTooltipPosition(x, y, el, viewWidth, viewHeight) {
        var width = el.clientWidth;
        var height = el.clientHeight;
        var gap = 20;

        if (x + width + gap > viewWidth) {
            x -= width + gap;
        }
        else {
            x += gap;
        }
        if (y + height + gap > viewHeight) {
            y -= height + gap;
        }
        else {
            y += gap;
        }
        return [x, y];
    }

    function calcTooltipPosition(position, rect, dom) {
        var domWidth = dom.clientWidth;
        var domHeight = dom.clientHeight;
        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];
    }

    /**
     * @param  {string|Function|Array.<number>} positionExpr
     * @param  {number} x Mouse x
     * @param  {number} y Mouse y
     * @param  {module:echarts/component/tooltip/TooltipContent} content
     * @param  {Object|<Array.<Object>} params
     * @param  {module:zrender/Element} el target element
     * @param  {module:echarts/ExtensionAPI} api
     * @return {Array.<number>}
     */
    function updatePosition(positionExpr, x, y, content, params, el, api) {
        var viewWidth = api.getWidth();
        var viewHeight = api.getHeight();

        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 positiont
            positionExpr = positionExpr([x, y], params, rect);
        }

        if (zrUtil.isArray(positionExpr)) {
            x = parsePercent(positionExpr[0], viewWidth);
            y = parsePercent(positionExpr[1], viewHeight);
        }
        // Specify tooltip position by string 'top' 'bottom' 'left' 'right' around graphic element
        else if (typeof positionExpr === 'string' && el) {
            var pos = calcTooltipPosition(
                positionExpr, rect, content.el
            );
            x = pos[0];
            y = pos[1];
        }
        else {
            var pos = refixTooltipPosition(
                x, y, content.el, viewWidth, viewHeight
            );
            x = pos[0];
            y = pos[1];
        }

        content.moveTo(x, y);
    }

    function ifSeriesSupportAxisTrigger(seriesModel) {
        var coordSys = seriesModel.coordinateSystem;
        var trigger = seriesModel.get('tooltip.trigger', true);
        // Ignore series use item tooltip trigger and series coordinate system is not cartesian or
        return !(!coordSys
            || (coordSys.type !== 'cartesian2d' && coordSys.type !== 'polar')
            || trigger === 'item');
    }

    require('../../echarts').extendComponentView({

        type: 'tooltip',

        _axisPointers: {},

        init: function (ecModel, api) {
            var tooltipContent = new TooltipContent(api.getDom(), api);
            this._tooltipContent = tooltipContent;

            api.on('showTip', this._manuallyShowTip, this);
            api.on('hideTip', this._hide, this);
        },

        render: function (tooltipModel, ecModel, api) {

            // Reset
            this.group.removeAll();

            /**
             * @type {Object}
             * @private
             */
            this._axisPointers = {};

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

            /**
             * @type {Object}
             * @private
             */
            this._lastHover = {
                // data
                // payloadBatch
            };

            var tooltipContent = this._tooltipContent;
            tooltipContent.update();
            tooltipContent.enterable = tooltipModel.get('enterable');

            this._alwaysShowContent = tooltipModel.get('alwaysShowContent');

            /**
             * @type {Object.<string, Array>}
             */
            this._seriesGroupByAxis = this._prepareAxisTriggerData(
                tooltipModel, ecModel
            );

            var crossText = this._crossText;
            if (crossText) {
                this.group.add(crossText);
            }

            var zr = this._api.getZr();
            var tryShow = this._tryShow;
            zr.off('click', tryShow);
            zr.off('mousemove', tryShow);
            zr.off('mouseout', this._hide);
            if (tooltipModel.get('triggerOn') === 'click') {
                zr.on('click', tryShow, this);
            }
            else {
                zr.on('mousemove', tryShow, this);
                zr.on('mouseout', this._hide, this);
            }
        },

        /**
         * Show tip manually by
         *  dispatchAction({
         *      type: 'showTip',
         *      x: 10,
         *      y: 10
         *  });
         * Or
         *  dispatchAction({
         *      type: 'showTip',
         *      seriesIndex: 0,
         *      dataIndex: 1
         *  });
         */
        _manuallyShowTip: function (event) {
            // From self
            if (event.from === this.uid) {
                return;
            }

            var ecModel = this._ecModel;
            var seriesIndex = event.seriesIndex;
            var dataIndex = event.dataIndex;
            var seriesModel = ecModel.getSeriesByIndex(seriesIndex);
            var api = this._api;

            if (event.x == null || event.y == null) {
                if (!seriesModel) {
                    // Find the first series can use axis trigger
                    ecModel.eachSeries(function (_series) {
                        if (ifSeriesSupportAxisTrigger(_series) && !seriesModel) {
                            seriesModel = _series;
                        }
                    });
                }
                if (seriesModel) {
                    var data = seriesModel.getData();
                    if (dataIndex == null) {
                        dataIndex = data.indexOfName(event.name);
                    }
                    var el = data.getItemGraphicEl(dataIndex);
                    // Use
                    if (el) {
                        // Use graphic bounding rect
                        var rect = el.getBoundingRect().clone();
                        rect.applyTransform(el.transform);
                        var cx = rect.x + rect.width / 2;
                        var cy = rect.y + rect.height / 2;

                        this._tryShow({
                            offsetX: cx,
                            offsetY: cy,
                            target: el,
                            event: {}
                        });
                    }
                }
            }
            else {
                // Use zrender handler to trigger event
                api.getZr().handler.dispatch('mousemove', {
                    zrX: event.x,
                    zrY: event.y
                });
            }
        },

        _prepareAxisTriggerData: function (tooltipModel, ecModel) {
            // Prepare data for axis trigger
            var seriesGroupByAxis = {};
            ecModel.eachSeries(function (seriesModel) {
                if (ifSeriesSupportAxisTrigger(seriesModel)) {
                    var coordSys = seriesModel.coordinateSystem;
                    var baseAxis;
                    var key;

                    // Only cartesian2d and polar support axis trigger
                    if (coordSys.type === 'cartesian2d') {
                        // FIXME `axisPointer.axis` is not baseAxis
                        baseAxis = coordSys.getBaseAxis();
                        key = baseAxis.dim + baseAxis.index;
                    }
                    else {
                        baseAxis = coordSys.getBaseAxis();
                        key = baseAxis.dim + coordSys.name;
                    }

                    seriesGroupByAxis[key] = seriesGroupByAxis[key] || {
                        coordSys: [],
                        series: []
                    };
                    seriesGroupByAxis[key].coordSys.push(coordSys);
                    seriesGroupByAxis[key].series.push(seriesModel);
                }
            }, this);

            return seriesGroupByAxis;
        },

        /**
         * mousemove handler
         * @param {Object} e
         * @private
         */
        _tryShow: function (e) {
            var el = e.target;
            var tooltipModel = this._tooltipModel;
            var globalTrigger = tooltipModel.get('trigger');
            var ecModel = this._ecModel;
            var api = this._api;

            if (!tooltipModel) {
                return;
            }

            // Always show item tooltip if mouse is on the element with dataIndex
            if (el && el.dataIndex != null) {
                // Use hostModel 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 hostModel = el.hostModel || ecModel.getSeriesByIndex(el.seriesIndex);
                var dataIndex = el.dataIndex;
                var itemModel = hostModel.getData().getItemModel(dataIndex);
                // Series or single data may use item trigger when global is axis trigger
                if ((itemModel.get('tooltip.trigger') || globalTrigger) === 'axis') {
                    this._showAxisTooltip(tooltipModel, ecModel, e);
                }
                else {
                    // Reset ticket
                    this._ticket = '';
                    // If either single data or series use item trigger
                    this._hideAxisPointer();
                    // Reset last hover and dispatch downplay action
                    this._resetLastHover();

                    this._showItemTooltipContent(hostModel, dataIndex, e);
                }

                api.dispatchAction({
                    type: 'showTip',
                    from: this.uid,
                    dataIndex: el.dataIndex,
                    seriesIndex: el.seriesIndex
                });
            }
            else {
                if (globalTrigger === 'item') {
                    this._hide();
                }
                else {
                    // Try show axis tooltip
                    this._showAxisTooltip(tooltipModel, ecModel, e);
                }

                api.dispatchAction({
                    type: 'showTip',
                    from: this.uid,
                    x: e.offsetX,
                    y: e.offsetY
                });
            }
        },

        /**
         * Show tooltip on axis
         * @param {module:echarts/component/tooltip/TooltipModel} tooltipModel
         * @param {module:echarts/model/Global} ecModel
         * @param {Object} e
         * @private
         */
        _showAxisTooltip: function (tooltipModel, ecModel, e) {
            var axisPointerModel = tooltipModel.getModel('axisPointer');
            var axisPointerType = axisPointerModel.get('type');

            if (axisPointerType === 'cross') {
                var el = e.target;
                if (el && el.dataIndex != null) {
                    var seriesModel = ecModel.getSeriesByIndex(el.seriesIndex);
                    var dataIndex = el.dataIndex;
                    this._showItemTooltipContent(seriesModel, dataIndex, e);
                }
            }

            this._showAxisPointer();
            var allNotShow = true;
            zrUtil.each(this._seriesGroupByAxis, function (seriesCoordSysSameAxis) {
                // Try show the axis pointer
                var allCoordSys = seriesCoordSysSameAxis.coordSys;
                var coordSys = allCoordSys[0];

                // If mouse position is not in the grid or polar
                var point = [e.offsetX, e.offsetY];

                if (!coordSys.containPoint(point)) {
                    // Hide axis pointer
                    this._hideAxisPointer(coordSys.name);
                    return;
                }

                allNotShow = false;
                // Make sure point is discrete on cateogry axis
                var dimensions = coordSys.dimensions;
                var value = coordSys.pointToData(point, true);
                point = coordSys.dataToPoint(value);
                var baseAxis = coordSys.getBaseAxis();
                var axisType = axisPointerModel.get('axis');
                if (axisType === 'auto') {
                    axisType = baseAxis.dim;
                }

                var contentNotChange = false;
                var lastHover = this._lastHover;
                if (axisPointerType === 'cross') {
                    // If hover data not changed
                    // Possible when two axes are all category
                    if (dataEqual(lastHover.data, value)) {
                        contentNotChange = true;
                    }
                    lastHover.data = value;
                }
                else {
                    var valIndex = zrUtil.indexOf(dimensions, axisType);
                    // If hover data not changed on the axis dimension
                    if (lastHover.data === value[valIndex]) {
                        contentNotChange = true;
                    }
                    lastHover.data = value[valIndex];
                }

                if (coordSys.type === 'cartesian2d' && !contentNotChange) {
                    this._showCartesianPointer(
                        axisPointerModel, coordSys, axisType, point
                    );
                }
                else if (coordSys.type === 'polar' && !contentNotChange) {
                    this._showPolarPointer(
                        axisPointerModel, coordSys, axisType, point
                    );
                }

                if (axisPointerType !== 'cross') {
                    this._showSeriesTooltipContent(
                        coordSys, seriesCoordSysSameAxis.series, point, value, contentNotChange
                    );
                }
            }, this);

            if (allNotShow) {
                this._hide();
            }
        },

        /**
         * Show tooltip on axis of cartesian coordinate
         * @param {module:echarts/model/Model} axisPointerModel
         * @param {module:echarts/coord/cartesian/Cartesian2D} cartesians
         * @param {string} axisType
         * @param {Array.<number>} point
         * @private
         */
        _showCartesianPointer: function (axisPointerModel, cartesian, axisType, point) {
            var self = this;

            var axisPointerType = axisPointerModel.get('type');
            var moveAnimation = axisPointerType !== 'cross';

            if (axisPointerType === 'cross') {
                moveGridLine('x', point, cartesian.getAxis('y').getGlobalExtent());
                moveGridLine('y', point, cartesian.getAxis('x').getGlobalExtent());

                this._updateCrossText(cartesian, point, axisPointerModel);
            }
            else {
                var otherAxis = cartesian.getAxis(axisType === 'x' ? 'y' : 'x');
                var otherExtent = otherAxis.getGlobalExtent();

                if (cartesian.type === 'cartesian2d') {
                    (axisPointerType === 'line' ? moveGridLine : moveGridShadow)(
                        axisType, point, otherExtent
                    );
                }
            }

            /**
             * @inner
             */
            function moveGridLine(axisType, point, otherExtent) {
                var targetShape = axisType === 'x'
                    ? makeLineShape(point[0], otherExtent[0], point[0], otherExtent[1])
                    : makeLineShape(otherExtent[0], point[1], otherExtent[1], point[1]);

                var pointerEl = self._getPointerElement(
                    cartesian, axisPointerModel, axisType, targetShape
                );
                moveAnimation
                    ? graphic.updateProps(pointerEl, {
                        shape: targetShape
                    }, axisPointerModel)
                    :  pointerEl.attr({
                        shape: targetShape
                    });
            }

            /**
             * @inner
             */
            function moveGridShadow(axisType, point, otherExtent) {
                var axis = cartesian.getAxis(axisType);
                var bandWidth = axis.getBandWidth();
                var span = otherExtent[1] - otherExtent[0];
                var targetShape = axisType === 'x'
                    ? makeRectShape(point[0] - bandWidth / 2, otherExtent[0], bandWidth, span)
                    : makeRectShape(otherExtent[0], point[1] - bandWidth / 2, span, bandWidth);

                var pointerEl = self._getPointerElement(
                    cartesian, axisPointerModel, axisType, targetShape
                );
                moveAnimation
                    ? graphic.updateProps(pointerEl, {
                        shape: targetShape
                    }, axisPointerModel)
                    :  pointerEl.attr({
                        shape: targetShape
                    });
            }
        },

        /**
         * Show tooltip on axis of polar coordinate
         * @param {module:echarts/model/Model} axisPointerModel
         * @param {Array.<module:echarts/coord/polar/Polar>} polar
         * @param {string} axisType
         * @param {Array.<number>} point
         */
        _showPolarPointer: function (axisPointerModel, polar, axisType, point) {
            var self = this;

            var axisPointerType = axisPointerModel.get('type');

            var angleAxis = polar.getAngleAxis();
            var radiusAxis = polar.getRadiusAxis();

            var moveAnimation = axisPointerType !== 'cross';

            if (axisPointerType === 'cross') {
                movePolarLine('angle', point, radiusAxis.getExtent());
                movePolarLine('radius', point, angleAxis.getExtent());

                this._updateCrossText(polar, point, axisPointerModel);
            }
            else {
                var otherAxis = polar.getAxis(axisType === 'radius' ? 'angle' : 'radius');
                var otherExtent = otherAxis.getExtent();

                (axisPointerType === 'line' ? movePolarLine : movePolarShadow)(
                    axisType, point, otherExtent
                );
            }
            /**
             * @inner
             */
            function movePolarLine(axisType, point, otherExtent) {
                var mouseCoord = polar.pointToCoord(point);

                var targetShape;

                if (axisType === 'angle') {
                    var p1 = polar.coordToPoint([otherExtent[0], mouseCoord[1]]);
                    var p2 = polar.coordToPoint([otherExtent[1], mouseCoord[1]]);
                    targetShape = makeLineShape(p1[0], p1[1], p2[0], p2[1]);
                }
                else {
                    targetShape = {
                        cx: polar.cx,
                        cy: polar.cy,
                        r: mouseCoord[0]
                    };
                }

                var pointerEl = self._getPointerElement(
                    polar, axisPointerModel, axisType, targetShape
                );

                moveAnimation
                    ? graphic.updateProps(pointerEl, {
                        shape: targetShape
                    }, axisPointerModel)
                    :  pointerEl.attr({
                        shape: targetShape
                    });
            }

            /**
             * @inner
             */
            function movePolarShadow(axisType, point, otherExtent) {
                var axis = polar.getAxis(axisType);
                var bandWidth = axis.getBandWidth();

                var mouseCoord = polar.pointToCoord(point);

                var targetShape;

                var radian = Math.PI / 180;

                if (axisType === 'angle') {
                    targetShape = makeSectorShape(
                        polar.cx, polar.cy,
                        otherExtent[0], otherExtent[1],
                        // In ECharts y is negative if angle is positive
                        (-mouseCoord[1] - bandWidth / 2) * radian,
                        (-mouseCoord[1] + bandWidth / 2) * radian
                    );
                }
                else {
                    targetShape = makeSectorShape(
                        polar.cx, polar.cy,
                        mouseCoord[0] - bandWidth / 2,
                        mouseCoord[0] + bandWidth / 2,
                        0, Math.PI * 2
                    );
                }

                var pointerEl = self._getPointerElement(
                    polar, axisPointerModel, axisType, targetShape
                );
                moveAnimation
                    ? graphic.updateProps(pointerEl, {
                        shape: targetShape
                    }, axisPointerModel)
                    :  pointerEl.attr({
                        shape: targetShape
                    });
            }
        },

        _updateCrossText: function (coordSys, point, axisPointerModel) {
            var crossStyleModel = axisPointerModel.getModel('crossStyle');
            var textStyleModel = crossStyleModel.getModel('textStyle');

            var tooltipModel = this._tooltipModel;

            var text = this._crossText;
            if (!text) {
                text = this._crossText = new graphic.Text({
                    style: {
                        textAlign: 'left',
                        textBaseline: 'bottom'
                    }
                });
                this.group.add(text);
            }

            var value = coordSys.pointToData(point);

            var dims = coordSys.dimensions;
            value = zrUtil.map(value, function (val, idx) {
                var axis = coordSys.getAxis(dims[idx]);
                if (axis.type === 'category' || axis.type === 'time') {
                    val = axis.scale.getLabel(val);
                }
                else {
                    val = formatUtil.addCommas(
                        val.toFixed(axis.getPixelPrecision())
                    );
                }
                return val;
            });

            text.setStyle({
                fill: textStyleModel.getTextColor() || crossStyleModel.get('color'),
                textFont: textStyleModel.getFont(),
                text: value.join(', '),
                x: point[0] + 5,
                y: point[1] - 5
            });
            text.z = tooltipModel.get('z');
            text.zlevel = tooltipModel.get('zlevel');
        },

        _getPointerElement: function (coordSys, pointerModel, axisType, initShape) {
            var tooltipModel = this._tooltipModel;
            var z = tooltipModel.get('z');
            var zlevel = tooltipModel.get('zlevel');
            var axisPointers = this._axisPointers;
            var coordSysName = coordSys.name;
            axisPointers[coordSysName] = axisPointers[coordSysName] || {};
            if (axisPointers[coordSysName][axisType]) {
                return axisPointers[coordSysName][axisType];
            }

            // Create if not exists
            var pointerType = pointerModel.get('type');
            var styleModel = pointerModel.getModel(pointerType + 'Style');
            var isShadow = pointerType === 'shadow';
            var style = styleModel[isShadow ? 'getAreaStyle' : 'getLineStyle']();

            var elementType = coordSys.type === 'polar'
                ? (isShadow ? 'Sector' : (axisType === 'radius' ? 'Circle' : 'Line'))
                : (isShadow ? 'Rect' : 'Line');

           isShadow ? (style.stroke = null) : (style.fill = null);

            var el = axisPointers[coordSysName][axisType] = new graphic[elementType]({
                style: style,
                z: z,
                zlevel: zlevel,
                silent: true,
                shape: initShape
            });

            this.group.add(el);
            return el;
        },

        /**
         * Show tooltip on item
         * @param {Array.<module:echarts/model/Series>} seriesList
         * @param {Array.<number>} point
         * @param {Array.<number>} value
         * @param {boolean} contentNotChange
         * @param {Object} e
         */
        _showSeriesTooltipContent: function (
            coordSys, seriesList, point, value, contentNotChange
        ) {

            var rootTooltipModel = this._tooltipModel;
            var tooltipContent = this._tooltipContent;

            var baseAxis = coordSys.getBaseAxis();
            // FIXME
            // Dont case by case
            var val = value[baseAxis.dim === 'x' || baseAxis.dim === 'radius' ? 0 : 1];

            var payloadBatch = zrUtil.map(seriesList, function (series) {
                return {
                    seriesIndex: series.seriesIndex,
                    dataIndex: series.getData().indexOfNearest(
                        series.getDimensionsOnAxis(baseAxis.dim),
                        val
                    )
                };
            });

            var api = this._api;

            var lastHover = this._lastHover;
            if (lastHover.payloadBatch && !contentNotChange) {
                this._api.dispatchAction({
                    type: 'downplay',
                    batch: zrUtil.clone(lastHover.payloadBatch)
                });
            }
            // Dispatch highlight action
            if (!contentNotChange) {
                this._api.dispatchAction({
                    type: 'highlight',
                    batch: zrUtil.clone(payloadBatch)
                });
                lastHover.payloadBatch = payloadBatch;
            }

            if (baseAxis && rootTooltipModel.get('showContent')) {

                var formatter = rootTooltipModel.get('formatter');
                var positionExpr = rootTooltipModel.get('position');
                var html;

                var paramsList = zrUtil.map(seriesList, function (series, index) {
                    return series.getDataParams(payloadBatch[index].dataIndex);
                });
                // If only one series
                // FIXME
                // if (paramsList.length === 1) {
                //     paramsList = paramsList[0];
                // }

                tooltipContent.show(rootTooltipModel);

                // Update html content
                var fitstDataIndex = payloadBatch[0].dataIndex;
                if (!contentNotChange) {
                    // Reset ticket
                    this._ticket = '';
                    if (!formatter) {
                        // Default tooltip content
                        // FIXME shold be the first data which has name?
                        html = seriesList[0].getData().getName(fitstDataIndex) + '<br />'
                            + zrUtil.map(seriesList, function (series, index) {
                                return series.formatTooltip(payloadBatch[index].dataIndex, true);
                            }).join('<br />');
                    }
                    else {
                        if (typeof formatter === 'string') {
                            html = formatUtil.formatTpl(formatter, paramsList);
                        }
                        else if (typeof formatter === 'function') {
                            var self = this;
                            var ticket = 'axis_' + coordSys.name + '_' + fitstDataIndex;
                            var callback = function (cbTicket, html) {
                                if (cbTicket === self._ticket) {
                                    tooltipContent.setContent(html);

                                    updatePosition(
                                        positionExpr, point[0], point[1],
                                        tooltipContent, paramsList, null, api
                                    );
                                }
                            };
                            self._ticket = ticket;
                            html = formatter(paramsList, ticket, callback);
                        }
                    }

                    tooltipContent.setContent(html);
                }

                updatePosition(
                    positionExpr, point[0], point[1],
                    tooltipContent, paramsList, null, api
                );
            }
        },

        /**
         * Show tooltip on item
         * @param {module:echarts/model/Series} seriesModel
         * @param {number} dataIndex
         * @param {Object} e
         */
        _showItemTooltipContent: function (seriesModel, dataIndex, e) {
            // FIXME Graph data
            var api = this._api;
            var data = seriesModel.getData();
            var itemModel = data.getItemModel(dataIndex);

            var rootTooltipModel = this._tooltipModel;

            var tooltipContent = this._tooltipContent;

            var tooltipModel = itemModel.getModel('tooltip');

            // If series model
            if (tooltipModel.parentModel) {
                tooltipModel.parentModel.parentModel = rootTooltipModel;
            }
            else {
                tooltipModel.parentModel = this._tooltipModel;
            }

            if (tooltipModel.get('showContent')) {
                var formatter = tooltipModel.get('formatter');
                var positionExpr = tooltipModel.get('position');
                var params = seriesModel.getDataParams(dataIndex);
                var html;
                if (!formatter) {
                    html = seriesModel.formatTooltip(dataIndex);
                }
                else {
                    if (typeof formatter === 'string') {
                        html = formatUtil.formatTpl(formatter, params);
                    }
                    else if (typeof formatter === 'function') {
                        var self = this;
                        var ticket = 'item_' + seriesModel.name + '_' + dataIndex;
                        var callback = function (cbTicket, html) {
                            if (cbTicket === self._ticket) {
                                tooltipContent.setContent(html);

                                updatePosition(
                                    positionExpr, e.offsetX, e.offsetY,
                                    tooltipContent, params, e.target, api
                                );
                            }
                        };
                        self._ticket = ticket;
                        html = formatter(params, ticket, callback);
                    }
                }

                tooltipContent.show(tooltipModel);
                tooltipContent.setContent(html);

                updatePosition(
                    positionExpr, e.offsetX, e.offsetY,
                    tooltipContent, params, e.target, api
                );
            }
        },

        /**
         * Show axis pointer
         * @param {string} [coordSysName]
         */
        _showAxisPointer: function (coordSysName) {
            if (coordSysName) {
                var axisPointers = this._axisPointers[coordSysName];
                axisPointers && zrUtil.each(axisPointers, function (el) {
                    el.show();
                });
            }
            else {
                this.group.eachChild(function (child) {
                    child.show();
                });
                this.group.show();
            }
        },

        _resetLastHover: function () {
            var lastHover = this._lastHover;
            if (lastHover.payloadBatch) {
                this._api.dispatchAction({
                    type: 'downplay',
                    batch: lastHover.payloadBatch
                });
            }
            // Reset lastHover
            this._lastHover = {};
        },
        /**
         * Hide axis pointer
         * @param {string} [coordSysName]
         */
        _hideAxisPointer: function (coordSysName) {
            if (coordSysName) {
                var axisPointers = this._axisPointers[coordSysName];
                axisPointers && zrUtil.each(axisPointers, function (el) {
                    el.hide();
                });
            }
            else {
                this.group.hide();
            }
        },

        _hide: function () {
            this._hideAxisPointer();
            this._resetLastHover();
            if (!this._alwaysShowContent) {
                this._tooltipContent.hideLater(this._tooltipModel.get('hideDelay'));
            }
        },

        dispose: function (ecModel, api) {
            var zr = api.getZr();
            zr.off('click', this._tryShow);
            zr.off('mousemove', this._tryShow);
            zr.off('mouseout', this._hide);

            api.off('showTip');
        }
    });
});
// FIXME Better way to pack data in graphic element
define('echarts/component/tooltip',['require','./tooltip/TooltipModel','./tooltip/TooltipView','../echarts','../echarts'],function (require) {

    require('./tooltip/TooltipModel');

    require('./tooltip/TooltipView');

    // Show tip action
    /**
     * @action
     * @property {string} type
     * @property {number} seriesIndex
     * @property {number} dataIndex
     * @property {number} [x]
     * @property {number} [y]
     */
    require('../echarts').registerAction(
        {
            type: 'showTip',
            event: 'showTip',
            update: 'none'
        },
        // noop
        function () {}
    );
    // Hide tip action
    require('../echarts').registerAction(
        {
            type: 'hideTip',
            event: 'hideTip',
            update: 'none'
        },
        // noop
        function () {}
    );
});
define('echarts/coord/polar/RadiusAxis',['require','zrender/core/util','../Axis'],function (require) {


    var zrUtil = require('zrender/core/util');
    var Axis = require('../Axis');

    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,

        dataToRadius: Axis.prototype.dataToCoord,

        radiusToData: Axis.prototype.coordToData
    };

    zrUtil.inherits(RadiusAxis, Axis);

    return RadiusAxis;
});
define('echarts/coord/polar/AngleAxis',['require','zrender/core/util','../Axis'],function(require) {


    var zrUtil = require('zrender/core/util');
    var Axis = require('../Axis');

    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,

        dataToAngle: Axis.prototype.dataToCoord,

        angleToData: Axis.prototype.coordToData
    };

    zrUtil.inherits(AngleAxis, Axis);

    return AngleAxis;
});
/**
 * @module echarts/coord/polar/Polar
 */
define('echarts/coord/polar/Polar',['require','./RadiusAxis','./AngleAxis'],function(require) {



    var RadiusAxis = require('./RadiusAxis');
    var AngleAxis = require('./AngleAxis');

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

        /**
         * @param {Array.<string>}
         * @readOnly
         */
        this.dimensions = ['radius', 'angle'];

        /**
         * @type {module:echarts/coord/polar/RadiusAxis}
         * @private
         */
        this._radiusAxis = new RadiusAxis();

        /**
         * @type {module:echarts/coord/polar/AngleAxis}
         * @private
         */
        this._angleAxis = new AngleAxis();
    };

    Polar.prototype = {

        constructor: Polar,

        type: 'polar',

        /**
         * 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} axisType
         * @return {module:echarts/coord/polar/AngleAxis|module:echarts/coord/polar/RadiusAxis}
         */
        getAxis: function (axisType) {
            return this['_' + axisType + 'Axis'];
        },

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

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

    return Polar;
});
define('echarts/coord/polar/AxisModel',['require','zrender/core/util','../../model/Component','../axisModelCreator','../axisModelCommonMixin'],function(require) {



    var zrUtil = require('zrender/core/util');
    var ComponentModel = require('../../model/Component');
    var axisModelCreator = require('../axisModelCreator');

    var PolarAxisModel = ComponentModel.extend({
        type: 'polarAxis',
        /**
         * @type {module:echarts/coord/polar/AngleAxis|module:echarts/coord/polar/RadiusAxis}
         */
        axis: null
    });

    zrUtil.merge(PolarAxisModel.prototype, require('../axisModelCommonMixin'));

    var polarAxisDefaultExtendedOption = {
        angle: {
            polarIndex: 0,

            startAngle: 90,

            clockwise: true,

            splitNumber: 12,

            axisLabel: {
                rotate: false
            }
        },
        radius: {
            polarIndex: 0,

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

});
define('echarts/coord/polar/PolarModel',['require','./AxisModel','../../echarts'],function (require) {



    require('./AxisModel');

    require('../../echarts').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 angleAxisModel;
            var ecModel = this.ecModel;
            ecModel.eachComponent(axisType, function (axisModel) {
                if (ecModel.getComponent(
                        'polar', axisModel.getShallow('polarIndex')
                    ) === this) {
                    angleAxisModel = axisModel;
                }
            }, this);
            return angleAxisModel;
        },

        defaultOption: {

            zlevel: 0,

            z: 0,

            center: ['50%', '50%'],

            radius: '80%'
        }
    });
});
// TODO Axis scale
define('echarts/coord/polar/polarCreator',['require','./Polar','../../util/number','zrender/core/util','../../coord/axisHelper','./PolarModel','../../CoordinateSystem'],function (require) {

    var Polar = require('./Polar');
    var numberUtil = require('../../util/number');
    var zrUtil = require('zrender/core/util');

    var axisHelper = require('../../coord/axisHelper');
    var niceScaleExtent = axisHelper.niceScaleExtent;

    // 依赖 PolarModel 做预处理
    require('./PolarModel');

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

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

    /**
     * Set polar axis scale from series data
     */
    function setPolarAxisFromSeries(polarList, ecModel, api) {
        ecModel.eachSeries(function (seriesModel) {
            if (seriesModel.get('coordinateSystem') === 'polar') {
                var polarIndex = seriesModel.get('polarIndex') || 0;

                var polar = polarList[polarIndex];
                if (!polar) {
                    // api.log('Polar configuration not exist for series ' + seriesModel.name + '.');
                    return;
                }
                // Inject polar instance
                seriesModel.coordinateSystem = polar;

                var radiusAxis = polar.getRadiusAxis();
                var angleAxis = polar.getAngleAxis();

                var data = seriesModel.getData();
                radiusAxis.scale.unionExtent(
                    data.getDataExtent('radius', radiusAxis.type !== 'category')
                );
                angleAxis.scale.unionExtent(
                    data.getDataExtent('angle', angleAxis.type !== 'category')
                );
            }
        });

        zrUtil.each(polarList, function (polar) {
            var angleAxis = polar.getAngleAxis();
            var radiusAxis = polar.getRadiusAxis();
            niceScaleExtent(angleAxis, angleAxis.model);
            niceScaleExtent(radiusAxis, radiusAxis.model);
        });
    }

    var polarCreator = {

        create: function (ecModel, api) {
            var polarList = [];
            ecModel.eachComponent('polar', function (polarModel, idx) {
                var polar = new Polar(idx);
                // Inject resize method
                polar.resize = resizePolar;

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

            setPolarAxisFromSeries(polarList, ecModel, api);

            // Fix extent of category angle axis
            // FIXME
            zrUtil.each(polarList, function (polar) {
                var angleAxis = polar.getAngleAxis();
                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]);
                }
            });

            return polarList;
        }
    };

    require('../../CoordinateSystem').register('polar', polarCreator);
});
define('echarts/component/axis/AngleAxisView',['require','zrender/core/util','../../util/graphic','../../model/Model','../../echarts'],function (require) {


    var zrUtil = require('zrender/core/util');
    var graphic = require('../../util/graphic');
    var Model = require('../../model/Model');

    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]
        };
    }
    require('../../echarts').extendComponentView({

        type: 'angleAxis',

        render: function (angleAxisModel, ecModel) {
            this.group.removeAll();
            if (!angleAxisModel.get('show')) {
                return;
            }

            var polarModel = ecModel.getComponent('polar', angleAxisModel.get('polarIndex'));
            var angleAxis = angleAxisModel.axis;
            var polar = polarModel.coordinateSystem;
            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')) {
                    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: tickModel.getModel('lineStyle').getLineStyle()
                }
            ));
        },

        /**
         * @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(),
                        text: labels[i],
                        textAlign: labelTextAlign,
                        textBaseline: 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
                }));
            }
        }
    });
});
define('echarts/component/angleAxis',['require','../coord/polar/polarCreator','./axis/AngleAxisView'],function(require) {


    require('../coord/polar/polarCreator');

    require('./axis/AngleAxisView');
});
define('echarts/component/axis/RadiusAxisView',['require','zrender/core/util','../../util/graphic','./AxisBuilder','../../echarts'],function (require) {



    var zrUtil = require('zrender/core/util');
    var graphic = require('../../util/graphic');
    var AxisBuilder = require('./AxisBuilder');

    var axisBuilderAttrs = [
        'axisLine', 'axisLabel', 'axisTick', 'axisName'
    ];
    var selfBuilderAttrs = [
        'splitLine', 'splitArea'
    ];

    require('../../echarts').extendComponentView({

        type: 'radiusAxis',

        render: function (radiusAxisModel, ecModel) {
            this.group.removeAll();
            if (!radiusAxisModel.get('show')) {
                return;
            }
            var polarModel = ecModel.getComponent('polar', radiusAxisModel.get('polarIndex'));
            var angleAxis = polarModel.coordinateSystem.getAngleAxis();
            var radiusAxis = radiusAxisModel.axis;
            var polar = polarModel.coordinateSystem;
            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')) {
                    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,
            labelRotation: radiusAxisModel.getModel('axisLabel').get('rotate'),
            // Over splitLine and splitArea
            z2: 1
        };
    }
});
define('echarts/component/radiusAxis',['require','../coord/polar/polarCreator','./axis/RadiusAxisView'],function(require) {

    require('../coord/polar/polarCreator');

    require('./axis/RadiusAxisView');
});
define('echarts/component/polar',['require','../coord/polar/polarCreator','./angleAxis','./radiusAxis','../echarts'],function(require) {


    require('../coord/polar/polarCreator');
    require('./angleAxis');
    require('./radiusAxis');

    // Polar view
    require('../echarts').extendComponentView({
        type: 'polar'
    });
});
define('echarts/chart/radar/RadarSeries',['require','../helper/createListFromArray','../../model/Series','zrender/core/util','../../util/number','../../component/polar'],function(require) {



    var createListFromArray = require('../helper/createListFromArray');
    var SeriesModel = require('../../model/Series');
    var zrUtil = require('zrender/core/util');
    var numberUtil = require('../../util/number');
    var linearMap = numberUtil.linearMap;

    // Must have polar coordinate system
    require('../../component/polar');

    return SeriesModel.extend({

        type: 'series.radar',

        dependencies: ['polar'],

        getInitialData: function (option, ecModel) {
            var indicators = option.indicator;
            var data = createListFromArray(option.data, this, ecModel);
            if (indicators) {
                var indicatorMap = zrUtil.reduce(indicators, function (map, value, idx) {
                    map[value.name] = value;
                    return map;
                }, {});
                // Linear map to indicator min-max
                // Only radius axis can be value
                data = data.map(['radius'], function (radius, idx) {
                    var indicator = indicatorMap[data.getName(idx)];
                    if (indicator && indicator.max) {
                        // Map to 0-1 percent value
                        return linearMap(radius, [indicator.min || 0, indicator.max], [0, 1]);
                    }
                });

                // FIXME
                var oldGetRawValue = this.getRawValue;
                this.getRawValue = function (idx) {
                    var val = oldGetRawValue.call(this, idx);
                    var indicator = indicatorMap[data.getName(idx)];
                    if (indicator && indicator.max != null) {
                        return linearMap(val, [0, 1], [indicator.min || 0, indicator.max]);
                    }
                };
            }
            return data;
        },

        defaultOption: {
            zlevel: 0,                  // 一级层叠
            z: 2,                       // 二级层叠
            coordinateSystem: 'polar',
            legendHoverLink: true,
            polarIndex: 0,
            lineStyle: {
                normal: {
                    width: 2,
                    type: 'solid'
                }
            },
            // areaStyle: {
            // },
            // 拐点图形类型
            symbol: 'emptyCircle',
            // 拐点图形大小
            symbolSize: 4,
            // 拐点图形旋转控制
            // symbolRotate: null,
            // 标志图形默认只有主轴显示（随主轴标签间隔隐藏策略）
            showAllSymbol: false

            // Indicators for each chart
            // indicator: [{
            //     name: '',
            //     min: 0,
            //     max: 100
            // }]
        }
    });
});
define('echarts/chart/radar/RadarView',['require','../helper/SymbolDraw','../../util/graphic','zrender/core/util','../../echarts'],function (require) {

    var SymbolDraw = require('../helper/SymbolDraw');
    var graphic = require('../../util/graphic');
    var zrUtil = require('zrender/core/util');

    return require('../../echarts').extendChartView({
        type: 'radar',

        init: function () {
            this._symbolDraw = new SymbolDraw();
        },

        render: function (seriesModel, ecModel, api) {
            var polar = seriesModel.coordinateSystem;
            var group = this.group;

            var data = seriesModel.getData();

            var points = data.mapArray(data.getItemLayout, true);
            if (points.length < 1) {
                return;
            }
            points.push(points[0].slice());

            var polygon = this._polygon || (this._polygon = new graphic.Polygon({
                shape: {
                    points: []
                }
            }));
            var polyline = this._polyline || (this._polyline = new graphic.Polyline({
                shape: {
                    points: []
                },
                z2: 10
            }));

            var polylineShape = polyline.shape;
            var polygonShape = polygon.shape;
            function getInitialPoints() {
                return zrUtil.map(points, function (pt) {
                    return [polar.cx, polar.cy];
                });
            }
            var target = {
                shape: {
                    points: points
                }
            };
            // Initialize or data changed
            if (polylineShape.points.length !== points.length) {
                polygonShape.points = getInitialPoints();
                polylineShape.points = getInitialPoints();
                graphic.initProps(polyline, target, seriesModel);
                graphic.initProps(polygon, target, seriesModel);
            }
            else {
                graphic.updateProps(polyline, target, seriesModel);
                graphic.updateProps(polygon, target, seriesModel);
            }

            this._symbolDraw.updateData(data);

            polyline.setStyle(
                zrUtil.extend(
                    seriesModel.getModel('lineStyle.normal').getLineStyle(),
                    {
                        stroke: data.getVisual('color')
                    }
                )
            );

            var areaStyleModel = seriesModel.getModel('areaStyle.normal');
            polygon.ignore = areaStyleModel.isEmpty();
            graphic.setHoverStyle(
                polyline,
                seriesModel.getModel('lineStyle.emphasis').getLineStyle()
            );

            if (!polygon.ignore) {
                polygon.setStyle(
                    zrUtil.defaults(
                        areaStyleModel.getAreaStyle(),
                        {
                            fill: data.getVisual('color'),
                            opacity: 0.7
                        }
                    )
                );
                graphic.setHoverStyle(
                    polygon,
                    seriesModel.getModel('areaStyle.emphasis').getLineStyle()
                );
            }

            group.add(polyline);
            group.add(polygon);
            group.add(this._symbolDraw.group);

            this._data = data;
        }
    });
});
// Backward compat for radar chart in 2
define('echarts/chart/radar/backwardCompat',['require','zrender/core/util','../../scale/Interval'],function (require) {

    var zrUtil = require('zrender/core/util');
    var IntervalScale = require('../../scale/Interval');
    var isArray = zrUtil.isArray;
    var each = zrUtil.each;
    var filter = zrUtil.filter;

    return function (option) {
        var polarOptList = option.polar;
        var radiusAxisOptList = option.radiusAxis;
        var angleAxisOptList = option.angleAxis;
        var radarSeries = filter(option.series, function (seriesOpt) {
            return seriesOpt.type === 'radar';
        }) || [];
        if (polarOptList && radarSeries.length) {
            if (!isArray(polarOptList)) {
                polarOptList = [polarOptList];
            }
            // In 2.0 there is no radiusAxis and angleAxis
            if (!radiusAxisOptList) {
                radiusAxisOptList = option.radiusAxis = [];
            }
            else if (!isArray(radiusAxisOptList)) {
                radiusAxisOptList = [radiusAxisOptList];
            }
            if (!angleAxisOptList) {
                angleAxisOptList = option.angleAxis = [];
            }
            else if (!isArray(angleAxisOptList)) {
                angleAxisOptList = [angleAxisOptList];
            }
            each(polarOptList, function (polarOpt, idx) {
                // Is 2.0 version
                if (polarOpt.indicator) {
                    var indicators = zrUtil.map(polarOpt.indicator, function (indicator) {
                        var min = indicator.min;
                        var max = indicator.max;
                        if (max != null && max >= 0) {
                            min = 0;
                        }
                        return {
                            name: indicator.text,
                            min: min,
                            max: max
                        };
                    });
                    var radiusAxisOpt = zrUtil.find(radiusAxisOptList, function (radiusAxisOpt) {
                        return (radiusAxisOpt.polarIndex || 0) === idx;
                    });
                    var angleAxisOpt = zrUtil.find(angleAxisOptList, function (angleAxisOpt) {
                        return (angleAxisOpt.polarIndex || 0) === idx;
                    });
                    if (!radiusAxisOpt) {
                        radiusAxisOpt = {
                            type: 'value',
                            polarIndex: idx
                        };
                        radiusAxisOptList.push(radiusAxisOpt);
                    }
                    if (!angleAxisOpt) {
                        angleAxisOpt = {
                            type: 'category',
                            polarIndex: idx
                        };
                        angleAxisOptList.push(angleAxisOpt);
                    }
                    angleAxisOpt.data = zrUtil.map(polarOpt.indicator, function (indicator) {
                        var obj = {
                            value: indicator.text
                        };
                        var axisLabel = indicator.axisLabel;
                        if (axisLabel && axisLabel.textStyle) {
                            obj.textStyle = axisLabel.textStyle;
                        }
                        return obj;
                    });
                    angleAxisOpt.startAngle = polarOpt.startAngle || 90;
                    // axisLine in 2.0 is same like splitLine of angleAxis
                    if (polarOpt.axisLine) {
                        angleAxisOpt.splitLine = polarOpt.axisLine;
                    }
                    if (polarOpt.axisLabel) {
                        angleAxisOpt.axisLabel = polarOpt.axisLabel;
                    }
                    // splitLine in 2.0 is same with splitLine of radiusAxis
                    if (polarOpt.splitLine) {
                        radiusAxisOpt.splitLine = polarOpt.splitLine;
                    }
                    if (polarOpt.splitArea) {
                        radiusAxisOpt.splitArea = polarOpt.splitArea;
                    }
                    // Default show splitLine and splitArea
                    radiusAxisOpt.splitLine = radiusAxisOpt.splitLine || {};
                    radiusAxisOpt.splitArea = radiusAxisOpt.splitArea || {};

                    if (radiusAxisOpt.splitLine.show == null) {
                        radiusAxisOpt.splitLine.show = true;
                    }
                    if (radiusAxisOpt.splitArea.show == null) {
                        radiusAxisOpt.splitArea.show = true;
                    }

                    angleAxisOpt.boundaryGap = false;
                    // indicators will be normalized to 0 - 1
                    radiusAxisOpt.min = 0;
                    radiusAxisOpt.max = 1;
                    radiusAxisOpt.interval = 1 / (polarOpt.splitNumber || 5);
                    radiusAxisOpt.axisLine = {
                        show: false
                    };
                    radiusAxisOpt.axisLabel = {
                        show: false
                    };
                    radiusAxisOpt.axisTick = {
                        show: false
                    };

                    var radarSeriesOfSamePolar = filter(radarSeries, function (seriesOpt) {
                        return (seriesOpt.polarIndex || 0) === idx;
                    });

                    var dataGroupPyIndicator = zrUtil.map(indicators, function () {
                        return [];
                    });

                    // Find polar use current polarOpt
                    each(radarSeriesOfSamePolar, function (seriesOpt) {
                        seriesOpt.indicator = indicators;
                        // Data format in 2.0 radar is strange, like following
                        // data : [
                        //     {
                        //         value : [4300, 10000, 28000, 35000, 50000, 19000],
                        //         name : '预算分配（Allocated Budget）'
                        //     },
                        //      {
                        //         value : [5000, 14000, 28000, 31000, 42000, 21000],
                        //         name : '实际开销（Actual Spending）'
                        //     }
                        // ]
                        // Convert them to series
                        if (
                            seriesOpt.data[0] && zrUtil.isArray(seriesOpt.data[0].value)
                        ) {
                            var dataList = seriesOpt.data;
                            var dataOpt = dataList[0];
                            seriesOpt.data = dataOpt.value;
                            seriesOpt.name = dataOpt.name;
                            for (var i = 1; i < dataList.length; i++) {
                                var dataOpt = dataList[i];
                                var newSeriesOpt = zrUtil.clone(seriesOpt);
                                option.series.push(zrUtil.extend(newSeriesOpt, {
                                    name: dataOpt.name,
                                    data: dataOpt.value,
                                    indicator: indicators
                                }));
                            }

                            for (var i = 0; i < dataOpt.value.length; i++) {
                                for (var j = 0; j < dataList.length; j++) {
                                    dataGroupPyIndicator[i].push(dataList[j].value[i]);
                                }
                            }
                        }
                    });

                    // Calculate min, max of each indicator from data
                    each(dataGroupPyIndicator, function (valuePerIndicator, idx) {
                        var intervalScale = new IntervalScale();
                        var min = Infinity;
                        var max = -Infinity;
                        var len = valuePerIndicator.length;
                        if (!len) {
                            return;
                        }
                        for (var i = 0; i < len; i++) {
                            min = Math.min(min, valuePerIndicator[i]);
                            max = Math.max(max, valuePerIndicator[i]);
                        }
                        intervalScale.setExtent(min, max);
                        intervalScale.niceExtent(polarOpt.splitNumber || 5);
                        var intervalExtent = intervalScale.getExtent();
                        if (indicators[idx].min == null) {
                            indicators[idx].min = intervalExtent[0];
                        }
                        if (indicators[idx].max == null) {
                            indicators[idx].max = intervalExtent[1];
                        }
                    });
                }
            });
        }
    };
});
define('echarts/chart/radar',['require','zrender/core/util','../echarts','./radar/RadarSeries','./radar/RadarView','../visual/symbol','../layout/points','./radar/backwardCompat'],function (require) {

    var zrUtil = require('zrender/core/util');
    var echarts = require('../echarts');

    require('./radar/RadarSeries');
    require('./radar/RadarView');

    echarts.registerVisualCoding('chart', zrUtil.curry(
        require('../visual/symbol'), 'radar', 'circle', null
    ));
    echarts.registerLayout(zrUtil.curry(
        require('../layout/points'), 'radar'
    ));

    echarts.registerPreprocessor(require('./radar/backwardCompat'));
});
define('echarts/component/legend/LegendModel',['require','zrender/core/util','../../model/Model','../../echarts'],function(require) {



    var zrUtil = require('zrender/core/util');
    var Model = require('../../model/Model');

    return require('../../echarts').extendComponentModel({

        type: 'legend',

        dependencies: ['series'],

        layoutMode: {type: 'box', ignoreSize: true},

        init: function (option, parentModel, ecModel) {
            this.mergeDefaultAndTheme(option, ecModel);

            option.selected = option.selected || {};

            var legendData = zrUtil.map(option.data || [], function (dataItem) {
                if (typeof dataItem === 'string') {
                    dataItem = {
                        name: dataItem
                    };
                }
                return new Model(dataItem, this);
            }, this);
            this._data = legendData;

            this._updateAvailableNames(ecModel);

            // If has any selected in option.selected
            var selectedMap = this.option.selected;
            // If selectedMode is single, try to select one
            if (legendData[0] && this.get('selectedMode') === 'single') {
                var hasSelected = false;
                for (var name in selectedMap) {
                    if (selectedMap[name]) {
                        this.select(name);
                        hasSelected = true;
                    }
                }
                // Try select the first if selectedMode is single
                !hasSelected && this.select(legendData[0].get('name'));
            }
        },

        mergeOption: function (option) {
            this.$superCall('mergeOption', option);

            this._updateAvailableNames(this.ecModel);
        },

        _updateAvailableNames: function (ecModel) {
            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 (!(name in selected)) {
                selected[name] = true;
            }
            this[selected[name] ? 'unSelect' : 'select'](name);
        },

        /**
         * @param {string} name
         */
        isSelected: function (name) {
            var selected = this.option.selected;
            return !((name in selected) && !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,
            textStyle: {
                // 图例文字颜色
                color: '#333'
            },
            // formatter: '',
            // 选择模式，默认开启图例开关
            selectedMode: true
            // 配置默认选中状态，可配合LEGEND.SELECTED事件做动态数据载入
            // selected: null,
            // 图例内容（详见legend.data，数组中每一项代表一个item
            // data: [],
        }
    });
});
/**
 * @file Legend action
 */
define('echarts/component/legend/legendAction',['require','../../echarts','zrender/core/util'],function(require) {

    var echarts = require('../../echarts');
    var zrUtil = require('zrender/core/util');

    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 (name in selectedMap) {
                    // 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')
    );
});
define('echarts/component/helper/listComponent',['require','../../util/layout','../../util/format','../../util/graphic'],function (require) {
    // List layout
    var layout = require('../../util/layout');
    var formatUtil = require('../../util/format');
    var graphic = require('../../util/graphic');

    function positionGroup(group, model, api) {
        layout.positionGroup(
            group, model.getBoxLayoutParams(),
            {
                width: api.getWidth(),
                height: api.getHeight()
            },
            model.get('padding')
        );
    }

    return {
        /**
         * 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) {
            layout.box(
                componentModel.get('orient'),
                group,
                componentModel.get('itemGap'),
                api.getWidth(),
                api.getHeight()
            );

            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
            });
            graphic.subPixelOptimizeRect(rect);

            group.add(rect);
        }
    };
});
define('echarts/component/legend/LegendView',['require','zrender/core/util','../../util/symbol','../../util/graphic','../helper/listComponent','../../echarts'],function (require) {

    var zrUtil = require('zrender/core/util');
    var symbolCreator = require('../../util/symbol');
    var graphic = require('../../util/graphic');
    var listComponentHelper = require('../helper/listComponent');

    var curry = zrUtil.curry;

    var LEGEND_DISABLE_COLOR = '#ccc';

    function dispatchSelectAction(name, api) {
        api.dispatchAction({
            type: 'legendToggleSelect',
            name: name
        });
    }

    function dispatchHighlightAction(seriesModel, dataName, api) {
        seriesModel.get('legendHoverLink') && api.dispatchAction({
            type: 'highlight',
            seriesName: seriesModel.name,
            name: dataName
        });
    }

    function dispatchDownplayAction(seriesModel, dataName, api) {
        seriesModel.get('legendHoverLink') &&api.dispatchAction({
            type: 'downplay',
            seriesName: seriesModel.name,
            name: dataName
        });
    }

    return require('../../echarts').extendComponentView({

        type: 'legend',

        init: function () {
            this._symbolTypeStore = {};
        },

        render: function (legendModel, ecModel, api) {
            var selectMode = legendModel.get('selectedMode');
            var itemWidth = legendModel.get('itemWidth');
            var itemHeight = legendModel.get('itemHeight');
            var itemAlign = legendModel.get('align');

            var group = this.group;
            group.removeAll();

            if (itemAlign === 'auto') {
                itemAlign = (legendModel.get('left') === 'right'
                    && legendModel.get('orient') === 'vertical')
                    ? 'right' : 'left';
            }

            var legendItemMap = {};
            var legendDrawedMap = {};
            zrUtil.each(legendModel.getData(), function (itemModel) {
                var seriesName = itemModel.get('name');
                // Use empty string or \n as a newline string
                if (seriesName === '' || seriesName === '\n') {
                    group.add(new graphic.Group({
                        newline: true
                    }));
                }

                var seriesModel = ecModel.getSeriesByName(seriesName)[0];

                legendItemMap[seriesName] = itemModel;

                if (!seriesModel || legendDrawedMap[seriesName]) {
                    // Series not exists
                    return;
                }

                var data = seriesModel.getData();
                var color = data.getVisual('color');

                if (!legendModel.isSelected(seriesName)) {
                    color = LEGEND_DISABLE_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(
                    seriesName, itemModel, legendModel,
                    legendSymbolType, symbolType,
                    itemWidth, itemHeight, itemAlign, color,
                    selectMode
                );

                itemGroup.on('click', curry(dispatchSelectAction, seriesName, api))
                    .on('mouseover', curry(dispatchHighlightAction, seriesModel, '', api))
                    .on('mouseout', curry(dispatchDownplayAction, seriesModel, '', api));

                legendDrawedMap[seriesName] = true;
            }, this);

            ecModel.eachRawSeries(function (seriesModel) {
                if (seriesModel.legendDataProvider) {
                    var data = seriesModel.legendDataProvider();
                    data.each(function (idx) {
                        var name = data.getName(idx);

                        // Avoid mutiple series use the same data name
                        if (!legendItemMap[name] || legendDrawedMap[name]) {
                            return;
                        }

                        var color = data.getItemVisual(idx, 'color');

                        if (!legendModel.isSelected(name)) {
                            color = LEGEND_DISABLE_COLOR;
                        }

                        var legendSymbolType = 'roundRect';

                        var itemGroup = this._createItem(
                            name, legendItemMap[name], legendModel,
                            legendSymbolType, null,
                            itemWidth, itemHeight, 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[name] = true;
                    }, false, this);
                }
            }, this);

            listComponentHelper.layout(group, legendModel, api);
            // Render background after group is layout
            // FIXME
            listComponentHelper.addBackground(group, legendModel);
        },

        _createItem: function (
            name, itemModel, legendModel,
            legendSymbolType, symbolType,
            itemWidth, itemHeight, itemAlign, color,
            selectMode
        ) {
            var itemGroup = new graphic.Group();

            var textStyleModel = itemModel.getModel('textStyle');

            var itemIcon = itemModel.get('icon');
            // Use user given icon first
            legendSymbolType = itemIcon || legendSymbolType;
            itemGroup.add(symbolCreator.createSymbol(
                legendSymbolType, 0, 0, itemWidth, itemHeight, color
            ));

            // Compose symbols
            // PENDING
            if (!itemIcon && symbolType
                && symbolType !== legendSymbolType
                && symbolType != 'none'
            ) {
                var size = itemHeight * 0.8;
                // Put symbol in the center
                itemGroup.add(symbolCreator.createSymbol(
                    symbolType, (itemWidth - size) / 2, (itemHeight - size) / 2, size, size, color
                ));
            }

            // Text
            var textX = itemAlign === 'left' ? itemWidth + 5 : -5;
            var textAlign = itemAlign;

            var formatter = legendModel.get('formatter');
            if (typeof formatter === 'string' && formatter) {
                name = formatter.replace('{name}', name);
            }
            else if (typeof formatter === 'function') {
                name = formatter(name);
            }

            var text = new graphic.Text({
                style: {
                    text: name,
                    x: textX,
                    y: itemHeight / 2,
                    fill: textStyleModel.getTextColor(),
                    textFont: textStyleModel.getFont(),
                    textAlign: textAlign,
                    textBaseline: 'middle'
                }
            });
            itemGroup.add(text);

            // Add a invisible rect to increase the area of mouse hover
            itemGroup.add(new graphic.Rect({
                shape: itemGroup.getBoundingRect(),
                invisible: true
            }));

            itemGroup.eachChild(function (child) {
                child.silent = !selectMode;
            });

            this.group.add(itemGroup);

            return itemGroup;
        }
    });
});
define('echarts/component/legend/legendFilter',[],function () {
   return 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
                for (var i = 0; i < legendModels.length; i++) {
                    if (!legendModels[i].isSelected(series.name)) {
                        return false;
                    }
                }
                return true;
            });
        }
    };
});
/**
 * Legend component entry file8
 */
define('echarts/component/legend',['require','./legend/LegendModel','./legend/legendAction','./legend/LegendView','../echarts','./legend/legendFilter'],function (require) {

    require('./legend/LegendModel');
    require('./legend/legendAction');
    require('./legend/LegendView');

    var echarts = require('../echarts');
    // Series Filter
    echarts.registerProcessor('filter', require('./legend/legendFilter'));
});
define('echarts/chart/map/MapSeries',['require','../../data/List','../../echarts','../../model/Series','zrender/core/util','../../data/helper/completeDimensions','../../util/format','../helper/dataSelectableMixin'],function (require) {

    var List = require('../../data/List');
    var echarts = require('../../echarts');
    var SeriesModel = require('../../model/Series');
    var zrUtil = require('zrender/core/util');
    var completeDimensions = require('../../data/helper/completeDimensions');

    var formatUtil = require('../../util/format');
    var encodeHTML = formatUtil.encodeHTML;
    var addCommas = formatUtil.addCommas;

    var dataSelectableMixin = require('../helper/dataSelectableMixin');

    function fillData(dataOpt, geoJson) {
        var dataNameMap = {};
        var features = geoJson.features;
        for (var i = 0; i < dataOpt.length; i++) {
            dataNameMap[dataOpt[i].name] = dataOpt[i];
        }

        for (var i = 0; i < features.length; i++) {
            var name = features[i].properties.name;
            if (!dataNameMap[name]) {
                dataOpt.push({
                    value: NaN,
                    name: name
                });
            }
        }
        return dataOpt;
    }

    var MapSeries = SeriesModel.extend({

        type: 'series.map',

        /**
         * 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.option = option;

            this.$superApply('init', arguments);

            this.updateSelectedMap();
        },

        getInitialData: function (option) {
            var dimensions = completeDimensions(['value'], option.data);

            var list = new List(dimensions, this);

            list.initData(option.data);

            return list;
        },

        mergeOption: function (newOption) {
            newOption = this._fillOption(newOption);
            SeriesModel.prototype.mergeOption.call(this, newOption);
            this.updateSelectedMap();
        },

        _fillOption: function (option) {
            // Shallow clone
            option = zrUtil.extend({}, option);

            var map = echarts.getMap(option.mapType);
            var geoJson = map && map.geoJson;
            geoJson && option.data
                && (option.data = fillData(option.data, geoJson));

            return option;
        },

        /**
         * @param {number} zoom
         */
        setRoamZoom: function (zoom) {
            var roamDetail = this.option.roamDetail;
            roamDetail && (roamDetail.zoom = zoom);
        },

        /**
         * @param {number} x
         * @param {number} y
         */
        setRoamPan: function (x, y) {
            var roamDetail = this.option.roamDetail;
            if (roamDetail) {
                roamDetail.x = x;
                roamDetail.y = y;
            }
        },

        /**
         * Map tooltip formatter
         *
         * @param {number} dataIndex
         */
        formatTooltip: function (dataIndex) {
            var data = this._data;
            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++) {
                if (!isNaN(seriesGroup[i].getRawValue(dataIndex))) {
                    seriesNames.push(
                        encodeHTML(seriesGroup[i].name)
                    );
                }
            }

            return seriesNames.join(', ') + '<br />'
                + name + ' : ' + formattedValue;
        },

        defaultOption: {
            // 一级层叠
            zlevel: 0,
            // 二级层叠
            z: 2,
            coordinateSystem: 'geo',
            // 各省的 map 暂时都用中文
            map: 'china',

            // 'center' | 'left' | 'right' | 'x%' | {number}
            left: 'center',
            // 'center' | 'top' | 'bottom' | 'x%' | {number}
            top: 'center',
            // right
            // bottom
            // width:
            // height   // 自适应

            // 数值合并方式，默认加和，可选为：
            // 'sum' | 'average' | 'max' | 'min'
            // mapValueCalculation: 'sum',
            // 地图数值计算结果小数精度
            // mapValuePrecision: 0,
            // 显示图例颜色标识（系列标识的小圆点），图例开启时有效
            showLegendSymbol: true,
            // 选择模式，默认关闭，可选single，multiple
            // selectedMode: false,
            dataRangeHoverLink: true,
            // 是否开启缩放及漫游模式
            // roam: false,

            // 在 roam 开启的时候使用
            roamDetail: {
                x: 0,
                y: 0,
                zoom: 1
            },

            label: {
                normal: {
                    show: false,
                    textStyle: {
                        color: '#000'
                    }
                },
                emphasis: {
                    show: false,
                    textStyle: {
                        color: '#000'
                    }
                }
            },
            // scaleLimit: null,
            itemStyle: {
                normal: {
                    // color: 各异,
                    borderWidth: 0.5,
                    borderColor: '#444',
                    areaColor: '#eee'
                },
                // 也是选中样式
                emphasis: {
                    areaColor: 'rgba(255,215, 0, 0.8)'
                }
            }
        }
    });

    zrUtil.mixin(MapSeries, dataSelectableMixin);

    return MapSeries;
});
define('echarts/component/helper/interactionMutex',['require'],function (require) {

    var ATTR = '\0_ec_interaction_mutex';

    var interactionMutex = {

        take: function (key, zr) {
            getStore(zr)[key] = true;
        },

        release: function (key, zr) {
            getStore(zr)[key] = false;
        },

        isTaken: function (key, zr) {
            return !!getStore(zr)[key];
        }
    };

    function getStore(zr) {
        return zr[ATTR] || (zr[ATTR] = {});
    }

    return interactionMutex;
});
/**
 * @module echarts/component/helper/RoamController
 */

define('echarts/component/helper/RoamController',['require','zrender/mixin/Eventful','zrender/core/util','zrender/core/event','./interactionMutex'],function (require) {

    var Eventful = require('zrender/mixin/Eventful');
    var zrUtil = require('zrender/core/util');
    var eventTool = require('zrender/core/event');
    var interactionMutex = require('./interactionMutex');

    function mousedown(e) {
        if (e.target && e.target.draggable) {
            return;
        }

        var x = e.offsetX;
        var y = e.offsetY;
        var rect = this.rect;
        if (rect && rect.contain(x, y)) {
            this._x = x;
            this._y = y;
            this._dragging = true;
        }
    }

    function mousemove(e) {
        if (!this._dragging) {
            return;
        }

        eventTool.stop(e.event);

        if (e.gestureEvent !== 'pinch') {

            if (interactionMutex.isTaken('globalPan', this._zr)) {
                return;
            }

            var x = e.offsetX;
            var y = e.offsetY;

            var dx = x - this._x;
            var dy = y - this._y;

            this._x = x;
            this._y = y;

            var target = this.target;

            if (target) {
                var pos = target.position;
                pos[0] += dx;
                pos[1] += dy;
                target.dirty();
            }

            eventTool.stop(e.event);
            this.trigger('pan', dx, dy);
        }
    }

    function mouseup(e) {
        this._dragging = false;
    }

    function mousewheel(e) {
        eventTool.stop(e.event);
        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('globalPan', this._zr)) {
            return;
        }

        eventTool.stop(e.event);
        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) {
        var rect = this.rect;

        if (rect && rect.contain(zoomX, zoomY)) {

            var target = this.target;

            if (target) {
                var pos = target.position;
                var scale = target.scale;

                var newZoom = this._zoom = this._zoom || 1;
                newZoom *= zoomDelta;
                // newZoom = Math.max(
                //     Math.min(target.maxZoom, newZoom),
                //     target.minZoom
                // );
                var zoomScale = newZoom / this._zoom;
                this._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();
            }

            this.trigger('zoom', zoomDelta, zoomX, zoomY);
        }
    }

    /**
     * @alias module:echarts/component/helper/RoamController
     * @constructor
     * @mixin {module:zrender/mixin/Eventful}
     *
     * @param {module:zrender/zrender~ZRender} zr
     * @param {module:zrender/Element} target
     * @param {module:zrender/core/BoundingRect} rect
     */
    function RoamController(zr, target, rect) {

        /**
         * @type {module:zrender/Element}
         */
        this.target = target;

        /**
         * @type {module:zrender/core/BoundingRect}
         */
        this.rect = rect;

        /**
         * @type {module:zrender}
         */
        this._zr = zr;

        // 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  {boolean} [controlType=true] Specify the control type, which can be only 'pan' or 'zoom'
         */
        this.enable = function (controlType) {
            // Disable previous first
            this.disable();
            if (controlType == null) {
                controlType = true;
            }
            if (controlType && controlType !== 'scale') {
                zr.on('mousedown', mousedownHandler);
                zr.on('mousemove', mousemoveHandler);
                zr.on('mouseup', mouseupHandler);
            }
            if (controlType && controlType !== 'move') {
                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);

    return RoamController;
});
/**
 * @module echarts/component/helper/MapDraw
 */
define('echarts/component/helper/MapDraw',['require','./RoamController','../../util/graphic','zrender/core/util'],function (require) {

    var RoamController = require('./RoamController');
    var graphic = require('../../util/graphic');
    var zrUtil = require('zrender/core/util');

    function getFixedItemStyle(model, scale) {
        var itemStyle = model.getItemStyle();
        var areaColor = model.get('areaColor');
        if (areaColor) {
            itemStyle.fill = areaColor;
        }

        return itemStyle;
    }

    function updateMapSelectHandler(mapOrGeoModel, data, group, api, fromView) {
        group.off('click');
        mapOrGeoModel.get('selectedMode')
            && group.on('click', function (e) {
                var dataIndex = e.target.dataIndex;
                if (dataIndex != null) {
                    var name = data.getName(dataIndex);

                    api.dispatchAction({
                        type: 'mapToggleSelect',
                        seriesIndex: mapOrGeoModel.seriesIndex,
                        name: name,
                        from: fromView.uid
                    });

                    updateMapSelected(mapOrGeoModel, data, api);
                }
            });
    }

    function updateMapSelected(mapOrGeoModel, data) {
        data.eachItemGraphicEl(function (el, idx) {
            var name = data.getName(idx);
            el.trigger(mapOrGeoModel.isSelected(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(), updateGroup ? group : null, null
        );

        /**
         * @type {module:zrender/container/Group}
         * @readOnly
         */
        this.group = group;

        /**
         * @type {boolean}
         * @private
         */
        this._updateGroup = updateGroup;
    }

    MapDraw.prototype = {

        constructor: MapDraw,

        draw: function (mapOrGeoModel, ecModel, api, fromView) {

            // geoModel has no data
            var data = mapOrGeoModel.getData && mapOrGeoModel.getData();

            var geo = mapOrGeoModel.coordinateSystem;

            var group = this.group;
            group.removeAll();

            var scale = geo.scale;
            group.position = geo.position.slice();
            group.scale = scale.slice();

            var itemStyleModel;
            var hoverItemStyleModel;
            var itemStyle;
            var hoverItemStyle;

            var labelModel;
            var hoverLabelModel;

            var itemStyleAccessPath = ['itemStyle', 'normal'];
            var hoverItemStyleAccessPath = ['itemStyle', 'emphasis'];
            var labelAccessPath = ['label', 'normal'];
            var hoverLabelAccessPath = ['label', 'emphasis'];
            if (!data) {
                itemStyleModel = mapOrGeoModel.getModel(itemStyleAccessPath);
                hoverItemStyleModel = mapOrGeoModel.getModel(hoverItemStyleAccessPath);

                itemStyle = getFixedItemStyle(itemStyleModel, scale);
                hoverItemStyle = getFixedItemStyle(hoverItemStyleModel, scale);

                labelModel = mapOrGeoModel.getModel(labelAccessPath);
                hoverLabelModel = mapOrGeoModel.getModel(hoverLabelAccessPath);
            }

            zrUtil.each(geo.regions, function (region) {

                var regionGroup = new graphic.Group();
                var dataIdx;
                // Use the itemStyle in data if has data
                if (data) {
                    // FIXME If dataIdx < 0
                    dataIdx = data.indexOfName(region.name);
                    var itemModel = data.getItemModel(dataIdx);

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

                    itemStyleModel = itemModel.getModel(itemStyleAccessPath);
                    hoverItemStyleModel = itemModel.getModel(hoverItemStyleAccessPath);

                    itemStyle = getFixedItemStyle(itemStyleModel, scale);
                    hoverItemStyle = getFixedItemStyle(hoverItemStyleModel, scale);

                    labelModel = itemModel.getModel(labelAccessPath);
                    hoverLabelModel = itemModel.getModel(hoverLabelAccessPath);

                    if (visualColor) {
                        itemStyle.fill = visualColor;
                    }
                }
                var textStyleModel = labelModel.getModel('textStyle');
                var hoverTextStyleModel = hoverLabelModel.getModel('textStyle');

                zrUtil.each(region.contours, function (contour) {

                    var polygon = new graphic.Polygon({
                        shape: {
                            points: contour
                        },
                        style: {
                            strokeNoScale: true
                        },
                        culling: true
                    });

                    polygon.setStyle(itemStyle);

                    regionGroup.add(polygon);
                });

                // 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 (
                    (!data || 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',
                            textBaseline: '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
                data && data.setItemGraphicEl(dataIdx, regionGroup);

                graphic.setHoverStyle(regionGroup, hoverItemStyle);

                group.add(regionGroup);
            });

            this._updateController(mapOrGeoModel, ecModel, api);

            data && updateMapSelectHandler(mapOrGeoModel, data, group, api, fromView);

            data && updateMapSelected(mapOrGeoModel, data);
        },

        remove: function () {
            this.group.removeAll();
            this._controller.dispose();
        },

        _updateController: function (mapOrGeoModel, ecModel, api) {
            var geo = mapOrGeoModel.coordinateSystem;
            var controller = this._controller;
            // roamType is will be set default true if it is null
            controller.enable(mapOrGeoModel.get('roam') || false);
            // FIXME mainType, subType 作为 component 的属性？
            var mainType = mapOrGeoModel.type.split('.')[0];
            controller.off('pan')
                .on('pan', function (dx, dy) {
                    api.dispatchAction({
                        type: 'geoRoam',
                        component: mainType,
                        name: mapOrGeoModel.name,
                        dx: dx,
                        dy: dy
                    });
                });
            controller.off('zoom')
                .on('zoom', function (zoom, mouseX, mouseY) {
                    api.dispatchAction({
                        type: 'geoRoam',
                        component: mainType,
                        name: mapOrGeoModel.name,
                        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.rect = geo.getViewRect();
        }
    };

    return MapDraw;
});
define('echarts/chart/map/MapView',['require','../../util/graphic','../../component/helper/MapDraw','../../echarts'],function (require) {

    // var zrUtil = require('zrender/core/util');
    var graphic = require('../../util/graphic');

    var MapDraw = require('../../component/helper/MapDraw');

    require('../../echarts').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();
            // Not update map if it is an roam action from self
            if (!(payload && payload.type === 'geoRoam'
                && payload.component === 'series'
                && payload.name === mapModel.name)) {

                if (mapModel.needsDrawMap) {
                    var mapDraw = this._mapDraw || new MapDraw(api, true);
                    group.add(mapDraw.group);

                    mapDraw.draw(mapModel, ecModel, api, this);

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

        _renderSymbols: function (mapModel, ecModel, api) {
            var data = mapModel.getData();
            var group = this.group;

            data.each('value', function (value, idx) {
                if (isNaN(value)) {
                    return;
                }

                var layout = data.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: {
                        fill: data.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 labelText = data.getName(idx);

                    var itemModel = data.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 = data.getItemGraphicEl(idx);
                    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);
            });
        }
    });
});
define('echarts/action/roamHelper',['require'],function (require) {

    var roamHelper = {};

    /**
     * Calculate pan and zoom which from roamDetail model
     * @param  {module:echarts/model/Model} roamDetailModel
     * @param  {Object} payload
     */
    roamHelper.calcPanAndZoom = function (roamDetailModel, payload) {
        var dx = payload.dx;
        var dy = payload.dy;
        var zoom = payload.zoom;

        var panX = roamDetailModel.get('x') || 0;
        var panY = roamDetailModel.get('y') || 0;

        var previousZoom = roamDetailModel.get('zoom') || 1;

        if (dx != null && dy != null) {
            panX += dx;
            panY += dy;
        }
        if (zoom != null) {
            var fixX = (payload.originX - panX) * (zoom - 1);
            var fixY = (payload.originY - panY) * (zoom - 1);

            panX -= fixX;
            panY -= fixY;
        }

        return {
            x: panX,
            y: panY,
            zoom: (zoom || 1) * previousZoom
        };
    };

    return roamHelper;
});
define('echarts/action/geoRoam',['require','zrender/core/util','./roamHelper','../echarts'],function (require) {

    var zrUtil = require('zrender/core/util');
    var roamHelper = require('./roamHelper');

    var echarts = require('../echarts');
    var actionInfo = {
        type: 'geoRoam',
        event: 'geoRoam',
        update: 'updateLayout'
    };

    /**
     * @payload
     * @property {string} [component=series]
     * @property {string} name Component name
     * @property {number} [dx]
     * @property {number} [dy]
     * @property {number} [zoom]
     * @property {number} [originX]
     * @property {number} [originY]
     */
    echarts.registerAction(actionInfo, function (payload, ecModel) {
        var componentType = payload.component || 'series';

        ecModel.eachComponent(componentType, function (componentModel) {
            if (componentModel.name === payload.name) {
                var geo = componentModel.coordinateSystem;
                if (geo.type !== 'geo') {
                    return;
                }

                var roamDetailModel = componentModel.getModel('roamDetail');
                var res = roamHelper.calcPanAndZoom(roamDetailModel, payload);

                componentModel.setRoamPan
                    && componentModel.setRoamPan(res.x, res.y);

                componentModel.setRoamZoom
                    && componentModel.setRoamZoom(res.zoom);

                geo && geo.setPan(res.x, res.y);
                geo && geo.setZoom(res.zoom);

                // All map series with same `map` use the same geo coordinate system
                // So the roamDetail must be in sync. Include the series not selected by legend
                if (componentType === 'series') {
                    zrUtil.each(componentModel.seriesGroup, function (seriesModel) {
                        seriesModel.setRoamPan(res.x, res.y);
                        seriesModel.setRoamZoom(res.zoom);
                    });
                }
            }
        });
    });
});
define('echarts/coord/geo/GeoModel',['require','../../util/model','../../model/Component'],function (require) {


    var modelUtil = require('../../util/model');
    var ComponentModel = require('../../model/Component');

    ComponentModel.extend({

        type: 'geo',

        /**
         * @type {module:echarts/coord/geo/Geo}
         */
        coordinateSystem: null,

        init: function (option) {
            ComponentModel.prototype.init.apply(this, arguments);

            // Default label emphasis `position` and `show`
            modelUtil.defaultEmphasis(
                option.label, ['position', 'show', 'textStyle', 'distance', 'formatter']
            );
        },

        defaultOption: {

            zlevel: 0,

            z: 0,

            show: true,

            left: 'center',

            top: 'center',

            // 自适应
            // width:,
            // height:,
            // right
            // bottom

            // Map type
            map: '',

            // 在 roam 开启的时候使用
            roamDetail: {
                x: 0,
                y: 0,
                zoom: 1
            },

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

        /**
         * Format label
         * @param {string} name Region name
         * @param {string} [status='normal'] 'normal' or 'emphasis'
         * @return {string}
         */
        getFormattedLabel: function (name, status) {
            var formatter = this.get('label.' + status + '.formatter');
            var params = {
                name: name
            };
            if (typeof formatter === 'function') {
                params.status = status;
                return formatter(params);
            }
            else if (typeof formatter === 'string') {
                return formatter.replace('{a}', params.seriesName);
            }
        },

        setRoamZoom: function (zoom) {
            var roamDetail = this.option.roamDetail;
            roamDetail && (roamDetail.zoom = zoom);
        },

        setRoamPan: function (x, y) {
            var roamDetail = this.option.roamDetail;
            if (roamDetail) {
                roamDetail.x = x;
                roamDetail.y = y;
            }
        }
    });
});
define('zrender/contain/polygon',['require','./windingLine'],function (require) {

    var windingLine = require('./windingLine');

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


    return {
        contain: contain
    };
});
/**
 * @module echarts/coord/geo/Region
 */
define('echarts/coord/geo/Region',['require','zrender/contain/polygon','zrender/core/BoundingRect','zrender/core/bbox','zrender/core/vector'],function (require) {

    var polygonContain = require('zrender/contain/polygon');

    var BoundingRect = require('zrender/core/BoundingRect');

    var bbox = require('zrender/core/bbox');
    var vec2 = require('zrender/core/vector');

    /**
     * @param {string} name
     * @param {Array} contours
     * @param {Array.<number>} cp
     */
    function Region(name, contours, cp) {

        /**
         * @type {string}
         * @readOnly
         */
        this.name = name;

        /**
         * @type {Array.<Array>}
         * @readOnly
         */
        this.contours = contours;

        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,

        /**
         * @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 contours = this.contours;
            for (var i = 0; i < contours.length; i++) {
                bbox.fromPoints(contours[i], 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 contours = this.contours;
            if (rect.contain(coord[0], coord[1])) {
                for (var i = 0, len = contours.length; i < len; i++) {
                    if (polygonContain.contain(contours[i], coord[0], coord[1])) {
                        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 contours = this.contours;
            for (var i = 0; i < contours.length; i++) {
                for (var p = 0; p < contours[i].length; p++) {
                    vec2.applyTransform(contours[i][p], contours[i][p], transform);
                }
            }
            rect = this._rect;
            rect.copy(target);
            // Update center
            this.center = [
                rect.x + rect.width / 2,
                rect.y + rect.height / 2
            ];
        }
    };

    return Region;
});
/**
 * Parse and decode geo json
 * @module echarts/coord/geo/parseGeoJson
 */
define('echarts/coord/geo/parseGeoJson',['require','zrender/core/util','./Region'],function (require) {

    var zrUtil = require('zrender/core/util');

    var Region = require('./Region');

    function decode(json) {
        if (!json.UTF8Encoding) {
            return json;
        }
        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]
                    );
                }
                else if (geometry.type === 'MultiPolygon') {
                    for (var c2 = 0; c2 < coordinate.length; c2++) {
                        var polygon = coordinate[c2];
                        coordinate[c2] = decodePolygon(
                            polygon,
                            encodeOffsets[c][c2]
                        );
                    }
                }
            }
        }
        // Has been decoded
        json.UTF8Encoding = false;
        return json;
    }

    function decodePolygon(coordinate, encodeOffsets) {
        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 / 1024, y / 1024]);
        }

        return result;
    }

    /**
     * @inner
     */
    function flattern2D(array) {
        var ret = [];
        for (var i = 0; i < array.length; i++) {
            for (var k = 0; k < array[i].length; k++) {
                ret.push(array[i][k]);
            }
        }
        return ret;
    }

    /**
     * @alias module:echarts/coord/geo/parseGeoJson
     * @param {Object} geoJson
     * @return {module:zrender/container/Group}
     */
    return 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;
        }), function (featureObj) {
            var properties = featureObj.properties;
            var geometry = featureObj.geometry;

            var coordinates = geometry.coordinates;

            if (geometry.type === 'MultiPolygon') {
                coordinates = flattern2D(coordinates);
            }

            return new Region(
                properties.name,
                coordinates,
                properties.cp
            );
        });
    };
});
/**
 * Simple view coordinate system
 * Mapping given x, y to transformd view x, y
 */
define('echarts/coord/View',['require','zrender/core/vector','zrender/core/matrix','zrender/mixin/Transformable','zrender/core/util','zrender/core/BoundingRect'],function (require) {

    var vector = require('zrender/core/vector');
    var matrix = require('zrender/core/matrix');

    var Transformable = require('zrender/mixin/Transformable');
    var zrUtil = require('zrender/core/util');

    var BoundingRect = require('zrender/core/BoundingRect');

    var v2ApplyTransform = vector.applyTransform;

    // Dummy transform node
    function TransformDummy() {
        Transformable.call(this);
    }
    zrUtil.mixin(TransformDummy, Transformable);

    function View(name) {
        /**
         * @type {string}
         */
        this.name = name;

        /**
         * @param {Array.<string>}
         * @readOnly
         */
        this.dimensions = ['x', 'y'];

        Transformable.call(this);

        this._roamTransform = new TransformDummy();

        this._viewTransform = new TransformDummy();
    }

    View.prototype = {

        constructor: View,

        type: 'view',

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

        /**
         * @param {number} x
         * @param {number} y
         */
        setPan: function (x, y) {

            this._roamTransform.position = [x, y];

            this._updateTransform();
        },

        /**
         * @param {number} zoom
         */
        setZoom: function (zoom) {
            this._roamTransform.scale = [zoom, zoom];

            this._updateTransform();
        },

        /**
         * @return {Array.<number}
         */
        getRoamTransform: function () {
            return this._roamTransform.transform;
        },

        /**
         * Update transform from roam and mapLocation
         * @private
         */
        _updateTransform: function () {
            var roamTransform = this._roamTransform;
            var viewTransform = this._viewTransform;
            // var scale = this.scale;

            viewTransform.parent = roamTransform;
            roamTransform.updateTransform();
            viewTransform.updateTransform();

            viewTransform.transform
                && matrix.copy(this.transform || (this.transform = []), viewTransform.transform);

            this.decomposeTransform();
        },

        /**
         * @return {module:zrender/core/BoundingRect}
         */
        getViewRect: function () {
            return this._viewRect;
        },

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

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

    return View;
});
// Fix for 南海诸岛
define('echarts/coord/geo/fix/nanhai',['require','../Region'],function (require) {

    var Region = require('../Region');

    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];
        }
    }
    return function (geo) {
        if (geo.map === 'china') {
            geo.regions.push(new Region(
                '南海诸岛', points, geoCoord
            ));
        }
    }
});
define('echarts/coord/geo/fix/textCoord',['require','zrender/core/util'],function (require) {

    var zrUtil = require('zrender/core/util');

    var coordsOffsetMap = {
        '南海诸岛' : [32, 80],
        // 全国
        '广东': [0, -10],
        '香港': [10, 5],
        '澳门': [-10, 10],
        //'北京': [-10, 0],
        '天津': [5, 5]
    };

    return 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);
            }
        });
    };
});
define('echarts/coord/geo/fix/geoCoord',['require','zrender/core/util'],function (require) {

    var zrUtil = require('zrender/core/util');

    var geoCoordMap = {
        'Russia': [100, 60],
        'United States of America': [-99, 38]
    };

    return 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];
            }
        });
    };
});
define('echarts/coord/geo/Geo',['require','./parseGeoJson','zrender/core/util','zrender/core/BoundingRect','../View','./fix/nanhai','./fix/textCoord','./fix/geoCoord'],function (require) {

    var parseGeoJson = require('./parseGeoJson');

    var zrUtil = require('zrender/core/util');

    var BoundingRect = require('zrender/core/BoundingRect');

    var View = require('../View');


    // Geo fix functions
    var geoFixFuncs = [
        require('./fix/nanhai'),
        require('./fix/textCoord'),
        require('./fix/geoCoord')
    ];

    /**
     * [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;
        /**
         * @param {Array.<string>}
         * @readOnly
         */
        this.dimensions = ['lng', 'lat'];

        this._nameCoordMap = {};

        this.loadGeoJson(geoJson, specialAreas, nameMap);
    }

    Geo.prototype = {

        constructor: Geo,

        type: 'geo',

        /**
         * @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;
            }
            specialAreas = specialAreas || {};
            nameMap = nameMap || {};
            var regions = this.regions;
            var regionsMap = {};
            for (var i = 0; i < regions.length; i++) {
                var regionName = regions[i].name;
                // Try use the alias in nameMap
                regionName = nameMap[regionName] || regionName;
                regions[i].name = regionName;

                regionsMap[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[name];
        },

        /**
         * Add geoCoord for indexing by name
         * @param {string} name
         * @param {Array.<number>} geoCoord
         */
        addGeoCoord: function (name, geoCoord) {
            this._nameCoordMap[name] = geoCoord;
        },

        /**
         * Get geoCoord by name
         * @param {string} name
         * @return {Array.<number>}
         */
        getGeoCoord: function (name) {
            return this._nameCoordMap[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);
        },

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

    zrUtil.mixin(Geo, View);

    return Geo;
});
define('echarts/coord/geo/geoCreator',['require','./GeoModel','./Geo','../../util/layout','zrender/core/util','../../echarts'],function (require) {

    require('./GeoModel');

    var Geo = require('./Geo');

    var layout = require('../../util/layout');
    var zrUtil = require('zrender/core/util');

    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 rect = this.getBoundingRect();

        var boxLayoutOption = geoModel.getBoxLayoutParams();
        // 0.75 rate
        boxLayoutOption.aspect = rect.width / rect.height * 0.75;

        var viewRect = layout.getLayoutRect(boxLayoutOption, {
            width: api.getWidth(),
            height: api.getHeight()
        });

        this.setViewRect(viewRect.x, viewRect.y, viewRect.width, viewRect.height);

        var roamDetailModel = geoModel.getModel('roamDetail');

        var panX = roamDetailModel.get('x') || 0;
        var panY = roamDetailModel.get('y') || 0;
        var zoom = roamDetailModel.get('zoom') || 1;

        this.setPan(panX, panY);
        this.setZoom(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);
        });
    }

    var geoCreator = {

        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 (!mapData) {
                    // Warning
                // }
                var geo = new Geo(
                    name + idx, name,
                    mapData && mapData.geoJson, mapData && mapData.specialAreas,
                    geoModel.get('nameMap')
                );
                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) {
                var mapType = seriesModel.get('map');

                mapModelGroupBySeries[mapType] = mapModelGroupBySeries[mapType] || [];

                mapModelGroupBySeries[mapType].push(seriesModel);
            });

            zrUtil.each(mapModelGroupBySeries, function (mapSeries, mapType) {
                var mapData = mapDataStores[mapType];
                // if (!mapData) {
                    // Warning
                // }

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

    // Inject methods into echarts
    var echarts = require('../../echarts');

    echarts.registerMap = geoCreator.registerMap;

    echarts.getMap = geoCreator.getMap;

    // TODO
    echarts.loadMap = function () {};

    echarts.registerCoordinateSystem('geo', geoCreator);
});
define('echarts/chart/map/mapSymbolLayout',['require','zrender/core/util'],function (require) {

    var zrUtil = require('zrender/core/util');

    return function (ecModel) {

        var processedMapType = {};

        ecModel.eachSeriesByType('map', function (mapSeries) {
            var mapType = mapSeries.get('mapType');
            if (processedMapType[mapType]) {
                return;
            }

            var mapSymbolOffsets = {};

            zrUtil.each(mapSeries.seriesGroup, function (subMapSeries) {
                var geo = subMapSeries.coordinateSystem;
                var data = subMapSeries.getData();
                if (subMapSeries.get('showLegendSymbol') && ecModel.getComponent('legend')) {
                    data.each('value', function (value, idx) {
                        var name = data.getName(idx);
                        var region = geo.getRegion(name);

                        // No region or no value
                        // In MapSeries data regions will be filled with NaN
                        // If they are not in the series.data array.
                        // 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;
        });
    };
});
define('echarts/chart/map/mapVisual',['require'],function (require) {
    return 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
            });
        });
    };
});
define('echarts/chart/map/mapDataStatistic',['require','zrender/core/util'],function (require) {

    var zrUtil = require('zrender/core/util');

    // FIXME 公用？
    /**
     * @param {Array.<module:echarts/data/List>} datas
     * @param {string} statisticsType 'average' 'sum'
     * @inner
     */
    function dataStatistics(datas, statisticsType) {
        var dataNameMap = {};
        var dims = ['value'];

        for (var i = 0; i < datas.length; i++) {
            datas[i].each(dims, function (value, idx) {
                var name = datas[i].getName(idx);
                dataNameMap[name] = dataNameMap[name] || [];
                if (!isNaN(value)) {
                    dataNameMap[name].push(value);
                }
            });
        }

        return datas[0].map(dims, function (value, idx) {
            var name = datas[0].getName(idx);
            var sum = 0;
            var min = Infinity;
            var max = -Infinity;
            var len = dataNameMap[name].length;
            for (var i = 0; i < len; i++) {
                min = Math.min(min, dataNameMap[name][i]);
                max = Math.max(max, dataNameMap[name][i]);
                sum += dataNameMap[name][i];
            }
            var result;
            if (statisticsType === 'min') {
                result = min;
            }
            else if (statisticsType === 'max') {
                result = max;
            }
            else if (statisticsType === 'average') {
                result = sum / len;
            }
            else {
                result = sum;
            }
            return len === 0 ? NaN : result;
        });
    }

    return function (ecModel) {
        var seriesGroupByMapType = {};
        ecModel.eachSeriesByType('map', function (seriesModel) {
            var mapType = seriesModel.get('map');
            seriesGroupByMapType[mapType] = seriesGroupByMapType[mapType] || [];
            seriesGroupByMapType[mapType].push(seriesModel);
        });

        zrUtil.each(seriesGroupByMapType, function (seriesList, mapType) {
            var data = dataStatistics(
                zrUtil.map(seriesList, function (seriesModel) {
                    return seriesModel.getData();
                }),
                seriesList[0].get('mapValueCalculation')
            );

            seriesList[0].seriesGroup = [];

            seriesList[0].setData(data);

            // FIXME Put where?
            for (var i = 0; i < seriesList.length; i++) {
                seriesList[i].seriesGroup = seriesList;
                seriesList[i].needsDrawMap = i === 0;
            }
        });
    };
});
define('echarts/chart/map/backwardCompat',['require','zrender/core/util'],function (require) {

    var zrUtil = require('zrender/core/util');
    var geoProps = [
        'x', 'y', 'x2', 'y2', 'width', 'height', 'map', 'roam', 'roamDetail', 'label', 'itemStyle'
    ];

    var geoCoordsMap = {};

    function createGeoFromMap(mapSeriesOpt) {
        var geoOpt = {};
        zrUtil.each(geoProps, function (propName) {
            if (mapSeriesOpt[propName] != null) {
                geoOpt[propName] = mapSeriesOpt[propName];
            }
        });
        return geoOpt;
    }
    return function (option) {
        // Save geoCoord
        var mapSeries = [];
        zrUtil.each(option.series, function (seriesOpt) {
            if (seriesOpt.type === 'map') {
                mapSeries.push(seriesOpt);
            }
            zrUtil.extend(geoCoordsMap, seriesOpt.geoCoord);
        });

        var newCreatedGeoOptMap = {};
        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);
            if (seriesOpt.markPoint) {
                var markPoint = seriesOpt.markPoint;
                // Convert name or geoCoord in markPoint to lng and lat
                // For example
                // { name: 'xxx', value: 10} Or
                // { geoCoord: [lng, lat], value: 10} to
                // { name: 'xxx', value: [lng, lat, 10]}
                markPoint.data = zrUtil.map(markPoint.data, function (dataOpt) {
                    if (!zrUtil.isArray(dataOpt.value)) {
                        var geoCoord;
                        if (dataOpt.geoCoord) {
                            geoCoord = dataOpt.geoCoord;
                        }
                        else if (dataOpt.name) {
                            geoCoord = geoCoordsMap[dataOpt.name];
                        }
                        var newValue = geoCoord ? [geoCoord[0], geoCoord[1]] : [NaN, NaN];
                        if (dataOpt.value != null) {
                            newValue.push(dataOpt.value);
                        }
                        dataOpt.value = newValue;
                    }
                    return dataOpt;
                });
                // Convert map series which only has markPoint without data to scatter series
                // FIXME
                if (!(seriesOpt.data && seriesOpt.data.length)) {
                    if (!option.geo) {
                        option.geo = [];
                    }

                    // Use same geo if multiple map series has same map type
                    var geoOpt = newCreatedGeoOptMap[seriesOpt.map];
                    if (!geoOpt) {
                        geoOpt = newCreatedGeoOptMap[seriesOpt.map] = createGeoFromMap(seriesOpt);
                        option.geo.push(geoOpt);
                    }

                    var scatterSeries = seriesOpt.markPoint;
                    scatterSeries.type = option.effect && option.effect.show ? 'effectScatter' : 'scatter';
                    scatterSeries.coordinateSystem = 'geo';
                    scatterSeries.geoIndex = zrUtil.indexOf(option.geo, geoOpt);
                    scatterSeries.name = seriesOpt.name;

                    option.series.splice(zrUtil.indexOf(option.series, seriesOpt), 1, scatterSeries);
                }
            }
        });
    };
});
define('echarts/chart/map',['require','../echarts','./map/MapSeries','./map/MapView','../action/geoRoam','../coord/geo/geoCreator','./map/mapSymbolLayout','./map/mapVisual','./map/mapDataStatistic','./map/backwardCompat','../action/createDataSelectAction'],function (require) {

    var echarts = require('../echarts');

    require('./map/MapSeries');

    require('./map/MapView');

    require('../action/geoRoam');

    require('../coord/geo/geoCreator');

    echarts.registerLayout(require('./map/mapSymbolLayout'));

    echarts.registerVisualCoding('chart', require('./map/mapVisual'));

    echarts.registerProcessor('statistic', require('./map/mapDataStatistic'));

    echarts.registerPreprocessor(require('./map/backwardCompat'));

    require('../action/createDataSelectAction')('map', [{
        type: 'mapToggleSelect',
        event: 'mapselectchanged',
        method: 'toggleSelected'
    }, {
        type: 'mapSelect',
        event: 'mapselected',
        method: 'select'
    }, {
        type: 'mapUnSelect',
        event: 'mapunselected',
        method: 'unSelect'
    }]);
});
/**
 * Link list to graph or tree
 */
define('echarts/data/helper/linkList',['require','zrender/core/util'],function (require) {

    var zrUtil = require('zrender/core/util');
    var arraySlice = Array.prototype.slice;

    // Caution:
    // In most case, only one of the list and its shallow clones (see list.cloneShallow)
    // can be active in echarts process. 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.

    function linkList(list, target, targetType) {
        zrUtil.each(listProxyMethods, function (method, methodName) {
            var originMethod = list[methodName];
            list[methodName] = zrUtil.curry(method, originMethod, target, targetType);
        });

        list[targetType] = target;
        target.data = list;

        return list;
    }

    var listProxyMethods = {
        cloneShallow: function (originMethod, target, targetType) {
            var newList = originMethod.apply(this, arraySlice.call(arguments, 3));
            return linkList(newList, target, targetType);
        },
        map: function (originMethod, target, targetType) {
            var newList = originMethod.apply(this, arraySlice.call(arguments, 3));
            return linkList(newList, target, targetType);
        },
        filterSelf: function (originMethod, target, targetType) {
            var result = originMethod.apply(this, arraySlice.call(arguments, 3));
            target.update();
            return result;
        }
    };

    return {
        linkToGraph: function (list, graph) {
            linkList(list, graph, 'graph');
        },

        linkToTree: function (list, tree) {
            linkList(list, tree, 'tree');
        }
    };
});
/**
 * Tree data structure
 *
 * @module echarts/data/Tree
 */
define('echarts/data/Tree',['require','zrender/core/util','../model/Model','./List','./helper/linkList','./helper/completeDimensions'],function(require) {

    var zrUtil = require('zrender/core/util');
    var Model = require('../model/Model');
    var List = require('./List');
    var linkListHelper = require('./helper/linkList');
    var completeDimensions = require('./helper/completeDimensions');

    /**
     * @constructor module:echarts/data/Tree~TreeNode
     * @param {string} name
     * @param {number} [dataIndex=-1]
     * @param {module:echarts/data/Tree} hostTree
     */
    var TreeNode = function (name, dataIndex, 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 = dataIndex == null ? -1 : dataIndex;

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

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

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

        buildHierarchy(dataRoot);

        function buildHierarchy(dataNode, parentNode) {
            listData.push(dataNode);

            var node = new TreeNode(dataNode.name, listData.length - 1, tree);
            parentNode
                ? addChild(node, parentNode)
                : (tree.root = 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);
        var list = new List(dimensions, hostModel);
        list.initData(listData);

        linkListHelper.linkToTree(list, tree);

        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;

        node.hostTree._nodes.push(child);
    }

    return Tree;
});
define('echarts/chart/treemap/TreemapSeries',['require','../../model/Series','../../data/Tree','zrender/core/util','../../model/Model','../../util/format'],function(require) {

    var SeriesModel = require('../../model/Series');
    var Tree = require('../../data/Tree');
    var zrUtil = require('zrender/core/util');
    var Model = require('../../model/Model');
    var formatUtil = require('../../util/format');
    var encodeHTML = formatUtil.encodeHTML;
    var addCommas = formatUtil.addCommas;


    return SeriesModel.extend({

        type: 'series.treemap',

        dependencies: ['grid', 'polar'],

        defaultOption: {
            // 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',               // 缩放时窗口大小。'origin' or 'fullscreen'
            squareRatio: 0.5 * (1 + Math.sqrt(5)), // golden ratio
            root: null,                         // default: tree root. This feature doesnt work unless node have id.
            visualDimension: 0,                 // Can be 0, 1, 2, 3.
            zoomToNodeRatio: 0.32 * 0.32,       // zoom to node时 node占可视区域的面积比例。
            roam: true,
            animation: true,
            animationDurationUpdate: 1500,
            animationEasing: 'quinticInOut',
            breadcrumb: {
                show: true,
                height: 22,
                left: 'center',
                top: 'bottom',
                // right
                // bottom
                emptyItemWidth: 25,                    // 空节点宽度
                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: ['50%', '50%'],      // 可以是 5 '5%' 'insideTopLeft', ...
                    textStyle: {
                        align: 'center',
                        baseline: 'middle',
                        color: '#fff',
                        ellipsis: true
                    }
                }
            },
            itemStyle: {
                normal: {
                    color: null,         // 各异 如不需，可设为'none'
                    colorAlpha: null,        // 默认不设置 如不需，可设为'none'
                    colorSaturation: null,        // 默认不设置 如不需，可设为'none'
                    borderWidth: 0,
                    gapWidth: 0,
                    borderColor: '#fff',
                    borderColorSaturation: null   // 如果设置，则borderColor的设置无效，而是取当前节点计算出的颜色，再经由borderColorSaturation处理。
                },
                emphasis: {}
            },
            color: 'none',    // 为数组，表示同一level的color 选取列表。默认空，在level[0].color中取系统color列表。
            colorAlpha: null,   // 为数组，表示同一level的color alpha 选取范围。
            colorSaturation: null,   // 为数组，表示同一level的color alpha 选取范围。
            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
                               // }
        },

        /**
         * @override
         */
        getInitialData: function (option, ecModel) {
            var data = option.data || [];
            var rootName = option.name;
            rootName == null && (rootName = option.name);

            // Create a virtual root.
            var root = {name: rootName, children: option.data};
            var value0 = (data[0] || {}).value;

            completeTreeValue(root, zrUtil.isArray(value0) ? value0.length : -1);

            // FIXME
            // sereis.mergeOption 的 getInitData是否放在merge后，从而能直接获取merege后的结果而非手动判断。
            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;
        },

        /**
         * @public
         */
        getViewRoot: function () {
            var optionRoot = this.option.root;
            var treeRoot = this.getData().tree.root;
            return optionRoot && treeRoot.getNodeById(optionRoot) || treeRoot;
        },

        /**
         * @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 data = this.getData();
            var node = data.tree.getNodeByDataIndex(dataIndex);
            var treePathInfo = params.treePathInfo = [];

            while (node) {
                var nodeDataIndex = node.dataIndex;
                treePathInfo.push({
                    name: node.name,
                    dataIndex: nodeDataIndex,
                    value: this.getRawValue(nodeDataIndex)
                });
                node = node.parentNode;
            }

            treePathInfo.reverse();

            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 = {};
                /**
                 * @private
                 * @type {number}
                 */
                this._idIndexMapCount = 0;
            }

            var index = idIndexMap[id];
            if (index == null) {
                idIndexMap[id] = index = this._idIndexMapCount++;
            }

            return index;
        }
    });

    /**
     * @param {Object} dataNode
     */
    function completeTreeValue(dataNode, arrValueLength) {
        // 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, arrValueLength);

            var childValue = child.value;
            zrUtil.isArray(childValue) && (childValue = childValue[0]);

            sum += childValue;
        });

        var thisValue = dataNode.value;

        if (arrValueLength >= 0) {
            if (!zrUtil.isArray(thisValue)) {
                dataNode.value = new Array(arrValueLength);
            }
            else {
                thisValue = thisValue[0];
            }
        }

        if (thisValue == null || isNaN(thisValue)) {
            thisValue = sum;
        }
        // Value should not less than 0.
        if (thisValue < 0) {
            thisValue = 0;
        }

        arrValueLength >= 0
            ? (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;
    }

});
define('echarts/chart/treemap/helper',['require'],function (require) {

    var helper = {

        retrieveTargetInfo: function (payload, seriesModel) {
            if (!payload || payload.type !== 'treemapZoomToNode') {
                return;
            }

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

            return null;
        }

    };

    return helper;
});
 define('echarts/chart/treemap/Breadcrumb',['require','../../util/graphic','../../util/layout','zrender/core/util'],function(require) {

    var graphic = require('../../util/graphic');
    var layout = require('../../util/layout');
    var zrUtil = require('zrender/core/util');

    var TEXT_PADDING = 8;
    var ITEM_GAP = 8;
    var ARRAY_LENGTH = 5;

    function Breadcrumb(containerGroup, onSelect) {
        /**
         * @private
         * @type {module:zrender/container/Group}
         */
        this.group = new graphic.Group();

        containerGroup.add(this.group);

        /**
         * @private
         * @type {Function}
         */
        this._onSelect = onSelect || zrUtil.noop;
    }

    Breadcrumb.prototype = {

        constructor: Breadcrumb,

        render: function (seriesModel, api, targetNode) {
            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(
                model, targetNode, layoutParam, textStyleModel
            );
            this._renderContent(
                model, targetNode, layoutParam, normalStyleModel, textStyleModel
            );

            layout.positionGroup(thisGroup, layoutParam.pos, layoutParam.box);
        },

        /**
         * Prepare render list and total width
         * @private
         */
        _prepare: function (model, 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 (
            model, targetNode, layoutParam, normalStyleModel, textStyleModel
        ) {
            // Start rendering.
            var lastX = 0;
            var emptyItemWidth = layoutParam.emptyItemWidth;
            var height = model.get('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 itemWidth = item.width;
                var text = item.text;

                // Hdie text and shorten width if necessary.
                if (totalWidth > availableSize.width) {
                    totalWidth -= itemWidth - emptyItemWidth;
                    itemWidth = emptyItemWidth;
                    text = '';
                }

                this.group.add(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()
                        }
                    ),
                    onclick: zrUtil.bind(this._onSelect, this, item.node)
                }));

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

    return Breadcrumb;
});
 define('echarts/util/animation',['require','zrender/core/util'],function(require) {

    var zrUtil = require('zrender/core/util');

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

    return {createWrap: createWrap};
});
 define('echarts/chart/treemap/TreemapView',['require','zrender/core/util','../../util/graphic','../../data/DataDiffer','./helper','./Breadcrumb','../../component/helper/RoamController','zrender/core/BoundingRect','zrender/core/matrix','../../util/animation','../../echarts'],function(require) {

    var zrUtil = require('zrender/core/util');
    var graphic = require('../../util/graphic');
    var DataDiffer = require('../../data/DataDiffer');
    var helper = require('./helper');
    var Breadcrumb = require('./Breadcrumb');
    var RoamController = require('../../component/helper/RoamController');
    var BoundingRect = require('zrender/core/BoundingRect');
    var matrix = require('zrender/core/matrix');
    var animationUtil = require('../../util/animation');
    var bind = zrUtil.bind;
    var Group = graphic.Group;
    var Rect = graphic.Rect;
    var each = zrUtil.each;

    var DRAG_THRESHOLD = 3;

    return require('../../echarts').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 payloadType = payload && payload.type;
            var layoutInfo = seriesModel.layoutInfo;
            var isInit = !this._oldTree;

            var containerGroup = this._giveContainerGroup(layoutInfo);

            var renderResult = this._doRender(containerGroup, seriesModel);

            (!isInit && (!payloadType || payloadType === 'treemapZoomToNode'))
                ? this._doAnimation(containerGroup, renderResult, seriesModel)
                : renderResult.renderFinally();

            this._resetController(api);

            var targetInfo = helper.retrieveTargetInfo(payload, seriesModel);
            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.position = [layoutInfo.x, layoutInfo.y];

            return containerGroup;
        },

        /**
         * @private
         */
        _doRender: function (containerGroup, seriesModel) {
            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 willVisibleEls = [];
            var willDeleteEls = [];
            var renderNode = bind(
                this._renderNode, this,
                thisStorage, oldStorage, lastsForAnimation, willInvisibleEls, willVisibleEls
            );
            var viewRoot = seriesModel.getViewRoot();

            // 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,
                viewRoot === thisTree.root
            );

            // 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, inView) {
                // 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;

                    // Whether under viewRoot.
                    var subInView = inView || thisNode === viewRoot;
                    // If not under viewRoot, only remove.
                    if (!subInView) {
                        thisNode = null;
                    }

                    var group = renderNode(thisNode, oldNode, parentGroup);

                    group && dualTravel(
                        thisNode && thisNode.viewChildren || [],
                        oldNode && oldNode.viewChildren || [],
                        group,
                        sameTree,
                        subInView
                    );
                }
            }

            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 = storageName);
                    });
                });
                return willDeleteEls;
            }

            function renderFinally() {
                each(willDeleteEls, function (els) {
                    each(els, function (el) {
                        el.parent && el.parent.remove(el);
                    });
                });
                // Theoritically there is no intersection between willInvisibleEls
                // and willVisibleEls have, but we set visible after for robustness.
                each(willInvisibleEls, function (el) {
                    el.invisible = true;
                    // Setting invisible is for optimizing, so no need to set dirty,
                    // just mark as invisible.
                });
                each(willVisibleEls, function (el) {
                    el.invisible = false;
                    el.__tmWillVisible = false;
                    el.dirty();
                });
            }
        },

        /**
         * @private
         */
        _renderNode: function (
            thisStorage, oldStorage, lastsForAnimation,
            willInvisibleEls, willVisibleEls,
            thisNode, oldNode, parentGroup
        ) {
            var thisRawIndex = thisNode && thisNode.getRawIndex();
            var oldRawIndex = oldNode && oldNode.getRawIndex();

            // Deleting things will performed finally. This method just find element from
            // old storage, or create new element, set them to new storage, and set styles.
            if (!thisNode) {
                return;
            }

            var layout = thisNode.getLayout();
            var thisWidth = layout.width;
            var thisHeight = layout.height;
            var invisible = layout.invisible;

            // Node group
            var group = giveGraphic('nodeGroup', Group);
            if (!group) {
                return;
            }
            parentGroup.add(group);
            group.position = [layout.x, layout.y];
            group.__tmNodeWidth = thisWidth;
            group.__tmNodeHeight = thisHeight;

            // Background
            var bg = giveGraphic('background', Rect);
            if (bg) {
                bg.setShape({x: 0, y: 0, width: thisWidth, height: thisHeight});
                updateStyle(bg, {fill: thisNode.getVisual('borderColor', true)});
                group.add(bg);
            }

            var thisViewChildren = thisNode.viewChildren;

            // No children, render content.
            if (!thisViewChildren || !thisViewChildren.length) {
                var borderWidth = layout.borderWidth;
                var content = giveGraphic('content', Rect);

                if (content) {
                    var contentWidth = Math.max(thisWidth - 2 * borderWidth, 0);
                    var contentHeight = Math.max(thisHeight - 2 * borderWidth, 0);
                    var labelModel = thisNode.getModel('label.normal');
                    var textStyleModel = thisNode.getModel('label.normal.textStyle');
                    var text = thisNode.getModel().get('name');
                    var textRect = textStyleModel.getTextRect(text);
                    var showLabel = labelModel.get('show');

                    if (!showLabel || textRect.height > contentHeight) {
                        text = '';
                    }
                    else if (textRect.width > contentWidth) {
                        text = textStyleModel.get('ellipsis')
                            ? textStyleModel.ellipsis(text, contentWidth) : '';
                    }

                    // For tooltip.
                    content.dataIndex = thisNode.dataIndex;
                    content.seriesIndex = this.seriesModel.seriesIndex;

                    content.culling = true;
                    content.setShape({
                        x: borderWidth,
                        y: borderWidth,
                        width: contentWidth,
                        height: contentHeight
                    });
                    updateStyle(content, {
                        fill: thisNode.getVisual('color', true),
                        text: text,
                        textPosition: labelModel.get('position'),
                        textFill: textStyleModel.getTextColor(),
                        textAlign: textStyleModel.get('align'),
                        textBaseline: textStyleModel.get('baseline'),
                        textFont: textStyleModel.getFont()
                    });
                    group.add(content);
                }
            }

            return group;

            function giveGraphic(storageName, Ctor) {
                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 (!invisible) {
                    element = new Ctor();
                    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) {
                // New background do not animate but delay show.
                if (storageName === 'background') {
                    element.invisible = true;
                    element.__tmWillVisible = true;
                    willVisibleEls.push(element);
                }
                else {
                    var parentNode = thisNode.parentNode;
                    var parentOldBg;
                    var parentOldX = 0;
                    var parentOldY = 0;
                    // For convenient, get old bounding rect from background.
                    if (parentNode && (
                        parentOldBg = lastsForAnimation.background[parentNode.getRawIndex()]
                    )) {
                        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}.
                    var lastCfg = lasts[thisRawIndex] = {};
                    lastCfg.old = storageName === 'nodeGroup'
                        ? [parentOldX, parentOldY]
                        : {x: parentOldX, y: parentOldY, width: 0, height: 0};

                    // Fade in, user can be aware that these nodes are new.
                    lastCfg.fadein = storageName !== 'nodeGroup';
                }
            }

            function updateStyle(element, style) {
                if (!invisible) {
                    // 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.
                    element.setStyle(style);
                    if (!element.__tmWillVisible) {
                        element.invisible = false;
                    }
                }
                else {
                    // Delay invisible setting utill animation finished,
                    // avoid element vanish suddenly before animation.
                    !element.invisible && willInvisibleEls.push(element);
                }
            }
        },

        /**
         * @private
         */
        _doAnimation: function (containerGroup, renderResult, seriesModel) {
            if (!seriesModel.get('animation')) {
                return;
            }

            var duration = seriesModel.get('animationDurationUpdate');
            var easing = seriesModel.get('animationEasing');

            var animationWrap = animationUtil.createWrap();

            // Make delete animations.
            var viewRoot = this.seriesModel.getViewRoot();
            var rootGroup = this._storage.nodeGroup[viewRoot.getRawIndex()];
            rootGroup && rootGroup.traverse(function (el) {
                var storageName;
                if (el.invisible || !(storageName = el.__tmWillDelete)) {
                    return;
                }
                var targetX = 0;
                var targetY = 0;
                var parent = el.parent; // Always has parent, and parent is nodeGroup.
                if (!parent.__tmWillDelete) {
                    // Let node animate to right-bottom corner, cooperating with fadeout,
                    // which is perfect for user understanding.
                    targetX = parent.__tmNodeWidth;
                    targetY = parent.__tmNodeHeight;
                }
                var target = storageName === 'nodeGroup'
                    ? {position: [targetX, targetY], style: {opacity: 0}}
                    : {shape: {x: targetX, y: targetY, width: 0, height: 0}, style: {opacity: 0}};
                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') {
                        target = {position: el.position.slice()};
                        el.position = last.old;
                    }
                    else {
                        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();
                controller.on('pan', bind(handle, this, this._onPan));
                controller.on('zoom', bind(handle, this, this._onZoom));
            }

            function handle(handler) {
                this._mayClick = false;
                return handler.apply(this, Array.prototype.slice.call(arguments, 1));
            }

            controller.rect = new BoundingRect(0, 0, api.getWidth(), api.getHeight());

            if (!this.seriesModel.get('roam')) {
                controller.off('pan').off('zoom');
                this._controller = null;
                return;
            }
        },

        /**
         * @private
         */
        _onPan: function (dx, dy) {
            if (this._state !== 'animating'
                && (Math.abs(dx) > DRAG_THRESHOLD || Math.abs(dy) > DRAG_THRESHOLD)
            ) {
                // These param must not be cached.
                var viewRoot = this.seriesModel.getViewRoot();

                if (!viewRoot) {
                    return;
                }

                var rootLayout = viewRoot.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) {
            if (this._state !== 'animating') {
                // These param must not be cached.
                var viewRoot = this.seriesModel.getViewRoot();

                if (!viewRoot) {
                    return;
                }

                var rootLayout = viewRoot.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 targetInfo = this.findTarget(e.offsetX, e.offsetY);
                if (targetInfo) {
                    this._zoomToNode(targetInfo);
                }
            }
        },

        /**
         * @private
         */
        _renderBreadcrumb: function (seriesModel, api, targetInfo) {
            if (!targetInfo) {
                // Find breadcrumb tail on center of containerGroup.
                targetInfo = this.findTarget(api.getWidth() / 2, api.getHeight() / 2);

                if (!targetInfo) {
                    targetInfo = {node: seriesModel.getData().tree.root};
                }
            }

            (this._breadcrumb || (this._breadcrumb = new Breadcrumb(this.group, bind(onSelect, this))))
                .render(seriesModel, api, targetInfo.node);

            function onSelect(node) {
                this._zoomToNode({node: node});
            }
        },

        /**
         * @override
         */
        remove: function () {
            this._containerGroup && this._containerGroup.removeAll();
            this._storage = createStorage();
            this._state = 'ready';
            this._breadcrumb && this._breadcrumb.remove();
        },

        /**
         * @private
         */
        _zoomToNode: function (targetInfo) {
            this.api.dispatchAction({
                type: 'treemapZoomToNode',
                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;
        }

    });

    function createStorage() {
        return {nodeGroup: [], background: [], content: []};
    }
});
/**
 * @file Treemap action
 */
define('echarts/chart/treemap/treemapAction',['require','../../echarts'],function(require) {

    var echarts = require('../../echarts');

    var noop = function () {};

    echarts.registerAction({type: 'treemapZoomToNode', update: 'updateView'}, noop);
    echarts.registerAction({type: 'treemapRender', update: 'updateView'}, noop);
    echarts.registerAction({type: 'treemapMove', update: 'updateView'}, noop);

});
/**
 * @file Visual mapping.
 */
define('echarts/visual/VisualMapping',['require','zrender/core/util','zrender/tool/color','../util/number'],function (require) {

    var zrUtil = require('zrender/core/util');
    var zrColor = require('zrender/tool/color');
    var linearMap = require('../util/number').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'
     * @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, it represents
     *                                            categories is [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 only be array.
     *
     */
    var VisualMapping = function (option) {
        var mappingMethod = option.mappingMethod;
        var visualType = option.type;

        /**
         * @readOnly
         * @type {string}
         */
        this.type = visualType;

        /**
         * @readOnly
         * @type {string}
         */
        this.mappingMethod = mappingMethod;

        /**
         * @readOnly
         * @type {Object}
         */
        var thisOption = this.option = zrUtil.clone(option);

        /**
         * @private
         * @type {Function}
         */
        this._normalizeData = normalizers[mappingMethod];

        /**
         * @private
         * @type {Function}
         */
        this._getSpecifiedVisual = zrUtil.bind(
            specifiedVisualGetters[mappingMethod], this, visualType
        );

        zrUtil.extend(this, visualHandlers[visualType]);

        if (mappingMethod === 'piecewise') {
            preprocessForPiecewise(thisOption);
        }
        if (mappingMethod === 'category') {
            preprocessForCategory(thisOption);
        }
    };

    VisualMapping.prototype = {

        constructor: VisualMapping,

        applyVisual: null,

        isValueActive: null,

        mapValueToVisual: null,

        getNormalizer: function () {
            return zrUtil.bind(this._normalizeData, this);
        }
    };

    var visualHandlers = VisualMapping.visualHandlers = {

        color: {

            applyVisual: defaultApplyColor,

            /**
             * Create a mapper function
             * @return {Function}
             */
            getColorMapper: function () {
                var visual = isCategory(this)
                    ? this.option.visual
                    : zrUtil.map(this.option.visual, zrColor.parse);
                return zrUtil.bind(
                    isCategory(this)
                    ? function (value, isNormalized) {
                        !isNormalized && (value = this._normalizeData(value));
                        return getVisualForCategory(this, visual, 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, visual, out);
                        return returnRGBArray ? out : zrUtil.stringify(out, 'rgba');
                    }, this);
            },

            // value:
            // (1) {number}
            // (2) {Array.<number>} Represents a interval, for colorStops.
            // Return type:
            // (1) {string} color value like '#444'
            // (2) {Array.<Object>} colorStops,
            // like [{color: '#fff', offset: 0}, {color: '#444', offset: 1}]
            // where offset is between 0 and 1.
            mapValueToVisual: function (value) {
                var visual = this.option.visual;

                if (zrUtil.isArray(value)) {
                    value = [
                        this._normalizeData(value[0]),
                        this._normalizeData(value[1])
                    ];

                    // For creating gradient color list.
                    return zrColor.mapIntervalToColor(value, visual);
                }
                else {
                    var normalized = this._normalizeData(value);
                    var result = this._getSpecifiedVisual(value);

                    if (result == null) {
                        result = isCategory(this)
                            ? getVisualForCategory(this, visual, normalized)
                            : zrColor.mapToColor(normalized, visual);
                    }

                    return result;
                }
            }
        },

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

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

            mapValueToVisual: function (value) {
                var normalized = this._normalizeData(value);
                var result = this._getSpecifiedVisual(value);
                var visual = this.option.visual;

                if (result == null) {
                    result = isCategory(this)
                        ? getVisualForCategory(this, visual, normalized)
                        : (arrayGetByNormalizedValue(visual, normalized) || {});
                }

                return result;
            }
        },

        symbolSize: {
            applyVisual: function (value, getter, setter) {
                setter('symbolSize', this.mapValueToVisual(value));
            },

            mapValueToVisual: function (value) {
                var normalized = this._normalizeData(value);
                var result = this._getSpecifiedVisual(value);
                var visual = this.option.visual;

                if (result == null) {
                    result = isCategory(this)
                        ? getVisualForCategory(this, visual, normalized)
                        : linearMap(normalized, [0, 1], visual, true);
                }
                return result;
            }
        }
    };

    function preprocessForPiecewise(thisOption) {
        var pieceList = thisOption.pieceList;
        thisOption.hasSpecialVisual = false;

        zrUtil.each(pieceList, function (piece, index) {
            piece.originIndex = index;
            if (piece.visual) {
                thisOption.hasSpecialVisual = true;
            }
        });
    }

    function preprocessForCategory(thisOption) {
        // Hash categories.
        var categories = thisOption.categories;
        var visual = thisOption.visual;
        var isVisualArray = zrUtil.isArray(visual);

        if (!categories) {
            if (!isVisualArray) {
                // visual should be array when no categories.
                throw new Error();
            }
            else {
                return;
            }
        }

        var categoryMap = thisOption.categoryMap = {};
        each(categories, function (cate, index) {
            categoryMap[cate] = index;
        });

        // Process visual map input.
        if (!isVisualArray) {
            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 = thisOption.visual = 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 makePartialColorVisualHandler(applyValue) {
        return {

            applyVisual: function (value, getter, setter) {
                // color can be {string} or {Array.<Object>} (for gradient color stops)
                var color = getter('color');
                var isArrayValue = zrUtil.isArray(value);
                value = isArrayValue
                    ? [this.mapValueToVisual(value[0]), this.mapValueToVisual(value[1])]
                    : this.mapValueToVisual(value);

                if (zrUtil.isArray(color)) {
                    for (var i = 0, len = color.length; i < len; i++) {
                        color[i].color = applyValue(
                            color[i].color, isArrayValue ? value[i] : value
                        );
                    }
                }
                else {
                    // Must not be array value
                    setter('color', applyValue(color, value));
                }
            },

            mapValueToVisual: function (value) {
                var normalized = this._normalizeData(value);
                var result = this._getSpecifiedVisual(value);
                var visual = this.option.visual;

                if (result == null) {
                    result = isCategory(this)
                        ? getVisualForCategory(this, visual, normalized)
                        : linearMap(normalized, [0, 1], visual, true);
                }
                return result;
            }
        };
    }

    function arrayGetByNormalizedValue(arr, normalized) {
        return arr[
            Math.round(linearMap(normalized, [0, 1], [0, arr.length - 1], true))
        ];
    }

    function defaultApplyColor(value, getter, setter) {
        setter('color', this.mapValueToVisual(value));
    }

    function getVisualForCategory(me, visual, normalized) {
        return visual[
            (me.option.loop && normalized !== CATEGORY_DEFAULT_VISUAL_INDEX)
                ? normalized % visual.length
                : normalized
        ];
    }

    function isCategory(me) {
        return me.option.mappingMethod === 'category';
    }


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


    // FIXME
    // refactor
    var specifiedVisualGetters = {

        // Linear do not support this feature.
        linear: zrUtil.noop,

        piecewise: function (visualType, 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[visualType];
                }
            }
        },

        // Category do not need to support this feature.
        // Visual can be set in visualMap.inRange or
        // visualMap.outOfRange directly.
        category: zrUtil.noop
    };

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

    /**
     * 'color', 'colorSaturation', 'colorAlpha', ... are in the same visualCluster named 'color'.
     * Other visuals are in the cluster named as the same as theirselves.
     *
     * @public
     * @param {string} visualType
     * @param {string} visualCluster
     * @return {boolean}
     */
    VisualMapping.isInVisualCluster = function (visualType, visualCluster) {
        return visualCluster === 'color'
            ? !!(visualType && visualType.indexOf(visualCluster) === 0)
            : visualType === visualCluster;
    };

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

    /**
     * @public {Array.<Object>} [{value: ..., interval: [min, max]}, ...]
     * @return {number} index
     */
    VisualMapping.findPieceIndex = function (value, pieceList) {
        // value has high priority.
        for (var i = 0, len = pieceList.length; i < len; i++) {
            var piece = pieceList[i];
            if (piece.value != null && piece.value === value) {
                return i;
            }
        }

        for (var i = 0, len = pieceList.length; i < len; i++) {
            var piece = pieceList[i];
            var interval = piece.interval;
            if (interval) {
                if (interval[0] === -Infinity) {
                    if (value < interval[1]) {
                        return i;
                    }
                }
                else if (interval[1] === Infinity) {
                    if (interval[0] < value) {
                        return i;
                    }
                }
                else if (
                    piece.interval[0] <= value
                    && value <= piece.interval[1]
                ) {
                    return i;
                }
            }
        }
    };

    return VisualMapping;

});

define('echarts/chart/treemap/treemapVisual',['require','../../visual/VisualMapping','zrender/tool/color','zrender/core/util'],function (require) {

    var VisualMapping = require('../../visual/VisualMapping');
    var zrColor = require('zrender/tool/color');
    var zrUtil = require('zrender/core/util');
    var isArray = zrUtil.isArray;

    var ITEM_STYLE_NORMAL = 'itemStyle.normal';

    return function (ecModel, 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,
                {},
                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.invisible) {
            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 colorMappingBy = nodeModel.get('colorMappingBy');
        var opt = {
            type: rangeVisual.name,
            dataExtent: nodeLayout.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;
    }

});
define('echarts/chart/treemap/treemapLayout',['require','zrender/core/util','../../util/number','../../util/layout','zrender/core/BoundingRect','./helper'],function (require) {

    var mathMax = Math.max;
    var mathMin = Math.min;
    var zrUtil = require('zrender/core/util');
    var numberUtil = require('../../util/number');
    var layout = require('../../util/layout');
    var parsePercent = numberUtil.parsePercent;
    var retrieveValue = zrUtil.retrieve;
    var BoundingRect = require('zrender/core/BoundingRect');
    var helper = require('./helper');

    /**
     * @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 size = seriesModel.get('size') || []; // Compatible with ec2.
            var containerWidth = parsePercent(
                retrieveValue(seriesModel.get('width'), size[0]),
                ecWidth
            );
            var containerHeight = parsePercent(
                retrieveValue(seriesModel.get('height'), size[1]),
                ecHeight
            );

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

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

            if (payloadType !== 'treemapMove') {
                var rootSize = payloadType === 'treemapZoomToNode'
                    ? estimateRootSize(seriesModel, targetInfo, containerWidth, containerHeight)
                    : rootRect
                    ? [rootRect.width, rootRect.height]
                    : [containerWidth, containerHeight];

                var sort = seriesModel.get('sort');
                if (sort && sort !== 'asc' && sort !== 'desc') {
                    sort = 'desc';
                }
                var options = {
                    squareRatio: seriesModel.get('squareRatio'),
                    sort: sort
                };

                viewRoot.setLayout({
                    x: 0, y: 0,
                    width: rootSize[0], height: rootSize[1],
                    area: rootSize[0] * rootSize[1]
                });

                squarify(viewRoot, options);
            }

            // Set root position
            viewRoot.setLayout(
                calculateRootPosition(layoutInfo, rootRect, targetInfo),
                true
            );

            seriesModel.setLayoutInfo(layoutInfo);

            // Optimize
            // FIXME
            // 现在没有clip功能，暂时取ec高宽。
            prunning(
                viewRoot,
                new BoundingRect(-layoutInfo.x, -layoutInfo.y, ecWidth, ecHeight)
            );

        });
    }

    /**
     * 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 {boolean} options.hideChildren
     * @param {number} options.squareRatio
     */
    function squarify(node, options) {
        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);

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

        // Update option carefully.
        var hideChildren;
        if (!options.hideChildren) {
            var childrenVisibleMin = nodeModel.get('childrenVisibleMin');
            if (childrenVisibleMin != null && totalArea < childrenVisibleMin) {
                hideChildren = true;
            }
        }

        for (var i = 0, len = viewChildren.length; i < len; i++) {
            var childOption = zrUtil.extend({
                hideChildren: hideChildren
            }, options);

            squarify(viewChildren[i], childOption);
        }
    }

    /**
     * Set area to each child, and calculate data extent for visual coding.
     */
    function initChildren(node, nodeModel, totalArea, options) {
        var viewChildren = node.children || [];
        var orderBy = options.sort;
        orderBy !== 'asc' && orderBy !== 'desc' && (orderBy = null);

        if (options.hideChildren) {
            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});
        }

        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) {
                return orderBy === 'asc'
                    ?  a.getValue() - b.getValue() : b.getValue() - a.getValue();
            });
        }
        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];
            zrUtil.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, 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 === seriesModel.getViewRoot()) {
            return defaultSize;
        }

        var parent;
        var viewArea = containerWidth * containerHeight;
        var area = viewArea * seriesModel.get('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 invisible nodes for prunning when visual coding and rendering.
    // Prunning depends on layout and root position, so we have to do it after them.
    function prunning(node, clipRect) {
        var nodeLayout = node.getLayout();

        node.setLayout({invisible: !clipRect.intersect(nodeLayout)}, true);

        var viewChildren = node.viewChildren || [];
        for (var i = 0, len = viewChildren.length; i < len; i++) {
            // Transform to child coordinate.
            var childClipRect = new BoundingRect(
                clipRect.x - nodeLayout.x,
                clipRect.y - nodeLayout.y,
                clipRect.width,
                clipRect.height
            );
            prunning(viewChildren[i], childClipRect);
        }
    }

    return update;
});
define('echarts/chart/treemap',['require','../echarts','./treemap/TreemapSeries','./treemap/TreemapView','./treemap/treemapAction','./treemap/treemapVisual','./treemap/treemapLayout'],function (require) {

    var echarts = require('../echarts');

    require('./treemap/TreemapSeries');
    require('./treemap/TreemapView');
    require('./treemap/treemapAction');

    echarts.registerVisualCoding('chart', require('./treemap/treemapVisual'));

    echarts.registerLayout(require('./treemap/treemapLayout'));
});
/**
 * Graph data structure
 *
 * @module echarts/data/Graph
 * @author Yi Shen(https://www.github.com/pissang)
 */
define('echarts/data/Graph',['require','zrender/core/util'],function(require) {



    var zrUtil = require('zrender/core/util');

    /**
     * @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) {
        var nodesMap = this._nodesMap;

        if (nodesMap[id]) {
            return;
        }

        var node = new Node(id, dataIndex);
        node.hostGraph = this;

        this.nodes.push(node);

        nodesMap[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[id];
    };

    /**
     * Add a new edge
     * @param {string|module:echarts/data/Graph.Node} n1
     * @param {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;

        if (!(n1 instanceof Node)) {
            n1 = nodesMap[n1];
        }
        if (!(n2 instanceof Node)) {
            n2 = nodesMap[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[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(otherNode, 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;
        }
    };

    /**
     * Set edge data
     * @param {module:echarts/data/List} edgeData
     */
    graphProto.setEdgeData = function (edgeData) {
        this.edgeData = edgeData;
        this._edgeDataSaved = edgeData.cloneShallow();
    };

    graphProto.restoreData = function () {
        this.edgeData = this._edgeDataSaved.cloneShallow();
    };

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

    return Graph;
});
define('echarts/chart/helper/createGraphFromNodeEdge',['require','../../data/List','../../data/Graph','../../data/helper/linkList','../../data/helper/completeDimensions','zrender/core/util'],function (require) {

    var List = require('../../data/List');
    var Graph = require('../../data/Graph');
    var linkList = require('../../data/helper/linkList');
    var completeDimensions = require('../../data/helper/completeDimensions');
    var zrUtil = require('zrender/core/util');

    return function (nodes, edges, hostModel, directed) {
        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 = [];
        for (var i = 0; i < edges.length; i++) {
            var link = edges[i];
            // addEdge may fail when source or target not exists
            if (graph.addEdge(link.source, link.target, i)) {
                validEdges.push(link);
                linkNameList.push(zrUtil.retrieve(link.id, link.source + ' - ' + link.target));
            }
        }

        // FIXME
        var dimensionNames = completeDimensions(['value'], nodes);

        var nodeData = new List(dimensionNames, hostModel);
        var edgeData = new List(['value'], hostModel);

        nodeData.initData(nodes);
        edgeData.initData(validEdges, linkNameList);

        graph.setEdgeData(edgeData);

        linkList.linkToGraph(nodeData, graph);
        // Update dataIndex of nodes and edges because invalid edge may be removed
        graph.update();

        return graph;
    };
});
define('echarts/chart/graph/GraphSeries',['require','../../data/List','zrender/core/util','../helper/createGraphFromNodeEdge','../../echarts'],function (require) {



    var List = require('../../data/List');
    var zrUtil = require('zrender/core/util');

    var createGraphFromNodeEdge = require('../helper/createGraphFromNodeEdge');

    return require('../../echarts').extendSeriesModel({

        type: 'series.graph',

        init: function (option) {
            this.$superApply('init', arguments);

            // Provide data for legend select
            this.legendDataProvider = function () {
                return this._categoriesData;
            };

            this._updateCategoriesData();
        },

        mergeOption: function (option) {
            this.$superApply('mergeOption', arguments);

            this._updateCategoriesData();
        },

        getInitialData: function (option, ecModel) {
            var edges = option.edges || option.links;
            var nodes = option.data || option.nodes;
            if (nodes && edges) {
                var graph = createGraphFromNodeEdge(nodes, edges, this, true);
                var list = graph.data;
                var self = this;
                // Overwrite list.getItemModel to
                list.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;
                });
                return list;
            }
        },

        restoreData: function () {
            this.$superApply('restoreData', arguments);
            this.getGraph().restoreData();
        },

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

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

        /**
         * @param {number} zoom
         */
        setRoamZoom: function (zoom) {
            var roamDetail = this.option.roamDetail;
            roamDetail && (roamDetail.zoom = zoom);
        },

        /**
         * @param {number} x
         * @param {number} y
         */
        setRoamPan: function (x, y) {
            var roamDetail = this.option.roamDetail;
            if (roamDetail) {
                roamDetail.x = x;
                roamDetail.y = y;
            }
        },

        defaultOption: {
            zlevel: 0,
            z: 2,

            color: ['#61a0a8', '#d14a61', '#fd9c35', '#675bba', '#fec42c',
                    '#dd4444', '#fd9c35', '#cd4870'],

            coordinateSystem: 'view',

            legendHoverLink: true,

            hoverAnimation: true,

            layout: null,

            // Configuration of force
            force: {
                initLayout: null,
                repulsion: 50,
                gravity: 0.1,
                edgeLength: 30,

                layoutAnimation: true
            },

            left: 'center',
            top: 'center',
            // right: null,
            // bottom: null,
            // width: '80%',
            // height: '80%',

            symbol: 'circle',
            symbolSize: 10,

            draggable: false,

            roam: false,
            roamDetail: {
                x: 0,
                y: 0,
                zoom: 1
            },

            // Symbol size scale ratio in roam
            nodeScaleRatio: 0.6,

            // Line width scale ratio in roam
            // edgeScaleRatio: 0.1,

            // categories: [],

            // data: []
            // Or
            // nodes: []
            //
            // links: []
            // Or
            // edges: []

            label: {
                normal: {
                    show: false
                },
                emphasis: {
                    show: true
                }
            },

            itemStyle: {
                normal: {},
                emphasis: {}
            },

            lineStyle: {
                normal: {
                    color: '#aaa',
                    width: 1,
                    curveness: 0,
                    opacity: 0.5
                },
                emphasis: {}
            }
        }
   });

});
/**
 * Line path for bezier and straight line draw
 */
define('echarts/chart/helper/LinePath',['require','../../util/graphic'],function (require) {
    var graphic = require('../../util/graphic');

    var straightLineProto = graphic.Line.prototype;
    var bezierCurveProto = graphic.BezierCurve.prototype;

    return 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) {
            (shape.cpx1 == null || shape.cpy1 == null
                ? straightLineProto : bezierCurveProto).buildPath(ctx, shape);
        },

        pointAt: function (t) {
            var shape = this.shape;
            return shape.cpx1 == null || shape.cpy1 == null
                ? straightLineProto.pointAt.call(this, t)
                : bezierCurveProto.pointAt.call(this, t);
        }
    });
});
/**
 * @module echarts/chart/helper/Line
 */
define('echarts/chart/helper/Line',['require','../../util/symbol','zrender/core/vector','./LinePath','../../util/graphic','zrender/core/util','../../util/number'],function (require) {

    var symbolUtil = require('../../util/symbol');
    var vector = require('zrender/core/vector');
    var LinePath = require('./LinePath');
    var graphic = require('../../util/graphic');
    var zrUtil = require('zrender/core/util');
    var numberUtil = require('../../util/number');

    /**
     * @inner
     */
    function createSymbol(name, data, idx) {
        var color = data.getItemVisual(idx, 'color');
        var symbolType = data.getItemVisual(idx, 'symbol');
        var symbolSize = data.getItemVisual(idx, 'symbolSize');

        if (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',
            style: {
                strokeNoScale: true
            }
        });
        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];
        }
    }

    function isSymbolArrow(symbol) {
        return symbol.type === 'symbol' && symbol.shape.symbolType === 'arrow';
    }

    function updateSymbolBeforeLineUpdate () {
        var lineGroup = this;
        var line = lineGroup.childOfName('line');
        // If line not changed
        if (!this.__dirty && !line.__dirty) {
            return;
        }
        var symbolFrom = lineGroup.childOfName('fromSymbol');
        var symbolTo = lineGroup.childOfName('toSymbol');
        var label = lineGroup.childOfName('label');
        var fromPos = line.pointAt(0);
        var toPos = line.pointAt(line.shape.percent);

        var d = vector.sub([], toPos, fromPos);
        vector.normalize(d, d);

        if (symbolFrom) {
            symbolFrom.attr('position', fromPos);
            // Rotate the arrow
            // FIXME Hard coded ?
            if (isSymbolArrow(symbolTo)) {
                symbolTo.attr('rotation', tangentRotation(fromPos, toPos));
            }
        }
        if (symbolTo) {
            symbolTo.attr('position', toPos);
            if (isSymbolArrow(symbolFrom)) {
                symbolFrom.attr('rotation', tangentRotation(toPos, fromPos));
            }
        }

        label.attr('position', toPos);

        var textPosition;
        var textAlign;
        var textBaseline;
        // End
        if (label.__position === 'end') {
            textPosition = [d[0] * 5 + toPos[0], d[1] * 5 + toPos[1]];
            textAlign = d[0] > 0.8 ? 'left' : (d[0] < -0.8 ? 'right' : 'center');
            textBaseline = d[1] > 0.8 ? 'top' : (d[1] < -0.8 ? 'bottom' : 'middle');
        }
        // Start
        else {
            textPosition = [-d[0] * 5 + fromPos[0], -d[1] * 5 + fromPos[1]];
            textAlign = d[0] > 0.8 ? 'right' : (d[0] < -0.8 ? 'left' : 'center');
            textBaseline = d[1] > 0.8 ? 'bottom' : (d[1] < -0.8 ? 'top' : 'middle');
        }
        label.attr({
            style: {
                // Use the user specified text align and baseline first
                textBaseline: label.__textBaseline || textBaseline,
                textAlign: label.__textAlign || textAlign
            },
            position: textPosition
        });
    }

    function tangentRotation(p1, p2) {
        return -Math.PI / 2 - Math.atan2(
            p2[1] - p1[1], p2[0] - p1[0]
        );
    }

    /**
     * @constructor
     * @extends {module:zrender/graphic/Group}
     * @alias {module:echarts/chart/helper/Line}
     */
    function Line(lineData, fromData, toData, idx) {
        graphic.Group.call(this);

        this._createLine(lineData, fromData, toData, idx);
    }

    var lineProto = Line.prototype;

    // Update symbol position and rotation
    lineProto.beforeUpdate = updateSymbolBeforeLineUpdate;

    lineProto._createLine = function (lineData, fromData, toData, idx) {
        var seriesModel = lineData.hostModel;
        var linePoints = lineData.getItemLayout(idx);

        var line = createLine(linePoints);
        line.shape.percent = 0;
        graphic.initProps(line, {
            shape: {
                percent: 1
            }
        }, seriesModel);

        this.add(line);

        var label = new graphic.Text({
            name: 'label'
        });
        this.add(label);

        if (fromData) {
            var symbolFrom = createSymbol('fromSymbol', fromData, 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(symbolFrom);

            this._fromSymbolType = fromData.getItemVisual(idx, 'symbol');
        }
        if (toData) {
            var symbolTo = createSymbol('toSymbol', toData, idx);
            this.add(symbolTo);

            this._toSymbolType = toData.getItemVisual(idx, 'symbol');
        }

        this._updateCommonStl(lineData, fromData, toData, idx);
    };

    lineProto.updateData = function (lineData, fromData, toData, idx) {
        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);

        // Symbol changed
        if (fromData) {
            var fromSymbolType = fromData.getItemVisual(idx, 'symbol');
            if (this._fromSymbolType !== fromSymbolType) {
                var symbolFrom = createSymbol('fromSymbol', fromData, idx);
                this.remove(line.childOfName('fromSymbol'));
                this.add(symbolFrom);
            }
            this._fromSymbolType = fromSymbolType;
        }
        if (toData) {
            var toSymbolType = toData.getItemVisual(idx, 'symbol');
            // Symbol changed
            if (toSymbolType !== this._toSymbolType) {
                var symbolTo = createSymbol('toSymbol', toData, idx);
                this.remove(line.childOfName('toSymbol'));
                this.add(symbolTo);
            }
            this._toSymbolType = toSymbolType;
        }

        this._updateCommonStl(lineData, fromData, toData, idx);
    };

    lineProto._updateCommonStl = function (lineData, fromData, toData, idx) {
        var seriesModel = lineData.hostModel;

        var line = this.childOfName('line');
        var itemModel = lineData.getItemModel(idx);

        var labelModel = itemModel.getModel('label.normal');
        var textStyleModel = labelModel.getModel('textStyle');
        var labelHoverModel = itemModel.getModel('label.emphasis');
        var textStyleHoverModel = labelHoverModel.getModel('textStyle');

        var defaultText = numberUtil.round(seriesModel.getRawValue(idx));
        if (isNaN(defaultText)) {
            // Use name
            defaultText = lineData.getName(idx);
        }
        line.setStyle(zrUtil.extend(
            {
                stroke: lineData.getItemVisual(idx, 'color')
            },
            itemModel.getModel('lineStyle.normal').getLineStyle()
        ));

        var label = this.childOfName('label');
        label.setStyle({
            text: labelModel.get('show')
                ? seriesModel.getFormattedLabel(idx, 'normal') || defaultText
                : '',
            textFont: textStyleModel.getFont(),
            fill: textStyleModel.getTextColor() || lineData.getItemVisual(idx, 'color')
        });
        label.hoverStyle = {
            text: labelHoverModel.get('show')
                ? seriesModel.getFormattedLabel(idx, 'emphasis') || defaultText
                : '',
            textFont: textStyleModel.getFont(),
            fill: textStyleHoverModel.getTextColor()
        };
        label.__textAlign = textStyleModel.get('align');
        label.__textBaseline = textStyleModel.get('baseline');
        label.__position = labelModel.get('position');

        graphic.setHoverStyle(
            this, itemModel.getModel('lineStyle.emphasis').getLineStyle()
        );
    };

    lineProto.updateLayout = function (lineData, fromData, toData, idx) {
        var points = lineData.getItemLayout(idx);
        var linePath = this.childOfName('line');
        setLinePoints(linePath.shape, points);
        linePath.dirty(true);
        fromData && fromData.getItemGraphicEl(idx).attr('position', points[0]);
        toData && toData.getItemGraphicEl(idx).attr('position', points[1]);
    };

    zrUtil.inherits(Line, graphic.Group);

    return Line;
});
/**
 * @module echarts/chart/helper/LineDraw
 */
define('echarts/chart/helper/LineDraw',['require','../../util/graphic','./Line'],function (require) {

    var graphic = require('../../util/graphic');
    var LineGroup = require('./Line');

    /**
     * @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
     * @param {module:echarts/data/List} [fromData]
     * @param {module:echarts/data/List} [toData]
     */
    lineDrawProto.updateData = function (lineData, fromData, toData) {

        var oldLineData = this._lineData;
        var group = this.group;
        var LineCtor = this._ctor;

        lineData.diff(oldLineData)
            .add(function (idx) {
                var lineGroup = new LineCtor(lineData, fromData, toData, idx);

                lineData.setItemGraphicEl(idx, lineGroup);

                group.add(lineGroup);
            })
            .update(function (newIdx, oldIdx) {
                var lineGroup = oldLineData.getItemGraphicEl(oldIdx);
                lineGroup.updateData(lineData, fromData, toData, newIdx);

                lineData.setItemGraphicEl(newIdx, lineGroup);

                group.add(lineGroup);
            })
            .remove(function (idx) {
                group.remove(oldLineData.getItemGraphicEl(idx));
            })
            .execute();

        this._lineData = lineData;
        this._fromData = fromData;
        this._toData = toData;
    };

    lineDrawProto.updateLayout = function () {
        var lineData = this._lineData;
        lineData.eachItemGraphicEl(function (el, idx) {
            el.updateLayout(lineData, this._fromData, this._toData, idx);
        }, this);
    };

    lineDrawProto.remove = function () {
        this.group.removeAll();
    };

    return LineDraw;
});

define('echarts/chart/graph/GraphView',['require','../helper/SymbolDraw','../helper/LineDraw','../../component/helper/RoamController','../../util/model','../../util/graphic','../../echarts'],function (require) {

    var SymbolDraw = require('../helper/SymbolDraw');
    var LineDraw = require('../helper/LineDraw');
    var RoamController = require('../../component/helper/RoamController');

    var modelUtil = require('../../util/model');
    var graphic = require('../../util/graphic');

    require('../../echarts').extendChartView({

        type: 'graph',

        init: function (ecModel, api) {
            var symbolDraw = new SymbolDraw();
            var lineDraw = new LineDraw();
            var group = this.group;

            var controller = new RoamController(api.getZr(), group);

            group.add(symbolDraw.group);
            group.add(lineDraw.group);

            this._symbolDraw = symbolDraw;
            this._lineDraw = lineDraw;
            this._controller = controller;

            this._firstRender = true;
        },

        render: function (seriesModel, ecModel, api) {
            var coordSys = seriesModel.coordinateSystem;
            // Only support view and geo coordinate system
            if (coordSys.type !== 'geo' && coordSys.type !== 'view') {
                return;
            }

            var data = seriesModel.getData();
            this._model = seriesModel;

            var symbolDraw = this._symbolDraw;
            var lineDraw = this._lineDraw;

            symbolDraw.updateData(data);

            var edgeData = data.graph.edgeData;
            var rawOption = seriesModel.option;
            var formatModel = modelUtil.createDataFormatModel(
                seriesModel, edgeData, rawOption.edges || rawOption.links
            );
            formatModel.formatTooltip = function (dataIndex) {
                var params = this.getDataParams(dataIndex);
                var rawDataOpt = params.data;
                var html = rawDataOpt.source + ' > ' + rawDataOpt.target;
                if (params.value) {
                    html += ':' + params.value;
                }
                return html;
            };
            lineDraw.updateData(edgeData, null, null);
            edgeData.eachItemGraphicEl(function (el) {
                el.traverse(function (child) {
                    child.hostModel = formatModel;
                });
            });

            // Save the original lineWidth
            data.graph.eachEdge(function (edge) {
                edge.__lineWidth = edge.getModel('lineStyle.normal').get('width');
            });

            var group = this.group;
            var groupNewProp = {
                position: coordSys.position,
                scale: coordSys.scale
            };
            if (this._firstRender) {
                group.attr(groupNewProp);
            }
            else {
                graphic.updateProps(group, groupNewProp, seriesModel);
            }

            this._nodeScaleRatio = seriesModel.get('nodeScaleRatio');
            // this._edgeScaleRatio = seriesModel.get('edgeScaleRatio');

            this._updateNodeAndLinkScale();

            this._updateController(seriesModel, coordSys, api);

            clearTimeout(this._layoutTimeout);
            var forceLayout = seriesModel.forceLayout;
            var layoutAnimation = seriesModel.get('force.layoutAnimation');
            if (forceLayout) {
                this._startForceLayoutIteration(forceLayout, layoutAnimation);
            }
            // Update draggable
            data.eachItemGraphicEl(function (el, idx) {
                var draggable = data.getItemModel(idx).get('draggable');
                if (draggable && forceLayout) {
                    el.on('drag', function () {
                        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 () {
                        forceLayout.setUnfixed(idx);
                    }, this);
                }
                else {
                    el.off('drag');
                }
                el.setDraggable(draggable);
            }, this);

            this._firstRender = false;
        },

        _startForceLayoutIteration: function (forceLayout, layoutAnimation) {
            var self = this;
            (function step() {
                forceLayout.step(function (stopped) {
                    self.updateLayout();
                    (self._layouting = !stopped) && (
                        layoutAnimation
                            ? (self._layoutTimeout = setTimeout(step, 16))
                            : step()
                    );
                });
            })();
        },

        _updateController: function (seriesModel, coordSys, api) {
            var controller = this._controller;
            controller.rect = coordSys.getViewRect();

            controller.enable(seriesModel.get('roam'));

            controller
                .off('pan')
                .off('zoom')
                .on('pan', function (dx, dy) {
                    api.dispatchAction({
                        seriesId: seriesModel.id,
                        type: 'graphRoam',
                        dx: dx,
                        dy: dy
                    });
                })
                .on('zoom', function (zoom, mouseX, mouseY) {
                    api.dispatchAction({
                        seriesId: seriesModel.id,
                        type: 'graphRoam',
                        zoom:  zoom,
                        originX: mouseX,
                        originY: mouseY
                    });
                })
                .on('zoom', this._updateNodeAndLinkScale, this);
        },

        _updateNodeAndLinkScale: function () {
            var seriesModel = this._model;
            var data = seriesModel.getData();

            var group = this.group;
            var nodeScaleRatio = this._nodeScaleRatio;
            // var edgeScaleRatio = this._edgeScaleRatio;

            // Assume scale aspect is 1
            var groupScale = group.scale[0];

            var nodeScale = (groupScale - 1) * nodeScaleRatio + 1;
            // var edgeScale = (groupScale - 1) * edgeScaleRatio + 1;
            var invScale = [
                nodeScale / groupScale,
                nodeScale / groupScale
            ];

            data.eachItemGraphicEl(function (el, idx) {
                el.attr('scale', invScale);
            });
            // data.graph.eachEdge(function (edge) {
            //     var lineGroup = edge.getGraphicEl();
            //     // FIXME
            //     lineGroup.childOfName('line').setStyle(
            //         'lineWidth',
            //         edge.__lineWidth * edgeScale / groupScale
            //     );
            // });
        },

        updateLayout: function (seriesModel, ecModel) {
            this._symbolDraw.updateLayout();
            this._lineDraw.updateLayout();
        },

        remove: function (ecModel, api) {
            this._symbolDraw && this._symbolDraw.remove();
            this._lineDraw && this._lineDraw.remove();
        }
    });
});
define('echarts/chart/graph/roamAction',['require','../../echarts','../../action/roamHelper'],function (require) {

    var echarts = require('../../echarts');
    var roamHelper = require('../../action/roamHelper');

    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 roamDetailModel = seriesModel.getModel('roamDetail');
            var res = roamHelper.calcPanAndZoom(roamDetailModel, payload);

            seriesModel.setRoamPan
                && seriesModel.setRoamPan(res.x, res.y);

            seriesModel.setRoamZoom
                && seriesModel.setRoamZoom(res.zoom);

            coordSys && coordSys.setPan(res.x, res.y);
            coordSys && coordSys.setZoom(res.zoom);
        });
    });
});
define('echarts/chart/graph/categoryFilter',['require'],function (require) {

    return 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);
    };
});
define('echarts/chart/graph/categoryVisual',['require'],function (require) {

    return function (ecModel) {
        ecModel.eachSeriesByType('graph', function (seriesModel) {
            var colorList = seriesModel.get('color');
            var categoriesData = seriesModel.getCategoriesData();
            var data = seriesModel.getData();

            var categoryNameIdxMap = {};

            categoriesData.each(function (idx) {
                categoryNameIdxMap[categoriesData.getName(idx)] = idx;

                var itemModel = categoriesData.getItemModel(idx);
                var rawIdx = categoriesData.getRawIndex(idx);
                var color = itemModel.get('itemStyle.normal.color')
                    || colorList[rawIdx % colorList.length];
                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[category];
                        }
                        data.setItemVisual(
                            idx, 'color',
                            categoriesData.getItemVisual(category, 'color')
                        );
                    }
                });
            }
        });
    };
});
define('echarts/chart/graph/simpleLayoutHelper',['require'],function (require) {
    return 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')]);
        });

        graph.eachEdge(function (edge) {
            var curveness = edge.getModel().get('lineStyle.normal.curveness') || 0;
            var p1 = edge.node1.getLayout();
            var p2 = edge.node2.getLayout();
            var cp1;
            if (curveness > 0) {
                cp1 = [
                    (p1[0] + p2[0]) / 2 - (p1[1] - p2[1]) * curveness,
                    (p1[1] + p2[1]) / 2 - (p2[0] - p1[0]) * curveness
                ];
            }
            edge.setLayout([p1, p2, cp1]);
        });
    };
});
define('echarts/chart/graph/simpleLayout',['require','./simpleLayoutHelper'],function (require) {

    var simpleLayoutHelper = require('./simpleLayoutHelper');
    return function (ecModel, api) {
        ecModel.eachSeriesByType('graph', function (seriesModel) {
            var layout = seriesModel.get('layout');
            if (!layout || layout === 'none') {
                simpleLayoutHelper(seriesModel);
            }
        });
    };
});
define('echarts/chart/graph/circularLayoutHelper',['require'],function (require) {
    return 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 : 2) / 2;

            node.setLayout([
                r * Math.cos(angle) + cx,
                r * Math.sin(angle) + cy
            ]);

            angle += unitAngle * (sum ? value : 2) / 2;
        });

        graph.eachEdge(function (edge) {
            var curveness = edge.getModel().get('lineStyle.normal.curveness') || 0;
            var p1 = edge.node1.getLayout();
            var p2 = edge.node2.getLayout();
            var cp1;
            if (curveness > 0) {
                cp1 = [cx, cy];
            }
            edge.setLayout([p1, p2, cp1]);
        });
    };
});
define('echarts/chart/graph/circularLayout',['require','./circularLayoutHelper'],function (require) {
    var circularLayoutHelper = require('./circularLayoutHelper');
    return function (ecModel, api) {
        ecModel.eachSeriesByType('graph', function (seriesModel) {
            if (seriesModel.get('layout') === 'circular') {
                circularLayoutHelper(seriesModel);
            }
        });
    };
});
define('echarts/chart/graph/forceHelper',['require','zrender/core/vector'],function (require) {

    var vec2 = require('zrender/core/vector');
    var scaleAndAdd = vec2.scaleAndAdd;

    // function adjacentNode(n, e) {
    //     return e.n1 === n ? e.n2 : e.n1;
    // }

    return 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);
            }
        };
    };
});
define('echarts/chart/graph/forceLayout',['require','./forceHelper','../../util/number','./simpleLayoutHelper','./circularLayoutHelper','zrender/core/vector'],function (require) {

    var forceHelper = require('./forceHelper');
    var numberUtil = require('../../util/number');
    var simpleLayoutHelper = require('./simpleLayoutHelper');
    var circularLayoutHelper = require('./circularLayoutHelper');
    var vec2 = require('zrender/core/vector');

    return function (ecModel, api) {
        ecModel.eachSeriesByType('graph', function (graphSeries) {
            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 repulsion = forceModel.get('repulsion');
                var edgeLength = forceModel.get('edgeLength');
                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, [0, repulsion]) || (repulsion / 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 w = numberUtil.linearMap(value, edgeDataExtent, [0, 100]);
                    return {
                        n1: nodes[edge.node1.dataIndex],
                        n2: nodes[edge.node2.dataIndex],
                        d: edgeLength,
                        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 p1 = e.n1.p;
                            var p2 = e.n2.p;
                            var points = [p1, p2];
                            if (e.curveness > 0) {
                                points.push([
                                    (p1[0] + p2[0]) / 2 - (p1[1] - p2[1]) * e.curveness,
                                    (p1[1] + p2[1]) / 2 - (p2[0] - p1[0]) * e.curveness
                                ]);
                            }
                            graph.getEdgeByIndex(i).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;
            }
        });
    };
});
define('echarts/chart/graph/createView',['require','../../coord/View','../../util/layout','zrender/core/bbox'],function (require) {
    // FIXME Where to create the simple view coordinate system
    var View = require('../../coord/View');
    var layout = require('../../util/layout');
    var bbox = require('zrender/core/bbox');

    function getViewRect(seriesModel, api, aspect) {
        var option = seriesModel.getBoxLayoutParams();
        option.aspect = aspect;
        return layout.getLayoutRect(option, {
            width: api.getWidth(),
            height: api.getHeight()
        });
    }

    return function (ecModel, api) {
        ecModel.eachSeriesByType('graph', function (seriesModel) {
            var coordSysType = seriesModel.get('coordinateSystem');
            if (!coordSysType || coordSysType === 'view') {
                var viewCoordSys = new 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);

                var viewRect = getViewRect(
                    seriesModel, api, (max[0] - min[0]) / (max[1] - min[1]) || 1
                );
                // Position may be NaN, use view rect instead
                if (isNaN(min[0]) || isNaN(min[1])) {
                    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;

                viewCoordSys = seriesModel.coordinateSystem = new View();

                viewCoordSys.setBoundingRect(
                    min[0], min[1], bbWidth, bbHeight
                );
                viewCoordSys.setViewRect(
                    viewRect.x, viewRect.y, viewWidth, viewHeight
                );

                // Update roam info
                var roamDetailModel = seriesModel.getModel('roamDetail');
                viewCoordSys.setPan(roamDetailModel.get('x') || 0, roamDetailModel.get('y') || 0);
                viewCoordSys.setZoom(roamDetailModel.get('zoom') || 1);
            }
        });
    };
});
define('echarts/chart/graph',['require','../echarts','zrender/core/util','./graph/GraphSeries','./graph/GraphView','./graph/roamAction','./graph/categoryFilter','../visual/symbol','./graph/categoryVisual','./graph/simpleLayout','./graph/circularLayout','./graph/forceLayout','./graph/createView'],function (require) {

    var echarts = require('../echarts');
    var zrUtil = require('zrender/core/util');

    require('./graph/GraphSeries');
    require('./graph/GraphView');

    require('./graph/roamAction');

    echarts.registerProcessor('filter', require('./graph/categoryFilter'));

    echarts.registerVisualCoding('chart', zrUtil.curry(
        require('../visual/symbol'), 'graph', 'circle', null
    ));
    echarts.registerVisualCoding('chart', require('./graph/categoryVisual'));

    echarts.registerLayout(require('./graph/simpleLayout'));
    echarts.registerLayout(require('./graph/circularLayout'));
    echarts.registerLayout(require('./graph/forceLayout'));

    // Graph view coordinate system
    echarts.registerCoordinateSystem('graphView', {
        create: require('./graph/createView')
    });
});
define('echarts/chart/gauge/GaugeSeries',['require','../../data/List','../../model/Series','zrender/core/util'],function (require) {

    var List = require('../../data/List');
    var SeriesModel = require('../../model/Series');
    var zrUtil = require('zrender/core/util');

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

    return GaugeSeries;
});
define('echarts/chart/gauge/PointerPath',['require','zrender/graphic/Path'],function (require) {

    return require('zrender/graphic/Path').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;
        }
    });
});
define('echarts/chart/gauge/GaugeView',['require','./PointerPath','../../util/graphic','../../util/number','../../view/Chart'],function (require) {

    var PointerPath = require('./PointerPath');

    var graphic = require('../../util/graphic');
    var numberUtil = require('../../util/number');
    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);
            }
            else if (typeof labelFormatter === 'function') {
                label = labelFormatter(label);
            }
        }

        return label;
    }

    var PI2 = Math.PI * 2;

    var GaugeView = require('../../view/Chart').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
            );
        },

        _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++) {
                var endAngle = startAngle + angleRangeSpan * colorList[i][0];
                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 = splitLineModel.get('length');
            var tickLen = tickModel.get('length');

            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 text = new graphic.Text({
                        style: {
                            text: label,
                            x: unitX * (r - splitLineLen - 5) + cx,
                            y: unitY * (r - splitLineLen - 5) + cy,
                            fill: textStyleModel.getTextColor(),
                            textFont: textStyleModel.getFont(),
                            textBaseline: 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 linearMap = numberUtil.linearMap;
            var valueExtent = [+seriesModel.get('min'), +seriesModel.get('max')];
            var angleExtent = [startAngle, endAngle];

            if (!clockwise) {
                angleExtent = angleExtent.reverse();
            }

            var data = seriesModel.getData();
            var oldData = this._data;

            var group = this.group;

            data.diff(oldData)
                .add(function (idx) {
                    var pointer = new PointerPath({
                        shape: {
                            angle: startAngle
                        }
                    });

                    graphic.updateProps(pointer, {
                        shape: {
                            angle: linearMap(data.get('value', idx), valueExtent, angleExtent)
                        }
                    }, seriesModel);

                    group.add(pointer);
                    data.setItemGraphicEl(idx, pointer);
                })
                .update(function (newIdx, oldIdx) {
                    var pointer = oldData.getItemGraphicEl(oldIdx);

                    graphic.updateProps(pointer, {
                        shape: {
                            angle: linearMap(data.get('value', newIdx), valueExtent, angleExtent)
                        }
                    }, 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.attr({
                    shape: {
                        x: posInfo.cx,
                        y: posInfo.cy,
                        width: pointerModel.get('width'),
                        r: parsePercent(pointerModel.get('length'), posInfo.r)
                    },
                    style: itemModel.getModel('itemStyle.normal').getItemStyle()
                });

                if (pointer.style.fill === 'auto') {
                    pointer.setStyle('fill', getColor(
                        (data.get('value', idx) - valueExtent[0]) / (valueExtent[1] - valueExtent[0])
                    ));
                }

                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',
                        textBaseline: 'middle'
                    }
                });
                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((value - minVal) / (maxVal - minVal)));
                }
                rect.setStyle(detailModel.getItemStyle(['color']));
                this.group.add(rect);
            }
        }
    });

    return GaugeView;
});
define('echarts/chart/gauge',['require','./gauge/GaugeSeries','./gauge/GaugeView'],function (require) {
    require('./gauge/GaugeSeries');
    require('./gauge/GaugeView');
});
define('echarts/chart/funnel/FunnelSeries',['require','../../data/List','../../util/model','../../data/helper/completeDimensions','../../echarts'],function(require) {



    var List = require('../../data/List');
    var modelUtil = require('../../util/model');
    var completeDimensions = require('../../data/helper/completeDimensions');

    require('../../echarts').extendSeriesModel({

        type: 'series.funnel',

        init: function (option) {
            this.$superApply('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._dataBeforeProcessed;
            };
            // 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;
        },

        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: 各异,
                }
            }
        }
    });
});
define('echarts/chart/funnel/FunnelView',['require','../../util/graphic','zrender/core/util','../../view/Chart'],function (require) {

    var graphic = require('../../util/graphic');
    var zrUtil = require('zrender/core/util');

    /**
     * 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: 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;
        if (firstCreate) {
            polygon.setShape({
                points: layout.points
            });
            polygon.setStyle({ opacity : 0 });
            graphic.updateProps(polygon, {
                style: {
                    opacity: opacity
                }
            }, seriesModel);
        }
        else {
            graphic.initProps(polygon, {
                shape: {
                    points: layout.points
                }
            }, seriesModel);
        }

        // Update common style
        var itemStyleModel = itemModel.getModel('itemStyle');
        var visualColor = data.getItemVisual(idx, 'color');

        polygon.setStyle(
            zrUtil.defaults(
                {
                    fill: visualColor
                },
                itemStyleModel.getModel('normal').getItemStyle()
            )
        );
        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);

        graphic.updateProps(labelText, {
            style: {
                x: labelLayout.x,
                y: labelLayout.y
            }
        }, seriesModel);
        labelText.attr({
            style: {
                textAlign: labelLayout.textAlign,
                textBaseline: labelLayout.textBaseline,
                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 = require('../../view/Chart').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;
        }
    });

    return Funnel;
});
define('echarts/chart/funnel/funnelLayout',['require','../../util/layout','../../util/number'],function (require) {

    var layout = require('../../util/layout');
    var number = require('../../util/number');

    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;
        }
        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,
                textBaseline: 'middle',
                textAlign: textAlign,
                inside: isLabelInside
            };
        });
    }

    return function (ecModel, api) {
        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);
        });
    };
});
define('echarts/chart/funnel',['require','zrender/core/util','../echarts','./funnel/FunnelSeries','./funnel/FunnelView','../visual/dataColor','./funnel/funnelLayout','../processor/dataFilter'],function (require) {

    var zrUtil = require('zrender/core/util');
    var echarts = require('../echarts');

    require('./funnel/FunnelSeries');
    require('./funnel/FunnelView');

    echarts.registerVisualCoding(
        'chart',  zrUtil.curry(require('../visual/dataColor'), 'funnel')
    );
    echarts.registerLayout(require('./funnel/funnelLayout'));

    echarts.registerProcessor(
        'filter', zrUtil.curry(require('../processor/dataFilter'), 'funnel')
    );
});
define('echarts/coord/parallel/ParallelAxis',['require','zrender/core/util','../Axis'],function (require) {

    var zrUtil = require('zrender/core/util');
    var Axis = require('../Axis');

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

    return ParallelAxis;
});
/**
 * Parallel Coordinates
 * <https://en.wikipedia.org/wiki/Parallel_coordinates>
 */
define('echarts/coord/parallel/Parallel',['require','../../util/layout','../../coord/axisHelper','zrender/core/util','./ParallelAxis','zrender/core/matrix','zrender/core/vector'],function(require) {

    var layout = require('../../util/layout');
    var axisHelper = require('../../coord/axisHelper');
    var zrUtil = require('zrender/core/util');
    var ParallelAxis = require('./ParallelAxis');
    var matrix = require('zrender/core/matrix');
    var vector = require('zrender/core/vector');

    var each = zrUtil.each;

    var PI = Math.PI;

    function Parallel(parallelModel, ecModel, api) {

        /**
         * key: dimension
         * @type {Object.<string, module:echarts/coord/parallel/Axis>}
         * @private
         */
        this._axesMap = {};

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

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

                // Inject axis into axisModel
                axisModel.axis = axis;

                // Inject axisModel into axis
                axis.model = axisModel;

            }, this);

            this._updateAxesFromSeries(parallelModel, ecModel);
        },

        /**
         * 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) {
                    this._axesMap[dim].scale.unionExtent(data.getDataExtent(dim));
                }, 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 = layout.getLayoutRect(
                parallelModel.getBoxLayoutParams(),
                {
                    width: api.getWidth(),
                    height: api.getHeight()
                }
            );

            this._layoutAxes(parallelModel);
        },

        /**
         * @return {module:zrender/core/BoundingRect}
         */
        getRect: function () {
            return this._rect;
        },

        /**
         * @private
         */
        _layoutAxes: function (parallelModel) {
            var rect = this._rect;
            var layout = parallelModel.get('layout');
            var axes = this._axesMap;
            var dimensions = this.dimensions;

            var size = [rect.width, rect.height];
            var sizeIdx = layout === 'horizontal' ? 0 : 1;
            var layoutLength = size[sizeIdx];
            var axisLength = size[1 - sizeIdx];
            var axisExtent = [0, axisLength];

            each(axes, function (axis) {
                var idx = axis.inverse ? 1 : 0;
                axis.setExtent(axisExtent[idx], axisExtent[1 - idx]);
                axisHelper.niceScaleExtent(axis, axis.model);
            });

            each(dimensions, function (dim, idx) {
                var pos = layoutLength * idx / (dimensions.length - 1);

                var positionTable = {
                    horizontal: {
                        x: pos,
                        y: axisLength
                    },
                    vertical: {
                        x: 0,
                        y: pos
                    }
                };
                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,
                    tickDirection: 1,
                    labelDirection: 1
                };
            }, this);
        },

        /**
         * Get axis by dim.
         * @param {string} dim
         * @return {module:echarts/coord/parallel/ParallelAxis} [description]
         */
        getAxis: function (dim) {
            return this._axesMap[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[dim].dataToCoord(value),
                dim
            );
        },

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

            for (var j = 0, lenj = dimensions.length; j < lenj; j++) {
                if (axesMap[dimensions[j]].model.getActiveState() !== 'normal') {
                    hasActiveSet = true;
                }
            }

            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[dimName].model.getActiveState(values[j], j);

                        if (state === 'inactive') {
                            activeState = 'inactive';
                            break;
                        }
                    }
                }

                callback.call(context, activeState, i);
            }
        },

        /**
         * 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];
            var point = [coord, 0];
            vector.applyTransform(point, point, axisLayout.transform);
            return point;
        },

        /**
         * Get axis layout.
         */
        getAxisLayout: function (dim) {
            return zrUtil.clone(this._axesLayout[dim]);
        }

    };

    return Parallel;
});
/**
 * Parallel coordinate system creater.
 */
define('echarts/coord/parallel/parallelCreator',['require','./Parallel','../../CoordinateSystem'],function(require) {

    var Parallel = require('./Parallel');

    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 parallelIndex = seriesModel.get('parallelIndex');
                seriesModel.coordinateSystem = coordSysList[parallelIndex];
            }
        });

        return coordSysList;
    }

    require('../../CoordinateSystem').register('parallel', {create: create});

});
define('echarts/coord/parallel/AxisModel',['require','../../model/Component','zrender/core/util','../../model/mixin/makeStyleMapper','../axisModelCreator','../../util/number','../axisModelCommonMixin'],function(require) {

    var ComponentModel = require('../../model/Component');
    var zrUtil = require('zrender/core/util');
    var makeStyleMapper = require('../../model/mixin/makeStyleMapper');
    var axisModelCreator = require('../axisModelCreator');
    var numberUtil = require('../../util/number');

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

        z: 10
    };

    zrUtil.merge(AxisModel.prototype, require('../axisModelCommonMixin'));

    function getAxisType(axisName, option) {
        return option.type || (option.data ? 'category' : 'value');
    }

    axisModelCreator('parallel', AxisModel, getAxisType, defaultOption);

    return AxisModel;
});
define('echarts/coord/parallel/ParallelModel',['require','zrender/core/util','../../model/Component','./AxisModel'],function(require) {

    var zrUtil = require('zrender/core/util');
    var Component = require('../../model/Component');

    require('./AxisModel');

    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,

        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'

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

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

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

    });

});
define('echarts/component/axis/parallelAxisAction',['require','../../echarts'],function (require) {

    var echarts = require('../../echarts');

    var actionInfo = {
        type: 'axisAreaSelect',
        event: 'axisAreaSelected',
        update: 'updateVisual'
    };

    /**
     * @payload
     * @property {string} parallelAxisId
     * @property {Array.<Array.<number>>} intervals
     */
    echarts.registerAction(actionInfo, function (payload, ecModel) {
        ecModel.eachComponent(
            {mainType: 'parallelAxis', query: payload},
            function (parallelAxisModel) {
                parallelAxisModel.axis.model.setActiveIntervals(payload.intervals);
            }
        );

    });
});
/**
 * Box selection tool.
 *
 * @module echarts/component/helper/SelectController
 */

define('echarts/component/helper/SelectController',['require','zrender/mixin/Eventful','zrender/core/util','../../util/graphic'],function (require) {

    var Eventful = require('zrender/mixin/Eventful');
    var zrUtil = require('zrender/core/util');
    var graphic = require('../../util/graphic');
    var bind = zrUtil.bind;
    var each = zrUtil.each;
    var mathMin = Math.min;
    var mathMax = Math.max;
    var mathPow = Math.pow;

    var UNSELECT_THRESHOLD = 2;
    var EVENTS = ['mousedown', 'mousemove', 'mouseup'];

    /**
     * @alias module:echarts/component/helper/SelectController
     * @constructor
     * @mixin {module:zrender/mixin/Eventful}
     *
     * @param {string} type 'line', 'rect'
     * @param {module:zrender/zrender~ZRender} zr
     * @param {Object} [opt]
     * @param {number} [opt.width]
     * @param {number} [opt.lineWidth]
     * @param {string} [opt.stroke]
     * @param {string} [opt.fill]
     */
    function SelectController(type, zr, opt) {

        Eventful.call(this);

        /**
         * @type {string}
         * @readOnly
         */
        this.type = type;

        /**
         * @type {module:zrender/zrender~ZRender}
         */
        this.zr = zr;

        /**
         * @type {Object}
         * @readOnly
         */
        this.opt = zrUtil.clone(opt);

        /**
         * @type {module:zrender/container/Group}
         * @readOnly
         */
        this.group = new graphic.Group();

        /**
         * @type {module:zrender/core/BoundingRect}
         */
        this._containerRect = null;

        /**
         * @type {Array.<nubmer>}
         * @private
         */
        this._track = [];

        /**
         * @type {boolean}
         */
        this._dragging;

        /**
         * @type {module:zrender/Element}
         * @private
         */
        this._cover;

        /**
         * @type {boolean}
         * @private
         */
        this._disabled = true;

        /**
         * @type {Object}
         * @private
         */
        this._handlers = {
            mousedown: bind(mousedown, this),
            mousemove: bind(mousemove, this),
            mouseup: bind(mouseup, this)
        };

        each(EVENTS, function (eventName) {
            this.zr.on(eventName, this._handlers[eventName]);
        }, this);
    }

    SelectController.prototype = {

        constructor: SelectController,

        /**
         * @param {module:zrender/mixin/Transformable} container
         * @param {module:zrender/core/BoundingRect|boolean} [rect] If not specified,
         *                                                  use container.getBoundingRect().
         *                                                  If false, do not use containerRect.
         */
        enable: function (container, rect) {

            this._disabled = false;

            // Remove from old container.
            removeGroup.call(this);

            // boundingRect will change when dragging, so we have
            // to keep initial boundingRect.
            this._containerRect = rect !== false
            ? (rect || container.getBoundingRect()) : null;

            // Add to new container.
            container.add(this.group);
        },

        /**
         * Update cover location.
         * @param {Array.<number>|Object} ranges If null/undefined, remove cover.
         */
        update: function (ranges) {
            // TODO
            // Only support one interval yet.
            renderCover.call(this, ranges && zrUtil.clone(ranges));
        },

        disable: function () {
            this._disabled = true;

            removeGroup.call(this);
        },

        dispose: function () {
            this.disable();

            each(EVENTS, function (eventName) {
                this.zr.off(eventName, this._handlers[eventName]);
            }, this);
        }
    };


    zrUtil.mixin(SelectController, Eventful);


    function isInContainer(x, y) {
        var localPos = this.group.transformCoordToLocal(x, y);
        return !this._containerRect
            || this._containerRect.contain(localPos[0], localPos[1]);
    }

    function preventDefault(e) {
        var rawE = e.event;
        rawE.preventDefault && rawE.preventDefault();
    }

    function mousedown(e) {
        if (this._disabled || (e.target && e.target.draggable)) {
            return;
        }

        preventDefault(e);

        var x = e.offsetX;
        var y = e.offsetY;

        if (isInContainer.call(this, x, y)) {
            this._dragging = true;
            this._track = [[x, y]];
        }
    }

    function mousemove(e) {
        if (!this._dragging || this._disabled) {
            return;
        }

        preventDefault(e);

        updateViewByCursor.call(this, e);
    }

    function mouseup(e) {
        if (!this._dragging || this._disabled) {
            return;
        }

        preventDefault(e);

        updateViewByCursor.call(this, e, true);

        this._dragging = false;
        this._track = [];
    }

    function updateViewByCursor(e, isEnd) {
        var x = e.offsetX;
        var y = e.offsetY;

        if (isInContainer.call(this, x, y)) {
            this._track.push([x, y]);

            // Create or update cover.
            var ranges = shouldShowCover.call(this)
                ? coverRenderers[this.type].getRanges.call(this)
                // Remove cover.
                : [];

            renderCover.call(this, ranges);

            this.trigger('selected', zrUtil.clone(ranges));

            if (isEnd) {
                this.trigger('selectEnd', zrUtil.clone(ranges));
            }
        }
    }

    function shouldShowCover() {
        var track = this._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 renderCover(ranges) {
        var coverRenderer = coverRenderers[this.type];

        if (ranges && ranges.length) {
            if (!this._cover) {
                this._cover = coverRenderer.create.call(this);
                this.group.add(this._cover);
            }
            coverRenderer.update.call(this, ranges);
        }
        else {
            this.group.remove(this._cover);
            this._cover = null;
        }
    }

    function removeGroup() {
        // container may 'removeAll' outside.
        var group = this.group;
        var container = group.parent;
        if (container) {
            container.remove(group);
        }
    }

    function createRectCover() {
        var opt = this.opt;
        return new graphic.Rect({
            // FIXME
            // customize style.
            style: {
                stroke: opt.stroke,
                fill: opt.fill,
                lineWidth: opt.lineWidth,
                opacity: opt.opacity
            }
        });
    }

    function getLocalTrack() {
        return zrUtil.map(this._track, function (point) {
            return this.group.transformCoordToLocal(point[0], point[1]);
        }, this);
    }

    function getLocalTrackEnds() {
        var localTrack = getLocalTrack.call(this);
        var tail = localTrack.length - 1;
        tail < 0 && (tail = 0);
        return [localTrack[0], localTrack[tail]];
    }

    /**
     * key: this.type
     * @type {Object}
     */
    var coverRenderers = {

        line: {

            create: createRectCover,

            getRanges: function () {
                var ends = getLocalTrackEnds.call(this);
                var min = mathMin(ends[0][0], ends[1][0]);
                var max = mathMax(ends[0][0], ends[1][0]);

                return [[min, max]];
            },

            update: function (ranges) {
                var range = ranges[0];
                var width = this.opt.width;
                this._cover.setShape({
                    x: range[0],
                    y: -width / 2,
                    width: range[1] - range[0],
                    height: width
                });
            }
        },

        rect: {

            create: createRectCover,

            getRanges: function () {
                var ends = getLocalTrackEnds.call(this);

                var min = [
                    mathMin(ends[1][0], ends[0][0]),
                    mathMin(ends[1][1], ends[0][1])
                ];
                var max = [
                    mathMax(ends[1][0], ends[0][0]),
                    mathMax(ends[1][1], ends[0][1])
                ];

                return [[
                    [min[0], max[0]], // x range
                    [min[1], max[1]] // y range
                ]];
            },

            update: function (ranges) {
                var range = ranges[0];
                this._cover.setShape({
                    x: range[0][0],
                    y: range[1][0],
                    width: range[0][1] - range[0][0],
                    height: range[1][1] - range[1][0]
                });
            }
        }
    };

    return SelectController;
});
define('echarts/component/axis/ParallelAxisView',['require','zrender/core/util','./AxisBuilder','../helper/SelectController','../../echarts'],function (require) {

    var zrUtil = require('zrender/core/util');
    var AxisBuilder = require('./AxisBuilder');
    var SelectController = require('../helper/SelectController');

    var elementList = ['axisLine', 'axisLabel', 'axisTick', 'axisName'];

    var AxisView = require('../../echarts').extendComponentView({

        type: 'parallelAxis',

        /**
         * @type {module:echarts/component/helper/SelectController}
         */
        _selectController: null,

        /**
         * @override
         */
        render: function (axisModel, ecModel, api, payload) {
            if (fromAxisAreaSelect(axisModel, ecModel, payload)) {
                return;
            }

            this.axisModel = axisModel;
            this.api = api;

            this.group.removeAll();

            if (!axisModel.get('show')) {
                return;
            }

            var coordSys = ecModel.getComponent(
                'parallel', axisModel.get('parallelIndex')
            ).coordinateSystem;

            var areaSelectStyle = axisModel.getAreaSelectStyle();
            var areaWidth = areaSelectStyle.width;

            var axisLayout = coordSys.getAxisLayout(axisModel.axis.dim);
            var builderOpt = zrUtil.extend(
                {
                    strokeContainThreshold: areaWidth,
                    // lineWidth === 0 or no value.
                    silent: !(areaWidth > 0) // jshint ignore:line
                },
                axisLayout
            );

            var axisBuilder = new AxisBuilder(axisModel, builderOpt);

            zrUtil.each(elementList, axisBuilder.add, axisBuilder);

            var axisGroup = axisBuilder.getGroup();

            this.group.add(axisGroup);

            this._buildSelectController(
                axisGroup, areaSelectStyle, axisModel, api
            );
        },

        _buildSelectController: function (axisGroup, areaSelectStyle, axisModel, api) {

            var axis = axisModel.axis;
            var selectController = this._selectController;

            if (!selectController) {
                selectController = this._selectController = new SelectController(
                    'line',
                    api.getZr(),
                    areaSelectStyle
                );

                selectController.on('selected', zrUtil.bind(this._onSelected, this));
            }

            selectController.enable(axisGroup);

            // After filtering, axis may change, select area needs to be update.
            var ranges = zrUtil.map(axisModel.activeIntervals, function (interval) {
                return [
                    axis.dataToCoord(interval[0], true),
                    axis.dataToCoord(interval[1], true)
                ];
            });
            selectController.update(ranges);
        },

        _onSelected: function (ranges) {
            // Do not cache these object, because the mey be changed.
            var axisModel = this.axisModel;
            var axis = axisModel.axis;

            var intervals = zrUtil.map(ranges, function (range) {
                return [
                    axis.coordToData(range[0], true),
                    axis.coordToData(range[1], true)
                ];
            });
            this.api.dispatchAction({
                type: 'axisAreaSelect',
                parallelAxisId: axisModel.id,
                intervals: intervals
            });
        },

        /**
         * @override
         */
        remove: function () {
            this._selectController && this._selectController.disable();
        },

        /**
         * @override
         */
        dispose: function () {
            if (this._selectController) {
                this._selectController.dispose();
                this._selectController = null;
            }
        }
    });

    function fromAxisAreaSelect(axisModel, ecModel, payload) {
        return payload
            && payload.type === 'axisAreaSelect'
            && ecModel.findComponents(
                {mainType: 'parallelAxis', query: payload}
            )[0] === axisModel;
    }

    return AxisView;
});
define('echarts/component/parallelAxis',['require','../coord/parallel/parallelCreator','./axis/parallelAxisAction','./axis/ParallelAxisView'],function(require) {

    require('../coord/parallel/parallelCreator');
    require('./axis/parallelAxisAction');
    require('./axis/ParallelAxisView');

});
define('echarts/coord/parallel/parallelPreprocessor',['require','zrender/core/util','../../util/model'],function (require) {

    var zrUtil = require('zrender/core/util');
    var modelUtil = require('../../util/model');

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

});
define('echarts/component/parallel',['require','../coord/parallel/parallelCreator','../coord/parallel/ParallelModel','./parallelAxis','../echarts','../coord/parallel/parallelPreprocessor'],function(require) {

    require('../coord/parallel/parallelCreator');
    require('../coord/parallel/ParallelModel');
    require('./parallelAxis');

    var echarts = require('../echarts');

    // Parallel view
    echarts.extendComponentView({
        type: 'parallel'
    });

    echarts.registerPreprocessor(
        require('../coord/parallel/parallelPreprocessor')
    );

});
define('echarts/chart/parallel/ParallelSeries',['require','../../data/List','zrender/core/util','../../model/Series'],function(require) {

    var List = require('../../data/List');
    var zrUtil = require('zrender/core/util');
    var SeriesModel = require('../../model/Series');

    return SeriesModel.extend({

        type: 'series.parallel',

        dependencies: ['parallel'],

        getInitialData: function (option, ecModel) {
            var parallelModel = ecModel.getComponent(
                'parallel', this.get('parallelIndex')
            );
            var dimensions = parallelModel.dimensions;
            var parallelAxisIndices = parallelModel.parallelAxisIndex;

            var rawData = option.data;

            var dimensionsInfo = zrUtil.map(dimensions, function (dim, index) {
                var axisModel = ecModel.getComponent(
                    'parallelAxis', parallelAxisIndices[index]
                );
                if (axisModel.get('type') === 'category') {
                    translateCategoryValue(axisModel, dim, rawData);
                    return {name: dim, type: 'ordinal'};
                }
                else {
                    return dim;
                }
            });

            var list = new List(dimensionsInfo, this);
            list.initData(rawData);

            return list;
        },

        defaultOption: {
            zlevel: 0,                  // 一级层叠
            z: 2,                       // 二级层叠

            coordinateSystem: 'parallel',
            parallelIndex: 0,

            // FIXME 尚无用
            label: {
                normal: {
                    show: false
                    // formatter: 标签文本格式器，同Tooltip.formatter，不支持异步回调
                    // position: 默认自适应，水平布局为'top'，垂直布局为'right'，可选为
                    //           'inside'|'left'|'right'|'top'|'bottom'
                    // textStyle: null      // 默认使用全局文本样式，详见TEXTSTYLE
                },
                emphasis: {
                    show: false
                    // formatter: 标签文本格式器，同Tooltip.formatter，不支持异步回调
                    // position: 默认自适应，水平布局为'top'，垂直布局为'right'，可选为
                    //           'inside'|'left'|'right'|'top'|'bottom'
                    // textStyle: null      // 默认使用全局文本样式，详见TEXTSTYLE
                }
            },

            inactiveOpacity: 0.05,
            activeOpacity: 1,

            lineStyle: {
                normal: {
                    width: 2,
                    opacity: 0.45,
                    type: 'solid'
                }
            },
            // smooth: false

            animationEasing: 'linear'
        }
    });

    function translateCategoryValue(axisModel, dim, rawData) {
        var axisData = axisModel.get('data');
        var numberDim = +dim.replace('dim', '');

        if (axisData && axisData.length) {
            zrUtil.each(rawData, function (dataItem) {
                if (!dataItem) {
                    return;
                }
                var index = zrUtil.indexOf(axisData, dataItem[numberDim]);
                dataItem[numberDim] = index >= 0 ? index : NaN;
            });
        }
        // FIXME
        // 如果没有设置axis data, 应自动算出，或者提示。
    }
});
define('echarts/chart/parallel/ParallelView',['require','../../util/graphic','zrender/core/util','../../view/Chart'],function (require) {

    var graphic = require('../../util/graphic');
    var zrUtil = require('zrender/core/util');

    var ParallelView = require('../../view/Chart').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) {

            var dataGroup = this._dataGroup;
            var data = seriesModel.getData();
            var oldData = this._data;
            var coordSys = seriesModel.coordinateSystem;
            var dimensions = coordSys.dimensions;

            data.diff(oldData)
                .add(add)
                .update(update)
                .remove(remove)
                .execute();

            // Update style
            data.eachItemGraphicEl(function (elGroup, idx) {
                var itemModel = data.getItemModel(idx);
                var lineStyleModel = itemModel.getModel('lineStyle.normal');
                elGroup.eachChild(function (child) {
                    child.setStyle(zrUtil.extend(
                        lineStyleModel.getLineStyle(),
                        {
                            stroke: data.getItemVisual(idx, 'color'),
                            opacity: data.getItemVisual(idx, 'opacity')
                        }
                    ));
                });
            });

            // First create
            if (!this._data) {
                dataGroup.setClipPath(createGridClipShape(
                    coordSys, seriesModel, function () {
                        dataGroup.removeClipPath();
                    }
                ));
            }

            this._data = data;

            function add(newDataIndex) {
                var values = data.getValues(dimensions, newDataIndex);
                var elGroup = new graphic.Group();
                dataGroup.add(elGroup);

                eachAxisPair(
                    values, dimensions, coordSys,
                    function (pointPair, pairIndex) {
                        // FIXME
                        // init animation
                        if (pointPair) {
                            elGroup.add(createEl(pointPair));
                        }
                    }
                );

                data.setItemGraphicEl(newDataIndex, elGroup);
            }

            function update(newDataIndex, oldDataIndex) {
                var values = data.getValues(dimensions, newDataIndex);
                var elGroup = oldData.getItemGraphicEl(oldDataIndex);
                var newEls = [];
                var elGroupIndex = 0;

                eachAxisPair(
                    values, dimensions, coordSys,
                    function (pointPair, pairIndex) {
                        var el = elGroup.childAt(elGroupIndex++);

                        if (pointPair && !el) {
                            newEls.push(createEl(pointPair));
                        }
                        else if (pointPair) {
                            graphic.updateProps(el, {
                                shape: {
                                    points: pointPair
                                }
                            }, seriesModel);
                        }
                    }
                );

                // Remove redundent els
                for (var i = elGroup.childCount() - 1; i >= elGroupIndex; i--) {
                    elGroup.remove(elGroup.childAt(i));
                }

                // Add new els
                for (var i = 0, len = newEls.length; i < len; i++) {
                    elGroup.add(newEls[i]);
                }

                data.setItemGraphicEl(newDataIndex, elGroup);
            }

            function remove(oldDataIndex) {
                var elGroup = oldData.getItemGraphicEl(oldDataIndex);
                dataGroup.remove(elGroup);
            }
        },

        /**
         * @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 eachAxisPair(values, dimensions, coordSys, cb) {
        for (var i = 0, len = dimensions.length - 1; i < len; i++) {
            var dimA = dimensions[i];
            var dimB = dimensions[i + 1];
            var valueA = values[i];
            var valueB = values[i + 1];

            cb(
                (isEmptyValue(valueA, coordSys.getAxis(dimA).type)
                    || isEmptyValue(valueB, coordSys.getAxis(dimB).type)
                )
                    ? null
                    : [
                        coordSys.dataToPoint(valueA, dimA),
                        coordSys.dataToPoint(valueB, dimB)
                    ],
                i
            );
        }
    }

    function createEl(pointPair) {
        return new graphic.Polyline({
            shape: {points: pointPair},
            silent: true
        });
    }


    // FIXME
    // 公用方法?
    function isEmptyValue(val, axisType) {
        return axisType === 'category'
            ? val == null
            : (val == null || isNaN(val)); // axisType === 'value'
    }

    return ParallelView;
});
define('echarts/chart/parallel/parallelVisual',['require'],function (require) {

    /**
     * @payload
     * @property {string} parallelAxisId
     * @property {Array.<number>} extent
     */
    return function (ecModel, payload) {

        ecModel.eachSeriesByType('parallel', function (seriesModel) {

            var itemStyleModel = seriesModel.getModel('itemStyle.normal');
            var globalColors = ecModel.get('color');

            var 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) {
                data.setItemVisual(dataIndex, 'opacity', opacityMap[activeState]);
            });

            data.setVisual('color', color);
        });
    };
});
define('echarts/chart/parallel',['require','../echarts','../component/parallel','./parallel/ParallelSeries','./parallel/ParallelView','./parallel/parallelVisual'],function (require) {

    var echarts = require('../echarts');

    require('../component/parallel');

    require('./parallel/ParallelSeries');
    require('./parallel/ParallelView');

    echarts.registerVisualCoding('chart', require('./parallel/parallelVisual'));

});
define('echarts/chart/sankey/SankeySeries',['require','../../model/Series','../helper/createGraphFromNodeEdge'],function (require) {



    var SeriesModel = require('../../model/Series');
    var createGraphFromNodeEdge = require('../helper/createGraphFromNodeEdge');

    return SeriesModel.extend({

        type: 'series.sankey',

        layoutInfo: null,

        getInitialData: function (option, ecModel) {
            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 {module:echarts/data/Graph}
         */
        getGraph: function () {
            return this.getData().graph;
        },

        /**
         * return {module:echarts/data/List}
         */
        getEdgeData: function() {
            return this.getGraph().edgeData;
        },

        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 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: {},
                emphasis: {}
            },

            lineStyle: {
                normal: {
                    color: '#314656',
                    opacity: 0.2,
                    curveness: 0.5
                },
                emphasis: {
                    opacity: 0.6
                }
            },


            // colorEncoded: 'node',

            color: ['#9e0142', '#d53e4f', '#f46d43', '#fdae61', '#fee08b','#ffffbf',
                    '#e6f598', '#abdda4', '#66c2a5', '#3288bd', '#5e4fa2'],

            animationEasing: 'linear',

            animationDuration: 1000
        }

    });

});
define('echarts/chart/sankey/SankeyView',['require','../../util/graphic','../../util/model','zrender/core/util','../../echarts'],function (require) {

    var graphic = require('../../util/graphic');
    var modelUtil = require('../../util/model');
    var zrUtil = require('zrender/core/util');

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

    return require('../../echarts').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;

            this._model = seriesModel;

            group.removeAll();

            group.position = [layoutInfo.x, layoutInfo.y];

            var edgeData = graph.edgeData;
            var rawOption = seriesModel.option;
            var formatModel = modelUtil.createDataFormatModel(
                seriesModel, edgeData, rawOption.edges || rawOption.links
            );

            formatModel.formatTooltip = function (dataIndex) {
                var params = this.getDataParams(dataIndex);
                var rawDataOpt = params.data;
                var html = rawDataOpt.source + ' -- ' + rawDataOpt.target;
                if (params.value) {
                    html += ':' + params.value;
                }
                return html;
            };

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

            // generate a bezire Curve for each edge
            graph.eachEdge(function (edge) {
                var curve = new SankeyShape();

                curve.dataIndex = edge.dataIndex;
                curve.hostModel = formatModel;

                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());
                graphic.setHoverStyle(curve, edge.getModel('lineStyle.emphasis').getItemStyle());

                group.add(curve);

            });
            if (!this._data) {
                group.setClipPath(createGridClipShape(group.getBoundingRect(), seriesModel, function () {
                    group.removeClipPath();
                }));
            }
            this._data = seriesModel.getData();
        }
    });

    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;
    }
});
define('echarts/util/array/nest',['require','zrender/core/util'],function (require) {

    var zrUtil = require('zrender/core/util');

    /**
     * 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 a
             * @param {Array} array
             */
            entries: function (array) {
                return entriesMap(map(array, 0), 0);
            }
        };
    }
    return nest;
});
define('echarts/chart/sankey/sankeyLayout',['require','../../util/layout','../../util/array/nest','zrender/core/util'],function (require) {

    var layout = require('../../util/layout');
    var nest = require('../../util/array/nest');
    var zrUtil = require('zrender/core/util');

    return function (ecModel, api) {

        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 = nodes.filter(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.
     */
    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
     */
    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
     * @param  {number} nodeWidth
     * @param  {number} width
     */
    function computeNodeBreadths(nodes, nodeWidth, width) {
        var remainNodes = nodes;
        var nextNode = null;
        var x = 0;
        var kx = 0;

        while (remainNodes.length) {
            nextNode = [];
            zrUtil.each(remainNodes, function (node) {
                node.setLayout({x: x}, true);
                node.setLayout({dx: nodeWidth}, true);
                zrUtil.each(node.outEdges, function (edge) {
                    nextNode.push(edge.node2);
                });
            });
            remainNodes = nextNode;
            ++x;
        }

        moveSinksRight(nodes, x);
        kx = (width - nodeWidth) / (x - 1);

        scaleNodeBreadths(nodes, kx);
    }

    /**
     * all the node without outEgdes are assigned maximum breadth and
     * be aligned in the last column.
     * @param {module:echarts/data/Graph~Node} nodes
     * @param {number} x
     */
    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
     * @param {number} kx
     */
    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
     * @param {module:echarts/data/Graph~Edge} edges
     * @param {number} height
     * @param {numbber} nodeGap
     * @param {number} iterations
     */
    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--) {
            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
     * @param {Array.<Array.<module:echarts/data/Graph~Node>>} nodesByBreadth
     * @param {module:echarts/data/Graph~Edge} edges
     * @param {number} height
     * @param {number} nodeGap
     */
    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.
     * @param {Array.<Array.<module:echarts/data/Graph~Node>>} nodesByBreadth
     * @param {number} nodeGap
     * @param {number} height
     */
    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 biunds, 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
     * @param {number} alpha
     */
    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
     * @param {number} alpha
     */
    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
     */
    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 s = 0;
        var n = array.length;
        var a;
        var i = -1;
        if (arguments.length === 1) {
            while (++i < n) {
                a = +array[i];
                if (!isNaN(a)) {
                    s += a;
                }
            }
        }
        else {
            while (++i < n) {
                a = +f.call(array, array[i], i);
                if(!isNaN(a)) {
                    s += a;
                }
            }
        }
        return s;
    }

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

});
define('echarts/chart/sankey/sankeyVisual',['require','../../visual/VisualMapping'],function (require) {

    var VisualMapping = require('../../visual/VisualMapping');

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

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

        }) ;
    };
});
define('echarts/chart/sankey',['require','../echarts','./sankey/SankeySeries','./sankey/SankeyView','./sankey/sankeyLayout','./sankey/sankeyVisual'],function (require) {

    var echarts = require('../echarts');

    require('./sankey/SankeySeries');
    require('./sankey/SankeyView');
    echarts.registerLayout(require('./sankey/sankeyLayout'));
    echarts.registerVisualCoding('chart', require('./sankey/sankeyVisual'));
});
/**
 * @module echarts/chart/helper/Symbol
 */
define('echarts/chart/helper/WhiskerBoxDraw',['require','zrender/core/util','../../util/graphic','zrender/graphic/Path'],function (require) {

    var zrUtil = require('zrender/core/util');
    var graphic = require('../../util/graphic');
    var Path = require('zrender/graphic/Path');

    var WhiskerPath = Path.extend({

        type: 'whiskerInBox',

        shape: {},

        buildPath: function (ctx, shape) {
            for (var i in shape) {
                if (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
        );
        updateMethod(
            this.childAt(this.whiskerIndex),
            {shape: makeWhiskerEndsShape(itemLayout.whiskerEnds)},
            seriesModel
        );

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

    return WhiskerBoxDraw;
});
define('echarts/chart/helper/whiskerBoxCommon',['require','../../data/List','../../data/helper/completeDimensions','../helper/WhiskerBoxDraw'],function(require) {



    var List = require('../../data/List');
    var completeDimensions = require('../../data/helper/completeDimensions');
    var WhiskerBoxDraw = require('../helper/WhiskerBoxDraw');

    function getItemValue(item) {
        return item.value == null ? item : item.value;
    }

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

            this._baseAxisDim = option.layout === 'horizontal' ? 'x' : 'y';

            var data = option.data;
            var dimensions = this.dimensions = ['base'].concat(this.valueDimensions);
            completeDimensions(dimensions, data);

            var list = new List(dimensions, this);
            list.initData(data, categories ? categories.slice() : null, function (dataItem, dimName, idx, dimIdx) {
                var value = getItemValue(dataItem);
                return addOrdinal ? (dimName === 'base' ? idx : value[dimIdx - 1]) : value[dimIdx];
            });

            return list;
        },

        /**
         * Used by Gird.
         * @param {string} axisDim 'x' or 'y'
         * @return {Array.<string>} dimensions on the axis.
         */
        getDimensionsOnAxis: function (axisDim) {
            var dims = this.valueDimensions.slice();
            var baseDim = ['base'];
            var map = {
                horizontal: {x: baseDim, y: dims},
                vertical: {x: dims, y: baseDim}
            };
            return map[this.get('layout')][axisDim];
        },

        /**
         * If horizontal, base axis is x, otherwise y.
         */
        getBaseAxisModel: function () {
            var dim = this._baseAxisDim;
            return this.ecModel.getComponent(dim + 'Axis', this.get(dim + 'AxisIndex'));
        }
    };

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

    function queryDataIndex(data, payload) {
        if (payload.dataIndex != null) {
            return payload.dataIndex;
        }
        else if (payload.name != null) {
            return data.indexOfName(payload.name);
        }
    }

    return {
        seriesModelMixin: seriesModelMixin,
        viewMixin: viewMixin
    };
});
define('echarts/chart/boxplot/BoxplotSeries',['require','zrender/core/util','../../model/Series','../helper/whiskerBoxCommon'],function(require) {



    var zrUtil = require('zrender/core/util');
    var SeriesModel = require('../../model/Series');
    var whiskerBoxCommon = require('../helper/whiskerBoxCommon');

    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
         */
        valueDimensions: ['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);

    return BoxplotSeries;

});
define('echarts/chart/boxplot/BoxplotView',['require','zrender/core/util','../../view/Chart','../../util/graphic','../helper/whiskerBoxCommon'],function(require) {



    var zrUtil = require('zrender/core/util');
    var ChartView = require('../../view/Chart');
    var graphic = require('../../util/graphic');
    var whiskerBoxCommon = require('../helper/whiskerBoxCommon');

    var BoxplotView = ChartView.extend({

        type: 'boxplot',

        getStyleUpdater: function () {
            return updateStyle;
        }
    });

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

    return BoxplotView;

});
define('echarts/chart/boxplot/boxplotVisual',['require'],function (require) {

    var borderColorQuery = ['itemStyle', 'normal', 'borderColor'];

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

    };
});
define('echarts/chart/boxplot/boxplotLayout',['require','zrender/core/util','../../util/number'],function (require) {

    var zrUtil = require('zrender/core/util');
    var numberUtil = require('../../util/number');
    var parsePercent = numberUtil.parsePercent;
    var each = zrUtil.each;

    return function (ecModel, api) {

        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.getBaseAxisModel().axis;
            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 dimensions = seriesModel.dimensions;
        var chartLayout = seriesModel.get('layout');
        var halfWidth = boxWidth / 2;

        data.each(dimensions, function () {
            var args = arguments;
            var dimLen = dimensions.length;
            var axisDimVal = args[0];
            var idx = args[dimLen];
            var variableDim = chartLayout === 'horizontal' ? 0 : 1;
            var constDim = 1 - variableDim;

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

});
define('echarts/chart/boxplot',['require','../echarts','./boxplot/BoxplotSeries','./boxplot/BoxplotView','./boxplot/boxplotVisual','./boxplot/boxplotLayout'],function (require) {

    var echarts = require('../echarts');

    require('./boxplot/BoxplotSeries');
    require('./boxplot/BoxplotView');

    echarts.registerVisualCoding('chart', require('./boxplot/boxplotVisual'));
    echarts.registerLayout(require('./boxplot/boxplotLayout'));

});
define('echarts/chart/candlestick/CandlestickSeries',['require','zrender/core/util','../../model/Series','../helper/whiskerBoxCommon','../../util/format'],function(require) {



    var zrUtil = require('zrender/core/util');
    var SeriesModel = require('../../model/Series');
    var whiskerBoxCommon = require('../helper/whiskerBoxCommon');
    var formatUtil = require('../../util/format');
    var encodeHTML = formatUtil.encodeHTML;
    var addCommas = formatUtil.addCommas;

    var CandlestickSeries = SeriesModel.extend({

        type: 'series.candlestick',

        dependencies: ['xAxis', 'yAxis', 'grid'],

        /**
         * @readOnly
         */
        valueDimensions: ['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
                }
            },

            animationUpdate: false,
            animationEasing: 'linear',
            animationDuration: 300
        },

        /**
         * Get dimension for shadow in dataZoom
         * @return {string} dimension name
         */
        getShadowDim: function () {
            return 'open';
        },

        /**
         * @override
         */
        formatTooltip: function (dataIndex, mutipleSeries) {
            // It rearly use mutiple candlestick series in one cartesian,
            // so only consider one series in this default tooltip.
            var valueHTMLArr = zrUtil.map(this.valueDimensions, function (dim) {
                return dim + ': ' + addCommas(this._data.get(dim, dataIndex));
            }, this);

            return encodeHTML(this.name) + '<br />' + valueHTMLArr.join('<br />');
        }

    });

    zrUtil.mixin(CandlestickSeries, whiskerBoxCommon.seriesModelMixin, true);

    return CandlestickSeries;

});
define('echarts/chart/candlestick/CandlestickView',['require','zrender/core/util','../../view/Chart','../../util/graphic','../helper/whiskerBoxCommon'],function(require) {



    var zrUtil = require('zrender/core/util');
    var ChartView = require('../../view/Chart');
    var graphic = require('../../util/graphic');
    var whiskerBoxCommon = require('../helper/whiskerBoxCommon');

    var CandlestickView = ChartView.extend({

        type: 'candlestick',

        getStyleUpdater: function () {
            return updateStyle;
        }

    });

    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 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.style.set(itemStyle);
        whiskerEl.style.stroke = borderColor;
        whiskerEl.dirty();

        var bodyEl = itemGroup.childAt(itemGroup.bodyIndex);
        bodyEl.style.set(itemStyle);
        bodyEl.style.fill = color;
        bodyEl.style.stroke = borderColor;
        bodyEl.dirty();

        var hoverStyle = itemModel.getModel(emphasisStyleAccessPath).getItemStyle();
        graphic.setHoverStyle(itemGroup, hoverStyle);
    }


    return CandlestickView;

});
define('echarts/chart/candlestick/preprocessor',['require','zrender/core/util'],function (require) {

    var zrUtil = require('zrender/core/util');

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

});
define('echarts/chart/candlestick/candlestickVisual',['require'],function (require) {

    var positiveBorderColorQuery = ['itemStyle', 'normal', 'borderColor'];
    var negativeBorderColorQuery = ['itemStyle', 'normal', 'borderColor0'];
    var positiveColorQuery = ['itemStyle', 'normal', 'color'];
    var negativeColorQuery = ['itemStyle', 'normal', 'color0'];

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

    };
});
define('echarts/chart/candlestick/candlestickLayout',['require'],function (require) {

    var CANDLE_MIN_WIDTH = 2;
    var CANDLE_MIN_NICE_WIDTH = 5;
    var GPA_MIN = 4;

    return function (ecModel, api) {

        ecModel.eachSeriesByType('candlestick', function (seriesModel) {

            var coordSys = seriesModel.coordinateSystem;
            var data = seriesModel.getData();
            var dimensions = seriesModel.dimensions;
            var chartLayout = seriesModel.get('layout');

            var candleWidth = calculateCandleWidth(seriesModel, data);

            data.each(dimensions, function () {
                var args = arguments;
                var dimLen = dimensions.length;
                var axisDimVal = args[0];
                var idx = args[dimLen];
                var variableDim = chartLayout === 'horizontal' ? 0 : 1;
                var constDim = 1 - variableDim;

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

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

            }, true);
        });
    };

    function calculateCandleWidth(seriesModel, data) {
        var baseAxis = seriesModel.getBaseAxisModel().axis;
        var extent;

        var bandWidth = baseAxis.type === 'category'
            ? baseAxis.getBandWidth()
            : (
                extent = baseAxis.getExtent(),
                Math.abs(extent[1] - extent[0]) / data.count()
            );

        // Half band width is perfect when space is enouph, otherwise
        // try not to be smaller than CANDLE_MIN_NICE_WIDTH (and only
        // gap is compressed), otherwise ensure not to be smaller than
        // CANDLE_MIN_WIDTH in spite of overlap.

        return bandWidth / 2 - 2 > CANDLE_MIN_NICE_WIDTH // "- 2" is minus border width
            ? bandWidth / 2 - 2
            : bandWidth - CANDLE_MIN_NICE_WIDTH > GPA_MIN
            ? CANDLE_MIN_NICE_WIDTH
            : Math.max(bandWidth - GPA_MIN, CANDLE_MIN_WIDTH);
    }

});
define('echarts/chart/candlestick',['require','../echarts','./candlestick/CandlestickSeries','./candlestick/CandlestickView','./candlestick/preprocessor','./candlestick/candlestickVisual','./candlestick/candlestickLayout'],function (require) {

    var echarts = require('../echarts');

    require('./candlestick/CandlestickSeries');
    require('./candlestick/CandlestickView');

    echarts.registerPreprocessor(
        require('./candlestick/preprocessor')
    );

    echarts.registerVisualCoding('chart', require('./candlestick/candlestickVisual'));
    echarts.registerLayout(require('./candlestick/candlestickLayout'));

});
define('echarts/chart/effectScatter/EffectScatterSeries',['require','../helper/createListFromArray','../../model/Series'],function (require) {



    var createListFromArray = require('../helper/createListFromArray');
    var SeriesModel = require('../../model/Series');

    return SeriesModel.extend({

        type: 'series.effectScatter',

        dependencies: ['grid', 'polar'],

        getInitialData: function (option, ecModel) {
            var list = createListFromArray(option.data, this, ecModel);
            return list;
        },

        defaultOption: {
            coordinateSystem: 'cartesian2d',
            zlevel: 0,
            z: 2,
            legendHoverLink: true,

            effectType: 'ripple',

            // 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
            //     }
            // }
        }
    });
});
/**
 * Symbol with ripple effect
 * @module echarts/chart/helper/EffectSymbol
 */
define('echarts/chart/helper/EffectSymbol',['require','zrender/core/util','../../util/symbol','../../util/graphic','../../util/number','./Symbol'],function (require) {

    var zrUtil = require('zrender/core/util');
    var symbolUtil = require('../../util/symbol');
    var graphic = require('../../util/graphic');
    var numberUtil = require('../../util/number');
    var Symbol = require('./Symbol');
    var Group = graphic.Group;

    var EFFECT_RIPPLE_NUMBER = 3;

    function normalizeSymbolSize(symbolSize) {
        if (!zrUtil.isArray(symbolSize)) {
            symbolSize = [+symbolSize, +symbolSize];
        }
        return symbolSize;
    }
    /**
     * @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 (
        period, brushType, rippleScale, effectOffset, z, zlevel
    ) {
        var symbolType = this._symbolType;
        var color = this._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
            );
            ripplePath.attr({
                style: {
                    stroke: brushType === 'stroke' ? color : null,
                    fill: brushType === 'fill' ? color : null,
                    strokeNoScale: true
                },
                z2: 99,
                silent: true,
                scale: [1, 1],
                z: z,
                zlevel: zlevel
            });

            var delay = -i / EFFECT_RIPPLE_NUMBER * period + effectOffset;
            // TODO Configurable period
            ripplePath.animate('', true)
                .when(period, {
                    scale: [rippleScale, rippleScale]
                })
                .delay(delay)
                .start();
            ripplePath.animateStyle(true)
                .when(period, {
                    opacity: 0
                })
                .delay(delay)
                .start();

            rippleGroup.add(ripplePath);
        }
    };

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

        this._symbolType = symbolType;
        this._color = color;

        var showEffectOn = seriesModel.get('showEffectOn');
        var rippleScale = itemModel.get('rippleEffect.scale');
        var brushType = itemModel.get('rippleEffect.brushType');
        var effectPeriod = itemModel.get('rippleEffect.period') * 1000;
        var effectOffset = idx / data.count();
        var z = itemModel.getShallow('z') || 0;
        var zlevel = itemModel.getShallow('zlevel') || 0;

        this.stopEffectAnimation();
        if (showEffectOn === 'render') {
            this.startEffectAnimation(
                effectPeriod, brushType, rippleScale, effectOffset, z, zlevel
            );
        }
        var symbol = this.childAt(0);
        function onEmphasis() {
            symbol.trigger('emphasis');
            if (showEffectOn !== 'render') {
                this.startEffectAnimation(
                    effectPeriod, brushType, rippleScale, effectOffset, z, zlevel
                );
            }
        }
        function onNormal() {
            symbol.trigger('normal');
            if (showEffectOn !== 'render') {
                this.stopEffectAnimation();
            }
        }
        this.on('mouseover', onEmphasis, this)
            .on('mouseout', onNormal, this)
            .on('emphasis', onEmphasis, this)
            .on('normal', onNormal, this);
    };

    effectSymbolProto.fadeOut = function (cb) {
        cb && cb();
    };

    zrUtil.inherits(EffectSymbol, Group);

    return EffectSymbol;
});
define('echarts/chart/effectScatter/EffectScatterView',['require','../helper/SymbolDraw','../helper/EffectSymbol','../../echarts'],function (require) {

    var SymbolDraw = require('../helper/SymbolDraw');
    var EffectSymbol = require('../helper/EffectSymbol');

    require('../../echarts').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);
        }
    });
});
define('echarts/chart/effectScatter',['require','zrender/core/util','../echarts','./effectScatter/EffectScatterSeries','./effectScatter/EffectScatterView','../visual/symbol','../layout/points'],function (require) {

    var zrUtil = require('zrender/core/util');
    var echarts = require('../echarts');

    require('./effectScatter/EffectScatterSeries');
    require('./effectScatter/EffectScatterView');

    echarts.registerVisualCoding('chart', zrUtil.curry(
        require('../visual/symbol'), 'effectScatter', 'circle', null
    ));
    echarts.registerLayout(zrUtil.curry(
        require('../layout/points'), 'effectScatter'
    ));
});
define('echarts/chart/lines/LinesSeries',['require','../../model/Series','../../data/List','zrender/core/util'],function (require) {



    var SeriesModel = require('../../model/Series');
    var List = require('../../data/List');
    var zrUtil = require('zrender/core/util');

    return SeriesModel.extend({

        type: 'series.lines',

        dependencies: ['grid', 'polar'],

        getInitialData: function (option, ecModel) {
            var fromDataArr = [];
            var toDataArr = [];
            var lineDataArr = [];
            zrUtil.each(option.data, function (opt) {
                fromDataArr.push(opt[0]);
                toDataArr.push(opt[1]);
                lineDataArr.push(zrUtil.extend(
                    zrUtil.extend({}, zrUtil.isArray(opt[0]) ? null : opt[0]),
                    zrUtil.isArray(opt[1]) ? null : opt[1]
                ));
            });

            var coordSys = option.coordinateSystem;
            if (coordSys !== 'cartesian2d' && coordSys !== 'geo') {
                throw new Error('Coordinate system can only be cartesian2d or geo in lines');
            }

            var dimensions = coordSys === 'geo' ? ['lng', 'lat'] : ['x', 'y'];

            var fromData = new List(dimensions, this);
            var toData = new List(dimensions, this);
            var lineData = new List(['value'], this);

            function geoCoordGetter(item, dim, dataIndex, dimIndex) {
                return item.coord && item.coord[dimIndex];
            }

            fromData.initData(fromDataArr, null, geoCoordGetter);
            toData.initData(toDataArr, null, geoCoordGetter);
            lineData.initData(lineDataArr);

            this.fromData = fromData;
            this.toData = toData;

            return lineData;
        },

        formatTooltip: function (dataIndex) {
            var fromName = this.fromData.getName(dataIndex);
            var toName = this.toData.getName(dataIndex);
            return fromName + ' > ' + toName;
        },

        defaultOption: {
            coordinateSystem: 'geo',
            zlevel: 0,
            z: 2,
            legendHoverLink: true,

            hoverAnimation: true,
            // Cartesian coordinate system
            xAxisIndex: 0,
            yAxisIndex: 0,

            // Geo coordinate system
            geoIndex: 0,

            // symbol: null,
            // symbolSize: 10,
            // symbolRotate: null,

            effect: {
                show: false,
                period: 4,
                symbol: 'circle',
                symbolSize: 3,
                // Length of trail, 0 - 1
                trailLength: 0.2
                // Same with lineStyle.normal.color
                // color
            },

            large: false,
            // Available when large is true
            largeThreshold: 2000,

            label: {
                normal: {
                    show: false,
                    position: 'end'
                    // distance: 5,
                    // formatter: 标签文本格式器，同Tooltip.formatter，不支持异步回调
                }
            },
            // itemStyle: {
            //     normal: {
            //     }
            // },
            lineStyle: {
                normal: {
                    opacity: 0.5
                }
            }
        }
    });
});
/**
 * @module echarts/chart/helper/EffectLine
 */
define('echarts/chart/helper/EffectLine',['require','../../util/graphic','./Line','zrender/core/util','../../util/symbol','zrender/core/curve'],function (require) {

    var graphic = require('../../util/graphic');
    var Line = require('./Line');
    var zrUtil = require('zrender/core/util');
    var symbolUtil = require('../../util/symbol');

    var curveUtil = require('zrender/core/curve');

    /**
     * @constructor
     * @extends {module:zrender/graphic/Group}
     * @alias {module:echarts/chart/helper/Line}
     */
    function EffectLine(lineData, fromData, toData, idx) {
        graphic.Group.call(this);

        var line = new Line(lineData, fromData, toData, idx);
        this.add(line);

        this._updateEffectSymbol(lineData, idx);
    }

    var effectLineProto = EffectLine.prototype;

    function setAnimationPoints(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
        ];
    }

    function updateSymbolPosition() {
        var p1 = this.__p1;
        var p2 = this.__p2;
        var cp1 = this.__cp1;
        var t = this.__t;
        var pos = this.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);

        this.rotation = -Math.atan2(ty, tx) - Math.PI / 2;

        this.ignore = false;
    }

    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);
        var period = effectModel.get('period') * 1000;
        if (this._symbolType !== symbolType || period !== this._period) {
            symbol = symbolUtil.createSymbol(
                symbolType, -0.5, -0.5, 1, 1, color
            );
            symbol.ignore = true;
            symbol.z2 = 100;
            this._symbolType = symbolType;
            this._period = period;

            this.add(symbol);

            symbol.__t = 0;
            symbol.animate('', true)
                .when(period, {
                    __t: 1
                })
                .delay(idx / lineData.count() * period / 2)
                .during(zrUtil.bind(updateSymbolPosition, symbol))
                .start();
        }
        // Shadow color is same with color in default
        symbol.setStyle('shadowColor', color);
        symbol.setStyle(effectModel.getItemStyle(['color']));

        symbol.attr('scale', size);
        var points = lineData.getItemLayout(idx);
        setAnimationPoints(symbol, points);

        symbol.setColor(color);
        symbol.attr('scale', size);
    };

    effectLineProto.updateData = function (lineData, fromData, toData, idx) {
        this.childAt(0).updateData(lineData, fromData, toData, idx);
        this._updateEffectSymbol(lineData, idx);
    };

    effectLineProto.updateLayout = function (lineData, fromData, toData, idx) {
        this.childAt(0).updateLayout(lineData, fromData, toData, idx);
        var symbol = this.childAt(1);
        var points = lineData.getItemLayout(idx);
        setAnimationPoints(symbol, points);
    };

    zrUtil.inherits(EffectLine, graphic.Group);

    return EffectLine;
});
define('echarts/chart/lines/LinesView',['require','../helper/LineDraw','../helper/EffectLine','../helper/Line','../../echarts'],function (require) {

    var LineDraw = require('../helper/LineDraw');
    var EffectLine = require('../helper/EffectLine');
    var Line = require('../helper/Line');

    require('../../echarts').extendChartView({

        type: 'lines',

        init: function () {},

        render: function (seriesModel, ecModel, api) {
            var data = seriesModel.getData();
            var lineDraw = this._lineDraw;

            var hasEffect = seriesModel.get('effect.show');
            if (hasEffect !== this._hasEffet) {
                if (lineDraw) {
                    lineDraw.remove();
                }
                lineDraw = this._lineDraw = new LineDraw(
                    hasEffect ? EffectLine : Line
                );
                this._hasEffet = hasEffect;
            }

            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) {
                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();
            // 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);
        }
    });
});
define('echarts/chart/lines/linesLayout',['require'],function (require) {

    return function (ecModel) {
        ecModel.eachSeriesByType('lines', function (seriesModel) {
            var coordSys = seriesModel.coordinateSystem;
            var fromData = seriesModel.fromData;
            var toData = seriesModel.toData;
            var lineData = seriesModel.getData();

            var dims = coordSys.dimensions;
            fromData.each(dims, function (x, y, idx) {
                fromData.setItemLayout(idx, coordSys.dataToPoint([x, y]));
            });
            toData.each(dims, function (x, y, idx) {
                toData.setItemLayout(idx, coordSys.dataToPoint([x, y]));
            });
            lineData.each(function (idx) {
                var p1 = fromData.getItemLayout(idx);
                var p2 = toData.getItemLayout(idx);
                var curveness = lineData.getItemModel(idx).get('lineStyle.normal.curveness');
                var cp1;
                if (curveness > 0) {
                    cp1 = [
                        (p1[0] + p2[0]) / 2 - (p1[1] - p2[1]) * curveness,
                        (p1[1] + p2[1]) / 2 - (p2[0] - p1[0]) * curveness
                    ];
                }
                lineData.setItemLayout(idx, [p1, p2, cp1]);
            });
        });
    };
});
define('echarts/chart/lines',['require','./lines/LinesSeries','./lines/LinesView','zrender/core/util','../echarts','./lines/linesLayout','../visual/seriesColor'],function (require) {

    require('./lines/LinesSeries');
    require('./lines/LinesView');

    var zrUtil = require('zrender/core/util');
    var echarts = require('../echarts');
    echarts.registerLayout(
        require('./lines/linesLayout')
    );

    echarts.registerVisualCoding(
        'chart', zrUtil.curry(require('../visual/seriesColor'), 'lines', 'lineStyle')
    );
});
define('echarts/chart/heatmap/HeatmapSeries',['require','../../model/Series','../helper/createListFromArray'],function (require) {

    var SeriesModel = require('../../model/Series');
    var createListFromArray = require('../helper/createListFromArray');

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

            // No blur
            // Available when heatmap is on geo
            blurSize: 20
        }
    });
});
/**
 * @file defines echarts Heatmap Chart
 * @author Ovilia (me@zhangwenli.com)
 * Inspired by https://github.com/mourner/simpleheat
 *
 * @module
 */
define('echarts/chart/heatmap/HeatmapLayer',['require','zrender/core/util'],function (require) {

    var BRUSH_SIZE = 20;
    var GRADIENT_LEVELS = 256;
    var zrUtil = require('zrender/core/util');

    /**
     * Heatmap Chart
     *
     * @class
     */
    function Heatmap() {
        var canvas = zrUtil.createCanvas();
        this.canvas = canvas;

        this.blurSize = 30;
        this.opacity = 1;

        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 = BRUSH_SIZE + 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;
            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;
                    pixels[offset++] = gradient[gradientOffset];
                    pixels[offset++] = gradient[gradientOffset + 1];
                    pixels[offset++] = gradient[gradientOffset + 2];
                    pixels[offset++] *= this.opacity * gradient[gradientOffset + 3];
                }
                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 = BRUSH_SIZE + 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, BRUSH_SIZE, 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 = [];
            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;
        }
    };

    return Heatmap;
});

define('echarts/chart/heatmap/HeatmapView',['require','../../util/graphic','./HeatmapLayer','zrender/core/util','../../echarts'],function (require) {

    var graphic = require('../../util/graphic');
    var HeatmapLayer = require('./HeatmapLayer');
    var zrUtil = require('zrender/core/util');

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

    return require('../../echarts').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 (!visualMapOfThisSeries) {
                throw new Error('Heatmap must use with visualMap');
            }

            this.group.removeAll();
            var coordSys = seriesModel.coordinateSystem;
            if (coordSys.type === 'cartesian2d') {
                this._renderOnCartesian(coordSys, seriesModel, api);
            }
            else if (coordSys.type === 'geo') {
                this._renderOnGeo(
                    coordSys, seriesModel, visualMapOfThisSeries, api
                );
            }
        },

        _renderOnCartesian: function (cartesian, seriesModel, api) {
            var xAxis = cartesian.getAxis('x');
            var yAxis = cartesian.getAxis('y');
            var group = this.group;

            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 data = seriesModel.getData();
            data.each(['x', 'y', 'z'], function (x, y, z, idx) {
                var itemModel = data.getItemModel(idx);
                var point = cartesian.dataToPoint([x, y]);
                // Ignore empty data
                if (isNaN(z)) {
                    return;
                }
                var 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')
                    }
                });
                var style = itemModel.getModel('itemStyle.normal').getItemStyle(['color']);
                var hoverStl = itemModel.getModel('itemStyle.emphasis').getItemStyle();
                var labelModel = itemModel.getModel('label.normal');
                var hoverLabelModel = itemModel.getModel('label.emphasis');

                var rawValue = seriesModel.getRawValue(idx);
                var defaultText = '-';
                if (rawValue && rawValue[2] != null) {
                    defaultText = rawValue[2];
                }
                if (labelModel.get('show')) {
                    graphic.setText(style, labelModel);
                    style.text = seriesModel.getFormattedLabel(idx, 'normal') || defaultText;
                }
                if (hoverLabelModel.get('show')) {
                    graphic.setText(hoverStl, hoverLabelModel);
                    hoverStl.text = seriesModel.getFormattedLabel(idx, 'emphasis') || defaultText;
                }

                rect.setStyle(style);

                graphic.setHoverStyle(rect, 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');

            var rect = geo.getViewRect().clone();
            var roamTransform = geo.getRoamTransform();
            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);
        }
    });
});
define('echarts/chart/heatmap',['require','./heatmap/HeatmapSeries','./heatmap/HeatmapView'],function (require) {

    require('./heatmap/HeatmapSeries');
    require('./heatmap/HeatmapView');
});
define('echarts/component/geo/GeoView',['require','../helper/MapDraw','../../echarts'],function (require) {



    var MapDraw = require('../helper/MapDraw');

    return require('../../echarts').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) {
            geoModel.get('show') &&
                this._mapDraw.draw(geoModel, ecModel, api);
        }
    });
});
define('echarts/component/geo',['require','../coord/geo/geoCreator','./geo/GeoView','../action/geoRoam'],function (require) {

    require('../coord/geo/geoCreator');

    require('./geo/GeoView');

    require('../action/geoRoam');
});
define('echarts/component/title',['require','../echarts','../util/graphic','../util/layout'],function(require) {



    var echarts = require('../echarts');
    var graphic = require('../util/graphic');
    var layout = require('../util/layout');

    // Model
    echarts.extendComponentModel({

        type: 'title',

        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: 'left',
            // 'top' ¦ 'bottom' ¦ 'center'
            // ¦ {number}（y坐标，单位px）
            top: 'top',

            // 水平对齐
            // 'auto' | 'left' | 'right'
            // 默认根据 x 的位置判断是左对齐还是右对齐
            //textAlign: 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 textEl = new graphic.Text({
                style: {
                    text: titleModel.get('text'),
                    textFont: textStyleModel.getFont(),
                    fill: textStyleModel.getTextColor(),
                    textBaseline: 'top'
                },
                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) {
                var p = layoutRect.x / api.getWidth();
                var p2 = (layoutRect.x + layoutRect.width) / api.getWidth();

                if (p < 0.2) {
                    textAlign = 'left';
                }
                else if (p2 > 0.8) {
                    layoutRect.x += layoutRect.width;
                    textAlign = 'right';
                }
                else {
                    layoutRect.x += layoutRect.width / 2;
                    textAlign = 'center';
                }
            }
            group.position = [layoutRect.x, layoutRect.y];
            textEl.setStyle('textAlign', textAlign);
            subTextEl.setStyle('textAlign', textAlign);

            // 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);
        }
    });
});
define('echarts/component/dataZoom/typeDefaulter',['require','../../model/Component'],function (require) {

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

});
/**
 * @file Axis operator
 */
define('echarts/component/dataZoom/AxisProxy',['require','zrender/core/util','../../util/number'],function(require) {

    var zrUtil = require('zrender/core/util');
    var numberUtil = require('../../util/number');
    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 {Object}
         */
        this._backup;

        /**
         * @private
         * @type {Array.<number>}
         */
        this._valueWindow;

        /**
         * @private
         * @type {Array.<number>}
         */
        this._percentWindow;

        /**
         * @private
         * @type {Array.<number>}
         */
        this._dataExtent;

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

        /**
         * @private
         * @type {module: echarts/component/dataZoom/DataZoomModel}
         */
        this._model = dataZoomModel;
    };

    AxisProxy.prototype = {

        constructor: AxisProxy,

        /**
         * Whether the axisProxy is hosted by model.
         * @public
         * @return {boolean}
         */
        hostedBy: function (model) {
            return this._model === model;
        },

        /**
         * @param {Object} option
         */
        backup: function (model, option) {
            if (model === this._model) {
                this._backup = option;
            }
        },

        /**
         * @return {Object}
         */
        getBackup: function () {
            return zrUtil.clone(this._backup);
        },

        /**
         * @return {Array.<number>}
         */
        getDataExtent: function () {
            return this._dataExtent.slice();
        },

        /**
         * @return {Array.<number>}
         */
        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 = [];

            this.ecModel.eachSeries(function (seriesModel) {
                if (this._axisIndex === seriesModel.get(this._dimName + 'AxisIndex')) {
                    seriesModels.push(seriesModel);
                }
            }, this);

            return seriesModels;
        },

        /**
         * @param {module: echarts/component/dataZoom/DataZoomModel} model
         */
        reset: function (model) {
            if (model !== this._model) {
                return;
            }

            // Process axis data
            var axisDim = this._dimName;
            var axisModel = this.ecModel.getComponent(axisDim + 'Axis', this._axisIndex);
            var isCategoryFilter = axisModel.get('type') === 'category';
            var seriesModels = this.getTargetSeriesModels();

            var dataExtent = calculateDataExtent(axisDim, seriesModels);
            var dataWindow = calculateDataWindow(model, dataExtent, isCategoryFilter);

            // Record data window and data extent.
            this._dataExtent = dataExtent.slice();
            this._valueWindow = dataWindow.valueWindow.slice();
            this._percentWindow = dataWindow.percentWindow.slice();
        },

        /**
         * @param {module: echarts/component/dataZoom/DataZoomModel} model
         */
        filterData: function (model) {
            if (model !== this._model) {
                return;
            }

            var axisDim = this._dimName;
            var seriesModels = this.getTargetSeriesModels();
            var filterMode = model.get('filterMode');
            var valueWindow = this._valueWindow;

            // Process series data
            each(seriesModels, function (seriesModel) {
                var seriesData = seriesModel.getData();
                if (!seriesData) {
                    return;
                }

                each(seriesModel.getDimensionsOnAxis(axisDim), 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(axisDim, seriesModels) {
        var dataExtent = [Number.MAX_VALUE, Number.MIN_VALUE];

        each(seriesModels, function (seriesModel) {
            var seriesData = seriesModel.getData();
            if (seriesData) {
                each(seriesModel.getDimensionsOnAxis(axisDim), function (dim) {
                    var seriesExtent = seriesData.getDataExtent(dim);
                    seriesExtent[0] < dataExtent[0] && (dataExtent[0] = seriesExtent[0]);
                    seriesExtent[1] > dataExtent[1] && (dataExtent[1] = seriesExtent[1]);
                });
            }
        }, this);

        return dataExtent;
    }

    function calculateDataWindow(dataZoomModel, dataExtent, isCategoryFilter) {
        var percentExtent = [0, 100];
        var modelOption = dataZoomModel.option;
        var percentWindow = [
            modelOption.start,
            modelOption.end
        ];
        var valueWindow = [
            modelOption.startValue,
            modelOption.endValue
        ];
        var mathFn = ['floor', 'ceil'];

        // Normalize bound.
        each([0, 1], function (idx) {
            var boundValue = valueWindow[idx];
            var boundPercent;
            var calcuPercent = true;

            if (isInvalidNumber(boundValue)) {
                boundPercent = percentWindow[idx];
                if (isInvalidNumber(boundPercent)) {
                    boundPercent = percentExtent[idx];
                }
                boundValue = numberUtil.linearMap(
                    boundPercent, percentExtent, dataExtent, true
                );
                calcuPercent = false;
            }
            if (isCategoryFilter) {
                boundValue = Math[mathFn[idx]](boundValue);
            }
            if (calcuPercent) {
                boundPercent = numberUtil.linearMap(
                    boundValue, dataExtent, percentExtent, true
                );
            }
            valueWindow[idx] = boundValue;
            percentWindow[idx] = boundPercent;
        });

        return {
            valueWindow: asc(valueWindow),
            percentWindow: asc(percentWindow)
        };
    }

    function isInvalidNumber(val) {
        return isNaN(val) || val == null;
    }

    return AxisProxy;

});
/**
 * @file Data zoom model
 */
define('echarts/component/dataZoom/DataZoomModel',['require','zrender/core/util','zrender/core/env','../../echarts','../../util/model','./AxisProxy'],function(require) {

    var zrUtil = require('zrender/core/util');
    var env = require('zrender/core/env');
    var echarts = require('../../echarts');
    var modelUtil = require('../../util/model');
    var AxisProxy = require('./AxisProxy');
    var each = zrUtil.each;
    var eachAxisDim = modelUtil.eachAxisDim;

    return echarts.extendComponentModel({

        type: 'dataZoom',

        dependencies: [
            'xAxis', 'yAxis', 'zAxis', 'radiusAxis', 'angleAxis', '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 all horizontal category axis.
            yAxisIndex: null,       // Default all vertical category axis.
            filterMode: 'filter',   // 'filter' or 'empty'
                                    // 'filter': data items which are out of window will be removed.
                                    //           This option is applicable when filtering outliers.
                                    // '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.
            throttle: 100,          // Dispatch action by the fixed rate, avoid frequency.
                                    // default 100. Do not throttle when use null/undefined.
            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.
        },

        /**
         * @override
         */
        init: function (option, parentModel, ecModel) {

            /**
             * can be 'axisIndex' or 'orient'
             *
             * @private
             * @type {string}
             */
            this._autoMode;

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

            this.mergeDefaultAndTheme(option, ecModel);
            this.mergeOption({}, true);
        },

        /**
         * @override
         */
        mergeOption: function (newOption, isInit) {
            var thisOption = this.option;

            newOption && zrUtil.merge(thisOption, newOption);

            // Disable realtime view update if canvas is not supported.
            if (!env.canvasSupported) {
                thisOption.realtime = false;
            }

            this.textStyleModel = this.getModel('textStyle');

            this._resetTarget(newOption, isInit);

            this._giveAxisProxies();

            this._backup();
        },

        /**
         * @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 (newOption, isInit) {

            this._resetAutoMode(newOption, isInit);

            var thisOption = this.option;

            eachAxisDim(function (dimNames) {
                var axisIndexName = dimNames.axisIndex;
                thisOption[axisIndexName] = autoMode === 'axisIndex'
                    ? [] : modelUtil.normalizeToArray(thisOption[axisIndexName]);
            }, this);

            var autoMode = this._autoMode;

            if (autoMode === 'axisIndex') {
                this._autoSetAxisIndex();
            }
            else if (autoMode === 'orient') {
                this._autoSetOrient();
            }
        },

        /**
         * @private
         */
        _resetAutoMode: function (newOption, isInit) {
            // Consider this case:
            // There is no axisIndex specified at the begining,
            // which means that auto choise of axisIndex is required.
            // Then user modifies series using setOption and do not specify axisIndex either.
            // At that moment axisIndex should be re-choised, but not remain last choise.
            // So we keep auto mode util user specified axisIndex or orient in newOption.
            var option = isInit ? this.option : newOption;

            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 (option[dimNames.axisIndex] != null) {
                    hasIndexSpecified = true;
                }
            }, this);

            var orient = option.orient;

            if (orient == null && hasIndexSpecified) {
                // Auto set orient by axisIndex.
                this._autoMode = 'orient';
            }
            else {
                if (orient == null) {
                    this.option.orient = 'horizontal';
                }
                if (!hasIndexSpecified) {
                    // Auto set axisIndex by orient.
                    this._autoMode = 'axisIndex';
                }
            }
        },

        /**
         * @private
         */
        _autoSetAxisIndex: function () {
            var autoAxisIndex = this._autoMode === 'axisIndex';
            var orient = this.get('orient');
            var thisOption = this.option;

            if (autoAxisIndex) {
                // Find axis that parallel to dataZoom as default.
                var dimNames = orient === 'vertical'
                    ? {dim: 'y', axisIndex: 'yAxisIndex', axis: 'yAxis'}
                    : {dim: 'x', axisIndex: 'xAxisIndex', axis: 'xAxis'};

                if (this.dependentModels[dimNames.axis].length) {
                    thisOption[dimNames.axisIndex] = [0];
                    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);
                            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
         */
        _backup: function () {
            this.eachTargetAxis(function (dimNames, axisIndex, dataZoomModel, ecModel) {
                var axisModel = ecModel.getComponent(dimNames.axis, axisIndex);
                this.getAxisProxy(dimNames.name, axisIndex).backup(
                    this,
                    {
                        scale: axisModel.get('scale', true),
                        min: axisModel.get('min', true),
                        max: axisModel.get('max', true)
                    }
                );
            }, this);
        },

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

        getAxisProxy: function (dimName, axisIndex) {
            return this._axisProxies[dimName + '_' + axisIndex];
        },

        /**
         * 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]
         */
        setRawRange: function (opt) {
            each(['start', 'end', 'startValue', 'endValue'], function (name) {
                this.option[name] = opt[name];
            }, this);
        },

        /**
         * @public
         * @return {Array.<number>}
         */
        getPercentRange: function () {
            // 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].getDataPercentWindow();
                }
            }

            // 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
            // show 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].getDataPercentWindow();
                }
            }
        }

    });

});
define('echarts/component/dataZoom/DataZoomView',['require','../../view/Component'],function (require) {

    var ComponentView = require('../../view/Component');

    return 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} {
         *                   cartesians: [
         *                       {model: coord0, axisModels: [axis1, axis3], coordIndex: 1},
         *                       {model: coord1, axisModels: [axis0, axis2], coordIndex: 0},
         *                       ...
         *                   ],  // cartesians must not be null/undefined.
         *                   polars: [
         *                       {model: coord0, axisModels: [axis4], coordIndex: 0},
         *                       ...
         *                   ],  // polars must not be null/undefined.
         *                   axisModels: [axis0, axis1, axis2, axis3, axis4]
         *                       // axisModels must not be null/undefined.
         *                  }
         */
        getTargetInfo: function () {
            var dataZoomModel = this.dataZoomModel;
            var ecModel = this.ecModel;
            var cartesians = [];
            var polars = [];
            var axisModels = [];

            dataZoomModel.eachTargetAxis(function (dimNames, axisIndex) {
                var axisModel = ecModel.getComponent(dimNames.axis, axisIndex);
                if (axisModel) {
                    axisModels.push(axisModel);

                    var gridIndex = axisModel.get('gridIndex');
                    var polarIndex = axisModel.get('polarIndex');

                    if (gridIndex != null) {
                        var coordModel = ecModel.getComponent('grid', gridIndex);
                        save(coordModel, axisModel, cartesians, gridIndex);
                    }
                    else if (polarIndex != null) {
                        var coordModel = ecModel.getComponent('polar', polarIndex);
                        save(coordModel, axisModel, polars, polarIndex);
                    }
                }
            }, 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 {
                cartesians: cartesians,
                polars: polars,
                axisModels: axisModels
            };
        }

    });

});
/**
 * @file Data zoom model
 */
define('echarts/component/dataZoom/SliderZoomModel',['require','./DataZoomModel'],function(require) {

    var DataZoomModel = require('./DataZoomModel');

    return DataZoomModel.extend({

        type: 'dataZoom.slider',

        /**
         * @readOnly
         */
        layoutMode: 'box',

        /**
         * @protected
         */
        defaultOption: {
            show: true,

            left: 'auto',   // Default align to grid rect.
            right: 'auto',  // Default align to grid rect.
            top: 'auto',    // Default align to grid rect.
            bottom: 'auto', // Default align to grid rect.
            width: 'auto',  // Default align to grid rect.
            height: 'auto', // Default align to grid rect.

            backgroundColor: 'rgba(47,69,84,0)',    // Background of slider zoom component.
            dataBackgroundColor: '#ddd',            // Background of data shadow.
            fillerColor: 'rgba(47,69,84,0.25)',     // Color of selected area.
            handleColor: 'rgba(47,69,84,0.65)',     // Color of handle.
            handleSize: 10,

            labelPrecision: null,
            labelFormatter: null,
            showDetail: true,
            showDataShadow: 'auto',                 // Default auto decision.
            realtime: true,
            zoomLock: false,                        // Whether disable zoom.
            textStyle: {
                color: '#333'
            }
        }

    });

});
define('echarts/util/throttle',[],function () {

    var lib = {};

    var ORIGIN_METHOD = '\0__throttleOriginMethod';
    var RATE = '\0__throttleRate';

    /**
     * 频率控制 返回函数连续调用时，fn 执行频率限定为每多少时间执行一次
     * 例如常见效果：
     * notifyWhenChangesStop
     *      频繁调用时，只保证最后一次执行
     *      配成：trailing：true；debounce：true 即可
     * notifyAtFixRate
     *      频繁调用时，按规律心跳执行
     *      配成：trailing：true；debounce：false 即可
     * 注意：
     *     根据model更新view的时候，可以使用throttle，
     *     但是根据view更新model的时候，避免使用这种延迟更新的方式。
     *     因为这可能导致model和server同步出现问题。
     *
     * @public
     * @param {(Function|Array.<Function>)} fn 需要调用的函数
     *                                         如果fn为array，则表示可以对多个函数进行throttle。
     *                                         他们共享同一个timer。
     * @param {number} delay 延迟时间，单位毫秒
     * @param {bool} trailing 是否保证最后一次触发的执行
     *                        true：表示保证最后一次调用会触发执行。
     *                        但任何调用后不可能立即执行，总会delay。
     *                        false：表示不保证最后一次调用会触发执行。
     *                        但只要间隔大于delay，调用就会立即执行。
     * @param {bool} debounce 节流
     *                        true：表示：频繁调用（间隔小于delay）时，根本不执行
     *                        false：表示：频繁调用（间隔小于delay）时，按规律心跳执行
     * @return {(Function|Array.<Function>)} 实际调用函数。
     *                                       当输入的fn为array时，返回值也为array。
     *                                       每项是Function。
     */
    lib.throttle = function (fn, delay, trailing, debounce) {

        var currCall = (new Date()).getTime();
        var lastCall = 0;
        var lastExec = 0;
        var timer = null;
        var diff;
        var scope;
        var args;
        var isSingle = typeof fn === 'function';
        delay = delay || 0;

        if (isSingle) {
            return createCallback();
        }
        else {
            var ret = [];
            for (var i = 0; i < fn.length; i++) {
                ret[i] = createCallback(i);
            }
            return ret;
        }

        function createCallback(index) {

            function exec() {
                lastExec = (new Date()).getTime();
                timer = null;
                (isSingle ? fn : fn[index]).apply(scope, args || []);
            }

            var cb = function () {
                currCall = (new Date()).getTime();
                scope = this;
                args = arguments;
                diff = currCall - (debounce ? lastCall : lastExec) - delay;

                clearTimeout(timer);

                if (debounce) {
                    if (trailing) {
                        timer = setTimeout(exec, delay);
                    }
                    else if (diff >= 0) {
                        exec();
                    }
                }
                else {
                    if (diff >= 0) {
                        exec();
                    }
                    else if (trailing) {
                        timer = setTimeout(exec, -diff);
                    }
                }

                lastCall = currCall;
            };

            /**
             * Clear throttle.
             * @public
             */
            cb.clear = function () {
                if (timer) {
                    clearTimeout(timer);
                    timer = null;
                }
            };

            return cb;
        }
    };

    /**
     * 按一定频率执行，最后一次调用总归会执行
     *
     * @public
     */
    lib.fixRate = function (fn, delay) {
        return delay != null
            ? lib.throttle(fn, delay, true, false)
            : fn;
    };

    /**
     * 直到不频繁调用了才会执行，最后一次调用总归会执行
     *
     * @public
     */
    lib.debounce = function (fn, delay) {
        return delay != null
             ? lib.throttle(fn, delay, true, true)
             : fn;
    };


    /**
     * 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' or 'debounce'
     */
    lib.createOrUpdate = function (obj, fnAttr, rate, throttleType) {
        var fn = obj[fnAttr];

        if (!fn || rate == null || !throttleType) {
            return;
        }

        var originFn = fn[ORIGIN_METHOD] || fn;
        var lastRate = fn[RATE];

        if (lastRate !== rate) {
            fn = obj[fnAttr] = lib[throttleType](originFn, rate);
            fn[ORIGIN_METHOD] = originFn;
            fn[RATE] = rate;
        }
    };

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

    return lib;
});

define('echarts/component/helper/sliderMove',['require'],function (require) {

    /**
     * Calculate slider move result.
     *
     * @param {number} delta Move length.
     * @param {Array.<number>} handleEnds handleEnds[0] and 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 {string} mode 'rigid': Math.abs(handleEnds[0] - handleEnds[1]) remain unchanged,
     *                      'cross' handleEnds[0] can be bigger then handleEnds[1],
     *                      'push' handleEnds[0] can not be bigger then handleEnds[1],
     *                              when they touch, one push other.
     * @param {number} handleIndex If mode is 'rigid', handleIndex is not required.
     * @param {Array.<number>} The input handleEnds.
     */
    return function (delta, handleEnds, extent, mode, handleIndex) {
        if (!delta) {
            return handleEnds;
        }

        if (mode === 'rigid') {
            delta = getRealDelta(delta, handleEnds, extent);
            handleEnds[0] += delta;
            handleEnds[1] += delta;
        }
        else {
            delta = getRealDelta(delta, handleEnds[handleIndex], extent);
            handleEnds[handleIndex] += delta;

            if (mode === 'push' && handleEnds[0] > handleEnds[1]) {
                handleEnds[1 - handleIndex] = handleEnds[handleIndex];
            }
        }

        return handleEnds;

        function getRealDelta(delta, handleEnds, extent) {
            var handleMinMax = !handleEnds.length
                ? [handleEnds, handleEnds]
                : handleEnds.slice();
            handleEnds[0] > handleEnds[1] && handleMinMax.reverse();

            if (delta < 0 && handleMinMax[0] + delta < extent[0]) {
                delta = extent[0] - handleMinMax[0];
            }
            if (delta > 0 && handleMinMax[1] + delta > extent[1]) {
                delta = extent[1] - handleMinMax[1];
            }
            return delta;
        }
    };
});
define('echarts/component/dataZoom/SliderZoomView',['require','zrender/core/util','../../util/graphic','../../util/throttle','./DataZoomView','../../util/number','../../util/layout','../helper/sliderMove'],function (require) {

    var zrUtil = require('zrender/core/util');
    var graphic = require('../../util/graphic');
    var throttle = require('../../util/throttle');
    var DataZoomView = require('./DataZoomView');
    var Rect = graphic.Rect;
    var numberUtil = require('../../util/number');
    var linearMap = numberUtil.linearMap;
    var layout = require('../../util/layout');
    var sliderMove = require('../helper/sliderMove');
    var asc = numberUtil.asc;
    var bind = zrUtil.bind;
    var mathRound = Math.round;
    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'];

    return 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._halfHandleSize;

            /**
             * @private
             */
            this._location;

            /**
             * @private
             */
            this._dragging;

            /**
             * @private
             */
            this._dataShadowInfo;

            this.api = api;
        },

        /**
         * @override
         */
        render: function (dataZoomModel, ecModel, api, payload) {
            this.$superApply('render', arguments);

            throttle.createOrUpdate(
                this,
                '_dispatchZoomAction',
                this.dataZoomModel.get('throttle'),
                'fixRate'
            );

            this._orient = dataZoomModel.get('orient');
            this._halfHandleSize = mathRound(dataZoomModel.get('handleSize') / 2);

            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 () {
            this.$superApply('remove', arguments);
            throttle.clear(this, '_dispatchZoomAction');
        },

        /**
         * @override
         */
        dispose: function () {
            this.$superApply('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._renderDataShadow();
            this._renderHandle();

            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.
            // Notice: Those params have processed by layout.mergeLayoutParam.
            var positionInfo = this._orient === HORIZONTAL
                ? {
                    left: coordRect.x,
                    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
                };

            zrUtil.each(
                layout.getLayoutParams(dataZoomModel.option),
                function (value, name) {
                    if (value !== 'auto') {
                        positionInfo[name] = value;
                    }
                }
            );

            var layoutRect = layout.getLayoutRect(
                positionInfo,
                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.position[0] = location.x - rect.x;
            thisGroup.position[1] = location.y - rect.y;
        },

        /**
         * @private
         */
        _getViewExtent: function () {
            // View total length.
            var halfHandleSize = this._halfHandleSize;
            var totalLength = mathMax(this._size[0], halfHandleSize * 4);
            var extent = [halfHandleSize, totalLength - halfHandleSize];

            return extent;
        },

        _renderBackground : function () {
            var dataZoomModel = this.dataZoomModel;
            var size = this._size;

            this._displayables.barGroup.add(new Rect({
                silent: true,
                shape: {
                    x: 0, y: 0, width: size[0], height: size[1]
                },
                style: {
                    fill: dataZoomModel.get('backgroundColor')
                }
            }));
        },

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

            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 points = [[size[0], 0], [0, 0]];
            var step = thisShadowExtent[1] / data.count();
            var thisCoord = 0;

            // Optimize for large data shadow
            var stride = Math.round(data.count() / size[0]);
            data.each([otherDim], function (value, index) {
                if (stride > 0 && (index % stride)) {
                    thisCoord += step;
                    return;
                }
                // FIXME
                // 应该使用统计的空判断？还是在list里进行空判断？
                var otherCoord = (value == null || isNaN(value) || value === '')
                    ? null
                    : linearMap(value, otherDataExtent, otherShadowExtent, true);
                otherCoord != null && points.push([thisCoord, otherCoord]);

                thisCoord += step;
            });

            this._displayables.barGroup.add(new graphic.Polyline({
                shape: {points: points},
                style: {fill: this.dataZoomModel.get('dataBackgroundColor'), lineWidth: 0},
                silent: true,
                z2: -20
            }));
        },

        _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 otherDim = getOtherDim(dimNames.name);

                    var thisAxis = ecModel.getComponent(dimNames.axis, axisIndex).axis;

                    result = {
                        thisAxis: thisAxis,
                        series: seriesModel,
                        thisDim: dimNames.name,
                        otherDim: otherDim,
                        otherAxisInverse: seriesModel
                            .coordinateSystem.getOtherAxis(thisAxis).inverse
                    };

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

            barGroup.add(displaybles.filler = new Rect({
                draggable: true,
                cursor: 'move',
                drift: bind(this._onDragMove, this, 'all'),
                ondragend: bind(this._onDragEnd, this),
                onmouseover: bind(this._showDataInfo, this, true),
                onmouseout: bind(this._showDataInfo, this, false),
                style: {
                    fill: this.dataZoomModel.get('fillerColor'),
                    // text: ':::',
                    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: this.dataZoomModel.get('dataBackgroundColor'),
                    lineWidth: DEFAULT_FRAME_BORDER_WIDTH,
                    fill: 'rgba(0,0,0,0)'
                }
            })));

            each([0, 1], function (handleIndex) {

                barGroup.add(handles[handleIndex] = new Rect({
                    style: {
                        fill: this.dataZoomModel.get('handleColor')
                    },
                    cursor: 'move',
                    draggable: true,
                    drift: bind(this._onDragMove, this, handleIndex),
                    ondragend: bind(this._onDragEnd, this),
                    onmouseover: bind(this._showDataInfo, this, true),
                    onmouseout: bind(this._showDataInfo, this, false)
                }));

                var textStyleModel = this.dataZoomModel.textStyleModel;

                this.group.add(
                    handleLabels[handleIndex] = new graphic.Text({
                    silent: true,
                    invisible: true,
                    style: {
                        x: 0, y: 0, text: '',
                        textBaseline: 'middle',
                        textAlign: 'center',
                        fill: textStyleModel.getTextColor(),
                        textFont: textStyleModel.getFont()
                    }
                }));

            }, this);
        },

        /**
         * @private
         */
        _resetInterval: function () {
            var range = this._range = this.dataZoomModel.getPercentRange();

            this._handleEnds = linearMap(range, [0, 100], this._getViewExtent(), true);
        },

        /**
         * @private
         * @param {(number|string)} handleIndex 0 or 1 or 'all'
         * @param {number} dx
         * @param {number} dy
         */
        _updateInterval: function (handleIndex, delta) {
            var handleEnds = this._handleEnds;
            var viewExtend = this._getViewExtent();

            sliderMove(
                delta,
                handleEnds,
                viewExtend,
                (handleIndex === 'all' || this.dataZoomModel.get('zoomLock'))
                    ? 'rigid' : 'cross',
                handleIndex
            );

            this._range = asc(linearMap(handleEnds, viewExtend, [0, 100], true));
        },

        /**
         * @private
         */
        _updateView: function () {
            var displaybles = this._displayables;
            var handleEnds = this._handleEnds;
            var handleInterval = asc(handleEnds.slice());
            var size = this._size;
            var halfHandleSize = this._halfHandleSize;

            each([0, 1], function (handleIndex) {

                // Handles
                var handle = displaybles.handles[handleIndex];
                handle.setShape({
                    x: handleEnds[handleIndex] - halfHandleSize,
                    y: -1,
                    width: halfHandleSize * 2,
                    height: size[1] + 2,
                    r: 1
                });

            }, this);

            // Filler
            displaybles.filler.setShape({
                x: handleInterval[0],
                y: 0,
                width: handleInterval[1] - handleInterval[0],
                height: this._size[1]
            });

            this._updateDataInfo();
        },

        /**
         * @private
         */
        _updateDataInfo: function () {
            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 dataInterval;
                var axis;
                dataZoomModel.eachTargetAxis(function (dimNames, axisIndex) {
                    // Using dataInterval of the first axis.
                    if (!dataInterval) {
                        dataInterval = dataZoomModel
                            .getAxisProxy(dimNames.name, axisIndex)
                            .getDataValueWindow();
                        axis = this.ecModel.getComponent(dimNames.axis, axisIndex).axis;
                    }
                }, this);

                if (dataInterval) {
                    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.
                var barTransform = graphic.getTransform(
                    displaybles.handles[handleIndex], this.group
                );
                var direction = graphic.transformDirection(
                    handleIndex === 0 ? 'right' : 'left', barTransform
                );
                var offset = this._halfHandleSize + 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],
                    textBaseline: 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');
            if (zrUtil.isFunction(labelFormatter)) {
                return labelFormatter(value);
            }

            var labelPrecision = dataZoomModel.get('labelPrecision');
            if (labelPrecision == null || labelPrecision === 'auto') {
                labelPrecision = axis.getPixelPrecision();
            }

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

            if (zrUtil.isString(labelFormatter)) {
                value = labelFormatter.replace('{value}', value);
            }

            return value;
        },

        /**
         * @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 vertex = this._applyBarTransform([dx, dy], true);

            this._updateInterval(handleIndex, vertex[0]);
            this._updateView();

            if (this.dataZoomModel.get('realtime')) {
                this._dispatchZoomAction();
            }
        },

        _onDragEnd: function () {
            this._dragging = false;
            this._showDataInfo(false);
            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
         */
        _applyBarTransform: function (vertex, inverse) {
            var barTransform = this._displayables.barGroup.getLocalTransform();
            return graphic.applyTransform(vertex, barTransform, inverse);
        },

        /**
         * @private
         */
        _findCoordRect: function () {
            // Find the grid coresponding to the first axis referred by dataZoom.
            var targetInfo = this.getTargetInfo();

            // FIXME
            // 判断是catesian还是polar
            var rect;
            if (targetInfo.cartesians.length) {
                rect = targetInfo.cartesians[0].model.coordinateSystem.getRect();
            }
            else { // Polar
                // FIXME
                // 暂时随便写的
                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里一致，但是写在这里是否不好
        return thisDim === 'x' ? 'y' : 'x';
    }

});
/**
 * @file Data zoom model
 */
define('echarts/component/dataZoom/InsideZoomModel',['require','./DataZoomModel'],function(require) {

    var DataZoomModel = require('./DataZoomModel');

    return DataZoomModel.extend({

        type: 'dataZoom.inside'

    });

});
define('echarts/component/dataZoom/InsideZoomView',['require','./DataZoomView','../../util/throttle','zrender/core/util','../helper/sliderMove','../../component/helper/RoamController'],function (require) {

    var DataZoomView = require('./DataZoomView');
    var throttle = require('../../util/throttle');
    var zrUtil = require('zrender/core/util');
    var sliderMove = require('../helper/sliderMove');
    var RoamController = require('../../component/helper/RoamController');
    var bind = zrUtil.bind;

    return DataZoomView.extend({

        type: 'dataZoom.inside',

        /**
         * @override
         */
        init: function (ecModel, api) {

            /**
             * @private
             * @type {Object.<string, module:echarts/component/helper/RoamController>}
             */
            this._controllers = {};

            /**
             * '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) {
            this.$superApply('render', arguments);

            throttle.createOrUpdate(
                this,
                '_dispatchZoomAction',
                this.dataZoomModel.get('throttle'),
                'fixRate'
            );

            // 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._range = dataZoomModel.getPercentRange();
            }

            this._resetController(api);
        },

        /**
         * @override
         */
        remove: function () {
            this.$superApply('remove', arguments);

            var controllers = this._controllers;
            zrUtil.each(controllers, function (controller) {
                controller.off('pan').off('zoom');
            });
            controllers.length = 0;

            throttle.clear(this, '_dispatchZoomAction');
        },

        /**
         * @override
         */
        dispose: function () {
            this.$superApply('dispose', arguments);
            throttle.clear(this, '_dispatchZoomAction');
        },

        /**
         * @private
         */
        _resetController: function (api) {
            var controllers = this._controllers;
            var targetInfo = this.getTargetInfo();

            zrUtil.each(targetInfo.cartesians, function (item) {
                // Init controller.
                var key = 'cartesian' + item.coordIndex;
                var controller = controllers[key];
                if (!controller) {
                    controller = controllers[key] = new RoamController(api.getZr());
                    controller.enable();
                    controller.on('pan', bind(this._onPan, this, controller, item));
                    controller.on('zoom', bind(this._onZoom, this, controller, item));
                }

                controller.rect = item.model.coordinateSystem.getRect().clone();

            }, this);

            // TODO
            // polar支持
        },

        /**
         * @private
         */
        _onPan: function (controller, coordInfo, dx, dy) {
            var range = this._range = panCartesian(
                [dx, dy], this._range, controller, coordInfo
            );

            if (range) {
                this._dispatchZoomAction(range);
            }
        },

        /**
         * @private
         */
        _onZoom: function (controller, coordInfo, scale, mouseX, mouseY) {
            var dataZoomModel = this.dataZoomModel;
            scale = 1 / scale;
            var range = this._range = scaleCartesian(
                scale, [mouseX, mouseY], this._range,
                controller, coordInfo, dataZoomModel
            );

            this._dispatchZoomAction(range);
        },

        /**
         * This action will be throttled.
         * @private
         */
        _dispatchZoomAction: function (range) {
            this.api.dispatchAction({
                type: 'dataZoom',
                from: this.uid,
                dataZoomId: this.dataZoomModel.id,
                start: range[0],
                end: range[1]
            });
        }

    });

    function panCartesian(pixelDeltas, range, controller, coordInfo) {
        range = range.slice();

        // Calculate transform by the first axis.
        var axisModel = coordInfo.axisModels[0];
        if (!axisModel) {
            return;
        }

        var directionInfo = getDirectionInfo(pixelDeltas, axisModel, controller);

        var percentDelta = directionInfo.signal
            * (range[1] - range[0])
            * directionInfo.pixel / directionInfo.pixelLength;

        sliderMove(
            percentDelta,
            range,
            [0, 100],
            'rigid'
        );

        return range;
    }

    function scaleCartesian(scale, mousePoint, range, controller, coordInfo, dataZoomModel) {
        range = range.slice();

        // Calculate transform by the first axis.
        var axisModel = coordInfo.axisModels[0];
        if (!axisModel) {
            return;
        }

        var directionInfo = getDirectionInfo(mousePoint, axisModel, controller);

        var mouse = directionInfo.pixel - directionInfo.pixelStart;
        var percentPoint = mouse / directionInfo.pixelLength * (range[1] - range[0]) + range[0];

        scale = Math.max(scale, 0);
        range[0] = (range[0] - percentPoint) * scale + percentPoint;
        range[1] = (range[1] - percentPoint) * scale + percentPoint;

        // FIXME
        // 改为基于绝对值的方式？

        return fixRange(range);
    }

    function getDirectionInfo(xy, axisModel, controller) {
        var axis = axisModel.axis;
        var rect = controller.rect;
        var ret = {};

        if (axis.dim === 'x') {
            ret.pixel = xy[0];
            ret.pixelLength = rect.width;
            ret.pixelStart = rect.x;
            ret.signal = axis.inverse ? 1 : -1;
        }
        else { // axis.dim === 'y'
            ret.pixel = xy[1];
            ret.pixelLength = rect.height;
            ret.pixelStart = rect.y;
            ret.signal = axis.inverse ? -1 : 1;
        }

        return ret;
    }

    function fixRange(range) {
        // Clamp, using !(<= or >=) to handle NaN.
        // jshint ignore:start
        var bound = [0, 100];
        !(range[0] <= bound[1]) && (range[0] = bound[1]);
        !(range[1] <= bound[1]) && (range[1] = bound[1]);
        !(range[0] >= bound[0]) && (range[0] = bound[0]);
        !(range[1] >= bound[0]) && (range[1] = bound[0]);
        // jshint ignore:end

        return range;
    }
});
/**
 * @file Data zoom processor
 */
define('echarts/component/dataZoom/dataZoomProcessor',['require','../../echarts','../../util/number'],function (require) {

    var echarts = require('../../echarts');
    var numberUtil = require('../../util/number');

    echarts.registerProcessor('filter', function (ecModel, api) {

        ecModel.eachComponent('dataZoom', function (dataZoomModel) {
            dataZoomModel.eachTargetAxis(resetSingleAxis);
        });

        ecModel.eachComponent('dataZoom', function (dataZoomModel) {
            dataZoomModel.eachTargetAxis(filterSingleAxis);
        });
    });

    function resetSingleAxis(dimNames, axisIndex, dataZoomModel, ecModel) {
        var dimName = dimNames.name;
        var axisProxy = dataZoomModel.getAxisProxy(dimName, axisIndex);

        axisProxy.reset(dataZoomModel);

        var percentRange = axisProxy.getDataPercentWindow();
        var valueRange = axisProxy.getDataValueWindow();
        var axisModel = ecModel.getComponent(dimNames.axis, axisIndex);
        var isFull = (percentRange[0] === 0 && percentRange[1] === 100);
        var backup = axisProxy.getBackup();

        // [0, 500]: guess axis extent.
        var precision = numberUtil.getPixelPrecision(valueRange, [0, 500]);
        // toFixed() digits argument must be between 0 and 20
        var invalidPrecision = !(precision < 20 && precision >= 0);

        axisModel.setNeedsCrossZero && axisModel.setNeedsCrossZero(
            isFull ? !backup.scale : false
        );
        axisModel.setMin && axisModel.setMin(
            (isFull || invalidPrecision) ? backup.min : +valueRange[0].toFixed(precision)
        );
        axisModel.setMax && axisModel.setMax(
            (isFull || invalidPrecision) ? backup.max : +valueRange[1].toFixed(precision)
        );
    }

    function filterSingleAxis(dimNames, axisIndex, dataZoomModel, ecModel) {
        dataZoomModel.getAxisProxy(dimNames.name, axisIndex).filterData(dataZoomModel);
    }

});

/**
 * @file Data zoom action
 */
define('echarts/component/dataZoom/dataZoomAction',['require','zrender/core/util','../../util/model','../../echarts'],function(require) {

    var zrUtil = require('zrender/core/util');
    var modelUtil = require('../../util/model');
    var echarts = require('../../echarts');


    echarts.registerAction('dataZoom', function (payload, ecModel) {

        var linkedNodesFinder = modelUtil.createLinkedNodesFinder(
            zrUtil.bind(ecModel.eachComponent, ecModel, 'dataZoom'),
            modelUtil.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
            });
        });

    });

});
/**
 * DataZoom component entry
 */
define('echarts/component/dataZoom',['require','./dataZoom/typeDefaulter','./dataZoom/DataZoomModel','./dataZoom/DataZoomView','./dataZoom/SliderZoomModel','./dataZoom/SliderZoomView','./dataZoom/InsideZoomModel','./dataZoom/InsideZoomView','./dataZoom/dataZoomProcessor','./dataZoom/dataZoomAction'],function (require) {

    require('./dataZoom/typeDefaulter');

    require('./dataZoom/DataZoomModel');
    require('./dataZoom/DataZoomView');

    require('./dataZoom/SliderZoomModel');
    require('./dataZoom/SliderZoomView');

    require('./dataZoom/InsideZoomModel');
    require('./dataZoom/InsideZoomView');

    require('./dataZoom/dataZoomProcessor');
    require('./dataZoom/dataZoomAction');

});
/**
 * @file VisualMap preprocessor
 */
define('echarts/component/visualMap/preprocessor',['require','zrender/core/util'],function(require) {

    var zrUtil = require('zrender/core/util');
    var each = zrUtil.each;

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

});
define('echarts/component/visualMap/typeDefaulter',['require','../../model/Component'],function (require) {

    require('../../model/Component').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';
    });

});
/**
 * @file Data range visual coding.
 */
define('echarts/component/visualMap/visualCoding',['require','../../echarts','../../visual/VisualMapping','zrender/core/util'],function (require) {

    var echarts = require('../../echarts');
    var VisualMapping = require('../../visual/VisualMapping');
    var zrUtil = require('zrender/core/util');

    echarts.registerVisualCoding('component', function (ecModel) {
        ecModel.eachComponent('visualMap', function (visualMapModel) {
            processSingleVisualMap(visualMapModel, ecModel);
        });
    });

    function processSingleVisualMap(visualMapModel, ecModel) {
        var visualMappings = visualMapModel.targetVisuals;
        var visualTypesMap = {};
        zrUtil.each(['inRange', 'outOfRange'], function (state) {
            var visualTypes = VisualMapping.prepareVisualTypes(visualMappings[state]);
            visualTypesMap[state] = visualTypes;
        });

        visualMapModel.eachTargetSeries(function (seriesModel) {
            var data = seriesModel.getData();
            var dimension = visualMapModel.getDataDimension(data);
            var dataIndex;

            function getVisual(key) {
                return data.getItemVisual(dataIndex, key);
            }

            function setVisual(key, value) {
                data.setItemVisual(dataIndex, key, value);
            }

            data.each([dimension], function (value, index) {
                // For performance consideration, do not use curry.
                dataIndex = index;
                var valueState = visualMapModel.getValueState(value);
                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(value, getVisual, setVisual);
                }
            });
        });
    }

});

/**
 * @file Visual mapping.
 */
define('echarts/visual/visualDefault',['require','zrender/core/util'],function (require) {

    var zrUtil = require('zrender/core/util');

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

        symbol: {
            active: ['circle', 'roundRect', 'diamond'],
            inactive: ['none']
        },

        symbolSize: {
            active: [10, 50],
            inactive: [0, 0]
        }
    };

    return visualDefault;

});

/**
 * @file Data zoom model
 */
define('echarts/component/visualMap/VisualMapModel',['require','zrender/core/util','zrender/core/env','../../echarts','../../util/model','../../visual/visualDefault','../../visual/VisualMapping','../../util/number'],function(require) {

    var zrUtil = require('zrender/core/util');
    var env = require('zrender/core/env');
    var echarts = require('../../echarts');
    var modelUtil = require('../../util/model');
    var visualDefault = require('../../visual/visualDefault');
    var VisualMapping = require('../../visual/VisualMapping');
    var mapVisual = VisualMapping.mapVisual;
    var eachVisual = VisualMapping.eachVisual;
    var numberUtil = require('../../util/number');
    var isArray = zrUtil.isArray;
    var each = zrUtil.each;
    var asc = numberUtil.asc;
    var linearMap = numberUtil.linearMap;

    return echarts.extendComponentModel({

        type: 'visualMap',

        dependencies: ['series'],

        /**
         * [lowerBound, upperBound]
         *
         * @readOnly
         * @type {Array.<number>}
         */
        dataBound: [-Infinity, Infinity],

        /**
         * @readOnly
         * @type {Array.<string>}
         */
        stateList: ['inRange', 'outOfRange'],

        /**
         * @readOnly
         * @type {string|Object}
         */
        layoutMode: {type: 'box', ignoreSize: true},

        /**
         * @protected
         */
        defaultOption: {
            show: true,

            zlevel: 0,
            z: 4,

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

            seriesIndex: null,          // 所控制的series indices，默认所有有value的series.
            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: ['#bf444c', '#d88273', '#f6efa6'], //颜色（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 {boolean}
             */
            this._autoSeriesIndex = false;

            /**
             * @private
             * @type {Array.<number>}
             */
            this._dataExtent;

            /**
             * @readOnly
             */
            this.controllerVisuals = {};

            /**
             * @readOnly
             */
            this.targetVisuals = {};

            /**
             * @readOnly
             */
            this.textStyleModel;

            /**
             * [width, height]
             * @readOnly
             * @type {Array.<number>}
             */
            this.itemSize;

            this.mergeDefaultAndTheme(option, ecModel);
            this.doMergeOption({}, true);
        },

        /**
         * @public
         */
        mergeOption: function (option) {
            this.$superApply('mergeOption', arguments);
            this.doMergeOption(option, false);
        },

        /**
         * @protected
         */
        doMergeOption: function (newOption, isInit) {
            var thisOption = this.option;

            // FIXME
            // necessary?
            // Disable realtime view update if canvas is not supported.
            if (!env.canvasSupported) {
                thisOption.realtime = false;
            }

            this.textStyleModel = this.getModel('textStyle');

            this.resetItemSize();

            this.completeVisualOption();
        },

        /**
         * @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.
         * @return {string}
         * @protected
         */
        formatValueText: function(value, isCategory) {
            var option = this.option;
            var precision = option.precision;
            var dataBound = this.dataBound;
            var formatter = option.formatter;
            var isMinMax;
            var textValue;

            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 '< ' + textValue[1];
                }
                else if (value[1] === dataBound[1]) {
                    return '> ' + 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
         */
        resetTargetSeries: function (newOption, isInit) {
            var thisOption = this.option;
            var autoSeriesIndex = this._autoSeriesIndex =
                (isInit ? thisOption : newOption).seriesIndex == null;
            thisOption.seriesIndex = autoSeriesIndex
                ? [] : modelUtil.normalizeToArray(thisOption.seriesIndex);

            autoSeriesIndex && this.ecModel.eachSeries(function (seriesModel, index) {
                var data = seriesModel.getData();
                // FIXME
                // 只考虑了list，还没有考虑map等。

                // FIXME
                // 这里可能应该这么判断：data.dimensions中有超出其所属coordSystem的量。
                if (data.type === 'list') {
                    thisOption.seriesIndex.push(index);
                }
            });
        },

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

        /**
         * @protected
         */
        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
         */
        resetVisual: function (fillVisualOption) {
            var dataExtent = this.getExtent();

            doReset.call(this, 'controller', this.controllerVisuals);
            doReset.call(this, 'target', this.targetVisuals);

            function doReset(baseAttr, visualMappings) {
                each(this.stateList, function (state) {
                    var mappings = visualMappings[state] || (visualMappings[state] = {});
                    var visaulOption = this.option[baseAttr][state] || {};
                    each(visaulOption, function (visualData, visualType) {
                        if (!VisualMapping.isValidType(visualType)) {
                            return;
                        }
                        var mappingOption = {
                            type: visualType,
                            dataExtent: dataExtent,
                            visual: visualData
                        };
                        fillVisualOption && fillVisualOption.call(this, mappingOption, state);
                        mappings[visualType] = new VisualMapping(mappingOption);
                    }, this);
                }, this);
            }
        },

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

                // 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) {
                        var defa = visualDefault.get(visualType, 'inactive', isCategory);
                        if (VisualMapping.isValidType(visualType) && defa) {
                            optAbsent[visualType] = defa;
                        }
                    });
                }
            }

            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) {
                        visuals.symbol = symbolExists
                            && zrUtil.clone(symbolExists)
                            || (isCategory ? 'roundRect' : ['roundRect']);
                    }
                    if (!visuals.symbolSize) {
                        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) {
                        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);
            }
        },

        /**
         * @public
         */
        eachTargetSeries: function (callback, context) {
            zrUtil.each(this.option.seriesIndex, function (seriesIndex) {
                callback.call(context, this.ecModel.getSeriesByIndex(seriesIndex));
            }, this);
        },

        /**
         * @public
         */
        isCategory: function () {
            return !!this.option.categories;
        },

        /**
         * @protected
         */
        resetItemSize: function () {
            this.itemSize = [
                parseFloat(this.get('itemWidth')),
                parseFloat(this.get('itemHeight'))
            ];
        },

        /**
         * @public
         * @abstract
         */
        setSelected: zrUtil.noop,

        /**
         * @public
         * @abstract
         */
        getValueState: zrUtil.noop

    });

});

/**
 * @file Data zoom model
 */
define('echarts/component/visualMap/ContinuousModel',['require','./VisualMapModel','zrender/core/util','../../util/number'],function(require) {

    var VisualMapModel = require('./VisualMapModel');
    var zrUtil = require('zrender/core/util');
    var numberUtil = require('../../util/number');

    // Constant
    var DEFAULT_BAR_BOUND = [20, 140];

    return VisualMapModel.extend({

        type: 'visualMap.continuous',

        /**
         * @protected
         */
        defaultOption: {
            handlePosition: 'auto',     // 'auto', 'left', 'right', 'top', 'bottom'
            calculable: false,         // 是否值域漫游，启用后无视splitNumber和pieces，线性渐变
            range: [-Infinity, Infinity], // 当前选中范围
            hoverLink: true,
            realtime: true,
            itemWidth: null,            // 值域图形宽度
            itemHeight: null            // 值域图形高度
        },

        /**
         * @override
         */
        doMergeOption: function (newOption, isInit) {
            this.$superApply('doMergeOption', arguments);

            this.resetTargetSeries(newOption, isInit);
            this.resetExtent();

            this.resetVisual(function (mappingOption) {
                mappingOption.mappingMethod = 'linear';
            });

            this._resetRange();
        },

        /**
         * @protected
         * @override
         */
        resetItemSize: function () {
            VisualMapModel.prototype.resetItemSize.apply(this, 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[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);
        },

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

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

    });

});
define('echarts/component/visualMap/VisualMapView',['require','../../echarts','zrender/core/util','../../util/graphic','../../util/format','../../util/layout','../../visual/VisualMapping'],function (require) {

    var echarts = require('../../echarts');
    var zrUtil = require('zrender/core/util');
    var graphic = require('../../util/graphic');
    var formatUtil = require('../../util/format');
    var layout = require('../../util/layout');
    var VisualMapping = require('../../visual/VisualMapping');

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

            /**
             * @private
             * @type {Object}
             */
            this._updatableShapes = {};
        },

        /**
         * @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|Array)} targetValue
         * @param {string=} forceState Specify state, instead of using getValueState method.
         * @param {string=} visualCluster Specify visual type, defualt all available visualClusters.
         */
        getControllerVisual: function (targetValue, forceState, visualCluster) {
            var visualMapModel = this.visualMapModel;
            var targetIsArray = zrUtil.isArray(targetValue);

            // targetValue is array when caculate gradient color,
            // where forceState is required.
            if (targetIsArray && (!forceState || visualCluster !== 'color')) {
                throw new Error(targetValue);
            }

            var mappings = visualMapModel.controllerVisuals[
                forceState || visualMapModel.getValueState(targetValue)
            ];
            var defaultColor = visualMapModel.get('contentColor');
            var visualObj = {
                symbol: visualMapModel.get('itemSymbol'),
                color: targetIsArray
                    ? [{color: defaultColor, offset: 0}, {color: defaultColor, offset: 1}]
                    : defaultColor
            };

            function getter(key) {
                return visualObj[key];
            }

            function setter(key, value) {
                visualObj[key] = value;
            }

            var visualTypes = VisualMapping.prepareVisualTypes(mappings);

            zrUtil.each(visualTypes, function (type) {
                var visualMapping = mappings[type];
                if (!visualCluster || VisualMapping.isInVisualCluster(type, visualCluster)) {
                    visualMapping && visualMapping.applyVisual(targetValue, getter, setter);
                }
            });

            return visualObj;
        },

        /**
         * @protected
         */
        positionGroup: function (group) {
            var model = this.visualMapModel;
            var api = this.api;

            layout.positionGroup(
                group,
                model.getBoxLayoutParams(),
                {width: api.getWidth(), height: api.getHeight()}
            );
        },

        /**
         * @protected
         * @abstract
         */
        doRender: zrUtil.noop

    });
});
define('echarts/component/visualMap/helper',['require','../../util/layout'],function(require) {

    var layout = require('../../util/layout');

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

    return helper;
});

define('echarts/component/visualMap/ContinuousView',['require','./VisualMapView','../../util/graphic','zrender/core/util','../../util/number','../helper/sliderMove','zrender/graphic/LinearGradient','./helper'],function(require) {

    var VisualMapView = require('./VisualMapView');
    var graphic = require('../../util/graphic');
    var zrUtil = require('zrender/core/util');
    var numberUtil = require('../../util/number');
    var sliderMove = require('../helper/sliderMove');
    var linearMap = numberUtil.linearMap;
    var LinearGradient = require('zrender/graphic/LinearGradient');
    var helper = require('./helper');
    var each = zrUtil.each;

    // 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 ContinuousVisualMapView = VisualMapView.extend({

        type: 'visualMap.continuous',

        /**
         * @override
         */
        init: function () {

            VisualMapView.prototype.init.apply(this, arguments);

            /**
             * @private
             */
            this._shapes = {};

            /**
             * @private
             */
            this._dataInterval = [];

            /**
             * @private
             */
            this._handleEnds = [];

            /**
             * @private
             */
            this._orient;

            /**
             * @private
             */
            this._useHandle;
        },

        /**
         * @protected
         * @override
         */
        doRender: function (visualMapModel, ecModel, api, payload) {
            if (!payload || payload.type !== 'selectDataRange' || payload.from !== this.uid) {
                this._buildView();
            }
            else {
                this._updateView();
            }
        },

        /**
         * @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.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],
                    textBaseline: 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,
                zrUtil.bind(this._modifyHandle, this, 'all'),
                useHandle ? 'move' : null
            ));

            var textRect = visualMapModel.textStyleModel.getTextRect('国');
            var textSize = Math.max(textRect.width, textRect.height);

            // Handle
            if (useHandle) {
                shapes.handleGroups = [];
                shapes.handleThumbs = [];
                shapes.handleLabels = [];
                shapes.handleLabelPoints = [];

                this._createHandle(barGroup, 0, itemSize, textSize, orient, itemAlign);
                this._createHandle(barGroup, 1, itemSize, textSize, orient, itemAlign);
            }

            // Indicator
            // FIXME

            targetGroup.add(barGroup);
        },

        /**
         * @private
         */
        _createHandle: function (barGroup, handleIndex, itemSize, textSize, orient) {
            var handleGroup = new graphic.Group({position: [itemSize[0], 0]});
            var handleThumb = createPolygon(
                createHandlePoints(handleIndex, textSize),
                zrUtil.bind(this._modifyHandle, this, handleIndex),
                'move'
            );
            handleGroup.add(handleThumb);

            // For text locating. Text is always horizontal layout
            // but should not be effected by transform.
            var handleLabelPoint = {
                x: orient === 'horizontal'
                    ? textSize / 2
                    : textSize * 1.5,
                y: orient === 'horizontal'
                    ? (handleIndex === 0 ? -(textSize * 1.5) : (textSize * 1.5))
                    : (handleIndex === 0 ? -textSize / 2 : textSize / 2)
            };

            var textStyleModel = this.visualMapModel.textStyleModel;
            var handleLabel = new graphic.Text({
                silent: true,
                style: {
                    x: 0, y: 0, text: '',
                    textBaseline: 'middle',
                    textFont: textStyleModel.getFont(),
                    fill: textStyleModel.getTextColor()
                }
            });

            this.group.add(handleLabel); // Text do not transform

            var shapes = this._shapes;
            shapes.handleThumbs[handleIndex] = handleThumb;
            shapes.handleGroups[handleIndex] = handleGroup;
            shapes.handleLabelPoints[handleIndex] = handleLabelPoint;
            shapes.handleLabels[handleIndex] = handleLabel;

            barGroup.add(handleGroup);
        },

        /**
         * @private
         */
        _modifyHandle: function (handleIndex, dx, dy) {
            if (!this._useHandle) {
                return;
            }

            // Transform dx, dy to bar coordination.
            var vertex = this._applyTransform([dx, dy], this._shapes.barGroup, true);
            this._updateInterval(handleIndex, vertex[1]);

            this.api.dispatchAction({
                type: 'selectDataRange',
                from: this.uid,
                visualMapId: this.visualMapModel.id,
                selected: this._dataInterval.slice()
            });
        },

        /**
         * @private
         */
        _resetInterval: function () {
            var visualMapModel = this.visualMapModel;

            var dataInterval = this._dataInterval = visualMapModel.getSelected();

            this._handleEnds = linearMap(
                dataInterval,
                visualMapModel.getExtent(),
                [0, visualMapModel.itemSize[1]],
                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;

            sliderMove(
                delta,
                handleEnds,
                [0, visualMapModel.itemSize[1]],
                handleIndex === 'all' ? 'rigid' : 'push',
                handleIndex
            );

            // Update data interval.
            this._dataInterval = linearMap(
                handleEnds,
                [0, visualMapModel.itemSize[1]],
                visualMapModel.getExtent(),
                true
            );
        },

        /**
         * @private
         */
        _updateView: function (forSketch) {
            var visualMapModel = this.visualMapModel;
            var dataExtent = visualMapModel.getExtent();
            var shapes = this._shapes;
            var dataInterval = this._dataInterval;

            var outOfRangeHandleEnds = [0, visualMapModel.itemSize[1]];
            var inRangeHandleEnds = forSketch ? outOfRangeHandleEnds : this._handleEnds;

            var visualInRange = this._createBarVisual(
                dataInterval, dataExtent, inRangeHandleEnds, 'inRange'
            );
            var visualOutOfRange = this._createBarVisual(
                dataExtent, dataExtent, outOfRangeHandleEnds, 'outOfRange'
            );

            shapes.inRange
                .setStyle('fill', visualInRange.barColor)
                .setShape('points', visualInRange.barPoints);
            shapes.outOfRange
                .setStyle('fill', visualOutOfRange.barColor)
                .setShape('points', visualOutOfRange.barPoints);

            this._useHandle && each([0, 1], function (handleIndex) {

                shapes.handleThumbs[handleIndex].setStyle(
                    'fill', visualInRange.handlesColor[handleIndex]
                );

                shapes.handleLabels[handleIndex].setStyle({
                    text: visualMapModel.formatValueText(dataInterval[handleIndex]),
                    textAlign: this._applyTransform(
                        this._orient === 'horizontal'
                            ? (handleIndex === 0 ? 'bottom' : 'top')
                            : 'left',
                        shapes.barGroup
                    )
                });

            }, this);

            this._updateHandlePosition(inRangeHandleEnds);
        },

        /**
         * @private
         */
        _createBarVisual: function (dataInterval, dataExtent, handleEnds, forceState) {
            var colorStops = this.getControllerVisual(dataInterval, forceState, 'color').color;

            var symbolSizes = [
                this.getControllerVisual(dataInterval[0], forceState, 'symbolSize').symbolSize,
                this.getControllerVisual(dataInterval[1], forceState, 'symbolSize').symbolSize
            ];
            var barPoints = this._createBarPoints(handleEnds, symbolSizes);

            return {
                barColor: new LinearGradient(0, 0, 1, 1, colorStops),
                barPoints: barPoints,
                handlesColor: [
                    colorStops[0].color,
                    colorStops[colorStops.length - 1].color
                ]
            };
        },

        /**
         * @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
         */
        _updateHandlePosition: function (handleEnds) {
            if (!this._useHandle) {
                return;
            }

            var shapes = this._shapes;

            each([0, 1], function (handleIndex) {
                var handleGroup = shapes.handleGroups[handleIndex];
                handleGroup.position[1] = handleEnds[handleIndex];

                // Update handle label position.
                var labelPoint = shapes.handleLabelPoints[handleIndex];
                var textPoint = graphic.applyTransform(
                    [labelPoint.x, labelPoint.y],
                    graphic.getTransform(handleGroup, this.group)
                );

                shapes.handleLabels[handleIndex].setStyle({
                    x: textPoint[0], y: textPoint[1]
                });
            }, this);
        },

        /**
         * @private
         */
        _applyTransform: function (vertex, element, inverse) {
            var transform = graphic.getTransform(element, this.group);

            return graphic[
                zrUtil.isArray(vertex)
                    ? 'applyTransform' : 'transformDirection'
            ](vertex, transform, inverse);
        }

    });

    function createPolygon(points, onDrift, cursor) {
        return new graphic.Polygon({
            shape: {points: points},
            draggable: !!onDrift,
            cursor: cursor,
            drift: onDrift
        });
    }

    function createHandlePoints(handleIndex, textSize) {
        return handleIndex === 0
            ? [[0, 0], [textSize, 0], [textSize, -textSize]]
            : [[0, 0], [textSize, 0], [textSize, textSize]];
    }

    return ContinuousVisualMapView;
});

/**
 * @file Data range action
 */
define('echarts/component/visualMap/visualMapAction',['require','../../echarts'],function(require) {

    var echarts = require('../../echarts');

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

    });

});
/**
 * DataZoom component entry
 */
define('echarts/component/visualMapContinuous',['require','../echarts','./visualMap/preprocessor','./visualMap/typeDefaulter','./visualMap/visualCoding','./visualMap/ContinuousModel','./visualMap/ContinuousView','./visualMap/visualMapAction'],function (require) {

    require('../echarts').registerPreprocessor(
        require('./visualMap/preprocessor')
    );

    require('./visualMap/typeDefaulter');
    require('./visualMap/visualCoding');
    require('./visualMap/ContinuousModel');
    require('./visualMap/ContinuousView');
    require('./visualMap/visualMapAction');

});
define('echarts/component/visualMap/PiecewiseModel',['require','./VisualMapModel','zrender/core/util','../../visual/VisualMapping'],function(require) {

    var VisualMapModel = require('./VisualMapModel');
    var zrUtil = require('zrender/core/util');
    var VisualMapping = require('../../visual/VisualMapping');

    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.
            align: 'auto',              // 'auto', 'left', 'right'
            itemWidth: 20,              // 值域图形宽度
            itemHeight: 14,             // 值域图形高度
            itemSymbol: 'roundRect',
            pieceList: null,            // 值顺序：由高到低, item can be:
                                        // {min, max, value, color, colorSaturation, colorAlpha, symbol, symbolSize}
            categories: null,           // 描述 category 数据。如：['some1', 'some2', 'some3']，设置后，min max失效。
            splitNumber: 5,             // 分割段数，默认为5，为0时为线性渐变 (continous)
            selectedMode: 'multiple',
            itemGap: 10                 // 各个item之间的间隔，单位px，默认为10，
                                        // 横向布局时为水平间隔，纵向布局时为纵向间隔
        },

        /**
         * @override
         */
        doMergeOption: function (newOption, isInit) {
            this.$superApply('doMergeOption', arguments);

            /**
             * The order is always [low, ..., high].
             * [{text: string, interval: Array.<number>}, ...]
             * @private
             * @type {Array.<Object>}
             */
            this._pieceList = [];

            this.resetTargetSeries(newOption, isInit);
            this.resetExtent();

            /**
             * 'pieces', 'categories', 'splitNumber'
             * @type {string}
             */
            var mode = this._mode = this._decideMode();

            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.mappingMethod = 'piecewise';
                    mappingOption.pieceList = zrUtil.map(this._pieceList, function (piece) {
                        var piece = zrUtil.clone(piece);
                        if (state !== 'inRange') {
                            piece.visual = null;
                        }
                        return piece;
                    });
                }
            });
        },

        _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 (!(key in selected)) {
                    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}
         */
        _decideMode: 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 pieceList = this._pieceList;
            var index = VisualMapping.findPieceIndex(value, pieceList);

            return index != null
                ? (this.option.selected[this.getSelectedMapKey(pieceList[index])]
                    ? 'inRange' : 'outOfRange'
                )
                : 'outOfRange';
        }

    });

    /**
     * Key is this._mode
     * @type {Object}
     * @this {module:echarts/component/viusalMap/PiecewiseMode}
     */
    var resetMethods = {

        splitNumber: function () {
            var thisOption = this.option;
            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);

            for (var i = 0, curr = dataExtent[0]; i < splitNumber; i++, curr += splitStep) {
                var max = i === splitNumber - 1 ? dataExtent[1] : (curr + splitStep);

                this._pieceList.push({
                    text: this.formatValueText([curr, max]),
                    index: i,
                    interval: [curr, max]
                });
            }
        },

        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;
            zrUtil.each(thisOption.pieces, function (pieceListItem, index) {

                if (!zrUtil.isObject(pieceListItem)) {
                    pieceListItem = {value: pieceListItem};
                }

                var item = {text: '', index: index};
                var hasLabel;

                if (pieceListItem.label != null) {
                    item.text = pieceListItem.label;
                    hasLabel = true;
                }

                if (pieceListItem.hasOwnProperty('value')) {
                    item.value = pieceListItem.value;

                    if (!hasLabel) {
                        item.text = this.formatValueText(item.value);
                    }
                }
                else {
                    var min = pieceListItem.min;
                    var max = pieceListItem.max;
                    min == null && (min = -Infinity);
                    max == null && (max = Infinity);
                    if (min === max) {
                        // Consider: [{min: 5, max: 5, visual: {...}}, {min: 0, max: 5}],
                        // we use value to lift the priority when min === max
                        item.value = min;
                    }
                    item.interval = [min, max];

                    if (!hasLabel) {
                        item.text = this.formatValueText([min, max]);
                    }
                }

                item.visual = VisualMapping.retrieveVisuals(pieceListItem);

                this._pieceList.push(item);

            }, this);

            // See "Order Rule".
            normalizeReverse(thisOption, this._pieceList);
        }
    };

    function normalizeReverse(thisOption, arr) {
        var inverse = thisOption.inverse;
        if (thisOption.orient === 'vertical' ? !inverse : inverse) {
             arr.reverse();
        }
    }

    return PiecewiseModel;
});

define('echarts/component/visualMap/PiecewiseView',['require','./VisualMapView','zrender/core/util','../../util/graphic','../../util/symbol','../../util/layout','./helper'],function(require) {

    var VisualMapView = require('./VisualMapView');
    var zrUtil = require('zrender/core/util');
    var graphic = require('../../util/graphic');
    var symbolCreators = require('../../util/symbol');
    var layout = require('../../util/layout');
    var helper = require('./helper');

    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 showLabel = !viewData.endsText;
            var showEndsText = !showLabel;

            showEndsText && this._renderEndsText(thisGroup, viewData.endsText[0], itemSize);

            zrUtil.each(viewData.pieceList, renderItem, this);

            showEndsText && this._renderEndsText(thisGroup, viewData.endsText[1], itemSize);

            layout.box(
                visualMapModel.get('orient'), thisGroup, visualMapModel.get('itemGap')
            );

            this.renderBackground(thisGroup);

            this.positionGroup(thisGroup);

            function renderItem(item) {
                var itemGroup = new graphic.Group();
                itemGroup.onclick = zrUtil.bind(this._onItemClick, this, item.piece);

                this._createItemSymbol(itemGroup, item.piece, [0, 0, itemSize[0], itemSize[1]]);

                if (showLabel) {
                    itemGroup.add(new graphic.Text({
                        style: {
                            x: itemAlign === 'right' ? -textGap : itemSize[0] + textGap,
                            y: itemSize[1] / 2,
                            text: item.piece.text,
                            textBaseline: 'middle',
                            textAlign: itemAlign,
                            textFont: textFont,
                            fill: textFill
                        }
                    }));
                }

                thisGroup.add(itemGroup);
            }
        },

        /**
         * @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) {
            if (!text) {
                return;
            }
            var itemGroup = new graphic.Group();
            var textStyleModel = this.visualMapModel.textStyleModel;
            itemGroup.add(new graphic.Text({
                style: {
                    x: itemSize[0] / 2,
                    y: itemSize[1] / 2,
                    textBaseline: 'middle',
                    textAlign: '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 pieceList = zrUtil.map(visualMapModel.getPieceList(), function (piece, index) {
                return {piece: piece, index: index};
            });
            var endsText = visualMapModel.get('text');

            // Consider orient and inverse.
            var orient = visualMapModel.get('orient');
            var inverse = visualMapModel.get('inverse');

            // Order of pieceList is always [low, ..., high]
            if (orient === 'horizontal' ? inverse : !inverse) {
                pieceList.reverse();
            }
            // Origin order of endsText is [high, low]
            else if (endsText) {
                endsText = endsText.slice().reverse();
            }

            return {pieceList: pieceList, endsText: endsText};
        },

        /**
         * @private
         */
        _createItemSymbol: function (group, piece, shapeParam) {
            var representValue;
            if (this.visualMapModel.isCategory()) {
                representValue = piece.value;
            }
            else {
                if (piece.value != null) {
                    representValue = piece.value;
                }
                else {
                    var pieceInterval = piece.interval || [];
                    representValue = (pieceInterval[0] + pieceInterval[1]) / 2;
                }
            }

            var visualObj = this.getControllerVisual(representValue);

            group.add(symbolCreators.createSymbol(
                visualObj.symbol,
                shapeParam[0], shapeParam[1], shapeParam[2], shapeParam[3],
                visualObj.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
            });
        }
    });

    return PiecewiseVisualMapView;
});

/**
 * DataZoom component entry
 */
define('echarts/component/visualMapPiecewise',['require','../echarts','./visualMap/preprocessor','./visualMap/typeDefaulter','./visualMap/visualCoding','./visualMap/PiecewiseModel','./visualMap/PiecewiseView','./visualMap/visualMapAction'],function (require) {

    require('../echarts').registerPreprocessor(
        require('./visualMap/preprocessor')
    );

    require('./visualMap/typeDefaulter');
    require('./visualMap/visualCoding');
    require('./visualMap/PiecewiseModel');
    require('./visualMap/PiecewiseView');
    require('./visualMap/visualMapAction');

});
/**
 * visualMap component entry
 */
define('echarts/component/visualMap',['require','./visualMapContinuous','./visualMapPiecewise'],function (require) {

    require('./visualMapContinuous');
    require('./visualMapPiecewise');

});
define('echarts/component/marker/MarkPointModel',['require','../../model/globalDefault','../../util/model','../../echarts'],function (require) {
    // Default enable markPoint
    var globalDefault = require('../../model/globalDefault');
    var modelUtil = require('../../util/model');

    // Force to load markPoint component
    globalDefault.markPoint = {};

    var MarkPointModel = require('../../echarts').extendComponentModel({

        type: 'markPoint',

        dependencies: ['series', 'grid', 'polar'],
        /**
         * @overrite
         */
        init: function (option, parentModel, ecModel, extraOpt, createdBySelf) {
            this.mergeDefaultAndTheme(option, ecModel);
            this.mergeOption(option, createdBySelf, true);
        },

        mergeOption: function (newOpt, createdBySelf, isInit) {
            if (!createdBySelf) {
                var ecModel = this.ecModel;
                ecModel.eachSeries(function (seriesModel) {
                    var markPointOpt = seriesModel.get('markPoint');
                    var mpModel = seriesModel.markPointModel;
                    if (!markPointOpt || !markPointOpt.data) {
                        seriesModel.markPointModel = null;
                        return;
                    }
                    if (!mpModel) {
                        if (isInit) {
                            // Default label emphasis `position` and `show`
                            modelUtil.defaultEmphasis(
                                markPointOpt.label,
                                ['position', 'show', 'textStyle', 'distance', 'formatter']
                            );
                        }
                        var opt = {
                            // Use the same series index and name
                            seriesIndex: seriesModel.seriesIndex,
                            name: seriesModel.name
                        };
                        mpModel = new MarkPointModel(
                            markPointOpt, this, ecModel, opt, true
                        );
                    }
                    else {
                        mpModel.mergeOption(markPointOpt, true);
                    }
                    seriesModel.markPointModel = mpModel;
                }, this);
            }
        },

        defaultOption: {
            zlevel: 0,
            z: 5,
            symbol: 'pin',         // 标注类型
            symbolSize: 50,  // 标注大小
            // symbolRotate: null, // 标注旋转控制
            tooltip: {
                trigger: 'item'
            },
            label: {
                normal: {
                    show: true,
                    // 标签文本格式器，同Tooltip.formatter，不支持回调
                    // formatter: null,
                    // 可选为'left'|'right'|'top'|'bottom'
                    position: 'inside'
                    // 默认使用全局文本样式，详见TEXTSTYLE
                    // textStyle: null
                },
                emphasis: {
                    show: true
                    // 标签文本格式器，同Tooltip.formatter，不支持回调
                    // formatter: null,
                    // position: 'inside'  // 'left'|'right'|'top'|'bottom'
                    // textStyle: null     // 默认使用全局文本样式，详见TEXTSTYLE
                }
            },
            itemStyle: {
                normal: {
                    // color: 各异，
                    // 标注边线颜色，优先于color
                    // borderColor: 各异,
                    // 标注边线线宽，单位px，默认为1
                    borderWidth: 2
                },
                emphasis: {
                    // color: 各异
                }
            }
        }
    });

    return MarkPointModel;
});
define('echarts/component/marker/markerHelper',['require','zrender/core/util','../../util/number'],function (require) {

    var zrUtil = require('zrender/core/util');
    var numberUtil = require('../../util/number');

    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(percent, data, baseAxisDim, valueAxisDim, valueIndex) {
        var extent = data.getDataExtent(valueAxisDim);
        var coordArr = [];
        var min = extent[0];
        var max = extent[1];
        var val = (max - min) * percent + min;
        var dataIndex = data.indexOfNearest(valueAxisDim, val);
        coordArr[1 - valueIndex] = data.get(baseAxisDim, dataIndex);
        coordArr[valueIndex] = data.get(valueAxisDim, dataIndex, true);

        var precision = getPrecision(data, valueAxisDim, dataIndex);
        if (precision >= 0) {
            coordArr[valueIndex] = +coordArr[valueIndex].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, 0),
        /**
         * @method
         * @param {module:echarts/data/List} data
         * @param {string} baseAxisDim
         * @param {string} valueAxisDim
         */
        max: curry(markerTypeCalculatorWithExtent, 1),
        /**
         * @method
         * @param {module:echarts/data/List} data
         * @param {string} baseAxisDim
         * @param {string} valueAxisDim
         */
        average: curry(markerTypeCalculatorWithExtent, 0.5)
    };

    /**
     * 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/data/List} data
     * @param  {module:echarts/coord/*} [coordSys]
     * @param  {Object} item
     * @return {Object}
     */
    var dataTransform = function (data, coordSys, item) {
        // 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
        if ((isNaN(item.x) || isNaN(item.y))
            && !zrUtil.isArray(item.coord)
            && coordSys
        ) {
            var valueAxisDim;
            var baseAxisDim;
            var valueAxis;
            var baseAxis;
            if (item.valueIndex != null) {
                valueAxisDim = coordSys.dimensions[item.valueIndex];
                baseAxisDim = coordSys.dimensions[1 - item.valueIndex];
                valueAxis = coordSys.getAxis(valueAxisDim);
                baseAxis = coordSys.getAxis(baseAxisDim);
            }
            else {
                baseAxis = coordSys.getBaseAxis();
                valueAxis = coordSys.getOtherAxis(baseAxis);
                baseAxisDim = baseAxis.dim;
                valueAxisDim = valueAxis.dim;
            }
            var valueIndex = item.valueIndex != null
                ? item.valueIndex
                : ((valueAxisDim === 'angle' || valueAxisDim === 'x') ? 0 : 1);
            // Clone the option
            // Transform the properties xAxis, yAxis, radiusAxis, angleAxis, geoCoord to value
            item = zrUtil.extend({}, item);
            if (item.type && markerTypeCalculator[item.type] && baseAxis && valueAxis) {
                item.coord = markerTypeCalculator[item.type](
                    data, baseAxis.dim, valueAxisDim, valueIndex
                );
            }
            else {
                // FIXME Only has one of xAxis and yAxis.
                item.coord = [
                    item.xAxis != null ? item.xAxis : item.radiusAxis,
                    item.yAxis != null ? item.yAxis : item.angleAxis
                ];
            }
        }
        return item;
    };


    /**
     * 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 && item.coord && (item.x == null || item.y == null))
            ? 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];
        }
        else {
            item.value;
        }
    };

    return {
        dataTransform: dataTransform,
        dataFilter: dataFilter,
        dimValueGetter: dimValueGetter
    };
});
define('echarts/component/marker/MarkPointView',['require','../../chart/helper/SymbolDraw','zrender/core/util','../../util/format','../../util/model','../../util/number','../../data/List','./markerHelper','../../echarts'],function (require) {

    var SymbolDraw = require('../../chart/helper/SymbolDraw');
    var zrUtil = require('zrender/core/util');
    var formatUtil = require('../../util/format');
    var modelUtil = require('../../util/model');
    var numberUtil = require('../../util/number');

    var addCommas = formatUtil.addCommas;
    var encodeHTML = formatUtil.encodeHTML;

    var List = require('../../data/List');

    var markerHelper = require('./markerHelper');

    // FIXME
    var markPointFormatMixin = {
        getRawDataArray: function () {
            return this.option.data;
        },

        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);
            return this.name + '<br />'
                + ((name ? encodeHTML(name) + ' : ' : '') + formattedValue);
        },

        getData: function () {
            return this._data;
        },

        setData: function (data) {
            this._data = data;
        }
    };

    zrUtil.defaults(markPointFormatMixin, modelUtil.dataFormatMixin);

    require('../../echarts').extendComponentView({

        type: 'markPoint',

        init: function () {
            this._symbolDrawMap = {};
        },

        render: function (markPointModel, ecModel, api) {
            var symbolDrawMap = this._symbolDrawMap;
            for (var name in symbolDrawMap) {
                symbolDrawMap[name].__keep = false;
            }

            ecModel.eachSeries(function (seriesModel) {
                var mpModel = seriesModel.markPointModel;
                mpModel && this._renderSeriesMP(seriesModel, mpModel, api);
            }, this);

            for (var name in symbolDrawMap) {
                if (!symbolDrawMap[name].__keep) {
                    symbolDrawMap[name].remove();
                    this.group.remove(symbolDrawMap[name].group);
                }
            }
        },

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

            var symbolDrawMap = this._symbolDrawMap;
            var symbolDraw = symbolDrawMap[seriesName];
            if (!symbolDraw) {
                symbolDraw = symbolDrawMap[seriesName] = new SymbolDraw();
            }

            var mpData = createList(coordSys, seriesData, mpModel);
            var dims = coordSys && coordSys.dimensions;

            // FIXME
            zrUtil.mixin(mpModel, markPointFormatMixin);
            mpModel.setData(mpData);

            mpData.each(function (idx) {
                var itemModel = mpData.getItemModel(idx);
                var point;
                var xPx = itemModel.getShallow('x');
                var yPx = itemModel.getShallow('y');
                if (xPx != null && yPx != null) {
                    point = [
                        numberUtil.parsePercent(xPx, api.getWidth()),
                        numberUtil.parsePercent(yPx, api.getHeight())
                    ];
                }
                else if (coordSys) {
                    var x = mpData.get(dims[0], idx);
                    var y = mpData.get(dims[1], idx);
                    point = coordSys.dataToPoint([x, y]);
                }

                mpData.setItemLayout(idx, point);

                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.hostModel = mpModel;
                });
            });

            symbolDraw.__keep = true;
        }
    });

    /**
     * @inner
     * @param {module:echarts/coord/*} [coordSys]
     * @param {module:echarts/data/List} seriesData
     * @param {module:echarts/model/Model} mpModel
     */
    function createList (coordSys, seriesData, mpModel) {
        var dataDimensions = seriesData.dimensions;

        var mpData = new List(zrUtil.map(
            dataDimensions, seriesData.getDimensionInfo, seriesData
        ), mpModel);

        if (coordSys) {
            mpData.initData(
                zrUtil.filter(
                    zrUtil.map(mpModel.get('data'), zrUtil.curry(
                        markerHelper.dataTransform, seriesData, coordSys
                    )),
                    zrUtil.curry(markerHelper.dataFilter, coordSys)
                ),
                null,
                markerHelper.dimValueGetter
            );
        }

        return mpData;
    }
});
// HINT Markpoint can't be used too much

define('echarts/component/markPoint',['require','./marker/MarkPointModel','./marker/MarkPointView'],function (require) {

    require('./marker/MarkPointModel');

    require('./marker/MarkPointView');
});
define('echarts/component/marker/MarkLineModel',['require','../../model/globalDefault','../../util/model','../../echarts'],function (require) {

    // Default enable markLine
    var globalDefault = require('../../model/globalDefault');
    var modelUtil = require('../../util/model');

    // Force to load markLine component
    globalDefault.markLine = {};

    var MarkLineModel = require('../../echarts').extendComponentModel({

        type: 'markLine',

        dependencies: ['series', 'grid', 'polar'],
        /**
         * @overrite
         */
        init: function (option, parentModel, ecModel, extraOpt, createdBySelf) {
            this.mergeDefaultAndTheme(option, ecModel);
            this.mergeOption(option, createdBySelf, true);
        },

        mergeOption: function (newOpt, createdBySelf, isInit) {
            if (!createdBySelf) {
                var ecModel = this.ecModel;
                ecModel.eachSeries(function (seriesModel) {
                    var markLineOpt = seriesModel.get('markLine');
                    var mlModel = seriesModel.markLineModel;
                    if (!markLineOpt || !markLineOpt.data) {
                        seriesModel.markLineModel = null;
                        return;
                    }
                    if (!mlModel) {
                        if (isInit) {
                            // Default label emphasis `position` and `show`
                            modelUtil.defaultEmphasis(
                                markLineOpt.label,
                                ['position', 'show', 'textStyle', 'distance', 'formatter']
                            );
                        }
                        var opt = {
                            // Use the same series index and name
                            seriesIndex: seriesModel.seriesIndex,
                            name: seriesModel.name
                        };
                        mlModel = new MarkLineModel(
                            markLineOpt, this, ecModel, opt, true
                        );
                    }
                    else {
                        mlModel.mergeOption(markLineOpt, true);
                    }
                    seriesModel.markLineModel = mlModel;
                }, this);
            }
        },

        defaultOption: {
            zlevel: 0,
            z: 5,
            // 标线起始和结束的symbol介绍类型，如果都一样，可以直接传string
            symbol: ['circle', 'arrow'],
            // 标线起始和结束的symbol大小，半宽（半径）参数，当图形为方向或菱形则总宽度为symbolSize * 2
            symbolSize: [8, 16],
            // 标线起始和结束的symbol旋转控制
            //symbolRotate: null,
            //smooth: false,
            precision: 2,
            tooltip: {
                trigger: 'item'
            },
            label: {
                normal: {
                    show: true,
                    // 标签文本格式器，同Tooltip.formatter，不支持回调
                    // formatter: null,
                    // 可选为 'start'|'end'|'left'|'right'|'top'|'bottom'
                    position: 'end'
                    // 默认使用全局文本样式，详见TEXTSTYLE
                    // textStyle: null
                },
                emphasis: {
                    show: true
                }
            },
            lineStyle: {
                normal: {
                    // color
                    // width
                    type: 'dashed'
                    // shadowColor: 'rgba(0,0,0,0)',
                    // shadowBlur: 0,
                    // shadowOffsetX: 0,
                    // shadowOffsetY: 0
                },
                emphasis: {
                    width: 3
                }
            },
            animationEasing: 'linear'
        }
    });

    return MarkLineModel;
});
define('echarts/component/marker/MarkLineView',['require','zrender/core/util','../../data/List','../../util/format','../../util/model','../../util/number','./markerHelper','../../chart/helper/LineDraw','../../echarts'],function (require) {

    var zrUtil = require('zrender/core/util');
    var List = require('../../data/List');
    var formatUtil = require('../../util/format');
    var modelUtil = require('../../util/model');
    var numberUtil = require('../../util/number');

    var addCommas = formatUtil.addCommas;
    var encodeHTML = formatUtil.encodeHTML;

    var markerHelper = require('./markerHelper');

    var LineDraw = require('../../chart/helper/LineDraw');

    var markLineTransform = function (data, coordSys, baseAxis, valueAxis, item) {
        // Special type markLine like 'min', 'max', 'average'
        var mlType = item.type;
        if (!zrUtil.isArray(item)
            && mlType === 'min' || mlType === 'max' || mlType === 'average'
        ) {
            if (item.valueIndex != null) {
                baseAxis = coordSys.getAxis(coordSys.dimensions[1 - item.valueIndex]);
                valueAxis = coordSys.getAxis(coordSys.dimensions[item.valueIndex]);
            }
            var baseAxisKey = baseAxis.dim + 'Axis';
            var valueAxisKey = valueAxis.dim + 'Axis';
            var baseScaleExtent = baseAxis.scale.getExtent();

            var mlFrom = zrUtil.extend({}, item);
            var mlTo = {};

            var extent = data.getDataExtent(valueAxis.dim, true);

            mlFrom.type = null;

            // FIXME Polar should use circle
            mlFrom[baseAxisKey] = baseScaleExtent[0];
            mlTo[baseAxisKey] = baseScaleExtent[1];

            var percent = mlType === 'average' ?
                0.5 : (mlType === 'max' ? 1 : 0);

            var value = (extent[1] - extent[0]) * percent + extent[0];
            // Round if axis is cateogry
            value = valueAxis.coordToData(valueAxis.dataToCoord(value));

            mlFrom[valueAxisKey] = mlTo[valueAxisKey] = value;

            item = [mlFrom, mlTo, { // Extra option for tooltip and label
                type: mlType
            }];
        }
        item = [
            markerHelper.dataTransform(data, coordSys, item[0]),
            markerHelper.dataTransform(data, coordSys, item[1]),
            {}
        ];

        // Merge from option and to option into line option
        zrUtil.merge(item[2], item[0]);
        zrUtil.merge(item[2], item[1]);

        return item;
    };

    function markLineFilter(coordSys, item) {
        return markerHelper.dataFilter(coordSys, item[0])
            && markerHelper.dataFilter(coordSys, item[1]);
    }

    var markLineFormatMixin = {
        formatTooltip: function (dataIndex) {
            var data = this._data;
            var value = this.getRawValue(dataIndex);
            var formattedValue = zrUtil.isArray(value)
                ? zrUtil.map(value, addCommas).join(', ') : addCommas(value);
            var name = data.getName(dataIndex);
            return this.name + '<br />'
                + ((name ? encodeHTML(name) + ' : ' : '') + formattedValue);
        },

        getRawDataArray: function () {
            return this.option.data;
        },

        getData: function () {
            return this._data;
        },

        setData: function (data) {
            this._data = data;
        }
    };

    zrUtil.defaults(markLineFormatMixin, modelUtil.dataFormatMixin);

    require('../../echarts').extendComponentView({

        type: 'markLine',

        init: function () {
            /**
             * Markline grouped by series
             * @private
             * @type {Object}
             */
            this._markLineMap = {};
        },

        render: function (markLineModel, ecModel, api) {
            var lineDrawMap = this._markLineMap;
            for (var name in lineDrawMap) {
                lineDrawMap[name].__keep = false;
            }

            ecModel.eachSeries(function (seriesModel) {
                var mlModel = seriesModel.markLineModel;
                mlModel && this._renderSeriesML(seriesModel, mlModel, ecModel, api);
            }, this);

            for (var name in lineDrawMap) {
                if (!lineDrawMap[name].__keep) {
                    this.group.remove(lineDrawMap[name].group);
                }
            }
        },

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

            var lineDrawMap = this._markLineMap;
            var lineDraw = lineDrawMap[seriesName];
            if (!lineDraw) {
                lineDraw = lineDrawMap[seriesName] = new LineDraw();
            }
            this.group.add(lineDraw.group);

            var mlData = createList(coordSys, seriesData, mlModel);
            var dims = coordSys.dimensions;

            var fromData = mlData.from;
            var toData = mlData.to;
            var lineData = mlData.line;

            // Line data for tooltip and formatter
            zrUtil.extend(mlModel, markLineFormatMixin);
            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);
            });

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

            lineDraw.updateData(lineData, fromData, toData);

            // Set host model for tooltip
            // FIXME
            mlData.line.eachItemGraphicEl(function (el, idx) {
                el.traverse(function (child) {
                    child.hostModel = mlModel;
                });
            });

            function updateDataVisualAndLayout(data, idx, isFrom) {
                var itemModel = data.getItemModel(idx);

                var point;
                var xPx = itemModel.get('x');
                var yPx = itemModel.get('y');
                if (xPx != null && yPx != null) {
                    point = [
                        numberUtil.parsePercent(xPx, api.getWidth()),
                        numberUtil.parsePercent(yPx, api.getHeight())
                    ];
                }
                else {
                    var x = data.get(dims[0], idx);
                    var y = data.get(dims[1], idx);
                    point = coordSys.dataToPoint([x, y]);
                }

                data.setItemLayout(idx, point);

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

    /**
     * @inner
     * @param {module:echarts/coord/*} coordSys
     * @param {module:echarts/data/List} seriesData
     * @param {module:echarts/model/Model} mpModel
     */
    function createList(coordSys, seriesData, mlModel) {
        // var dataDimensions = seriesData.dimensions;
        // var dimensionInfosMap = zrUtil.map(
        //         dataDimensions, seriesData.getDimensionInfo, seriesData
        //     );

        // Mark line get the dimensions from coordinate system
        // Because user specify the data by xAxis, yAxis
        var dimensions = coordSys.dimensions;
        var fromData = new List(dimensions, mlModel);
        var toData = new List(dimensions, mlModel);
        // No dimensions
        var lineData = new List([], mlModel);

        if (coordSys) {
            var baseAxis = coordSys.getBaseAxis();
            var valueAxis = coordSys.getOtherAxis(baseAxis);

            var optData = zrUtil.filter(
                zrUtil.map(mlModel.get('data'), zrUtil.curry(
                    markLineTransform, seriesData, coordSys, baseAxis, valueAxis
                )),
                zrUtil.curry(markLineFilter, coordSys)
            );
            fromData.initData(
                zrUtil.map(optData, function (item) { return item[0]; }),
                null,
                markerHelper.dimValueGetter
            );
            toData.initData(
                zrUtil.map(optData, function (item) { return item[1]; }),
                null,
                markerHelper.dimValueGetter
            );
            lineData.initData(
                zrUtil.map(optData, function (item) { return item[2]; })
            );

        }
        return {
            from: fromData,
            to: toData,
            line: lineData
        };
    }
});
define('echarts/component/markLine',['require','./marker/MarkLineModel','./marker/MarkLineView'],function (require) {

    require('./marker/MarkLineModel');

    require('./marker/MarkLineView');
});
/**
 * @file Timeline preprocessor
 */
define('echarts/component/timeline/preprocessor',['require','zrender/core/util'],function(require) {

    var zrUtil = require('zrender/core/util');

    return 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 = {});
        var itemStyleNormal = itemStyle.normal || (itemStyle.normal = {});

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

});
define('echarts/component/timeline/typeDefaulter',['require','../../model/Component'],function (require) {

    require('../../model/Component').registerSubTypeDefaulter('timeline', function () {
        // Only slider now.
        return 'slider';
    });

});
/**
 * @file Timeilne action
 */
define('echarts/component/timeline/timelineAction',['require','../../echarts'],function(require) {

    var echarts = require('../../echarts');

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

            ecModel.resetOption('timeline');
        }
    );

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

});
/**
 * @file Timeline model
 */
define('echarts/component/timeline/TimelineModel',['require','../../model/Component','../../data/List','zrender/core/util','../../util/model'],function(require) {

    var ComponentModel = require('../../model/Component');
    var List = require('../../data/List');
    var zrUtil = require('zrender/core/util');
    var modelUtil = require('../../util/model');

    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) {
            this.$superApply('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();
            }
        }

    });

    return TimelineModel;
});
/**
 * @file Silder timeline model
 */
define('echarts/component/timeline/SliderTimelineModel',['require','./TimelineModel'],function(require) {

    var TimelineModel = require('./TimelineModel');

    return 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: false,                    // boolean or Object
                                               // 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',
                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',
                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',
                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',
                normal: {
                    color: '#304654',
                    borderColor: '#304654',
                    borderWidth: 1
                },
                emphasis: {
                    color: '#c23531',
                    borderColor: '#c23531',
                    borderWidth: 2
                }
            },
            data: []
        }

    });

});
/**
 * @file Timeline view
 */
define('echarts/component/timeline/TimelineView',['require','../../view/Component'],function (require) {

    // var zrUtil = require('zrender/core/util');
    // var graphic = require('../../util/graphic');
    var ComponentView = require('../../view/Component');

    return ComponentView.extend({

        type: 'timeline'
    });

});
define('echarts/component/timeline/TimelineAxis',['require','zrender/core/util','../../coord/Axis','../../coord/axisHelper'],function (require) {

    var zrUtil = require('zrender/core/util');
    var Axis = require('../../coord/Axis');
    var axisHelper = require('../../coord/axisHelper');

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

    return TimelineAxis;
});
/**
 * @file Silder timeline view
 */
define('echarts/component/timeline/SliderTimelineView',['require','zrender/core/util','../../util/graphic','../../util/layout','./TimelineView','./TimelineAxis','../../util/symbol','../../coord/axisHelper','zrender/core/BoundingRect','zrender/core/matrix','../../util/number','../../util/model','../../util/format'],function (require) {

    var zrUtil = require('zrender/core/util');
    var graphic = require('../../util/graphic');
    var layout = require('../../util/layout');
    var TimelineView = require('./TimelineView');
    var TimelineAxis = require('./TimelineAxis');
    var symbolUtil = require('../../util/symbol');
    var axisHelper = require('../../coord/axisHelper');
    var BoundingRect = require('zrender/core/BoundingRect');
    var matrix = require('zrender/core/matrix');
    var numberUtil = require('../../util/number');
    var modelUtil = require('../../util/model');
    var formatUtil = require('../../util/format');
    var encodeHTML = formatUtil.encodeHTML;

    var bind = zrUtil.bind;
    var each = zrUtil.each;

    var PI = Math.PI;

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

            // var mainGroup = new graphic.Group();

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

            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.position = mainPosition;
            labelGroup.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();
            var tooltipHostModel = this._prepareTooltipHostModel(data, timelineModel);

            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.hostModel = tooltipHostModel;
                }
                else {
                    el.dataIndex = el.hostModel = null;
                }

            }, this);
        },

        /**
         * @private
         */
        _prepareTooltipHostModel: function (data, timelineModel) {
            var tooltipHostModel = modelUtil.createDataFormatModel(
                {}, data, timelineModel.get('data')
            );
            var me = this;

            tooltipHostModel.formatTooltip = function (dataIndex) {
                return encodeHTML(me._axis.scale.getLabel(dataIndex));
            };

            return tooltipHostModel;
        },

        /**
         * @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,
                        textBaseline: 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
     */
    function giveSymbol(hostModel, itemStyleModel, group, opt, symbol, callback) {
        var symbolType = hostModel.get('symbol');
        var color = itemStyleModel.get('color');
        var symbolSize = hostModel.get('symbolSize');
        var halfSymbolSize = symbolSize / 2;
        var itemStyle = itemStyleModel.getItemStyle(['color', 'symbol', 'symbolSize']);

        if (!symbol) {
            symbol = symbolUtil.createSymbol(
                symbolType, -halfSymbolSize, -halfSymbolSize, symbolSize, symbolSize, color
            );
            group.add(symbol);
            callback && callback.onCreate(symbol);
        }
        else {
            symbol.setStyle(itemStyle);
            symbol.setColor(color);
            group.add(symbol); // Group may be new, also need to add.
            callback && callback.onUpdate(symbol);
        }

        opt = zrUtil.merge({
            rectHover: true,
            style: itemStyle,
            z2: 100
        }, opt, true);

        symbol.attr(opt);

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

});
/**
 * DataZoom component entry
 */
define('echarts/component/timeline',['require','../echarts','./timeline/preprocessor','./timeline/typeDefaulter','./timeline/timelineAction','./timeline/SliderTimelineModel','./timeline/SliderTimelineView'],function (require) {

    var echarts = require('../echarts');

    echarts.registerPreprocessor(require('./timeline/preprocessor'));

    require('./timeline/typeDefaulter');
    require('./timeline/timelineAction');
    require('./timeline/SliderTimelineModel');
    require('./timeline/SliderTimelineView');

});
define('echarts/component/toolbox/featureManager',['require'],function(require) {


    var features = {};

    return {
        register: function (name, ctor) {
            features[name] = ctor;
        },

        get: function (name) {
            return features[name];
        }
    };
});
define('echarts/component/toolbox/ToolboxModel',['require','./featureManager','zrender/core/util','../../echarts'],function (require) {

    var featureManager = require('./featureManager');
    var zrUtil = require('zrender/core/util');

    require('../../echarts').extendComponentModel({

        type: 'toolbox',

        mergeDefaultAndTheme: function (option) {
            this.$superApply('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
        }
    });
});
define('echarts/component/toolbox/ToolboxView',['require','./featureManager','zrender/core/util','../../util/graphic','../../model/Model','../../data/DataDiffer','../helper/listComponent','zrender/contain/text','../../echarts'],function (require) {

    var featureManager = require('./featureManager');
    var zrUtil = require('zrender/core/util');
    var graphic = require('../../util/graphic');
    var Model = require('../../model/Model');
    var DataDiffer = require('../../data/DataDiffer');
    var listComponentHelper = require('../helper/listComponent');
    var textContain = require('zrender/contain/text');

    return require('../../echarts').extendComponentView({

        type: 'toolbox',

        render: function (toolboxModel, ecModel, api) {
            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
                    var Feature = featureManager.get(featureName);
                    if (!Feature) {
                        return;
                    }
                    features[featureName] = feature = new Feature(featureModel);
                }
                else {
                    feature = features[oldName];
                    // If not exsits feature
                    if (!feature) {
                        return;
                    }
                    feature.model = featureModel;
                }

                if (!featureName && oldName) {
                    feature.dispose && feature.dispose(ecModel, api);
                    return;
                }

                if (!featureModel.get('show')) {
                    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);
                }
            }

            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 path = graphic.makePath(
                        icon, {
                            style: normalStyle,
                            hoverStyle: hoverStyle,
                            rectHover: true
                        }, {
                            x: -itemSize / 2,
                            y: -itemSize / 2,
                            width: itemSize,
                            height: itemSize
                        }, 'center'
                    );

                    graphic.setHoverStyle(path);

                    if (toolboxModel.get('showTitle')) {
                        path.__title = titles[iconName];
                        path.on('mouseover', function () {
                                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';
                    }
                }
            });
        },

        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);
            });
        }
    });
});
define('echarts/component/toolbox/feature/SaveAsImage',['require','../featureManager'],function (require) {

    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.6\
            M29.2,45.1L29.2,0',
        title: '保存为图片',
        type: 'png',
        // Default use option.backgroundColor
        // backgroundColor: '#fff',
        name: '',
        excludeComponents: ['toolbox'],
        pixelRatio: 1
    };

    var proto = SaveAsImage.prototype;

    proto.onclick = function (ecModel, api) {
        var model = this.model;
        var title = 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';
        $a.href = api.getConnectedDataURL({
            type: type,
            backgroundColor: model.get('backgroundColor', true)
                || ecModel.get('backgroundColor') || '#fff',
            excludeComponents: model.get('excludeComponents'),
            pixelRatio: model.get('pixelRatio')
        });
        $a.click();
    };

    require('../featureManager').register(
        'saveAsImage', SaveAsImage
    );

    return SaveAsImage;
});
define('echarts/component/toolbox/feature/MagicType',['require','zrender/core/util','../../../echarts','../featureManager'],function(require) {


    var zrUtil = require('zrender/core/util');

    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',
            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')
                }, model.get('option.line'));
            }
        },
        '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')
                }, model.get('option.bar'));
            }
        },
        'stack': function (seriesType, seriesId, seriesModel, model) {
            if (seriesType === 'line' || seriesType === 'bar') {
                return {
                    id: seriesId,
                    stack: '__ec_magicType_stack__'
                };
            }
        },
        'tiled': function (seriesType, seriesId, seriesModel, model) {
            if (seriesType === 'line' || seriesType === 'bar') {
                return {
                    id: seriesId,
                    stack: ''
                };
            }
        }
    };

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

        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',
                seriesIndex: seriesIndex
            }, generateNewSeriesTypes
        );
        api.dispatchAction({
            type: 'changeMagicType',
            currentType: type,
            newOption: newOption
        });
    };

    var echarts = require('../../../echarts');
    echarts.registerAction({
        type: 'changeMagicType',
        event: 'magicTypeChanged',
        update: 'prepareAndUpdate'
    }, function (payload, ecModel) {
        ecModel.mergeOption(payload.newOption);
    });

    require('../featureManager').register('magicType', MagicType);

    return MagicType;
});
/**
 * @module echarts/component/toolbox/feature/DataView
 */

define('echarts/component/toolbox/feature/DataView',['require','zrender/core/util','zrender/core/event','../featureManager','../../../echarts'],function (require) {

    var zrUtil = require('zrender/core/util');
    var eventTool = require('zrender/core/event');


    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,
        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 textarea = document.createElement('textarea');
        // Textarea style
        textarea.style.cssText = 'display:block;width:100%;font-size:14px;line-height:1.6rem;font-family:Monaco,Consolas,Courier new,monospace';
        textarea.readOnly = model.get('readOnly');
        textarea.style.color = model.get('textColor');
        textarea.style.borderColor = model.get('textareaBorderColor');
        textarea.style.backgroundColor = model.get('textareaColor');

        var result = getContentFromModel(ecModel);
        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 {
                newOption = parseContents(textarea.value, blockMetaList);
            }
            catch (e) {
                close();
                throw new Error('Data view format error ' + e);
            }
            api.dispatchAction({
                type: 'changeDataView',
                newOption: newOption
            });

            close();
        });

        closeButton.innerHTML = lang[1];
        refreshButton.innerHTML = lang[2];
        refreshButton.style.cssText = buttonStyle;
        closeButton.style.cssText = buttonStyle;

        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(textarea);
        root.appendChild(buttonContainer);

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

    require('../featureManager').register('dataView', DataView);

    require('../../../echarts').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));
    });

    return DataView;
});
/**
 * @file History manager.
 */
define('echarts/component/dataZoom/history',['require','zrender/core/util'],function(require) {

    var zrUtil = require('zrender/core/util');
    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;
    }

    return history;

});
/**
 * @file Data zoom model
 */
define('echarts/component/dataZoom/SelectZoomModel',['require','./DataZoomModel'],function(require) {

    var DataZoomModel = require('./DataZoomModel');

    return DataZoomModel.extend({

        type: 'dataZoom.select'

    });

});
define('echarts/component/dataZoom/SelectZoomView',['require','./DataZoomView'],function (require) {

    return require('./DataZoomView').extend({

        type: 'dataZoom.select'

    });

});
/**
 * DataZoom component entry
 */
define('echarts/component/dataZoomSelect',['require','./dataZoom/typeDefaulter','./dataZoom/DataZoomModel','./dataZoom/DataZoomView','./dataZoom/SelectZoomModel','./dataZoom/SelectZoomView','./dataZoom/dataZoomProcessor','./dataZoom/dataZoomAction'],function (require) {

    require('./dataZoom/typeDefaulter');

    require('./dataZoom/DataZoomModel');
    require('./dataZoom/DataZoomView');

    require('./dataZoom/SelectZoomModel');
    require('./dataZoom/SelectZoomView');

    require('./dataZoom/dataZoomProcessor');
    require('./dataZoom/dataZoomAction');

});
define('echarts/component/toolbox/feature/DataZoom',['require','zrender/core/util','../../../util/number','../../helper/SelectController','zrender/core/BoundingRect','zrender/container/Group','../../dataZoom/history','../../helper/interactionMutex','../../dataZoomSelect','../featureManager','../../../echarts'],function(require) {


    var zrUtil = require('zrender/core/util');
    var numberUtil = require('../../../util/number');
    var SelectController = require('../../helper/SelectController');
    var BoundingRect = require('zrender/core/BoundingRect');
    var Group = require('zrender/container/Group');
    var history = require('../../dataZoom/history');
    var interactionMutex = require('../../helper/interactionMutex');

    var each = zrUtil.each;
    var asc = numberUtil.asc;

    // Use dataZoomSelect
    require('../../dataZoomSelect');

    // 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) {
        this.model = model;

        /**
         * @private
         * @type {module:zrender/container/Group}
         */
        this._controllerGroup;

        /**
         * @private
         * @type {module:echarts/component/helper/SelectController}
         */
        this._controller;

        /**
         * Is zoom active.
         * @private
         * @type {Object}
         */
        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) {
        updateBackBtnStatus(featureModel, ecModel);
    };

    proto.onclick = function (ecModel, api, type) {
        var controllerGroup = this._controllerGroup;
        if (!this._controllerGroup) {
            controllerGroup = this._controllerGroup = new Group();
            api.getZr().add(controllerGroup);
        }

        handlers[type].call(this, controllerGroup, this.model, ecModel, api);
    };

    proto.remove = function (ecModel, api) {
        this._disposeController();
        interactionMutex.release('globalPan', api.getZr());
    };

    proto.dispose = function (ecModel, api) {
        var zr = api.getZr();
        interactionMutex.release('globalPan', zr);
        this._disposeController();
        this._controllerGroup && zr.remove(this._controllerGroup);
    };

    /**
     * @private
     */
    var handlers = {

        zoom: function (controllerGroup, featureModel, ecModel, api) {
            var isZoomActive = this._isZoomActive = !this._isZoomActive;
            var zr = api.getZr();

            interactionMutex[isZoomActive ? 'take' : 'release']('globalPan', zr);

            featureModel.setIconStatus('zoom', isZoomActive ? 'emphasis' : 'normal');

            if (isZoomActive) {
                zr.setDefaultCursorStyle('crosshair');

                this._createController(
                    controllerGroup, featureModel, ecModel, api
                );
            }
            else {
                zr.setDefaultCursorStyle('default');
                this._disposeController();
            }
        },

        back: function (controllerGroup, featureModel, ecModel, api) {
            this._dispatchAction(history.pop(ecModel), api);
        }
    };

    /**
     * @private
     */
    proto._createController = function (
        controllerGroup, featureModel, ecModel, api
    ) {
        var controller = this._controller = new SelectController(
            'rect',
            api.getZr(),
            {
                // FIXME
                lineWidth: 3,
                stroke: '#333',
                fill: 'rgba(0,0,0,0.2)'
            }
        );
        controller.on(
            'selectEnd',
            zrUtil.bind(
                this._onSelected, this, controller,
                featureModel, ecModel, api
            )
        );
        controller.enable(controllerGroup, false);
    };

    proto._disposeController = function () {
        var controller = this._controller;
        if (controller) {
            controller.off('selected');
            controller.dispose();
        }
    };

    function prepareCoordInfo(grid, ecModel) {
        // Default use the first axis.
        // FIXME
        var coordInfo = [
            {axisModel: grid.getAxis('x').model, axisIndex: 0}, // x
            {axisModel: grid.getAxis('y').model, axisIndex: 0}  // y
        ];
        coordInfo.grid = grid;

        ecModel.eachComponent(
            {mainType: 'dataZoom', subType: 'select'},
            function (dzModel, dataZoomIndex) {
                if (isTheAxis('xAxis', coordInfo[0].axisModel, dzModel, ecModel)) {
                    coordInfo[0].dataZoomModel = dzModel;
                }
                if (isTheAxis('yAxis', coordInfo[1].axisModel, dzModel, ecModel)) {
                    coordInfo[1].dataZoomModel = dzModel;
                }
            }
        );

        return coordInfo;
    }

    function isTheAxis(axisName, axisModel, dataZoomModel, ecModel) {
        var axisIndex = dataZoomModel.get(axisName + 'Index');
        return axisIndex != null
            && ecModel.getComponent(axisName, axisIndex) === axisModel;
    }

    /**
     * @private
     */
    proto._onSelected = function (controller, featureModel, ecModel, api, selRanges) {
        if (!selRanges.length) {
            return;
        }
        var selRange = selRanges[0];

        controller.update(); // remove cover

        var snapshot = {};

        // FIXME
        // polar

        ecModel.eachComponent('grid', function (gridModel, gridIndex) {
            var grid = gridModel.coordinateSystem;
            var coordInfo = prepareCoordInfo(grid, ecModel);
            var selDataRange = pointToDataInCartesian(selRange, coordInfo);

            if (selDataRange) {
                var xBatchItem = scaleCartesianAxis(selDataRange, coordInfo, 0, 'x');
                var yBatchItem = scaleCartesianAxis(selDataRange, coordInfo, 1, 'y');

                xBatchItem && (snapshot[xBatchItem.dataZoomId] = xBatchItem);
                yBatchItem && (snapshot[yBatchItem.dataZoomId] = yBatchItem);
            }
        }, this);

        history.push(ecModel, snapshot);

        this._dispatchAction(snapshot, api);
    };

    function pointToDataInCartesian(selRange, coordInfo) {
        var grid = coordInfo.grid;

        var selRect = new BoundingRect(
            selRange[0][0],
            selRange[1][0],
            selRange[0][1] - selRange[0][0],
            selRange[1][1] - selRange[1][0]
        );
        if (!selRect.intersect(grid.getRect())) {
            return;
        }
        var cartesian = grid.getCartesian(coordInfo[0].axisIndex, coordInfo[1].axisIndex);
        var dataLeftTop = cartesian.pointToData([selRange[0][0], selRange[1][0]], true);
        var dataRightBottom = cartesian.pointToData([selRange[0][1], selRange[1][1]], true);

        return [
            asc([dataLeftTop[0], dataRightBottom[0]]), // x, using asc to handle inverse
            asc([dataLeftTop[1], dataRightBottom[1]]) // y, using asc to handle inverse
        ];
    }

    function scaleCartesianAxis(selDataRange, coordInfo, dimIdx, dimName) {
        var dimCoordInfo = coordInfo[dimIdx];
        var dataZoomModel = dimCoordInfo.dataZoomModel;

        return {
            dataZoomId: dataZoomModel.id,
            startValue: selDataRange[dimIdx][0],
            endValue: selDataRange[dimIdx][1]
        };
    }

    /**
     * @private
     */
    proto._dispatchAction = function (snapshot, api) {
        var batch = [];

        each(snapshot, function (batchItem) {
            batch.push(batchItem);
        });

        batch.length && api.dispatchAction({
            type: 'dataZoom',
            from: this.uid,
            batch: zrUtil.clone(batch, true)
        });
    };

    function updateBackBtnStatus(featureModel, ecModel) {
        featureModel.setIconStatus(
            'back',
            history.count(ecModel) > 1 ? 'emphasis' : 'normal'
        );
    }


    require('../featureManager').register('dataZoom', DataZoom);


    // Create special dataZoom option for select
    require('../../../echarts').registerPreprocessor(function (option) {
        if (!option) {
            return;
        }

        var dataZoomOpts = option.dataZoom || (option.dataZoom = []);
        if (!zrUtil.isArray(dataZoomOpts)) {
            dataZoomOpts = [dataZoomOpts];
        }

        // TODO
        // polar

        addForAxis('xAxis');
        addForAxis('yAxis');

        function addForAxis(axisName) {
            forEachComponent(axisName, function (axisOpt, axisIndex) {
                var newOpt = {
                    type: 'select',
                    // Id for merge mapping.
                    id: DATA_ZOOM_ID_BASE + axisName + axisIndex
                };
                // FIXME
                // Only support one axis now.
                newOpt[axisName + 'Index'] = axisIndex;
                dataZoomOpts.push(newOpt);
            });
        }

        function forEachComponent(mainType, cb) {
            var opts = option[mainType];
            if (!zrUtil.isArray(opts)) {
                opts = opts ? [opts] : [];
            }
            each(opts, cb);
        }
    });

    return DataZoom;
});
define('echarts/component/toolbox/feature/Restore',['require','../../dataZoom/history','../featureManager','../../../echarts'],function(require) {


    var history = require('../../dataZoom/history');

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


    require('../featureManager').register('restore', Restore);


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

    return Restore;
});
define('echarts/component/toolbox',['require','./toolbox/ToolboxModel','./toolbox/ToolboxView','./toolbox/feature/SaveAsImage','./toolbox/feature/MagicType','./toolbox/feature/DataView','./toolbox/feature/DataZoom','./toolbox/feature/Restore'],function (require) {

    require('./toolbox/ToolboxModel');
    require('./toolbox/ToolboxView');

    require('./toolbox/feature/SaveAsImage');
    require('./toolbox/feature/MagicType');
    require('./toolbox/feature/DataView');
    require('./toolbox/feature/DataZoom');
    require('./toolbox/feature/Restore');
});
define('zrender/vml/core',['require','../core/env'],function (require) {

    if (require('../core/env').canvasSupported) {
        return;
    }

    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
    function initVML() {
        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)')
        }
    }

    return {
        doc: doc,
        initVML: initVML,
        createNode: createNode
    };
});
// http://www.w3.org/TR/NOTE-VML
// TODO Use proxy like svg instead of overwrite brush methods
define('zrender/vml/graphic',['require','../core/env','../core/vector','../core/BoundingRect','../core/PathProxy','../tool/color','../contain/text','../graphic/mixin/RectText','../graphic/Displayable','../graphic/Image','../graphic/Text','../graphic/Path','../graphic/Gradient','./core'],function (require) {

    if (require('../core/env').canvasSupported) {
        return;
    }

    var vec2 = require('../core/vector');
    var BoundingRect = require('../core/BoundingRect');
    var CMD = require('../core/PathProxy').CMD;
    var colorTool = require('../tool/color');
    var textContain = require('../contain/text');
    var RectText = require('../graphic/mixin/RectText');
    var Displayable = require('../graphic/Displayable');
    var ZImage = require('../graphic/Image');
    var Text = require('../graphic/Text');
    var Path = require('../graphic/Path');

    var Gradient = require('../graphic/Gradient');

    var vmlCore = require('./core');

    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;

    function initRootElStyle(el) {
        el.style.cssText = 'position:absolute;left:0;top:0;width:1px;height:1px;';
        el.coordsize = Z + ','  + Z;
        el.coordorigin = '0,0';
    }

    function encodeHtmlAttribute(s) {
        return String(s).replace(/&/g, '&amp;').replace(/"/g, '&quot;');
    }

    function rgb2Str(r, g, b) {
        return 'rgb(' + [r, g, b].join(',') + ')';
    }

    function append(parent, child) {
        if (child && parent && child.parentNode !== parent) {
            parent.appendChild(child);
        }
    }

    function remove(parent, child) {
        if (child && parent && child.parentNode === parent) {
            parent.removeChild(child);
        }
    }

    function getZIndex(zlevel, z, z2) {
        // z 的取值范围为 [0, 1000]
        return (parseFloat(zlevel) || 0) * ZLEVEL_BASE + (parseFloat(z) || 0) * Z_BASE + z2;
    }

    /***************************************************
     * PATH
     **************************************************/

    function setColorAndOpacity(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];
        }
    }

    function getColorAndAlpha(color) {
        var colorArr = colorTool.parse(color);
        return [
            rgb2Str(colorArr[0], colorArr[1], colorArr[2]),
            colorArr[3]
        ];
    }

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

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

    function updateFillAndStroke(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 = [[], [], []];
    function pathDataToString(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 ';

                    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.brush = 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;
        if (this.__dirtyPath) {
            path.beginPath();
            this.buildPath(path, this.shape);
            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) {
            this.drawRectText(vmlRoot, this.getBoundingRect());
        }
    };

    Path.prototype.onRemoveFromStorage = function (vmlRoot) {
        remove(vmlRoot, this._vmlEl);
        this.removeRectText(vmlRoot);
    };

    Path.prototype.onAddToStorage = function (vmlRoot) {
        append(vmlRoot, this._vmlEl);
        this.appendRectText(vmlRoot);
    };

    /***************************************************
     * IMAGE
     **************************************************/
    function isImage(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.brush = 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) {
            this.drawRectText(vmlRoot, this.getBoundingRect());
        }
    };

    ZImage.prototype.onRemoveFromStorage = function (vmlRoot) {
        remove(vmlRoot, this._vmlEl);

        this._vmlEl = null;
        this._cropEl = null;
        this._imageEl = null;

        this.removeRectText(vmlRoot);
    };

    ZImage.prototype.onAddToStorage = 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');

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

    function drawRectText(vmlRoot, rect, textRect, fromTextEl) {

        var style = this.style;
        var text = style.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;

        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 + textPosition[0];
                y = rect.y + textPosition[1];

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

    function removeRectText(vmlRoot) {
        remove(vmlRoot, this._textVmlEl);
        this._textVmlEl = null;
    }

    function appendRectText(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.brush = function (root) {
        var style = this.style;
        if (style.text) {
            this.drawRectText(root, {
                x: style.x || 0, y: style.y || 0,
                width: 0, height: 0
            }, this.getBoundingRect(), true);
        }
    };

    Text.prototype.onRemoveFromStorage = function (vmlRoot) {
        this.removeRectText(vmlRoot);
    };

    Text.prototype.onAddToStorage = function (vmlRoot) {
        this.appendRectText(vmlRoot);
    };
});
/**
 * VML Painter.
 *
 * @module zrender/vml/Painter
 */

define('zrender/vml/Painter',['require','../core/log','./core'],function (require) {

    var zrLog = require('../core/log');
    var vmlCore = require('./core');

    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 oldDelFromMap = storage.delFromMap;
        var oldAddToMap = storage.addToMap;
        storage.delFromMap = function (elId) {
            var el = storage.get(elId);

            oldDelFromMap.call(storage, elId);

            if (el) {
                el.onRemoveFromStorage && el.onRemoveFromStorage(vmlRoot);
            }
        };

        storage.addToMap = function (el) {
            // Displayable already has a vml node
            el.onAddToStorage && el.onAddToStorage(vmlRoot);

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

            this._paintList(list);
        },

        _paintList: function (list) {
            var vmlRoot = this._vmlRoot;
            for (var i = 0; i < list.length; i++) {
                var el = list[i];
                if (el.__dirty && !el.invisible) {
                    el.beforeBrush && el.beforeBrush();
                    el.brush(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 () {
            var width = this._getWidth();
            var height = this._getHeight();

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

        _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', 'eachBuildinLayer', 'eachOtherLayer', 'getLayers',
        'modLayer', 'delLayer', 'clearLayer', 'toDataURL', 'pathToImage'
    ];

    for (var i = 0; i < notSupportedMethods.length; i++) {
        var name = notSupportedMethods[i];
        VMLPainter.prototype[name] = createMethodNotSupport(name);
    }

    return VMLPainter;
});
define('zrender/vml/vml',['require','./graphic','../zrender','./Painter'],function (require) {
    require('./graphic');
    require('../zrender').registerPainter('vml', require('./Painter'));
});
var echarts = require('echarts');


require("echarts/chart/line");

require("echarts/chart/bar");

require("echarts/component/grid");

require("echarts/chart/pie");

require("echarts/chart/scatter");

require("echarts/component/tooltip");

require("echarts/component/polar");

require("echarts/chart/radar");

require("echarts/component/legend");

require("echarts/chart/map");

require("echarts/chart/treemap");

require("echarts/chart/graph");

require("echarts/chart/gauge");

require("echarts/chart/funnel");

require("echarts/chart/parallel");

require("echarts/chart/sankey");

require("echarts/chart/boxplot");

require("echarts/chart/candlestick");

require("echarts/chart/effectScatter");

require("echarts/chart/lines");

require("echarts/chart/heatmap");

require("echarts/component/geo");

require("echarts/component/parallel");

require("echarts/component/title");

require("echarts/component/dataZoom");

require("echarts/component/visualMap");

require("echarts/component/markPoint");

require("echarts/component/markLine");

require("echarts/component/timeline");

require("echarts/component/toolbox");

require("zrender/vml/vml");


return echarts;
}));
