(function (global, factory) {
	typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
	typeof define === 'function' && define.amd ? define(['exports'], factory) :
	(factory((global.echarts = {})));
}(this, (function (exports) { 'use strict';

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

// (1) The code `if (__DEV__) ...` can be removed by build tool.
// (2) If intend to use `__DEV__`, this module should be imported. Use a global
// variable `__DEV__` may cause that miss the declaration (see #6535), or the
// declaration is behind of the using position (for example in `Model.extent`,
// And tools like rollup can not analysis the dependency if not import).

var dev;

// In browser
if (typeof window !== 'undefined') {
    dev = window.__DEV__;
}
// In node
else if (typeof global !== 'undefined') {
    dev = global.__DEV__;
}

if (typeof dev === 'undefined') {
    dev = true;
}

var __DEV__ = dev;

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

var idStart = 0x0907;

var guid = function () {
    return idStart++;
};

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

/* global wx */

var env = {};

if (typeof wx === 'object' && typeof wx.getSystemInfoSync === 'function') {
    // In Weixin Application
    env = {
        browser: {},
        os: {},
        node: false,
        wxa: true, // Weixin Application
        canvasSupported: true,
        svgSupported: false,
        touchEventsSupported: true,
        domSupported: false
    };
}
else if (typeof document === 'undefined' && typeof self !== 'undefined') {
    // In worker
    env = {
        browser: {},
        os: {},
        node: false,
        worker: true,
        canvasSupported: true,
        domSupported: false
    };
}
else if (typeof navigator === 'undefined') {
    // In node
    env = {
        browser: {},
        os: {},
        node: true,
        worker: false,
        // Assume canvas is supported
        canvasSupported: true,
        svgSupported: true,
        domSupported: false
    };
}
else {
    env = detect(navigator.userAgent);
}

var env$1 = env;

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

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

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

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

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

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

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

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

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

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

    return {
        browser: browser,
        os: os,
        node: false,
        // 原生canvas支持，改极端点了
        // canvasSupported : !(browser.ie && parseFloat(browser.version) < 9)
        canvasSupported: !!document.createElement('canvas').getContext,
        svgSupported: typeof SVGRect !== 'undefined',
        // works on most browsers
        // IE10/11 does not support touch event, and MS Edge supports them but not by
        // default, so we dont check navigator.maxTouchPoints for them here.
        touchEventsSupported: 'ontouchstart' in window && !browser.ie && !browser.edge,
        // <http://caniuse.com/#search=pointer%20event>.
        pointerEventsSupported:
            // (1) Firefox supports pointer but not by default, only MS browsers are reliable on pointer
            // events currently. So we dont use that on other browsers unless tested sufficiently.
            // For example, in iOS 13 Mobile Chromium 78, if the touching behavior starts page
            // scroll, the `pointermove` event can not be fired any more. That will break some
            // features like "pan horizontally to move something and pan vertically to page scroll".
            // The horizontal pan probably be interrupted by the casually triggered page scroll.
            // (2) Although IE 10 supports pointer event, it use old style and is different from the
            // standard. So we exclude that. (IE 10 is hardly used on touch device)
            'onpointerdown' in window
                && (browser.edge || (browser.ie && browser.version >= 11)),
        // passiveSupported: detectPassiveSupport()
        domSupported: typeof document !== 'undefined'
    };
}

// See https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md#feature-detection
// function detectPassiveSupport() {
//     // Test via a getter in the options object to see if the passive property is accessed
//     var supportsPassive = false;
//     try {
//         var opts = Object.defineProperty({}, 'passive', {
//             get: function() {
//                 supportsPassive = true;
//             }
//         });
//         window.addEventListener('testPassive', function() {}, opts);
//     } catch (e) {
//     }
//     return supportsPassive;
// }

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

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

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

var objToString = Object.prototype.toString;

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

// Avoid assign to an exported variable, for transforming to cjs.
var methods = {};

function $override(name, fn) {
    // Clear ctx instance for different environment
    if (name === 'createCanvas') {
        _ctx = null;
    }

    methods[name] = fn;
}

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

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

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

    return result;
}

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

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

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

    return target;
}

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

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

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

var createCanvas = function () {
    return methods.createCanvas();
};

methods.createCanvas = function () {
    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 = createCanvas().getContext('2d');
    }
    return _ctx;
}

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

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

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

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

    defaults(target, source, overlay);
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

/**
 * Whether is exactly NaN. Notice isNaN('a') returns true.
 * @param {*} value
 * @return {boolean}
 */
function eqNaN(value) {
    /* eslint-disable-next-line no-self-compare */
    return value !== value;
}

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

function retrieve2(value0, value1) {
    return value0 != null
        ? value0
        : value1;
}

function retrieve3(value0, value1, value2) {
    return value0 != null
        ? value0
        : value1 != null
        ? value1
        : value2;
}

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

/**
 * 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
 * @return {Array.<number>}
 */
function normalizeCssArray(val) {
    if (typeof (val) === 'number') {
        return [val, val, val, val];
    }
    var len = val.length;
    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;
}

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

/**
 * @memberOf module:zrender/core/util
 * @param {string} str string to be trimed
 * @return {string} trimed string
 */
function trim(str) {
    if (str == null) {
        return null;
    }
    else if (typeof str.trim === 'function') {
        return str.trim();
    }
    else {
        return str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
    }
}

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

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

/**
 * @constructor
 * @param {Object} obj Only apply `ownProperty`.
 */
function HashMap(obj) {
    var isArr = isArray(obj);
    // Key should not be set on this, otherwise
    // methods get/set/... may be overrided.
    this.data = {};
    var thisMap = this;

    (obj instanceof HashMap)
        ? obj.each(visit)
        : (obj && each$1(obj, visit));

    function visit(value, key) {
        isArr ? thisMap.set(value, key) : thisMap.set(key, value);
    }
}

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

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

function concatArray(a, b) {
    var newArray = new a.constructor(a.length + b.length);
    for (var i = 0; i < a.length; i++) {
        newArray[i] = a[i];
    }
    var offset = a.length;
    for (i = 0; i < b.length; i++) {
        newArray[i + offset] = b[i];
    }
    return newArray;
}


function noop() {}


var zrUtil = (Object.freeze || Object)({
	$override: $override,
	clone: clone,
	merge: merge,
	mergeAll: mergeAll,
	extend: extend,
	defaults: defaults,
	createCanvas: createCanvas,
	getContext: getContext,
	indexOf: indexOf,
	inherits: inherits,
	mixin: mixin,
	isArrayLike: isArrayLike,
	each: each$1,
	map: map,
	reduce: reduce,
	filter: filter,
	find: find,
	bind: bind,
	curry: curry,
	isArray: isArray,
	isFunction: isFunction$1,
	isString: isString,
	isObject: isObject$1,
	isBuiltInObject: isBuiltInObject,
	isTypedArray: isTypedArray,
	isDom: isDom,
	eqNaN: eqNaN,
	retrieve: retrieve,
	retrieve2: retrieve2,
	retrieve3: retrieve3,
	slice: slice,
	normalizeCssArray: normalizeCssArray,
	assert: assert$1,
	trim: trim,
	setAsPrimitive: setAsPrimitive,
	isPrimitive: isPrimitive,
	createHashMap: createHashMap,
	concatArray: concatArray,
	noop: noop
});

/* global Float32Array */

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

/**
 * 创建一个向量
 * @param {number} [x=0]
 * @param {number} [y=0]
 * @return {Vector2}
 */
function create(x, y) {
    var out = new ArrayCtor(2);
    if (x == null) {
        x = 0;
    }
    if (y == null) {
        y = 0;
    }
    out[0] = x;
    out[1] = y;
    return out;
}

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

/**
 * 克隆一个向量
 * @param {Vector2} v
 * @return {Vector2}
 */
function clone$1(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} 结果
 */
function set(out, a, b) {
    out[0] = a;
    out[1] = b;
    return out;
}

/**
 * 向量相加
 * @param {Vector2} out
 * @param {Vector2} v1
 * @param {Vector2} v2
 */
function add(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
 */
function scaleAndAdd(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
 */
function sub(out, v1, v2) {
    out[0] = v1[0] - v2[0];
    out[1] = v1[1] - v2[1];
    return out;
}

/**
 * 向量长度
 * @param {Vector2} v
 * @return {number}
 */
function len(v) {
    return Math.sqrt(lenSquare(v));
}
var length = len; // jshint ignore:line

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

/**
 * 向量乘法
 * @param {Vector2} out
 * @param {Vector2} v1
 * @param {Vector2} v2
 */
function mul(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
 */
function div(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}
 */
function dot(v1, v2) {
    return v1[0] * v2[0] + v1[1] * v2[1];
}

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

/**
 * 向量归一化
 * @param {Vector2} out
 * @param {Vector2} v
 */
function normalize(out, v) {
    var d = 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}
 */
function distance(v1, v2) {
    return Math.sqrt(
        (v1[0] - v2[0]) * (v1[0] - v2[0])
        + (v1[1] - v2[1]) * (v1[1] - v2[1])
    );
}
var dist = distance;

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

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

/**
 * 插值两个点
 * @param {Vector2} out
 * @param {Vector2} v1
 * @param {Vector2} v2
 * @param {number} t
 */
function lerp(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
 */
function applyTransform(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
 */
function min(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
 */
function max(out, v1, v2) {
    out[0] = Math.max(v1[0], v2[0]);
    out[1] = Math.max(v1[1], v2[1]);
    return out;
}


var vector = (Object.freeze || Object)({
	create: create,
	copy: copy,
	clone: clone$1,
	set: set,
	add: add,
	scaleAndAdd: scaleAndAdd,
	sub: sub,
	len: len,
	length: length,
	lenSquare: lenSquare,
	lengthSquare: lengthSquare,
	mul: mul,
	div: div,
	dot: dot,
	scale: scale,
	normalize: normalize,
	distance: distance,
	dist: dist,
	distanceSquare: distanceSquare,
	distSquare: distSquare,
	negate: negate,
	lerp: lerp,
	applyTransform: applyTransform,
	min: min,
	max: max
});

// TODO Draggable for group
// FIXME Draggable on element which has parent rotation or scale
function Draggable() {

    this.on('mousedown', this._dragStart, this);
    this.on('mousemove', this._drag, this);
    this.on('mouseup', this._dragEnd, this);
    // `mosuemove` and `mouseup` can be continue to fire when dragging.
    // See [Drag outside] in `Handler.js`. So we do not need to trigger
    // `_dragEnd` when globalout. That would brings better user experience.
    // 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;
        // Find if there is draggable in the ancestor
        while (draggingTarget && !draggingTarget.draggable) {
            draggingTarget = draggingTarget.parent;
        }
        if (draggingTarget) {
            this._draggingTarget = draggingTarget;
            draggingTarget.dragging = true;
            this._x = e.offsetX;
            this._y = e.offsetY;

            this.dispatchToElement(param(draggingTarget, e), 'dragstart', e.event);
        }
    },

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

            var x = e.offsetX;
            var y = e.offsetY;

            var dx = x - this._x;
            var dy = y - this._y;
            this._x = x;
            this._y = y;

            draggingTarget.drift(dx, dy, e);
            this.dispatchToElement(param(draggingTarget, e), 'drag', e.event);

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

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

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

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

        this.dispatchToElement(param(draggingTarget, e), 'dragend', e.event);

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

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

};

function param(target, e) {
    return {target: target, topTarget: e && e.topTarget};
}

/**
 * Event Mixin
 * @module zrender/mixin/Eventful
 * @author Kener (@Kener-林峰, kener.linfeng@gmail.com)
 *         pissang (https://www.github.com/pissang)
 */

var arrySlice = Array.prototype.slice;

/**
 * Event dispatcher.
 *
 * @alias module:zrender/mixin/Eventful
 * @constructor
 * @param {Object} [eventProcessor] The object eventProcessor is the scope when
 *        `eventProcessor.xxx` called.
 * @param {Function} [eventProcessor.normalizeQuery]
 *        param: {string|Object} Raw query.
 *        return: {string|Object} Normalized query.
 * @param {Function} [eventProcessor.filter] Event will be dispatched only
 *        if it returns `true`.
 *        param: {string} eventType
 *        param: {string|Object} query
 *        return: {boolean}
 * @param {Function} [eventProcessor.afterTrigger] Called after all handlers called.
 *        param: {string} eventType
 */
var Eventful = function (eventProcessor) {
    this._$handlers = {};
    this._$eventProcessor = eventProcessor;
};

Eventful.prototype = {

    constructor: Eventful,

    /**
     * The handler can only be triggered once, then removed.
     *
     * @param {string} event The event name.
     * @param {string|Object} [query] Condition used on event filter.
     * @param {Function} handler The event handler.
     * @param {Object} context
     */
    one: function (event, query, handler, context) {
        return on(this, event, query, handler, context, true);
    },

    /**
     * Bind a handler.
     *
     * @param {string} event The event name.
     * @param {string|Object} [query] Condition used on event filter.
     * @param {Function} handler The event handler.
     * @param {Object} [context]
     */
    on: function (event, query, handler, context) {
        return on(this, event, query, handler, context, false);
    },

    /**
     * Whether any handler has bound.
     *
     * @param  {string}  event
     * @return {boolean}
     */
    isSilent: function (event) {
        var _h = this._$handlers;
        return !_h[event] || !_h[event].length;
    },

    /**
     * Unbind a event.
     *
     * @param {string} [event] The event name.
     *        If no `event` input, "off" all listeners.
     * @param {Function} [handler] The event handler.
     *        If no `handler` input, "off" all listeners of the `event`.
     */
    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;
    },

    /**
     * Dispatch a event.
     *
     * @param {string} type The event name.
     */
    trigger: function (type) {
        var _h = this._$handlers[type];
        var eventProcessor = this._$eventProcessor;

        if (_h) {
            var args = arguments;
            var argLen = args.length;

            if (argLen > 3) {
                args = arrySlice.call(args, 1);
            }

            var len = _h.length;
            for (var i = 0; i < len;) {
                var hItem = _h[i];
                if (eventProcessor
                    && eventProcessor.filter
                    && hItem.query != null
                    && !eventProcessor.filter(type, hItem.query)
                ) {
                    i++;
                    continue;
                }

                // Optimize advise from backbone
                switch (argLen) {
                    case 1:
                        hItem.h.call(hItem.ctx);
                        break;
                    case 2:
                        hItem.h.call(hItem.ctx, args[1]);
                        break;
                    case 3:
                        hItem.h.call(hItem.ctx, args[1], args[2]);
                        break;
                    default:
                        // have more than 2 given arguments
                        hItem.h.apply(hItem.ctx, args);
                        break;
                }

                if (hItem.one) {
                    _h.splice(i, 1);
                    len--;
                }
                else {
                    i++;
                }
            }
        }

        eventProcessor && eventProcessor.afterTrigger
            && eventProcessor.afterTrigger(type);

        return this;
    },

    /**
     * Dispatch a event with context, which is specified at the last parameter.
     *
     * @param {string} type The event name.
     */
    triggerWithContext: function (type) {
        var _h = this._$handlers[type];
        var eventProcessor = this._$eventProcessor;

        if (_h) {
            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 len = _h.length;
            for (var i = 0; i < len;) {
                var hItem = _h[i];
                if (eventProcessor
                    && eventProcessor.filter
                    && hItem.query != null
                    && !eventProcessor.filter(type, hItem.query)
                ) {
                    i++;
                    continue;
                }

                // Optimize advise from backbone
                switch (argLen) {
                    case 1:
                        hItem.h.call(ctx);
                        break;
                    case 2:
                        hItem.h.call(ctx, args[1]);
                        break;
                    case 3:
                        hItem.h.call(ctx, args[1], args[2]);
                        break;
                    default:
                        // have more than 2 given arguments
                        hItem.h.apply(ctx, args);
                        break;
                }

                if (hItem.one) {
                    _h.splice(i, 1);
                    len--;
                }
                else {
                    i++;
                }
            }
        }

        eventProcessor && eventProcessor.afterTrigger
            && eventProcessor.afterTrigger(type);

        return this;
    }
};


function normalizeQuery(host, query) {
    var eventProcessor = host._$eventProcessor;
    if (query != null && eventProcessor && eventProcessor.normalizeQuery) {
        query = eventProcessor.normalizeQuery(query);
    }
    return query;
}

function on(eventful, event, query, handler, context, isOnce) {
    var _h = eventful._$handlers;

    if (typeof query === 'function') {
        context = handler;
        handler = query;
        query = null;
    }

    if (!handler || !event) {
        return eventful;
    }

    query = normalizeQuery(eventful, query);

    if (!_h[event]) {
        _h[event] = [];
    }

    for (var i = 0; i < _h[event].length; i++) {
        if (_h[event][i].h === handler) {
            return eventful;
        }
    }

    var wrap = {
        h: handler,
        one: isOnce,
        query: query,
        ctx: context || eventful,
        // FIXME
        // Do not publish this feature util it is proved that it makes sense.
        callAtLast: handler.zrEventfulCallAtLast
    };

    var lastIndex = _h[event].length - 1;
    var lastWrap = _h[event][lastIndex];
    (lastWrap && lastWrap.callAtLast)
        ? _h[event].splice(lastIndex, 0, wrap)
        : _h[event].push(wrap);

    return eventful;
}

/**
 * The algoritm is learnt from
 * https://franklinta.com/2014/09/08/computing-css-matrix3d-transforms/
 * And we made some optimization for matrix inversion.
 * Other similar approaches:
 * "cv::getPerspectiveTransform", "Direct Linear Transformation".
 */

var LN2 = Math.log(2);

function determinant(rows, rank, rowStart, rowMask, colMask, detCache) {
    var cacheKey = rowMask + '-' + colMask;
    var fullRank = rows.length;

    if (detCache.hasOwnProperty(cacheKey)) {
        return detCache[cacheKey];
    }

    if (rank === 1) {
        // In this case the colMask must be like: `11101111`. We can find the place of `0`.
        var colStart = Math.round(Math.log(((1 << fullRank) - 1) & ~colMask) / LN2);
        return rows[rowStart][colStart];
    }

    var subRowMask = rowMask | (1 << rowStart);
    var subRowStart = rowStart + 1;
    while (rowMask & (1 << subRowStart)) {
        subRowStart++;
    }

    var sum = 0;
    for (var j = 0, colLocalIdx = 0; j < fullRank; j++) {
        var colTag = 1 << j;
        if (!(colTag & colMask)) {
            sum += (colLocalIdx % 2 ? -1 : 1) * rows[rowStart][j]
                // det(subMatrix(0, j))
                * determinant(rows, rank - 1, subRowStart, subRowMask, colMask | colTag, detCache);
            colLocalIdx++;
        }
    }

    detCache[cacheKey] = sum;

    return sum;
}

/**
 * Usage:
 * ```js
 * var transformer = buildTransformer(
 *     [10, 44, 100, 44, 100, 300, 10, 300],
 *     [50, 54, 130, 14, 140, 330, 14, 220]
 * );
 * var out = [];
 * transformer && transformer([11, 33], out);
 * ```
 *
 * Notice: `buildTransformer` may take more than 10ms in some Android device.
 *
 * @param {Array.<number>} src source four points, [x0, y0, x1, y1, x2, y2, x3, y3]
 * @param {Array.<number>} dest destination four points, [x0, y0, x1, y1, x2, y2, x3, y3]
 * @return {Function} transformer If fail, return null/undefined.
 */
function buildTransformer(src, dest) {
    var mA = [
        [src[0], src[1], 1, 0, 0, 0, -dest[0] * src[0], -dest[0] * src[1]],
        [0, 0, 0, src[0], src[1], 1, -dest[1] * src[0], -dest[1] * src[1]],
        [src[2], src[3], 1, 0, 0, 0, -dest[2] * src[2], -dest[2] * src[3]],
        [0, 0, 0, src[2], src[3], 1, -dest[3] * src[2], -dest[3] * src[3]],
        [src[4], src[5], 1, 0, 0, 0, -dest[4] * src[4], -dest[4] * src[5]],
        [0, 0, 0, src[4], src[5], 1, -dest[5] * src[4], -dest[5] * src[5]],
        [src[6], src[7], 1, 0, 0, 0, -dest[6] * src[6], -dest[6] * src[7]],
        [0, 0, 0, src[6], src[7], 1, -dest[7] * src[6], -dest[7] * src[7]]
    ];

    var detCache = {};
    var det = determinant(mA, 8, 0, 0, 0, detCache);
    if (det === 0) {
        // can not make transformer when and only when
        // any three of the markers are collinear.
        return;
    }

    // `invert(mA) * dest`, that is, `adj(mA) / det * dest`.
    var vh = [];
    for (var i = 0; i < 8; i++) {
        for (var j = 0; j < 8; j++) {
            vh[j] == null && (vh[j] = 0);
            vh[j] += ((i + j) % 2 ? -1 : 1)
                // det(subMatrix(i, j))
                * determinant(mA, 7, i === 0 ? 1 : 0, 1 << i, 1 << j, detCache)
                / det * dest[i];
        }
    }

    return function (out, srcPointX, srcPointY) {
        var pk = srcPointX * vh[6] + srcPointY * vh[7] + 1;
        out[0] = (srcPointX * vh[0] + srcPointY * vh[1] + vh[2]) / pk;
        out[1] = (srcPointX * vh[3] + srcPointY * vh[4] + vh[5]) / pk;
    };
}

var EVENT_SAVED_PROP = '___zrEVENTSAVED';
var _calcOut$1 = [];

/**
 * Transform "local coord" from `elFrom` to `elTarget`.
 * "local coord": the coord based on the input `el`. The origin point is at
 *     the position of "left: 0; top: 0;" in the `el`.
 *
 * Support when CSS transform is used.
 *
 * Having the `out` (that is, `[outX, outY]`), we can create an DOM element
 * and set the CSS style as "left: outX; top: outY;" and append it to `elTarge`
 * to locate the element.
 *
 * For example, this code below positions a child of `document.body` on the event
 * point, no matter whether `body` has `margin`/`paddin`/`transfrom`/... :
 * ```js
 * transformLocalCoord(out, container, document.body, event.offsetX, event.offsetY);
 * if (!eqNaN(out[0])) {
 *     // Then locate the tip element on the event point.
 *     var tipEl = document.createElement('div');
 *     tipEl.style.cssText = 'position: absolute; left:' + out[0] + ';top:' + out[1] + ';';
 *     document.body.appendChild(tipEl);
 * }
 * ```
 *
 * Notice: In some env this method is not supported. If called, `out` will be `[NaN, NaN]`.
 *
 * @param {Array.<number>} out [inX: number, inY: number] The output..
 *        If can not transform, `out` will not be modified but return `false`.
 * @param {HTMLElement} elFrom The `[inX, inY]` is based on elFrom.
 * @param {HTMLElement} elTarget The `out` is based on elTarget.
 * @param {number} inX
 * @param {number} inY
 * @return {boolean} Whether transform successfully.
 */
function transformLocalCoord(out, elFrom, elTarget, inX, inY) {
    return transformCoordWithViewport(_calcOut$1, elFrom, inX, inY, true)
        && transformCoordWithViewport(out, elTarget, _calcOut$1[0], _calcOut$1[1]);
}

/**
 * Transform between a "viewport coord" and a "local coord".
 * "viewport coord": the coord based on the left-top corner of the viewport
 *     of the browser.
 * "local coord": the coord based on the input `el`. The origin point is at
 *     the position of "left: 0; top: 0;" in the `el`.
 *
 * Support the case when CSS transform is used on el.
 *
 * @param {Array.<number>} out [inX: number, inY: number] The output. If `inverse: false`,
 *        it represents "local coord", otherwise "vireport coord".
 *        If can not transform, `out` will not be modified but return `false`.
 * @param {HTMLElement} el The "local coord" is based on the `el`, see comment above.
 * @param {number} inX If `inverse: false`,
 *        it represents "vireport coord", otherwise "local coord".
 * @param {number} inY If `inverse: false`,
 *        it represents "vireport coord", otherwise "local coord".
 * @param {boolean} [inverse=false]
 *        `true`: from "viewport coord" to "local coord".
 *        `false`: from "local coord" to "viewport coord".
 * @return {boolean} Whether transform successfully.
 */
function transformCoordWithViewport(out, el, inX, inY, inverse) {
    if (el.getBoundingClientRect && env$1.domSupported && !isCanvasEl(el)) {
        var saved = el[EVENT_SAVED_PROP] || (el[EVENT_SAVED_PROP] = {});
        var markers = prepareCoordMarkers(el, saved);
        var transformer = preparePointerTransformer(markers, saved, inverse);
        if (transformer) {
            transformer(out, inX, inY);
            return true;
        }
    }
    return false;
}

function prepareCoordMarkers(el, saved) {
    var markers = saved.markers;
    if (markers) {
        return markers;
    }

    markers = saved.markers = [];
    var propLR = ['left', 'right'];
    var propTB = ['top', 'bottom'];

    for (var i = 0; i < 4; i++) {
        var marker = document.createElement('div');
        var stl = marker.style;
        var idxLR = i % 2;
        var idxTB = (i >> 1) % 2;
        stl.cssText = [
            'position: absolute',
            'visibility: hidden',
            'padding: 0',
            'margin: 0',
            'border-width: 0',
            'user-select: none',
            'width:0',
            'height:0',
            // 'width: 5px',
            // 'height: 5px',
            propLR[idxLR] + ':0',
            propTB[idxTB] + ':0',
            propLR[1 - idxLR] + ':auto',
            propTB[1 - idxTB] + ':auto',
            ''
        ].join('!important;');
        el.appendChild(marker);
        markers.push(marker);
    }

    return markers;
}

function preparePointerTransformer(markers, saved, inverse) {
    var transformerName = inverse ? 'invTrans' : 'trans';
    var transformer = saved[transformerName];
    var oldSrcCoords = saved.srcCoords;
    var oldCoordTheSame = true;
    var srcCoords = [];
    var destCoords = [];

    for (var i = 0; i < 4; i++) {
        var rect = markers[i].getBoundingClientRect();
        var ii = 2 * i;
        var x = rect.left;
        var y = rect.top;
        srcCoords.push(x, y);
        oldCoordTheSame = oldCoordTheSame && oldSrcCoords && x === oldSrcCoords[ii] && y === oldSrcCoords[ii + 1];
        destCoords.push(markers[i].offsetLeft, markers[i].offsetTop);
    }
    // Cache to avoid time consuming of `buildTransformer`.
    return (oldCoordTheSame && transformer)
        ? transformer
        : (
            saved.srcCoords = srcCoords,
            saved[transformerName] = inverse
                ? buildTransformer(destCoords, srcCoords)
                : buildTransformer(srcCoords, destCoords)
        );
}

function isCanvasEl(el) {
    return el.nodeName.toUpperCase() === 'CANVAS';
}

/**
 * Utilities for mouse or touch events.
 */

var isDomLevel2 = (typeof window !== 'undefined') && !!window.addEventListener;

var MOUSE_EVENT_REG = /^(?:mouse|pointer|contextmenu|drag|drop)|click/;
var _calcOut = [];

/**
 * Get the `zrX` and `zrY`, which are relative to the top-left of
 * the input `el`.
 * CSS transform (2D & 3D) is supported.
 *
 * The strategy to fetch the coords:
 * + If `calculate` is not set as `true`, users of this method should
 * ensure that `el` is the same or the same size & location as `e.target`.
 * Otherwise the result coords are probably not expected. Because we
 * firstly try to get coords from e.offsetX/e.offsetY.
 * + If `calculate` is set as `true`, the input `el` can be any element
 * and we force to calculate the coords based on `el`.
 * + The input `el` should be positionable (not position:static).
 *
 * The force `calculate` can be used in case like:
 * When mousemove event triggered on ec tooltip, `e.target` is not `el`(zr painter.dom).
 *
 * @param {HTMLElement} el DOM element.
 * @param {Event} e Mouse event or touch event.
 * @param {Object} out Get `out.zrX` and `out.zrY` as the result.
 * @param {boolean} [calculate=false] Whether to force calculate
 *        the coordinates but not use ones provided by browser.
 */
function clientToLocal(el, e, out, calculate) {
    out = out || {};

    // According to the W3C Working Draft, offsetX and offsetY should be relative
    // to the padding edge of the target element. The only browser using this convention
    // is IE. Webkit uses the border edge, Opera uses the content edge, and FireFox does
    // not support the properties.
    // (see http://www.jacklmoore.com/notes/mouse-position/)
    // In zr painter.dom, padding edge equals to border edge.

    if (calculate || !env$1.canvasSupported) {
        calculateZrXY(el, e, out);
    }
    // Caution: In FireFox, layerX/layerY Mouse position relative to the closest positioned
    // ancestor element, so we should make sure el is positioned (e.g., not position:static).
    // BTW1, Webkit don't return the same results as FF in non-simple cases (like add
    // zoom-factor, overflow / opacity layers, transforms ...)
    // BTW2, (ev.offsetY || ev.pageY - $(ev.target).offset().top) is not correct in preserve-3d.
    // <https://bugs.jquery.com/ticket/8523#comment:14>
    // BTW3, In ff, offsetX/offsetY is always 0.
    else if (env$1.browser.firefox && e.layerX != null && e.layerX !== e.offsetX) {
        out.zrX = e.layerX;
        out.zrY = e.layerY;
    }
    // For IE6+, chrome, safari, opera. (When will ff support offsetX?)
    else if (e.offsetX != null) {
        out.zrX = e.offsetX;
        out.zrY = e.offsetY;
    }
    // For some other device, e.g., IOS safari.
    else {
        calculateZrXY(el, e, out);
    }

    return out;
}

function calculateZrXY(el, e, out) {
    // BlackBerry 5, iOS 3 (original iPhone) don't have getBoundingRect.
    if (env$1.domSupported && el.getBoundingClientRect) {
        var ex = e.clientX;
        var ey = e.clientY;

        if (isCanvasEl(el)) {
            // Original approach, which do not support CSS transform.
            // marker can not be locationed in a canvas container
            // (getBoundingClientRect is always 0). We do not support
            // that input a pre-created canvas to zr while using css
            // transform in iOS.
            var box = el.getBoundingClientRect();
            out.zrX = ex - box.left;
            out.zrY = ey - box.top;
            return;
        }
        else {
            if (transformCoordWithViewport(_calcOut, el, ex, ey)) {
                out.zrX = _calcOut[0];
                out.zrY = _calcOut[1];
                return;
            }
        }
    }
    out.zrX = out.zrY = 0;
}

/**
 * Find native event compat for legency IE.
 * Should be called at the begining of a native event listener.
 *
 * @param {Event} [e] Mouse event or touch event or pointer event.
 *        For lagency IE, we use `window.event` is used.
 * @return {Event} The native event.
 */
function getNativeEvent(e) {
    return e || window.event;
}

/**
 * Normalize the coordinates of the input event.
 *
 * Get the `e.zrX` and `e.zrY`, which are relative to the top-left of
 * the input `el`.
 * Get `e.zrDelta` if using mouse wheel.
 * Get `e.which`, see the comment inside this function.
 *
 * Do not calculate repeatly if `zrX` and `zrY` already exist.
 *
 * Notice: see comments in `clientToLocal`. check the relationship
 * between the result coords and the parameters `el` and `calculate`.
 *
 * @param {HTMLElement} el DOM element.
 * @param {Event} [e] See `getNativeEvent`.
 * @param {boolean} [calculate=false] Whether to force calculate
 *        the coordinates but not use ones provided by browser.
 * @return {UIEvent} The normalized native UIEvent.
 */
function normalizeEvent(el, e, calculate) {

    e = getNativeEvent(e);

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

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

    if (!isTouch) {
        clientToLocal(el, e, e, calculate);
        e.zrDelta = (e.wheelDelta) ? e.wheelDelta / 120 : -(e.detail || 0) / 3;
    }
    else {
        var touch = eventType !== 'touchend'
            ? e.targetTouches[0]
            : e.changedTouches[0];
        touch && clientToLocal(el, touch, e, calculate);
    }

    // Add which for click: 1 === left; 2 === middle; 3 === right; otherwise: 0;
    // See jQuery: https://github.com/jquery/jquery/blob/master/src/event.js
    // If e.which has been defined, it may be readonly,
    // see: https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/which
    var button = e.button;
    if (e.which == null && button !== undefined && MOUSE_EVENT_REG.test(e.type)) {
        e.which = (button & 1 ? 1 : (button & 2 ? 3 : (button & 4 ? 2 : 0)));
    }
    // [Caution]: `e.which` from browser is not always reliable. For example,
    // when press left button and `mousemove (pointermove)` in Edge, the `e.which`
    // is 65536 and the `e.button` is -1. But the `mouseup (pointerup)` and
    // `mousedown (pointerdown)` is the same as Chrome does.

    return e;
}

/**
 * @param {HTMLElement} el
 * @param {string} name
 * @param {Function} handler
 * @param {Object|boolean} opt If boolean, means `opt.capture`
 * @param {boolean} [opt.capture=false]
 * @param {boolean} [opt.passive=false]
 */
function addEventListener(el, name, handler, opt) {
    if (isDomLevel2) {
        // Reproduct the console warning:
        // [Violation] Added non-passive event listener to a scroll-blocking <some> event.
        // Consider marking event handler as 'passive' to make the page more responsive.
        // Just set console log level: verbose in chrome dev tool.
        // then the warning log will be printed when addEventListener called.
        // See https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md
        // We have not yet found a neat way to using passive. Because in zrender the dom event
        // listener delegate all of the upper events of element. Some of those events need
        // to prevent default. For example, the feature `preventDefaultMouseMove` of echarts.
        // Before passive can be adopted, these issues should be considered:
        // (1) Whether and how a zrender user specifies an event listener passive. And by default,
        // passive or not.
        // (2) How to tread that some zrender event listener is passive, and some is not. If
        // we use other way but not preventDefault of mousewheel and touchmove, browser
        // compatibility should be handled.

        // var opts = (env.passiveSupported && name === 'mousewheel')
        //     ? {passive: true}
        //     // By default, the third param of el.addEventListener is `capture: false`.
        //     : void 0;
        // el.addEventListener(name, handler /* , opts */);
        el.addEventListener(name, handler, opt);
    }
    else {
        // For simplicity, do not implement `setCapture` for IE9-.
        el.attachEvent('on' + name, handler);
    }
}

/**
 * Parameter are the same as `addEventListener`.
 *
 * Notice that if a listener is registered twice, one with capture and one without,
 * remove each one separately. Removal of a capturing listener does not affect a
 * non-capturing version of the same listener, and vice versa.
 */
function removeEventListener(el, name, handler, opt) {
    if (isDomLevel2) {
        el.removeEventListener(name, handler, opt);
    }
    else {
        el.detachEvent('on' + name, handler);
    }
}

/**
 * preventDefault and stopPropagation.
 * Notice: do not use this method in zrender. It can only be
 * used by upper applications if necessary.
 *
 * @param {Event} e A mouse or touch event.
 */
var stop = isDomLevel2
    ? function (e) {
        e.preventDefault();
        e.stopPropagation();
        e.cancelBubble = true;
    }
    : function (e) {
        e.returnValue = false;
        e.cancelBubble = true;
    };

/**
 * This method only works for mouseup and mousedown. The functionality is restricted
 * for fault tolerance, See the `e.which` compatibility above.
 *
 * @param {MouseEvent} e
 * @return {boolean}
 */
function isMiddleOrRightButtonOnMouseUpDown(e) {
    return e.which === 2 || e.which === 3;
}

/**
 * To be removed.
 * @deprecated
 */

/**
 * Only implements needed gestures for mobile.
 */

var GestureMgr = function () {

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

GestureMgr.prototype = {

    constructor: GestureMgr,

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

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

    _doTrack: function (event, target, root) {
        var touches = event.touches;

        if (!touches) {
            return;
        }

        var trackItem = {
            points: [],
            touches: [],
            target: target,
            event: event
        };

        for (var i = 0, len = touches.length; i < len; i++) {
            var touch = touches[i];
            var pos = clientToLocal(root, touch, {});
            trackItem.points.push([pos.zrX, pos.zrY]);
            trackItem.touches.push(touch);
        }

        this._track.push(trackItem);
    },

    _recognize: function (event) {
        for (var eventName in recognizers) {
            if (recognizers.hasOwnProperty(eventName)) {
                var gestureInfo = recognizers[eventName](this._track, event);
                if (gestureInfo) {
                    return gestureInfo;
                }
            }
        }
    }
};

function dist$1(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$1(pinchEnd) / dist$1(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.
};

/**
 * [The interface between `Handler` and `HandlerProxy`]:
 *
 * The default `HandlerProxy` only support the common standard web environment
 * (e.g., standalone browser, headless browser, embed browser in mobild APP, ...).
 * But `HandlerProxy` can be replaced to support more non-standard environment
 * (e.g., mini app), or to support more feature that the default `HandlerProxy`
 * not provided (like echarts-gl did).
 * So the interface between `Handler` and `HandlerProxy` should be stable. Do not
 * make break changes util inevitable. The interface include the public methods
 * of `Handler` and the events listed in `handlerNames` below, by which `HandlerProxy`
 * drives `Handler`.
 */

/**
 * [Drag outside]:
 *
 * That is, triggering `mousemove` and `mouseup` event when the pointer is out of the
 * zrender area when dragging. That is important for the improvement of the user experience
 * when dragging something near the boundary without being terminated unexpectedly.
 *
 * We originally consider to introduce new events like `pagemovemove` and `pagemouseup`
 * to resolve this issue. But some drawbacks of it is described in
 * https://github.com/ecomfe/zrender/pull/536#issuecomment-560286899
 *
 * Instead, we referenced the specifications:
 * https://www.w3.org/TR/touch-events/#the-touchmove-event
 * https://www.w3.org/TR/2014/WD-DOM-Level-3-Events-20140925/#event-type-mousemove
 * where the the mousemove/touchmove can be continue to fire if the user began a drag
 * operation and the pointer has left the boundary. (for the mouse event, browsers
 * only do it on `document` and when the pointer has left the boundary of the browser.)
 *
 * So the default `HandlerProxy` supports this feature similarly: if it is in the dragging
 * state (see `pointerCapture` in `HandlerProxy`), the `mousemove` and `mouseup` continue
 * to fire until release the pointer. That is implemented by listen to those event on
 * `document`.
 * If we implement some other `HandlerProxy` only for touch device, that would be easier.
 * The touch event support this feature by default.
 *
 * Note:
 * There might be some cases that the mouse event can not be
 * received on `document`. For example,
 * (A) `useCapture` is not supported and some user defined event listeners on the ancestor
 * of zr dom throw Error .
 * (B) `useCapture` is not supported Some user defined event listeners on the ancestor of
 * zr dom call `stopPropagation`.
 * In these cases, the `mousemove` event might be keep triggered event
 * if the mouse is released. We try to reduce the side-effect in those cases.
 * That is, do nothing (especially, `findHover`) in those cases. See `isOutsideBoundary`.
 *
 * Note:
 * If `HandlerProxy` listens to `document` with `useCapture`, `HandlerProxy` needs to
 * make sure `stopPropagation` and `preventDefault` doing nothing if and only if the event
 * target is not zrender dom. Becuase it is dangerous to enable users to call them in
 * `document` capture phase to prevent the propagation to any listener of the webpage.
 * But they are needed to work when the pointer inside the zrender dom.
 */


var SILENT = 'silent';

function makeEventPacket(eveType, targetInfo, event) {
    return {
        type: eveType,
        event: event,
        // target can only be an element that is not silent.
        target: targetInfo.target,
        // topTarget can be a silent element.
        topTarget: targetInfo.topTarget,
        cancelBubble: false,
        offsetX: event.zrX,
        offsetY: event.zrY,
        gestureEvent: event.gestureEvent,
        pinchX: event.pinchX,
        pinchY: event.pinchY,
        pinchScale: event.pinchScale,
        wheelDelta: event.zrDelta,
        zrByTouch: event.zrByTouch,
        which: event.which,
        stop: stopEvent
    };
}

function stopEvent() {
    stop(this.event);
}

function EmptyProxy() {}
EmptyProxy.prototype.dispose = function () {};


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

/**
 * @alias module:zrender/Handler
 * @constructor
 * @extends module:zrender/mixin/Eventful
 * @param {module:zrender/Storage} storage Storage instance.
 * @param {module:zrender/Painter} painter Painter instance.
 * @param {module:zrender/dom/HandlerProxy} proxy HandlerProxy instance.
 * @param {HTMLElement} painterRoot painter.root (not painter.getViewportRoot()).
 */
var Handler = function (storage, painter, proxy, painterRoot) {
    Eventful.call(this);

    this.storage = storage;

    this.painter = painter;

    this.painterRoot = painterRoot;

    proxy = proxy || new EmptyProxy();

    /**
     * Proxy of event. can be Dom, WebGLSurface, etc.
     */
    this.proxy = null;

    /**
     * {target, topTarget, x, y}
     * @private
     * @type {Object}
     */
    this._hovered = {};

    /**
     * @private
     * @type {Date}
     */
    this._lastTouchMoment;

    /**
     * @private
     * @type {number}
     */
    this._lastX;

    /**
     * @private
     * @type {number}
     */
    this._lastY;

    /**
     * @private
     * @type {module:zrender/core/GestureMgr}
     */
    this._gestureMgr;

    Draggable.call(this);

    this.setHandlerProxy(proxy);
};

Handler.prototype = {

    constructor: Handler,

    setHandlerProxy: function (proxy) {
        if (this.proxy) {
            this.proxy.dispose();
        }

        if (proxy) {
            each$1(handlerNames, function (name) {
                proxy.on && proxy.on(name, this[name], this);
            }, this);
            // Attach handler
            proxy.handler = this;
        }
        this.proxy = proxy;
    },

    mousemove: function (event) {
        var x = event.zrX;
        var y = event.zrY;

        var isOutside = isOutsideBoundary(this, x, y);

        var lastHovered = this._hovered;
        var lastHoveredTarget = lastHovered.target;

        // If lastHoveredTarget is removed from zr (detected by '__zr') by some API call
        // (like 'setOption' or 'dispatchAction') in event handlers, we should find
        // lastHovered again here. Otherwise 'mouseout' can not be triggered normally.
        // See #6198.
        if (lastHoveredTarget && !lastHoveredTarget.__zr) {
            lastHovered = this.findHover(lastHovered.x, lastHovered.y);
            lastHoveredTarget = lastHovered.target;
        }

        var hovered = this._hovered = isOutside ? {x: x, y: y} : this.findHover(x, y);
        var hoveredTarget = hovered.target;

        var proxy = this.proxy;
        proxy.setCursor && proxy.setCursor(hoveredTarget ? hoveredTarget.cursor : 'default');

        // Mouse out on previous hovered element
        if (lastHoveredTarget && hoveredTarget !== lastHoveredTarget) {
            this.dispatchToElement(lastHovered, 'mouseout', event);
        }

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

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

    mouseout: function (event) {
        var eventControl = event.zrEventControl;
        var zrIsToLocalDOM = event.zrIsToLocalDOM;

        if (eventControl !== 'only_globalout') {
            this.dispatchToElement(this._hovered, 'mouseout', event);
        }

        if (eventControl !== 'no_globalout') {
            // FIXME: if the pointer moving from the extra doms to realy "outside",
            // the `globalout` should have been triggered. But currently not.
            !zrIsToLocalDOM && this.trigger('globalout', {type: 'globalout', event: event});
        }
    },

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

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

    /**
     * Dispose
     */
    dispose: function () {

        this.proxy.dispose();

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

    /**
     * 设置默认的cursor style
     * @param {string} [cursorStyle='default'] 例如 crosshair
     */
    setCursorStyle: function (cursorStyle) {
        var proxy = this.proxy;
        proxy.setCursor && proxy.setCursor(cursorStyle);
    },

    /**
     * 事件分发代理
     *
     * @private
     * @param {Object} targetInfo {target, topTarget} 目标图形元素
     * @param {string} eventName 事件名称
     * @param {Object} event 事件对象
     */
    dispatchToElement: function (targetInfo, eventName, event) {
        targetInfo = targetInfo || {};
        var el = targetInfo.target;
        if (el && el.silent) {
            return;
        }
        var eventHandler = 'on' + eventName;
        var eventPacket = makeEventPacket(eventName, targetInfo, event);

        while (el) {
            el[eventHandler]
                && (eventPacket.cancelBubble = el[eventHandler].call(el, eventPacket));

            el.trigger(eventName, eventPacket);

            el = el.parent;

            if (eventPacket.cancelBubble) {
                break;
            }
        }

        if (!eventPacket.cancelBubble) {
            // 冒泡到顶级 zrender 对象
            this.trigger(eventName, eventPacket);
            // 分发事件到用户自定义层
            // 用户有可能在全局 click 事件中 dispose，所以需要判断下 painter 是否存在
            this.painter && this.painter.eachOtherLayer(function (layer) {
                if (typeof (layer[eventHandler]) === 'function') {
                    layer[eventHandler].call(layer, eventPacket);
                }
                if (layer.trigger) {
                    layer.trigger(eventName, eventPacket);
                }
            });
        }
    },

    /**
     * @private
     * @param {number} x
     * @param {number} y
     * @param {module:zrender/graphic/Displayable} exclude
     * @return {model:zrender/Element}
     * @method
     */
    findHover: function (x, y, exclude) {
        var list = this.storage.getDisplayList();
        var out = {x: x, y: y};

        for (var i = list.length - 1; i >= 0; i--) {
            var hoverCheckResult;
            if (list[i] !== exclude
                // getDisplayList may include ignored item in VML mode
                && !list[i].ignore
                && (hoverCheckResult = isHover(list[i], x, y))
            ) {
                !out.topTarget && (out.topTarget = list[i]);
                if (hoverCheckResult !== SILENT) {
                    out.target = list[i];
                    break;
                }
            }
        }

        return out;
    },

    processGesture: function (event, stage) {
        if (!this._gestureMgr) {
            this._gestureMgr = new GestureMgr();
        }
        var gestureMgr = this._gestureMgr;

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

        var gestureInfo = gestureMgr.recognize(
            event,
            this.findHover(event.zrX, event.zrY, null).target,
            this.proxy.dom
        );

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

        // Do not do any preventDefault here. Upper application do that if necessary.
        if (gestureInfo) {
            var type = gestureInfo.type;
            event.gestureEvent = type;

            this.dispatchToElement({target: gestureInfo.target}, type, gestureInfo.event);
        }
    }
};

// Common handlers
each$1(['click', 'mousedown', 'mouseup', 'mousewheel', 'dblclick', 'contextmenu'], function (name) {
    Handler.prototype[name] = function (event) {
        var x = event.zrX;
        var y = event.zrY;
        var isOutside = isOutsideBoundary(this, x, y);

        var hovered;
        var hoveredTarget;

        if (name !== 'mouseup' || !isOutside) {
            // Find hover again to avoid click event is dispatched manually. Or click is triggered without mouseover
            hovered = this.findHover(x, y);
            hoveredTarget = hovered.target;
        }

        if (name === 'mousedown') {
            this._downEl = hoveredTarget;
            this._downPoint = [event.zrX, event.zrY];
            // In case click triggered before mouseup
            this._upEl = hoveredTarget;
        }
        else if (name === 'mouseup') {
            this._upEl = hoveredTarget;
        }
        else if (name === 'click') {
            if (this._downEl !== this._upEl
                // Original click event is triggered on the whole canvas element,
                // including the case that `mousedown` - `mousemove` - `mouseup`,
                // which should be filtered, otherwise it will bring trouble to
                // pan and zoom.
                || !this._downPoint
                // Arbitrary value
                || dist(this._downPoint, [event.zrX, event.zrY]) > 4
            ) {
                return;
            }
            this._downPoint = null;
        }

        this.dispatchToElement(hovered, name, event);
    };
});

function isHover(displayable, x, y) {
    if (displayable[displayable.rectHover ? 'rectContain' : 'contain'](x, y)) {
        var el = displayable;
        var isSilent;
        while (el) {
            // If clipped by ancestor.
            // FIXME: If clipPath has neither stroke nor fill,
            // el.clipPath.contain(x, y) will always return false.
            if (el.clipPath && !el.clipPath.contain(x, y)) {
                return false;
            }
            if (el.silent) {
                isSilent = true;
            }
            el = el.parent;
        }
        return isSilent ? SILENT : true;
    }

    return false;
}

/**
 * See [Drag outside].
 */
function isOutsideBoundary(handlerInstance, x, y) {
    var painter = handlerInstance.painter;
    return x < 0 || x > painter.getWidth() || y < 0 || y > painter.getHeight();
}

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

/**
 * 3x2矩阵操作类
 * @exports zrender/tool/matrix
 */

/* global Float32Array */

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

/**
 * Create a identity matrix.
 * @return {Float32Array|Array.<number>}
 */
function create$1() {
    var out = new ArrayCtor$1(6);
    identity(out);

    return out;
}

/**
 * 设置矩阵为单位矩阵
 * @param {Float32Array|Array.<number>} out
 */
function identity(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
 */
function copy$1(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
 */
function mul$1(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
 */
function translate(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
 */
function rotate(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
 */
function scale$1(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
 */
function invert(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;
}

/**
 * Clone a new matrix.
 * @param {Float32Array|Array.<number>} a
 */
function clone$2(a) {
    var b = create$1();
    copy$1(b, a);
    return b;
}

var matrix = (Object.freeze || Object)({
	create: create$1,
	identity: identity,
	copy: copy$1,
	mul: mul$1,
	translate: translate,
	rotate: rotate,
	scale: scale$1,
	invert: invert,
	clone: clone$2
});

/**
 * 提供变换扩展
 * @module zrender/mixin/Transformable
 * @author pissang (https://www.github.com/pissang)
 */

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

var scaleTmp = [];
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 || create$1();

    if (needLocalTransform) {
        this.getLocalTransform(m);
    }
    else {
        mIdentity(m);
    }

    // 应用父节点变换
    if (parentHasTransform) {
        if (needLocalTransform) {
            mul$1(m, parent.transform, m);
        }
        else {
            copy$1(m, parent.transform);
        }
    }
    // 保存这个变换矩阵
    this.transform = m;

    var globalScaleRatio = this.globalScaleRatio;
    if (globalScaleRatio != null && globalScaleRatio !== 1) {
        this.getGlobalScale(scaleTmp);
        var relX = scaleTmp[0] < 0 ? -1 : 1;
        var relY = scaleTmp[1] < 0 ? -1 : 1;
        var sx = ((scaleTmp[0] - relX) * globalScaleRatio + relX) / scaleTmp[0] || 0;
        var sy = ((scaleTmp[1] - relY) * globalScaleRatio + relY) / scaleTmp[1] || 0;

        m[0] *= sx;
        m[1] *= sx;
        m[2] *= sy;
        m[3] *= sy;
    }

    this.invTransform = this.invTransform || create$1();
    invert(this.invTransform, m);
};

transformableProto.getLocalTransform = function (m) {
    return Transformable.getLocalTransform(this, m);
};

/**
 * 将自己的transform应用到context上
 * @param {CanvasRenderingContext2D} ctx
 */
transformableProto.setTransform = function (ctx) {
    var m = this.transform;
    var dpr = ctx.dpr || 1;
    if (m) {
        ctx.setTransform(dpr * m[0], dpr * m[1], dpr * m[2], dpr * m[3], dpr * m[4], dpr * m[5]);
    }
    else {
        ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
    }
};

transformableProto.restoreTransform = function (ctx) {
    var dpr = ctx.dpr || 1;
    ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
};

var tmpTransform = [];
var originTransform = create$1();

transformableProto.setLocalTransform = function (m) {
    if (!m) {
        // TODO return or set identity?
        return;
    }
    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$$1 = 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$$1[0] = sx;
    scale$$1[1] = sy;
    this.rotation = Math.atan2(-m[1] / sy, m[0] / sx);
};
/**
 * 分解`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
        mul$1(tmpTransform, parent.invTransform, m);
        m = tmpTransform;
    }
    var origin = this.origin;
    if (origin && (origin[0] || origin[1])) {
        originTransform[4] = origin[0];
        originTransform[5] = origin[1];
        mul$1(tmpTransform, m, originTransform);
        tmpTransform[4] -= origin[0];
        tmpTransform[5] -= origin[1];
        m = tmpTransform;
    }

    this.setLocalTransform(m);
};

/**
 * Get global scale
 * @return {Array.<number>}
 */
transformableProto.getGlobalScale = function (out) {
    var m = this.transform;
    out = out || [];
    if (!m) {
        out[0] = 1;
        out[1] = 1;
        return out;
    }
    out[0] = Math.sqrt(m[0] * m[0] + m[1] * m[1]);
    out[1] = Math.sqrt(m[2] * m[2] + m[3] * m[3]);
    if (m[0] < 0) {
        out[0] = -out[0];
    }
    if (m[3] < 0) {
        out[1] = -out[1];
    }
    return out;
};
/**
 * 变换坐标位置到 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) {
        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) {
        applyTransform(v2, v2, transform);
    }
    return v2;
};

/**
 * @static
 * @param {Object} target
 * @param {Array.<number>} target.origin
 * @param {number} target.rotation
 * @param {Array.<number>} target.position
 * @param {Array.<number>} [m]
 */
Transformable.getLocalTransform = function (target, m) {
    m = m || [];
    mIdentity(m);

    var origin = target.origin;
    var scale$$1 = target.scale || [1, 1];
    var rotation = target.rotation || 0;
    var position = target.position || [0, 0];

    if (origin) {
        // Translate to origin
        m[4] -= origin[0];
        m[5] -= origin[1];
    }
    scale$1(m, m, scale$$1);
    if (rotation) {
        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;
};

/**
 * 缓动代码来自 https://github.com/sole/tween.js/blob/master/src/Tween.js
 * @see http://sole.github.io/tween.js/examples/03_graphs.html
 * @exports zrender/animation/easing
 */
var easing = {
    /**
    * @param {number} k
    * @return {number}
    */
    linear: function (k) {
        return k;
    },

    /**
    * @param {number} k
    * @return {number}
    */
    quadraticIn: function (k) {
        return k * k;
    },
    /**
    * @param {number} k
    * @return {number}
    */
    quadraticOut: function (k) {
        return k * (2 - k);
    },
    /**
    * @param {number} k
    * @return {number}
    */
    quadraticInOut: function (k) {
        if ((k *= 2) < 1) {
            return 0.5 * k * k;
        }
        return -0.5 * (--k * (k - 2) - 1);
    },

    // 三次方的缓动（t^3）
    /**
    * @param {number} k
    * @return {number}
    */
    cubicIn: function (k) {
        return k * k * k;
    },
    /**
    * @param {number} k
    * @return {number}
    */
    cubicOut: function (k) {
        return --k * k * k + 1;
    },
    /**
    * @param {number} k
    * @return {number}
    */
    cubicInOut: function (k) {
        if ((k *= 2) < 1) {
            return 0.5 * k * k * k;
        }
        return 0.5 * ((k -= 2) * k * k + 2);
    },

    // 四次方的缓动（t^4）
    /**
    * @param {number} k
    * @return {number}
    */
    quarticIn: function (k) {
        return k * k * k * k;
    },
    /**
    * @param {number} k
    * @return {number}
    */
    quarticOut: function (k) {
        return 1 - (--k * k * k * k);
    },
    /**
    * @param {number} k
    * @return {number}
    */
    quarticInOut: function (k) {
        if ((k *= 2) < 1) {
            return 0.5 * k * k * k * k;
        }
        return -0.5 * ((k -= 2) * k * k * k - 2);
    },

    // 五次方的缓动（t^5）
    /**
    * @param {number} k
    * @return {number}
    */
    quinticIn: function (k) {
        return k * k * k * k * k;
    },
    /**
    * @param {number} k
    * @return {number}
    */
    quinticOut: function (k) {
        return --k * k * k * k * k + 1;
    },
    /**
    * @param {number} k
    * @return {number}
    */
    quinticInOut: function (k) {
        if ((k *= 2) < 1) {
            return 0.5 * k * k * k * k * k;
        }
        return 0.5 * ((k -= 2) * k * k * k * k + 2);
    },

    // 正弦曲线的缓动（sin(t)）
    /**
    * @param {number} k
    * @return {number}
    */
    sinusoidalIn: function (k) {
        return 1 - Math.cos(k * Math.PI / 2);
    },
    /**
    * @param {number} k
    * @return {number}
    */
    sinusoidalOut: function (k) {
        return Math.sin(k * Math.PI / 2);
    },
    /**
    * @param {number} k
    * @return {number}
    */
    sinusoidalInOut: function (k) {
        return 0.5 * (1 - Math.cos(Math.PI * k));
    },

    // 指数曲线的缓动（2^t）
    /**
    * @param {number} k
    * @return {number}
    */
    exponentialIn: function (k) {
        return k === 0 ? 0 : Math.pow(1024, k - 1);
    },
    /**
    * @param {number} k
    * @return {number}
    */
    exponentialOut: function (k) {
        return k === 1 ? 1 : 1 - Math.pow(2, -10 * k);
    },
    /**
    * @param {number} k
    * @return {number}
    */
    exponentialInOut: function (k) {
        if (k === 0) {
            return 0;
        }
        if (k === 1) {
            return 1;
        }
        if ((k *= 2) < 1) {
            return 0.5 * Math.pow(1024, k - 1);
        }
        return 0.5 * (-Math.pow(2, -10 * (k - 1)) + 2);
    },

    // 圆形曲线的缓动（sqrt(1-t^2)）
    /**
    * @param {number} k
    * @return {number}
    */
    circularIn: function (k) {
        return 1 - Math.sqrt(1 - k * k);
    },
    /**
    * @param {number} k
    * @return {number}
    */
    circularOut: function (k) {
        return Math.sqrt(1 - (--k * k));
    },
    /**
    * @param {number} k
    * @return {number}
    */
    circularInOut: function (k) {
        if ((k *= 2) < 1) {
            return -0.5 * (Math.sqrt(1 - k * k) - 1);
        }
        return 0.5 * (Math.sqrt(1 - (k -= 2) * k) + 1);
    },

    // 创建类似于弹簧在停止前来回振荡的动画
    /**
    * @param {number} k
    * @return {number}
    */
    elasticIn: function (k) {
        var s;
        var a = 0.1;
        var p = 0.4;
        if (k === 0) {
            return 0;
        }
        if (k === 1) {
            return 1;
        }
        if (!a || a < 1) {
            a = 1;
            s = p / 4;
        }
        else {
            s = p * Math.asin(1 / a) / (2 * Math.PI);
        }
        return -(a * Math.pow(2, 10 * (k -= 1))
                    * Math.sin((k - s) * (2 * Math.PI) / p));
    },
    /**
    * @param {number} k
    * @return {number}
    */
    elasticOut: function (k) {
        var s;
        var a = 0.1;
        var p = 0.4;
        if (k === 0) {
            return 0;
        }
        if (k === 1) {
            return 1;
        }
        if (!a || a < 1) {
            a = 1;
            s = p / 4;
        }
        else {
            s = p * Math.asin(1 / a) / (2 * Math.PI);
        }
        return (a * Math.pow(2, -10 * k)
                    * Math.sin((k - s) * (2 * Math.PI) / p) + 1);
    },
    /**
    * @param {number} k
    * @return {number}
    */
    elasticInOut: function (k) {
        var s;
        var a = 0.1;
        var p = 0.4;
        if (k === 0) {
            return 0;
        }
        if (k === 1) {
            return 1;
        }
        if (!a || a < 1) {
            a = 1;
            s = p / 4;
        }
        else {
            s = p * Math.asin(1 / a) / (2 * Math.PI);
        }
        if ((k *= 2) < 1) {
            return -0.5 * (a * Math.pow(2, 10 * (k -= 1))
                * Math.sin((k - s) * (2 * Math.PI) / p));
        }
        return a * Math.pow(2, -10 * (k -= 1))
                * Math.sin((k - s) * (2 * Math.PI) / p) * 0.5 + 1;

    },

    // 在某一动画开始沿指示的路径进行动画处理前稍稍收回该动画的移动
    /**
    * @param {number} k
    * @return {number}
    */
    backIn: function (k) {
        var s = 1.70158;
        return k * k * ((s + 1) * k - s);
    },
    /**
    * @param {number} k
    * @return {number}
    */
    backOut: function (k) {
        var s = 1.70158;
        return --k * k * ((s + 1) * k + s) + 1;
    },
    /**
    * @param {number} k
    * @return {number}
    */
    backInOut: function (k) {
        var s = 1.70158 * 1.525;
        if ((k *= 2) < 1) {
            return 0.5 * (k * k * ((s + 1) * k - s));
        }
        return 0.5 * ((k -= 2) * k * ((s + 1) * k + s) + 2);
    },

    // 创建弹跳效果
    /**
    * @param {number} k
    * @return {number}
    */
    bounceIn: function (k) {
        return 1 - easing.bounceOut(1 - k);
    },
    /**
    * @param {number} k
    * @return {number}
    */
    bounceOut: function (k) {
        if (k < (1 / 2.75)) {
            return 7.5625 * k * k;
        }
        else if (k < (2 / 2.75)) {
            return 7.5625 * (k -= (1.5 / 2.75)) * k + 0.75;
        }
        else if (k < (2.5 / 2.75)) {
            return 7.5625 * (k -= (2.25 / 2.75)) * k + 0.9375;
        }
        else {
            return 7.5625 * (k -= (2.625 / 2.75)) * k + 0.984375;
        }
    },
    /**
    * @param {number} k
    * @return {number}
    */
    bounceInOut: function (k) {
        if (k < 0.5) {
            return easing.bounceIn(k * 2) * 0.5;
        }
        return easing.bounceOut(k * 2 - 1) * 0.5 + 0.5;
    }
};

/**
 * 动画主控制器
 * @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
 */

function Clip(options) {

    this._target = options.target;

    // 生命周期
    this._life = options.life || 1000;
    // 延时
    this._delay = options.delay || 0;
    // 开始时间
    // this._startTime = new Date().getTime() + this._delay;// 单位毫秒
    this._initialized = false;

    // 是否循环
    this.loop = options.loop == null ? false : options.loop;

    this.gap = options.gap || 0;

    this.easing = options.easing || 'Linear';

    this.onframe = options.onframe;
    this.ondestroy = options.ondestroy;
    this.onrestart = options.onrestart;

    this._pausedTime = 0;
    this._paused = false;
}

Clip.prototype = {

    constructor: Clip,

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

        if (this._paused) {
            this._pausedTime += deltaTime;
            return;
        }

        var percent = (globalTime - this._startTime - this._pausedTime) / this._life;

        // 还没开始
        if (percent < 0) {
            return;
        }

        percent = Math.min(percent, 1);

        var easing$$1 = this.easing;
        var easingFunc = typeof easing$$1 === 'string' ? easing[easing$$1] : easing$$1;
        var schedule = typeof easingFunc === 'function'
            ? easingFunc(percent)
            : percent;

        this.fire('frame', schedule);

        // 结束
        if (percent === 1) {
            if (this.loop) {
                this.restart(globalTime);
                // 重新开始周期
                // 抛出而不是直接调用事件直到 stage.update 后再统一调用这些事件
                return 'restart';
            }

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

        return null;
    },

    restart: function (globalTime) {
        var remainder = (globalTime - this._startTime - this._pausedTime) % this._life;
        this._startTime = globalTime - remainder + this.gap;
        this._pausedTime = 0;

        this._needsRemove = false;
    },

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

    pause: function () {
        this._paused = true;
    },

    resume: function () {
        this._paused = false;
    }
};

// Simple LRU cache use doubly linked list
// @module zrender/core/LRU

/**
 * Simple double linked list. Compared with array, it has O(1) remove operation.
 * @constructor
 */
var LinkedList = function () {

    /**
     * @type {module:zrender/core/LRU~Entry}
     */
    this.head = null;

    /**
     * @type {module:zrender/core/LRU~Entry}
     */
    this.tail = null;

    this._len = 0;
};

var linkedListProto = LinkedList.prototype;
/**
 * Insert a new value at the tail
 * @param  {} val
 * @return {module:zrender/core/LRU~Entry}
 */
linkedListProto.insert = function (val) {
    var entry = new Entry(val);
    this.insertEntry(entry);
    return entry;
};

/**
 * Insert an entry at the tail
 * @param  {module:zrender/core/LRU~Entry} entry
 */
linkedListProto.insertEntry = function (entry) {
    if (!this.head) {
        this.head = this.tail = entry;
    }
    else {
        this.tail.next = entry;
        entry.prev = this.tail;
        entry.next = null;
        this.tail = entry;
    }
    this._len++;
};

/**
 * Remove entry.
 * @param  {module:zrender/core/LRU~Entry} entry
 */
linkedListProto.remove = function (entry) {
    var prev = entry.prev;
    var next = entry.next;
    if (prev) {
        prev.next = next;
    }
    else {
        // Is head
        this.head = next;
    }
    if (next) {
        next.prev = prev;
    }
    else {
        // Is tail
        this.tail = prev;
    }
    entry.next = entry.prev = null;
    this._len--;
};

/**
 * @return {number}
 */
linkedListProto.len = function () {
    return this._len;
};

/**
 * Clear list
 */
linkedListProto.clear = function () {
    this.head = this.tail = null;
    this._len = 0;
};

/**
 * @constructor
 * @param {} val
 */
var Entry = function (val) {
    /**
     * @type {}
     */
    this.value = val;

    /**
     * @type {module:zrender/core/LRU~Entry}
     */
    this.next;

    /**
     * @type {module:zrender/core/LRU~Entry}
     */
    this.prev;
};

/**
 * LRU Cache
 * @constructor
 * @alias module:zrender/core/LRU
 */
var LRU = function (maxSize) {

    this._list = new LinkedList();

    this._map = {};

    this._maxSize = maxSize || 10;

    this._lastRemovedEntry = null;
};

var LRUProto = LRU.prototype;

/**
 * @param  {string} key
 * @param  {} value
 * @return {} Removed value
 */
LRUProto.put = function (key, value) {
    var list = this._list;
    var map = this._map;
    var removed = null;
    if (map[key] == null) {
        var len = list.len();
        // Reuse last removed entry
        var entry = this._lastRemovedEntry;

        if (len >= this._maxSize && len > 0) {
            // Remove the least recently used
            var leastUsedEntry = list.head;
            list.remove(leastUsedEntry);
            delete map[leastUsedEntry.key];

            removed = leastUsedEntry.value;
            this._lastRemovedEntry = leastUsedEntry;
        }

        if (entry) {
            entry.value = value;
        }
        else {
            entry = new Entry(value);
        }
        entry.key = key;
        list.insertEntry(entry);
        map[key] = entry;
    }

    return removed;
};

/**
 * @param  {string} key
 * @return {}
 */
LRUProto.get = function (key) {
    var entry = this._map[key];
    var list = this._list;
    if (entry != null) {
        // Put the latest used entry in the tail
        if (entry !== list.tail) {
            list.remove(entry);
            list.insertEntry(entry);
        }

        return entry.value;
    }
};

/**
 * Clear the cache
 */
LRUProto.clear = function () {
    this._list.clear();
    this._map = {};
};

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 lerpNumber(a, b, p) {
    return a + (b - a) * p;
}

function setRgba(out, r, g, b, a) {
    out[0] = r;
    out[1] = g;
    out[2] = b;
    out[3] = a;
    return out;
}
function copyRgba(out, a) {
    out[0] = a[0];
    out[1] = a[1];
    out[2] = a[2];
    out[3] = a[3];
    return out;
}

var colorCache = new LRU(20);
var lastRemovedArr = null;

function putToCache(colorStr, rgbaArr) {
    // Reuse removed array
    if (lastRemovedArr) {
        copyRgba(lastRemovedArr, rgbaArr);
    }
    lastRemovedArr = colorCache.put(colorStr, lastRemovedArr || (rgbaArr.slice()));
}

/**
 * @param {string} colorStr
 * @param {Array.<number>} out
 * @return {Array.<number>}
 * @memberOf module:zrender/util/color
 */
function parse(colorStr, rgbaArr) {
    if (!colorStr) {
        return;
    }
    rgbaArr = rgbaArr || [];

    var cached = colorCache.get(colorStr);
    if (cached) {
        return copyRgba(rgbaArr, cached);
    }

    // colorStr may be not string
    colorStr = colorStr + '';
    // Remove all whitespace, not compliant, but should just be more accepting.
    var str = colorStr.replace(/ /g, '').toLowerCase();

    // Color keywords (and transparent) lookup.
    if (str in kCSSColorTable) {
        copyRgba(rgbaArr, kCSSColorTable[str]);
        putToCache(colorStr, rgbaArr);
        return rgbaArr;
    }

    // #abc and #abc123 syntax.
    if (str.charAt(0) === '#') {
        if (str.length === 4) {
            var iv = parseInt(str.substr(1), 16);  // TODO(deanm): Stricter parsing.
            if (!(iv >= 0 && iv <= 0xfff)) {
                setRgba(rgbaArr, 0, 0, 0, 1);
                return;  // Covers NaN.
            }
            setRgba(rgbaArr,
                ((iv & 0xf00) >> 4) | ((iv & 0xf00) >> 8),
                (iv & 0xf0) | ((iv & 0xf0) >> 4),
                (iv & 0xf) | ((iv & 0xf) << 4),
                1
            );
            putToCache(colorStr, rgbaArr);
            return rgbaArr;
        }
        else if (str.length === 7) {
            var iv = parseInt(str.substr(1), 16);  // TODO(deanm): Stricter parsing.
            if (!(iv >= 0 && iv <= 0xffffff)) {
                setRgba(rgbaArr, 0, 0, 0, 1);
                return;  // Covers NaN.
            }
            setRgba(rgbaArr,
                (iv & 0xff0000) >> 16,
                (iv & 0xff00) >> 8,
                iv & 0xff,
                1
            );
            putToCache(colorStr, rgbaArr);
            return rgbaArr;
        }

        return;
    }
    var op = str.indexOf('(');
    var ep = str.indexOf(')');
    if (op !== -1 && ep + 1 === str.length) {
        var fname = str.substr(0, op);
        var params = str.substr(op + 1, ep - (op + 1)).split(',');
        var alpha = 1;  // To allow case fallthrough.
        switch (fname) {
            case 'rgba':
                if (params.length !== 4) {
                    setRgba(rgbaArr, 0, 0, 0, 1);
                    return;
                }
                alpha = parseCssFloat(params.pop()); // jshint ignore:line
            // Fall through.
            case 'rgb':
                if (params.length !== 3) {
                    setRgba(rgbaArr, 0, 0, 0, 1);
                    return;
                }
                setRgba(rgbaArr,
                    parseCssInt(params[0]),
                    parseCssInt(params[1]),
                    parseCssInt(params[2]),
                    alpha
                );
                putToCache(colorStr, rgbaArr);
                return rgbaArr;
            case 'hsla':
                if (params.length !== 4) {
                    setRgba(rgbaArr, 0, 0, 0, 1);
                    return;
                }
                params[3] = parseCssFloat(params[3]);
                hsla2rgba(params, rgbaArr);
                putToCache(colorStr, rgbaArr);
                return rgbaArr;
            case 'hsl':
                if (params.length !== 3) {
                    setRgba(rgbaArr, 0, 0, 0, 1);
                    return;
                }
                hsla2rgba(params, rgbaArr);
                putToCache(colorStr, rgbaArr);
                return rgbaArr;
            default:
                return;
        }
    }

    setRgba(rgbaArr, 0, 0, 0, 1);
    return;
}

/**
 * @param {Array.<number>} hsla
 * @param {Array.<number>} rgba
 * @return {Array.<number>} rgba
 */
function hsla2rgba(hsla, rgba) {
    var h = (((parseFloat(hsla[0]) % 360) + 360) % 360) / 360;  // 0 .. 1
    // NOTE(deanm): According to the CSS spec s/l should only be
    // percentages, but we don't bother and let float or percentage.
    var s = parseCssFloat(hsla[1]);
    var l = parseCssFloat(hsla[2]);
    var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
    var m1 = l * 2 - m2;

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

    if (hsla.length === 4) {
        rgba[3] = hsla[3];
    }

    return rgba;
}

/**
 * @param {Array.<number>} rgba
 * @return {Array.<number>} hsla
 */
function rgba2hsla(rgba) {
    if (!rgba) {
        return;
    }

    // RGB from 0 to 255
    var R = rgba[0] / 255;
    var G = rgba[1] / 255;
    var B = rgba[2] / 255;

    var vMin = Math.min(R, G, B); // Min. value of RGB
    var vMax = Math.max(R, G, B); // Max. value of RGB
    var delta = vMax - vMin; // Delta RGB value

    var L = (vMax + vMin) / 2;
    var H;
    var S;
    // HSL results from 0 to 1
    if (delta === 0) {
        H = 0;
        S = 0;
    }
    else {
        if (L < 0.5) {
            S = delta / (vMax + vMin);
        }
        else {
            S = delta / (2 - vMax - vMin);
        }

        var deltaR = (((vMax - R) / 6) + (delta / 2)) / delta;
        var deltaG = (((vMax - G) / 6) + (delta / 2)) / delta;
        var deltaB = (((vMax - B) / 6) + (delta / 2)) / delta;

        if (R === vMax) {
            H = deltaB - deltaG;
        }
        else if (G === vMax) {
            H = (1 / 3) + deltaR - deltaB;
        }
        else if (B === vMax) {
            H = (2 / 3) + deltaG - deltaR;
        }

        if (H < 0) {
            H += 1;
        }

        if (H > 1) {
            H -= 1;
        }
    }

    var hsla = [H * 360, S, L];

    if (rgba[3] != null) {
        hsla.push(rgba[3]);
    }

    return hsla;
}

/**
 * @param {string} color
 * @param {number} level
 * @return {string}
 * @memberOf module:zrender/util/color
 */
function lift(color, level) {
    var colorArr = parse(color);
    if (colorArr) {
        for (var i = 0; i < 3; i++) {
            if (level < 0) {
                colorArr[i] = colorArr[i] * (1 - level) | 0;
            }
            else {
                colorArr[i] = ((255 - colorArr[i]) * level + colorArr[i]) | 0;
            }
            if (colorArr[i] > 255) {
                colorArr[i] = 255;
            }
            else if (color[i] < 0) {
                colorArr[i] = 0;
            }
        }
        return stringify(colorArr, colorArr.length === 4 ? 'rgba' : 'rgb');
    }
}

/**
 * @param {string} color
 * @return {string}
 * @memberOf module:zrender/util/color
 */
function toHex(color) {
    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 lerp methods because color is represented by rgba array.
 * @param {number} normalizedValue A float between 0 and 1.
 * @param {Array.<Array.<number>>} colors List of rgba color array
 * @param {Array.<number>} [out] Mapped gba color array
 * @return {Array.<number>} will be null/undefined if input illegal.
 */
function fastLerp(normalizedValue, colors, out) {
    if (!(colors && colors.length)
        || !(normalizedValue >= 0 && normalizedValue <= 1)
    ) {
        return;
    }

    out = out || [];

    var value = normalizedValue * (colors.length - 1);
    var leftIndex = Math.floor(value);
    var rightIndex = Math.ceil(value);
    var leftColor = colors[leftIndex];
    var rightColor = colors[rightIndex];
    var dv = value - leftIndex;
    out[0] = clampCssByte(lerpNumber(leftColor[0], rightColor[0], dv));
    out[1] = clampCssByte(lerpNumber(leftColor[1], rightColor[1], dv));
    out[2] = clampCssByte(lerpNumber(leftColor[2], rightColor[2], dv));
    out[3] = clampCssFloat(lerpNumber(leftColor[3], rightColor[3], dv));

    return out;
}

/**
 * @deprecated
 */
var fastMapToColor = fastLerp;

/**
 * @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 lerp$1(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(lerpNumber(leftColor[0], rightColor[0], dv)),
            clampCssByte(lerpNumber(leftColor[1], rightColor[1], dv)),
            clampCssByte(lerpNumber(leftColor[2], rightColor[2], dv)),
            clampCssFloat(lerpNumber(leftColor[3], rightColor[3], dv))
        ],
        'rgba'
    );

    return fullOutput
        ? {
            color: color,
            leftIndex: leftIndex,
            rightIndex: rightIndex,
            value: value
        }
        : color;
}

/**
 * @deprecated
 */
var mapToColor = lerp$1;

/**
 * @param {string} color
 * @param {number=} h 0 ~ 360, ignore when null.
 * @param {number=} s 0 ~ 1, ignore when null.
 * @param {number=} l 0 ~ 1, ignore when null.
 * @return {string} Color string in rgba format.
 * @memberOf module:zrender/util/color
 */
function modifyHSL(color, h, s, l) {
    color = parse(color);

    if (color) {
        color = rgba2hsla(color);
        h != null && (color[0] = clampCssAngle(h));
        s != null && (color[1] = parseCssFloat(s));
        l != null && (color[2] = parseCssFloat(l));

        return stringify(hsla2rgba(color), 'rgba');
    }
}

/**
 * @param {string} color
 * @param {number=} alpha 0 ~ 1
 * @return {string} Color string in rgba format.
 * @memberOf module:zrender/util/color
 */
function modifyAlpha(color, alpha) {
    color = parse(color);

    if (color && alpha != null) {
        color[3] = clampCssFloat(alpha);
        return stringify(color, 'rgba');
    }
}

/**
 * @param {Array.<number>} arrColor like [12,33,44,0.4]
 * @param {string} type 'rgba', 'hsva', ...
 * @return {string} Result color. (If input illegal, return undefined).
 */
function stringify(arrColor, type) {
    if (!arrColor || !arrColor.length) {
        return;
    }
    var colorStr = arrColor[0] + ',' + arrColor[1] + ',' + arrColor[2];
    if (type === 'rgba' || type === 'hsva' || type === 'hsla') {
        colorStr += ',' + arrColor[3];
    }
    return type + '(' + colorStr + ')';
}


var color = (Object.freeze || Object)({
	parse: parse,
	lift: lift,
	toHex: toHex,
	fastLerp: fastLerp,
	fastMapToColor: fastMapToColor,
	lerp: lerp$1,
	mapToColor: mapToColor,
	modifyHSL: modifyHSL,
	modifyAlpha: modifyAlpha,
	stringify: stringify
});

/**
 * @module echarts/animation/Animator
 */

var arraySlice = Array.prototype.slice;

function defaultGetter(target, key) {
    return target[key];
}

function defaultSetter(target, key, value) {
    target[key] = value;
}

/**
 * @param  {number} p0
 * @param  {number} p1
 * @param  {number} percent
 * @return {number}
 */
function interpolateNumber(p0, p1, percent) {
    return (p1 - p0) * percent + p0;
}

/**
 * @param  {string} p0
 * @param  {string} p1
 * @param  {number} percent
 * @return {string}
 */
function interpolateString(p0, p1, percent) {
    return percent > 0.5 ? p1 : p0;
}

/**
 * @param  {Array} p0
 * @param  {Array} p1
 * @param  {number} percent
 * @param  {Array} out
 * @param  {number} arrDim
 */
function interpolateArray(p0, p1, percent, out, arrDim) {
    var len = p0.length;
    if (arrDim === 1) {
        for (var i = 0; i < len; i++) {
            out[i] = interpolateNumber(p0[i], p1[i], percent);
        }
    }
    else {
        var len2 = len && p0[0].length;
        for (var i = 0; i < len; i++) {
            for (var j = 0; j < len2; j++) {
                out[i][j] = interpolateNumber(
                    p0[i][j], p1[i][j], percent
                );
            }
        }
    }
}

// arr0 is source array, arr1 is target array.
// Do some preprocess to avoid error happened when interpolating from arr0 to arr1
function fillArr(arr0, arr1, arrDim) {
    var arr0Len = arr0.length;
    var arr1Len = arr1.length;
    if (arr0Len !== arr1Len) {
        // FIXME Not work for TypedArray
        var isPreviousLarger = arr0Len > arr1Len;
        if (isPreviousLarger) {
            // Cut the previous
            arr0.length = arr1Len;
        }
        else {
            // Fill the previous
            for (var i = arr0Len; i < arr1Len; i++) {
                arr0.push(
                    arrDim === 1 ? arr1[i] : arraySlice.call(arr1[i])
                );
            }
        }
    }
    // Handling NaN value
    var len2 = arr0[0] && arr0[0].length;
    for (var i = 0; i < arr0.length; i++) {
        if (arrDim === 1) {
            if (isNaN(arr0[i])) {
                arr0[i] = arr1[i];
            }
        }
        else {
            for (var j = 0; j < len2; j++) {
                if (isNaN(arr0[i][j])) {
                    arr0[i][j] = arr1[i][j];
                }
            }
        }
    }
}

/**
 * @param  {Array} arr0
 * @param  {Array} arr1
 * @param  {number} arrDim
 * @return {boolean}
 */
function isArraySame(arr0, arr1, arrDim) {
    if (arr0 === arr1) {
        return true;
    }
    var len = arr0.length;
    if (len !== arr1.length) {
        return false;
    }
    if (arrDim === 1) {
        for (var i = 0; i < len; i++) {
            if (arr0[i] !== arr1[i]) {
                return false;
            }
        }
    }
    else {
        var len2 = arr0[0].length;
        for (var i = 0; i < len; i++) {
            for (var j = 0; j < len2; j++) {
                if (arr0[i][j] !== arr1[i][j]) {
                    return false;
                }
            }
        }
    }
    return true;
}

/**
 * Catmull Rom interpolate array
 * @param  {Array} p0
 * @param  {Array} p1
 * @param  {Array} p2
 * @param  {Array} p3
 * @param  {number} t
 * @param  {number} t2
 * @param  {number} t3
 * @param  {Array} out
 * @param  {number} arrDim
 */
function catmullRomInterpolateArray(
    p0, p1, p2, p3, t, t2, t3, out, arrDim
) {
    var len = p0.length;
    if (arrDim === 1) {
        for (var i = 0; i < len; i++) {
            out[i] = catmullRomInterpolate(
                p0[i], p1[i], p2[i], p3[i], t, t2, t3
            );
        }
    }
    else {
        var len2 = p0[0].length;
        for (var i = 0; i < len; i++) {
            for (var j = 0; j < len2; j++) {
                out[i][j] = catmullRomInterpolate(
                    p0[i][j], p1[i][j], p2[i][j], p3[i][j],
                    t, t2, t3
                );
            }
        }
    }
}

/**
 * Catmull Rom interpolate number
 * @param  {number} p0
 * @param  {number} p1
 * @param  {number} p2
 * @param  {number} p3
 * @param  {number} t
 * @param  {number} t2
 * @param  {number} t3
 * @return {number}
 */
function catmullRomInterpolate(p0, p1, p2, p3, t, t2, t3) {
    var v0 = (p2 - p0) * 0.5;
    var v1 = (p3 - p1) * 0.5;
    return (2 * (p1 - p2) + v0 + v1) * t3
            + (-3 * (p1 - p2) - 2 * v0 - v1) * t2
            + v0 * t + p1;
}

function cloneValue(value) {
    if (isArrayLike(value)) {
        var len = value.length;
        if (isArrayLike(value[0])) {
            var ret = [];
            for (var i = 0; i < len; i++) {
                ret.push(arraySlice.call(value[i]));
            }
            return ret;
        }

        return arraySlice.call(value);
    }

    return value;
}

function rgba2String(rgba) {
    rgba[0] = Math.floor(rgba[0]);
    rgba[1] = Math.floor(rgba[1]);
    rgba[2] = Math.floor(rgba[2]);

    return 'rgba(' + rgba.join(',') + ')';
}

function getArrayDim(keyframes) {
    var lastValue = keyframes[keyframes.length - 1].value;
    return isArrayLike(lastValue && lastValue[0]) ? 2 : 1;
}

function createTrackClip(animator, easing, oneTrackDone, keyframes, propName, forceAnimate) {
    var getter = animator._getter;
    var setter = animator._setter;
    var useSpline = easing === 'spline';

    var trackLen = keyframes.length;
    if (!trackLen) {
        return;
    }
    // Guess data type
    var firstVal = keyframes[0].value;
    var isValueArray = isArrayLike(firstVal);
    var isValueColor = false;
    var isValueString = false;

    // For vertices morphing
    var arrDim = isValueArray ? getArrayDim(keyframes) : 0;

    var trackMaxTime;
    // Sort keyframe as ascending
    keyframes.sort(function (a, b) {
        return a.time - b.time;
    });

    trackMaxTime = keyframes[trackLen - 1].time;
    // Percents of each keyframe
    var kfPercents = [];
    // Value of each keyframe
    var kfValues = [];
    var prevValue = keyframes[0].value;
    var isAllValueEqual = true;
    for (var i = 0; i < trackLen; i++) {
        kfPercents.push(keyframes[i].time / trackMaxTime);
        // Assume value is a color when it is a string
        var value = keyframes[i].value;

        // Check if value is equal, deep check if value is array
        if (!((isValueArray && isArraySame(value, prevValue, arrDim))
            || (!isValueArray && value === prevValue))) {
            isAllValueEqual = false;
        }
        prevValue = value;

        // Try converting a string to a color array
        if (typeof value === 'string') {
            var colorArray = parse(value);
            if (colorArray) {
                value = colorArray;
                isValueColor = true;
            }
            else {
                isValueString = true;
            }
        }
        kfValues.push(value);
    }
    if (!forceAnimate && isAllValueEqual) {
        return;
    }

    var lastValue = kfValues[trackLen - 1];
    // Polyfill array and NaN value
    for (var i = 0; i < trackLen - 1; i++) {
        if (isValueArray) {
            fillArr(kfValues[i], lastValue, arrDim);
        }
        else {
            if (isNaN(kfValues[i]) && !isNaN(lastValue) && !isValueString && !isValueColor) {
                kfValues[i] = lastValue;
            }
        }
    }
    isValueArray && fillArr(getter(animator._target, propName), lastValue, arrDim);

    // Cache the key of last frame to speed up when
    // animation playback is sequency
    var lastFrame = 0;
    var lastFramePercent = 0;
    var start;
    var w;
    var p0;
    var p1;
    var p2;
    var p3;

    if (isValueColor) {
        var rgba = [0, 0, 0, 0];
    }

    var onframe = function (target, percent) {
        // Find the range keyframes
        // kf1-----kf2---------current--------kf3
        // find kf2 and kf3 and do interpolation
        var frame;
        // In the easing function like elasticOut, percent may less than 0
        if (percent < 0) {
            frame = 0;
        }
        else if (percent < lastFramePercent) {
            // Start from next key
            // PENDING start from lastFrame ?
            start = Math.min(lastFrame + 1, trackLen - 1);
            for (frame = start; frame >= 0; frame--) {
                if (kfPercents[frame] <= percent) {
                    break;
                }
            }
            // PENDING really need to do this ?
            frame = Math.min(frame, trackLen - 2);
        }
        else {
            for (frame = lastFrame; frame < trackLen; frame++) {
                if (kfPercents[frame] > percent) {
                    break;
                }
            }
            frame = Math.min(frame - 1, trackLen - 2);
        }
        lastFrame = frame;
        lastFramePercent = percent;

        var range = (kfPercents[frame + 1] - kfPercents[frame]);
        if (range === 0) {
            return;
        }
        else {
            w = (percent - kfPercents[frame]) / range;
        }
        if (useSpline) {
            p1 = kfValues[frame];
            p0 = kfValues[frame === 0 ? frame : frame - 1];
            p2 = kfValues[frame > trackLen - 2 ? trackLen - 1 : frame + 1];
            p3 = kfValues[frame > trackLen - 3 ? trackLen - 1 : frame + 2];
            if (isValueArray) {
                catmullRomInterpolateArray(
                    p0, p1, p2, p3, w, w * w, w * w * w,
                    getter(target, propName),
                    arrDim
                );
            }
            else {
                var value;
                if (isValueColor) {
                    value = catmullRomInterpolateArray(
                        p0, p1, p2, p3, w, w * w, w * w * w,
                        rgba, 1
                    );
                    value = rgba2String(rgba);
                }
                else if (isValueString) {
                    // String is step(0.5)
                    return interpolateString(p1, p2, w);
                }
                else {
                    value = catmullRomInterpolate(
                        p0, p1, p2, p3, w, w * w, w * w * w
                    );
                }
                setter(
                    target,
                    propName,
                    value
                );
            }
        }
        else {
            if (isValueArray) {
                interpolateArray(
                    kfValues[frame], kfValues[frame + 1], w,
                    getter(target, propName),
                    arrDim
                );
            }
            else {
                var value;
                if (isValueColor) {
                    interpolateArray(
                        kfValues[frame], kfValues[frame + 1], w,
                        rgba, 1
                    );
                    value = rgba2String(rgba);
                }
                else if (isValueString) {
                    // String is step(0.5)
                    return interpolateString(kfValues[frame], kfValues[frame + 1], w);
                }
                else {
                    value = interpolateNumber(kfValues[frame], kfValues[frame + 1], w);
                }
                setter(
                    target,
                    propName,
                    value
                );
            }
        }
    };

    var clip = new Clip({
        target: animator._target,
        life: trackMaxTime,
        loop: animator._loop,
        delay: animator._delay,
        onframe: onframe,
        ondestroy: oneTrackDone
    });

    if (easing && easing !== 'spline') {
        clip.easing = easing;
    }

    return clip;
}

/**
 * @alias module:zrender/animation/Animator
 * @constructor
 * @param {Object} target
 * @param {boolean} loop
 * @param {Function} getter
 * @param {Function} setter
 */
var Animator = function (target, loop, getter, setter) {
    this._tracks = {};
    this._target = target;

    this._loop = loop || false;

    this._getter = getter || defaultGetter;
    this._setter = setter || defaultSetter;

    this._clipCount = 0;

    this._delay = 0;

    this._doneList = [];

    this._onframeList = [];

    this._clipList = [];
};

Animator.prototype = {
    /**
     * Set Animation keyframe
     * @param  {number} time 关键帧时间，单位是ms
     * @param  {Object} props 关键帧的属性值，key-value表示
     * @return {module:zrender/animation/Animator}
     */
    when: function (time /* ms */, props) {
        var tracks = this._tracks;
        for (var propName in props) {
            if (!props.hasOwnProperty(propName)) {
                continue;
            }

            if (!tracks[propName]) {
                tracks[propName] = [];
                // Invalid value
                var value = this._getter(this._target, propName);
                if (value == null) {
                    // zrLog('Invalid property ' + propName);
                    continue;
                }
                // If time is 0
                //  Then props is given initialize value
                // Else
                //  Initialize value from current prop value
                if (time !== 0) {
                    tracks[propName].push({
                        time: 0,
                        value: cloneValue(value)
                    });
                }
            }
            tracks[propName].push({
                time: time,
                value: props[propName]
            });
        }
        return this;
    },
    /**
     * 添加动画每一帧的回调函数
     * @param  {Function} callback
     * @return {module:zrender/animation/Animator}
     */
    during: function (callback) {
        this._onframeList.push(callback);
        return this;
    },

    pause: function () {
        for (var i = 0; i < this._clipList.length; i++) {
            this._clipList[i].pause();
        }
        this._paused = true;
    },

    resume: function () {
        for (var i = 0; i < this._clipList.length; i++) {
            this._clipList[i].resume();
        }
        this._paused = false;
    },

    isPaused: function () {
        return !!this._paused;
    },

    _doneCallback: function () {
        // Clear all tracks
        this._tracks = {};
        // Clear all clips
        this._clipList.length = 0;

        var doneList = this._doneList;
        var len = doneList.length;
        for (var i = 0; i < len; i++) {
            doneList[i].call(this);
        }
    },
    /**
     * Start the animation
     * @param  {string|Function} [easing]
     *         动画缓动函数，详见{@link module:zrender/animation/easing}
     * @param  {boolean} forceAnimate
     * @return {module:zrender/animation/Animator}
     */
    start: function (easing, forceAnimate) {

        var self = this;
        var clipCount = 0;

        var oneTrackDone = function () {
            clipCount--;
            if (!clipCount) {
                self._doneCallback();
            }
        };

        var lastClip;
        for (var propName in this._tracks) {
            if (!this._tracks.hasOwnProperty(propName)) {
                continue;
            }
            var clip = createTrackClip(
                this, easing, oneTrackDone,
                this._tracks[propName], propName, forceAnimate
            );
            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);
                }
            };
        }

        // This optimization will help the case that in the upper application
        // the view may be refreshed frequently, where animation will be
        // called repeatly but nothing changed.
        if (!clipCount) {
            this._doneCallback();
        }
        return this;
    },
    /**
     * Stop animation
     * @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;
    },
    /**
     * Set when animation delay starts
     * @param  {number} time 单位ms
     * @return {module:zrender/animation/Animator}
     */
    delay: function (time) {
        this._delay = time;
        return this;
    },
    /**
     * Add callback for animation end
     * @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;
    }
};

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

/**
 * Debug log mode:
 * 0: Do nothing, for release.
 * 1: console.error, for debug.
 */
var debugMode = 0;

// retina 屏幕优化
var devicePixelRatio = dpr;

var logError = function () {
};

if (debugMode === 1) {
    logError = console.error;
}

var logError$1 = logError;

/**
 * @alias module:zrender/mixin/Animatable
 * @constructor
 */
var Animatable = function () {

    /**
     * @type {Array.<module:zrender/animation/Animator>}
     * @readOnly
     */
    this.animators = [];
};

Animatable.prototype = {

    constructor: Animatable,

    /**
     * 动画
     *
     * @param {string} path The path to fetch value from object, like 'a.b.c'.
     * @param {boolean} [loop] Whether to loop animation.
     * @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) {
            logError$1(
                '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(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;
    },

    /**
     * Caution: this method will stop previous animation.
     * So do not use this method to one element twice before
     * animation starts, unless you know what you are doing.
     * @param {Object} target
     * @param {number} [time=500] Time in ms
     * @param {string} [easing='linear']
     * @param {number} [delay=0]
     * @param {Function} [callback]
     * @param {Function} [forceAnimate] Prevent stop animation and callback
     *        immediently when target values are the same as current values.
     *
     * @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, forceAnimate) {
        animateTo(this, target, time, delay, easing, callback, forceAnimate);
    },

    /**
     * Animate from the target state to current state.
     * The params and the return value are the same as `this.animateTo`.
     */
    animateFrom: function (target, time, delay, easing, callback, forceAnimate) {
        animateTo(this, target, time, delay, easing, callback, forceAnimate, true);
    }
};

function animateTo(animatable, target, time, delay, easing, callback, forceAnimate, reverse) {
    // animateTo(target, time, easing, callback);
    if (isString(delay)) {
        callback = easing;
        easing = delay;
        delay = 0;
    }
    // animateTo(target, time, delay, callback);
    else if (isFunction$1(easing)) {
        callback = easing;
        easing = 'linear';
        delay = 0;
    }
    // animateTo(target, time, callback);
    else if (isFunction$1(delay)) {
        callback = delay;
        delay = 0;
    }
    // animateTo(target, callback)
    else if (isFunction$1(time)) {
        callback = time;
        time = 500;
    }
    // animateTo(target)
    else if (!time) {
        time = 500;
    }
    // Stop all previous animations
    animatable.stopAnimation();
    animateToShallow(animatable, '', animatable, target, time, delay, reverse);

    // Animators may be removed immediately after start
    // if there is nothing to animate
    var animators = animatable.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, forceAnimate);
    }
}

/**
 * @param {string} path=''
 * @param {Object} source=animatable
 * @param {Object} target
 * @param {number} [time=500]
 * @param {number} [delay=0]
 * @param {boolean} [reverse] If `true`, animate
 *        from the `target` to current state.
 *
 * @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)
 */
function animateToShallow(animatable, path, source, target, time, delay, reverse) {
    var objShallow = {};
    var propertyCount = 0;
    for (var name in target) {
        if (!target.hasOwnProperty(name)) {
            continue;
        }

        if (source[name] != null) {
            if (isObject$1(target[name]) && !isArrayLike(target[name])) {
                animateToShallow(
                    animatable,
                    path ? path + '.' + name : name,
                    source[name],
                    target[name],
                    time,
                    delay,
                    reverse
                );
            }
            else {
                if (reverse) {
                    objShallow[name] = source[name];
                    setAttrByPath(animatable, path, name, target[name]);
                }
                else {
                    objShallow[name] = target[name];
                }
                propertyCount++;
            }
        }
        else if (target[name] != null && !reverse) {
            setAttrByPath(animatable, path, name, target[name]);
        }
    }

    if (propertyCount > 0) {
        animatable.animate(path, false)
            .when(time == null ? 500 : time, objShallow)
            .delay(delay || 0);
    }
}

function setAttrByPath(el, path, name, value) {
    // Attr directly if not has property
    // FIXME, if some property not needed for element ?
    if (!path) {
        el.attr(name, value);
    }
    else {
        // Only support set shape or style
        var props = {};
        props[path] = {};
        props[path][name] = value;
        el.attr(props);
    }
}

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

    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,

    /**
     * 是否是 Group
     * @type {boolean}
     */
    isGroup: false,

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

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

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

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

    /**
     * @param  {Function} cb
     * @param  {}   context
     */
    traverse: function (cb, context) {},

    /**
     * @protected
     */
    attrKV: function (key, value) {
        if (key === 'position' || key === 'scale' || key === 'origin') {
            // Copy the array
            if (value) {
                var target = this[key];
                if (!target) {
                    target = this[key] = [];
                }
                target[0] = value[0];
                target[1] = value[1];
            }
        }
        else {
            this[key] = value;
        }
    },

    /**
     * Hide the element
     */
    hide: function () {
        this.ignore = true;
        this.__zr && this.__zr.refresh();
    },

    /**
     * Show the element
     */
    show: function () {
        this.ignore = false;
        this.__zr && this.__zr.refresh();
    },

    /**
     * @param {string|Object} key
     * @param {*} value
     */
    attr: function (key, value) {
        if (typeof key === 'string') {
            this.attrKV(key, value);
        }
        else if (isObject$1(key)) {
            for (var name in key) {
                if (key.hasOwnProperty(name)) {
                    this.attrKV(name, key[name]);
                }
            }
        }

        this.dirty(false);

        return this;
    },

    /**
     * @param {module:zrender/graphic/Path} clipPath
     */
    setClipPath: function (clipPath) {
        var zr = this.__zr;
        if (zr) {
            clipPath.addSelfToZr(zr);
        }

        // Remove previous clip path
        if (this.clipPath && this.clipPath !== clipPath) {
            this.removeClipPath();
        }

        this.clipPath = clipPath;
        clipPath.__zr = zr;
        clipPath.__clipTarget = this;

        this.dirty(false);
    },

    /**
     */
    removeClipPath: function () {
        var clipPath = this.clipPath;
        if (clipPath) {
            if (clipPath.__zr) {
                clipPath.removeSelfFromZr(clipPath.__zr);
            }

            clipPath.__zr = null;
            clipPath.__clipTarget = null;
            this.clipPath = null;

            this.dirty(false);
        }
    },

    /**
     * Add self from zrender instance.
     * Not recursively because it will be invoked when element added to storage.
     * @param {module:zrender/ZRender} zr
     */
    addSelfToZr: function (zr) {
        this.__zr = zr;
        // 添加动画
        var animators = this.animators;
        if (animators) {
            for (var i = 0; i < animators.length; i++) {
                zr.animation.addAnimator(animators[i]);
            }
        }

        if (this.clipPath) {
            this.clipPath.addSelfToZr(zr);
        }
    },

    /**
     * Remove self from zrender instance.
     * Not recursively because it will be invoked when element added to storage.
     * @param {module:zrender/ZRender} zr
     */
    removeSelfFromZr: function (zr) {
        this.__zr = null;
        // 移除动画
        var animators = this.animators;
        if (animators) {
            for (var i = 0; i < animators.length; i++) {
                zr.animation.removeAnimator(animators[i]);
            }
        }

        if (this.clipPath) {
            this.clipPath.removeSelfFromZr(zr);
        }
    }
};

mixin(Element, Animatable);
mixin(Element, Transformable);
mixin(Element, Eventful);

/**
 * @module echarts/core/BoundingRect
 */

var v2ApplyTransform = applyTransform;
var mathMin = Math.min;
var mathMax = Math.max;

/**
 * @alias module:echarts/core/BoundingRect
 */
function BoundingRect(x, y, width, height) {

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

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

BoundingRect.prototype = {

    constructor: BoundingRect,

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

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

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

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

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

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

        var m = create$1();

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

        return m;
    },

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

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

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

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

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

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

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

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

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

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

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

/**
 * @alias module:zrender/graphic/Group
 * @constructor
 * @extends module:zrender/mixin/Transformable
 * @extends module:zrender/mixin/Eventful
 */
var Group = function (opts) {

    opts = opts || {};

    Element.call(this, opts);

    for (var key in opts) {
        if (opts.hasOwnProperty(key)) {
            this[key] = opts[key];
        }
    }

    this._children = [];

    this.__storage = null;

    this.__dirty = true;
};

Group.prototype = {

    constructor: Group,

    isGroup: true,

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

    /**
     * 所有子孙元素是否响应鼠标事件
     * @name module:/zrender/container/Group#silent
     * @type {boolean}
     * @default false
     */
    silent: false,

    /**
     * @return {Array.<module:zrender/Element>}
     */
    children: function () {
        return this._children.slice();
    },

    /**
     * 获取指定 index 的儿子节点
     * @param  {number} idx
     * @return {module:zrender/Element}
     */
    childAt: function (idx) {
        return this._children[idx];
    },

    /**
     * 获取指定名字的儿子节点
     * @param  {string} name
     * @return {module:zrender/Element}
     */
    childOfName: function (name) {
        var children = this._children;
        for (var i = 0; i < children.length; i++) {
            if (children[i].name === name) {
                return children[i];
            }
            }
    },

    /**
     * @return {number}
     */
    childCount: function () {
        return this._children.length;
    },

    /**
     * 添加子节点到最后
     * @param {module:zrender/Element} child
     */
    add: function (child) {
        if (child && child !== this && child.parent !== this) {

            this._children.push(child);

            this._doAdd(child);
        }

        return this;
    },

    /**
     * 添加子节点在 nextSibling 之前
     * @param {module:zrender/Element} child
     * @param {module:zrender/Element} nextSibling
     */
    addBefore: function (child, nextSibling) {
        if (child && child !== this && child.parent !== this
            && nextSibling && nextSibling.parent === this) {

            var children = this._children;
            var idx = children.indexOf(nextSibling);

            if (idx >= 0) {
                children.splice(idx, 0, child);
                this._doAdd(child);
            }
        }

        return this;
    },

    _doAdd: function (child) {
        if (child.parent) {
            child.parent.remove(child);
        }

        child.parent = this;

        var storage = this.__storage;
        var zr = this.__zr;
        if (storage && storage !== child.__storage) {

            storage.addToStorage(child);

            if (child instanceof Group) {
                child.addChildrenToStorage(storage);
            }
        }

        zr && zr.refresh();
    },

    /**
     * 移除子节点
     * @param {module:zrender/Element} child
     */
    remove: function (child) {
        var zr = this.__zr;
        var storage = this.__storage;
        var children = this._children;

        var idx = indexOf(children, child);
        if (idx < 0) {
            return this;
        }
        children.splice(idx, 1);

        child.parent = null;

        if (storage) {

            storage.delFromStorage(child);

            if (child instanceof Group) {
                child.delChildrenFromStorage(storage);
            }
        }

        zr && zr.refresh();

        return this;
    },

    /**
     * 移除所有子节点
     */
    removeAll: function () {
        var children = this._children;
        var storage = this.__storage;
        var child;
        var i;
        for (i = 0; i < children.length; i++) {
            child = children[i];
            if (storage) {
                storage.delFromStorage(child);
                if (child instanceof Group) {
                    child.delChildrenFromStorage(storage);
                }
            }
            child.parent = null;
        }
        children.length = 0;

        return this;
    },

    /**
     * 遍历所有子节点
     * @param  {Function} cb
     * @param  {}   context
     */
    eachChild: function (cb, context) {
        var children = this._children;
        for (var i = 0; i < children.length; i++) {
            var child = children[i];
            cb.call(context, child, i);
        }
        return this;
    },

    /**
     * 深度优先遍历所有子孙节点
     * @param  {Function} cb
     * @param  {}   context
     */
    traverse: function (cb, context) {
        for (var i = 0; i < this._children.length; i++) {
            var child = this._children[i];
            cb.call(context, child);

            if (child.type === 'group') {
                child.traverse(cb, context);
            }
        }
        return this;
    },

    addChildrenToStorage: function (storage) {
        for (var i = 0; i < this._children.length; i++) {
            var child = this._children[i];
            storage.addToStorage(child);
            if (child instanceof Group) {
                child.addChildrenToStorage(storage);
            }
        }
    },

    delChildrenFromStorage: function (storage) {
        for (var i = 0; i < this._children.length; i++) {
            var child = this._children[i];
            storage.delFromStorage(child);
            if (child instanceof Group) {
                child.delChildrenFromStorage(storage);
            }
        }
    },

    dirty: function () {
        this.__dirty = true;
        this.__zr && this.__zr.refresh();
        return this;
    },

    /**
     * @return {module:zrender/core/BoundingRect}
     */
    getBoundingRect: function (includeChildren) {
        // TODO Caching
        var rect = null;
        var tmpRect = new BoundingRect(0, 0, 0, 0);
        var children = includeChildren || this._children;
        var tmpMat = [];

        for (var i = 0; i < children.length; i++) {
            var child = children[i];
            if (child.ignore || child.invisible) {
                continue;
            }

            var childRect = child.getBoundingRect();
            var transform = child.getLocalTransform(tmpMat);
            // TODO
            // The boundingRect cacluated by transforming original
            // rect may be bigger than the actual bundingRect when rotation
            // is used. (Consider a circle rotated aginst its center, where
            // the actual boundingRect should be the same as that not be
            // rotated.) But we can not find better approach to calculate
            // actual boundingRect yet, considering performance.
            if (transform) {
                tmpRect.copy(childRect);
                tmpRect.applyTransform(transform);
                rect = rect || tmpRect.clone();
                rect.union(tmpRect);
            }
            else {
                rect = rect || childRect.clone();
                rect.union(childRect);
            }
        }
        return rect || tmpRect;
    }
};

inherits(Group, Element);

// https://github.com/mziccard/node-timsort
var DEFAULT_MIN_MERGE = 32;

var DEFAULT_MIN_GALLOPING = 7;

function minRunLength(n) {
    var r = 0;

    while (n >= DEFAULT_MIN_MERGE) {
        r |= n & 1;
        n >>= 1;
    }

    return n + r;
}

function makeAscendingRun(array, lo, hi, compare) {
    var runHi = lo + 1;

    if (runHi === hi) {
        return 1;
    }

    if (compare(array[runHi++], array[lo]) < 0) {
        while (runHi < hi && compare(array[runHi], array[runHi - 1]) < 0) {
            runHi++;
        }

        reverseRun(array, lo, runHi);
    }
    else {
        while (runHi < hi && compare(array[runHi], array[runHi - 1]) >= 0) {
            runHi++;
        }
    }

    return runHi - lo;
}

function reverseRun(array, lo, hi) {
    hi--;

    while (lo < hi) {
        var t = array[lo];
        array[lo++] = array[hi];
        array[hi--] = t;
    }
}

function binaryInsertionSort(array, lo, hi, start, compare) {
    if (start === lo) {
        start++;
    }

    for (; start < hi; start++) {
        var pivot = array[start];

        var left = lo;
        var right = start;
        var mid;

        while (left < right) {
            mid = left + right >>> 1;

            if (compare(pivot, array[mid]) < 0) {
                right = mid;
            }
            else {
                left = mid + 1;
            }
        }

        var n = start - left;

        switch (n) {
            case 3:
                array[left + 3] = array[left + 2];

            case 2:
                array[left + 2] = array[left + 1];

            case 1:
                array[left + 1] = array[left];
                break;
            default:
                while (n > 0) {
                    array[left + n] = array[left + n - 1];
                    n--;
                }
        }

        array[left] = pivot;
    }
}

function gallopLeft(value, array, start, length, hint, compare) {
    var lastOffset = 0;
    var maxOffset = 0;
    var offset = 1;

    if (compare(value, array[start + hint]) > 0) {
        maxOffset = length - hint;

        while (offset < maxOffset && compare(value, array[start + hint + offset]) > 0) {
            lastOffset = offset;
            offset = (offset << 1) + 1;

            if (offset <= 0) {
                offset = maxOffset;
            }
        }

        if (offset > maxOffset) {
            offset = maxOffset;
        }

        lastOffset += hint;
        offset += hint;
    }
    else {
        maxOffset = hint + 1;
        while (offset < maxOffset && compare(value, array[start + hint - offset]) <= 0) {
            lastOffset = offset;
            offset = (offset << 1) + 1;

            if (offset <= 0) {
                offset = maxOffset;
            }
        }
        if (offset > maxOffset) {
            offset = maxOffset;
        }

        var tmp = lastOffset;
        lastOffset = hint - offset;
        offset = hint - tmp;
    }

    lastOffset++;
    while (lastOffset < offset) {
        var m = lastOffset + (offset - lastOffset >>> 1);

        if (compare(value, array[start + m]) > 0) {
            lastOffset = m + 1;
        }
        else {
            offset = m;
        }
    }
    return offset;
}

function gallopRight(value, array, start, length, hint, compare) {
    var lastOffset = 0;
    var maxOffset = 0;
    var offset = 1;

    if (compare(value, array[start + hint]) < 0) {
        maxOffset = hint + 1;

        while (offset < maxOffset && compare(value, array[start + hint - offset]) < 0) {
            lastOffset = offset;
            offset = (offset << 1) + 1;

            if (offset <= 0) {
                offset = maxOffset;
            }
        }

        if (offset > maxOffset) {
            offset = maxOffset;
        }

        var tmp = lastOffset;
        lastOffset = hint - offset;
        offset = hint - tmp;
    }
    else {
        maxOffset = length - hint;

        while (offset < maxOffset && compare(value, array[start + hint + offset]) >= 0) {
            lastOffset = offset;
            offset = (offset << 1) + 1;

            if (offset <= 0) {
                offset = maxOffset;
            }
        }

        if (offset > maxOffset) {
            offset = maxOffset;
        }

        lastOffset += hint;
        offset += hint;
    }

    lastOffset++;

    while (lastOffset < offset) {
        var m = lastOffset + (offset - lastOffset >>> 1);

        if (compare(value, array[start + m]) < 0) {
            offset = m;
        }
        else {
            lastOffset = m + 1;
        }
    }

    return offset;
}

function TimSort(array, compare) {
    var minGallop = DEFAULT_MIN_GALLOPING;
    var runStart;
    var runLength;
    var stackSize = 0;

    var tmp = [];

    runStart = [];
    runLength = [];

    function pushRun(_runStart, _runLength) {
        runStart[stackSize] = _runStart;
        runLength[stackSize] = _runLength;
        stackSize += 1;
    }

    function mergeRuns() {
        while (stackSize > 1) {
            var n = stackSize - 2;

            if (
                (n >= 1 && runLength[n - 1] <= runLength[n] + runLength[n + 1])
                || (n >= 2 && runLength[n - 2] <= runLength[n] + runLength[n - 1])
            ) {
                if (runLength[n - 1] < runLength[n + 1]) {
                    n--;
                }
            }
            else if (runLength[n] > runLength[n + 1]) {
                break;
            }
            mergeAt(n);
        }
    }

    function forceMergeRuns() {
        while (stackSize > 1) {
            var n = stackSize - 2;

            if (n > 0 && runLength[n - 1] < runLength[n + 1]) {
                n--;
            }

            mergeAt(n);
        }
    }

    function mergeAt(i) {
        var start1 = runStart[i];
        var length1 = runLength[i];
        var start2 = runStart[i + 1];
        var length2 = runLength[i + 1];

        runLength[i] = length1 + length2;

        if (i === stackSize - 3) {
            runStart[i + 1] = runStart[i + 2];
            runLength[i + 1] = runLength[i + 2];
        }

        stackSize--;

        var k = gallopRight(array[start2], array, start1, length1, 0, compare);
        start1 += k;
        length1 -= k;

        if (length1 === 0) {
            return;
        }

        length2 = gallopLeft(array[start1 + length1 - 1], array, start2, length2, length2 - 1, compare);

        if (length2 === 0) {
            return;
        }

        if (length1 <= length2) {
            mergeLow(start1, length1, start2, length2);
        }
        else {
            mergeHigh(start1, length1, start2, length2);
        }
    }

    function mergeLow(start1, length1, start2, length2) {
        var i = 0;

        for (i = 0; i < length1; i++) {
            tmp[i] = array[start1 + i];
        }

        var cursor1 = 0;
        var cursor2 = start2;
        var dest = start1;

        array[dest++] = array[cursor2++];

        if (--length2 === 0) {
            for (i = 0; i < length1; i++) {
                array[dest + i] = tmp[cursor1 + i];
            }
            return;
        }

        if (length1 === 1) {
            for (i = 0; i < length2; i++) {
                array[dest + i] = array[cursor2 + i];
            }
            array[dest + length2] = tmp[cursor1];
            return;
        }

        var _minGallop = minGallop;
        var count1;
        var count2;
        var exit;

        while (1) {
            count1 = 0;
            count2 = 0;
            exit = false;

            do {
                if (compare(array[cursor2], tmp[cursor1]) < 0) {
                    array[dest++] = array[cursor2++];
                    count2++;
                    count1 = 0;

                    if (--length2 === 0) {
                        exit = true;
                        break;
                    }
                }
                else {
                    array[dest++] = tmp[cursor1++];
                    count1++;
                    count2 = 0;
                    if (--length1 === 1) {
                        exit = true;
                        break;
                    }
                }
            } while ((count1 | count2) < _minGallop);

            if (exit) {
                break;
            }

            do {
                count1 = gallopRight(array[cursor2], tmp, cursor1, length1, 0, compare);

                if (count1 !== 0) {
                    for (i = 0; i < count1; i++) {
                        array[dest + i] = tmp[cursor1 + i];
                    }

                    dest += count1;
                    cursor1 += count1;
                    length1 -= count1;
                    if (length1 <= 1) {
                        exit = true;
                        break;
                    }
                }

                array[dest++] = array[cursor2++];

                if (--length2 === 0) {
                    exit = true;
                    break;
                }

                count2 = gallopLeft(tmp[cursor1], array, cursor2, length2, 0, compare);

                if (count2 !== 0) {
                    for (i = 0; i < count2; i++) {
                        array[dest + i] = array[cursor2 + i];
                    }

                    dest += count2;
                    cursor2 += count2;
                    length2 -= count2;

                    if (length2 === 0) {
                        exit = true;
                        break;
                    }
                }
                array[dest++] = tmp[cursor1++];

                if (--length1 === 1) {
                    exit = true;
                    break;
                }

                _minGallop--;
            } while (count1 >= DEFAULT_MIN_GALLOPING || count2 >= DEFAULT_MIN_GALLOPING);

            if (exit) {
                break;
            }

            if (_minGallop < 0) {
                _minGallop = 0;
            }

            _minGallop += 2;
        }

        minGallop = _minGallop;

        minGallop < 1 && (minGallop = 1);

        if (length1 === 1) {
            for (i = 0; i < length2; i++) {
                array[dest + i] = array[cursor2 + i];
            }
            array[dest + length2] = tmp[cursor1];
        }
        else if (length1 === 0) {
            throw new Error();
            // throw new Error('mergeLow preconditions were not respected');
        }
        else {
            for (i = 0; i < length1; i++) {
                array[dest + i] = tmp[cursor1 + i];
            }
        }
    }

    function mergeHigh(start1, length1, start2, length2) {
        var i = 0;

        for (i = 0; i < length2; i++) {
            tmp[i] = array[start2 + i];
        }

        var cursor1 = start1 + length1 - 1;
        var cursor2 = length2 - 1;
        var dest = start2 + length2 - 1;
        var customCursor = 0;
        var customDest = 0;

        array[dest--] = array[cursor1--];

        if (--length1 === 0) {
            customCursor = dest - (length2 - 1);

            for (i = 0; i < length2; i++) {
                array[customCursor + i] = tmp[i];
            }

            return;
        }

        if (length2 === 1) {
            dest -= length1;
            cursor1 -= length1;
            customDest = dest + 1;
            customCursor = cursor1 + 1;

            for (i = length1 - 1; i >= 0; i--) {
                array[customDest + i] = array[customCursor + i];
            }

            array[dest] = tmp[cursor2];
            return;
        }

        var _minGallop = minGallop;

        while (true) {
            var count1 = 0;
            var count2 = 0;
            var exit = false;

            do {
                if (compare(tmp[cursor2], array[cursor1]) < 0) {
                    array[dest--] = array[cursor1--];
                    count1++;
                    count2 = 0;
                    if (--length1 === 0) {
                        exit = true;
                        break;
                    }
                }
                else {
                    array[dest--] = tmp[cursor2--];
                    count2++;
                    count1 = 0;
                    if (--length2 === 1) {
                        exit = true;
                        break;
                    }
                }
            } while ((count1 | count2) < _minGallop);

            if (exit) {
                break;
            }

            do {
                count1 = length1 - gallopRight(tmp[cursor2], array, start1, length1, length1 - 1, compare);

                if (count1 !== 0) {
                    dest -= count1;
                    cursor1 -= count1;
                    length1 -= count1;
                    customDest = dest + 1;
                    customCursor = cursor1 + 1;

                    for (i = count1 - 1; i >= 0; i--) {
                        array[customDest + i] = array[customCursor + i];
                    }

                    if (length1 === 0) {
                        exit = true;
                        break;
                    }
                }

                array[dest--] = tmp[cursor2--];

                if (--length2 === 1) {
                    exit = true;
                    break;
                }

                count2 = length2 - gallopLeft(array[cursor1], tmp, 0, length2, length2 - 1, compare);

                if (count2 !== 0) {
                    dest -= count2;
                    cursor2 -= count2;
                    length2 -= count2;
                    customDest = dest + 1;
                    customCursor = cursor2 + 1;

                    for (i = 0; i < count2; i++) {
                        array[customDest + i] = tmp[customCursor + i];
                    }

                    if (length2 <= 1) {
                        exit = true;
                        break;
                    }
                }

                array[dest--] = array[cursor1--];

                if (--length1 === 0) {
                    exit = true;
                    break;
                }

                _minGallop--;
            } while (count1 >= DEFAULT_MIN_GALLOPING || count2 >= DEFAULT_MIN_GALLOPING);

            if (exit) {
                break;
            }

            if (_minGallop < 0) {
                _minGallop = 0;
            }

            _minGallop += 2;
        }

        minGallop = _minGallop;

        if (minGallop < 1) {
            minGallop = 1;
        }

        if (length2 === 1) {
            dest -= length1;
            cursor1 -= length1;
            customDest = dest + 1;
            customCursor = cursor1 + 1;

            for (i = length1 - 1; i >= 0; i--) {
                array[customDest + i] = array[customCursor + i];
            }

            array[dest] = tmp[cursor2];
        }
        else if (length2 === 0) {
            throw new Error();
            // throw new Error('mergeHigh preconditions were not respected');
        }
        else {
            customCursor = dest - (length2 - 1);
            for (i = 0; i < length2; i++) {
                array[customCursor + i] = tmp[i];
            }
        }
    }

    this.mergeRuns = mergeRuns;
    this.forceMergeRuns = forceMergeRuns;
    this.pushRun = pushRun;
}

function sort(array, compare, lo, hi) {
    if (!lo) {
        lo = 0;
    }
    if (!hi) {
        hi = array.length;
    }

    var remaining = hi - lo;

    if (remaining < 2) {
        return;
    }

    var runLength = 0;

    if (remaining < DEFAULT_MIN_MERGE) {
        runLength = makeAscendingRun(array, lo, hi, compare);
        binaryInsertionSort(array, lo, hi, lo + runLength, compare);
        return;
    }

    var ts = new TimSort(array, compare);

    var minRun = minRunLength(remaining);

    do {
        runLength = makeAscendingRun(array, lo, hi, compare);
        if (runLength < minRun) {
            var force = remaining;
            if (force > minRun) {
                force = minRun;
            }

            binaryInsertionSort(array, lo, lo + force, lo + runLength, compare);
            runLength = force;
        }

        ts.pushRun(lo, runLength);
        ts.mergeRuns();

        remaining -= runLength;
        lo += runLength;
    } while (remaining !== 0);

    ts.forceMergeRuns();
}

// Use timsort because in most case elements are partially sorted
// https://jsfiddle.net/pissang/jr4x7mdm/8/
function shapeCompareFunc(a, b) {
    if (a.zlevel === b.zlevel) {
        if (a.z === b.z) {
            // if (a.z2 === b.z2) {
            //     // FIXME Slow has renderidx compare
            //     // http://stackoverflow.com/questions/20883421/sorting-in-javascript-should-every-compare-function-have-a-return-0-statement
            //     // https://github.com/v8/v8/blob/47cce544a31ed5577ffe2963f67acb4144ee0232/src/js/array.js#L1012
            //     return a.__renderidx - b.__renderidx;
            // }
            return a.z2 - b.z2;
        }
        return a.z - b.z;
    }
    return a.zlevel - b.zlevel;
}
/**
 * 内容仓库 (M)
 * @alias module:zrender/Storage
 * @constructor
 */
var Storage = function () { // jshint ignore:line
    this._roots = [];

    this._displayList = [];

    this._displayListLen = 0;
};

Storage.prototype = {

    constructor: Storage,

    /**
     * @param  {Function} cb
     *
     */
    traverse: function (cb, context) {
        for (var i = 0; i < this._roots.length; i++) {
            this._roots[i].traverse(cb, context);
        }
    },

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

    /**
     * 更新图形的绘制队列。
     * 每次绘制前都会调用，该方法会先深度优先遍历整个树，更新所有Group和Shape的变换并且把所有可见的Shape保存到数组中，
     * 最后根据绘制的优先级（zlevel > z > 插入顺序）排序得到绘制队列
     * @param {boolean} [includeIgnore=false] 是否包含 ignore 的数组
     */
    updateDisplayList: function (includeIgnore) {
        this._displayListLen = 0;

        var roots = this._roots;
        var displayList = this._displayList;
        for (var i = 0, len = roots.length; i < len; i++) {
            this._updateAndAddDisplayable(roots[i], null, includeIgnore);
        }

        displayList.length = this._displayListLen;

        env$1.canvasSupported && sort(displayList, shapeCompareFunc);
    },

    _updateAndAddDisplayable: function (el, clipPaths, includeIgnore) {

        if (el.ignore && !includeIgnore) {
            return;
        }

        el.beforeUpdate();

        if (el.__dirty) {

            el.update();

        }

        el.afterUpdate();

        var userSetClipPath = el.clipPath;
        if (userSetClipPath) {

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

            var currentClipPath = userSetClipPath;
            var parentClipPath = el;
            // Recursively add clip path
            while (currentClipPath) {
                // clipPath 的变换是基于使用这个 clipPath 的元素
                currentClipPath.parent = parentClipPath;
                currentClipPath.updateTransform();

                clipPaths.push(currentClipPath);

                parentClipPath = currentClipPath;
                currentClipPath = currentClipPath.clipPath;
            }
        }

        if (el.isGroup) {
            var children = el._children;

            for (var i = 0; i < children.length; i++) {
                var child = children[i];

                // Force to mark as dirty if group is dirty
                // FIXME __dirtyPath ?
                if (el.__dirty) {
                    child.__dirty = true;
                }

                this._updateAndAddDisplayable(child, clipPaths, includeIgnore);
            }

            // Mark group clean here
            el.__dirty = false;

        }
        else {
            el.__clipPaths = clipPaths;

            this._displayList[this._displayListLen++] = el;
        }
    },

    /**
     * 添加图形(Shape)或者组(Group)到根节点
     * @param {module:zrender/Element} el
     */
    addRoot: function (el) {
        if (el.__storage === this) {
            return;
        }

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

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

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

            this._roots = [];
            this._displayList = [];
            this._displayListLen = 0;

            return;
        }

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


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

    addToStorage: function (el) {
        if (el) {
            el.__storage = this;
            el.dirty(false);
        }
        return this;
    },

    delFromStorage: function (el) {
        if (el) {
            el.__storage = null;
        }

        return this;
    },

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

    displayableSortFunc: shapeCompareFunc
};

var SHADOW_PROPS = {
    'shadowBlur': 1,
    'shadowOffsetX': 1,
    'shadowOffsetY': 1,
    'textShadowBlur': 1,
    'textShadowOffsetX': 1,
    'textShadowOffsetY': 1,
    'textBoxShadowBlur': 1,
    'textBoxShadowOffsetX': 1,
    'textBoxShadowOffsetY': 1
};

var fixShadow = function (ctx, propName, value) {
    if (SHADOW_PROPS.hasOwnProperty(propName)) {
        return value *= ctx.dpr;
    }
    return value;
};

var ContextCachedBy = {
    NONE: 0,
    STYLE_BIND: 1,
    PLAIN_TEXT: 2
};

// Avoid confused with 0/false.
var WILL_BE_RESTORED = 9;

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

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

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

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

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

    // Fix NaN when rect is Infinity
    x = isNaN(x) ? 0 : x;
    x2 = isNaN(x2) ? 1 : x2;
    y = isNaN(y) ? 0 : y;
    y2 = isNaN(y2) ? 0 : y2;

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

    return canvasGradient;
}

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

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

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

    return canvasGradient;
}


Style.prototype = {

    constructor: Style,

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

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

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

    /**
     * @type {number}
     */
    fillOpacity: null,

    /**
     * @type {number}
     */
    strokeOpacity: null,

    /**
     * `true` is not supported.
     * `false`/`null`/`undefined` are the same.
     * `false` is used to remove lineDash in some
     * case that `null`/`undefined` can not be set.
     * (e.g., emphasis.lineStyle in echarts)
     * @type {Array.<number>|boolean}
     */
    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,

    /**
     * If `fontSize` or `fontFamily` exists, `font` will be reset by
     * `fontSize`, `fontStyle`, `fontWeight`, `fontFamily`.
     * So do not visit it directly in upper application (like echarts),
     * but use `contain/text#makeFont` instead.
     * @type {string}
     */
    font: null,

    /**
     * The same as font. Use font please.
     * @deprecated
     * @type {string}
     */
    textFont: null,

    /**
     * It helps merging respectively, rather than parsing an entire font string.
     * @type {string}
     */
    fontStyle: null,

    /**
     * It helps merging respectively, rather than parsing an entire font string.
     * @type {string}
     */
    fontWeight: null,

    /**
     * It helps merging respectively, rather than parsing an entire font string.
     * Should be 12 but not '12px'.
     * @type {number}
     */
    fontSize: null,

    /**
     * It helps merging respectively, rather than parsing an entire font string.
     * @type {string}
     */
    fontFamily: null,

    /**
     * Reserved for special functinality, like 'hr'.
     * @type {string}
     */
    textTag: null,

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

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

    /**
     * @type {number}
     */
    textWidth: null,

    /**
     * Only for textBackground.
     * @type {number}
     */
    textHeight: null,

    /**
     * textStroke may be set as some color as a default
     * value in upper applicaion, where the default value
     * of textStrokeWidth should be 0 to make sure that
     * user can choose to do not use text stroke.
     * @type {number}
     */
    textStrokeWidth: 0,

    /**
     * @type {number}
     */
    textLineHeight: null,

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

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

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

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

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

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

    /**
     * @type {string}
     */
    textShadowColor: 'transparent',

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

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

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

    /**
     * @type {string}
     */
    textBoxShadowColor: 'transparent',

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

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

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

    /**
     * Whether transform text.
     * Only available in Path and Image element,
     * where the text is called as `RectText`.
     * @type {boolean}
     */
    transformText: false,

    /**
     * Text rotate around position of Path or Image.
     * The origin of the rotation can be specified by `textOrigin`.
     * Only available in Path and Image element,
     * where the text is called as `RectText`.
     */
    textRotation: 0,

    /**
     * Text origin of text rotation.
     * Useful in the case like label rotation of circular symbol.
     * Only available in Path and Image element, where the text is called
     * as `RectText` and the element is called as "host element".
     * The value can be:
     * + If specified as a coordinate like `[10, 40]`, it is the `[x, y]`
     * base on the left-top corner of the rect of its host element.
     * + If specified as a string `center`, it is the center of the rect of
     * its host element.
     * + By default, this origin is the `textPosition`.
     * @type {string|Array.<number>}
     */
    textOrigin: null,

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

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

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

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

    /**
     * Can be `2` or `[2, 4]` or `[2, 3, 4, 5]`
     * @type {number|Array.<number>}
     */
    textPadding: null,

    /**
     * Text styles for rich text.
     * @type {Object}
     */
    rich: null,

    /**
     * {outerWidth, outerHeight, ellipsis, placeholder}
     * @type {Object}
     */
    truncate: null,

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

    /**
     * @param {CanvasRenderingContext2D} ctx
     */
    bind: function (ctx, el, prevEl) {
        var style = this;
        var prevStyle = prevEl && prevEl.style;
        // If no prevStyle, it means first draw.
        // Only apply cache if the last time cachced by this function.
        var notCheckCache = !prevStyle || ctx.__attrCachedBy !== ContextCachedBy.STYLE_BIND;

        ctx.__attrCachedBy = ContextCachedBy.STYLE_BIND;

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

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

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

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

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

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

    /**
     * Extend from other style
     * @param {zrender/graphic/Style} otherStyle
     * @param {boolean} overwrite true: overwrirte any way.
     *                            false: overwrite only when !target.hasOwnProperty
     *                            others: overwrite when property is not null/undefined.
     */
    extendFrom: function (otherStyle, overwrite) {
        if (otherStyle) {
            for (var name in otherStyle) {
                if (otherStyle.hasOwnProperty(name)
                    && (overwrite === true
                        || (
                            overwrite === false
                                ? !this.hasOwnProperty(name)
                                : otherStyle[name] != null
                        )
                    )
                ) {
                    this[name] = otherStyle[name];
                }
            }
        }
    },

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

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

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

};

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

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

var Pattern = function (image, repeat) {
    // Should do nothing more in this constructor. Because gradient can be
    // declard by `color: {image: ...}`, where this constructor will not be called.

    this.image = image;
    this.repeat = repeat;

    // Can be cloned
    this.type = 'pattern';
};

Pattern.prototype.getCanvasPattern = function (ctx) {
    return ctx.createPattern(this.image, this.repeat || 'repeat');
};

/**
 * @module zrender/Layer
 * @author pissang(https://www.github.com/pissang)
 */

function returnFalse() {
    return false;
}

/**
 * 创建dom
 *
 * @inner
 * @param {string} id dom id 待用
 * @param {Painter} painter painter instance
 * @param {number} number
 */
function createDom(id, painter, dpr) {
    var newDom = createCanvas();
    var width = painter.getWidth();
    var height = painter.getHeight();

    var newDomStyle = newDom.style;
    if (newDomStyle) {  // In node or some other non-browser environment
        newDomStyle.position = 'absolute';
        newDomStyle.left = 0;
        newDomStyle.top = 0;
        newDomStyle.width = width + 'px';
        newDomStyle.height = height + 'px';

        newDom.setAttribute('data-zr-dom-id', id);
    }

    newDom.width = width * dpr;
    newDom.height = height * dpr;

    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 || devicePixelRatio;
    if (typeof id === 'string') {
        dom = createDom(id, painter, dpr);
    }
    // Not using isDom because in node it will return false
    else if (isObject$1(id)) {
        dom = id;
        id = dom.id;
    }
    this.id = id;
    this.dom = dom;

    var domStyle = dom.style;
    if (domStyle) { // Not in node
        dom.onselectstart = returnFalse; // 避免页面选中的尴尬
        domStyle['-webkit-user-select'] = 'none';
        domStyle['user-select'] = 'none';
        domStyle['-webkit-touch-callout'] = 'none';
        domStyle['-webkit-tap-highlight-color'] = 'rgba(0,0,0,0)';
        domStyle['padding'] = 0; // eslint-disable-line dot-notation
        domStyle['margin'] = 0; // eslint-disable-line dot-notation
        domStyle['border-width'] = 0;
    }

    this.domBack = null;
    this.ctxBack = null;

    this.painter = painter;

    this.config = null;

    // Configs
    /**
     * 每次清空画布的颜色
     * @type {string}
     * @default 0
     */
    this.clearColor = 0;
    /**
     * 是否开启动态模糊
     * @type {boolean}
     * @default false
     */
    this.motionBlur = false;
    /**
     * 在开启动态模糊的时候使用，与上一帧混合的alpha值，值越大尾迹越明显
     * @type {number}
     * @default 0.7
     */
    this.lastFrameAlpha = 0.7;

    /**
     * Layer dpr
     * @type {number}
     */
    this.dpr = dpr;
};

Layer.prototype = {

    constructor: Layer,

    __dirty: true,

    __used: false,

    __drawIndex: 0,
    __startIndex: 0,
    __endIndex: 0,

    incremental: false,

    getElementCount: function () {
        return this.__endIndex - this.__startIndex;
    },

    initContext: function () {
        this.ctx = this.dom.getContext('2d');
        this.ctx.dpr = this.dpr;
    },

    createBackBuffer: function () {
        var dpr = this.dpr;

        this.domBack = createDom('back-' + this.id, 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;

        if (domStyle) {
            domStyle.width = width + 'px';
            domStyle.height = height + 'px';
        }

        dom.width = width * dpr;
        dom.height = height * dpr;

        if (domBack) {
            domBack.width = width * dpr;
            domBack.height = height * dpr;

            if (dpr !== 1) {
                this.ctxBack.scale(dpr, dpr);
            }
        }
    },

    /**
     * 清空该层画布
     * @param {boolean} [clearAll]=false Clear all with out motion blur
     * @param {Color} [clearColor]
     */
    clear: function (clearAll, clearColor) {
        var dom = this.dom;
        var ctx = this.ctx;
        var width = dom.width;
        var height = dom.height;

        var clearColor = clearColor || this.clearColor;
        var haveMotionBLur = this.motionBlur && !clearAll;
        var lastFrameAlpha = this.lastFrameAlpha;

        var dpr = this.dpr;

        if (haveMotionBLur) {
            if (!this.domBack) {
                this.createBackBuffer();
            }

            this.ctxBack.globalCompositeOperation = 'copy';
            this.ctxBack.drawImage(
                dom, 0, 0,
                width / dpr,
                height / dpr
            );
        }

        ctx.clearRect(0, 0, width, height);
        if (clearColor && clearColor !== 'transparent') {
            var clearColorGradientOrPattern;
            // Gradient
            if (clearColor.colorStops) {
                // Cache canvas gradient
                clearColorGradientOrPattern = clearColor.__canvasGradient || Style.getGradient(ctx, clearColor, {
                    x: 0,
                    y: 0,
                    width: width,
                    height: height
                });

                clearColor.__canvasGradient = clearColorGradientOrPattern;
            }
            // Pattern
            else if (clearColor.image) {
                clearColorGradientOrPattern = Pattern.prototype.getCanvasPattern.call(clearColor, ctx);
            }
            ctx.save();
            ctx.fillStyle = clearColorGradientOrPattern || clearColor;
            ctx.fillRect(0, 0, width, height);
            ctx.restore();
        }

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

var requestAnimationFrame = (
    typeof window !== 'undefined'
    && (
        (window.requestAnimationFrame && window.requestAnimationFrame.bind(window))
        // https://github.com/ecomfe/zrender/issues/189#issuecomment-224919809
        || (window.msRequestAnimationFrame && window.msRequestAnimationFrame.bind(window))
        || window.mozRequestAnimationFrame
        || window.webkitRequestAnimationFrame
    )
) || function (func) {
    setTimeout(func, 16);
};

var globalImageCache = new LRU(50);

/**
 * @param {string|HTMLImageElement|HTMLCanvasElement|Canvas} newImageOrSrc
 * @return {HTMLImageElement|HTMLCanvasElement|Canvas} image
 */
function findExistImage(newImageOrSrc) {
    if (typeof newImageOrSrc === 'string') {
        var cachedImgObj = globalImageCache.get(newImageOrSrc);
        return cachedImgObj && cachedImgObj.image;
    }
    else {
        return newImageOrSrc;
    }
}

/**
 * Caution: User should cache loaded images, but not just count on LRU.
 * Consider if required images more than LRU size, will dead loop occur?
 *
 * @param {string|HTMLImageElement|HTMLCanvasElement|Canvas} newImageOrSrc
 * @param {HTMLImageElement|HTMLCanvasElement|Canvas} image Existent image.
 * @param {module:zrender/Element} [hostEl] For calling `dirty`.
 * @param {Function} [cb] params: (image, cbPayload)
 * @param {Object} [cbPayload] Payload on cb calling.
 * @return {HTMLImageElement|HTMLCanvasElement|Canvas} image
 */
function createOrUpdateImage(newImageOrSrc, image, hostEl, cb, cbPayload) {
    if (!newImageOrSrc) {
        return image;
    }
    else if (typeof newImageOrSrc === 'string') {

        // Image should not be loaded repeatly.
        if ((image && image.__zrImageSrc === newImageOrSrc) || !hostEl) {
            return image;
        }

        // Only when there is no existent image or existent image src
        // is different, this method is responsible for load.
        var cachedImgObj = globalImageCache.get(newImageOrSrc);

        var pendingWrap = {hostEl: hostEl, cb: cb, cbPayload: cbPayload};

        if (cachedImgObj) {
            image = cachedImgObj.image;
            !isImageReady(image) && cachedImgObj.pending.push(pendingWrap);
        }
        else {
            image = new Image();
            image.onload = image.onerror = imageOnLoad;

            globalImageCache.put(
                newImageOrSrc,
                image.__cachedImgObj = {
                    image: image,
                    pending: [pendingWrap]
                }
            );

            image.src = image.__zrImageSrc = newImageOrSrc;
        }

        return image;
    }
    // newImageOrSrc is an HTMLImageElement or HTMLCanvasElement or Canvas
    else {
        return newImageOrSrc;
    }
}

function imageOnLoad() {
    var cachedImgObj = this.__cachedImgObj;
    this.onload = this.onerror = this.__cachedImgObj = null;

    for (var i = 0; i < cachedImgObj.pending.length; i++) {
        var pendingWrap = cachedImgObj.pending[i];
        var cb = pendingWrap.cb;
        cb && cb(this, pendingWrap.cbPayload);
        pendingWrap.hostEl.dirty();
    }
    cachedImgObj.pending.length = 0;
}

function isImageReady(image) {
    return image && image.width && image.height;
}

var textWidthCache = {};
var textWidthCacheCounter = 0;

var TEXT_CACHE_MAX = 5000;
var STYLE_REG = /\{([a-zA-Z0-9_]+)\|([^}]*)\}/g;

var DEFAULT_FONT$1 = '12px sans-serif';

// Avoid assign to an exported variable, for transforming to cjs.
var methods$1 = {};

function $override$1(name, fn) {
    methods$1[name] = fn;
}

/**
 * @public
 * @param {string} text
 * @param {string} font
 * @return {number} width
 */
function getWidth(text, font) {
    font = font || DEFAULT_FONT$1;
    var key = text + ':' + font;
    if (textWidthCache[key]) {
        return textWidthCache[key];
    }

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

    for (var i = 0, l = textLines.length; i < l; i++) {
        // textContain.measureText may be overrided in SVG or VML
        width = Math.max(measureText(textLines[i], font).width, width);
    }

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

    return width;
}

/**
 * @public
 * @param {string} text
 * @param {string} font
 * @param {string} [textAlign='left']
 * @param {string} [textVerticalAlign='top']
 * @param {Array.<number>} [textPadding]
 * @param {Object} [rich]
 * @param {Object} [truncate]
 * @return {Object} {x, y, width, height, lineHeight}
 */
function getBoundingRect(text, font, textAlign, textVerticalAlign, textPadding, textLineHeight, rich, truncate) {
    return rich
        ? getRichTextRect(text, font, textAlign, textVerticalAlign, textPadding, textLineHeight, rich, truncate)
        : getPlainTextRect(text, font, textAlign, textVerticalAlign, textPadding, textLineHeight, truncate);
}

function getPlainTextRect(text, font, textAlign, textVerticalAlign, textPadding, textLineHeight, truncate) {
    var contentBlock = parsePlainText(text, font, textPadding, textLineHeight, truncate);
    var outerWidth = getWidth(text, font);
    if (textPadding) {
        outerWidth += textPadding[1] + textPadding[3];
    }
    var outerHeight = contentBlock.outerHeight;

    var x = adjustTextX(0, outerWidth, textAlign);
    var y = adjustTextY(0, outerHeight, textVerticalAlign);

    var rect = new BoundingRect(x, y, outerWidth, outerHeight);
    rect.lineHeight = contentBlock.lineHeight;

    return rect;
}

function getRichTextRect(text, font, textAlign, textVerticalAlign, textPadding, textLineHeight, rich, truncate) {
    var contentBlock = parseRichText(text, {
        rich: rich,
        truncate: truncate,
        font: font,
        textAlign: textAlign,
        textPadding: textPadding,
        textLineHeight: textLineHeight
    });
    var outerWidth = contentBlock.outerWidth;
    var outerHeight = contentBlock.outerHeight;

    var x = adjustTextX(0, outerWidth, textAlign);
    var y = adjustTextY(0, outerHeight, textVerticalAlign);

    return new BoundingRect(x, y, outerWidth, outerHeight);
}

/**
 * @public
 * @param {number} x
 * @param {number} width
 * @param {string} [textAlign='left']
 * @return {number} Adjusted x.
 */
function adjustTextX(x, width, textAlign) {
    // FIXME Right to left language
    if (textAlign === 'right') {
        x -= width;
    }
    else if (textAlign === 'center') {
        x -= width / 2;
    }
    return x;
}

/**
 * @public
 * @param {number} y
 * @param {number} height
 * @param {string} [textVerticalAlign='top']
 * @return {number} Adjusted y.
 */
function adjustTextY(y, height, textVerticalAlign) {
    if (textVerticalAlign === 'middle') {
        y -= height / 2;
    }
    else if (textVerticalAlign === 'bottom') {
        y -= height;
    }
    return y;
}

/**
 * Follow same interface to `Displayable.prototype.calculateTextPosition`.
 * @public
 * @param {Obejct} [out] Prepared out object. If not input, auto created in the method.
 * @param {module:zrender/graphic/Style} style where `textPosition` and `textDistance` are visited.
 * @param {Object} rect {x, y, width, height} Rect of the host elment, according to which the text positioned.
 * @return {Object} The input `out`. Set: {x, y, textAlign, textVerticalAlign}
 */
function calculateTextPosition(out, style, rect) {
    var textPosition = style.textPosition;
    var distance = style.textDistance;

    var x = rect.x;
    var y = rect.y;
    distance = distance || 0;

    var height = rect.height;
    var width = rect.width;
    var halfHeight = height / 2;

    var textAlign = 'left';
    var textVerticalAlign = 'top';

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

    out = out || {};
    out.x = x;
    out.y = y;
    out.textAlign = textAlign;
    out.textVerticalAlign = textVerticalAlign;

    return out;
}

/**
 * To be removed. But still do not remove in case that some one has imported it.
 * @deprecated
 * @public
 * @param {stirng} textPosition
 * @param {Object} rect {x, y, width, height}
 * @param {number} distance
 * @return {Object} {x, y, textAlign, textVerticalAlign}
 */


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

    var textLines = (text + '').split('\n');
    options = prepareTruncateOptions(containerWidth, font, ellipsis, options);

    // FIXME
    // It is not appropriate that every line has '...' when truncate multiple lines.
    for (var i = 0, len = textLines.length; i < len; i++) {
        textLines[i] = truncateSingleLine(textLines[i], options);
    }

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

function prepareTruncateOptions(containerWidth, font, ellipsis, options) {
    options = extend({}, options);

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

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

    var ellipsisWidth = getWidth(ellipsis, font);
    if (ellipsisWidth > contentWidth) {
        ellipsis = '';
        ellipsisWidth = 0;
    }

    contentWidth = containerWidth - ellipsisWidth;

    options.ellipsis = ellipsis;
    options.ellipsisWidth = ellipsisWidth;
    options.contentWidth = contentWidth;
    options.containerWidth = containerWidth;

    return options;
}

function truncateSingleLine(textLine, options) {
    var containerWidth = options.containerWidth;
    var font = options.font;
    var contentWidth = options.contentWidth;

    if (!containerWidth) {
        return '';
    }

    var lineWidth = getWidth(textLine, font);

    if (lineWidth <= containerWidth) {
        return textLine;
    }

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

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

        textLine = textLine.substr(0, subLength);
        lineWidth = getWidth(textLine, font);
    }

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

    return textLine;
}

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

/**
 * @public
 * @param {string} font
 * @return {number} line height
 */
function getLineHeight(font) {
    // FIXME A rough approach.
    return getWidth('国', font);
}

/**
 * @public
 * @param {string} text
 * @param {string} font
 * @return {Object} width
 */
function measureText(text, font) {
    return methods$1.measureText(text, font);
}

// Avoid assign to an exported variable, for transforming to cjs.
methods$1.measureText = function (text, font) {
    var ctx = getContext();
    ctx.font = font || DEFAULT_FONT$1;
    return ctx.measureText(text);
};

/**
 * @public
 * @param {string} text
 * @param {string} font
 * @param {Object} [truncate]
 * @return {Object} block: {lineHeight, lines, height, outerHeight, canCacheByTextString}
 *  Notice: for performance, do not calculate outerWidth util needed.
 *  `canCacheByTextString` means the result `lines` is only determined by the input `text`.
 *  Thus we can simply comparing the `input` text to determin whether the result changed,
 *  without travel the result `lines`.
 */
function parsePlainText(text, font, padding, textLineHeight, truncate) {
    text != null && (text += '');

    var lineHeight = retrieve2(textLineHeight, getLineHeight(font));
    var lines = text ? text.split('\n') : [];
    var height = lines.length * lineHeight;
    var outerHeight = height;
    var canCacheByTextString = true;

    if (padding) {
        outerHeight += padding[0] + padding[2];
    }

    if (text && truncate) {
        canCacheByTextString = false;
        var truncOuterHeight = truncate.outerHeight;
        var truncOuterWidth = truncate.outerWidth;
        if (truncOuterHeight != null && outerHeight > truncOuterHeight) {
            text = '';
            lines = [];
        }
        else if (truncOuterWidth != null) {
            var options = prepareTruncateOptions(
                truncOuterWidth - (padding ? padding[1] + padding[3] : 0),
                font,
                truncate.ellipsis,
                {minChar: truncate.minChar, placeholder: truncate.placeholder}
            );

            // FIXME
            // It is not appropriate that every line has '...' when truncate multiple lines.
            for (var i = 0, len = lines.length; i < len; i++) {
                lines[i] = truncateSingleLine(lines[i], options);
            }
        }
    }

    return {
        lines: lines,
        height: height,
        outerHeight: outerHeight,
        lineHeight: lineHeight,
        canCacheByTextString: canCacheByTextString
    };
}

/**
 * For example: 'some text {a|some text}other text{b|some text}xxx{c|}xxx'
 * Also consider 'bbbb{a|xxx\nzzz}xxxx\naaaa'.
 *
 * @public
 * @param {string} text
 * @param {Object} style
 * @return {Object} block
 * {
 *      width,
 *      height,
 *      lines: [{
 *          lineHeight,
 *          width,
 *          tokens: [[{
 *              styleName,
 *              text,
 *              width,      // include textPadding
 *              height,     // include textPadding
 *              textWidth, // pure text width
 *              textHeight, // pure text height
 *              lineHeihgt,
 *              font,
 *              textAlign,
 *              textVerticalAlign
 *          }], [...], ...]
 *      }, ...]
 * }
 * If styleName is undefined, it is plain text.
 */
function parseRichText(text, style) {
    var contentBlock = {lines: [], width: 0, height: 0};

    text != null && (text += '');
    if (!text) {
        return contentBlock;
    }

    var lastIndex = STYLE_REG.lastIndex = 0;
    var result;
    while ((result = STYLE_REG.exec(text)) != null) {
        var matchedIndex = result.index;
        if (matchedIndex > lastIndex) {
            pushTokens(contentBlock, text.substring(lastIndex, matchedIndex));
        }
        pushTokens(contentBlock, result[2], result[1]);
        lastIndex = STYLE_REG.lastIndex;
    }

    if (lastIndex < text.length) {
        pushTokens(contentBlock, text.substring(lastIndex, text.length));
    }

    var lines = contentBlock.lines;
    var contentHeight = 0;
    var contentWidth = 0;
    // For `textWidth: 100%`
    var pendingList = [];

    var stlPadding = style.textPadding;

    var truncate = style.truncate;
    var truncateWidth = truncate && truncate.outerWidth;
    var truncateHeight = truncate && truncate.outerHeight;
    if (stlPadding) {
        truncateWidth != null && (truncateWidth -= stlPadding[1] + stlPadding[3]);
        truncateHeight != null && (truncateHeight -= stlPadding[0] + stlPadding[2]);
    }

    // Calculate layout info of tokens.
    for (var i = 0; i < lines.length; i++) {
        var line = lines[i];
        var lineHeight = 0;
        var lineWidth = 0;

        for (var j = 0; j < line.tokens.length; j++) {
            var token = line.tokens[j];
            var tokenStyle = token.styleName && style.rich[token.styleName] || {};
            // textPadding should not inherit from style.
            var textPadding = token.textPadding = tokenStyle.textPadding;

            // textFont has been asigned to font by `normalizeStyle`.
            var font = token.font = tokenStyle.font || style.font;

            // textHeight can be used when textVerticalAlign is specified in token.
            var tokenHeight = token.textHeight = retrieve2(
                // textHeight should not be inherited, consider it can be specified
                // as box height of the block.
                tokenStyle.textHeight, getLineHeight(font)
            );
            textPadding && (tokenHeight += textPadding[0] + textPadding[2]);
            token.height = tokenHeight;
            token.lineHeight = retrieve3(
                tokenStyle.textLineHeight, style.textLineHeight, tokenHeight
            );

            token.textAlign = tokenStyle && tokenStyle.textAlign || style.textAlign;
            token.textVerticalAlign = tokenStyle && tokenStyle.textVerticalAlign || 'middle';

            if (truncateHeight != null && contentHeight + token.lineHeight > truncateHeight) {
                return {lines: [], width: 0, height: 0};
            }

            token.textWidth = getWidth(token.text, font);
            var tokenWidth = tokenStyle.textWidth;
            var tokenWidthNotSpecified = tokenWidth == null || tokenWidth === 'auto';

            // Percent width, can be `100%`, can be used in drawing separate
            // line when box width is needed to be auto.
            if (typeof tokenWidth === 'string' && tokenWidth.charAt(tokenWidth.length - 1) === '%') {
                token.percentWidth = tokenWidth;
                pendingList.push(token);
                tokenWidth = 0;
                // Do not truncate in this case, because there is no user case
                // and it is too complicated.
            }
            else {
                if (tokenWidthNotSpecified) {
                    tokenWidth = token.textWidth;

                    // FIXME: If image is not loaded and textWidth is not specified, calling
                    // `getBoundingRect()` will not get correct result.
                    var textBackgroundColor = tokenStyle.textBackgroundColor;
                    var bgImg = textBackgroundColor && textBackgroundColor.image;

                    // Use cases:
                    // (1) If image is not loaded, it will be loaded at render phase and call
                    // `dirty()` and `textBackgroundColor.image` will be replaced with the loaded
                    // image, and then the right size will be calculated here at the next tick.
                    // See `graphic/helper/text.js`.
                    // (2) If image loaded, and `textBackgroundColor.image` is image src string,
                    // use `imageHelper.findExistImage` to find cached image.
                    // `imageHelper.findExistImage` will always be called here before
                    // `imageHelper.createOrUpdateImage` in `graphic/helper/text.js#renderRichText`
                    // which ensures that image will not be rendered before correct size calcualted.
                    if (bgImg) {
                        bgImg = findExistImage(bgImg);
                        if (isImageReady(bgImg)) {
                            tokenWidth = Math.max(tokenWidth, bgImg.width * tokenHeight / bgImg.height);
                        }
                    }
                }

                var paddingW = textPadding ? textPadding[1] + textPadding[3] : 0;
                tokenWidth += paddingW;

                var remianTruncWidth = truncateWidth != null ? truncateWidth - lineWidth : null;

                if (remianTruncWidth != null && remianTruncWidth < tokenWidth) {
                    if (!tokenWidthNotSpecified || remianTruncWidth < paddingW) {
                        token.text = '';
                        token.textWidth = tokenWidth = 0;
                    }
                    else {
                        token.text = truncateText(
                            token.text, remianTruncWidth - paddingW, font, truncate.ellipsis,
                            {minChar: truncate.minChar}
                        );
                        token.textWidth = getWidth(token.text, font);
                        tokenWidth = token.textWidth + paddingW;
                    }
                }
            }

            lineWidth += (token.width = tokenWidth);
            tokenStyle && (lineHeight = Math.max(lineHeight, token.lineHeight));
        }

        line.width = lineWidth;
        line.lineHeight = lineHeight;
        contentHeight += lineHeight;
        contentWidth = Math.max(contentWidth, lineWidth);
    }

    contentBlock.outerWidth = contentBlock.width = retrieve2(style.textWidth, contentWidth);
    contentBlock.outerHeight = contentBlock.height = retrieve2(style.textHeight, contentHeight);

    if (stlPadding) {
        contentBlock.outerWidth += stlPadding[1] + stlPadding[3];
        contentBlock.outerHeight += stlPadding[0] + stlPadding[2];
    }

    for (var i = 0; i < pendingList.length; i++) {
        var token = pendingList[i];
        var percentWidth = token.percentWidth;
        // Should not base on outerWidth, because token can not be placed out of padding.
        token.width = parseInt(percentWidth, 10) / 100 * contentWidth;
    }

    return contentBlock;
}

function pushTokens(block, str, styleName) {
    var isEmptyStr = str === '';
    var strs = str.split('\n');
    var lines = block.lines;

    for (var i = 0; i < strs.length; i++) {
        var text = strs[i];
        var token = {
            styleName: styleName,
            text: text,
            isLineHolder: !text && !isEmptyStr
        };

        // The first token should be appended to the last line.
        if (!i) {
            var tokens = (lines[lines.length - 1] || (lines[0] = {tokens: []})).tokens;

            // Consider cases:
            // (1) ''.split('\n') => ['', '\n', ''], the '' at the first item
            // (which is a placeholder) should be replaced by new token.
            // (2) A image backage, where token likes {a|}.
            // (3) A redundant '' will affect textAlign in line.
            // (4) tokens with the same tplName should not be merged, because
            // they should be displayed in different box (with border and padding).
            var tokensLen = tokens.length;
            (tokensLen === 1 && tokens[0].isLineHolder)
                ? (tokens[0] = token)
                // Consider text is '', only insert when it is the "lineHolder" or
                // "emptyStr". Otherwise a redundant '' will affect textAlign in line.
                : ((text || !tokensLen || isEmptyStr) && tokens.push(token));
        }
        // Other tokens always start a new line.
        else {
            // If there is '', insert it as a placeholder.
            lines.push({tokens: [token]});
        }
    }
}

function makeFont(style) {
    // FIXME in node-canvas fontWeight is before fontStyle
    // Use `fontSize` `fontFamily` to check whether font properties are defined.
    var font = (style.fontSize || style.fontFamily) && [
        style.fontStyle,
        style.fontWeight,
        (style.fontSize || 12) + 'px',
        // If font properties are defined, `fontFamily` should not be ignored.
        style.fontFamily || 'sans-serif'
    ].join(' ');
    return font && trim(font) || style.textFont || style.font;
}

/**
 * @param {Object} ctx
 * @param {Object} shape
 * @param {number} shape.x
 * @param {number} shape.y
 * @param {number} shape.width
 * @param {number} shape.height
 * @param {number} shape.r
 */
function buildPath(ctx, shape) {
    var x = shape.x;
    var y = shape.y;
    var width = shape.width;
    var height = shape.height;
    var r = shape.r;
    var r1;
    var r2;
    var r3;
    var r4;

    // Convert width and height to positive for better borderRadius
    if (width < 0) {
        x = x + width;
        width = -width;
    }
    if (height < 0) {
        y = y + height;
        height = -height;
    }

    if (typeof r === 'number') {
        r1 = r2 = r3 = r4 = r;
    }
    else if (r instanceof Array) {
        if (r.length === 1) {
            r1 = r2 = r3 = r4 = r[0];
        }
        else if (r.length === 2) {
            r1 = r3 = r[0];
            r2 = r4 = r[1];
        }
        else if (r.length === 3) {
            r1 = r[0];
            r2 = r4 = r[1];
            r3 = r[2];
        }
        else {
            r1 = r[0];
            r2 = r[1];
            r3 = r[2];
            r4 = r[3];
        }
    }
    else {
        r1 = r2 = r3 = r4 = 0;
    }

    var total;
    if (r1 + r2 > width) {
        total = r1 + r2;
        r1 *= width / total;
        r2 *= width / total;
    }
    if (r3 + r4 > width) {
        total = r3 + r4;
        r3 *= width / total;
        r4 *= width / total;
    }
    if (r2 + r3 > height) {
        total = r2 + r3;
        r2 *= height / total;
        r3 *= height / total;
    }
    if (r1 + r4 > height) {
        total = r1 + r4;
        r1 *= height / total;
        r4 *= height / total;
    }
    ctx.moveTo(x + r1, y);
    ctx.lineTo(x + width - r2, y);
    r2 !== 0 && ctx.arc(x + width - r2, y + r2, r2, -Math.PI / 2, 0);
    ctx.lineTo(x + width, y + height - r3);
    r3 !== 0 && ctx.arc(x + width - r3, y + height - r3, r3, 0, Math.PI / 2);
    ctx.lineTo(x + r4, y + height);
    r4 !== 0 && ctx.arc(x + r4, y + height - r4, r4, Math.PI / 2, Math.PI);
    ctx.lineTo(x, y + r1);
    r1 !== 0 && ctx.arc(x + r1, y + r1, r1, Math.PI, Math.PI * 1.5);
}

var DEFAULT_FONT = DEFAULT_FONT$1;

// TODO: Have not support 'start', 'end' yet.
var VALID_TEXT_ALIGN = {left: 1, right: 1, center: 1};
var VALID_TEXT_VERTICAL_ALIGN = {top: 1, bottom: 1, middle: 1};
// Different from `STYLE_COMMON_PROPS` of `graphic/Style`,
// the default value of shadowColor is `'transparent'`.
var SHADOW_STYLE_COMMON_PROPS = [
    ['textShadowBlur', 'shadowBlur', 0],
    ['textShadowOffsetX', 'shadowOffsetX', 0],
    ['textShadowOffsetY', 'shadowOffsetY', 0],
    ['textShadowColor', 'shadowColor', 'transparent']
];
var _tmpTextPositionResult = {};
var _tmpBoxPositionResult = {};

/**
 * @param {module:zrender/graphic/Style} style
 * @return {module:zrender/graphic/Style} The input style.
 */
function normalizeTextStyle(style) {
    normalizeStyle(style);
    each$1(style.rich, normalizeStyle);
    return style;
}

function normalizeStyle(style) {
    if (style) {

        style.font = makeFont(style);

        var textAlign = style.textAlign;
        textAlign === 'middle' && (textAlign = 'center');
        style.textAlign = (
            textAlign == null || VALID_TEXT_ALIGN[textAlign]
        ) ? textAlign : 'left';

        // Compatible with textBaseline.
        var textVerticalAlign = style.textVerticalAlign || style.textBaseline;
        textVerticalAlign === 'center' && (textVerticalAlign = 'middle');
        style.textVerticalAlign = (
            textVerticalAlign == null || VALID_TEXT_VERTICAL_ALIGN[textVerticalAlign]
        ) ? textVerticalAlign : 'top';

        var textPadding = style.textPadding;
        if (textPadding) {
            style.textPadding = normalizeCssArray(style.textPadding);
        }
    }
}

/**
 * @param {CanvasRenderingContext2D} ctx
 * @param {string} text
 * @param {module:zrender/graphic/Style} style
 * @param {Object|boolean} [rect] {x, y, width, height}
 *                  If set false, rect text is not used.
 * @param {Element|module:zrender/graphic/helper/constant.WILL_BE_RESTORED} [prevEl] For ctx prop cache.
 */
function renderText(hostEl, ctx, text, style, rect, prevEl) {
    style.rich
        ? renderRichText(hostEl, ctx, text, style, rect, prevEl)
        : renderPlainText(hostEl, ctx, text, style, rect, prevEl);
}

// Avoid setting to ctx according to prevEl if possible for
// performance in scenarios of large amount text.
function renderPlainText(hostEl, ctx, text, style, rect, prevEl) {
    'use strict';

    var needDrawBg = needDrawBackground(style);

    var prevStyle;
    var checkCache = false;
    var cachedByMe = ctx.__attrCachedBy === ContextCachedBy.PLAIN_TEXT;

    // Only take and check cache for `Text` el, but not RectText.
    if (prevEl !== WILL_BE_RESTORED) {
        if (prevEl) {
            prevStyle = prevEl.style;
            checkCache = !needDrawBg && cachedByMe && prevStyle;
        }

        // Prevent from using cache in `Style::bind`, because of the case:
        // ctx property is modified by other properties than `Style::bind`
        // used, and Style::bind is called next.
        ctx.__attrCachedBy = needDrawBg ? ContextCachedBy.NONE : ContextCachedBy.PLAIN_TEXT;
    }
    // Since this will be restored, prevent from using these props to check cache in the next
    // entering of this method. But do not need to clear other cache like `Style::bind`.
    else if (cachedByMe) {
        ctx.__attrCachedBy = ContextCachedBy.NONE;
    }

    var styleFont = style.font || DEFAULT_FONT;
    // PENDING
    // Only `Text` el set `font` and keep it (`RectText` will restore). So theoretically
    // we can make font cache on ctx, which can cache for text el that are discontinuous.
    // But layer save/restore needed to be considered.
    // if (styleFont !== ctx.__fontCache) {
    //     ctx.font = styleFont;
    //     if (prevEl !== WILL_BE_RESTORED) {
    //         ctx.__fontCache = styleFont;
    //     }
    // }
    if (!checkCache || styleFont !== (prevStyle.font || DEFAULT_FONT)) {
        ctx.font = styleFont;
    }

    // Use the final font from context-2d, because the final
    // font might not be the style.font when it is illegal.
    // But get `ctx.font` might be time consuming.
    var computedFont = hostEl.__computedFont;
    if (hostEl.__styleFont !== styleFont) {
        hostEl.__styleFont = styleFont;
        computedFont = hostEl.__computedFont = ctx.font;
    }

    var textPadding = style.textPadding;
    var textLineHeight = style.textLineHeight;

    var contentBlock = hostEl.__textCotentBlock;
    if (!contentBlock || hostEl.__dirtyText) {
        contentBlock = hostEl.__textCotentBlock = parsePlainText(
            text, computedFont, textPadding, textLineHeight, style.truncate
        );
    }

    var outerHeight = contentBlock.outerHeight;

    var textLines = contentBlock.lines;
    var lineHeight = contentBlock.lineHeight;

    var boxPos = getBoxPosition(_tmpBoxPositionResult, hostEl, style, rect);
    var baseX = boxPos.baseX;
    var baseY = boxPos.baseY;
    var textAlign = boxPos.textAlign || 'left';
    var textVerticalAlign = boxPos.textVerticalAlign;

    // Origin of textRotation should be the base point of text drawing.
    applyTextRotation(ctx, style, rect, baseX, baseY);

    var boxY = adjustTextY(baseY, outerHeight, textVerticalAlign);
    var textX = baseX;
    var textY = boxY;

    if (needDrawBg || textPadding) {
        // Consider performance, do not call getTextWidth util necessary.
        var textWidth = getWidth(text, computedFont);
        var outerWidth = textWidth;
        textPadding && (outerWidth += textPadding[1] + textPadding[3]);
        var boxX = adjustTextX(baseX, outerWidth, textAlign);

        needDrawBg && drawBackground(hostEl, ctx, style, boxX, boxY, outerWidth, outerHeight);

        if (textPadding) {
            textX = getTextXForPadding(baseX, textAlign, textPadding);
            textY += textPadding[0];
        }
    }

    // Always set textAlign and textBase line, because it is difficute to calculate
    // textAlign from prevEl, and we dont sure whether textAlign will be reset if
    // font set happened.
    ctx.textAlign = textAlign;
    // Force baseline to be "middle". Otherwise, if using "top", the
    // text will offset downward a little bit in font "Microsoft YaHei".
    ctx.textBaseline = 'middle';
    // Set text opacity
    ctx.globalAlpha = style.opacity || 1;

    // Always set shadowBlur and shadowOffset to avoid leak from displayable.
    for (var i = 0; i < SHADOW_STYLE_COMMON_PROPS.length; i++) {
        var propItem = SHADOW_STYLE_COMMON_PROPS[i];
        var styleProp = propItem[0];
        var ctxProp = propItem[1];
        var val = style[styleProp];
        if (!checkCache || val !== prevStyle[styleProp]) {
            ctx[ctxProp] = fixShadow(ctx, ctxProp, val || propItem[2]);
        }
    }

    // `textBaseline` is set as 'middle'.
    textY += lineHeight / 2;

    var textStrokeWidth = style.textStrokeWidth;
    var textStrokeWidthPrev = checkCache ? prevStyle.textStrokeWidth : null;
    var strokeWidthChanged = !checkCache || textStrokeWidth !== textStrokeWidthPrev;
    var strokeChanged = !checkCache || strokeWidthChanged || style.textStroke !== prevStyle.textStroke;
    var textStroke = getStroke(style.textStroke, textStrokeWidth);
    var textFill = getFill(style.textFill);

    if (textStroke) {
        if (strokeWidthChanged) {
            ctx.lineWidth = textStrokeWidth;
        }
        if (strokeChanged) {
            ctx.strokeStyle = textStroke;
        }
    }
    if (textFill) {
        if (!checkCache || style.textFill !== prevStyle.textFill) {
            ctx.fillStyle = textFill;
        }
    }

    // Optimize simply, in most cases only one line exists.
    if (textLines.length === 1) {
        // Fill after stroke so the outline will not cover the main part.
        textStroke && ctx.strokeText(textLines[0], textX, textY);
        textFill && ctx.fillText(textLines[0], textX, textY);
    }
    else {
        for (var i = 0; i < textLines.length; i++) {
            // Fill after stroke so the outline will not cover the main part.
            textStroke && ctx.strokeText(textLines[i], textX, textY);
            textFill && ctx.fillText(textLines[i], textX, textY);
            textY += lineHeight;
        }
    }
}

function renderRichText(hostEl, ctx, text, style, rect, prevEl) {
    // Do not do cache for rich text because of the complexity.
    // But `RectText` this will be restored, do not need to clear other cache like `Style::bind`.
    if (prevEl !== WILL_BE_RESTORED) {
        ctx.__attrCachedBy = ContextCachedBy.NONE;
    }

    var contentBlock = hostEl.__textCotentBlock;

    if (!contentBlock || hostEl.__dirtyText) {
        contentBlock = hostEl.__textCotentBlock = parseRichText(text, style);
    }

    drawRichText(hostEl, ctx, contentBlock, style, rect);
}

function drawRichText(hostEl, ctx, contentBlock, style, rect) {
    var contentWidth = contentBlock.width;
    var outerWidth = contentBlock.outerWidth;
    var outerHeight = contentBlock.outerHeight;
    var textPadding = style.textPadding;

    var boxPos = getBoxPosition(_tmpBoxPositionResult, hostEl, style, rect);
    var baseX = boxPos.baseX;
    var baseY = boxPos.baseY;
    var textAlign = boxPos.textAlign;
    var textVerticalAlign = boxPos.textVerticalAlign;

    // Origin of textRotation should be the base point of text drawing.
    applyTextRotation(ctx, style, rect, baseX, baseY);

    var boxX = adjustTextX(baseX, outerWidth, textAlign);
    var boxY = adjustTextY(baseY, outerHeight, textVerticalAlign);
    var xLeft = boxX;
    var lineTop = boxY;
    if (textPadding) {
        xLeft += textPadding[3];
        lineTop += textPadding[0];
    }
    var xRight = xLeft + contentWidth;

    needDrawBackground(style) && drawBackground(
        hostEl, ctx, style, boxX, boxY, outerWidth, outerHeight
    );

    for (var i = 0; i < contentBlock.lines.length; i++) {
        var line = contentBlock.lines[i];
        var tokens = line.tokens;
        var tokenCount = tokens.length;
        var lineHeight = line.lineHeight;
        var usedWidth = line.width;

        var leftIndex = 0;
        var lineXLeft = xLeft;
        var lineXRight = xRight;
        var rightIndex = tokenCount - 1;
        var token;

        while (
            leftIndex < tokenCount
            && (token = tokens[leftIndex], !token.textAlign || token.textAlign === 'left')
        ) {
            placeToken(hostEl, ctx, token, style, lineHeight, lineTop, lineXLeft, 'left');
            usedWidth -= token.width;
            lineXLeft += token.width;
            leftIndex++;
        }

        while (
            rightIndex >= 0
            && (token = tokens[rightIndex], token.textAlign === 'right')
        ) {
            placeToken(hostEl, ctx, token, style, lineHeight, lineTop, lineXRight, 'right');
            usedWidth -= token.width;
            lineXRight -= token.width;
            rightIndex--;
        }

        // The other tokens are placed as textAlign 'center' if there is enough space.
        lineXLeft += (contentWidth - (lineXLeft - xLeft) - (xRight - lineXRight) - usedWidth) / 2;
        while (leftIndex <= rightIndex) {
            token = tokens[leftIndex];
            // Consider width specified by user, use 'center' rather than 'left'.
            placeToken(hostEl, ctx, token, style, lineHeight, lineTop, lineXLeft + token.width / 2, 'center');
            lineXLeft += token.width;
            leftIndex++;
        }

        lineTop += lineHeight;
    }
}

function applyTextRotation(ctx, style, rect, x, y) {
    // textRotation only apply in RectText.
    if (rect && style.textRotation) {
        var origin = style.textOrigin;
        if (origin === 'center') {
            x = rect.width / 2 + rect.x;
            y = rect.height / 2 + rect.y;
        }
        else if (origin) {
            x = origin[0] + rect.x;
            y = origin[1] + rect.y;
        }

        ctx.translate(x, y);
        // Positive: anticlockwise
        ctx.rotate(-style.textRotation);
        ctx.translate(-x, -y);
    }
}

function placeToken(hostEl, ctx, token, style, lineHeight, lineTop, x, textAlign) {
    var tokenStyle = style.rich[token.styleName] || {};
    tokenStyle.text = token.text;

    // 'ctx.textBaseline' is always set as 'middle', for sake of
    // the bias of "Microsoft YaHei".
    var textVerticalAlign = token.textVerticalAlign;
    var y = lineTop + lineHeight / 2;
    if (textVerticalAlign === 'top') {
        y = lineTop + token.height / 2;
    }
    else if (textVerticalAlign === 'bottom') {
        y = lineTop + lineHeight - token.height / 2;
    }

    !token.isLineHolder && needDrawBackground(tokenStyle) && drawBackground(
        hostEl,
        ctx,
        tokenStyle,
        textAlign === 'right'
            ? x - token.width
            : textAlign === 'center'
            ? x - token.width / 2
            : x,
        y - token.height / 2,
        token.width,
        token.height
    );

    var textPadding = token.textPadding;
    if (textPadding) {
        x = getTextXForPadding(x, textAlign, textPadding);
        y -= token.height / 2 - textPadding[2] - token.textHeight / 2;
    }

    setCtx(ctx, 'shadowBlur', retrieve3(tokenStyle.textShadowBlur, style.textShadowBlur, 0));
    setCtx(ctx, 'shadowColor', tokenStyle.textShadowColor || style.textShadowColor || 'transparent');
    setCtx(ctx, 'shadowOffsetX', retrieve3(tokenStyle.textShadowOffsetX, style.textShadowOffsetX, 0));
    setCtx(ctx, 'shadowOffsetY', retrieve3(tokenStyle.textShadowOffsetY, style.textShadowOffsetY, 0));

    setCtx(ctx, 'textAlign', textAlign);
    // Force baseline to be "middle". Otherwise, if using "top", the
    // text will offset downward a little bit in font "Microsoft YaHei".
    setCtx(ctx, 'textBaseline', 'middle');

    setCtx(ctx, 'font', token.font || DEFAULT_FONT);

    var textStroke = getStroke(tokenStyle.textStroke || style.textStroke, textStrokeWidth);
    var textFill = getFill(tokenStyle.textFill || style.textFill);
    var textStrokeWidth = retrieve2(tokenStyle.textStrokeWidth, style.textStrokeWidth);

    // Fill after stroke so the outline will not cover the main part.
    if (textStroke) {
        setCtx(ctx, 'lineWidth', textStrokeWidth);
        setCtx(ctx, 'strokeStyle', textStroke);
        ctx.strokeText(token.text, x, y);
    }
    if (textFill) {
        setCtx(ctx, 'fillStyle', textFill);
        ctx.fillText(token.text, x, y);
    }
}

function needDrawBackground(style) {
    return !!(
        style.textBackgroundColor
        || (style.textBorderWidth && style.textBorderColor)
    );
}

// style: {textBackgroundColor, textBorderWidth, textBorderColor, textBorderRadius, text}
// shape: {x, y, width, height}
function drawBackground(hostEl, ctx, style, x, y, width, height) {
    var textBackgroundColor = style.textBackgroundColor;
    var textBorderWidth = style.textBorderWidth;
    var textBorderColor = style.textBorderColor;
    var isPlainBg = isString(textBackgroundColor);

    setCtx(ctx, 'shadowBlur', style.textBoxShadowBlur || 0);
    setCtx(ctx, 'shadowColor', style.textBoxShadowColor || 'transparent');
    setCtx(ctx, 'shadowOffsetX', style.textBoxShadowOffsetX || 0);
    setCtx(ctx, 'shadowOffsetY', style.textBoxShadowOffsetY || 0);

    if (isPlainBg || (textBorderWidth && textBorderColor)) {
        ctx.beginPath();
        var textBorderRadius = style.textBorderRadius;
        if (!textBorderRadius) {
            ctx.rect(x, y, width, height);
        }
        else {
            buildPath(ctx, {
                x: x, y: y, width: width, height: height, r: textBorderRadius
            });
        }
        ctx.closePath();
    }

    if (isPlainBg) {
        setCtx(ctx, 'fillStyle', textBackgroundColor);

        if (style.fillOpacity != null) {
            var originalGlobalAlpha = ctx.globalAlpha;
            ctx.globalAlpha = style.fillOpacity * style.opacity;
            ctx.fill();
            ctx.globalAlpha = originalGlobalAlpha;
        }
        else {
            ctx.fill();
        }
    }
    else if (isObject$1(textBackgroundColor)) {
        var image = textBackgroundColor.image;

        image = createOrUpdateImage(
            image, null, hostEl, onBgImageLoaded, textBackgroundColor
        );
        if (image && isImageReady(image)) {
            ctx.drawImage(image, x, y, width, height);
        }
    }

    if (textBorderWidth && textBorderColor) {
        setCtx(ctx, 'lineWidth', textBorderWidth);
        setCtx(ctx, 'strokeStyle', textBorderColor);

        if (style.strokeOpacity != null) {
            var originalGlobalAlpha = ctx.globalAlpha;
            ctx.globalAlpha = style.strokeOpacity * style.opacity;
            ctx.stroke();
            ctx.globalAlpha = originalGlobalAlpha;
        }
        else {
            ctx.stroke();
        }
    }
}

function onBgImageLoaded(image, textBackgroundColor) {
    // Replace image, so that `contain/text.js#parseRichText`
    // will get correct result in next tick.
    textBackgroundColor.image = image;
}

function getBoxPosition(out, hostEl, style, rect) {
    var baseX = style.x || 0;
    var baseY = style.y || 0;
    var textAlign = style.textAlign;
    var textVerticalAlign = style.textVerticalAlign;

    // Text position represented by coord
    if (rect) {
        var textPosition = style.textPosition;
        if (textPosition instanceof Array) {
            // Percent
            baseX = rect.x + parsePercent(textPosition[0], rect.width);
            baseY = rect.y + parsePercent(textPosition[1], rect.height);
        }
        else {
            var res = (hostEl && hostEl.calculateTextPosition)
                ? hostEl.calculateTextPosition(_tmpTextPositionResult, style, rect)
                : calculateTextPosition(_tmpTextPositionResult, style, rect);
            baseX = res.x;
            baseY = res.y;
            // Default align and baseline when has textPosition
            textAlign = textAlign || res.textAlign;
            textVerticalAlign = textVerticalAlign || res.textVerticalAlign;
        }

        // textOffset is only support in RectText, otherwise
        // we have to adjust boundingRect for textOffset.
        var textOffset = style.textOffset;
        if (textOffset) {
            baseX += textOffset[0];
            baseY += textOffset[1];
        }
    }

    out = out || {};
    out.baseX = baseX;
    out.baseY = baseY;
    out.textAlign = textAlign;
    out.textVerticalAlign = textVerticalAlign;

    return out;
}


function setCtx(ctx, prop, value) {
    ctx[prop] = fixShadow(ctx, prop, value);
    return ctx[prop];
}

/**
 * @param {string} [stroke] If specified, do not check style.textStroke.
 * @param {string} [lineWidth] If specified, do not check style.textStroke.
 * @param {number} style
 */
function getStroke(stroke, lineWidth) {
    return (stroke == null || lineWidth <= 0 || stroke === 'transparent' || stroke === 'none')
        ? null
        // TODO pattern and gradient?
        : (stroke.image || stroke.colorStops)
        ? '#000'
        : stroke;
}

function getFill(fill) {
    return (fill == null || fill === 'none')
        ? null
        // TODO pattern and gradient?
        : (fill.image || fill.colorStops)
        ? '#000'
        : fill;
}

function parsePercent(value, maxValue) {
    if (typeof value === 'string') {
        if (value.lastIndexOf('%') >= 0) {
            return parseFloat(value) / 100 * maxValue;
        }
        return parseFloat(value);
    }
    return value;
}

function getTextXForPadding(x, textAlign, textPadding) {
    return textAlign === 'right'
        ? (x - textPadding[1])
        : textAlign === 'center'
        ? (x + textPadding[3] / 2 - textPadding[1] / 2)
        : (x + textPadding[3]);
}

/**
 * @param {string} text
 * @param {module:zrender/Style} style
 * @return {boolean}
 */
function needDrawText(text, style) {
    return text != null
        && (text
            || style.textBackgroundColor
            || (style.textBorderWidth && style.textBorderColor)
            || style.textPadding
        );
}

/**
 * Mixin for drawing text in a element bounding rect
 * @module zrender/mixin/RectText
 */

var tmpRect$1 = new BoundingRect();

var RectText = function () {};

RectText.prototype = {

    constructor: RectText,

    /**
     * Draw text in a rect with specified position.
     * @param  {CanvasRenderingContext2D} ctx
     * @param  {Object} rect Displayable rect
     */
    drawRectText: function (ctx, rect) {
        var style = this.style;

        rect = style.textRect || rect;

        // Optimize, avoid normalize every time.
        this.__dirty && normalizeTextStyle(style, true);

        var text = style.text;

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

        if (!needDrawText(text, style)) {
            return;
        }

        // FIXME
        // Do not provide prevEl to `textHelper.renderText` for ctx prop cache,
        // but use `ctx.save()` and `ctx.restore()`. Because the cache for rect
        // text propably break the cache for its host elements.
        ctx.save();

        // Transform rect to view space
        var transform = this.transform;
        if (!style.transformText) {
            if (transform) {
                tmpRect$1.copy(rect);
                tmpRect$1.applyTransform(transform);
                rect = tmpRect$1;
            }
        }
        else {
            this.setTransform(ctx);
        }

        // transformText and textRotation can not be used at the same time.
        renderText(this, ctx, text, style, rect, WILL_BE_RESTORED);

        ctx.restore();
    }
};

/**
 * Base class of all displayable graphic objects
 * @module zrender/graphic/Displayable
 */


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

    this._rect = null;
    // Shapes for cascade clipping.
    // Can only be `null`/`undefined` or an non-empty array, MUST NOT be an empty array.
    // because it is easy to only using null to check whether clipPaths changed.
    this.__clipPaths = null;

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

Displayable.prototype = {

    constructor: Displayable,

    type: 'displayable',

    /**
     * Dirty flag. From which painter will determine if this displayable object needs brush.
     * @name module:zrender/graphic/Displayable#__dirty
     * @type {boolean}
     */
    __dirty: true,

    /**
     * Whether the displayable object is visible. when it is true, the displayable object
     * is not drawn, but the mouse event can still trigger the object.
     * @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,

    /**
     * The z level determines the displayable object can be drawn in which layer canvas.
     * @name module:/zrender/graphic/Displayable#zlevel
     * @type {number}
     * @default 0
     */
    zlevel: 0,

    /**
     * Whether it can be dragged.
     * @name module:/zrender/graphic/Displayable#draggable
     * @type {boolean}
     * @default false
     */
    draggable: false,

    /**
     * Whether is it dragging.
     * @name module:/zrender/graphic/Displayable#draggable
     * @type {boolean}
     * @default false
     */
    dragging: false,

    /**
     * Whether to respond to mouse events.
     * @name module:/zrender/graphic/Displayable#silent
     * @type {boolean}
     * @default false
     */
    silent: false,

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

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

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

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

    /**
     * @type {boolean}
     */
    incremental: false,
    /**
     * Scale ratio for global scale.
     * @type {boolean}
     */
    globalScaleRatio: 1,

    beforeBrush: function (ctx) {},

    afterBrush: function (ctx) {},

    /**
     * Graphic drawing method.
     * @param {CanvasRenderingContext2D} ctx
     */
    // Interface
    brush: function (ctx, prevEl) {},

    /**
     * Get the minimum bounding box.
     * @return {module:zrender/core/BoundingRect}
     */
    // Interface
    getBoundingRect: function () {},

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

    /**
     * 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 = this.__dirtyText = true;

        this._rect = null;

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

    /**
     * If displayable object binded any event
     * @return {boolean}
     */
    // TODO, events bound by bind
    // isSilent: function () {
    //     return !(
    //         this.hoverable || this.draggable
    //         || this.onmousemove || this.onmouseover || this.onmouseout
    //         || this.onmousedown || this.onmouseup || this.onclick
    //         || this.ondragenter || this.ondragover || this.ondragleave
    //         || this.ondrop
    //     );
    // },
    /**
     * Alias for animate('style')
     * @param {boolean} loop
     */
    animateStyle: function (loop) {
        return this.animate('style', loop);
    },

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

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

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

    /**
     * The string value of `textPosition` needs to be calculated to a real postion.
     * For example, `'inside'` is calculated to `[rect.width/2, rect.height/2]`
     * by default. See `contain/text.js#calculateTextPosition` for more details.
     * But some coutom shapes like "pin", "flag" have center that is not exactly
     * `[width/2, height/2]`. So we provide this hook to customize the calculation
     * for those shapes. It will be called if the `style.textPosition` is a string.
     * @param {Obejct} [out] Prepared out object. If not provided, this method should
     *        be responsible for creating one.
     * @param {module:zrender/graphic/Style} style
     * @param {Object} rect {x, y, width, height}
     * @return {Obejct} out The same as the input out.
     *         {
     *             x: number. mandatory.
     *             y: number. mandatory.
     *             textAlign: string. optional. use style.textAlign by default.
     *             textVerticalAlign: string. optional. use style.textVerticalAlign by default.
     *         }
     */
    calculateTextPosition: null
};

inherits(Displayable, Element);

mixin(Displayable, RectText);

/**
 * @alias zrender/graphic/Image
 * @extends module:zrender/graphic/Displayable
 * @constructor
 * @param {Object} opts
 */
function ZImage(opts) {
    Displayable.call(this, opts);
}

ZImage.prototype = {

    constructor: ZImage,

    type: 'image',

    brush: function (ctx, prevEl) {
        var style = this.style;
        var src = style.image;

        // Must bind each time
        style.bind(ctx, this, prevEl);

        var image = this._image = createOrUpdateImage(
            src,
            this._image,
            this,
            this.onload
        );

        if (!image || !isImageReady(image)) {
            return;
        }

        // 图片已经加载完成
        // if (image.nodeName.toUpperCase() == 'IMG') {
        //     if (!image.complete) {
        //         return;
        //     }
        // }
        // Else is canvas

        var x = style.x || 0;
        var y = style.y || 0;
        var width = style.width;
        var height = style.height;
        var aspect = image.width / image.height;
        if (width == null && height != null) {
            // Keep image/height ratio
            width = height * aspect;
        }
        else if (height == null && width != null) {
            height = width / aspect;
        }
        else if (width == null && height == null) {
            width = image.width;
            height = image.height;
        }

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

        if (style.sWidth && style.sHeight) {
            var sx = style.sx || 0;
            var sy = style.sy || 0;
            ctx.drawImage(
                image,
                sx, sy, style.sWidth, style.sHeight,
                x, y, width, height
            );
        }
        else if (style.sx && style.sy) {
            var sx = style.sx;
            var sy = style.sy;
            var sWidth = width - sx;
            var sHeight = height - sy;
            ctx.drawImage(
                image,
                sx, sy, sWidth, sHeight,
                x, y, width, height
            );
        }
        else {
            ctx.drawImage(image, x, y, width, height);
        }

        // Draw rect text
        if (style.text != null) {
            // Only restore transform when needs draw text.
            this.restoreTransform(ctx);
            this.drawRectText(ctx, this.getBoundingRect());
        }
    },

    getBoundingRect: function () {
        var style = this.style;
        if (!this._rect) {
            this._rect = new BoundingRect(
                style.x || 0, style.y || 0, style.width || 0, style.height || 0
            );
        }
        return this._rect;
    }
};

inherits(ZImage, Displayable);

var HOVER_LAYER_ZLEVEL = 1e5;
var CANVAS_ZLEVEL = 314159;

var EL_AFTER_INCREMENTAL_INC = 0.01;
var INCREMENTAL_INC = 0.001;

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

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

    if (layer.__builtin__) {
        return true;
    }

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

    return true;
}

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) {
    // displayable.__clipPaths can only be `null`/`undefined` or an non-empty array.
    if (clipPaths === prevClipPaths) {
        return false;
    }
    if (!clipPaths || !prevClipPaths || (clipPaths.length !== prevClipPaths.length)) {
        return true;
    }
    for (var i = 0; i < clipPaths.length; i++) {
        if (clipPaths[i] !== prevClipPaths[i]) {
            return true;
        }
    }
    return false;
}

function doClip(clipPaths, ctx) {
    for (var i = 0; i < clipPaths.length; i++) {
        var clipPath = clipPaths[i];

        clipPath.setTransform(ctx);
        ctx.beginPath();
        clipPath.buildPath(ctx, clipPath.shape);
        ctx.clip();
        // Transform back
        clipPath.restoreTransform(ctx);
    }
}

function createRoot(width, height) {
    var domRoot = document.createElement('div');

    // domRoot.onselectstart = returnFalse; // Avoid page selected
    domRoot.style.cssText = [
        'position:relative',
        // IOS13 safari probably has a compositing bug (z order of the canvas and the consequent
        // dom does not act as expected) when some of the parent dom has
        // `-webkit-overflow-scrolling: touch;` and the webpage is longer than one screen and
        // the canvas is not at the top part of the page.
        // Check `https://bugs.webkit.org/show_bug.cgi?id=203681` for more details. We remove
        // this `overflow:hidden` to avoid the bug.
        // 'overflow:hidden',
        'width:' + width + 'px',
        'height:' + height + 'px',
        'padding:0',
        'margin:0',
        'border-width:0'
    ].join(';') + ';';

    return domRoot;
}


/**
 * @alias module:zrender/Painter
 * @constructor
 * @param {HTMLElement} root 绘图容器
 * @param {module:zrender/Storage} storage
 * @param {Object} opts
 */
var Painter = function (root, storage, opts) {

    this.type = 'canvas';

    // In node environment using node-canvas
    var singleCanvas = !root.nodeName // In node ?
        || root.nodeName.toUpperCase() === 'CANVAS';

    this._opts = opts = extend({}, opts || {});

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

    var rootStyle = root.style;

    if (rootStyle) {
        rootStyle['-webkit-tap-highlight-color'] = 'transparent';
        rootStyle['-webkit-user-select'] =
        rootStyle['user-select'] =
        rootStyle['-webkit-touch-callout'] = 'none';

        root.innerHTML = '';
    }

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

    /**
     * @type {Array.<number>}
     * @private
     */
    var zlevelList = this._zlevelList = [];

    /**
     * @type {Object.<string, module:zrender/Layer>}
     * @private
     */
    var layers = this._layers = {};

    /**
     * @type {Object.<string, Object>}
     * @private
     */
    this._layerConfig = {};

    /**
     * zrender will do compositing when root is a canvas and have multiple zlevels.
     */
    this._needsManuallyCompositing = false;

    if (!singleCanvas) {
        this._width = this._getSize(0);
        this._height = this._getSize(1);

        var domRoot = this._domRoot = createRoot(
            this._width, this._height
        );
        root.appendChild(domRoot);
    }
    else {
        var width = root.width;
        var height = root.height;

        if (opts.width != null) {
            width = opts.width;
        }
        if (opts.height != null) {
            height = opts.height;
        }
        this.dpr = opts.devicePixelRatio || 1;

        // Use canvas width and height directly
        root.width = width * this.dpr;
        root.height = height * this.dpr;

        this._width = width;
        this._height = height;

        // Create layer if only one given canvas
        // Device can be specified to create a high dpi image.
        var mainLayer = new Layer(root, this, this.dpr);
        mainLayer.__builtin__ = true;
        mainLayer.initContext();
        // FIXME Use canvas width and height
        // mainLayer.resize(width, height);
        layers[CANVAS_ZLEVEL] = mainLayer;
        mainLayer.zlevel = CANVAS_ZLEVEL;
        // Not use common zlevel.
        zlevelList.push(CANVAS_ZLEVEL);

        this._domRoot = root;
    }

    /**
     * @type {module:zrender/Layer}
     * @private
     */
    this._hoverlayer = null;

    this._hoverElements = [];
};

Painter.prototype = {

    constructor: Painter,

    getType: function () {
        return 'canvas';
    },

    /**
     * If painter use a single canvas
     * @return {boolean}
     */
    isSingleCanvas: function () {
        return this._singleCanvas;
    },
    /**
     * @return {HTMLDivElement}
     */
    getViewportRoot: function () {
        return this._domRoot;
    },

    getViewportRootOffset: function () {
        var viewportRoot = this.getViewportRoot();
        if (viewportRoot) {
            return {
                offsetLeft: viewportRoot.offsetLeft || 0,
                offsetTop: viewportRoot.offsetTop || 0
            };
        }
    },

    /**
     * 刷新
     * @param {boolean} [paintAll=false] 强制绘制所有displayable
     */
    refresh: function (paintAll) {

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

        var zlevelList = this._zlevelList;

        this._redrawId = Math.random();

        this._paintList(list, paintAll, this._redrawId);

        // Paint custum layers
        for (var i = 0; i < zlevelList.length; i++) {
            var z = zlevelList[i];
            var layer = this._layers[z];
            if (!layer.__builtin__ && layer.refresh) {
                var clearColor = i === 0 ? this._backgroundColor : null;
                layer.refresh(clearColor);
            }
        }

        this.refreshHover();

        return this;
    },

    addHover: function (el, hoverStyle) {
        if (el.__hoverMir) {
            return;
        }
        var elMirror = new el.constructor({
            style: el.style,
            shape: el.shape,
            z: el.z,
            z2: el.z2,
            silent: el.silent
        });
        elMirror.__from = el;
        el.__hoverMir = elMirror;
        hoverStyle && elMirror.setStyle(hoverStyle);
        this._hoverElements.push(elMirror);

        return elMirror;
    },

    removeHover: function (el) {
        var elMirror = el.__hoverMir;
        var hoverElements = this._hoverElements;
        var idx = indexOf(hoverElements, elMirror);
        if (idx >= 0) {
            hoverElements.splice(idx, 1);
        }
        el.__hoverMir = null;
    },

    clearHover: function (el) {
        var hoverElements = this._hoverElements;
        for (var i = 0; i < hoverElements.length; i++) {
            var from = hoverElements[i].__from;
            if (from) {
                from.__hoverMir = null;
            }
        }
        hoverElements.length = 0;
    },

    refreshHover: function () {
        var hoverElements = this._hoverElements;
        var len = hoverElements.length;
        var hoverLayer = this._hoverlayer;
        hoverLayer && hoverLayer.clear();

        if (!len) {
            return;
        }
        sort(hoverElements, this.storage.displayableSortFunc);

        // Use a extream large zlevel
        // FIXME?
        if (!hoverLayer) {
            hoverLayer = this._hoverlayer = this.getLayer(HOVER_LAYER_ZLEVEL);
        }

        var scope = {};
        hoverLayer.ctx.save();
        for (var i = 0; i < len;) {
            var el = hoverElements[i];
            var originalEl = el.__from;
            // Original el is removed
            // PENDING
            if (!(originalEl && originalEl.__zr)) {
                hoverElements.splice(i, 1);
                originalEl.__hoverMir = null;
                len--;
                continue;
            }
            i++;

            // Use transform
            // FIXME style and shape ?
            if (!originalEl.invisible) {
                el.transform = originalEl.transform;
                el.invTransform = originalEl.invTransform;
                el.__clipPaths = originalEl.__clipPaths;
                // el.
                this._doPaintEl(el, hoverLayer, true, scope);
            }
        }

        hoverLayer.ctx.restore();
    },

    getHoverLayer: function () {
        return this.getLayer(HOVER_LAYER_ZLEVEL);
    },

    _paintList: function (list, paintAll, redrawId) {
        if (this._redrawId !== redrawId) {
            return;
        }

        paintAll = paintAll || false;

        this._updateLayerStatus(list);

        var finished = this._doPaintList(list, paintAll);

        if (this._needsManuallyCompositing) {
            this._compositeManually();
        }

        if (!finished) {
            var self = this;
            requestAnimationFrame(function () {
                self._paintList(list, paintAll, redrawId);
            });
        }
    },

    _compositeManually: function () {
        var ctx = this.getLayer(CANVAS_ZLEVEL).ctx;
        var width = this._domRoot.width;
        var height = this._domRoot.height;
        ctx.clearRect(0, 0, width, height);
        // PENDING, If only builtin layer?
        this.eachBuiltinLayer(function (layer) {
            if (layer.virtual) {
                ctx.drawImage(layer.dom, 0, 0, width, height);
            }
        });
    },

    _doPaintList: function (list, paintAll) {
        var layerList = [];
        for (var zi = 0; zi < this._zlevelList.length; zi++) {
            var zlevel = this._zlevelList[zi];
            var layer = this._layers[zlevel];
            if (layer.__builtin__
                && layer !== this._hoverlayer
                && (layer.__dirty || paintAll)
            ) {
                layerList.push(layer);
            }
        }

        var finished = true;

        for (var k = 0; k < layerList.length; k++) {
            var layer = layerList[k];
            var ctx = layer.ctx;
            var scope = {};
            ctx.save();

            var start = paintAll ? layer.__startIndex : layer.__drawIndex;

            var useTimer = !paintAll && layer.incremental && Date.now;
            var startTime = useTimer && Date.now();

            var clearColor = layer.zlevel === this._zlevelList[0]
                ? this._backgroundColor : null;
            // All elements in this layer are cleared.
            if (layer.__startIndex === layer.__endIndex) {
                layer.clear(false, clearColor);
            }
            else if (start === layer.__startIndex) {
                var firstEl = list[start];
                if (!firstEl.incremental || !firstEl.notClear || paintAll) {
                    layer.clear(false, clearColor);
                }
            }
            if (start === -1) {
                console.error('For some unknown reason. drawIndex is -1');
                start = layer.__startIndex;
            }
            for (var i = start; i < layer.__endIndex; i++) {
                var el = list[i];
                this._doPaintEl(el, layer, paintAll, scope);
                el.__dirty = el.__dirtyText = false;

                if (useTimer) {
                    // Date.now can be executed in 13,025,305 ops/second.
                    var dTime = Date.now() - startTime;
                    // Give 15 millisecond to draw.
                    // The rest elements will be drawn in the next frame.
                    if (dTime > 15) {
                        break;
                    }
                }
            }

            layer.__drawIndex = i;

            if (layer.__drawIndex < layer.__endIndex) {
                finished = false;
            }

            if (scope.prevElClipPaths) {
                // Needs restore the state. If last drawn element is in the clipping area.
                ctx.restore();
            }

            ctx.restore();
        }

        if (env$1.wxa) {
            // Flush for weixin application
            each$1(this._layers, function (layer) {
                if (layer && layer.ctx && layer.ctx.draw) {
                    layer.ctx.draw();
                }
            });
        }

        return finished;
    },

    _doPaintEl: function (el, currentLayer, forcePaint, scope) {
        var ctx = currentLayer.ctx;
        var m = el.transform;
        if (
            (currentLayer.__dirty || forcePaint)
            // Ignore invisible element
            && !el.invisible
            // Ignore transparent element
            && el.style.opacity !== 0
            // Ignore scale 0 element, in some environment like node-canvas
            // Draw a scale 0 element can cause all following draw wrong
            // And setTransform with scale 0 will cause set back transform failed.
            && !(m && !m[0] && !m[3])
            // Ignore culled element
            && !(el.culling && isDisplayableCulled(el, this._width, this._height))
        ) {

            var clipPaths = el.__clipPaths;
            var prevElClipPaths = scope.prevElClipPaths;

            // Optimize when clipping on group with several elements
            if (!prevElClipPaths || isClipPathChanged(clipPaths, prevElClipPaths)) {
                // If has previous clipping state, restore from it
                if (prevElClipPaths) {
                    ctx.restore();
                    scope.prevElClipPaths = null;
                    // Reset prevEl since context has been restored
                    scope.prevEl = null;
                }
                // New clipping state
                if (clipPaths) {
                    ctx.save();
                    doClip(clipPaths, ctx);
                    scope.prevElClipPaths = clipPaths;
                }
            }
            el.beforeBrush && el.beforeBrush(ctx);

            el.brush(ctx, scope.prevEl || null);
            scope.prevEl = el;

            el.afterBrush && el.afterBrush(ctx);
        }
    },

    /**
     * 获取 zlevel 所在层，如果不存在则会创建一个新的层
     * @param {number} zlevel
     * @param {boolean} virtual Virtual layer will not be inserted into dom.
     * @return {module:zrender/Layer}
     */
    getLayer: function (zlevel, virtual) {
        if (this._singleCanvas && !this._needsManuallyCompositing) {
            zlevel = CANVAS_ZLEVEL;
        }
        var layer = this._layers[zlevel];
        if (!layer) {
            // Create a new layer
            layer = new Layer('zr_' + zlevel, this, this.dpr);
            layer.zlevel = zlevel;
            layer.__builtin__ = true;

            if (this._layerConfig[zlevel]) {
                merge(layer, this._layerConfig[zlevel], true);
            }
            // TODO Remove EL_AFTER_INCREMENTAL_INC magic number
            else if (this._layerConfig[zlevel - EL_AFTER_INCREMENTAL_INC]) {
                merge(layer, this._layerConfig[zlevel - EL_AFTER_INCREMENTAL_INC], true);
            }

            if (virtual) {
                layer.virtual = virtual;
            }

            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]) {
            logError$1('ZLevel ' + zlevel + ' has been used already');
            return;
        }
        // Check if is a valid layer
        if (!isLayerValid(layer)) {
            logError$1('Layer of zlevel ' + zlevel + ' is not valid');
            return;
        }

        if (len > 0 && zlevel > zlevelList[0]) {
            for (i = 0; i < len - 1; i++) {
                if (
                    zlevelList[i] < zlevel
                    && zlevelList[i + 1] > zlevel
                ) {
                    break;
                }
            }
            prevLayer = layersMap[zlevelList[i]];
        }
        zlevelList.splice(i + 1, 0, zlevel);

        layersMap[zlevel] = layer;

        // Vitual layer will not directly show on the screen.
        // (It can be a WebGL layer and assigned to a ZImage element)
        // But it still under management of zrender.
        if (!layer.virtual) {
            if (prevLayer) {
                var prevDom = prevLayer.dom;
                if (prevDom.nextSibling) {
                    domRoot.insertBefore(
                        layer.dom,
                        prevDom.nextSibling
                    );
                }
                else {
                    domRoot.appendChild(layer.dom);
                }
            }
            else {
                if (domRoot.firstChild) {
                    domRoot.insertBefore(layer.dom, domRoot.firstChild);
                }
                else {
                    domRoot.appendChild(layer.dom);
                }
            }
        }
    },

    // Iterate each layer
    eachLayer: function (cb, context) {
        var zlevelList = this._zlevelList;
        var z;
        var i;
        for (i = 0; i < zlevelList.length; i++) {
            z = zlevelList[i];
            cb.call(context, this._layers[z], z);
        }
    },

    // Iterate each buildin layer
    eachBuiltinLayer: function (cb, context) {
        var zlevelList = this._zlevelList;
        var layer;
        var z;
        var i;
        for (i = 0; i < zlevelList.length; i++) {
            z = zlevelList[i];
            layer = this._layers[z];
            if (layer.__builtin__) {
                cb.call(context, layer, z);
            }
        }
    },

    // Iterate each other layer except buildin layer
    eachOtherLayer: function (cb, context) {
        var zlevelList = this._zlevelList;
        var layer;
        var z;
        var i;
        for (i = 0; i < zlevelList.length; i++) {
            z = zlevelList[i];
            layer = this._layers[z];
            if (!layer.__builtin__) {
                cb.call(context, layer, z);
            }
        }
    },

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

    _updateLayerStatus: function (list) {

        this.eachBuiltinLayer(function (layer, z) {
            layer.__dirty = layer.__used = false;
        });

        function updatePrevLayer(idx) {
            if (prevLayer) {
                if (prevLayer.__endIndex !== idx) {
                    prevLayer.__dirty = true;
                }
                prevLayer.__endIndex = idx;
            }
        }

        if (this._singleCanvas) {
            for (var i = 1; i < list.length; i++) {
                var el = list[i];
                if (el.zlevel !== list[i - 1].zlevel || el.incremental) {
                    this._needsManuallyCompositing = true;
                    break;
                }
            }
        }

        var prevLayer = null;
        var incrementalLayerCount = 0;
        var prevZlevel;
        for (var i = 0; i < list.length; i++) {
            var el = list[i];
            var zlevel = el.zlevel;
            var layer;

            if (prevZlevel !== zlevel) {
                prevZlevel = zlevel;
                incrementalLayerCount = 0;
            }

            // TODO Not use magic number on zlevel.

            // Each layer with increment element can be separated to 3 layers.
            //          (Other Element drawn after incremental element)
            // -----------------zlevel + EL_AFTER_INCREMENTAL_INC--------------------
            //                      (Incremental element)
            // ----------------------zlevel + INCREMENTAL_INC------------------------
            //              (Element drawn before incremental element)
            // --------------------------------zlevel--------------------------------
            if (el.incremental) {
                layer = this.getLayer(zlevel + INCREMENTAL_INC, this._needsManuallyCompositing);
                layer.incremental = true;
                incrementalLayerCount = 1;
            }
            else {
                layer = this.getLayer(
                    zlevel + (incrementalLayerCount > 0 ? EL_AFTER_INCREMENTAL_INC : 0),
                    this._needsManuallyCompositing
                );
            }

            if (!layer.__builtin__) {
                logError$1('ZLevel ' + zlevel + ' has been used by unkown layer ' + layer.id);
            }

            if (layer !== prevLayer) {
                layer.__used = true;
                if (layer.__startIndex !== i) {
                    layer.__dirty = true;
                }
                layer.__startIndex = i;
                if (!layer.incremental) {
                    layer.__drawIndex = i;
                }
                else {
                    // Mark layer draw index needs to update.
                    layer.__drawIndex = -1;
                }
                updatePrevLayer(i);
                prevLayer = layer;
            }
            if (el.__dirty) {
                layer.__dirty = true;
                if (layer.incremental && layer.__drawIndex < 0) {
                    // Start draw from the first dirty element.
                    layer.__drawIndex = i;
                }
            }
        }

        updatePrevLayer(i);

        this.eachBuiltinLayer(function (layer, z) {
            // Used in last frame but not in this frame. Needs clear
            if (!layer.__used && layer.getElementCount() > 0) {
                layer.__dirty = true;
                layer.__startIndex = layer.__endIndex = layer.__drawIndex = 0;
            }
            // For incremental layer. In case start index changed and no elements are dirty.
            if (layer.__dirty && layer.__drawIndex < 0) {
                layer.__drawIndex = layer.__startIndex;
            }
        });
    },

    /**
     * 清除hover层外所有内容
     */
    clear: function () {
        this.eachBuiltinLayer(this._clearLayer);
        return this;
    },

    _clearLayer: function (layer) {
        layer.clear();
    },

    setBackgroundColor: function (backgroundColor) {
        this._backgroundColor = backgroundColor;
    },

    /**
     * 修改指定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 {
                merge(layerConfig[zlevel], config, true);
            }

            for (var i = 0; i < this._zlevelList.length; i++) {
                var _zlevel = this._zlevelList[i];
                // TODO Remove EL_AFTER_INCREMENTAL_INC magic number
                if (_zlevel === zlevel || _zlevel === zlevel + EL_AFTER_INCREMENTAL_INC) {
                    var layer = this._layers[_zlevel];
                    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(indexOf(zlevelList, zlevel), 1);
    },

    /**
     * 区域大小变化后重绘
     */
    resize: function (width, height) {
        if (!this._domRoot.style) { // Maybe in node or worker
            if (width == null || height == null) {
                return;
            }
            this._width = width;
            this._height = height;

            this.getLayer(CANVAS_ZLEVEL).resize(width, height);
        }
        else {
            var domRoot = this._domRoot;
            // FIXME Why ?
            domRoot.style.display = 'none';

            // Save input w/h
            var opts = this._opts;
            width != null && (opts.width = width);
            height != null && (opts.height = height);

            width = this._getSize(0);
            height = this._getSize(1);

            domRoot.style.display = '';

            // 优化没有实际改变的resize
            if (this._width !== width || height !== this._height) {
                domRoot.style.width = width + 'px';
                domRoot.style.height = height + 'px';

                for (var id in this._layers) {
                    if (this._layers.hasOwnProperty(id)) {
                        this._layers[id].resize(width, height);
                    }
                }
                each$1(this._progressiveLayers, function (layer) {
                    layer.resize(width, height);
                });

                this.refresh(true);
            }

            this._width = width;
            this._height = height;

        }
        return this;
    },

    /**
     * 清除单独的一个层
     * @param {number} zlevel
     */
    clearLayer: function (zlevel) {
        var layer = this._layers[zlevel];
        if (layer) {
            layer.clear();
        }
    },

    /**
     * 释放
     */
    dispose: function () {
        this.root.innerHTML = '';

        this.root =
        this.storage =

        this._domRoot =
        this._layers = null;
    },

    /**
     * Get canvas which has all thing rendered
     * @param {Object} opts
     * @param {string} [opts.backgroundColor]
     * @param {number} [opts.pixelRatio]
     */
    getRenderedCanvas: function (opts) {
        opts = opts || {};
        if (this._singleCanvas && !this._compositeManually) {
            return this._layers[CANVAS_ZLEVEL].dom;
        }

        var imageLayer = new Layer('image', this, opts.pixelRatio || this.dpr);
        imageLayer.initContext();
        imageLayer.clear(false, opts.backgroundColor || this._backgroundColor);

        if (opts.pixelRatio <= this.dpr) {
            this.refresh();

            var width = imageLayer.dom.width;
            var height = imageLayer.dom.height;
            var ctx = imageLayer.ctx;
            this.eachLayer(function (layer) {
                if (layer.__builtin__) {
                    ctx.drawImage(layer.dom, 0, 0, width, height);
                }
                else if (layer.renderToCanvas) {
                    imageLayer.ctx.save();
                    layer.renderToCanvas(imageLayer.ctx);
                    imageLayer.ctx.restore();
                }
            });
        }
        else {
            // PENDING, echarts-gl and incremental rendering.
            var scope = {};
            var displayList = this.storage.getDisplayList(true);
            for (var i = 0; i < displayList.length; i++) {
                var el = displayList[i];
                this._doPaintEl(el, imageLayer, true, scope);
            }
        }

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

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

    _getSize: function (whIdx) {
        var opts = this._opts;
        var wh = ['width', 'height'][whIdx];
        var cwh = ['clientWidth', 'clientHeight'][whIdx];
        var plt = ['paddingLeft', 'paddingTop'][whIdx];
        var prb = ['paddingRight', 'paddingBottom'][whIdx];

        if (opts[wh] != null && opts[wh] !== 'auto') {
            return parseFloat(opts[wh]);
        }

        var root = this.root;
        // IE8 does not support getComputedStyle, but it use VML.
        var stl = document.defaultView.getComputedStyle(root);

        return (
            (root[cwh] || parseInt10(stl[wh]) || parseInt10(root.style[wh]))
            - (parseInt10(stl[plt]) || 0)
            - (parseInt10(stl[prb]) || 0)
        ) | 0;
    },

    pathToImage: function (path, dpr) {
        dpr = dpr || this.dpr;

        var canvas = document.createElement('canvas');
        var ctx = canvas.getContext('2d');
        var rect = path.getBoundingRect();
        var style = path.style;
        var shadowBlurSize = style.shadowBlur * dpr;
        var shadowOffsetX = style.shadowOffsetX * dpr;
        var shadowOffsetY = style.shadowOffsetY * dpr;
        var lineWidth = style.hasStroke() ? style.lineWidth : 0;

        var leftMargin = Math.max(lineWidth / 2, -shadowOffsetX + shadowBlurSize);
        var rightMargin = Math.max(lineWidth / 2, shadowOffsetX + shadowBlurSize);
        var topMargin = Math.max(lineWidth / 2, -shadowOffsetY + shadowBlurSize);
        var bottomMargin = Math.max(lineWidth / 2, shadowOffsetY + shadowBlurSize);
        var width = rect.width + leftMargin + rightMargin;
        var height = rect.height + topMargin + bottomMargin;

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

        ctx.scale(dpr, dpr);
        ctx.clearRect(0, 0, width, height);
        ctx.dpr = dpr;

        var pathTransform = {
            position: path.position,
            rotation: path.rotation,
            scale: path.scale
        };
        path.position = [leftMargin - rect.x, topMargin - rect.y];
        path.rotation = 0;
        path.scale = [1, 1];
        path.updateTransform();
        if (path) {
            path.brush(ctx);
        }

        var ImageShape = ZImage;
        var imgShape = new ImageShape({
            style: {
                x: 0,
                y: 0,
                image: canvas
            }
        });

        if (pathTransform.position != null) {
            imgShape.position = path.position = pathTransform.position;
        }

        if (pathTransform.rotation != null) {
            imgShape.rotation = path.rotation = pathTransform.rotation;
        }

        if (pathTransform.scale != null) {
            imgShape.scale = path.scale = pathTransform.scale;
        }

        return imgShape;
    }
};

/**
 * Animation main class, dispatch and manage all animation controllers
 *
 * @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

/**
 * @typedef {Object} IZRenderStage
 * @property {Function} update
 */

/**
 * @alias module:zrender/animation/Animation
 * @constructor
 * @param {Object} [options]
 * @param {Function} [options.onframe]
 * @param {IZRenderStage} [options.stage]
 * @example
 *     var animation = new Animation();
 *     var obj = {
 *         x: 100,
 *         y: 100
 *     };
 *     animation.animate(node.position)
 *         .when(1000, {
 *             x: 500,
 *             y: 500
 *         })
 *         .when(2000, {
 *             x: 100,
 *             y: 100
 *         })
 *         .start('spline');
 */
var Animation = function (options) {

    options = options || {};

    this.stage = options.stage || {};

    this.onframe = options.onframe || function () {};

    // private properties
    this._clips = [];

    this._running = false;

    this._time;

    this._pausedTime;

    this._pauseStart;

    this._paused = false;

    Eventful.call(this);
};

Animation.prototype = {

    constructor: Animation,
    /**
     * Add clip
     * @param {module:zrender/animation/Clip} clip
     */
    addClip: function (clip) {
        this._clips.push(clip);
    },
    /**
     * Add 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]);
        }
    },
    /**
     * Delete animation clip
     * @param {module:zrender/animation/Clip} clip
     */
    removeClip: function (clip) {
        var idx = indexOf(this._clips, clip);
        if (idx >= 0) {
            this._clips.splice(idx, 1);
        }
    },

    /**
     * Delete animation clip
     * @param {module:zrender/animation/Animator} animator
     */
    removeAnimator: function (animator) {
        var clips = animator.getClips();
        for (var i = 0; i < clips.length; i++) {
            this.removeClip(clips[i]);
        }
        animator.animation = null;
    },

    _update: function () {
        var time = new Date().getTime() - this._pausedTime;
        var delta = time - this._time;
        var clips = this._clips;
        var len = clips.length;

        var deferredEvents = [];
        var deferredClips = [];
        for (var i = 0; i < len; i++) {
            var clip = clips[i];
            var e = clip.step(time, delta);
            // Throw out the events need to be called after
            // stage.update, like destroy
            if (e) {
                deferredEvents.push(e);
                deferredClips.push(clip);
            }
        }

        // Remove the finished clip
        for (var i = 0; i < len;) {
            if (clips[i]._needsRemove) {
                clips[i] = clips[len - 1];
                clips.pop();
                len--;
            }
            else {
                i++;
            }
        }

        len = deferredEvents.length;
        for (var i = 0; i < len; i++) {
            deferredClips[i].fire(deferredEvents[i]);
        }

        this._time = time;

        this.onframe(delta);

        // 'frame' should be triggered before stage, because upper application
        // depends on the sequence (e.g., echarts-stream and finish
        // event judge)
        this.trigger('frame', delta);

        if (this.stage.update) {
            this.stage.update();
        }
    },

    _startLoop: function () {
        var self = this;

        this._running = true;

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

                requestAnimationFrame(step);

                !self._paused && self._update();
            }
        }

        requestAnimationFrame(step);
    },

    /**
     * Start animation.
     */
    start: function () {

        this._time = new Date().getTime();
        this._pausedTime = 0;

        this._startLoop();
    },

    /**
     * Stop animation.
     */
    stop: function () {
        this._running = false;
    },

    /**
     * Pause animation.
     */
    pause: function () {
        if (!this._paused) {
            this._pauseStart = new Date().getTime();
            this._paused = true;
        }
    },

    /**
     * Resume animation.
     */
    resume: function () {
        if (this._paused) {
            this._pausedTime += (new Date().getTime()) - this._pauseStart;
            this._paused = false;
        }
    },

    /**
     * Clear animation.
     */
    clear: function () {
        this._clips = [];
    },

    /**
     * Whether animation finished.
     */
    isFinished: function () {
        return !this._clips.length;
    },

    /**
     * Creat animator for a target, whose props can be animated.
     *
     * @param  {Object} target
     * @param  {Object} options
     * @param  {boolean} [options.loop=false] Whether loop animation.
     * @param  {Function} [options.getter=null] Get value from target.
     * @param  {Function} [options.setter=null] Set value to target.
     * @return {module:zrender/animation/Animation~Animator}
     */
    // TODO Gap
    animate: function (target, options) {
        options = options || {};

        var animator = new Animator(
            target,
            options.loop,
            options.getter,
            options.setter
        );

        this.addAnimator(animator);

        return animator;
    }
};

mixin(Animation, Eventful);

/* global document */

var TOUCH_CLICK_DELAY = 300;

var globalEventSupported = env$1.domSupported;


var localNativeListenerNames = (function () {
    var mouseHandlerNames = [
        'click', 'dblclick', 'mousewheel', 'mouseout',
        'mouseup', 'mousedown', 'mousemove', 'contextmenu'
    ];
    var touchHandlerNames = [
        'touchstart', 'touchend', 'touchmove'
    ];
    var pointerEventNameMap = {
        pointerdown: 1, pointerup: 1, pointermove: 1, pointerout: 1
    };
    var pointerHandlerNames = map(mouseHandlerNames, function (name) {
        var nm = name.replace('mouse', 'pointer');
        return pointerEventNameMap.hasOwnProperty(nm) ? nm : name;
    });

    return {
        mouse: mouseHandlerNames,
        touch: touchHandlerNames,
        pointer: pointerHandlerNames
    };
})();

var globalNativeListenerNames = {
    mouse: ['mousemove', 'mouseup'],
    pointer: ['pointermove', 'pointerup']
};


function eventNameFix(name) {
    return (name === 'mousewheel' && env$1.browser.firefox) ? 'DOMMouseScroll' : name;
}

function isPointerFromTouch(event) {
    var pointerType = event.pointerType;
    return pointerType === 'pen' || pointerType === 'touch';
}

// function useMSGuesture(handlerProxy, event) {
//     return isPointerFromTouch(event) && !!handlerProxy._msGesture;
// }

// function onMSGestureChange(proxy, event) {
//     if (event.translationX || event.translationY) {
//         // mousemove is carried by MSGesture to reduce the sensitivity.
//         proxy.handler.dispatchToElement(event.target, 'mousemove', event);
//     }
//     if (event.scale !== 1) {
//         event.pinchX = event.offsetX;
//         event.pinchY = event.offsetY;
//         event.pinchScale = event.scale;
//         proxy.handler.dispatchToElement(event.target, 'pinch', event);
//     }
// }

/**
 * Prevent mouse event from being dispatched after Touch Events action
 * @see <https://github.com/deltakosh/handjs/blob/master/src/hand.base.js>
 * 1. Mobile browsers dispatch mouse events 300ms after touchend.
 * 2. Chrome for Android dispatch mousedown for long-touch about 650ms
 * Result: Blocking Mouse Events for 700ms.
 *
 * @param {DOMHandlerScope} scope
 */
function setTouchTimer(scope) {
    scope.touching = true;
    if (scope.touchTimer != null) {
        clearTimeout(scope.touchTimer);
        scope.touchTimer = null;
    }
    scope.touchTimer = setTimeout(function () {
        scope.touching = false;
        scope.touchTimer = null;
    }, 700);
}

// Mark touch, which is useful in distinguish touch and
// mouse event in upper applicatoin.
function markTouch(event) {
    event && (event.zrByTouch = true);
}


// function markTriggeredFromLocal(event) {
//     event && (event.__zrIsFromLocal = true);
// }

// function isTriggeredFromLocal(instance, event) {
//     return !!(event && event.__zrIsFromLocal);
// }

function normalizeGlobalEvent(instance, event) {
    // offsetX, offsetY still need to be calculated. They are necessary in the event
    // handlers of the upper applications. Set `true` to force calculate them.
    return normalizeEvent(instance.dom, new FakeGlobalEvent(instance, event), true);
}

/**
 * Detect whether the given el is in `painterRoot`.
 */
function isLocalEl(instance, el) {
    var elTmp = el;
    var isLocal = false;
    while (elTmp && elTmp.nodeType !== 9
        && !(
            isLocal = elTmp.domBelongToZr
                || (elTmp !== el && elTmp === instance.painterRoot)
        )
    ) {
        elTmp = elTmp.parentNode;
    }
    return isLocal;
}

/**
 * Make a fake event but not change the original event,
 * becuase the global event probably be used by other
 * listeners not belonging to zrender.
 * @class
 */
function FakeGlobalEvent(instance, event) {
    this.type = event.type;
    this.target = this.currentTarget = instance.dom;
    this.pointerType = event.pointerType;
    // Necessray for the force calculation of zrX, zrY
    this.clientX = event.clientX;
    this.clientY = event.clientY;
    // Because we do not mount global listeners to touch events,
    // we do not copy `targetTouches` and `changedTouches` here.
}
var fakeGlobalEventProto = FakeGlobalEvent.prototype;
// we make the default methods on the event do nothing,
// otherwise it is dangerous. See more details in
// [Drag outside] in `Handler.js`.
fakeGlobalEventProto.stopPropagation =
    fakeGlobalEventProto.stopImmediatePropagation =
    fakeGlobalEventProto.preventDefault = noop;


/**
 * Local DOM Handlers
 * @this {HandlerProxy}
 */
var localDOMHandlers = {

    mousedown: function (event) {
        event = normalizeEvent(this.dom, event);

        this._mayPointerCapture = [event.zrX, event.zrY];

        this.trigger('mousedown', event);
    },

    mousemove: function (event) {
        event = normalizeEvent(this.dom, event);

        var downPoint = this._mayPointerCapture;
        if (downPoint && (event.zrX !== downPoint[0] || event.zrY !== downPoint[1])) {
            togglePointerCapture(this, true);
        }

        this.trigger('mousemove', event);
    },

    mouseup: function (event) {
        event = normalizeEvent(this.dom, event);

        togglePointerCapture(this, false);

        this.trigger('mouseup', event);
    },

    mouseout: function (event) {
        event = normalizeEvent(this.dom, event);

        // Similarly to the browser did on `document` and touch event,
        // `globalout` will be delayed to final pointer cature release.
        if (this._pointerCapturing) {
            event.zrEventControl = 'no_globalout';
        }

        // There might be some doms created by upper layer application
        // at the same level of painter.getViewportRoot() (e.g., tooltip
        // dom created by echarts), where 'globalout' event should not
        // be triggered when mouse enters these doms. (But 'mouseout'
        // should be triggered at the original hovered element as usual).
        var element = event.toElement || event.relatedTarget;
        event.zrIsToLocalDOM = isLocalEl(this, element);

        this.trigger('mouseout', event);
    },

    touchstart: function (event) {
        // Default mouse behaviour should not be disabled here.
        // For example, page may needs to be slided.
        event = normalizeEvent(this.dom, event);

        markTouch(event);

        this._lastTouchMoment = new Date();

        this.handler.processGesture(event, 'start');

        // For consistent event listener for both touch device and mouse device,
        // we simulate "mouseover-->mousedown" in touch device. So we trigger
        // `mousemove` here (to trigger `mouseover` inside), and then trigger
        // `mousedown`.
        localDOMHandlers.mousemove.call(this, event);
        localDOMHandlers.mousedown.call(this, event);
    },

    touchmove: function (event) {
        event = normalizeEvent(this.dom, event);

        markTouch(event);

        this.handler.processGesture(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.
        localDOMHandlers.mousemove.call(this, event);
    },

    touchend: function (event) {
        event = normalizeEvent(this.dom, event);

        markTouch(event);

        this.handler.processGesture(event, 'end');

        localDOMHandlers.mouseup.call(this, event);

        // Do not trigger `mouseout` here, in spite of `mousemove`(`mouseover`) is
        // triggered in `touchstart`. This seems to be illogical, but by this mechanism,
        // we can conveniently implement "hover style" in both PC and touch device just
        // by listening to `mouseover` to add "hover style" and listening to `mouseout`
        // to remove "hover style" on an element, without any additional code for
        // compatibility. (`mouseout` will not be triggered in `touchend`, so "hover
        // style" will remain for user view)

        // click event should always be triggered no matter whether
        // there is gestrue event. System click can not be prevented.
        if (+new Date() - this._lastTouchMoment < TOUCH_CLICK_DELAY) {
            localDOMHandlers.click.call(this, event);
        }
    },

    pointerdown: function (event) {
        localDOMHandlers.mousedown.call(this, event);

        // if (useMSGuesture(this, event)) {
        //     this._msGesture.addPointer(event.pointerId);
        // }
    },

    pointermove: function (event) {
        // FIXME
        // pointermove is so sensitive that it always triggered when
        // tap(click) on touch screen, which affect some judgement in
        // upper application. So, we dont support mousemove on MS touch
        // device yet.
        if (!isPointerFromTouch(event)) {
            localDOMHandlers.mousemove.call(this, event);
        }
    },

    pointerup: function (event) {
        localDOMHandlers.mouseup.call(this, event);
    },

    pointerout: function (event) {
        // pointerout will be triggered when tap on touch screen
        // (IE11+/Edge on MS Surface) after click event triggered,
        // which is inconsistent with the mousout behavior we defined
        // in touchend. So we unify them.
        // (check localDOMHandlers.touchend for detailed explanation)
        if (!isPointerFromTouch(event)) {
            localDOMHandlers.mouseout.call(this, event);
        }
    }

};

/**
 * Othere DOM UI Event handlers for zr dom.
 * @this {HandlerProxy}
 */
each$1(['click', 'mousewheel', 'dblclick', 'contextmenu'], function (name) {
    localDOMHandlers[name] = function (event) {
        event = normalizeEvent(this.dom, event);
        this.trigger(name, event);
    };
});


/**
 * DOM UI Event handlers for global page.
 *
 * [Caution]:
 * those handlers should both support in capture phase and bubble phase!
 *
 * @this {HandlerProxy}
 */
var globalDOMHandlers = {

    pointermove: function (event) {
        // FIXME
        // pointermove is so sensitive that it always triggered when
        // tap(click) on touch screen, which affect some judgement in
        // upper application. So, we dont support mousemove on MS touch
        // device yet.
        if (!isPointerFromTouch(event)) {
            globalDOMHandlers.mousemove.call(this, event);
        }
    },

    pointerup: function (event) {
        globalDOMHandlers.mouseup.call(this, event);
    },

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

    mouseup: function (event) {
        var pointerCaptureReleasing = this._pointerCapturing;

        togglePointerCapture(this, false);

        this.trigger('mouseup', event);

        if (pointerCaptureReleasing) {
            event.zrEventControl = 'only_globalout';
            this.trigger('mouseout', event);
        }
    }

};


/**
 * @param {HandlerProxy} instance
 * @param {DOMHandlerScope} scope
 */
function mountLocalDOMEventListeners(instance, scope) {
    var domHandlers = scope.domHandlers;

    if (env$1.pointerEventsSupported) { // Only IE11+/Edge
        // 1. On devices that both enable touch and mouse (e.g., MS Surface and lenovo X240),
        // IE11+/Edge do not trigger touch event, but trigger pointer event and mouse event
        // at the same time.
        // 2. On MS Surface, it probablely only trigger mousedown but no mouseup when tap on
        // screen, which do not occurs in pointer event.
        // So we use pointer event to both detect touch gesture and mouse behavior.
        each$1(localNativeListenerNames.pointer, function (nativeEventName) {
            mountSingleDOMEventListener(scope, nativeEventName, function (event) {
                // markTriggeredFromLocal(event);
                domHandlers[nativeEventName].call(instance, event);
            });
        });

        // FIXME
        // Note: MS Gesture require CSS touch-action set. But touch-action is not reliable,
        // which does not prevent defuault behavior occasionally (which may cause view port
        // zoomed in but use can not zoom it back). And event.preventDefault() does not work.
        // So we have to not to use MSGesture and not to support touchmove and pinch on MS
        // touch screen. And we only support click behavior on MS touch screen now.

        // MS Gesture Event is only supported on IE11+/Edge and on Windows 8+.
        // We dont support touch on IE on win7.
        // See <https://msdn.microsoft.com/en-us/library/dn433243(v=vs.85).aspx>
        // if (typeof MSGesture === 'function') {
        //     (this._msGesture = new MSGesture()).target = dom; // jshint ignore:line
        //     dom.addEventListener('MSGestureChange', onMSGestureChange);
        // }
    }
    else {
        if (env$1.touchEventsSupported) {
            each$1(localNativeListenerNames.touch, function (nativeEventName) {
                mountSingleDOMEventListener(scope, nativeEventName, function (event) {
                    // markTriggeredFromLocal(event);
                    domHandlers[nativeEventName].call(instance, event);
                    setTouchTimer(scope);
                });
            });
            // Handler of 'mouseout' event is needed in touch mode, which will be mounted below.
            // addEventListener(root, 'mouseout', this._mouseoutHandler);
        }

        // 1. Considering some devices that both enable touch and mouse event (like on MS Surface
        // and lenovo X240, @see #2350), we make mouse event be always listened, otherwise
        // mouse event can not be handle in those devices.
        // 2. On MS Surface, Chrome will trigger both touch event and mouse event. How to prevent
        // mouseevent after touch event triggered, see `setTouchTimer`.
        each$1(localNativeListenerNames.mouse, function (nativeEventName) {
            mountSingleDOMEventListener(scope, nativeEventName, function (event) {
                event = getNativeEvent(event);
                if (!scope.touching) {
                    // markTriggeredFromLocal(event);
                    domHandlers[nativeEventName].call(instance, event);
                }
            });
        });
    }
}

/**
 * @param {HandlerProxy} instance
 * @param {DOMHandlerScope} scope
 */
function mountGlobalDOMEventListeners(instance, scope) {
    // Only IE11+/Edge. See the comment in `mountLocalDOMEventListeners`.
    if (env$1.pointerEventsSupported) {
        each$1(globalNativeListenerNames.pointer, mount);
    }
    // Touch event has implemented "drag outside" so we do not mount global listener for touch event.
    // (see https://www.w3.org/TR/touch-events/#the-touchmove-event)
    // We do not consider "both-support-touch-and-mouse device" for this feature (see the comment of
    // `mountLocalDOMEventListeners`) to avoid bugs util some requirements come.
    else if (!env$1.touchEventsSupported) {
        each$1(globalNativeListenerNames.mouse, mount);
    }

    function mount(nativeEventName) {
        function nativeEventListener(event) {
            event = getNativeEvent(event);
            // See the reason in [Drag outside] in `Handler.js`
            // This checking supports both `useCapture` or not.
            // PENDING: if there is performance issue in some devices,
            // we probably can not use `useCapture` and change a easier
            // to judes whether local (mark).
            if (!isLocalEl(instance, event.target)) {
                event = normalizeGlobalEvent(instance, event);
                scope.domHandlers[nativeEventName].call(instance, event);
            }
        }
        mountSingleDOMEventListener(
            scope, nativeEventName, nativeEventListener,
            {capture: true} // See [Drag Outside] in `Handler.js`
        );
    }
}

function mountSingleDOMEventListener(scope, nativeEventName, listener, opt) {
    scope.mounted[nativeEventName] = listener;
    scope.listenerOpts[nativeEventName] = opt;
    addEventListener(scope.domTarget, eventNameFix(nativeEventName), listener, opt);
}

function unmountDOMEventListeners(scope) {
    var mounted = scope.mounted;
    for (var nativeEventName in mounted) {
        if (mounted.hasOwnProperty(nativeEventName)) {
            removeEventListener(
                scope.domTarget, eventNameFix(nativeEventName), mounted[nativeEventName],
                scope.listenerOpts[nativeEventName]
            );
        }
    }
    scope.mounted = {};
}

/**
 * See [Drag Outside] in `Handler.js`.
 * @implement
 * @param {boolean} isPointerCapturing Should never be `null`/`undefined`.
 *        `true`: start to capture pointer if it is not capturing.
 *        `false`: end the capture if it is capturing.
 */
function togglePointerCapture(instance, isPointerCapturing) {
    instance._mayPointerCapture = null;

    if (globalEventSupported && (instance._pointerCapturing ^ isPointerCapturing)) {
        instance._pointerCapturing = isPointerCapturing;

        var globalHandlerScope = instance._globalHandlerScope;
        isPointerCapturing
            ? mountGlobalDOMEventListeners(instance, globalHandlerScope)
            : unmountDOMEventListeners(globalHandlerScope);
    }
}

/**
 * @inner
 * @class
 */
function DOMHandlerScope(domTarget, domHandlers) {
    this.domTarget = domTarget;
    this.domHandlers = domHandlers;

    // Key: eventName, value: mounted handler funcitons.
    // Used for unmount.
    this.mounted = {};
    this.listenerOpts = {};

    this.touchTimer = null;
    this.touching = false;
}

/**
 * @public
 * @class
 */
function HandlerDomProxy(dom, painterRoot) {
    Eventful.call(this);

    this.dom = dom;
    this.painterRoot = painterRoot;

    this._localHandlerScope = new DOMHandlerScope(dom, localDOMHandlers);

    if (globalEventSupported) {
        this._globalHandlerScope = new DOMHandlerScope(document, globalDOMHandlers);
    }

    /**
     * @type {boolean}
     */
    this._pointerCapturing = false;
    /**
     * @type {Array.<number>} [x, y] or null.
     */
    this._mayPointerCapture = null;

    mountLocalDOMEventListeners(this, this._localHandlerScope);
}

var handlerDomProxyProto = HandlerDomProxy.prototype;

handlerDomProxyProto.dispose = function () {
    unmountDOMEventListeners(this._localHandlerScope);
    if (globalEventSupported) {
        unmountDOMEventListeners(this._globalHandlerScope);
    }
};

handlerDomProxyProto.setCursor = function (cursorStyle) {
    this.dom.style && (this.dom.style.cursor = cursorStyle || 'default');
};


mixin(HandlerDomProxy, Eventful);

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

var useVML = !env$1.canvasSupported;

var painterCtors = {
    canvas: Painter
};

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

/**
 * @type {string}
 */
var version$1 = '4.3.2';

/**
 * Initializing a zrender instance
 * @param {HTMLElement} dom
 * @param {Object} [opts]
 * @param {string} [opts.renderer='canvas'] 'canvas' or 'svg'
 * @param {number} [opts.devicePixelRatio]
 * @param {number|string} [opts.width] Can be 'auto' (the same as null/undefined)
 * @param {number|string} [opts.height] Can be 'auto' (the same as null/undefined)
 * @return {module:zrender/ZRender}
 */
function init$1(dom, opts) {
    var zr = new ZRender(guid(), dom, opts);
    instances$1[zr.id] = zr;
    return zr;
}

/**
 * Dispose zrender instance
 * @param {module:zrender/ZRender} zr
 */
function dispose$1(zr) {
    if (zr) {
        zr.dispose();
    }
    else {
        for (var key in instances$1) {
            if (instances$1.hasOwnProperty(key)) {
                instances$1[key].dispose();
            }
        }
        instances$1 = {};
    }

    return this;
}

/**
 * Get zrender instance by id
 * @param {string} id zrender instance id
 * @return {module:zrender/ZRender}
 */
function getInstance(id) {
    return instances$1[id];
}

function registerPainter(name, Ctor) {
    painterCtors[name] = Ctor;
}

function delInstance(id) {
    delete instances$1[id];
}

/**
 * @module zrender/ZRender
 */
/**
 * @constructor
 * @alias module:zrender/ZRender
 * @param {string} id
 * @param {HTMLElement} dom
 * @param {Object} opts
 * @param {string} [opts.renderer='canvas'] 'canvas' or 'svg'
 * @param {number} [opts.devicePixelRatio]
 * @param {number} [opts.width] Can be 'auto' (the same as null/undefined)
 * @param {number} [opts.height] Can be 'auto' (the same as null/undefined)
 */
var ZRender = function (id, dom, opts) {

    opts = opts || {};

    /**
     * @type {HTMLDomElement}
     */
    this.dom = dom;

    /**
     * @type {string}
     */
    this.id = id;

    var self = this;
    var storage = new Storage();

    var rendererType = opts.renderer;
    // TODO WebGL
    if (useVML) {
        if (!painterCtors.vml) {
            throw new Error('You need to require \'zrender/vml/vml\' to support IE8');
        }
        rendererType = 'vml';
    }
    else if (!rendererType || !painterCtors[rendererType]) {
        rendererType = 'canvas';
    }
    var painter = new painterCtors[rendererType](dom, storage, opts, id);

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

    var handerProxy = (!env$1.node && !env$1.worker) ? new HandlerDomProxy(painter.getViewportRoot(), painter.root) : null;
    this.handler = new Handler(storage, painter, handerProxy, painter.root);

    /**
     * @type {module:zrender/animation/Animation}
     */
    this.animation = new Animation({
        stage: {
            update: bind(this.flush, this)
        }
    });
    this.animation.start();

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

    // 修改 storage.delFromStorage, 每次删除元素之前删除动画
    // FIXME 有点ugly
    var oldDelFromStorage = storage.delFromStorage;
    var oldAddToStorage = storage.addToStorage;

    storage.delFromStorage = function (el) {
        oldDelFromStorage.call(storage, el);

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

    storage.addToStorage = function (el) {
        oldAddToStorage.call(storage, el);

        el.addSelfToZr(self);
    };
};

ZRender.prototype = {

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

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

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

    /**
     * Change configuration of layer
     * @param {string} zLevel
     * @param {Object} config
     * @param {string} [config.clearColor=0] Clear color
     * @param {string} [config.motionBlur=false] If enable motion blur
     * @param {number} [config.lastFrameAlpha=0.7] Motion blur factor. Larger value cause longer trailer
    */
    configLayer: function (zLevel, config) {
        if (this.painter.configLayer) {
            this.painter.configLayer(zLevel, config);
        }
        this._needsRefresh = true;
    },

    /**
     * Set background color
     * @param {string} backgroundColor
     */
    setBackgroundColor: function (backgroundColor) {
        if (this.painter.setBackgroundColor) {
            this.painter.setBackgroundColor(backgroundColor);
        }
        this._needsRefresh = true;
    },

    /**
     * Repaint the canvas immediately
     */
    refreshImmediately: function () {
        // var start = new Date();

        // Clear needsRefresh ahead to avoid something wrong happens in refresh
        // Or it will cause zrender refreshes again and again.
        this._needsRefresh = this._needsRefreshHover = false;
        this.painter.refresh();
        // Avoid trigger zr.refresh in Element#beforeUpdate hook
        this._needsRefresh = this._needsRefreshHover = false;

        // var end = new Date();
        // var log = document.getElementById('log');
        // if (log) {
        //     log.innerHTML = log.innerHTML + '<br>' + (end - start);
        // }
    },

    /**
     * Mark and repaint the canvas in the next frame of browser
     */
    refresh: function () {
        this._needsRefresh = true;
    },

    /**
     * Perform all refresh
     */
    flush: function () {
        var triggerRendered;

        if (this._needsRefresh) {
            triggerRendered = true;
            this.refreshImmediately();
        }
        if (this._needsRefreshHover) {
            triggerRendered = true;
            this.refreshHoverImmediately();
        }

        triggerRendered && this.trigger('rendered');
    },

    /**
     * Add element to hover layer
     * @param  {module:zrender/Element} el
     * @param {Object} style
     */
    addHover: function (el, style) {
        if (this.painter.addHover) {
            var elMirror = this.painter.addHover(el, style);
            this.refreshHover();
            return elMirror;
        }
    },

    /**
     * Add element from hover layer
     * @param  {module:zrender/Element} el
     */
    removeHover: function (el) {
        if (this.painter.removeHover) {
            this.painter.removeHover(el);
            this.refreshHover();
        }
    },

    /**
     * Clear all hover elements in hover layer
     * @param  {module:zrender/Element} el
     */
    clearHover: function () {
        if (this.painter.clearHover) {
            this.painter.clearHover();
            this.refreshHover();
        }
    },

    /**
     * Refresh hover in next frame
     */
    refreshHover: function () {
        this._needsRefreshHover = true;
    },

    /**
     * Refresh hover immediately
     */
    refreshHoverImmediately: function () {
        this._needsRefreshHover = false;
        this.painter.refreshHover && this.painter.refreshHover();
    },

    /**
     * Resize the canvas.
     * Should be invoked when container size is changed
     * @param {Object} [opts]
     * @param {number|string} [opts.width] Can be 'auto' (the same as null/undefined)
     * @param {number|string} [opts.height] Can be 'auto' (the same as null/undefined)
     */
    resize: function (opts) {
        opts = opts || {};
        this.painter.resize(opts.width, opts.height);
        this.handler.resize();
    },

    /**
     * Stop and clear all animation immediately
     */
    clearAnimation: function () {
        this.animation.clear();
    },

    /**
     * Get container width
     */
    getWidth: function () {
        return this.painter.getWidth();
    },

    /**
     * Get container height
     */
    getHeight: function () {
        return this.painter.getHeight();
    },

    /**
     * Export the canvas as Base64 URL
     * @param {string} type
     * @param {string} [backgroundColor='#fff']
     * @return {string} Base64 URL
     */
    // toDataURL: function(type, backgroundColor) {
    //     return this.painter.getRenderedCanvas({
    //         backgroundColor: backgroundColor
    //     }).toDataURL(type);
    // },

    /**
     * Converting a path to image.
     * It has much better performance of drawing image rather than drawing a vector path.
     * @param {module:zrender/graphic/Path} e
     * @param {number} width
     * @param {number} height
     */
    pathToImage: function (e, dpr) {
        return this.painter.pathToImage(e, dpr);
    },

    /**
     * Set default cursor
     * @param {string} [cursorStyle='default'] 例如 crosshair
     */
    setCursorStyle: function (cursorStyle) {
        this.handler.setCursorStyle(cursorStyle);
    },

    /**
     * Find hovered element
     * @param {number} x
     * @param {number} y
     * @return {Object} {target, topTarget}
     */
    findHover: function (x, y) {
        return this.handler.findHover(x, y);
    },

    /**
     * Bind event
     *
     * @param {string} eventName Event name
     * @param {Function} eventHandler Handler function
     * @param {Object} [context] Context object
     */
    on: function (eventName, eventHandler, context) {
        this.handler.on(eventName, eventHandler, context);
    },

    /**
     * Unbind event
     * @param {string} eventName Event name
     * @param {Function} [eventHandler] Handler function
     */
    off: function (eventName, eventHandler) {
        this.handler.off(eventName, eventHandler);
    },

    /**
     * Trigger event manually
     *
     * @param {string} eventName Event name
     * @param {event=} event Event object
     */
    trigger: function (eventName, event) {
        this.handler.trigger(eventName, event);
    },


    /**
     * Clear all objects and the canvas.
     */
    clear: function () {
        this.storage.delRoot();
        this.painter.clear();
    },

    /**
     * Dispose self.
     */
    dispose: function () {
        this.animation.stop();

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

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

        delInstance(this.id);
    }
};



var zrender = (Object.freeze || Object)({
	version: version$1,
	init: init$1,
	dispose: dispose$1,
	getInstance: getInstance,
	registerPainter: registerPainter
});

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var each$2 = each$1;
var isObject$2 = isObject$1;
var isArray$1 = isArray;

/**
 * Make the name displayable. But we should
 * make sure it is not duplicated with user
 * specified name, so use '\0';
 */
var DUMMY_COMPONENT_NAME_PREFIX = 'series\0';

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

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

        // Default emphasis option from normal
        for (var i = 0, len = subOpts.length; i < len; i++) {
            var subOptName = subOpts[i];
            if (!opt.emphasis[key].hasOwnProperty(subOptName)
                && opt[key].hasOwnProperty(subOptName)
            ) {
                opt.emphasis[key][subOptName] = opt[key][subOptName];
            }
        }
    }
}

var TEXT_STYLE_OPTIONS = [
    'fontStyle', 'fontWeight', 'fontSize', 'fontFamily',
    'rich', 'tag', 'color', 'textBorderColor', 'textBorderWidth',
    'width', 'height', 'lineHeight', 'align', 'verticalAlign', 'baseline',
    'shadowColor', 'shadowBlur', 'shadowOffsetX', 'shadowOffsetY',
    'textShadowColor', 'textShadowBlur', 'textShadowOffsetX', 'textShadowOffsetY',
    'backgroundColor', 'borderColor', 'borderWidth', 'borderRadius', 'padding'
];

// modelUtil.LABEL_OPTIONS = modelUtil.TEXT_STYLE_OPTIONS.concat([
//     'position', 'offset', 'rotate', 'origin', 'show', 'distance', 'formatter',
//     'fontStyle', 'fontWeight', 'fontSize', 'fontFamily',
//     // FIXME: deprecated, check and remove it.
//     'textStyle'
// ]);

/**
 * The method do not ensure performance.
 * 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>}
 */
function getDataItemValue(dataItem) {
    return (isObject$2(dataItem) && !isArray$1(dataItem) && !(dataItem instanceof Date))
        ? dataItem.value : dataItem;
}

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

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

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

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

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

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

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

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

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

    return result;
}

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

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

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

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

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

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

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

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

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

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

        // name can be overwitten. Consider case: axis.name = '20km'.
        // But id generated by name will not be changed, which affect
        // only in that case: setOption with 'not merge mode' and view
        // instance will be recreated, which can be accepted.
        keyInfo.name = opt.name != null
            ? opt.name + ''
            : existCpt
            ? existCpt.name
            // Avoid diffferent series has the same name,
            // because name may be used like in color pallet.
            : DUMMY_COMPONENT_NAME_PREFIX + index;

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

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

function isNameSpecified(componentModel) {
    var name = componentModel.name;
    // Is specified when `indexOf` get -1 or > 0.
    return !!(name && name.indexOf(DUMMY_COMPONENT_NAME_PREFIX));
}

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

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


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

/**
 * Enable property storage to any host object.
 * Notice: Serialization is not supported.
 *
 * For example:
 * var inner = zrUitl.makeInner();
 *
 * function some1(hostObj) {
 *      inner(hostObj).someProperty = 1212;
 *      ...
 * }
 * function some2() {
 *      var fields = inner(this);
 *      fields.someProperty1 = 1212;
 *      fields.someProperty2 = 'xx';
 *      ...
 * }
 *
 * @return {Function}
 */
function makeInner() {
    // Consider different scope by es module import.
    var key = '__\0ec_inner_' + innerUniqueIndex++ + '_' + Math.random().toFixed(5);
    return function (hostObj) {
        return hostObj[key] || (hostObj[key] = {});
    };
}
var innerUniqueIndex = 0;

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

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

    var result = {};

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

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

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

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

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

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

    return result;
}

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

function setAttribute(dom, key, value) {
    dom.setAttribute
        ? dom.setAttribute(key, value)
        : (dom[key] = value);
}

function getAttribute(dom, key) {
    return dom.getAttribute
        ? dom.getAttribute(key)
        : dom[key];
}

function getTooltipRenderMode(renderModeOption) {
    if (renderModeOption === 'auto') {
        // Using html when `document` exists, use richText otherwise
        return env$1.domSupported ? 'html' : 'richText';
    }
    else {
        return renderModeOption || 'html';
    }
}

/**
 * Group a list by key.
 *
 * @param {Array} array
 * @param {Function} getKey
 *        param {*} Array item
 *        return {string} key
 * @return {Object} Result
 *        {Array}: keys,
 *        {module:zrender/core/util/HashMap} buckets: {key -> Array}
 */

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var TYPE_DELIMITER = '.';
var IS_CONTAINER = '___EC__COMPONENT__CONTAINER___';

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

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

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

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

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

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

        extend(ExtendedClass.prototype, proto);

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

        return ExtendedClass;
    };
}

var classBase = 0;

/**
 * Can not use instanceof, consider different scope by
 * cross domain or es module import in ec extensions.
 * Mount a method "isInstance()" to Clz.
 */
function enableClassCheck(Clz) {
    var classAttr = ['__\0is_clz', classBase++, Math.random().toFixed(3)].join('_');
    Clz.prototype[classAttr] = true;

    if (__DEV__) {
        assert$1(!Clz.isInstance, 'The method "is" can not be defined.');
    }

    Clz.isInstance = function (obj) {
        return !!(obj && obj[classAttr]);
    };
}

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

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

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

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

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

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

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

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

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

        return Clazz;
    };

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

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

        if (obj && obj[IS_CONTAINER]) {
            each$1(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$1(componentType);
        return !!storage[componentType.main];
    };

    /**
     * @return {Array.<string>} Like ['aa', 'bb'], but can not be ['aa.xx']
     */
    entity.getAllClassMainTypes = function () {
        var types = [];
        each$1(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$1(componentType);
        var obj = storage[componentType.main];
        return obj && obj[IS_CONTAINER];
    };

    entity.parseClassType = parseClassType$1;

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

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

// TODO Parse shadow style
// TODO Only shallow path support
var makeStyleMapper = function (properties) {
    // Normalize
    for (var i = 0; i < properties.length; i++) {
        if (!properties[i][1]) {
            properties[i][1] = properties[i][0];
        }
    }
    return function (model, excludes, includes) {
        var style = {};
        for (var i = 0; i < properties.length; i++) {
            var propName = properties[i][1];
            if ((excludes && indexOf(excludes, propName) >= 0)
                || (includes && indexOf(includes, propName) < 0)
            ) {
                continue;
            }
            var val = model.getShallow(propName);
            if (val != null) {
                style[properties[i][0]] = val;
            }
        }
        return style;
    };
};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var getLineStyle = makeStyleMapper(
    [
        ['lineWidth', 'width'],
        ['stroke', 'color'],
        ['opacity'],
        ['shadowBlur'],
        ['shadowOffsetX'],
        ['shadowOffsetY'],
        ['shadowColor']
    ]
);

var lineStyleMixin = {
    getLineStyle: function (excludes) {
        var style = getLineStyle(this, excludes);
        // Always set lineDash whether dashed, otherwise we can not
        // erase the previous style when assigning to el.style.
        style.lineDash = this.getLineDash(style.lineWidth);
        return style;
    },

    getLineDash: function (lineWidth) {
        if (lineWidth == null) {
            lineWidth = 1;
        }
        var lineType = this.get('type');
        var dotSize = Math.max(lineWidth, 2);
        var dashSize = lineWidth * 4;
        return (lineType === 'solid' || lineType == null)
            // Use `false` but not `null` for the solid line here, because `null` might be
            // ignored when assigning to `el.style`. e.g., when setting `lineStyle.type` as
            // `'dashed'` and `emphasis.lineStyle.type` as `'solid'` in graph series, the
            // `lineDash` gotten form the latter one is not able to erase that from the former
            // one if using `null` here according to the emhpsis strategy in `util/graphic.js`.
            ? false
            : lineType === 'dashed'
            ? [dashSize, dashSize]
            : [dotSize, dotSize];
    }
};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var getAreaStyle = makeStyleMapper(
    [
        ['fill', 'color'],
        ['shadowBlur'],
        ['shadowOffsetX'],
        ['shadowOffsetY'],
        ['opacity'],
        ['shadowColor']
    ]
);

var areaStyleMixin = {
    getAreaStyle: function (excludes, includes) {
        return getAreaStyle(this, excludes, includes);
    }
};

/**
 * 曲线辅助模块
 * @module zrender/core/curve
 * @author pissang(https://www.github.com/pissang)
 */

var mathPow = Math.pow;
var mathSqrt$2 = Math.sqrt;

var EPSILON$1 = 1e-8;
var EPSILON_NUMERIC = 1e-4;

var THREE_SQRT = mathSqrt$2(3);
var ONE_THIRD = 1 / 3;

// 临时变量
var _v0 = create();
var _v1 = create();
var _v2 = create();

function isAroundZero(val) {
    return val > -EPSILON$1 && val < EPSILON$1;
}
function isNotAroundZero$1(val) {
    return val > EPSILON$1 || val < -EPSILON$1;
}
/**
 * 计算三次贝塞尔值
 * @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$2(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$2(A * A * A));
            var theta = Math.acos(T) / 3;
            var ASqrt = mathSqrt$2(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$1(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$2(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 = distSquare(_v0, _v1);
        if (d1 < d) {
            t = _t;
            d = d1;
        }
    }
    d = Infinity;

    // At most 32 iteration
    for (var i = 0; i < 32; i++) {
        if (interval < EPSILON_NUMERIC) {
            break;
        }
        prev = t - interval;
        next = t + interval;
        // t - interval
        _v1[0] = cubicAt(x0, x1, x2, x3, prev);
        _v1[1] = cubicAt(y0, y1, y2, y3, prev);

        d1 = distSquare(_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 = distSquare(_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$2(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$1(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$2(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 = distSquare(_v0, _v1);
        if (d1 < d) {
            t = _t;
            d = d1;
        }
    }
    d = Infinity;

    // At most 32 iteration
    for (var i = 0; i < 32; i++) {
        if (interval < EPSILON_NUMERIC) {
            break;
        }
        var prev = t - interval;
        var next = t + interval;
        // t - interval
        _v1[0] = quadraticAt(x0, x1, x2, prev);
        _v1[1] = quadraticAt(y0, y1, y2, prev);

        var d1 = distSquare(_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 = distSquare(_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$2(d);
}

/**
 * @author Yi Shen(https://github.com/pissang)
 */

var mathMin$3 = Math.min;
var mathMax$3 = Math.max;
var mathSin$2 = Math.sin;
var mathCos$2 = Math.cos;
var PI2 = Math.PI * 2;

var start = create();
var end = create();
var extremity = create();

/**
 * 从顶点数组中计算出最小包围盒，写入`min`和`max`中
 * @module zrender/core/bbox
 * @param {Array<Object>} points 顶点数组
 * @param {number} min
 * @param {number} max
 */
function fromPoints(points, min$$1, max$$1) {
    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$3(left, p[0]);
        right = mathMax$3(right, p[0]);
        top = mathMin$3(top, p[1]);
        bottom = mathMax$3(bottom, p[1]);
    }

    min$$1[0] = left;
    min$$1[1] = top;
    max$$1[0] = right;
    max$$1[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
 */
function fromLine(x0, y0, x1, y1, min$$1, max$$1) {
    min$$1[0] = mathMin$3(x0, x1);
    min$$1[1] = mathMin$3(y0, y1);
    max$$1[0] = mathMax$3(x0, x1);
    max$$1[1] = mathMax$3(y0, y1);
}

var xDim = [];
var yDim = [];
/**
 * 从三阶贝塞尔曲线(p0, p1, p2, p3)中计算出最小包围盒，写入`min`和`max`中
 * @memberOf module:zrender/core/bbox
 * @param {number} x0
 * @param {number} y0
 * @param {number} x1
 * @param {number} y1
 * @param {number} x2
 * @param {number} y2
 * @param {number} x3
 * @param {number} y3
 * @param {Array.<number>} min
 * @param {Array.<number>} max
 */
function fromCubic(
    x0, y0, x1, y1, x2, y2, x3, y3, min$$1, max$$1
) {
    var cubicExtrema$$1 = cubicExtrema;
    var cubicAt$$1 = cubicAt;
    var i;
    var n = cubicExtrema$$1(x0, x1, x2, x3, xDim);
    min$$1[0] = Infinity;
    min$$1[1] = Infinity;
    max$$1[0] = -Infinity;
    max$$1[1] = -Infinity;

    for (i = 0; i < n; i++) {
        var x = cubicAt$$1(x0, x1, x2, x3, xDim[i]);
        min$$1[0] = mathMin$3(x, min$$1[0]);
        max$$1[0] = mathMax$3(x, max$$1[0]);
    }
    n = cubicExtrema$$1(y0, y1, y2, y3, yDim);
    for (i = 0; i < n; i++) {
        var y = cubicAt$$1(y0, y1, y2, y3, yDim[i]);
        min$$1[1] = mathMin$3(y, min$$1[1]);
        max$$1[1] = mathMax$3(y, max$$1[1]);
    }

    min$$1[0] = mathMin$3(x0, min$$1[0]);
    max$$1[0] = mathMax$3(x0, max$$1[0]);
    min$$1[0] = mathMin$3(x3, min$$1[0]);
    max$$1[0] = mathMax$3(x3, max$$1[0]);

    min$$1[1] = mathMin$3(y0, min$$1[1]);
    max$$1[1] = mathMax$3(y0, max$$1[1]);
    min$$1[1] = mathMin$3(y3, min$$1[1]);
    max$$1[1] = mathMax$3(y3, max$$1[1]);
}

/**
 * 从二阶贝塞尔曲线(p0, p1, p2)中计算出最小包围盒，写入`min`和`max`中
 * @memberOf module:zrender/core/bbox
 * @param {number} x0
 * @param {number} y0
 * @param {number} x1
 * @param {number} y1
 * @param {number} x2
 * @param {number} y2
 * @param {Array.<number>} min
 * @param {Array.<number>} max
 */
function fromQuadratic(x0, y0, x1, y1, x2, y2, min$$1, max$$1) {
    var quadraticExtremum$$1 = quadraticExtremum;
    var quadraticAt$$1 = quadraticAt;
    // Find extremities, where derivative in x dim or y dim is zero
    var tx =
        mathMax$3(
            mathMin$3(quadraticExtremum$$1(x0, x1, x2), 1), 0
        );
    var ty =
        mathMax$3(
            mathMin$3(quadraticExtremum$$1(y0, y1, y2), 1), 0
        );

    var x = quadraticAt$$1(x0, x1, x2, tx);
    var y = quadraticAt$$1(y0, y1, y2, ty);

    min$$1[0] = mathMin$3(x0, x2, x);
    min$$1[1] = mathMin$3(y0, y2, y);
    max$$1[0] = mathMax$3(x0, x2, x);
    max$$1[1] = mathMax$3(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
 */
function fromArc(
    x, y, rx, ry, startAngle, endAngle, anticlockwise, min$$1, max$$1
) {
    var vec2Min = min;
    var vec2Max = max;

    var diff = Math.abs(startAngle - endAngle);


    if (diff % PI2 < 1e-4 && diff > 1e-4) {
        // Is a circle
        min$$1[0] = x - rx;
        min$$1[1] = y - ry;
        max$$1[0] = x + rx;
        max$$1[1] = y + ry;
        return;
    }

    start[0] = mathCos$2(startAngle) * rx + x;
    start[1] = mathSin$2(startAngle) * ry + y;

    end[0] = mathCos$2(endAngle) * rx + x;
    end[1] = mathSin$2(endAngle) * ry + y;

    vec2Min(min$$1, start, end);
    vec2Max(max$$1, 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$2(angle) * rx + x;
            extremity[1] = mathSin$2(angle) * ry + y;

            vec2Min(min$$1, extremity, min$$1);
            vec2Max(max$$1, extremity, max$$1);
        }
    }
}

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

// TODO getTotalLength, getPointAtLength

/* global Float32Array */

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

// var CMD_MEM_SIZE = {
//     M: 3,
//     L: 3,
//     C: 7,
//     Q: 5,
//     A: 9,
//     R: 5,
//     Z: 1
// };

var min$1 = [];
var max$1 = [];
var min2 = [];
var max2 = [];
var mathMin$2 = Math.min;
var mathMax$2 = Math.max;
var mathCos$1 = Math.cos;
var mathSin$1 = Math.sin;
var mathSqrt$1 = Math.sqrt;
var mathAbs = Math.abs;

var hasTypedArray = typeof Float32Array !== 'undefined';

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

    this._saveData = !(notSaveData || false);

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

    this._ctx = null;
};

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

    constructor: PathProxy,

    _xi: 0,
    _yi: 0,

    _x0: 0,
    _y0: 0,
    // Unit x, Unit y. Provide for avoiding drawing that too short line segment
    _ux: 0,
    _uy: 0,

    _len: 0,

    _lineDash: null,

    _dashOffset: 0,

    _dashIdx: 0,

    _dashSum: 0,

    /**
     * @readOnly
     */
    setScale: function (sx, sy, segmentIgnoreThreshold) {
        // Compat. Previously there is no segmentIgnoreThreshold.
        segmentIgnoreThreshold = segmentIgnoreThreshold || 0;
        this._ux = mathAbs(segmentIgnoreThreshold / devicePixelRatio / sx) || 0;
        this._uy = mathAbs(segmentIgnoreThreshold / devicePixelRatio / sy) || 0;
    },

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

    /**
     * @param  {CanvasRenderingContext2D} ctx
     * @return {module:zrender/core/PathProxy}
     */
    beginPath: function (ctx) {

        this._ctx = ctx;

        ctx && ctx.beginPath();

        ctx && (this.dpr = ctx.dpr);

        // Reset
        if (this._saveData) {
            this._len = 0;
        }

        if (this._lineDash) {
            this._lineDash = null;

            this._dashOffset = 0;
        }

        return this;
    },

    /**
     * @param  {number} x
     * @param  {number} y
     * @return {module:zrender/core/PathProxy}
     */
    moveTo: function (x, y) {
        this.addData(CMD.M, x, y);
        this._ctx && this._ctx.moveTo(x, y);

        // x0, y0, xi, yi 是记录在 _dashedXXXXTo 方法中使用
        // xi, yi 记录当前点, x0, y0 在 closePath 的时候回到起始点。
        // 有可能在 beginPath 之后直接调用 lineTo，这时候 x0, y0 需要
        // 在 lineTo 方法中记录，这里先不考虑这种情况，dashed line 也只在 IE10- 中不支持
        this._x0 = x;
        this._y0 = y;

        this._xi = x;
        this._yi = y;

        return this;
    },

    /**
     * @param  {number} x
     * @param  {number} y
     * @return {module:zrender/core/PathProxy}
     */
    lineTo: function (x, y) {
        var exceedUnit = mathAbs(x - this._xi) > this._ux
            || mathAbs(y - this._yi) > this._uy
            // Force draw the first segment
            || this._len < 5;

        this.addData(CMD.L, x, y);

        if (this._ctx && exceedUnit) {
            this._needsDash() ? this._dashedLineTo(x, y)
                : this._ctx.lineTo(x, y);
        }
        if (exceedUnit) {
            this._xi = x;
            this._yi = y;
        }

        return this;
    },

    /**
     * @param  {number} x1
     * @param  {number} y1
     * @param  {number} x2
     * @param  {number} y2
     * @param  {number} x3
     * @param  {number} y3
     * @return {module:zrender/core/PathProxy}
     */
    bezierCurveTo: function (x1, y1, x2, y2, x3, y3) {
        this.addData(CMD.C, x1, y1, x2, y2, x3, y3);
        if (this._ctx) {
            this._needsDash() ? this._dashedBezierTo(x1, y1, x2, y2, x3, y3)
                : this._ctx.bezierCurveTo(x1, y1, x2, y2, x3, y3);
        }
        this._xi = x3;
        this._yi = y3;
        return this;
    },

    /**
     * @param  {number} x1
     * @param  {number} y1
     * @param  {number} x2
     * @param  {number} y2
     * @return {module:zrender/core/PathProxy}
     */
    quadraticCurveTo: function (x1, y1, x2, y2) {
        this.addData(CMD.Q, x1, y1, x2, y2);
        if (this._ctx) {
            this._needsDash() ? this._dashedQuadraticTo(x1, y1, x2, y2)
                : this._ctx.quadraticCurveTo(x1, y1, x2, y2);
        }
        this._xi = x2;
        this._yi = y2;
        return this;
    },

    /**
     * @param  {number} cx
     * @param  {number} cy
     * @param  {number} r
     * @param  {number} startAngle
     * @param  {number} endAngle
     * @param  {boolean} anticlockwise
     * @return {module:zrender/core/PathProxy}
     */
    arc: function (cx, cy, r, startAngle, endAngle, anticlockwise) {
        this.addData(
            CMD.A, cx, cy, r, r, startAngle, endAngle - startAngle, 0, anticlockwise ? 0 : 1
        );
        this._ctx && this._ctx.arc(cx, cy, r, startAngle, endAngle, anticlockwise);

        this._xi = mathCos$1(endAngle) * r + cx;
        this._yi = mathSin$1(endAngle) * r + cy;
        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$$1 = data.length;

        if (!(this.data && this.data.length === len$$1) && hasTypedArray) {
            this.data = new Float32Array(len$$1);
        }

        for (var i = 0; i < len$$1; i++) {
            this.data[i] = data[i];
        }

        this._len = len$$1;
    },

    /**
     * 添加子路径
     * @param {module:zrender/core/PathProxy|Array.<module:zrender/core/PathProxy>} path
     */
    appendPath: function (path) {
        if (!(path instanceof Array)) {
            path = [path];
        }
        var len$$1 = path.length;
        var appendSize = 0;
        var offset = this._len;
        for (var i = 0; i < len$$1; i++) {
            appendSize += path[i].len();
        }
        if (hasTypedArray && (this.data instanceof Float32Array)) {
            this.data = new Float32Array(offset + appendSize);
        }
        for (var i = 0; i < len$$1; i++) {
            var appendPathData = path[i].data;
            for (var k = 0; k < appendPathData.length; k++) {
                this.data[offset++] = appendPathData[k];
            }
        }
        this._len = offset;
    },

    /**
     * 填充 Path 数据。
     * 尽量复用而不申明新的数组。大部分图形重绘的指令数据长度都是不变的。
     */
    addData: function (cmd) {
        if (!this._saveData) {
            return;
        }

        var data = this.data;
        if (this._len + arguments.length > data.length) {
            // 因为之前的数组已经转换成静态的 Float32Array
            // 所以不够用时需要扩展一个新的动态数组
            this._expandData();
            data = this.data;
        }
        for (var i = 0; i < arguments.length; i++) {
            data[this._len++] = arguments[i];
        }

        this._prevCmd = cmd;
    },

    _expandData: function () {
        // Only if data is Float32Array
        if (!(this.data instanceof Array)) {
            var newData = [];
            for (var i = 0; i < this._len; i++) {
                newData[i] = this.data[i];
            }
            this.data = newData;
        }
    },

    /**
     * If needs js implemented dashed line
     * @return {boolean}
     * @private
     */
    _needsDash: function () {
        return this._lineDash;
    },

    _dashedLineTo: function (x1, y1) {
        var dashSum = this._dashSum;
        var offset = this._dashOffset;
        var lineDash = this._lineDash;
        var ctx = this._ctx;

        var x0 = this._xi;
        var y0 = this._yi;
        var dx = x1 - x0;
        var dy = y1 - y0;
        var dist$$1 = mathSqrt$1(dx * dx + dy * dy);
        var x = x0;
        var y = y0;
        var dash;
        var nDash = lineDash.length;
        var idx;
        dx /= dist$$1;
        dy /= dist$$1;

        if (offset < 0) {
            // Convert to positive offset
            offset = dashSum + offset;
        }
        offset %= dashSum;
        x -= offset * dx;
        y -= offset * dy;

        while ((dx > 0 && x <= x1) || (dx < 0 && x >= x1)
        || (dx === 0 && ((dy > 0 && y <= y1) || (dy < 0 && y >= y1)))) {
            idx = this._dashIdx;
            dash = lineDash[idx];
            x += dx * dash;
            y += dy * dash;
            this._dashIdx = (idx + 1) % nDash;
            // Skip positive offset
            if ((dx > 0 && x < x0) || (dx < 0 && x > x0) || (dy > 0 && y < y0) || (dy < 0 && y > y0)) {
                continue;
            }
            ctx[idx % 2 ? 'moveTo' : 'lineTo'](
                dx >= 0 ? mathMin$2(x, x1) : mathMax$2(x, x1),
                dy >= 0 ? mathMin$2(y, y1) : mathMax$2(y, y1)
            );
        }
        // Offset for next lineTo
        dx = x - x1;
        dy = y - y1;
        this._dashOffset = -mathSqrt$1(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$$1 = 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$$1(x0, x1, x2, x3, t + 0.1)
                - cubicAt$$1(x0, x1, x2, x3, t);
            dy = cubicAt$$1(y0, y1, y2, y3, t + 0.1)
                - cubicAt$$1(y0, y1, y2, y3, t);
            bezierLen += mathSqrt$1(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$$1(x0, x1, x2, x3, t);
            y = cubicAt$$1(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$1(dx * dx + dy * dy);
    },

    _dashedQuadraticTo: function (x1, y1, x2, y2) {
        // Convert quadratic to cubic using degree elevation
        var x3 = x2;
        var y3 = y2;
        x2 = (x2 + 2 * x1) / 3;
        y2 = (y2 + 2 * y1) / 3;
        x1 = (this._xi + 2 * x1) / 3;
        y1 = (this._yi + 2 * y1) / 3;

        this._dashedBezierTo(x1, y1, x2, y2, x3, y3);
    },

    /**
     * 转成静态的 Float32Array 减少堆内存占用
     * Convert dynamic array to static Float32Array
     */
    toStatic: function () {
        var data = this.data;
        if (data instanceof Array) {
            data.length = this._len;
            if (hasTypedArray) {
                this.data = new Float32Array(data);
            }
        }
    },

    /**
     * @return {module:zrender/core/BoundingRect}
     */
    getBoundingRect: function () {
        min$1[0] = min$1[1] = min2[0] = min2[1] = Number.MAX_VALUE;
        max$1[0] = max$1[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:
                    fromLine(xi, yi, data[i], data[i + 1], min2, max2);
                    xi = data[i++];
                    yi = data[i++];
                    break;
                case CMD.C:
                    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:
                    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 旋转
                    i += 1;
                    var anticlockwise = 1 - data[i++];

                    if (i === 1) {
                        // 直接使用 arc 命令
                        // 第一个命令起点还未定义
                        x0 = mathCos$1(startAngle) * rx + cx;
                        y0 = mathSin$1(startAngle) * ry + cy;
                    }

                    fromArc(
                        cx, cy, rx, ry, startAngle, endAngle,
                        anticlockwise, min2, max2
                    );

                    xi = mathCos$1(endAngle) * rx + cx;
                    yi = mathSin$1(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
                    fromLine(x0, y0, x0 + width, y0 + height, min2, max2);
                    break;
                case CMD.Z:
                    xi = x0;
                    yi = y0;
                    break;
            }

            // Union
            min(min$1, min$1, min2);
            max(max$1, max$1, max2);
        }

        // No data
        if (i === 0) {
            min$1[0] = min$1[1] = max$1[0] = max$1[1] = 0;
        }

        return new BoundingRect(
            min$1[0], min$1[1], max$1[0] - min$1[0], max$1[1] - min$1[1]
        );
    },

    /**
     * Rebuild path from current data
     * Rebuild path will not consider javascript implemented line dash.
     * @param {CanvasRenderingContext2D} ctx
     */
    rebuildPath: function (ctx) {
        var d = this.data;
        var x0;
        var y0;
        var xi;
        var yi;
        var x;
        var y;
        var ux = this._ux;
        var uy = this._uy;
        var len$$1 = this._len;
        for (var i = 0; i < len$$1;) {
            var cmd = d[i++];

            if (i === 1) {
                // 如果第一个命令是 L, C, Q
                // 则 previous point 同绘制命令的第一个 point
                //
                // 第一个命令为 Arc 的情况下会在后面特殊处理
                xi = d[i];
                yi = d[i + 1];

                x0 = xi;
                y0 = yi;
            }
            switch (cmd) {
                case CMD.M:
                    x0 = xi = d[i++];
                    y0 = yi = d[i++];
                    ctx.moveTo(xi, yi);
                    break;
                case CMD.L:
                    x = d[i++];
                    y = d[i++];
                    // Not draw too small seg between
                    if (mathAbs(x - xi) > ux || mathAbs(y - yi) > uy || i === len$$1 - 1) {
                        ctx.lineTo(x, y);
                        xi = x;
                        yi = y;
                    }
                    break;
                case CMD.C:
                    ctx.bezierCurveTo(
                        d[i++], d[i++], d[i++], d[i++], d[i++], d[i++]
                    );
                    xi = d[i - 2];
                    yi = d[i - 1];
                    break;
                case CMD.Q:
                    ctx.quadraticCurveTo(d[i++], d[i++], d[i++], d[i++]);
                    xi = d[i - 2];
                    yi = d[i - 1];
                    break;
                case CMD.A:
                    var cx = d[i++];
                    var cy = d[i++];
                    var rx = d[i++];
                    var ry = d[i++];
                    var theta = d[i++];
                    var dTheta = d[i++];
                    var psi = d[i++];
                    var fs = d[i++];
                    var r = (rx > ry) ? rx : ry;
                    var scaleX = (rx > ry) ? 1 : rx / ry;
                    var scaleY = (rx > ry) ? ry / rx : 1;
                    var isEllipse = Math.abs(rx - ry) > 1e-3;
                    var endAngle = theta + dTheta;
                    if (isEllipse) {
                        ctx.translate(cx, cy);
                        ctx.rotate(psi);
                        ctx.scale(scaleX, scaleY);
                        ctx.arc(0, 0, r, theta, endAngle, 1 - fs);
                        ctx.scale(1 / scaleX, 1 / scaleY);
                        ctx.rotate(-psi);
                        ctx.translate(-cx, -cy);
                    }
                    else {
                        ctx.arc(cx, cy, r, theta, endAngle, 1 - fs);
                    }

                    if (i === 1) {
                        // 直接使用 arc 命令
                        // 第一个命令起点还未定义
                        x0 = mathCos$1(theta) * rx + cx;
                        y0 = mathSin$1(theta) * ry + cy;
                    }
                    xi = mathCos$1(endAngle) * rx + cx;
                    yi = mathSin$1(endAngle) * ry + cy;
                    break;
                case CMD.R:
                    x0 = xi = d[i];
                    y0 = yi = d[i + 1];
                    ctx.rect(d[i++], d[i++], d[i++], d[i++]);
                    break;
                case CMD.Z:
                    ctx.closePath();
                    xi = x0;
                    yi = y0;
            }
        }
    }
};

PathProxy.CMD = CMD;

/**
 * 线段包含判断
 * @param  {number}  x0
 * @param  {number}  y0
 * @param  {number}  x1
 * @param  {number}  y1
 * @param  {number}  lineWidth
 * @param  {number}  x
 * @param  {number}  y
 * @return {boolean}
 */
function containStroke$1(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;
}

/**
 * 三次贝塞尔曲线描边包含判断
 * @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}
 */
function containStroke$2(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 = cubicProjectPoint(
        x0, y0, x1, y1, x2, y2, x3, y3,
        x, y, null
    );
    return d <= _l / 2;
}

/**
 * 二次贝塞尔曲线描边包含判断
 * @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}
 */
function containStroke$3(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 = quadraticProjectPoint(
        x0, y0, x1, y1, x2, y2,
        x, y, null
    );
    return d <= _l / 2;
}

var PI2$3 = Math.PI * 2;

function normalizeRadian(angle) {
    angle %= PI2$3;
    if (angle < 0) {
        angle += PI2$3;
    }
    return angle;
}

var PI2$2 = Math.PI * 2;

/**
 * 圆弧描边包含判断
 * @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}
 */
function containStroke$4(
    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$2 < 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$2;
    }

    var angle = Math.atan2(y, x);
    if (angle < 0) {
        angle += PI2$2;
    }
    return (angle >= startAngle && angle <= endAngle)
        || (angle + PI2$2 >= startAngle && angle + PI2$2 <= endAngle);
}

function windingLine(x0, y0, x1, y1, x, y) {
    if ((y > y0 && y > y1) || (y < y0 && y < y1)) {
        return 0;
    }
    // Ignore horizontal line
    if (y1 === y0) {
        return 0;
    }
    var dir = y1 < y0 ? 1 : -1;
    var t = (y - y0) / (y1 - y0);

    // Avoid winding error when intersection point is the connect point of two line of polygon
    if (t === 1 || t === 0) {
        dir = y1 < y0 ? 0.5 : -0.5;
    }

    var x_ = t * (x1 - x0) + x0;

    // If (x, y) on the line, considered as "contain".
    return x_ === x ? Infinity : x_ > x ? dir : 0;
}

var CMD$1 = PathProxy.CMD;
var PI2$1 = Math.PI * 2;

var EPSILON$2 = 1e-4;

function isAroundEqual(a, b) {
    return Math.abs(a - b) < EPSILON$2;
}

// 临时数组
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 = cubicRootAt(y0, y1, y2, y3, y, roots);
    if (nRoots === 0) {
        return 0;
    }
    else {
        var w = 0;
        var nExtrema = -1;
        var y0_;
        var y1_;
        for (var i = 0; i < nRoots; i++) {
            var t = roots[i];

            // Avoid winding error when intersection point is the connect point of two line of polygon
            var unit = (t === 0 || t === 1) ? 0.5 : 1;

            var x_ = cubicAt(x0, x1, x2, x3, t);
            if (x_ < x) { // Quick reject
                continue;
            }
            if (nExtrema < 0) {
                nExtrema = cubicExtrema(y0, y1, y2, y3, extrema);
                if (extrema[1] < extrema[0] && nExtrema > 1) {
                    swapExtrema();
                }
                y0_ = cubicAt(y0, y1, y2, y3, extrema[0]);
                if (nExtrema > 1) {
                    y1_ = cubicAt(y0, y1, y2, y3, extrema[1]);
                }
            }
            if (nExtrema === 2) {
                // 分成三段单调函数
                if (t < extrema[0]) {
                    w += y0_ < y0 ? unit : -unit;
                }
                else if (t < extrema[1]) {
                    w += y1_ < y0_ ? unit : -unit;
                }
                else {
                    w += y3 < y1_ ? unit : -unit;
                }
            }
            else {
                // 分成两段单调函数
                if (t < extrema[0]) {
                    w += y0_ < y0 ? unit : -unit;
                }
                else {
                    w += y3 < y0_ ? unit : -unit;
                }
            }
        }
        return w;
    }
}

function windingQuadratic(x0, y0, x1, y1, x2, y2, x, y) {
    // Quick reject
    if (
        (y > y0 && y > y1 && y > y2)
        || (y < y0 && y < y1 && y < y2)
    ) {
        return 0;
    }
    var nRoots = quadraticRootAt(y0, y1, y2, y, roots);
    if (nRoots === 0) {
        return 0;
    }
    else {
        var t = quadraticExtremum(y0, y1, y2);
        if (t >= 0 && t <= 1) {
            var w = 0;
            var y_ = quadraticAt(y0, y1, y2, t);
            for (var i = 0; i < nRoots; i++) {
                // Remove one endpoint.
                var unit = (roots[i] === 0 || roots[i] === 1) ? 0.5 : 1;

                var x_ = quadraticAt(x0, x1, x2, roots[i]);
                if (x_ < x) {   // Quick reject
                    continue;
                }
                if (roots[i] < t) {
                    w += y_ < y0 ? unit : -unit;
                }
                else {
                    w += y2 < y_ ? unit : -unit;
                }
            }
            return w;
        }
        else {
            // Remove one endpoint.
            var unit = (roots[0] === 0 || roots[0] === 1) ? 0.5 : 1;

            var x_ = quadraticAt(x0, x1, x2, roots[0]);
            if (x_ < x) {   // Quick reject
                return 0;
            }
            return y2 < y0 ? unit : -unit;
        }
    }
}

// TODO
// Arc 旋转
function windingArc(
    cx, cy, r, startAngle, endAngle, anticlockwise, x, y
) {
    y -= cy;
    if (y > r || y < -r) {
        return 0;
    }
    var tmp = Math.sqrt(r * r - y * y);
    roots[0] = -tmp;
    roots[1] = tmp;

    var diff = Math.abs(startAngle - endAngle);
    if (diff < 1e-4) {
        return 0;
    }
    if (diff % PI2$1 < 1e-4) {
        // Is a circle
        startAngle = 0;
        endAngle = PI2$1;
        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$1;
    }

    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$1 + angle;
            }
            if (
                (angle >= startAngle && angle <= endAngle)
                || (angle + PI2$1 >= startAngle && angle + PI2$1 <= 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$1.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$1.M:
                // moveTo 命令重新创建一个新的 subpath, 并且更新新的起点
                // 在 closePath 的时候使用
                x0 = data[i++];
                y0 = data[i++];
                xi = x0;
                yi = y0;
                break;
            case CMD$1.L:
                if (isStroke) {
                    if (containStroke$1(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$1.C:
                if (isStroke) {
                    if (containStroke$2(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$1.Q:
                if (isStroke) {
                    if (containStroke$3(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$1.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 旋转
                i += 1;
                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 (containStroke$4(
                        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$1.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$1(x0, y0, x1, y0, lineWidth, x, y)
                        || containStroke$1(x1, y0, x1, y1, lineWidth, x, y)
                        || containStroke$1(x1, y1, x0, y1, lineWidth, x, y)
                        || containStroke$1(x0, y1, x0, y0, lineWidth, x, y)
                    ) {
                        return true;
                    }
                }
                else {
                    // FIXME Clockwise ?
                    w += windingLine(x1, y0, x1, y1, x, y);
                    w += windingLine(x0, y1, x0, y0, x, y);
                }
                break;
            case CMD$1.Z:
                if (isStroke) {
                    if (containStroke$1(
                        xi, yi, x0, y0, lineWidth, x, y
                    )) {
                        return true;
                    }
                }
                else {
                    // Close a subpath
                    w += windingLine(xi, yi, x0, y0, x, y);
                    // 如果被任何一个 subpath 包含
                    // FIXME subpaths may overlap
                    // if (w !== 0) {
                    //     return true;
                    // }
                }
                xi = x0;
                yi = y0;
                break;
        }
    }
    if (!isStroke && !isAroundEqual(yi, y0)) {
        w += windingLine(xi, yi, x0, y0, x, y) || 0;
    }
    return w !== 0;
}

function contain(pathData, x, y) {
    return containPath(pathData, 0, false, x, y);
}

function containStroke(pathData, lineWidth, x, y) {
    return containPath(pathData, lineWidth, true, x, y);
}

var getCanvasPattern = Pattern.prototype.getCanvasPattern;

var abs = Math.abs;

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

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

Path.prototype = {

    constructor: Path,

    type: 'path',

    __dirtyPath: true,

    strokeContainThreshold: 5,

    // This item default to be false. But in map series in echarts,
    // in order to improve performance, it should be set to true,
    // so the shorty segment won't draw.
    segmentIgnoreThreshold: 0,

    /**
     * See `module:zrender/src/graphic/helper/subPixelOptimize`.
     * @type {boolean}
     */
    subPixelOptimize: false,

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

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

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

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

        var ctxLineDash = !!ctx.setLineDash;

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

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

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

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

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

        if (hasFill) {
            if (style.fillOpacity != null) {
                var originalGlobalAlpha = ctx.globalAlpha;
                ctx.globalAlpha = style.fillOpacity * style.opacity;
                path.fill(ctx);
                ctx.globalAlpha = originalGlobalAlpha;
            }
            else {
                path.fill(ctx);
            }
        }

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

        if (hasStroke) {
            if (style.strokeOpacity != null) {
                var originalGlobalAlpha = ctx.globalAlpha;
                ctx.globalAlpha = style.strokeOpacity * style.opacity;
                path.stroke(ctx);
                ctx.globalAlpha = originalGlobalAlpha;
            }
            else {
                path.stroke(ctx);
            }
        }

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

        // Draw rect text
        if (style.text != null) {
            // Only restore transform when needs draw text.
            this.restoreTransform(ctx);
            this.drawRectText(ctx, this.getBoundingRect());
        }
    },

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

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

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

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

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

            // Return rect with stroke
            return rectWithStroke;
        }

        return rect;
    },

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

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

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

        this.__dirty = this.__dirtyText = true;

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

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

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

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

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

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

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

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

        // Extend default shape
        var defaultShape = defaults$$1.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$$1.init && defaults$$1.init.call(this, opts);
    };

    inherits(Sub, Path);

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

    return Sub;
};

inherits(Path, Displayable);

var CMD$2 = PathProxy.CMD;

var points = [[], [], []];
var mathSqrt$3 = Math.sqrt;
var mathAtan2 = Math.atan2;

var transformPath = function (path, m) {
    var data = path.data;
    var cmd;
    var nPoint;
    var i;
    var j;
    var k;
    var p;

    var M = CMD$2.M;
    var C = CMD$2.C;
    var L = CMD$2.L;
    var R = CMD$2.R;
    var A = CMD$2.A;
    var Q = CMD$2.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$3(m[0] * m[0] + m[1] * m[1]);
                var sy = mathSqrt$3(m[2] * m[2] + m[3] * m[3]);
                var angle = mathAtan2(-m[1] / sy, m[0] / sx);
                // cx
                data[i] *= sx;
                data[i++] += x;
                // cy
                data[i] *= sy;
                data[i++] += y;
                // Scale rx and ry
                // FIXME Assume psi is 0 here
                data[i++] *= sx;
                data[i++] *= sy;

                // Start angle
                data[i++] += angle;
                // end angle
                data[i++] += angle;
                // FIXME psi
                i += 2;
                j = i;
                break;
            case R:
                // x0, y0
                p[0] = data[i++];
                p[1] = data[i++];
                applyTransform(p, p, m);
                data[j++] = p[0];
                data[j++] = p[1];
                // x1, y1
                p[0] += data[i++];
                p[1] += data[i++];
                applyTransform(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++];

            applyTransform(p, p, m);
            // Write back
            data[j++] = p[0];
            data[j++] = p[1];
        }
    }
};

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


var commandReg = /([mlvhzcqtsa])([^mlvhzcqtsa]*)/ig;
// Consider case:
// (1) delimiter can be comma or space, where continuous commas
// or spaces should be seen as one comma.
// (2) value can be like:
// '2e-4', 'l.5.9' (ignore 0), 'M-10-10', 'l-2.43e-1,34.9983',
// 'l-.5E1,54', '121-23-44-11' (no delimiter)
var numberReg = /-?([0-9]*\.)?[0-9]+([eE]-?[0-9]+)?/g;
// var valueSplitReg = /[\s,]+/;

function createPathProxyFromString(data) {
    if (!data) {
        return new PathProxy();
    }

    // var data = 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]);
    // }

    // data = data.replace(/-/g, ',-');

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

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

    // commandReg.lastIndex = 0;
    // var cmdResult;
    // while ((cmdResult = commandReg.exec(data)) != null) {
    //     var cmdStr = cmdResult[1];
    //     var cmdContent = cmdResult[2];

    var cmdList = data.match(commandReg);
    for (var l = 0; l < cmdList.length; l++) {
        var cmdText = cmdList[l];
        var cmdStr = cmdText.charAt(0);

        var cmd;

        // String#split is faster a little bit than String#replace or RegExp#exec.
        // var p = cmdContent.split(valueSplitReg);
        // var pLen = 0;
        // for (var i = 0; i < p.length; i++) {
        //     // '' and other invalid str => NaN
        //     var val = parseFloat(p[i]);
        //     !isNaN(val) && (p[pLen++] = val);
        // }

        var p = cmdText.match(numberReg) || [];
        var pLen = p.length;
        for (var i = 0; i < pLen; i++) {
            p[i] = parseFloat(p[i]);
        }

        var off = 0;
        while (off < pLen) {
            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 (cmdStr) {
                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);
                    subpathX = cpx;
                    subpathY = cpy;
                    cmdStr = 'l';
                    break;
                case 'M':
                    cpx = p[off++];
                    cpy = p[off++];
                    cmd = CMD.M;
                    path.addData(cmd, cpx, cpy);
                    subpathX = cpx;
                    subpathY = cpy;
                    cmdStr = '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 (cmdStr === 'z' || cmdStr === 'Z') {
            cmd = CMD.Z;
            path.addData(cmd);
            // z may be in the middle of the path.
            cpx = subpathX;
            cpy = subpathY;
        }

        prevCmd = cmd;
    }

    path.toStatic();

    return path;
}

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

    opts.applyTransform = function (m) {
        transformPath(pathProxy, m);
        this.dirty(true);
    };

    return opts;
}

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

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

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

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

    return pathBundle;
}

/**
 * @alias zrender/graphic/Text
 * @extends module:zrender/graphic/Displayable
 * @constructor
 * @param {Object} opts
 */
var Text = function (opts) { // jshint ignore:line
    Displayable.call(this, opts);
};

Text.prototype = {

    constructor: Text,

    type: 'text',

    brush: function (ctx, prevEl) {
        var style = this.style;

        // Optimize, avoid normalize every time.
        this.__dirty && normalizeTextStyle(style, true);

        // Use props with prefix 'text'.
        style.fill = style.stroke = style.shadowBlur = style.shadowColor =
            style.shadowOffsetX = style.shadowOffsetY = null;

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

        // Do not apply style.bind in Text node. Because the real bind job
        // is in textHelper.renderText, and performance of text render should
        // be considered.
        // style.bind(ctx, this, prevEl);

        if (!needDrawText(text, style)) {
            // The current el.style is not applied
            // and should not be used as cache.
            ctx.__attrCachedBy = ContextCachedBy.NONE;
            return;
        }

        this.setTransform(ctx);

        renderText(this, ctx, text, style, null, prevEl);

        this.restoreTransform(ctx);
    },

    getBoundingRect: function () {
        var style = this.style;

        // Optimize, avoid normalize every time.
        this.__dirty && normalizeTextStyle(style, true);

        if (!this._rect) {
            var text = style.text;
            text != null ? (text += '') : (text = '');

            var rect = getBoundingRect(
                style.text + '',
                style.font,
                style.textAlign,
                style.textVerticalAlign,
                style.textPadding,
                style.textLineHeight,
                style.rich
            );

            rect.x += style.x || 0;
            rect.y += style.y || 0;

            if (getStroke(style.textStroke, style.textStrokeWidth)) {
                var w = style.textStrokeWidth;
                rect.x -= w / 2;
                rect.y -= w / 2;
                rect.width += w;
                rect.height += w;
            }

            this._rect = rect;
        }

        return this._rect;
    }
};

inherits(Text, Displayable);

/**
 * 圆形
 * @module zrender/shape/Circle
 */

var Circle = Path.extend({

    type: 'circle',

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


    buildPath: function (ctx, shape, inBundle) {
        // Better stroking in ShapeBundle
        // Always do it may have performence issue ( fill may be 2x more cost)
        if (inBundle) {
            ctx.moveTo(shape.cx + shape.r, shape.cy);
        }
        // else {
        //     if (ctx.allocate && !ctx.data.length) {
        //         ctx.allocate(ctx.CMD_MEM_SIZE.A);
        //     }
        // }
        // Better stroking in ShapeBundle
        // ctx.moveTo(shape.cx + shape.r, shape.cy);
        ctx.arc(shape.cx, shape.cy, shape.r, 0, Math.PI * 2, true);
    }
});

// Fix weird bug in some version of IE11 (like 11.0.9600.178**),
// where exception "unexpected call to method or property access"
// might be thrown when calling ctx.fill or ctx.stroke after a path
// whose area size is zero is drawn and ctx.clip() is called and
// shadowBlur is set. See #4572, #3112, #5777.
// (e.g.,
//  ctx.moveTo(10, 10);
//  ctx.lineTo(20, 10);
//  ctx.closePath();
//  ctx.clip();
//  ctx.shadowBlur = 10;
//  ...
//  ctx.fill();
// )

var shadowTemp = [
    ['shadowBlur', 0],
    ['shadowColor', '#000'],
    ['shadowOffsetX', 0],
    ['shadowOffsetY', 0]
];

var fixClipWithShadow = function (orignalBrush) {

    // version string can be: '11.0'
    return (env$1.browser.ie && env$1.browser.version >= 11)

        ? function () {
            var clipPaths = this.__clipPaths;
            var style = this.style;
            var modified;

            if (clipPaths) {
                for (var i = 0; i < clipPaths.length; i++) {
                    var clipPath = clipPaths[i];
                    var shape = clipPath && clipPath.shape;
                    var type = clipPath && clipPath.type;

                    if (shape && (
                        (type === 'sector' && shape.startAngle === shape.endAngle)
                        || (type === 'rect' && (!shape.width || !shape.height))
                    )) {
                        for (var j = 0; j < shadowTemp.length; j++) {
                            // It is save to put shadowTemp static, because shadowTemp
                            // will be all modified each item brush called.
                            shadowTemp[j][2] = style[shadowTemp[j][0]];
                            style[shadowTemp[j][0]] = shadowTemp[j][1];
                        }
                        modified = true;
                        break;
                    }
                }
            }

            orignalBrush.apply(this, arguments);

            if (modified) {
                for (var j = 0; j < shadowTemp.length; j++) {
                    style[shadowTemp[j][0]] = shadowTemp[j][2];
                }
            }
        }

        : orignalBrush;
};

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

var Sector = Path.extend({

    type: 'sector',

    shape: {

        cx: 0,

        cy: 0,

        r0: 0,

        r: 0,

        startAngle: 0,

        endAngle: Math.PI * 2,

        clockwise: true
    },

    brush: fixClipWithShadow(Path.prototype.brush),

    buildPath: function (ctx, shape) {

        var x = shape.cx;
        var y = shape.cy;
        var r0 = Math.max(shape.r0 || 0, 0);
        var r = Math.max(shape.r, 0);
        var startAngle = shape.startAngle;
        var endAngle = shape.endAngle;
        var clockwise = shape.clockwise;

        var unitX = Math.cos(startAngle);
        var unitY = Math.sin(startAngle);

        ctx.moveTo(unitX * r0 + x, unitY * r0 + y);

        ctx.lineTo(unitX * r + x, unitY * r + y);

        ctx.arc(x, y, r, startAngle, endAngle, !clockwise);

        ctx.lineTo(
            Math.cos(endAngle) * r0 + x,
            Math.sin(endAngle) * r0 + y
        );

        if (r0 !== 0) {
            ctx.arc(x, y, r0, endAngle, startAngle, clockwise);
        }

        ctx.closePath();
    }
});

/**
 * 圆环
 * @module zrender/graphic/shape/Ring
 */

var Ring = Path.extend({

    type: 'ring',

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

    buildPath: function (ctx, shape) {
        var x = shape.cx;
        var y = shape.cy;
        var PI2 = Math.PI * 2;
        ctx.moveTo(x + shape.r, y);
        ctx.arc(x, y, shape.r, 0, PI2, false);
        ctx.moveTo(x + shape.r0, y);
        ctx.arc(x, y, shape.r0, 0, PI2, true);
    }
});

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

/**
 * @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}
 */
var smoothSpline = function (points, isLoop) {
    var len$$1 = points.length;
    var ret = [];

    var distance$$1 = 0;
    for (var i = 1; i < len$$1; i++) {
        distance$$1 += distance(points[i - 1], points[i]);
    }

    var segs = distance$$1 / 2;
    segs = segs < len$$1 ? len$$1 : segs;
    for (var i = 0; i < segs; i++) {
        var pos = i / (segs - 1) * (isLoop ? len$$1 : len$$1 - 1);
        var idx = Math.floor(pos);

        var w = pos - idx;

        var p0;
        var p1 = points[idx % len$$1];
        var p2;
        var p3;
        if (!isLoop) {
            p0 = points[idx === 0 ? idx : idx - 1];
            p2 = points[idx > len$$1 - 2 ? len$$1 - 1 : idx + 1];
            p3 = points[idx > len$$1 - 3 ? len$$1 - 1 : idx + 2];
        }
        else {
            p0 = points[(idx - 1 + len$$1) % len$$1];
            p2 = points[(idx + 1) % len$$1];
            p3 = points[(idx + 2) % len$$1];
        }

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

/**
 * 贝塞尔平滑曲线
 * @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} 计算出来的控制点数组
 */
var smoothBezier = function (points, smooth, isLoop, constraint) {
    var cps = [];

    var v = [];
    var v1 = [];
    var v2 = [];
    var prevPoint;
    var nextPoint;

    var min$$1;
    var max$$1;
    if (constraint) {
        min$$1 = [Infinity, Infinity];
        max$$1 = [-Infinity, -Infinity];
        for (var i = 0, len$$1 = points.length; i < len$$1; i++) {
            min(min$$1, min$$1, points[i]);
            max(max$$1, max$$1, points[i]);
        }
        // 与指定的包围盒做并集
        min(min$$1, min$$1, constraint[0]);
        max(max$$1, max$$1, constraint[1]);
    }

    for (var i = 0, len$$1 = points.length; i < len$$1; i++) {
        var point = points[i];

        if (isLoop) {
            prevPoint = points[i ? i - 1 : len$$1 - 1];
            nextPoint = points[(i + 1) % len$$1];
        }
        else {
            if (i === 0 || i === len$$1 - 1) {
                cps.push(clone$1(points[i]));
                continue;
            }
            else {
                prevPoint = points[i - 1];
                nextPoint = points[i + 1];
            }
        }

        sub(v, nextPoint, prevPoint);

        // use degree to scale the handle length
        scale(v, v, smooth);

        var d0 = distance(point, prevPoint);
        var d1 = distance(point, nextPoint);
        var sum = d0 + d1;
        if (sum !== 0) {
            d0 /= sum;
            d1 /= sum;
        }

        scale(v1, v, -d0);
        scale(v2, v, d1);
        var cp0 = add([], point, v1);
        var cp1 = add([], point, v2);
        if (constraint) {
            max(cp0, cp0, min$$1);
            min(cp0, cp0, max$$1);
            max(cp1, cp1, min$$1);
            min(cp1, cp1, max$$1);
        }
        cps.push(cp0);
        cps.push(cp1);
    }

    if (isLoop) {
        cps.push(cps.shift());
    }

    return cps;
};

function buildPath$1(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
 */

var Polygon = Path.extend({

    type: 'polygon',

    shape: {
        points: null,

        smooth: false,

        smoothConstraint: null
    },

    buildPath: function (ctx, shape) {
        buildPath$1(ctx, shape, true);
    }
});

/**
 * @module zrender/graphic/shape/Polyline
 */

var Polyline = Path.extend({

    type: 'polyline',

    shape: {
        points: null,

        smooth: false,

        smoothConstraint: null
    },

    style: {
        stroke: '#000',

        fill: null
    },

    buildPath: function (ctx, shape) {
        buildPath$1(ctx, shape, false);
    }
});

/**
 * Sub-pixel optimize for canvas rendering, prevent from blur
 * when rendering a thin vertical/horizontal line.
 */

var round = Math.round;

/**
 * Sub pixel optimize line for canvas
 *
 * @param {Object} outputShape The modification will be performed on `outputShape`.
 *                 `outputShape` and `inputShape` can be the same object.
 *                 `outputShape` object can be used repeatly, because all of
 *                 the `x1`, `x2`, `y1`, `y2` will be assigned in this method.
 * @param {Object} [inputShape]
 * @param {number} [inputShape.x1]
 * @param {number} [inputShape.y1]
 * @param {number} [inputShape.x2]
 * @param {number} [inputShape.y2]
 * @param {Object} [style]
 * @param {number} [style.lineWidth] If `null`/`undefined`/`0`, do not optimize.
 */
function subPixelOptimizeLine$1(outputShape, inputShape, style) {
    if (!inputShape) {
        return;
    }

    var x1 = inputShape.x1;
    var x2 = inputShape.x2;
    var y1 = inputShape.y1;
    var y2 = inputShape.y2;

    outputShape.x1 = x1;
    outputShape.x2 = x2;
    outputShape.y1 = y1;
    outputShape.y2 = y2;

    var lineWidth = style && style.lineWidth;
    if (!lineWidth) {
        return;
    }

    if (round(x1 * 2) === round(x2 * 2)) {
        outputShape.x1 = outputShape.x2 = subPixelOptimize$1(x1, lineWidth, true);
    }
    if (round(y1 * 2) === round(y2 * 2)) {
        outputShape.y1 = outputShape.y2 = subPixelOptimize$1(y1, lineWidth, true);
    }
}

/**
 * Sub pixel optimize rect for canvas
 *
 * @param {Object} outputShape The modification will be performed on `outputShape`.
 *                 `outputShape` and `inputShape` can be the same object.
 *                 `outputShape` object can be used repeatly, because all of
 *                 the `x`, `y`, `width`, `height` will be assigned in this method.
 * @param {Object} [inputShape]
 * @param {number} [inputShape.x]
 * @param {number} [inputShape.y]
 * @param {number} [inputShape.width]
 * @param {number} [inputShape.height]
 * @param {Object} [style]
 * @param {number} [style.lineWidth] If `null`/`undefined`/`0`, do not optimize.
 */
function subPixelOptimizeRect$1(outputShape, inputShape, style) {
    if (!inputShape) {
        return;
    }

    var originX = inputShape.x;
    var originY = inputShape.y;
    var originWidth = inputShape.width;
    var originHeight = inputShape.height;

    outputShape.x = originX;
    outputShape.y = originY;
    outputShape.width = originWidth;
    outputShape.height = originHeight;

    var lineWidth = style && style.lineWidth;
    if (!lineWidth) {
        return;
    }

    outputShape.x = subPixelOptimize$1(originX, lineWidth, true);
    outputShape.y = subPixelOptimize$1(originY, lineWidth, true);
    outputShape.width = Math.max(
        subPixelOptimize$1(originX + originWidth, lineWidth, false) - outputShape.x,
        originWidth === 0 ? 0 : 1
    );
    outputShape.height = Math.max(
        subPixelOptimize$1(originY + originHeight, lineWidth, false) - outputShape.y,
        originHeight === 0 ? 0 : 1
    );
}

/**
 * Sub pixel optimize for canvas
 *
 * @param {number} position Coordinate, such as x, y
 * @param {number} lineWidth If `null`/`undefined`/`0`, do not optimize.
 * @param {boolean=} positiveOrNegative Default false (negative).
 * @return {number} Optimized position.
 */
function subPixelOptimize$1(position, lineWidth, positiveOrNegative) {
    if (!lineWidth) {
        return position;
    }
    // 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;
}

/**
 * 矩形
 * @module zrender/graphic/shape/Rect
 */

// Avoid create repeatly.
var subPixelOptimizeOutputShape = {};

var Rect = 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;
        var y;
        var width;
        var height;

        if (this.subPixelOptimize) {
            subPixelOptimizeRect$1(subPixelOptimizeOutputShape, shape, this.style);
            x = subPixelOptimizeOutputShape.x;
            y = subPixelOptimizeOutputShape.y;
            width = subPixelOptimizeOutputShape.width;
            height = subPixelOptimizeOutputShape.height;
            subPixelOptimizeOutputShape.r = shape.r;
            shape = subPixelOptimizeOutputShape;
        }
        else {
            x = shape.x;
            y = shape.y;
            width = shape.width;
            height = shape.height;
        }

        if (!shape.r) {
            ctx.rect(x, y, width, height);
        }
        else {
            buildPath(ctx, shape);
        }
        ctx.closePath();
        return;
    }
});

/**
 * 直线
 * @module zrender/graphic/shape/Line
 */

// Avoid create repeatly.
var subPixelOptimizeOutputShape$1 = {};

var Line = 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;
        var y1;
        var x2;
        var y2;

        if (this.subPixelOptimize) {
            subPixelOptimizeLine$1(subPixelOptimizeOutputShape$1, shape, this.style);
            x1 = subPixelOptimizeOutputShape$1.x1;
            y1 = subPixelOptimizeOutputShape$1.y1;
            x2 = subPixelOptimizeOutputShape$1.x2;
            y2 = subPixelOptimizeOutputShape$1.y2;
        }
        else {
            x1 = shape.x1;
            y1 = shape.y1;
            x2 = shape.x2;
            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
 */

var out = [];

function someVectorAt(shape, t, isTangent) {
    var cpx2 = shape.cpx2;
    var cpy2 = shape.cpy2;
    if (cpx2 === null || cpy2 === null) {
        return [
            (isTangent ? cubicDerivativeAt : cubicAt)(shape.x1, shape.cpx1, shape.cpx2, shape.x2, t),
            (isTangent ? cubicDerivativeAt : cubicAt)(shape.y1, shape.cpy1, shape.cpy2, shape.y2, t)
        ];
    }
    else {
        return [
            (isTangent ? quadraticDerivativeAt : quadraticAt)(shape.x1, shape.cpx1, shape.x2, t),
            (isTangent ? quadraticDerivativeAt : quadraticAt)(shape.y1, shape.cpy1, shape.y2, t)
        ];
    }
}

var BezierCurve = 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} t
     * @return {Array.<number>}
     */
    pointAt: function (t) {
        return someVectorAt(this.shape, t, false);
    },

    /**
     * Get tangent at percent
     * @param  {number} t
     * @return {Array.<number>}
     */
    tangentAt: function (t) {
        var p = someVectorAt(this.shape, t, true);
        return normalize(p, p);
    }
});

/**
 * 圆弧
 * @module zrender/graphic/shape/Arc
 */

var Arc = 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 = Math.max(shape.r, 0);
        var startAngle = shape.startAngle;
        var endAngle = shape.endAngle;
        var clockwise = shape.clockwise;

        var unitX = Math.cos(startAngle);
        var unitY = Math.sin(startAngle);

        ctx.moveTo(unitX * r + x, unitY * r + y);
        ctx.arc(x, y, r, startAngle, endAngle, !clockwise);
    }
});

// CompoundPath to improve performance

var CompoundPath = Path.extend({

    type: 'compound',

    shape: {

        paths: null
    },

    _updatePathDirty: function () {
        var dirtyPath = this.__dirtyPath;
        var paths = this.shape.paths;
        for (var i = 0; i < paths.length; i++) {
            // Mark as dirty if any subpath is dirty
            dirtyPath = dirtyPath || paths[i].__dirtyPath;
        }
        this.__dirtyPath = dirtyPath;
        this.__dirty = this.__dirty || dirtyPath;
    },

    beforeBrush: function () {
        this._updatePathDirty();
        var paths = this.shape.paths || [];
        var scale = this.getGlobalScale();
        // Update path scale
        for (var i = 0; i < paths.length; i++) {
            if (!paths[i].path) {
                paths[i].createPathProxy();
            }
            paths[i].path.setScale(scale[0], scale[1], paths[i].segmentIgnoreThreshold);
        }
    },

    buildPath: function (ctx, shape) {
        var paths = shape.paths || [];
        for (var i = 0; i < paths.length; i++) {
            paths[i].buildPath(ctx, paths[i].shape, true);
        }
    },

    afterBrush: function () {
        var paths = this.shape.paths || [];
        for (var i = 0; i < paths.length; i++) {
            paths[i].__dirtyPath = false;
        }
    },

    getBoundingRect: function () {
        this._updatePathDirty();
        return Path.prototype.getBoundingRect.call(this);
    }
});

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

};

/**
 * x, y, x2, y2 are all percent from 0 to 1
 * @param {number} [x=0]
 * @param {number} [y=0]
 * @param {number} [x2=1]
 * @param {number} [y2=0]
 * @param {Array.<Object>} colorStops
 * @param {boolean} [globalCoord=false]
 */
var LinearGradient = function (x, y, x2, y2, colorStops, globalCoord) {
    // Should do nothing more in this constructor. Because gradient can be
    // declard by `color: {type: 'linear', colorStops: ...}`, where
    // this constructor will not be called.

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

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

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

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

    // Can be cloned
    this.type = 'linear';

    // If use global coord
    this.global = globalCoord || false;

    Gradient.call(this, colorStops);
};

LinearGradient.prototype = {

    constructor: LinearGradient
};

inherits(LinearGradient, 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]
 * @param {boolean} [globalCoord=false]
 */
var RadialGradient = function (x, y, r, colorStops, globalCoord) {
    // Should do nothing more in this constructor. Because gradient can be
    // declard by `color: {type: 'radial', colorStops: ...}`, where
    // this constructor will not be called.

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

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

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

    // Can be cloned
    this.type = 'radial';

    // If use global coord
    this.global = globalCoord || false;

    Gradient.call(this, colorStops);
};

RadialGradient.prototype = {

    constructor: RadialGradient
};

inherits(RadialGradient, Gradient);

/**
 * Displayable for incremental rendering. It will be rendered in a separate layer
 * IncrementalDisplay have two main methods. `clearDisplayables` and `addDisplayables`
 * addDisplayables will render the added displayables incremetally.
 *
 * It use a not clearFlag to tell the painter don't clear the layer if it's the first element.
 */
// TODO Style override ?
function IncrementalDisplayble(opts) {

    Displayable.call(this, opts);

    this._displayables = [];

    this._temporaryDisplayables = [];

    this._cursor = 0;

    this.notClear = true;
}

IncrementalDisplayble.prototype.incremental = true;

IncrementalDisplayble.prototype.clearDisplaybles = function () {
    this._displayables = [];
    this._temporaryDisplayables = [];
    this._cursor = 0;
    this.dirty();

    this.notClear = false;
};

IncrementalDisplayble.prototype.addDisplayable = function (displayable, notPersistent) {
    if (notPersistent) {
        this._temporaryDisplayables.push(displayable);
    }
    else {
        this._displayables.push(displayable);
    }
    this.dirty();
};

IncrementalDisplayble.prototype.addDisplayables = function (displayables, notPersistent) {
    notPersistent = notPersistent || false;
    for (var i = 0; i < displayables.length; i++) {
        this.addDisplayable(displayables[i], notPersistent);
    }
};

IncrementalDisplayble.prototype.eachPendingDisplayable = function (cb) {
    for (var i = this._cursor; i < this._displayables.length; i++) {
        cb && cb(this._displayables[i]);
    }
    for (var i = 0; i < this._temporaryDisplayables.length; i++) {
        cb && cb(this._temporaryDisplayables[i]);
    }
};

IncrementalDisplayble.prototype.update = function () {
    this.updateTransform();
    for (var i = this._cursor; i < this._displayables.length; i++) {
        var displayable = this._displayables[i];
        // PENDING
        displayable.parent = this;
        displayable.update();
        displayable.parent = null;
    }
    for (var i = 0; i < this._temporaryDisplayables.length; i++) {
        var displayable = this._temporaryDisplayables[i];
        // PENDING
        displayable.parent = this;
        displayable.update();
        displayable.parent = null;
    }
};

IncrementalDisplayble.prototype.brush = function (ctx, prevEl) {
    // Render persistant displayables.
    for (var i = this._cursor; i < this._displayables.length; i++) {
        var displayable = this._displayables[i];
        displayable.beforeBrush && displayable.beforeBrush(ctx);
        displayable.brush(ctx, i === this._cursor ? null : this._displayables[i - 1]);
        displayable.afterBrush && displayable.afterBrush(ctx);
    }
    this._cursor = i;
    // Render temporary displayables.
    for (var i = 0; i < this._temporaryDisplayables.length; i++) {
        var displayable = this._temporaryDisplayables[i];
        displayable.beforeBrush && displayable.beforeBrush(ctx);
        displayable.brush(ctx, i === 0 ? null : this._temporaryDisplayables[i - 1]);
        displayable.afterBrush && displayable.afterBrush(ctx);
    }

    this._temporaryDisplayables = [];

    this.notClear = true;
};

var m = [];
IncrementalDisplayble.prototype.getBoundingRect = function () {
    if (!this._rect) {
        var rect = new BoundingRect(Infinity, Infinity, -Infinity, -Infinity);
        for (var i = 0; i < this._displayables.length; i++) {
            var displayable = this._displayables[i];
            var childRect = displayable.getBoundingRect().clone();
            if (displayable.needLocalTransform()) {
                childRect.applyTransform(displayable.getLocalTransform(m));
            }
            rect.union(childRect);
        }
        this._rect = rect;
    }
    return this._rect;
};

IncrementalDisplayble.prototype.contain = function (x, y) {
    var localPos = this.transformCoordToLocal(x, y);
    var rect = this.getBoundingRect();

    if (rect.contain(localPos[0], localPos[1])) {
        for (var i = 0; i < this._displayables.length; i++) {
            var displayable = this._displayables[i];
            if (displayable.contain(x, y)) {
                return true;
            }
        }
    }
    return false;
};

inherits(IncrementalDisplayble, Displayable);

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var mathMax$1 = Math.max;
var mathMin$1 = Math.min;

var EMPTY_OBJ = {};

var Z2_EMPHASIS_LIFT = 1;

// key: label model property nane, value: style property name.
var CACHED_LABEL_STYLE_PROPERTIES = {
    color: 'textFill',
    textBorderColor: 'textStroke',
    textBorderWidth: 'textStrokeWidth'
};

var EMPHASIS = 'emphasis';
var NORMAL = 'normal';

// Reserve 0 as default.
var _highlightNextDigit = 1;
var _highlightKeyMap = {};

var _customShapeMap = {};


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

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

/**
 * Register a user defined shape.
 * The shape class can be fetched by `getShapeClass`
 * This method will overwrite the registered shapes, including
 * the registered built-in shapes, if using the same `name`.
 * The shape can be used in `custom series` and
 * `graphic component` by declaring `{type: name}`.
 *
 * @param {string} name
 * @param {Object} ShapeClass Can be generated by `extendShape`.
 */
function registerShape(name, ShapeClass) {
    _customShapeMap[name] = ShapeClass;
}

/**
 * Find shape class registered by `registerShape`. Usually used in
 * fetching user defined shape.
 *
 * [Caution]:
 * (1) This method **MUST NOT be used inside echarts !!!**, unless it is prepared
 * to use user registered shapes.
 * Because the built-in shape (see `getBuiltInShape`) will be registered by
 * `registerShape` by default. That enables users to get both built-in
 * shapes as well as the shapes belonging to themsleves. But users can overwrite
 * the built-in shapes by using names like 'circle', 'rect' via calling
 * `registerShape`. So the echarts inner featrues should not fetch shapes from here
 * in case that it is overwritten by users, except that some features, like
 * `custom series`, `graphic component`, do it deliberately.
 *
 * (2) In the features like `custom series`, `graphic component`, the user input
 * `{tpye: 'xxx'}` does not only specify shapes but also specify other graphic
 * elements like `'group'`, `'text'`, `'image'` or event `'path'`. Those names
 * are reserved names, that is, if some user register a shape named `'image'`,
 * the shape will not be used. If we intending to add some more reserved names
 * in feature, that might bring break changes (disable some existing user shape
 * names). But that case probably rearly happen. So we dont make more mechanism
 * to resolve this issue here.
 *
 * @param {string} name
 * @return {Object} The shape class. If not found, return nothing.
 */
function getShapeClass(name) {
    if (_customShapeMap.hasOwnProperty(name)) {
        return _customShapeMap[name];
    }
}

/**
 * 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'
 */
function makePath(pathData, opts, rect, layout) {
    var path = createFromString(pathData, opts);
    if (rect) {
        if (layout === 'center') {
            rect = centerGraphic(rect, path.getBoundingRect());
        }
        resizePath(path, rect);
    }
    return path;
}

/**
 * Create a image element from image url
 * @param {string} imageUrl image url
 * @param {Object} opts options
 * @param {module:zrender/core/BoundingRect} rect constrain rect
 * @param {string} [layout=cover] 'center' or 'cover'
 */
function makeImage(imageUrl, rect, layout) {
    var path = new ZImage({
        style: {
            image: imageUrl,
            x: rect.x,
            y: rect.y,
            width: rect.width,
            height: rect.height
        },
        onload: function (img) {
            if (layout === 'center') {
                var boundingRect = {
                    width: img.width,
                    height: img.height
                };
                path.setStyle(centerGraphic(rect, boundingRect));
            }
        }
    });
    return path;
}

/**
 * Get position of centered element in bounding box.
 *
 * @param  {Object} rect         element local bounding box
 * @param  {Object} boundingRect constraint bounding box
 * @return {Object} element position containing x, y, width, and height
 */
function centerGraphic(rect, boundingRect) {
    // Set rect to center, keep width / height ratio.
    var aspect = boundingRect.width / boundingRect.height;
    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;

    return {
        x: cx - width / 2,
        y: cy - height / 2,
        width: width,
        height: height
    };
}

var mergePath = mergePath$1;

/**
 * Resize a path to fit the rect
 * @param {module:zrender/graphic/Path} path
 * @param {Object} rect
 */
function resizePath(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
 */
function subPixelOptimizeLine(param) {
    subPixelOptimizeLine$1(param.shape, param.shape, param.style);
    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
 */
function subPixelOptimizeRect(param) {
    subPixelOptimizeRect$1(param.shape, param.shape, param.style);
    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.
 */
var subPixelOptimize = subPixelOptimize$1;


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

// Most lifted color are duplicated.
var liftedColorMap = createHashMap();
var liftedColorCount = 0;

function liftColor(color) {
    if (typeof color !== 'string') {
        return color;
    }
    var liftedColor = liftedColorMap.get(color);
    if (!liftedColor) {
        liftedColor = lift(color, -0.1);
        if (liftedColorCount < 10000) {
            liftedColorMap.set(color, liftedColor);
            liftedColorCount++;
        }
    }
    return liftedColor;
}

function cacheElementStl(el) {
    if (!el.__hoverStlDirty) {
        return;
    }
    el.__hoverStlDirty = false;

    var hoverStyle = el.__hoverStl;
    if (!hoverStyle) {
        el.__cachedNormalStl = el.__cachedNormalZ2 = null;
        return;
    }

    var normalStyle = el.__cachedNormalStl = {};
    el.__cachedNormalZ2 = el.z2;
    var elStyle = el.style;

    for (var name in hoverStyle) {
        // See comment in `singleEnterEmphasis`.
        if (hoverStyle[name] != null) {
            normalStyle[name] = elStyle[name];
        }
    }

    // Always cache fill and stroke to normalStyle for lifting color.
    normalStyle.fill = elStyle.fill;
    normalStyle.stroke = elStyle.stroke;
}

function singleEnterEmphasis(el) {
    var hoverStl = el.__hoverStl;

    if (!hoverStl || el.__highlighted) {
        return;
    }

    var zr = el.__zr;

    var useHoverLayer = el.useHoverLayer && zr && zr.painter.type === 'canvas';
    el.__highlighted = useHoverLayer ? 'layer' : 'plain';

    if (el.isGroup || (!zr && el.useHoverLayer)) {
        return;
    }

    var elTarget = el;
    var targetStyle = el.style;

    if (useHoverLayer) {
        elTarget = zr.addHover(el);
        targetStyle = elTarget.style;
    }

    rollbackDefaultTextStyle(targetStyle);

    if (!useHoverLayer) {
        cacheElementStl(elTarget);
    }

    // styles can be:
    // {
    //    label: {
    //        show: false,
    //        position: 'outside',
    //        fontSize: 18
    //    },
    //    emphasis: {
    //        label: {
    //            show: true
    //        }
    //    }
    // },
    // where properties of `emphasis` may not appear in `normal`. We previously use
    // module:echarts/util/model#defaultEmphasis to merge `normal` to `emphasis`.
    // But consider rich text and setOption in merge mode, it is impossible to cover
    // all properties in merge. So we use merge mode when setting style here.
    // But we choose the merge strategy that only properties that is not `null/undefined`.
    // Because when making a textStyle (espacially rich text), it is not easy to distinguish
    // `hasOwnProperty` and `null/undefined` in code, so we trade them as the same for simplicity.
    // But this strategy brings a trouble that `null/undefined` can not be used to remove
    // style any more in `emphasis`. Users can both set properties directly on normal and
    // emphasis to avoid this issue, or we might support `'none'` for this case if required.
    targetStyle.extendFrom(hoverStl);

    setDefaultHoverFillStroke(targetStyle, hoverStl, 'fill');
    setDefaultHoverFillStroke(targetStyle, hoverStl, 'stroke');

    applyDefaultTextStyle(targetStyle);

    if (!useHoverLayer) {
        el.dirty(false);
        el.z2 += Z2_EMPHASIS_LIFT;
    }
}

function setDefaultHoverFillStroke(targetStyle, hoverStyle, prop) {
    if (!hasFillOrStroke(hoverStyle[prop]) && hasFillOrStroke(targetStyle[prop])) {
        targetStyle[prop] = liftColor(targetStyle[prop]);
    }
}

function singleEnterNormal(el) {
    var highlighted = el.__highlighted;

    if (!highlighted) {
        return;
    }

    el.__highlighted = false;

    if (el.isGroup) {
        return;
    }

    if (highlighted === 'layer') {
        el.__zr && el.__zr.removeHover(el);
    }
    else {
        var style = el.style;

        var normalStl = el.__cachedNormalStl;
        if (normalStl) {
            rollbackDefaultTextStyle(style);
            el.setStyle(normalStl);
            applyDefaultTextStyle(style);
        }
        // `__cachedNormalZ2` will not be reset if calling `setElementHoverStyle`
        // when `el` is on emphasis state. So here by comparing with 1, we try
        // hard to make the bug case rare.
        var normalZ2 = el.__cachedNormalZ2;
        if (normalZ2 != null && el.z2 - normalZ2 === Z2_EMPHASIS_LIFT) {
            el.z2 = normalZ2;
        }
    }
}

function traverseUpdate(el, updater, commonParam) {
    // If root is group, also enter updater for `highDownOnUpdate`.
    var fromState = NORMAL;
    var toState = NORMAL;
    var trigger;
    // See the rule of `highDownOnUpdate` on `graphic.setAsHighDownDispatcher`.
    el.__highlighted && (fromState = EMPHASIS, trigger = true);
    updater(el, commonParam);
    el.__highlighted && (toState = EMPHASIS, trigger = true);

    el.isGroup && el.traverse(function (child) {
        !child.isGroup && updater(child, commonParam);
    });

    trigger && el.__highDownOnUpdate && el.__highDownOnUpdate(fromState, toState);
}

/**
 * Set hover style (namely "emphasis style") of element, based on the current
 * style of the given `el`.
 * This method should be called after all of the normal styles have been adopted
 * to the `el`. See the reason on `setHoverStyle`.
 *
 * @param {module:zrender/Element} el Should not be `zrender/container/Group`.
 * @param {Object} [el.hoverStyle] Can be set on el or its descendants,
 *        e.g., `el.hoverStyle = ...; graphic.setHoverStyle(el); `.
 *        Often used when item group has a label element and it's hoverStyle is different.
 * @param {Object|boolean} [hoverStl] The specified hover style.
 *        If set as `false`, disable the hover style.
 *        Similarly, The `el.hoverStyle` can alse be set
 *        as `false` to disable the hover style.
 *        Otherwise, use the default hover style if not provided.
 */
function setElementHoverStyle(el, hoverStl) {
    // For performance consideration, it might be better to make the "hover style" only the
    // difference properties from the "normal style", but not a entire copy of all styles.
    hoverStl = el.__hoverStl = hoverStl !== false && (el.hoverStyle || hoverStl || {});
    el.__hoverStlDirty = true;

    // FIXME
    // It is not completely right to save "normal"/"emphasis" flag on elements.
    // It probably should be saved on `data` of series. Consider the cases:
    // (1) A highlighted elements are moved out of the view port and re-enter
    // again by dataZoom.
    // (2) call `setOption` and replace elements totally when they are highlighted.
    if (el.__highlighted) {
        // Consider the case:
        // The styles of a highlighted `el` is being updated. The new "emphasis style"
        // should be adapted to the `el`. Notice here new "normal styles" should have
        // been set outside and the cached "normal style" is out of date.
        el.__cachedNormalStl = null;
        // Do not clear `__cachedNormalZ2` here, because setting `z2` is not a constraint
        // of this method. In most cases, `z2` is not set and hover style should be able
        // to rollback. Of course, that would bring bug, but only in a rare case, see
        // `doSingleLeaveHover` for details.
        singleEnterNormal(el);

        singleEnterEmphasis(el);
    }
}

function onElementMouseOver(e) {
    !shouldSilent(this, e)
        // "emphasis" event highlight has higher priority than mouse highlight.
        && !this.__highByOuter
        && traverseUpdate(this, singleEnterEmphasis);
}

function onElementMouseOut(e) {
    !shouldSilent(this, e)
        // "emphasis" event highlight has higher priority than mouse highlight.
        && !this.__highByOuter
        && traverseUpdate(this, singleEnterNormal);
}

function onElementEmphasisEvent(highlightDigit) {
    this.__highByOuter |= 1 << (highlightDigit || 0);
    traverseUpdate(this, singleEnterEmphasis);
}

function onElementNormalEvent(highlightDigit) {
    !(this.__highByOuter &= ~(1 << (highlightDigit || 0)))
        && traverseUpdate(this, singleEnterNormal);
}

function shouldSilent(el, e) {
    return el.__highDownSilentOnTouch && e.zrByTouch;
}

/**
 * Set hover style (namely "emphasis style") of element,
 * based on the current style of the given `el`.
 *
 * (1)
 * **CONSTRAINTS** for this method:
 * <A> This method MUST be called after all of the normal styles having been adopted
 * to the `el`.
 * <B> The input `hoverStyle` (that is, "emphasis style") MUST be the subset of the
 * "normal style" having been set to the el.
 * <C> `color` MUST be one of the "normal styles" (because color might be lifted as
 * a default hover style).
 *
 * The reason: this method treat the current style of the `el` as the "normal style"
 * and cache them when enter/update the "emphasis style". Consider the case: the `el`
 * is in "emphasis" state and `setOption`/`dispatchAction` trigger the style updating
 * logic, where the el should shift from the original emphasis style to the new
 * "emphasis style" and should be able to "downplay" back to the new "normal style".
 *
 * Indeed, it is error-prone to make a interface has so many constraints, but I have
 * not found a better solution yet to fit the backward compatibility, performance and
 * the current programming style.
 *
 * (2)
 * Call the method for a "root" element once. Do not call it for each descendants.
 * If the descendants elemenets of a group has itself hover style different from the
 * root group, we can simply mount the style on `el.hoverStyle` for them, but should
 * not call this method for them.
 *
 * (3) These input parameters can be set directly on `el`:
 *
 * @param {module:zrender/Element} el
 * @param {Object} [el.hoverStyle] See `graphic.setElementHoverStyle`.
 * @param {boolean} [el.highDownSilentOnTouch=false] See `graphic.setAsHighDownDispatcher`.
 * @param {Function} [el.highDownOnUpdate] See `graphic.setAsHighDownDispatcher`.
 * @param {Object|boolean} [hoverStyle] See `graphic.setElementHoverStyle`.
 */
function setHoverStyle(el, hoverStyle) {
    setAsHighDownDispatcher(el, true);
    traverseUpdate(el, setElementHoverStyle, hoverStyle);
}

/**
 * @param {module:zrender/Element} el
 * @param {Function} [el.highDownOnUpdate] Called when state updated.
 *        Since `setHoverStyle` has the constraint that it must be called after
 *        all of the normal style updated, `highDownOnUpdate` is not needed to
 *        trigger if both `fromState` and `toState` is 'normal', and needed to
 *        trigger if both `fromState` and `toState` is 'emphasis', which enables
 *        to sync outside style settings to "emphasis" state.
 *        @this {string} This dispatcher `el`.
 *        @param {string} fromState Can be "normal" or "emphasis".
 *               `fromState` might equal to `toState`,
 *               for example, when this method is called when `el` is
 *               on "emphasis" state.
 *        @param {string} toState Can be "normal" or "emphasis".
 *
 *        FIXME
 *        CAUTION: Do not expose `highDownOnUpdate` outside echarts.
 *        Because it is not a complete solution. The update
 *        listener should not have been mount in element,
 *        and the normal/emphasis state should not have
 *        mantained on elements.
 *
 * @param {boolean} [el.highDownSilentOnTouch=false]
 *        In touch device, mouseover event will be trigger on touchstart event
 *        (see module:zrender/dom/HandlerProxy). By this mechanism, we can
 *        conveniently use hoverStyle when tap on touch screen without additional
 *        code for compatibility.
 *        But if the chart/component has select feature, which usually also use
 *        hoverStyle, there might be conflict between 'select-highlight' and
 *        'hover-highlight' especially when roam is enabled (see geo for example).
 *        In this case, `highDownSilentOnTouch` should be used to disable
 *        hover-highlight on touch device.
 * @param {boolean} [asDispatcher=true] If `false`, do not set as "highDownDispatcher".
 */
function setAsHighDownDispatcher(el, asDispatcher) {
    var disable = asDispatcher === false;
    // Make `highDownSilentOnTouch` and `highDownOnUpdate` only work after
    // `setAsHighDownDispatcher` called. Avoid it is modified by user unexpectedly.
    el.__highDownSilentOnTouch = el.highDownSilentOnTouch;
    el.__highDownOnUpdate = el.highDownOnUpdate;

    // Simple optimize, since this method might be
    // called for each elements of a group in some cases.
    if (!disable || el.__highDownDispatcher) {
        var method = disable ? 'off' : 'on';

        // Duplicated function will be auto-ignored, see Eventful.js.
        el[method]('mouseover', onElementMouseOver)[method]('mouseout', onElementMouseOut);
        // Emphasis, normal can be triggered manually by API or other components like hover link.
        el[method]('emphasis', onElementEmphasisEvent)[method]('normal', onElementNormalEvent);
        // Also keep previous record.
        el.__highByOuter = el.__highByOuter || 0;

        el.__highDownDispatcher = !disable;
    }
}

/**
 * @param {module:zrender/src/Element} el
 * @return {boolean}
 */
function isHighDownDispatcher(el) {
    return !!(el && el.__highDownDispatcher);
}

/**
 * Support hightlight/downplay record on each elements.
 * For the case: hover highlight/downplay (legend, visualMap, ...) and
 * user triggerred hightlight/downplay should not conflict.
 * Only all of the highlightDigit cleared, return to normal.
 * @param {string} highlightKey
 * @return {number} highlightDigit
 */
function getHighlightDigit(highlightKey) {
    var highlightDigit = _highlightKeyMap[highlightKey];
    if (highlightDigit == null && _highlightNextDigit <= 32) {
        highlightDigit = _highlightKeyMap[highlightKey] = _highlightNextDigit++;
    }
    return highlightDigit;
}

/**
 * See more info in `setTextStyleCommon`.
 * @param {Object|module:zrender/graphic/Style} normalStyle
 * @param {Object} emphasisStyle
 * @param {module:echarts/model/Model} normalModel
 * @param {module:echarts/model/Model} emphasisModel
 * @param {Object} opt Check `opt` of `setTextStyleCommon` to find other props.
 * @param {string|Function} [opt.defaultText]
 * @param {module:echarts/model/Model} [opt.labelFetcher] Fetch text by
 *      `opt.labelFetcher.getFormattedLabel(opt.labelDataIndex, 'normal'/'emphasis', null, opt.labelDimIndex, opt.labelProp)`
 * @param {number} [opt.labelDataIndex] Fetch text by
 *      `opt.textFetcher.getFormattedLabel(opt.labelDataIndex, 'normal'/'emphasis', null, opt.labelDimIndex, opt.labelProp)`
 * @param {number} [opt.labelDimIndex] Fetch text by
 *      `opt.textFetcher.getFormattedLabel(opt.labelDataIndex, 'normal'/'emphasis', null, opt.labelDimIndex, opt.labelProp)`
 * @param {string} [opt.labelProp] Fetch text by
 *      `opt.textFetcher.getFormattedLabel(opt.labelDataIndex, 'normal'/'emphasis', null, opt.labelDimIndex, opt.labelProp)`
 * @param {Object} [normalSpecified]
 * @param {Object} [emphasisSpecified]
 */
function setLabelStyle(
    normalStyle, emphasisStyle,
    normalModel, emphasisModel,
    opt,
    normalSpecified, emphasisSpecified
) {
    opt = opt || EMPTY_OBJ;
    var labelFetcher = opt.labelFetcher;
    var labelDataIndex = opt.labelDataIndex;
    var labelDimIndex = opt.labelDimIndex;
    var labelProp = opt.labelProp;

    // This scenario, `label.normal.show = true; label.emphasis.show = false`,
    // is not supported util someone requests.

    var showNormal = normalModel.getShallow('show');
    var showEmphasis = emphasisModel.getShallow('show');

    // Consider performance, only fetch label when necessary.
    // If `normal.show` is `false` and `emphasis.show` is `true` and `emphasis.formatter` is not set,
    // label should be displayed, where text is fetched by `normal.formatter` or `opt.defaultText`.
    var baseText;
    if (showNormal || showEmphasis) {
        if (labelFetcher) {
            baseText = labelFetcher.getFormattedLabel(labelDataIndex, 'normal', null, labelDimIndex, labelProp);
        }
        if (baseText == null) {
            baseText = isFunction$1(opt.defaultText) ? opt.defaultText(labelDataIndex, opt) : opt.defaultText;
        }
    }
    var normalStyleText = showNormal ? baseText : null;
    var emphasisStyleText = showEmphasis
        ? retrieve2(
            labelFetcher
                ? labelFetcher.getFormattedLabel(labelDataIndex, 'emphasis', null, labelDimIndex, labelProp)
                : null,
            baseText
        )
        : null;

    // Optimize: If style.text is null, text will not be drawn.
    if (normalStyleText != null || emphasisStyleText != null) {
        // Always set `textStyle` even if `normalStyle.text` is null, because default
        // values have to be set on `normalStyle`.
        // If we set default values on `emphasisStyle`, consider case:
        // Firstly, `setOption(... label: {normal: {text: null}, emphasis: {show: true}} ...);`
        // Secondly, `setOption(... label: {noraml: {show: true, text: 'abc', color: 'red'} ...);`
        // Then the 'red' will not work on emphasis.
        setTextStyle(normalStyle, normalModel, normalSpecified, opt);
        setTextStyle(emphasisStyle, emphasisModel, emphasisSpecified, opt, true);
    }

    normalStyle.text = normalStyleText;
    emphasisStyle.text = emphasisStyleText;
}

/**
 * Modify label style manually.
 * Only works after `setLabelStyle` and `setElementHoverStyle` called.
 *
 * @param {module:zrender/src/Element} el
 * @param {Object} [normalStyleProps] optional
 * @param {Object} [emphasisStyleProps] optional
 */
function modifyLabelStyle(el, normalStyleProps, emphasisStyleProps) {
    var elStyle = el.style;
    if (normalStyleProps) {
        rollbackDefaultTextStyle(elStyle);
        el.setStyle(normalStyleProps);
        applyDefaultTextStyle(elStyle);
    }
    elStyle = el.__hoverStl;
    if (emphasisStyleProps && elStyle) {
        rollbackDefaultTextStyle(elStyle);
        extend(elStyle, emphasisStyleProps);
        applyDefaultTextStyle(elStyle);
    }
}

/**
 * Set basic textStyle properties.
 * See more info in `setTextStyleCommon`.
 * @param {Object|module:zrender/graphic/Style} textStyle
 * @param {module:echarts/model/Model} model
 * @param {Object} [specifiedTextStyle] Can be overrided by settings in model.
 * @param {Object} [opt] See `opt` of `setTextStyleCommon`.
 * @param {boolean} [isEmphasis]
 */
function setTextStyle(
    textStyle, textStyleModel, specifiedTextStyle, opt, isEmphasis
) {
    setTextStyleCommon(textStyle, textStyleModel, opt, isEmphasis);
    specifiedTextStyle && extend(textStyle, specifiedTextStyle);
    // textStyle.host && textStyle.host.dirty && textStyle.host.dirty(false);

    return textStyle;
}

/**
 * Set text option in the style.
 * See more info in `setTextStyleCommon`.
 * @deprecated
 * @param {Object} textStyle
 * @param {module:echarts/model/Model} labelModel
 * @param {string|boolean} defaultColor Default text color.
 *        If set as false, it will be processed as a emphasis style.
 */
function setText(textStyle, labelModel, defaultColor) {
    var opt = {isRectText: true};
    var isEmphasis;

    if (defaultColor === false) {
        isEmphasis = true;
    }
    else {
        // Support setting color as 'auto' to get visual color.
        opt.autoColor = defaultColor;
    }
    setTextStyleCommon(textStyle, labelModel, opt, isEmphasis);
    // textStyle.host && textStyle.host.dirty && textStyle.host.dirty(false);
}

/**
 * The uniform entry of set text style, that is, retrieve style definitions
 * from `model` and set to `textStyle` object.
 *
 * Never in merge mode, but in overwrite mode, that is, all of the text style
 * properties will be set. (Consider the states of normal and emphasis and
 * default value can be adopted, merge would make the logic too complicated
 * to manage.)
 *
 * The `textStyle` object can either be a plain object or an instance of
 * `zrender/src/graphic/Style`, and either be the style of normal or emphasis.
 * After this mothod called, the `textStyle` object can then be used in
 * `el.setStyle(textStyle)` or `el.hoverStyle = textStyle`.
 *
 * Default value will be adopted and `insideRollbackOpt` will be created.
 * See `applyDefaultTextStyle` `rollbackDefaultTextStyle` for more details.
 *
 * opt: {
 *      disableBox: boolean, Whether diable drawing box of block (outer most).
 *      isRectText: boolean,
 *      autoColor: string, specify a color when color is 'auto',
 *              for textFill, textStroke, textBackgroundColor, and textBorderColor.
 *              If autoColor specified, it is used as default textFill.
 *      useInsideStyle:
 *              `true`: Use inside style (textFill, textStroke, textStrokeWidth)
 *                  if `textFill` is not specified.
 *              `false`: Do not use inside style.
 *              `null/undefined`: use inside style if `isRectText` is true and
 *                  `textFill` is not specified and textPosition contains `'inside'`.
 *      forceRich: boolean
 * }
 */
function setTextStyleCommon(textStyle, textStyleModel, opt, isEmphasis) {
    // Consider there will be abnormal when merge hover style to normal style if given default value.
    opt = opt || EMPTY_OBJ;

    if (opt.isRectText) {
        var textPosition;
        if (opt.getTextPosition) {
            textPosition = opt.getTextPosition(textStyleModel, isEmphasis);
        }
        else {
            textPosition = textStyleModel.getShallow('position')
                || (isEmphasis ? null : 'inside');
            // 'outside' is not a valid zr textPostion value, but used
            // in bar series, and magric type should be considered.
            textPosition === 'outside' && (textPosition = 'top');
        }

        textStyle.textPosition = textPosition;
        textStyle.textOffset = textStyleModel.getShallow('offset');
        var labelRotate = textStyleModel.getShallow('rotate');
        labelRotate != null && (labelRotate *= Math.PI / 180);
        textStyle.textRotation = labelRotate;
        textStyle.textDistance = retrieve2(
            textStyleModel.getShallow('distance'), isEmphasis ? null : 5
        );
    }

    var ecModel = textStyleModel.ecModel;
    var globalTextStyle = ecModel && ecModel.option.textStyle;

    // Consider case:
    // {
    //     data: [{
    //         value: 12,
    //         label: {
    //             rich: {
    //                 // no 'a' here but using parent 'a'.
    //             }
    //         }
    //     }],
    //     rich: {
    //         a: { ... }
    //     }
    // }
    var richItemNames = getRichItemNames(textStyleModel);
    var richResult;
    if (richItemNames) {
        richResult = {};
        for (var name in richItemNames) {
            if (richItemNames.hasOwnProperty(name)) {
                // Cascade is supported in rich.
                var richTextStyle = textStyleModel.getModel(['rich', name]);
                // In rich, never `disableBox`.
                // FIXME: consider `label: {formatter: '{a|xx}', color: 'blue', rich: {a: {}}}`,
                // the default color `'blue'` will not be adopted if no color declared in `rich`.
                // That might confuses users. So probably we should put `textStyleModel` as the
                // root ancestor of the `richTextStyle`. But that would be a break change.
                setTokenTextStyle(richResult[name] = {}, richTextStyle, globalTextStyle, opt, isEmphasis);
            }
        }
    }
    textStyle.rich = richResult;

    setTokenTextStyle(textStyle, textStyleModel, globalTextStyle, opt, isEmphasis, true);

    if (opt.forceRich && !opt.textStyle) {
        opt.textStyle = {};
    }

    return textStyle;
}

// Consider case:
// {
//     data: [{
//         value: 12,
//         label: {
//             rich: {
//                 // no 'a' here but using parent 'a'.
//             }
//         }
//     }],
//     rich: {
//         a: { ... }
//     }
// }
function getRichItemNames(textStyleModel) {
    // Use object to remove duplicated names.
    var richItemNameMap;
    while (textStyleModel && textStyleModel !== textStyleModel.ecModel) {
        var rich = (textStyleModel.option || EMPTY_OBJ).rich;
        if (rich) {
            richItemNameMap = richItemNameMap || {};
            for (var name in rich) {
                if (rich.hasOwnProperty(name)) {
                    richItemNameMap[name] = 1;
                }
            }
        }
        textStyleModel = textStyleModel.parentModel;
    }
    return richItemNameMap;
}

function setTokenTextStyle(textStyle, textStyleModel, globalTextStyle, opt, isEmphasis, isBlock) {
    // In merge mode, default value should not be given.
    globalTextStyle = !isEmphasis && globalTextStyle || EMPTY_OBJ;

    textStyle.textFill = getAutoColor(textStyleModel.getShallow('color'), opt)
        || globalTextStyle.color;
    textStyle.textStroke = getAutoColor(textStyleModel.getShallow('textBorderColor'), opt)
        || globalTextStyle.textBorderColor;
    textStyle.textStrokeWidth = retrieve2(
        textStyleModel.getShallow('textBorderWidth'),
        globalTextStyle.textBorderWidth
    );

    if (!isEmphasis) {
        if (isBlock) {
            textStyle.insideRollbackOpt = opt;
            applyDefaultTextStyle(textStyle);
        }

        // Set default finally.
        if (textStyle.textFill == null) {
            textStyle.textFill = opt.autoColor;
        }
    }

    // Do not use `getFont` here, because merge should be supported, where
    // part of these properties may be changed in emphasis style, and the
    // others should remain their original value got from normal style.
    textStyle.fontStyle = textStyleModel.getShallow('fontStyle') || globalTextStyle.fontStyle;
    textStyle.fontWeight = textStyleModel.getShallow('fontWeight') || globalTextStyle.fontWeight;
    textStyle.fontSize = textStyleModel.getShallow('fontSize') || globalTextStyle.fontSize;
    textStyle.fontFamily = textStyleModel.getShallow('fontFamily') || globalTextStyle.fontFamily;

    textStyle.textAlign = textStyleModel.getShallow('align');
    textStyle.textVerticalAlign = textStyleModel.getShallow('verticalAlign')
        || textStyleModel.getShallow('baseline');

    textStyle.textLineHeight = textStyleModel.getShallow('lineHeight');
    textStyle.textWidth = textStyleModel.getShallow('width');
    textStyle.textHeight = textStyleModel.getShallow('height');
    textStyle.textTag = textStyleModel.getShallow('tag');

    if (!isBlock || !opt.disableBox) {
        textStyle.textBackgroundColor = getAutoColor(textStyleModel.getShallow('backgroundColor'), opt);
        textStyle.textPadding = textStyleModel.getShallow('padding');
        textStyle.textBorderColor = getAutoColor(textStyleModel.getShallow('borderColor'), opt);
        textStyle.textBorderWidth = textStyleModel.getShallow('borderWidth');
        textStyle.textBorderRadius = textStyleModel.getShallow('borderRadius');

        textStyle.textBoxShadowColor = textStyleModel.getShallow('shadowColor');
        textStyle.textBoxShadowBlur = textStyleModel.getShallow('shadowBlur');
        textStyle.textBoxShadowOffsetX = textStyleModel.getShallow('shadowOffsetX');
        textStyle.textBoxShadowOffsetY = textStyleModel.getShallow('shadowOffsetY');
    }

    textStyle.textShadowColor = textStyleModel.getShallow('textShadowColor')
        || globalTextStyle.textShadowColor;
    textStyle.textShadowBlur = textStyleModel.getShallow('textShadowBlur')
        || globalTextStyle.textShadowBlur;
    textStyle.textShadowOffsetX = textStyleModel.getShallow('textShadowOffsetX')
        || globalTextStyle.textShadowOffsetX;
    textStyle.textShadowOffsetY = textStyleModel.getShallow('textShadowOffsetY')
        || globalTextStyle.textShadowOffsetY;
}

function getAutoColor(color, opt) {
    return color !== 'auto' ? color : (opt && opt.autoColor) ? opt.autoColor : null;
}

/**
 * Give some default value to the input `textStyle` object, based on the current settings
 * in this `textStyle` object.
 *
 * The Scenario:
 * when text position is `inside` and `textFill` is not specified, we show
 * text border by default for better view. But it should be considered that text position
 * might be changed when hovering or being emphasis, where the `insideRollback` is used to
 * restore the style.
 *
 * Usage (& NOTICE):
 * When a style object (eithor plain object or instance of `zrender/src/graphic/Style`) is
 * about to be modified on its text related properties, `rollbackDefaultTextStyle` should
 * be called before the modification and `applyDefaultTextStyle` should be called after that.
 * (For the case that all of the text related properties is reset, like `setTextStyleCommon`
 * does, `rollbackDefaultTextStyle` is not needed to be called).
 */
function applyDefaultTextStyle(textStyle) {
    var textPosition = textStyle.textPosition;
    var opt = textStyle.insideRollbackOpt;
    var insideRollback;

    if (opt && textStyle.textFill == null) {
        var autoColor = opt.autoColor;
        var isRectText = opt.isRectText;
        var useInsideStyle = opt.useInsideStyle;

        var useInsideStyleCache = useInsideStyle !== false
            && (useInsideStyle === true
                || (isRectText
                    && textPosition
                    // textPosition can be [10, 30]
                    && typeof textPosition === 'string'
                    && textPosition.indexOf('inside') >= 0
                )
            );
        var useAutoColorCache = !useInsideStyleCache && autoColor != null;

        // All of the props declared in `CACHED_LABEL_STYLE_PROPERTIES` are to be cached.
        if (useInsideStyleCache || useAutoColorCache) {
            insideRollback = {
                textFill: textStyle.textFill,
                textStroke: textStyle.textStroke,
                textStrokeWidth: textStyle.textStrokeWidth
            };
        }
        if (useInsideStyleCache) {
            textStyle.textFill = '#fff';
            // Consider text with #fff overflow its container.
            if (textStyle.textStroke == null) {
                textStyle.textStroke = autoColor;
                textStyle.textStrokeWidth == null && (textStyle.textStrokeWidth = 2);
            }
        }
        if (useAutoColorCache) {
            textStyle.textFill = autoColor;
        }
    }

    // Always set `insideRollback`, so that the previous one can be cleared.
    textStyle.insideRollback = insideRollback;
}

/**
 * Consider the case: in a scatter,
 * label: {
 *     normal: {position: 'inside'},
 *     emphasis: {position: 'top'}
 * }
 * In the normal state, the `textFill` will be set as '#fff' for pretty view (see
 * `applyDefaultTextStyle`), but when switching to emphasis state, the `textFill`
 * should be retured to 'autoColor', but not keep '#fff'.
 */
function rollbackDefaultTextStyle(style) {
    var insideRollback = style.insideRollback;
    if (insideRollback) {
        // Reset all of the props in `CACHED_LABEL_STYLE_PROPERTIES`.
        style.textFill = insideRollback.textFill;
        style.textStroke = insideRollback.textStroke;
        style.textStrokeWidth = insideRollback.textStrokeWidth;
        style.insideRollback = null;
    }
}

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

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

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

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

/**
 * Update graphic element properties with or without animation according to the
 * configuration in series.
 *
 * Caution: this method will stop previous animation.
 * So do not use this method to one element twice before
 * animation starts, unless you know what you are doing.
 *
 * @param {module:zrender/Element} el
 * @param {Object} props
 * @param {module:echarts/model/Model} [animatableModel]
 * @param {number} [dataIndex]
 * @param {Function} [cb]
 * @example
 *     graphic.updateProps(el, {
 *         position: [100, 100]
 *     }, seriesModel, dataIndex, function () { console.log('Animation done!'); });
 *     // Or
 *     graphic.updateProps(el, {
 *         position: [100, 100]
 *     }, seriesModel, function () { console.log('Animation done!'); });
 */
function updateProps(el, props, animatableModel, dataIndex, cb) {
    animateOrSetProps(true, el, props, animatableModel, dataIndex, cb);
}

/**
 * Init graphic element properties with or without animation according to the
 * configuration in series.
 *
 * Caution: this method will stop previous animation.
 * So do not use this method to one element twice before
 * animation starts, unless you know what you are doing.
 *
 * @param {module:zrender/Element} el
 * @param {Object} props
 * @param {module:echarts/model/Model} [animatableModel]
 * @param {number} [dataIndex]
 * @param {Function} cb
 */
function initProps(el, props, animatableModel, dataIndex, cb) {
    animateOrSetProps(false, el, props, animatableModel, dataIndex, cb);
}

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

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

    return mat;
}

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

    if (invert$$1) {
        transform = invert([], transform);
    }
    return applyTransform([], target, transform);
}

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

    // 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 = applyTransform$1(vertex, transform, invert$$1);

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

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

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

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

/**
 * @param {Array.<Array.<number>>} points Like: [[23, 44], [53, 66], ...]
 * @param {Object} rect {x, y, width, height}
 * @return {Array.<Array.<number>>} A new clipped points.
 */
function clipPointsByRect(points, rect) {
    // FIXME: this way migth be incorrect when grpahic clipped by a corner.
    // and when element have border.
    return map(points, function (point) {
        var x = point[0];
        x = mathMax$1(x, rect.x);
        x = mathMin$1(x, rect.x + rect.width);
        var y = point[1];
        y = mathMax$1(y, rect.y);
        y = mathMin$1(y, rect.y + rect.height);
        return [x, y];
    });
}

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

    // If the total rect is cliped, nothing, including the border,
    // should be painted. So return undefined.
    if (x2 >= x && y2 >= y) {
        return {
            x: x,
            y: y,
            width: x2 - x,
            height: y2 - y
        };
    }
}

/**
 * @param {string} iconStr Support 'image://' or 'path://' or direct svg path.
 * @param {Object} [opt] Properties of `module:zrender/Element`, except `style`.
 * @param {Object} [rect] {x, y, width, height}
 * @return {module:zrender/Element} Icon path or image element.
 */
function createIcon(iconStr, opt, rect) {
    opt = extend({rectHover: true}, opt);
    var style = opt.style = {strokeNoScale: true};
    rect = rect || {x: -1, y: -1, width: 2, height: 2};

    if (iconStr) {
        return iconStr.indexOf('image://') === 0
            ? (
                style.image = iconStr.slice(8),
                defaults(style, rect),
                new ZImage(opt)
            )
            : (
                makePath(
                    iconStr.replace('path://', ''),
                    opt,
                    rect,
                    'center'
                )
            );
    }
}

/**
 * Return `true` if the given line (line `a`) and the given polygon
 * are intersect.
 * Note that we do not count colinear as intersect here because no
 * requirement for that. We could do that if required in future.
 *
 * @param {number} a1x
 * @param {number} a1y
 * @param {number} a2x
 * @param {number} a2y
 * @param {Array.<Array.<number>>} points Points of the polygon.
 * @return {boolean}
 */
function linePolygonIntersect(a1x, a1y, a2x, a2y, points) {
    for (var i = 0, p2 = points[points.length - 1]; i < points.length; i++) {
        var p = points[i];
        if (lineLineIntersect(a1x, a1y, a2x, a2y, p[0], p[1], p2[0], p2[1])) {
            return true;
        }
        p2 = p;
    }
}

/**
 * Return `true` if the given two lines (line `a` and line `b`)
 * are intersect.
 * Note that we do not count colinear as intersect here because no
 * requirement for that. We could do that if required in future.
 *
 * @param {number} a1x
 * @param {number} a1y
 * @param {number} a2x
 * @param {number} a2y
 * @param {number} b1x
 * @param {number} b1y
 * @param {number} b2x
 * @param {number} b2y
 * @return {boolean}
 */
function lineLineIntersect(a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y) {
    // let `vec_m` to be `vec_a2 - vec_a1` and `vec_n` to be `vec_b2 - vec_b1`.
    var mx = a2x - a1x;
    var my = a2y - a1y;
    var nx = b2x - b1x;
    var ny = b2y - b1y;

    // `vec_m` and `vec_n` are parallel iff
    //     exising `k` such that `vec_m = k · vec_n`, equivalent to `vec_m X vec_n = 0`.
    var nmCrossProduct = crossProduct2d(nx, ny, mx, my);
    if (nearZero(nmCrossProduct)) {
        return false;
    }

    // `vec_m` and `vec_n` are intersect iff
    //     existing `p` and `q` in [0, 1] such that `vec_a1 + p * vec_m = vec_b1 + q * vec_n`,
    //     such that `q = ((vec_a1 - vec_b1) X vec_m) / (vec_n X vec_m)`
    //           and `p = ((vec_a1 - vec_b1) X vec_n) / (vec_n X vec_m)`.
    var b1a1x = a1x - b1x;
    var b1a1y = a1y - b1y;
    var q = crossProduct2d(b1a1x, b1a1y, mx, my) / nmCrossProduct;
    if (q < 0 || q > 1) {
        return false;
    }
    var p = crossProduct2d(b1a1x, b1a1y, nx, ny) / nmCrossProduct;
    if (p < 0 || p > 1) {
        return false;
    }

    return true;
}

/**
 * Cross product of 2-dimension vector.
 */
function crossProduct2d(x1, y1, x2, y2) {
    return x1 * y2 - x2 * y1;
}

function nearZero(val) {
    return val <= (1e-6) && val >= -(1e-6);
}

// Register built-in shapes. These shapes might be overwirtten
// by users, although we do not recommend that.
registerShape('circle', Circle);
registerShape('sector', Sector);
registerShape('ring', Ring);
registerShape('polygon', Polygon);
registerShape('polyline', Polyline);
registerShape('rect', Rect);
registerShape('line', Line);
registerShape('bezierCurve', BezierCurve);
registerShape('arc', Arc);




var graphic = (Object.freeze || Object)({
	Z2_EMPHASIS_LIFT: Z2_EMPHASIS_LIFT,
	CACHED_LABEL_STYLE_PROPERTIES: CACHED_LABEL_STYLE_PROPERTIES,
	extendShape: extendShape,
	extendPath: extendPath,
	registerShape: registerShape,
	getShapeClass: getShapeClass,
	makePath: makePath,
	makeImage: makeImage,
	mergePath: mergePath,
	resizePath: resizePath,
	subPixelOptimizeLine: subPixelOptimizeLine,
	subPixelOptimizeRect: subPixelOptimizeRect,
	subPixelOptimize: subPixelOptimize,
	setElementHoverStyle: setElementHoverStyle,
	setHoverStyle: setHoverStyle,
	setAsHighDownDispatcher: setAsHighDownDispatcher,
	isHighDownDispatcher: isHighDownDispatcher,
	getHighlightDigit: getHighlightDigit,
	setLabelStyle: setLabelStyle,
	modifyLabelStyle: modifyLabelStyle,
	setTextStyle: setTextStyle,
	setText: setText,
	getFont: getFont,
	updateProps: updateProps,
	initProps: initProps,
	getTransform: getTransform,
	applyTransform: applyTransform$1,
	transformDirection: transformDirection,
	groupTransition: groupTransition,
	clipPointsByRect: clipPointsByRect,
	clipRectByRect: clipRectByRect,
	createIcon: createIcon,
	linePolygonIntersect: linePolygonIntersect,
	lineLineIntersect: lineLineIntersect,
	Group: Group,
	Image: ZImage,
	Text: Text,
	Circle: Circle,
	Sector: Sector,
	Ring: Ring,
	Polygon: Polygon,
	Polyline: Polyline,
	Rect: Rect,
	Line: Line,
	BezierCurve: BezierCurve,
	Arc: Arc,
	IncrementalDisplayable: IncrementalDisplayble,
	CompoundPath: CompoundPath,
	LinearGradient: LinearGradient,
	RadialGradient: RadialGradient,
	BoundingRect: BoundingRect
});

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var PATH_COLOR = ['textStyle', 'color'];

var textStyleMixin = {
    /**
     * Get color property or get color from option.textStyle.color
     * @param {boolean} [isEmphasis]
     * @return {string}
     */
    getTextColor: function (isEmphasis) {
        var ecModel = this.ecModel;
        return this.getShallow('color')
            || (
                (!isEmphasis && ecModel) ? ecModel.get(PATH_COLOR) : null
            );
    },

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

    getTextRect: function (text) {
        return getBoundingRect(
            text,
            this.getFont(),
            this.getShallow('align'),
            this.getShallow('verticalAlign') || this.getShallow('baseline'),
            this.getShallow('padding'),
            this.getShallow('lineHeight'),
            this.getShallow('rich'),
            this.getShallow('truncateText')
        );
    }
};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var getItemStyle = makeStyleMapper(
    [
        ['fill', 'color'],
        ['stroke', 'borderColor'],
        ['lineWidth', 'borderWidth'],
        ['opacity'],
        ['shadowBlur'],
        ['shadowOffsetX'],
        ['shadowOffsetY'],
        ['shadowColor'],
        ['textPosition'],
        ['textAlign']
    ]
);

var itemStyleMixin = {
    getItemStyle: function (excludes, includes) {
        var style = getItemStyle(this, excludes, includes);
        var lineDash = this.getBorderLineDash();
        lineDash && (style.lineDash = lineDash);
        return style;
    },

    getBorderLineDash: function () {
        var lineType = this.get('borderType');
        return (lineType === 'solid' || lineType == null) ? null
            : (lineType === 'dashed' ? [5, 5] : [1, 1]);
    }
};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

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

var mixin$1 = mixin;
var inner = makeInner();

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

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

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

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

Model.prototype = {

    constructor: Model,

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

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

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

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

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

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

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

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

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

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

    restoreData: function () {},

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

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

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

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

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

};

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

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

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

mixin$1(Model, lineStyleMixin);
mixin$1(Model, areaStyleMixin);
mixin$1(Model, textStyleMixin);
mixin$1(Model, itemStyleMixin);

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var base = 0;

/**
 * @public
 * @param {string} type
 * @return {string}
 */
function getUID(type) {
    // Considering the case of crossing js context,
    // use Math.random to make id as unique as possible.
    return [(type || ''), base++, Math.random().toFixed(5)].join('_');
}

/**
 * @inner
 */
function enableSubTypeDefaulter(entity) {

    var subTypeDefaulters = {};

    entity.registerSubTypeDefaulter = function (componentType, defaulter) {
        componentType = parseClassType$1(componentType);
        subTypeDefaulters[componentType.main] = defaulter;
    };

    entity.determineSubType = function (componentType, option) {
        var type = option.type;
        if (!type) {
            var componentTypeMain = parseClassType$1(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.
 *
 */
function enableTopologicalTravel(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 = {};
        each$1(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];
            }
            each$1(
                currVertex.successor,
                isInTargetNameSet ? removeEdgeAndAdd : removeEdge
            );
        }

        each$1(targetNameSet, function () {
            throw new Error('Circle dependency may exists');
        });

        function removeEdge(succComponentType) {
            graph[succComponentType].entryCount--;
            if (graph[succComponentType].entryCount === 0) {
                stack.push(succComponentType);
            }
        }

        // Consider this case: legend depends on series, and we call
        // chart.setOption({series: [...]}), where only series is in option.
        // If we do not have 'removeEdgeAndAdd', legendModel.mergeOption will
        // not be called, but only sereis.mergeOption is called. Thus legend
        // have no chance to update its local record about series (like which
        // name of series is available in legend).
        function removeEdgeAndAdd(succComponentType) {
            targetNameSet[succComponentType] = true;
            removeEdge(succComponentType);
        }
    };

    /**
     * DepndencyGraph: {Object}
     * key: conponentType,
     * value: {
     *     successor: [conponentTypes...],
     *     originalDeps: [conponentTypes...],
     *     entryCount: {number}
     * }
     */
    function makeDepndencyGraph(fullNameList) {
        var graph = {};
        var noEntryList = [];

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

            each$1(availableDeps, function (dependentName) {
                if (indexOf(thisItem.predecessor, dependentName) < 0) {
                    thisItem.predecessor.push(dependentName);
                }
                var thatItem = createDependencyGraphItem(graph, dependentName);
                if (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 = [];
        each$1(originalDeps, function (dep) {
            indexOf(fullNameList, dep) >= 0 && availableDeps.push(dep);
        });
        return availableDeps;
    }
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/*
* A third-party license is embeded for some of the code in this file:
* The method "quantile" was copied from "d3.js".
* (See more details in the comment of the method below.)
* The use of the source code of this file is also subject to the terms
* and consitions of the license of "d3.js" (BSD-3Clause, see
* </licenses/LICENSE-d3>).
*/

var RADIAN_EPSILON = 1e-4;

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

/**
 * 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>}
 */
function linearMap(val, domain, range, clamp) {
    var subDomain = domain[1] - domain[0];
    var subRange = range[1] - range[0];

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

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

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

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

        return parseFloat(percent);
    }

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

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

/**
 * asc sort arr.
 * The input arr will be modified.
 *
 * @param {Array} arr
 * @return {Array} The input arr.
 */
function asc(arr) {
    arr.sort(function (a, b) {
        return a - b;
    });
    return arr;
}

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

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

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

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

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

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

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

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

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

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

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

    return seats[idx] / digits;
}

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

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

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

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

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

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

        // Use local time when no timezone offset specifed.
        if (!match[8]) {
            // match[n] can only be string or undefined.
            // But take care of '12' + 1 => '121'.
            return new Date(
                +match[1],
                +(match[2] || 1) - 1,
                +match[3] || 1,
                +match[4] || 0,
                +(match[5] || 0),
                +match[6] || 0,
                +match[7] || 0
            );
        }
        // Timezoneoffset of Javascript Date has considered DST (Daylight Saving Time,
        // https://tc39.github.io/ecma262/#sec-daylight-saving-time-adjustment).
        // For example, system timezone is set as "Time Zone: America/Toronto",
        // then these code will get different result:
        // `new Date(1478411999999).getTimezoneOffset();  // get 240`
        // `new Date(1478412000000).getTimezoneOffset();  // get 300`
        // So we should not use `new Date`, but use `Date.UTC`.
        else {
            var hour = +match[4] || 0;
            if (match[8].toUpperCase() !== 'Z') {
                hour -= match[8].slice(0, 3);
            }
            return new Date(Date.UTC(
                +match[1],
                +(match[2] || 1) - 1,
                +match[3] || 1,
                hour,
                +(match[5] || 0),
                +match[6] || 0,
                +match[7] || 0
            ));
        }
    }
    else if (value == null) {
        return new Date(NaN);
    }

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

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

/**
 * Exponent of the quantity of a number
 * e.g., 1234 equals to 1.234*10^3, so quantityExponent(1234) is 3
 *
 * @param  {number} val non-negative value
 * @return {number}
 */
function quantityExponent(val) {
    if (val === 0) {
        return 0;
    }

    var exp = Math.floor(Math.log(val) / Math.LN10);
    /**
     * exp is expected to be the rounded-down result of the base-10 log of val.
     * But due to the precision loss with Math.log(val), we need to restore it
     * using 10^exp to make sure we can get val back from exp. #11249
     */
    if (val / Math.pow(10, exp) >= 10) {
        exp++;
    }
    return exp;
}

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

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

/**
 * This code was copied from "d3.js"
 * <https://github.com/d3/d3/blob/9cc9a875e636a1dcf36cc1e07bdf77e1ad6e2c74/src/arrays/quantile.js>.
 * See the license statement at the head of this file.
 * @param {Array.<number>} ascArr
 */
function quantile(ascArr, p) {
    var H = (ascArr.length - 1) * p + 1;
    var h = Math.floor(H);
    var v = +ascArr[h - 1];
    var e = H - h;
    return e ? v + e * (ascArr[h] - v) : v;
}

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

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

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

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

    return list;

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

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


var number = (Object.freeze || Object)({
	linearMap: linearMap,
	parsePercent: parsePercent$1,
	round: round$1,
	asc: asc,
	getPrecision: getPrecision,
	getPrecisionSafe: getPrecisionSafe,
	getPixelPrecision: getPixelPrecision,
	getPercentWithPrecision: getPercentWithPrecision,
	MAX_SAFE_INTEGER: MAX_SAFE_INTEGER,
	remRadian: remRadian,
	isRadianAroundZero: isRadianAroundZero,
	parseDate: parseDate,
	quantity: quantity,
	quantityExponent: quantityExponent,
	nice: nice,
	quantile: quantile,
	reformIntervals: reformIntervals,
	isNumeric: isNumeric
});

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

// import Text from 'zrender/src/graphic/Text';

/**
 * add commas after every three numbers
 * @param {string|number} x
 * @return {string}
 */
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
 * @param {boolean} [upperCaseFirst=false]
 * @return {string} str
 */
function toCamelCase(str, upperCaseFirst) {
    str = (str || '').toLowerCase().replace(/-(.)/g, function (match, group1) {
        return group1.toUpperCase();
    });

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

    return str;
}

var normalizeCssArray$1 = normalizeCssArray;


var replaceReg = /([&<>"'])/g;
var replaceMap = {
    '&': '&amp;',
    '<': '&lt;',
    '>': '&gt;',
    '"': '&quot;',
    '\'': '&#39;'
};

function encodeHTML(source) {
    return source == null
        ? ''
        : (source + '').replace(replaceReg, function (str, c) {
            return replaceMap[c];
        });
}

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

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

/**
 * Template formatter
 * @param {string} tpl
 * @param {Array.<Object>|Object} paramsList
 * @param {boolean} [encode=false]
 * @return {string}
 */
function formatTpl(tpl, paramsList, encode) {
    if (!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++) {
            var val = paramsList[seriesIdx][$vars[k]];
            tpl = tpl.replace(
                wrapVar(TPL_VAR_ALIAS[k], seriesIdx),
                encode ? encodeHTML(val) : val
            );
        }
    }

    return tpl;
}

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

/**
 * @param {Object|string} [opt] If string, means color.
 * @param {string} [opt.color]
 * @param {string} [opt.extraCssText]
 * @param {string} [opt.type='item'] 'item' or 'subItem'
 * @param {string} [opt.renderMode='html'] render mode of tooltip, 'html' or 'richText'
 * @param {string} [opt.markerId='X'] id name for marker. If only one marker is in a rich text, this can be omitted.
 * @return {string}
 */
function getTooltipMarker(opt, extraCssText) {
    opt = isString(opt) ? {color: opt, extraCssText: extraCssText} : (opt || {});
    var color = opt.color;
    var type = opt.type;
    var extraCssText = opt.extraCssText;
    var renderMode = opt.renderMode || 'html';
    var markerId = opt.markerId || 'X';

    if (!color) {
        return '';
    }

    if (renderMode === 'html') {
        return type === 'subItem'
        ? '<span style="display:inline-block;vertical-align:middle;margin-right:8px;margin-left:3px;'
            + 'border-radius:4px;width:4px;height:4px;background-color:'
            + encodeHTML(color) + ';' + (extraCssText || '') + '"></span>'
        : '<span style="display:inline-block;margin-right:5px;'
            + 'border-radius:10px;width:10px;height:10px;background-color:'
            + encodeHTML(color) + ';' + (extraCssText || '') + '"></span>';
    }
    else {
        // Space for rich element marker
        return {
            renderMode: renderMode,
            content: '{marker' + markerId + '|}  ',
            style: {
                color: color
            }
        };
    }
}

function pad(str, len) {
    str += '';
    return '0000'.substr(0, len - str.length) + str;
}


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

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

    tpl = tpl.replace('MM', pad(M, 2))
        .replace('M', M)
        .replace('yyyy', y)
        .replace('yy', y % 100)
        .replace('dd', pad(d, 2))
        .replace('d', d)
        .replace('hh', pad(h, 2))
        .replace('h', h)
        .replace('mm', pad(m, 2))
        .replace('m', m)
        .replace('ss', pad(s, 2))
        .replace('s', s)
        .replace('SSS', pad(S, 3));

    return tpl;
}

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

var truncateText$1 = truncateText;

/**
 * @public
 * @param {Object} opt
 * @param {string} opt.text
 * @param {string} opt.font
 * @param {string} [opt.textAlign='left']
 * @param {string} [opt.textVerticalAlign='top']
 * @param {Array.<number>} [opt.textPadding]
 * @param {number} [opt.textLineHeight]
 * @param {Object} [opt.rich]
 * @param {Object} [opt.truncate]
 * @return {Object} {x, y, width, height, lineHeight}
 */
function getTextBoundingRect(opt) {
    return getBoundingRect(
        opt.text,
        opt.font,
        opt.textAlign,
        opt.textVerticalAlign,
        opt.textPadding,
        opt.textLineHeight,
        opt.rich,
        opt.truncate
    );
}

/**
 * @deprecated
 * the `textLineHeight` was added later.
 * For backward compatiblility, put it as the last parameter.
 * But deprecated this interface. Please use `getTextBoundingRect` instead.
 */
function getTextRect(
    text, font, textAlign, textVerticalAlign, textPadding, rich, truncate, textLineHeight
) {
    return getBoundingRect(
        text, font, textAlign, textVerticalAlign, textPadding, textLineHeight, rich, truncate
    );
}

/**
 * open new tab
 * @param {string} link url
 * @param {string} target blank or self
 */
function windowOpen(link, target) {
    if (target === '_blank' || target === 'blank') {
        var blank = window.open();
        blank.opener = null;
        blank.location = link;
    }
    else {
        window.open(link, target);
    }
}


var format = (Object.freeze || Object)({
	addCommas: addCommas,
	toCamelCase: toCamelCase,
	normalizeCssArray: normalizeCssArray$1,
	encodeHTML: encodeHTML,
	formatTpl: formatTpl,
	formatTplSimple: formatTplSimple,
	getTooltipMarker: getTooltipMarker,
	formatTime: formatTime,
	capitalFirst: capitalFirst,
	truncateText: truncateText$1,
	getTextBoundingRect: getTextBoundingRect,
	getTextRect: getTextRect,
	windowOpen: windowOpen
});

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

// Layout helpers for each component positioning

var each$3 = each$1;

/**
 * @public
 */
var LOCATION_PARAMS = [
    'left', 'right', 'top', 'bottom', 'width', 'height'
];

/**
 * @public
 */
var HV_NAMES = [
    ['width', 'left', 'right'],
    ['height', 'top', 'bottom']
];

function boxLayout(orient, group, gap, maxWidth, maxHeight) {
    var x = 0;
    var y = 0;

    if (maxWidth == null) {
        maxWidth = Infinity;
    }
    if (maxHeight == null) {
        maxHeight = Infinity;
    }
    var currentLineMaxSize = 0;

    group.eachChild(function (child, idx) {
        var position = child.position;
        var rect = child.getBoundingRect();
        var nextChild = group.childAt(idx + 1);
        var nextChildRect = nextChild && nextChild.getBoundingRect();
        var nextX;
        var nextY;

        if (orient === 'horizontal') {
            var moveX = rect.width + (nextChildRect ? (-nextChildRect.x + rect.x) : 0);
            nextX = x + moveX;
            // Wrap when width exceeds maxWidth or meet a `newline` group
            // FIXME compare before adding gap?
            if (nextX > maxWidth || child.newline) {
                x = 0;
                nextX = moveX;
                y += currentLineMaxSize + gap;
                currentLineMaxSize = rect.height;
            }
            else {
                // FIXME: consider rect.y is not `0`?
                currentLineMaxSize = Math.max(currentLineMaxSize, rect.height);
            }
        }
        else {
            var moveY = rect.height + (nextChildRect ? (-nextChildRect.y + rect.y) : 0);
            nextY = y + moveY;
            // Wrap when width exceeds maxHeight or meet a `newline` group
            if (nextY > maxHeight || child.newline) {
                x += currentLineMaxSize + gap;
                y = 0;
                nextY = moveY;
                currentLineMaxSize = rect.width;
            }
            else {
                currentLineMaxSize = Math.max(currentLineMaxSize, rect.width);
            }
        }

        if (child.newline) {
            return;
        }

        position[0] = x;
        position[1] = y;

        orient === 'horizontal'
            ? (x = nextX + gap)
            : (y = nextY + gap);
    });
}

/**
 * VBox or HBox layouting
 * @param {string} orient
 * @param {module:zrender/container/Group} group
 * @param {number} gap
 * @param {number} [width=Infinity]
 * @param {number} [height=Infinity]
 */
var box = boxLayout;

/**
 * VBox layouting
 * @param {module:zrender/container/Group} group
 * @param {number} gap
 * @param {number} [width=Infinity]
 * @param {number} [height=Infinity]
 */
var vbox = curry(boxLayout, 'vertical');

/**
 * HBox layouting
 * @param {module:zrender/container/Group} group
 * @param {number} gap
 * @param {number} [width=Infinity]
 * @param {number} [height=Infinity]
 */
var hbox = 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 {width, height}
 * @param {string|number} margin
 * @return {Object} {width, height}
 */


/**
 * 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}
 */
function getLayoutRect(
    positionInfo, containerRect, margin
) {
    margin = normalizeCssArray$1(margin || 0);

    var containerWidth = containerRect.width;
    var containerHeight = containerRect.height;

    var left = parsePercent$1(positionInfo.left, containerWidth);
    var top = parsePercent$1(positionInfo.top, containerHeight);
    var right = parsePercent$1(positionInfo.right, containerWidth);
    var bottom = parsePercent$1(positionInfo.bottom, containerHeight);
    var width = parsePercent$1(positionInfo.width, containerWidth);
    var height = parsePercent$1(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 (aspect != null) {
        // 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
        // FIXME
        // Margin is not considered, because there is no case that both
        // using margin and aspect so far.
        if (isNaN(width) && isNaN(height)) {
            if (aspect > containerWidth / containerHeight) {
                width = containerWidth * 0.8;
            }
            else {
                height = containerHeight * 0.8;
            }
        }

        // Calculate width or height with given aspect
        if (isNaN(width)) {
            width = aspect * height;
        }
        if (isNaN(height)) {
            height = width / aspect;
        }
    }

    // If left is not specified, calculate left from right and width
    if (isNaN(left)) {
        left = containerWidth - right - width - horizontalMargin;
    }
    if (isNaN(top)) {
        top = containerHeight - bottom - height - verticalMargin;
    }

    // Align left and top
    switch (positionInfo.left || positionInfo.right) {
        case 'center':
            left = containerWidth / 2 - width / 2 - margin[3];
            break;
        case 'right':
            left = containerWidth - width - horizontalMargin;
            break;
    }
    switch (positionInfo.top || positionInfo.bottom) {
        case 'middle':
        case 'center':
            top = containerHeight / 2 - height / 2 - margin[0];
            break;
        case 'bottom':
            top = containerHeight - height - verticalMargin;
            break;
    }
    // If something is wrong and left, top, width, height are calculated as NaN
    left = left || 0;
    top = top || 0;
    if (isNaN(width)) {
        // Width may be NaN if only one value is given except width
        width = containerWidth - horizontalMargin - left - (right || 0);
    }
    if (isNaN(height)) {
        // Height may be NaN if only one value is given except height
        height = containerHeight - verticalMargin - top - (bottom || 0);
    }

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


/**
 * Position a zr element in viewport
 *  Group position is specified by either
 *  {left, top}, {right, bottom}
 *  If all properties exists, right and bottom will be igonred.
 *
 * Logic:
 *     1. Scale (against origin point in parent coord)
 *     2. Rotate (against origin point in parent coord)
 *     3. Traslate (with el.position by this method)
 * So this method only fixes the last step 'Traslate', which does not affect
 * scaling and rotating.
 *
 * If be called repeatly with the same input el, the same result will be gotten.
 *
 * @param {module:zrender/Element} el Should have `getBoundingRect` method.
 * @param {Object} positionInfo
 * @param {number|string} [positionInfo.left]
 * @param {number|string} [positionInfo.top]
 * @param {number|string} [positionInfo.right]
 * @param {number|string} [positionInfo.bottom]
 * @param {number|string} [positionInfo.width] Only for opt.boundingModel: 'raw'
 * @param {number|string} [positionInfo.height] Only for opt.boundingModel: 'raw'
 * @param {Object} containerRect
 * @param {string|number} margin
 * @param {Object} [opt]
 * @param {Array.<number>} [opt.hv=[1,1]] Only horizontal or only vertical.
 * @param {Array.<number>} [opt.boundingMode='all']
 *        Specify how to calculate boundingRect when locating.
 *        'all': Position the boundingRect that is transformed and uioned
 *               both itself and its descendants.
 *               This mode simplies confine the elements in the bounding
 *               of their container (e.g., using 'right: 0').
 *        'raw': Position the boundingRect that is not transformed and only itself.
 *               This mode is useful when you want a element can overflow its
 *               container. (Consider a rotated circle needs to be located in a corner.)
 *               In this mode positionInfo.width/height can only be number.
 */
function positionElement(el, positionInfo, containerRect, margin, opt) {
    var h = !opt || !opt.hv || opt.hv[0];
    var v = !opt || !opt.hv || opt.hv[1];
    var boundingMode = opt && opt.boundingMode || 'all';

    if (!h && !v) {
        return;
    }

    var rect;
    if (boundingMode === 'raw') {
        rect = el.type === 'group'
            ? new BoundingRect(0, 0, +positionInfo.width || 0, +positionInfo.height || 0)
            : el.getBoundingRect();
    }
    else {
        rect = el.getBoundingRect();
        if (el.needLocalTransform()) {
            var transform = el.getLocalTransform();
            // Notice: raw rect may be inner object of el,
            // which should not be modified.
            rect = rect.clone();
            rect.applyTransform(transform);
        }
    }

    // The real width and height can not be specified but calculated by the given el.
    positionInfo = getLayoutRect(
        defaults(
            {width: rect.width, height: rect.height},
            positionInfo
        ),
        containerRect,
        margin
    );

    // Because 'tranlate' is the last step in transform
    // (see zrender/core/Transformable#getLocalTransform),
    // we can just only modify el.position to get final result.
    var elPos = el.position;
    var dx = h ? positionInfo.x - rect.x : 0;
    var dy = v ? positionInfo.y - rect.y : 0;

    el.attr('position', boundingMode === 'raw' ? [dx, dy] : [elPos[0] + dx, elPos[1] + dy]);
}

/**
 * @param {Object} option Contains some of the properties in HV_NAMES.
 * @param {number} hvIdx 0: horizontal; 1: vertical.
 */


/**
 * Consider Case:
 * When defulat option has {left: 0, width: 100}, and we set {right: 0}
 * through setOption or media query, using normal zrUtil.merge will cause
 * {right: 0} does not take effect.
 *
 * @example
 * ComponentModel.extend({
 *     init: function () {
 *         ...
 *         var inputPositionParams = layout.getLayoutParams(option);
 *         this.mergeOption(inputPositionParams);
 *     },
 *     mergeOption: function (newOption) {
 *         newOption && zrUtil.merge(thisOption, newOption, true);
 *         layout.mergeLayoutParam(thisOption, newOption);
 *     }
 * });
 *
 * @param {Object} targetOption
 * @param {Object} newOption
 * @param {Object|string} [opt]
 * @param {boolean|Array.<boolean>} [opt.ignoreSize=false] Used for the components
 *  that width (or height) should not be calculated by left and right (or top and bottom).
 */
function mergeLayoutParam(targetOption, newOption, opt) {
    !isObject$1(opt) && (opt = {});

    var ignoreSize = opt.ignoreSize;
    !isArray(ignoreSize) && (ignoreSize = [ignoreSize, ignoreSize]);

    var hResult = merge$$1(HV_NAMES[0], 0);
    var vResult = merge$$1(HV_NAMES[1], 1);

    copy(HV_NAMES[0], targetOption, hResult);
    copy(HV_NAMES[1], targetOption, vResult);

    function merge$$1(names, hvIdx) {
        var newParams = {};
        var newValueCount = 0;
        var merged = {};
        var mergedValueCount = 0;
        var enoughParamNumber = 2;

        each$3(names, function (name) {
            merged[name] = targetOption[name];
        });
        each$3(names, function (name) {
            // Consider case: newOption.width is null, which is
            // set by user for removing width setting.
            hasProp(newOption, name) && (newParams[name] = merged[name] = newOption[name]);
            hasValue(newParams, name) && newValueCount++;
            hasValue(merged, name) && mergedValueCount++;
        });

        if (ignoreSize[hvIdx]) {
            // Only one of left/right is premitted to exist.
            if (hasValue(newOption, names[1])) {
                merged[names[2]] = null;
            }
            else if (hasValue(newOption, names[2])) {
                merged[names[1]] = null;
            }
            return merged;
        }

        // Case: newOption: {width: ..., right: ...},
        // or targetOption: {right: ...} and newOption: {width: ...},
        // There is no conflict when merged only has params count
        // little than enoughParamNumber.
        if (mergedValueCount === enoughParamNumber || !newValueCount) {
            return merged;
        }
        // Case: newOption: {width: ..., right: ...},
        // Than we can make sure user only want those two, and ignore
        // all origin params in targetOption.
        else if (newValueCount >= enoughParamNumber) {
            return newParams;
        }
        else {
            // Chose another param from targetOption by priority.
            for (var i = 0; i < names.length; i++) {
                var name = names[i];
                if (!hasProp(newParams, name) && hasProp(targetOption, name)) {
                    newParams[name] = targetOption[name];
                    break;
                }
            }
            return newParams;
        }
    }

    function hasProp(obj, name) {
        return obj.hasOwnProperty(name);
    }

    function hasValue(obj, name) {
        return obj[name] != null && obj[name] !== 'auto';
    }

    function copy(names, target, source) {
        each$3(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.
 */
function getLayoutParams(source) {
    return copyLayoutParams({}, source);
}

/**
 * Retrieve 'left', 'right', 'top', 'bottom', 'width', 'height' from object.
 * @param {Object} source
 * @return {Object} Result contains those props.
 */
function copyLayoutParams(target, source) {
    source && target && each$3(LOCATION_PARAMS, function (name) {
        source.hasOwnProperty(name) && (target[name] = source[name]);
    });
    return target;
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/


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

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * Component model
 *
 * @module echarts/model/Component
 */

var inner$1 = makeInner();

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

    /**
     * Because simplified concept is probably better, series.name (or component.name)
     * has been having too many resposibilities:
     * (1) Generating id (which requires name in option should not be modified).
     * (2) As an index to mapping series when merging option or calling API (a name
     * can refer to more then one components, which is convinient is some case).
     * (3) Display.
     * @readOnly
     */
    name: '',

    /**
     * @readOnly
     * @type {string}
     */
    mainType: '',

    /**
     * @readOnly
     * @type {string}
     */
    subType: '',

    /**
     * @readOnly
     * @type {number}
     */
    componentIndex: 0,

    /**
     * @type {Object}
     * @protected
     */
    defaultOption: null,

    /**
     * @type {module:echarts/model/Global}
     * @readOnly
     */
    ecModel: null,

    /**
     * key: componentType
     * value:  Component model list, can not be null.
     * @type {Object.<string, Array.<module:echarts/model/Model>>}
     * @readOnly
     */
    dependentModels: [],

    /**
     * @type {string}
     * @readOnly
     */
    uid: null,

    /**
     * Support merge layout params.
     * Only support 'box' now (left/right/top/bottom/width/height).
     * @type {string|Object} Object can be {ignoreSize: true}
     * @readOnly
     */
    layoutMode: null,

    $constructor: function (option, parentModel, ecModel, extraOpt) {
        Model.call(this, option, parentModel, ecModel, extraOpt);

        this.uid = getUID('ec_cpt_model');
    },

    init: function (option, parentModel, ecModel, extraOpt) {
        this.mergeDefaultAndTheme(option, ecModel);
    },

    mergeDefaultAndTheme: function (option, ecModel) {
        var layoutMode = this.layoutMode;
        var inputPositionParams = layoutMode
            ? getLayoutParams(option) : {};

        var themeModel = ecModel.getTheme();
        merge(option, themeModel.get(this.mainType));
        merge(option, this.getDefaultOption());

        if (layoutMode) {
            mergeLayoutParam(option, inputPositionParams, layoutMode);
        }
    },

    mergeOption: function (option, extraOpt) {
        merge(this.option, option, true);

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

    // Hooker after init or mergeOption
    optionUpdated: function (newCptOption, isInit) {},

    getDefaultOption: function () {
        var fields = inner$1(this);
        if (!fields.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 = merge(defaultOption, optList[i], true);
            }
            fields.defaultOption = defaultOption;
        }
        return fields.defaultOption;
    },

    getReferringComponents: function (mainType) {
        return this.ecModel.queryComponents({
            mainType: mainType,
            index: this.get(mainType + 'Index', true),
            id: this.get(mainType + 'Id', true)
        });
    }

});

// Reset ComponentModel.extend, add preConstruct.
// clazzUtil.enableClassExtend(
//     ComponentModel,
//     function (option, parentModel, ecModel, extraOpt) {
//         // Set dependentModels, componentIndex, name, id, mainType, subType.
//         zrUtil.extend(this, extraOpt);

//         this.uid = componentUtil.getUID('componentModel');

//         // this.setReadOnly([
//         //     'type', 'id', 'uid', 'name', 'mainType', 'subType',
//         //     'dependentModels', 'componentIndex'
//         // ]);
//     }
// );

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

// Add capability of ComponentModel.topologicalTravel.
enableTopologicalTravel(ComponentModel, getDependencies);

function getDependencies(componentType) {
    var deps = [];
    each$1(ComponentModel.getClassesByMainType(componentType), function (Clazz) {
        deps = deps.concat(Clazz.prototype.dependencies || []);
    });

    // Ensure main type.
    deps = map(deps, function (type) {
        return parseClassType$1(type).main;
    });

    // Hack dataset for convenience.
    if (componentType !== 'dataset' && indexOf(deps, 'dataset') <= 0) {
        deps.unshift('dataset');
    }

    return deps;
}

mixin(ComponentModel, boxLayoutMixin);

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/


var platform = '';
// Navigator not exists in node
if (typeof navigator !== 'undefined') {
    platform = navigator.platform || '';
}

var globalDefault = {
    // backgroundColor: 'rgba(0,0,0,0)',

    // https://dribbble.com/shots/1065960-Infographic-Pie-chart-visualization
    // color: ['#5793f3', '#d14a61', '#fd9c35', '#675bba', '#fec42c', '#dd4444', '#d4df5a', '#cd4870'],
    // Light colors:
    // color: ['#bcd3bb', '#e88f70', '#edc1a5', '#9dc5c8', '#e1e8c8', '#7b7c68', '#e5b5b5', '#f0b489', '#928ea8', '#bda29a'],
    // color: ['#cc5664', '#9bd6ec', '#ea946e', '#8acaaa', '#f1ec64', '#ee8686', '#a48dc1', '#5da6bc', '#b9dcae'],
    // Dark colors:
    color: [
        '#c23531', '#2f4554', '#61a0a8', '#d48265', '#91c7ae', '#749f83',
        '#ca8622', '#bda29a', '#6e7074', '#546570', '#c4ccd3'
    ],

    gradientColor: ['#f6efa6', '#d88273', '#bf444c'],

    // If xAxis and yAxis declared, grid is created by default.
    // grid: {},

    textStyle: {
        // color: '#000',
        // decoration: 'none',
        // PENDING
        fontFamily: platform.match(/^Win/) ? 'Microsoft YaHei' : 'sans-serif',
        // fontFamily: 'Arial, Verdana, sans-serif',
        fontSize: 12,
        fontStyle: 'normal',
        fontWeight: 'normal'
    },

    // http://blogs.adobe.com/webplatform/2014/02/24/using-blend-modes-in-html-canvas/
    // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation
    // Default is source-over
    blendMode: null,

    animation: 'auto',
    animationDuration: 1000,
    animationDurationUpdate: 300,
    animationEasing: 'exponentialOut',
    animationEasingUpdate: 'cubicOut',

    animationThreshold: 2000,
    // Configuration for progressive/incremental rendering
    progressiveThreshold: 3000,
    progressive: 400,

    // Threshold of if use single hover layer to optimize.
    // It is recommended that `hoverLayerThreshold` is equivalent to or less than
    // `progressiveThreshold`, otherwise hover will cause restart of progressive,
    // which is unexpected.
    // see example <echarts/test/heatmap-large.html>.
    hoverLayerThreshold: 3000,

    // See: module:echarts/scale/Time
    useUTC: false
};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var inner$2 = makeInner();

function getNearestColorPalette(colors, requestColorNum) {
    var paletteNum = colors.length;
    // TODO colors must be in order
    for (var i = 0; i < paletteNum; i++) {
        if (colors[i].length > requestColorNum) {
            return colors[i];
        }
    }
    return colors[paletteNum - 1];
}

var colorPaletteMixin = {
    clearColorPalette: function () {
        inner$2(this).colorIdx = 0;
        inner$2(this).colorNameMap = {};
    },

    /**
     * @param {string} name MUST NOT be null/undefined. Otherwise call this function
     *                 twise with the same parameters will get different result.
     * @param {Object} [scope=this]
     * @param {Object} [requestColorNum]
     * @return {string} color string.
     */
    getColorFromPalette: function (name, scope, requestColorNum) {
        scope = scope || this;
        var scopeFields = inner$2(scope);
        var colorIdx = scopeFields.colorIdx || 0;
        var colorNameMap = scopeFields.colorNameMap = scopeFields.colorNameMap || {};
        // Use `hasOwnProperty` to avoid conflict with Object.prototype.
        if (colorNameMap.hasOwnProperty(name)) {
            return colorNameMap[name];
        }
        var defaultColorPalette = normalizeToArray(this.get('color', true));
        var layeredColorPalette = this.get('colorLayer', true);
        var colorPalette = ((requestColorNum == null || !layeredColorPalette)
            ? defaultColorPalette : getNearestColorPalette(layeredColorPalette, requestColorNum));

        // In case can't find in layered color palette.
        colorPalette = colorPalette || defaultColorPalette;

        if (!colorPalette || !colorPalette.length) {
            return;
        }

        var color = colorPalette[colorIdx];
        if (name) {
            colorNameMap[name] = color;
        }
        scopeFields.colorIdx = (colorIdx + 1) % colorPalette.length;

        return color;
    }
};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

// Avoid typo.
var SOURCE_FORMAT_ORIGINAL = 'original';
var SOURCE_FORMAT_ARRAY_ROWS = 'arrayRows';
var SOURCE_FORMAT_OBJECT_ROWS = 'objectRows';
var SOURCE_FORMAT_KEYED_COLUMNS = 'keyedColumns';
var SOURCE_FORMAT_UNKNOWN = 'unknown';
// ??? CHANGE A NAME
var SOURCE_FORMAT_TYPED_ARRAY = 'typedArray';

var SERIES_LAYOUT_BY_COLUMN = 'column';
var SERIES_LAYOUT_BY_ROW = 'row';

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * [sourceFormat]
 *
 * + "original":
 * This format is only used in series.data, where
 * itemStyle can be specified in data item.
 *
 * + "arrayRows":
 * [
 *     ['product', 'score', 'amount'],
 *     ['Matcha Latte', 89.3, 95.8],
 *     ['Milk Tea', 92.1, 89.4],
 *     ['Cheese Cocoa', 94.4, 91.2],
 *     ['Walnut Brownie', 85.4, 76.9]
 * ]
 *
 * + "objectRows":
 * [
 *     {product: 'Matcha Latte', score: 89.3, amount: 95.8},
 *     {product: 'Milk Tea', score: 92.1, amount: 89.4},
 *     {product: 'Cheese Cocoa', score: 94.4, amount: 91.2},
 *     {product: 'Walnut Brownie', score: 85.4, amount: 76.9}
 * ]
 *
 * + "keyedColumns":
 * {
 *     'product': ['Matcha Latte', 'Milk Tea', 'Cheese Cocoa', 'Walnut Brownie'],
 *     'count': [823, 235, 1042, 988],
 *     'score': [95.8, 81.4, 91.2, 76.9]
 * }
 *
 * + "typedArray"
 *
 * + "unknown"
 */

/**
 * @constructor
 * @param {Object} fields
 * @param {string} fields.sourceFormat
 * @param {Array|Object} fields.fromDataset
 * @param {Array|Object} [fields.data]
 * @param {string} [seriesLayoutBy='column']
 * @param {Array.<Object|string>} [dimensionsDefine]
 * @param {Objet|HashMap} [encodeDefine]
 * @param {number} [startIndex=0]
 * @param {number} [dimensionsDetectCount]
 */
function Source(fields) {

    /**
     * @type {boolean}
     */
    this.fromDataset = fields.fromDataset;

    /**
     * Not null/undefined.
     * @type {Array|Object}
     */
    this.data = fields.data || (
        fields.sourceFormat === SOURCE_FORMAT_KEYED_COLUMNS ? {} : []
    );

    /**
     * See also "detectSourceFormat".
     * Not null/undefined.
     * @type {string}
     */
    this.sourceFormat = fields.sourceFormat || SOURCE_FORMAT_UNKNOWN;

    /**
     * 'row' or 'column'
     * Not null/undefined.
     * @type {string} seriesLayoutBy
     */
    this.seriesLayoutBy = fields.seriesLayoutBy || SERIES_LAYOUT_BY_COLUMN;

    /**
     * dimensions definition in option.
     * can be null/undefined.
     * @type {Array.<Object|string>}
     */
    this.dimensionsDefine = fields.dimensionsDefine;

    /**
     * encode definition in option.
     * can be null/undefined.
     * @type {Objet|HashMap}
     */
    this.encodeDefine = fields.encodeDefine && createHashMap(fields.encodeDefine);

    /**
     * Not null/undefined, uint.
     * @type {number}
     */
    this.startIndex = fields.startIndex || 0;

    /**
     * Can be null/undefined (when unknown), uint.
     * @type {number}
     */
    this.dimensionsDetectCount = fields.dimensionsDetectCount;
}

/**
 * Wrap original series data for some compatibility cases.
 */
Source.seriesDataToSource = function (data) {
    return new Source({
        data: data,
        sourceFormat: isTypedArray(data)
            ? SOURCE_FORMAT_TYPED_ARRAY
            : SOURCE_FORMAT_ORIGINAL,
        fromDataset: false
    });
};

enableClassCheck(Source);

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

// The result of `guessOrdinal`.
var BE_ORDINAL = {
    Must: 1, // Encounter string but not '-' and not number-like.
    Might: 2, // Encounter string but number-like.
    Not: 3 // Other cases
};

var inner$3 = makeInner();

/**
 * @see {module:echarts/data/Source}
 * @param {module:echarts/component/dataset/DatasetModel} datasetModel
 * @return {string} sourceFormat
 */
function detectSourceFormat(datasetModel) {
    var data = datasetModel.option.source;
    var sourceFormat = SOURCE_FORMAT_UNKNOWN;

    if (isTypedArray(data)) {
        sourceFormat = SOURCE_FORMAT_TYPED_ARRAY;
    }
    else if (isArray(data)) {
        // FIXME Whether tolerate null in top level array?
        if (data.length === 0) {
            sourceFormat = SOURCE_FORMAT_ARRAY_ROWS;
        }

        for (var i = 0, len = data.length; i < len; i++) {
            var item = data[i];

            if (item == null) {
                continue;
            }
            else if (isArray(item)) {
                sourceFormat = SOURCE_FORMAT_ARRAY_ROWS;
                break;
            }
            else if (isObject$1(item)) {
                sourceFormat = SOURCE_FORMAT_OBJECT_ROWS;
                break;
            }
        }
    }
    else if (isObject$1(data)) {
        for (var key in data) {
            if (data.hasOwnProperty(key) && isArrayLike(data[key])) {
                sourceFormat = SOURCE_FORMAT_KEYED_COLUMNS;
                break;
            }
        }
    }
    else if (data != null) {
        throw new Error('Invalid data');
    }

    inner$3(datasetModel).sourceFormat = sourceFormat;
}

/**
 * [Scenarios]:
 * (1) Provide source data directly:
 *     series: {
 *         encode: {...},
 *         dimensions: [...]
 *         seriesLayoutBy: 'row',
 *         data: [[...]]
 *     }
 * (2) Refer to datasetModel.
 *     series: [{
 *         encode: {...}
 *         // Ignore datasetIndex means `datasetIndex: 0`
 *         // and the dimensions defination in dataset is used
 *     }, {
 *         encode: {...},
 *         seriesLayoutBy: 'column',
 *         datasetIndex: 1
 *     }]
 *
 * Get data from series itself or datset.
 * @return {module:echarts/data/Source} source
 */
function getSource(seriesModel) {
    return inner$3(seriesModel).source;
}

/**
 * MUST be called before mergeOption of all series.
 * @param {module:echarts/model/Global} ecModel
 */
function resetSourceDefaulter(ecModel) {
    // `datasetMap` is used to make default encode.
    inner$3(ecModel).datasetMap = createHashMap();
}

/**
 * [Caution]:
 * MUST be called after series option merged and
 * before "series.getInitailData()" called.
 *
 * [The rule of making default encode]:
 * Category axis (if exists) alway map to the first dimension.
 * Each other axis occupies a subsequent dimension.
 *
 * [Why make default encode]:
 * Simplify the typing of encode in option, avoiding the case like that:
 * series: [{encode: {x: 0, y: 1}}, {encode: {x: 0, y: 2}}, {encode: {x: 0, y: 3}}],
 * where the "y" have to be manually typed as "1, 2, 3, ...".
 *
 * @param {module:echarts/model/Series} seriesModel
 */
function prepareSource(seriesModel) {
    var seriesOption = seriesModel.option;

    var data = seriesOption.data;
    var sourceFormat = isTypedArray(data)
        ? SOURCE_FORMAT_TYPED_ARRAY : SOURCE_FORMAT_ORIGINAL;
    var fromDataset = false;

    var seriesLayoutBy = seriesOption.seriesLayoutBy;
    var sourceHeader = seriesOption.sourceHeader;
    var dimensionsDefine = seriesOption.dimensions;

    var datasetModel = getDatasetModel(seriesModel);
    if (datasetModel) {
        var datasetOption = datasetModel.option;

        data = datasetOption.source;
        sourceFormat = inner$3(datasetModel).sourceFormat;
        fromDataset = true;

        // These settings from series has higher priority.
        seriesLayoutBy = seriesLayoutBy || datasetOption.seriesLayoutBy;
        sourceHeader == null && (sourceHeader = datasetOption.sourceHeader);
        dimensionsDefine = dimensionsDefine || datasetOption.dimensions;
    }

    var completeResult = completeBySourceData(
        data, sourceFormat, seriesLayoutBy, sourceHeader, dimensionsDefine
    );

    inner$3(seriesModel).source = new Source({
        data: data,
        fromDataset: fromDataset,
        seriesLayoutBy: seriesLayoutBy,
        sourceFormat: sourceFormat,
        dimensionsDefine: completeResult.dimensionsDefine,
        startIndex: completeResult.startIndex,
        dimensionsDetectCount: completeResult.dimensionsDetectCount,
        // Note: dataset option does not have `encode`.
        encodeDefine: seriesOption.encode
    });
}

// return {startIndex, dimensionsDefine, dimensionsCount}
function completeBySourceData(data, sourceFormat, seriesLayoutBy, sourceHeader, dimensionsDefine) {
    if (!data) {
        return {dimensionsDefine: normalizeDimensionsDefine(dimensionsDefine)};
    }

    var dimensionsDetectCount;
    var startIndex;

    if (sourceFormat === SOURCE_FORMAT_ARRAY_ROWS) {
        // Rule: Most of the first line are string: it is header.
        // Caution: consider a line with 5 string and 1 number,
        // it still can not be sure it is a head, because the
        // 5 string may be 5 values of category columns.
        if (sourceHeader === 'auto' || sourceHeader == null) {
            arrayRowsTravelFirst(function (val) {
                // '-' is regarded as null/undefined.
                if (val != null && val !== '-') {
                    if (isString(val)) {
                        startIndex == null && (startIndex = 1);
                    }
                    else {
                        startIndex = 0;
                    }
                }
            // 10 is an experience number, avoid long loop.
            }, seriesLayoutBy, data, 10);
        }
        else {
            startIndex = sourceHeader ? 1 : 0;
        }

        if (!dimensionsDefine && startIndex === 1) {
            dimensionsDefine = [];
            arrayRowsTravelFirst(function (val, index) {
                dimensionsDefine[index] = val != null ? val : '';
            }, seriesLayoutBy, data);
        }

        dimensionsDetectCount = dimensionsDefine
            ? dimensionsDefine.length
            : seriesLayoutBy === SERIES_LAYOUT_BY_ROW
            ? data.length
            : data[0]
            ? data[0].length
            : null;
    }
    else if (sourceFormat === SOURCE_FORMAT_OBJECT_ROWS) {
        if (!dimensionsDefine) {
            dimensionsDefine = objectRowsCollectDimensions(data);
        }
    }
    else if (sourceFormat === SOURCE_FORMAT_KEYED_COLUMNS) {
        if (!dimensionsDefine) {
            dimensionsDefine = [];
            each$1(data, function (colArr, key) {
                dimensionsDefine.push(key);
            });
        }
    }
    else if (sourceFormat === SOURCE_FORMAT_ORIGINAL) {
        var value0 = getDataItemValue(data[0]);
        dimensionsDetectCount = isArray(value0) && value0.length || 1;
    }
    else if (sourceFormat === SOURCE_FORMAT_TYPED_ARRAY) {
        if (__DEV__) {
            assert$1(!!dimensionsDefine, 'dimensions must be given if data is TypedArray.');
        }
    }

    return {
        startIndex: startIndex,
        dimensionsDefine: normalizeDimensionsDefine(dimensionsDefine),
        dimensionsDetectCount: dimensionsDetectCount
    };
}

// Consider dimensions defined like ['A', 'price', 'B', 'price', 'C', 'price'],
// which is reasonable. But dimension name is duplicated.
// Returns undefined or an array contains only object without null/undefiend or string.
function normalizeDimensionsDefine(dimensionsDefine) {
    if (!dimensionsDefine) {
        // The meaning of null/undefined is different from empty array.
        return;
    }
    var nameMap = createHashMap();
    return map(dimensionsDefine, function (item, index) {
        item = extend({}, isObject$1(item) ? item : {name: item});

        // User can set null in dimensions.
        // We dont auto specify name, othewise a given name may
        // cause it be refered unexpectedly.
        if (item.name == null) {
            return item;
        }

        // Also consider number form like 2012.
        item.name += '';
        // User may also specify displayName.
        // displayName will always exists except user not
        // specified or dim name is not specified or detected.
        // (A auto generated dim name will not be used as
        // displayName).
        if (item.displayName == null) {
            item.displayName = item.name;
        }

        var exist = nameMap.get(item.name);
        if (!exist) {
            nameMap.set(item.name, {count: 1});
        }
        else {
            item.name += '-' + exist.count++;
        }

        return item;
    });
}

function arrayRowsTravelFirst(cb, seriesLayoutBy, data, maxLoop) {
    maxLoop == null && (maxLoop = Infinity);
    if (seriesLayoutBy === SERIES_LAYOUT_BY_ROW) {
        for (var i = 0; i < data.length && i < maxLoop; i++) {
            cb(data[i] ? data[i][0] : null, i);
        }
    }
    else {
        var value0 = data[0] || [];
        for (var i = 0; i < value0.length && i < maxLoop; i++) {
            cb(value0[i], i);
        }
    }
}

function objectRowsCollectDimensions(data) {
    var firstIndex = 0;
    var obj;
    while (firstIndex < data.length && !(obj = data[firstIndex++])) {} // jshint ignore: line
    if (obj) {
        var dimensions = [];
        each$1(obj, function (value, key) {
            dimensions.push(key);
        });
        return dimensions;
    }
}

/**
 * [The strategy of the arrengment of data dimensions for dataset]:
 * "value way": all axes are non-category axes. So series one by one take
 *     several (the number is coordSysDims.length) dimensions from dataset.
 *     The result of data arrengment of data dimensions like:
 *     | ser0_x | ser0_y | ser1_x | ser1_y | ser2_x | ser2_y |
 * "category way": at least one axis is category axis. So the the first data
 *     dimension is always mapped to the first category axis and shared by
 *     all of the series. The other data dimensions are taken by series like
 *     "value way" does.
 *     The result of data arrengment of data dimensions like:
 *     | ser_shared_x | ser0_y | ser1_y | ser2_y |
 *
 * @param {Array.<Object|string>} coordDimensions [{name: <string>, type: <string>, dimsDef: <Array>}, ...]
 * @param {module:model/Series} seriesModel
 * @param {module:data/Source} source
 * @return {Object} encode Never be `null/undefined`.
 */
function makeSeriesEncodeForAxisCoordSys(coordDimensions, seriesModel, source) {
    var encode = {};

    var datasetModel = getDatasetModel(seriesModel);
    // Currently only make default when using dataset, util more reqirements occur.
    if (!datasetModel || !coordDimensions) {
        return encode;
    }

    var encodeItemName = [];
    var encodeSeriesName = [];

    var ecModel = seriesModel.ecModel;
    var datasetMap = inner$3(ecModel).datasetMap;
    var key = datasetModel.uid + '_' + source.seriesLayoutBy;

    var baseCategoryDimIndex;
    var categoryWayValueDimStart;
    coordDimensions = coordDimensions.slice();
    each$1(coordDimensions, function (coordDimInfo, coordDimIdx) {
        !isObject$1(coordDimInfo) && (coordDimensions[coordDimIdx] = {name: coordDimInfo});
        if (coordDimInfo.type === 'ordinal' && baseCategoryDimIndex == null) {
            baseCategoryDimIndex = coordDimIdx;
            categoryWayValueDimStart = getDataDimCountOnCoordDim(coordDimensions[coordDimIdx]);
        }
        encode[coordDimInfo.name] = [];
    });

    var datasetRecord = datasetMap.get(key)
        || datasetMap.set(key, {categoryWayDim: categoryWayValueDimStart, valueWayDim: 0});

    // TODO
    // Auto detect first time axis and do arrangement.
    each$1(coordDimensions, function (coordDimInfo, coordDimIdx) {
        var coordDimName = coordDimInfo.name;
        var count = getDataDimCountOnCoordDim(coordDimInfo);

        // In value way.
        if (baseCategoryDimIndex == null) {
            var start = datasetRecord.valueWayDim;
            pushDim(encode[coordDimName], start, count);
            pushDim(encodeSeriesName, start, count);
            datasetRecord.valueWayDim += count;

            // ??? TODO give a better default series name rule?
            // especially when encode x y specified.
            // consider: when mutiple series share one dimension
            // category axis, series name should better use
            // the other dimsion name. On the other hand, use
            // both dimensions name.
        }
        // In category way, the first category axis.
        else if (baseCategoryDimIndex === coordDimIdx) {
            pushDim(encode[coordDimName], 0, count);
            pushDim(encodeItemName, 0, count);
        }
        // In category way, the other axis.
        else {
            var start = datasetRecord.categoryWayDim;
            pushDim(encode[coordDimName], start, count);
            pushDim(encodeSeriesName, start, count);
            datasetRecord.categoryWayDim += count;
        }
    });

    function pushDim(dimIdxArr, idxFrom, idxCount) {
        for (var i = 0; i < idxCount; i++) {
            dimIdxArr.push(idxFrom + i);
        }
    }

    function getDataDimCountOnCoordDim(coordDimInfo) {
        var dimsDef = coordDimInfo.dimsDef;
        return dimsDef ? dimsDef.length : 1;
    }

    encodeItemName.length && (encode.itemName = encodeItemName);
    encodeSeriesName.length && (encode.seriesName = encodeSeriesName);

    return encode;
}

/**
 * Work for data like [{name: ..., value: ...}, ...].
 *
 * @param {module:model/Series} seriesModel
 * @param {module:data/Source} source
 * @return {Object} encode Never be `null/undefined`.
 */
function makeSeriesEncodeForNameBased(seriesModel, source, dimCount) {
    var encode = {};

    var datasetModel = getDatasetModel(seriesModel);
    // Currently only make default when using dataset, util more reqirements occur.
    if (!datasetModel) {
        return encode;
    }

    var sourceFormat = source.sourceFormat;
    var dimensionsDefine = source.dimensionsDefine;

    var potentialNameDimIndex;
    if (sourceFormat === SOURCE_FORMAT_OBJECT_ROWS || sourceFormat === SOURCE_FORMAT_KEYED_COLUMNS) {
        each$1(dimensionsDefine, function (dim, idx) {
            if ((isObject$1(dim) ? dim.name : dim) === 'name') {
                potentialNameDimIndex = idx;
            }
        });
    }

    // idxResult: {v, n}.
    var idxResult = (function () {

        var idxRes0 = {};
        var idxRes1 = {};
        var guessRecords = [];

        // 5 is an experience value.
        for (var i = 0, len = Math.min(5, dimCount); i < len; i++) {
            var guessResult = doGuessOrdinal(
                source.data, sourceFormat, source.seriesLayoutBy,
                dimensionsDefine, source.startIndex, i
            );
            guessRecords.push(guessResult);
            var isPureNumber = guessResult === BE_ORDINAL.Not;

            // [Strategy of idxRes0]: find the first BE_ORDINAL.Not as the value dim,
            // and then find a name dim with the priority:
            // "BE_ORDINAL.Might|BE_ORDINAL.Must" > "other dim" > "the value dim itself".
            if (isPureNumber && idxRes0.v == null && i !== potentialNameDimIndex) {
                idxRes0.v = i;
            }
            if (idxRes0.n == null
                || (idxRes0.n === idxRes0.v)
                || (!isPureNumber && guessRecords[idxRes0.n] === BE_ORDINAL.Not)
            ) {
                idxRes0.n = i;
            }
            if (fulfilled(idxRes0) && guessRecords[idxRes0.n] !== BE_ORDINAL.Not) {
                return idxRes0;
            }

            // [Strategy of idxRes1]: if idxRes0 not satisfied (that is, no BE_ORDINAL.Not),
            // find the first BE_ORDINAL.Might as the value dim,
            // and then find a name dim with the priority:
            // "other dim" > "the value dim itself".
            // That is for backward compat: number-like (e.g., `'3'`, `'55'`) can be
            // treated as number.
            if (!isPureNumber) {
                if (guessResult === BE_ORDINAL.Might && idxRes1.v == null && i !== potentialNameDimIndex) {
                    idxRes1.v = i;
                }
                if (idxRes1.n == null || (idxRes1.n === idxRes1.v)) {
                    idxRes1.n = i;
                }
            }
        }

        function fulfilled(idxResult) {
            return idxResult.v != null && idxResult.n != null;
        }

        return fulfilled(idxRes0) ? idxRes0 : fulfilled(idxRes1) ? idxRes1 : null;
    })();

    if (idxResult) {
        encode.value = idxResult.v;
        // `potentialNameDimIndex` has highest priority.
        var nameDimIndex = potentialNameDimIndex != null ? potentialNameDimIndex : idxResult.n;
        // By default, label use itemName in charts.
        // So we dont set encodeLabel here.
        encode.itemName = [nameDimIndex];
        encode.seriesName = [nameDimIndex];
    }

    return encode;
}

/**
 * If return null/undefined, indicate that should not use datasetModel.
 */
function getDatasetModel(seriesModel) {
    var option = seriesModel.option;
    // Caution: consider the scenario:
    // A dataset is declared and a series is not expected to use the dataset,
    // and at the beginning `setOption({series: { noData })` (just prepare other
    // option but no data), then `setOption({series: {data: [...]}); In this case,
    // the user should set an empty array to avoid that dataset is used by default.
    var thisData = option.data;
    if (!thisData) {
        return seriesModel.ecModel.getComponent('dataset', option.datasetIndex || 0);
    }
}

/**
 * The rule should not be complex, otherwise user might not
 * be able to known where the data is wrong.
 * The code is ugly, but how to make it neat?
 *
 * @param {module:echars/data/Source} source
 * @param {number} dimIndex
 * @return {BE_ORDINAL} guess result.
 */
function guessOrdinal(source, dimIndex) {
    return doGuessOrdinal(
        source.data,
        source.sourceFormat,
        source.seriesLayoutBy,
        source.dimensionsDefine,
        source.startIndex,
        dimIndex
    );
}

// dimIndex may be overflow source data.
// return {BE_ORDINAL}
function doGuessOrdinal(
    data, sourceFormat, seriesLayoutBy, dimensionsDefine, startIndex, dimIndex
) {
    var result;
    // Experience value.
    var maxLoop = 5;

    if (isTypedArray(data)) {
        return BE_ORDINAL.Not;
    }

    // When sourceType is 'objectRows' or 'keyedColumns', dimensionsDefine
    // always exists in source.
    var dimName;
    var dimType;
    if (dimensionsDefine) {
        var dimDefItem = dimensionsDefine[dimIndex];
        if (isObject$1(dimDefItem)) {
            dimName = dimDefItem.name;
            dimType = dimDefItem.type;
        }
        else if (isString(dimDefItem)) {
            dimName = dimDefItem;
        }
    }

    if (dimType != null) {
        return dimType === 'ordinal' ? BE_ORDINAL.Must : BE_ORDINAL.Not;
    }

    if (sourceFormat === SOURCE_FORMAT_ARRAY_ROWS) {
        if (seriesLayoutBy === SERIES_LAYOUT_BY_ROW) {
            var sample = data[dimIndex];
            for (var i = 0; i < (sample || []).length && i < maxLoop; i++) {
                if ((result = detectValue(sample[startIndex + i])) != null) {
                    return result;
                }
            }
        }
        else {
            for (var i = 0; i < data.length && i < maxLoop; i++) {
                var row = data[startIndex + i];
                if (row && (result = detectValue(row[dimIndex])) != null) {
                    return result;
                }
            }
        }
    }
    else if (sourceFormat === SOURCE_FORMAT_OBJECT_ROWS) {
        if (!dimName) {
            return BE_ORDINAL.Not;
        }
        for (var i = 0; i < data.length && i < maxLoop; i++) {
            var item = data[i];
            if (item && (result = detectValue(item[dimName])) != null) {
                return result;
            }
        }
    }
    else if (sourceFormat === SOURCE_FORMAT_KEYED_COLUMNS) {
        if (!dimName) {
            return BE_ORDINAL.Not;
        }
        var sample = data[dimName];
        if (!sample || isTypedArray(sample)) {
            return BE_ORDINAL.Not;
        }
        for (var i = 0; i < sample.length && i < maxLoop; i++) {
            if ((result = detectValue(sample[i])) != null) {
                return result;
            }
        }
    }
    else if (sourceFormat === SOURCE_FORMAT_ORIGINAL) {
        for (var i = 0; i < data.length && i < maxLoop; i++) {
            var item = data[i];
            var val = getDataItemValue(item);
            if (!isArray(val)) {
                return BE_ORDINAL.Not;
            }
            if ((result = detectValue(val[dimIndex])) != null) {
                return result;
            }
        }
    }

    function detectValue(val) {
        var beStr = isString(val);
        // Consider usage convenience, '1', '2' will be treated as "number".
        // `isFinit('')` get `true`.
        if (val != null && isFinite(val) && val !== '') {
            return beStr ? BE_ORDINAL.Might : BE_ORDINAL.Not;
        }
        else if (beStr && val !== '-') {
            return BE_ORDINAL.Must;
        }
    }

    return BE_ORDINAL.Not;
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

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


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

var OPTION_INNER_KEY = '\0_ec_inner';

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

    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) {
        assert$1(
            !(OPTION_INNER_KEY in option),
            'please use chart.getOption()'
        );

        this._optionManager.setOption(option, optionPreprocessorFuncs);

        this.resetOption(null);
    },

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

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

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

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

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

        if (!type || type === 'recreate' || type === 'media') {
            var mediaOptions = optionManager.getMediaOption(this, this._api);
            if (mediaOptions.length) {
                each$1(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 = [];

        resetSourceDefaulter(this);

        // If no component class, merge directly.
        // For example: color, animaiton options, etc.
        each$1(newOption, function (componentOption, mainType) {
            if (componentOption == null) {
                return;
            }

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

        ComponentModel.topologicalTravel(
            newCptTypes, ComponentModel.getAllClassMainTypes(), visitComponent, this
        );

        function visitComponent(mainType, dependencies) {

            var newCptOptionList = normalizeToArray(newOption[mainType]);

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

            makeIdAndName(mapResult);

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

            var dependentModels = getComponentsByTypes(
                componentsMap, dependencies
            );

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

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

                assert$1(
                    isObject$1(newCptOption) || componentModel,
                    'Empty component definition'
                );

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

                    if (componentModel && componentModel.constructor === ComponentModelClass) {
                        componentModel.name = resultItem.keyInfo.name;
                        // componentModel.settingTask && componentModel.settingTask.dirty();
                        componentModel.mergeOption(newCptOption, this);
                        componentModel.optionUpdated(newCptOption, false);
                    }
                    else {
                        // PENDING Global as parent ?
                        var extraOpt = extend(
                            {
                                dependentModels: dependentModels,
                                componentIndex: index
                            },
                            resultItem.keyInfo
                        );
                        componentModel = new ComponentModelClass(
                            newCptOption, this, this, extraOpt
                        );
                        extend(componentModel, extraOpt);
                        componentModel.init(newCptOption, this, this, extraOpt);

                        // Call optionUpdated after init.
                        // newCptOption has been used as componentModel.option
                        // and may be merged with theme and default, so pass null
                        // to avoid confusion.
                        componentModel.optionUpdated(null, true);
                    }
                }

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

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

        this._seriesIndicesMap = createHashMap(
            this._seriesIndices = this._seriesIndices || []
        );
    },

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

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

        delete option[OPTION_INNER_KEY];

        return option;
    },

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

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

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

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

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

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

        var result;

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

        return filterBySubType(result, condition);
    },

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

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

        return doFilter(filterBySubType(result, condition));

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

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

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

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

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

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

    /**
     * Get series list before filtered by type.
     * FIXME: rename to getRawSeriesByType?
     *
     * @param {string} subType
     * @return {Array.<module:echarts/model/Series>}
     */
    getSeriesByType: function (subType) {
        var series = this._componentsMap.get('series');
        return filter(series, function (oneSeries) {
            return oneSeries.subType === subType;
        });
    },

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

    /**
     * @return {number}
     */
    getSeriesCount: function () {
        return this._componentsMap.get('series').length;
    },

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

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

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

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

    /**
     * @param {module:echarts/model/Series} seriesModel
     */
    isSeriesFiltered: function (seriesModel) {
        assertSeriesInitialized(this);
        return this._seriesIndicesMap.get(seriesModel.componentIndex) == null;
    },

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

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

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

        createSeriesIndices(this, componentsMap.get('series'));

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

        ComponentModel.topologicalTravel(
            componentTypes,
            ComponentModel.getAllClassMainTypes(),
            function (componentType, dependencies) {
                each$1(componentsMap.get(componentType), function (component) {
                    (componentType !== 'series' || !isNotTargetSeries(component, payload))
                        && component.restoreData();
                });
            }
        );
    }

});

function isNotTargetSeries(seriesModel, payload) {
    if (payload) {
        var index = payload.seiresIndex;
        var id = payload.seriesId;
        var name = payload.seriesName;
        return (index != null && seriesModel.componentIndex !== index)
            || (id != null && seriesModel.id !== id)
            || (name != null && seriesModel.name !== name);
    }
}

/**
 * @inner
 */
function mergeTheme(option, theme) {
    // PENDING
    // NOT use `colorLayer` in theme if option has `color`
    var notMergeColorLayer = option.color && !option.colorLayer;

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

function initBase(baseOption) {
    baseOption = baseOption;

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

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

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

    this._seriesIndicesMap;

    mergeTheme(baseOption, this._theme.option);

    // TODO Needs clone when merging to the unexisted property
    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 (!isArray(types)) {
        types = types ? [types] : [];
    }

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

    return ret;
}

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

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

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

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

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

mixin(GlobalModel, colorPaletteMixin);

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var echartsAPIList = [
    'getDom', 'getZr', 'getWidth', 'getHeight', 'getDevicePixelRatio', 'dispatchAction', 'isDisposed',
    'on', 'off', 'getDataURL', 'getConnectedDataURL', 'getModel', 'getOption',
    'getViewOfComponentModel', 'getViewOfSeriesModel'
];
// And `getCoordinateSystems` and `getComponentByElement` will be injected in echarts.js

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

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var coordinateSystemCreators = {};

function CoordinateSystemManager() {

    this._coordinateSystems = [];
}

CoordinateSystemManager.prototype = {

    constructor: CoordinateSystemManager,

    create: function (ecModel, api) {
        var coordinateSystems = [];
        each$1(coordinateSystemCreators, function (creater, type) {
            var list = creater.create(ecModel, api);
            coordinateSystems = coordinateSystems.concat(list || []);
        });

        this._coordinateSystems = coordinateSystems;
    },

    update: function (ecModel, api) {
        each$1(this._coordinateSystems, function (coordSys) {
            coordSys.update && coordSys.update(ecModel, api);
        });
    },

    getCoordinateSystems: function () {
        return this._coordinateSystems.slice();
    }
};

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

CoordinateSystemManager.get = function (type) {
    return coordinateSystemCreators[type];
};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * ECharts option manager
 *
 * @module {echarts/model/OptionManager}
 */


var each$4 = each$1;
var clone$3 = clone;
var map$1 = map;
var merge$1 = merge;

var QUERY_REG = /^(min|max)?(.+)$/;

/**
 * TERM EXPLANATIONS:
 *
 * [option]:
 *
 *     An object that contains definitions of components. For example:
 *     var option = {
 *         title: {...},
 *         legend: {...},
 *         visualMap: {...},
 *         series: [
 *             {data: [...]},
 *             {data: [...]},
 *             ...
 *         ]
 *     };
 *
 * [rawOption]:
 *
 *     An object input to echarts.setOption. 'rawOption' may be an
 *     'option', or may be an object contains multi-options. For example:
 *     var option = {
 *         baseOption: {
 *             title: {...},
 *             legend: {...},
 *             series: [
 *                 {data: [...]},
 *                 {data: [...]},
 *                 ...
 *             ]
 *         },
 *         timeline: {...},
 *         options: [
 *             {title: {...}, series: {data: [...]}},
 *             {title: {...}, series: {data: [...]}},
 *             ...
 *         ],
 *         media: [
 *             {
 *                 query: {maxWidth: 320},
 *                 option: {series: {x: 20}, visualMap: {show: false}}
 *             },
 *             {
 *                 query: {minWidth: 320, maxWidth: 720},
 *                 option: {series: {x: 500}, visualMap: {show: true}}
 *             },
 *             {
 *                 option: {series: {x: 1200}, visualMap: {show: true}}
 *             }
 *         ]
 *     };
 *
 * @alias module:echarts/model/OptionManager
 * @param {module:echarts/ExtensionAPI} api
 */
function OptionManager(api) {

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

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

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

    /**
     * @private
     * @type {Object}
     */
    this._mediaDefault;

    /**
     * -1, means default.
     * empty means no media.
     * @private
     * @type {Array.<number>}
     */
    this._currentMediaIndices = [];

    /**
     * @private
     * @type {Object}
     */
    this._optionBackup;

    /**
     * @private
     * @type {Object}
     */
    this._newBaseOption;
}

// timeline.notMerge is not supported in ec3. Firstly there is rearly
// case that notMerge is needed. Secondly supporting 'notMerge' requires
// rawOption cloned and backuped when timeline changed, which does no
// good to performance. What's more, that both timeline and setOption
// method supply 'notMerge' brings complex and some problems.
// Consider this case:
// (step1) chart.setOption({timeline: {notMerge: false}, ...}, false);
// (step2) chart.setOption({timeline: {notMerge: true}, ...}, false);

OptionManager.prototype = {

    constructor: OptionManager,

    /**
     * @public
     * @param {Object} rawOption Raw option.
     * @param {module:echarts/model/Global} ecModel
     * @param {Array.<Function>} optionPreprocessorFuncs
     * @return {Object} Init option
     */
    setOption: function (rawOption, optionPreprocessorFuncs) {
        if (rawOption) {
            // That set dat primitive is dangerous if user reuse the data when setOption again.
            each$1(normalizeToArray(rawOption.series), function (series) {
                series && series.data && isTypedArray(series.data) && setAsPrimitive(series.data);
            });
        }

        // Caution: some series modify option data, if do not clone,
        // it should ensure that the repeat modify correctly
        // (create a new object when modify itself).
        rawOption = clone$3(rawOption);

        // FIXME
        // 如果 timeline options 或者 media 中设置了某个属性，而baseOption中没有设置，则进行警告。

        var oldOptionBackup = this._optionBackup;
        var newParsedOption = parseRawOption.call(
            this, rawOption, optionPreprocessorFuncs, !oldOptionBackup
        );
        this._newBaseOption = newParsedOption.baseOption;

        // For setOption at second time (using merge mode);
        if (oldOptionBackup) {
            // Only baseOption can be merged.
            mergeOption(oldOptionBackup.baseOption, newParsedOption.baseOption);

            // For simplicity, timeline options and media options do not support merge,
            // that is, if you `setOption` twice and both has timeline options, the latter
            // timeline opitons will not be merged to the formers, but just substitude them.
            if (newParsedOption.timelineOptions.length) {
                oldOptionBackup.timelineOptions = newParsedOption.timelineOptions;
            }
            if (newParsedOption.mediaList.length) {
                oldOptionBackup.mediaList = newParsedOption.mediaList;
            }
            if (newParsedOption.mediaDefault) {
                oldOptionBackup.mediaDefault = newParsedOption.mediaDefault;
            }
        }
        else {
            this._optionBackup = newParsedOption;
        }
    },

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

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

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

        return clone$3(isRecreate
            // this._optionBackup.baseOption, which is created at the first `setOption`
            // called, and is merged into every new option by inner method `mergeOption`
            // each time `setOption` called, can be only used in `isRecreate`, because
            // its reliability is under suspicion. In other cases option merge is
            // performed by `model.mergeOption`.
            ? optionBackup.baseOption : this._newBaseOption
        );
    },

    /**
     * @param {module:echarts/model/Global} ecModel
     * @return {Object}
     */
    getTimelineOption: function (ecModel) {
        var option;
        var timelineOptions = this._timelineOptions;

        if (timelineOptions.length) {
            // getTimelineOption can only be called after ecModel inited,
            // so we can get currentIndex from timelineModel.
            var timelineModel = ecModel.getComponent('timeline');
            if (timelineModel) {
                option = clone$3(
                    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$1(indices, function (index) {
                return clone$3(
                    index === -1 ? mediaDefault.option : mediaList[index].option
                );
            });
        }
        // Otherwise return nothing.

        this._currentMediaIndices = indices;

        return result;
    }
};

function parseRawOption(rawOption, optionPreprocessorFuncs, isNew) {
    var timelineOptions = [];
    var mediaList = [];
    var mediaDefault;
    var baseOption;

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

    if (rawOption.baseOption) {
        baseOption = rawOption.baseOption;
    }

    // For timeline
    if (timelineOpt || rawOption.options) {
        baseOption = baseOption || {};
        timelineOptions = (rawOption.options || []).slice();
    }

    // For media query
    if (rawOption.media) {
        baseOption = baseOption || {};
        var media = rawOption.media;
        each$4(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$4([baseOption].concat(timelineOptions)
        .concat(map(mediaList, function (media) {
            return media.option;
        })),
        function (option) {
            each$4(optionPreprocessorFuncs, function (preProcess) {
                preProcess(option, isNew);
            });
        }
    );

    return {
        baseOption: baseOption,
        timelineOptions: timelineOptions,
        mediaDefault: mediaDefault,
        mediaList: mediaList
    };
}

/**
 * @see <http://www.w3.org/TR/css3-mediaqueries/#media1>
 * Support: width, height, aspectRatio
 * Can use max or min as prefix.
 */
function applyMediaQuery(query, ecWidth, ecHeight) {
    var realMap = {
        width: ecWidth,
        height: ecHeight,
        aspectratio: ecWidth / ecHeight // lowser case for convenientce.
    };

    var applicatable = true;

    each$1(query, function (value, attr) {
        var matched = attr.match(QUERY_REG);

        if (!matched || !matched[1] || !matched[2]) {
            return;
        }

        var operator = matched[1];
        var realAttr = matched[2].toLowerCase();

        if (!compare(realMap[realAttr], value, operator)) {
            applicatable = false;
        }
    });

    return applicatable;
}

function compare(real, expect, operator) {
    if (operator === 'min') {
        return real >= expect;
    }
    else if (operator === 'max') {
        return real <= expect;
    }
    else { // Equals
        return real === expect;
    }
}

function indicesEquals(indices1, indices2) {
    // indices is always order by asc and has only finite number.
    return indices1.join(',') === indices2.join(',');
}

/**
 * Consider case:
 * `chart.setOption(opt1);`
 * Then user do some interaction like dataZoom, dataView changing.
 * `chart.setOption(opt2);`
 * Then user press 'reset button' in toolbox.
 *
 * After doing that all of the interaction effects should be reset, the
 * chart should be the same as the result of invoke
 * `chart.setOption(opt1); chart.setOption(opt2);`.
 *
 * Although it is not able ensure that
 * `chart.setOption(opt1); chart.setOption(opt2);` is equivalents to
 * `chart.setOption(merge(opt1, opt2));` exactly,
 * this might be the only simple way to implement that feature.
 *
 * MEMO: We've considered some other approaches:
 * 1. Each model handle its self restoration but not uniform treatment.
 *     (Too complex in logic and error-prone)
 * 2. Use a shadow ecModel. (Performace expensive)
 */
function mergeOption(oldOption, newOption) {
    newOption = newOption || {};

    each$4(newOption, function (newCptOpt, mainType) {
        if (newCptOpt == null) {
            return;
        }

        var oldCptOpt = oldOption[mainType];

        if (!ComponentModel.hasClass(mainType)) {
            oldOption[mainType] = merge$1(oldCptOpt, newCptOpt, true);
        }
        else {
            newCptOpt = normalizeToArray(newCptOpt);
            oldCptOpt = normalizeToArray(oldCptOpt);

            var mapResult = mappingToExists(oldCptOpt, newCptOpt);

            oldOption[mainType] = map$1(mapResult, function (item) {
                return (item.option && item.exist)
                    ? merge$1(item.exist, item.option, true)
                    : (item.exist || item.option);
            });
        }
    });
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var each$5 = each$1;
var isObject$3 = isObject$1;

var POSSIBLE_STYLES = [
    'areaStyle', 'lineStyle', 'nodeStyle', 'linkStyle',
    'chordStyle', 'label', 'labelLine'
];

function compatEC2ItemStyle(opt) {
    var itemStyleOpt = opt && opt.itemStyle;
    if (!itemStyleOpt) {
        return;
    }
    for (var i = 0, len = POSSIBLE_STYLES.length; i < len; i++) {
        var styleName = POSSIBLE_STYLES[i];
        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 {
                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 {
                merge(opt[styleName].emphasis, emphasisItemStyleOpt[styleName]);
            }
            emphasisItemStyleOpt[styleName] = null;
        }
    }
}

function convertNormalEmphasis(opt, optType, useExtend) {
    if (opt && opt[optType] && (opt[optType].normal || opt[optType].emphasis)) {
        var normalOpt = opt[optType].normal;
        var emphasisOpt = opt[optType].emphasis;

        if (normalOpt) {
            // Timeline controlStyle has other properties besides normal and emphasis
            if (useExtend) {
                opt[optType].normal = opt[optType].emphasis = null;
                defaults(opt[optType], normalOpt);
            }
            else {
                opt[optType] = normalOpt;
            }
        }
        if (emphasisOpt) {
            opt.emphasis = opt.emphasis || {};
            opt.emphasis[optType] = emphasisOpt;
        }
    }
}

function removeEC3NormalStatus(opt) {
    convertNormalEmphasis(opt, 'itemStyle');
    convertNormalEmphasis(opt, 'lineStyle');
    convertNormalEmphasis(opt, 'areaStyle');
    convertNormalEmphasis(opt, 'label');
    convertNormalEmphasis(opt, 'labelLine');
    // treemap
    convertNormalEmphasis(opt, 'upperLabel');
    // graph
    convertNormalEmphasis(opt, 'edgeLabel');
}

function compatTextStyle(opt, propName) {
    // Check whether is not object (string\null\undefined ...)
    var labelOptSingle = isObject$3(opt) && opt[propName];
    var textStyle = isObject$3(labelOptSingle) && labelOptSingle.textStyle;
    if (textStyle) {
        for (var i = 0, len = TEXT_STYLE_OPTIONS.length; i < len; i++) {
            var propName = TEXT_STYLE_OPTIONS[i];
            if (textStyle.hasOwnProperty(propName)) {
                labelOptSingle[propName] = textStyle[propName];
            }
        }
    }
}

function compatEC3CommonStyles(opt) {
    if (opt) {
        removeEC3NormalStatus(opt);
        compatTextStyle(opt, 'label');
        opt.emphasis && compatTextStyle(opt.emphasis, 'label');
    }
}

function processSeries(seriesOpt) {
    if (!isObject$3(seriesOpt)) {
        return;
    }

    compatEC2ItemStyle(seriesOpt);
    removeEC3NormalStatus(seriesOpt);

    compatTextStyle(seriesOpt, 'label');
    // treemap
    compatTextStyle(seriesOpt, 'upperLabel');
    // graph
    compatTextStyle(seriesOpt, 'edgeLabel');
    if (seriesOpt.emphasis) {
        compatTextStyle(seriesOpt.emphasis, 'label');
        // treemap
        compatTextStyle(seriesOpt.emphasis, 'upperLabel');
        // graph
        compatTextStyle(seriesOpt.emphasis, 'edgeLabel');
    }

    var markPoint = seriesOpt.markPoint;
    if (markPoint) {
        compatEC2ItemStyle(markPoint);
        compatEC3CommonStyles(markPoint);
    }

    var markLine = seriesOpt.markLine;
    if (markLine) {
        compatEC2ItemStyle(markLine);
        compatEC3CommonStyles(markLine);
    }

    var markArea = seriesOpt.markArea;
    if (markArea) {
        compatEC3CommonStyles(markArea);
    }

    var data = seriesOpt.data;

    // Break with ec3: if `setOption` again, there may be no `type` in option,
    // then the backward compat based on option type will not be performed.

    if (seriesOpt.type === 'graph') {
        data = data || seriesOpt.nodes;
        var edgeData = seriesOpt.links || seriesOpt.edges;
        if (edgeData && !isTypedArray(edgeData)) {
            for (var i = 0; i < edgeData.length; i++) {
                compatEC3CommonStyles(edgeData[i]);
            }
        }
        each$1(seriesOpt.categories, function (opt) {
            removeEC3NormalStatus(opt);
        });
    }

    if (data && !isTypedArray(data)) {
        for (var i = 0; i < data.length; i++) {
            compatEC3CommonStyles(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++) {
            compatEC3CommonStyles(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 (isArray(mlData[i])) {
                compatEC3CommonStyles(mlData[i][0]);
                compatEC3CommonStyles(mlData[i][1]);
            }
            else {
                compatEC3CommonStyles(mlData[i]);
            }
        }
    }

    // Series
    if (seriesOpt.type === 'gauge') {
        compatTextStyle(seriesOpt, 'axisLabel');
        compatTextStyle(seriesOpt, 'title');
        compatTextStyle(seriesOpt, 'detail');
    }
    else if (seriesOpt.type === 'treemap') {
        convertNormalEmphasis(seriesOpt.breadcrumb, 'itemStyle');
        each$1(seriesOpt.levels, function (opt) {
            removeEC3NormalStatus(opt);
        });
    }
    else if (seriesOpt.type === 'tree') {
        removeEC3NormalStatus(seriesOpt.leaves);
    }
    // sunburst starts from ec4, so it does not need to compat levels.
}

function toArr(o) {
    return isArray(o) ? o : o ? [o] : [];
}

function toObj(o) {
    return (isArray(o) ? o[0] : o) || {};
}

var compatStyle = function (option, isTheme) {
    each$5(toArr(option.series), function (seriesOpt) {
        isObject$3(seriesOpt) && processSeries(seriesOpt);
    });

    var axes = ['xAxis', 'yAxis', 'radiusAxis', 'angleAxis', 'singleAxis', 'parallelAxis', 'radar'];
    isTheme && axes.push('valueAxis', 'categoryAxis', 'logAxis', 'timeAxis');

    each$5(
        axes,
        function (axisName) {
            each$5(toArr(option[axisName]), function (axisOpt) {
                if (axisOpt) {
                    compatTextStyle(axisOpt, 'axisLabel');
                    compatTextStyle(axisOpt.axisPointer, 'label');
                }
            });
        }
    );

    each$5(toArr(option.parallel), function (parallelOpt) {
        var parallelAxisDefault = parallelOpt && parallelOpt.parallelAxisDefault;
        compatTextStyle(parallelAxisDefault, 'axisLabel');
        compatTextStyle(parallelAxisDefault && parallelAxisDefault.axisPointer, 'label');
    });

    each$5(toArr(option.calendar), function (calendarOpt) {
        convertNormalEmphasis(calendarOpt, 'itemStyle');
        compatTextStyle(calendarOpt, 'dayLabel');
        compatTextStyle(calendarOpt, 'monthLabel');
        compatTextStyle(calendarOpt, 'yearLabel');
    });

    // radar.name.textStyle
    each$5(toArr(option.radar), function (radarOpt) {
        compatTextStyle(radarOpt, 'name');
    });

    each$5(toArr(option.geo), function (geoOpt) {
        if (isObject$3(geoOpt)) {
            compatEC3CommonStyles(geoOpt);
            each$5(toArr(geoOpt.regions), function (regionObj) {
                compatEC3CommonStyles(regionObj);
            });
        }
    });

    each$5(toArr(option.timeline), function (timelineOpt) {
        compatEC3CommonStyles(timelineOpt);
        convertNormalEmphasis(timelineOpt, 'label');
        convertNormalEmphasis(timelineOpt, 'itemStyle');
        convertNormalEmphasis(timelineOpt, 'controlStyle', true);

        var data = timelineOpt.data;
        isArray(data) && each$1(data, function (item) {
            if (isObject$1(item)) {
                convertNormalEmphasis(item, 'label');
                convertNormalEmphasis(item, 'itemStyle');
            }
        });
    });

    each$5(toArr(option.toolbox), function (toolboxOpt) {
        convertNormalEmphasis(toolboxOpt, 'iconStyle');
        each$5(toolboxOpt.feature, function (featureOpt) {
            convertNormalEmphasis(featureOpt, 'iconStyle');
        });
    });

    compatTextStyle(toObj(option.axisPointer), 'label');
    compatTextStyle(toObj(option.tooltip).axisPointer, 'label');
};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

// Compatitable with 2.0

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$1(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$1(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 backwardCompat = function (option, isTheme) {
    compatStyle(option, isTheme);

    // Make sure series array for model initialization.
    option.series = normalizeToArray(option.series);

    each$1(option.series, function (seriesOpt) {
        if (!isObject$1(seriesOpt)) {
            return;
        }

        var seriesType = seriesOpt.type;

        if (seriesType === 'line') {
            if (seriesOpt.clipOverflow != null) {
                seriesOpt.clip = seriesOpt.clipOverflow;
            }
        }
        else if (seriesType === 'pie' || seriesType === 'gauge') {
            if (seriesOpt.clockWise != null) {
                seriesOpt.clockwise = seriesOpt.clockWise;
            }
        }
        else if (seriesType === 'gauge') {
            var pointerColor = get(seriesOpt, 'pointer.color');
            pointerColor != null
                && set$1(seriesOpt, 'itemStyle.color', pointerColor);
        }

        compatLayoutProperties(seriesOpt);
    });

    // dataRange has changed to visualMap
    if (option.dataRange) {
        option.visualMap = option.dataRange;
    }

    each$1(COMPATITABLE_COMPONENTS, function (componentName) {
        var options = option[componentName];
        if (options) {
            if (!isArray(options)) {
                options = [options];
            }
            each$1(options, function (option) {
                compatLayoutProperties(option);
            });
        }
    });
};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

// (1) [Caution]: the logic is correct based on the premises:
//     data processing stage is blocked in stream.
//     See <module:echarts/stream/Scheduler#performDataProcessorTasks>
// (2) Only register once when import repeatly.
//     Should be executed after series filtered and before stack calculation.
var dataStack = function (ecModel) {
    var stackInfoMap = createHashMap();
    ecModel.eachSeries(function (seriesModel) {
        var stack = seriesModel.get('stack');
        // Compatibal: when `stack` is set as '', do not stack.
        if (stack) {
            var stackInfoList = stackInfoMap.get(stack) || stackInfoMap.set(stack, []);
            var data = seriesModel.getData();

            var stackInfo = {
                // Used for calculate axis extent automatically.
                stackResultDimension: data.getCalculationInfo('stackResultDimension'),
                stackedOverDimension: data.getCalculationInfo('stackedOverDimension'),
                stackedDimension: data.getCalculationInfo('stackedDimension'),
                stackedByDimension: data.getCalculationInfo('stackedByDimension'),
                isStackedByIndex: data.getCalculationInfo('isStackedByIndex'),
                data: data,
                seriesModel: seriesModel
            };

            // If stacked on axis that do not support data stack.
            if (!stackInfo.stackedDimension
                || !(stackInfo.isStackedByIndex || stackInfo.stackedByDimension)
            ) {
                return;
            }

            stackInfoList.length && data.setCalculationInfo(
                'stackedOnSeries', stackInfoList[stackInfoList.length - 1].seriesModel
            );

            stackInfoList.push(stackInfo);
        }
    });

    stackInfoMap.each(calculateStack);
};

function calculateStack(stackInfoList) {
    each$1(stackInfoList, function (targetStackInfo, idxInStack) {
        var resultVal = [];
        var resultNaN = [NaN, NaN];
        var dims = [targetStackInfo.stackResultDimension, targetStackInfo.stackedOverDimension];
        var targetData = targetStackInfo.data;
        var isStackedByIndex = targetStackInfo.isStackedByIndex;

        // Should not write on raw data, because stack series model list changes
        // depending on legend selection.
        var newData = targetData.map(dims, function (v0, v1, dataIndex) {
            var sum = targetData.get(targetStackInfo.stackedDimension, dataIndex);

            // Consider `connectNulls` of line area, if value is NaN, stackedOver
            // should also be NaN, to draw a appropriate belt area.
            if (isNaN(sum)) {
                return resultNaN;
            }

            var byValue;
            var stackedDataRawIndex;

            if (isStackedByIndex) {
                stackedDataRawIndex = targetData.getRawIndex(dataIndex);
            }
            else {
                byValue = targetData.get(targetStackInfo.stackedByDimension, dataIndex);
            }

            // If stackOver is NaN, chart view will render point on value start.
            var stackedOver = NaN;

            for (var j = idxInStack - 1; j >= 0; j--) {
                var stackInfo = stackInfoList[j];

                // Has been optimized by inverted indices on `stackedByDimension`.
                if (!isStackedByIndex) {
                    stackedDataRawIndex = stackInfo.data.rawIndexOf(stackInfo.stackedByDimension, byValue);
                }

                if (stackedDataRawIndex >= 0) {
                    var val = stackInfo.data.getByRawIndex(stackInfo.stackResultDimension, stackedDataRawIndex);

                    // Considering positive stack, negative stack and empty data
                    if ((sum >= 0 && val > 0) // Positive stack
                        || (sum <= 0 && val < 0) // Negative stack
                    ) {
                        sum += val;
                        stackedOver = val;
                        break;
                    }
                }
            }

            resultVal[0] = sum;
            resultVal[1] = stackedOver;

            return resultVal;
        });

        targetData.hostModel.setData(newData);
        // Update for consequent calculation
        targetStackInfo.data = newData;
    });
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

// TODO
// ??? refactor? check the outer usage of data provider.
// merge with defaultDimValueGetter?

/**
 * If normal array used, mutable chunk size is supported.
 * If typed array used, chunk size must be fixed.
 */
function DefaultDataProvider(source, dimSize) {
    if (!Source.isInstance(source)) {
        source = Source.seriesDataToSource(source);
    }
    this._source = source;

    var data = this._data = source.data;
    var sourceFormat = source.sourceFormat;

    // Typed array. TODO IE10+?
    if (sourceFormat === SOURCE_FORMAT_TYPED_ARRAY) {
        if (__DEV__) {
            if (dimSize == null) {
                throw new Error('Typed array data must specify dimension size');
            }
        }
        this._offset = 0;
        this._dimSize = dimSize;
        this._data = data;
    }

    var methods = providerMethods[
        sourceFormat === SOURCE_FORMAT_ARRAY_ROWS
        ? sourceFormat + '_' + source.seriesLayoutBy
        : sourceFormat
    ];

    if (__DEV__) {
        assert$1(methods, 'Invalide sourceFormat: ' + sourceFormat);
    }

    extend(this, methods);
}

var providerProto = DefaultDataProvider.prototype;
// If data is pure without style configuration
providerProto.pure = false;
// If data is persistent and will not be released after use.
providerProto.persistent = true;

// ???! FIXME legacy data provider do not has method getSource
providerProto.getSource = function () {
    return this._source;
};

var providerMethods = {

    'arrayRows_column': {
        pure: true,
        count: function () {
            return Math.max(0, this._data.length - this._source.startIndex);
        },
        getItem: function (idx) {
            return this._data[idx + this._source.startIndex];
        },
        appendData: appendDataSimply
    },

    'arrayRows_row': {
        pure: true,
        count: function () {
            var row = this._data[0];
            return row ? Math.max(0, row.length - this._source.startIndex) : 0;
        },
        getItem: function (idx) {
            idx += this._source.startIndex;
            var item = [];
            var data = this._data;
            for (var i = 0; i < data.length; i++) {
                var row = data[i];
                item.push(row ? row[idx] : null);
            }
            return item;
        },
        appendData: function () {
            throw new Error('Do not support appendData when set seriesLayoutBy: "row".');
        }
    },

    'objectRows': {
        pure: true,
        count: countSimply,
        getItem: getItemSimply,
        appendData: appendDataSimply
    },

    'keyedColumns': {
        pure: true,
        count: function () {
            var dimName = this._source.dimensionsDefine[0].name;
            var col = this._data[dimName];
            return col ? col.length : 0;
        },
        getItem: function (idx) {
            var item = [];
            var dims = this._source.dimensionsDefine;
            for (var i = 0; i < dims.length; i++) {
                var col = this._data[dims[i].name];
                item.push(col ? col[idx] : null);
            }
            return item;
        },
        appendData: function (newData) {
            var data = this._data;
            each$1(newData, function (newCol, key) {
                var oldCol = data[key] || (data[key] = []);
                for (var i = 0; i < (newCol || []).length; i++) {
                    oldCol.push(newCol[i]);
                }
            });
        }
    },

    'original': {
        count: countSimply,
        getItem: getItemSimply,
        appendData: appendDataSimply
    },

    'typedArray': {
        persistent: false,
        pure: true,
        count: function () {
            return this._data ? (this._data.length / this._dimSize) : 0;
        },
        getItem: function (idx, out) {
            idx = idx - this._offset;
            out = out || [];
            var offset = this._dimSize * idx;
            for (var i = 0; i < this._dimSize; i++) {
                out[i] = this._data[offset + i];
            }
            return out;
        },
        appendData: function (newData) {
            if (__DEV__) {
                assert$1(
                    isTypedArray(newData),
                    'Added data must be TypedArray if data in initialization is TypedArray'
                );
            }

            this._data = newData;
        },

        // Clean self if data is already used.
        clean: function () {
            // PENDING
            this._offset += this.count();
            this._data = null;
        }
    }
};

function countSimply() {
    return this._data.length;
}
function getItemSimply(idx) {
    return this._data[idx];
}
function appendDataSimply(newData) {
    for (var i = 0; i < newData.length; i++) {
        this._data.push(newData[i]);
    }
}



var rawValueGetters = {

    arrayRows: getRawValueSimply,

    objectRows: function (dataItem, dataIndex, dimIndex, dimName) {
        return dimIndex != null ? dataItem[dimName] : dataItem;
    },

    keyedColumns: getRawValueSimply,

    original: function (dataItem, dataIndex, dimIndex, dimName) {
        // FIXME
        // In some case (markpoint in geo (geo-map.html)), dataItem
        // is {coord: [...]}
        var value = getDataItemValue(dataItem);
        return (dimIndex == null || !(value instanceof Array))
            ? value
            : value[dimIndex];
    },

    typedArray: getRawValueSimply
};

function getRawValueSimply(dataItem, dataIndex, dimIndex, dimName) {
    return dimIndex != null ? dataItem[dimIndex] : dataItem;
}


var defaultDimValueGetters = {

    arrayRows: getDimValueSimply,

    objectRows: function (dataItem, dimName, dataIndex, dimIndex) {
        return converDataValue(dataItem[dimName], this._dimensionInfos[dimName]);
    },

    keyedColumns: getDimValueSimply,

    original: function (dataItem, dimName, dataIndex, dimIndex) {
        // Performance sensitive, do not use modelUtil.getDataItemValue.
        // If dataItem is an plain object with no value field, the var `value`
        // will be assigned with the object, but it will be tread correctly
        // in the `convertDataValue`.
        var value = dataItem && (dataItem.value == null ? dataItem : dataItem.value);

        // If any dataItem is like { value: 10 }
        if (!this._rawData.pure && isDataItemOption(dataItem)) {
            this.hasItemOption = true;
        }
        return converDataValue(
            (value instanceof Array)
                ? value[dimIndex]
                // If value is a single number or something else not array.
                : value,
            this._dimensionInfos[dimName]
        );
    },

    typedArray: function (dataItem, dimName, dataIndex, dimIndex) {
        return dataItem[dimIndex];
    }

};

function getDimValueSimply(dataItem, dimName, dataIndex, dimIndex) {
    return converDataValue(dataItem[dimIndex], this._dimensionInfos[dimName]);
}

/**
 * This helper method convert value in data.
 * @param {string|number|Date} value
 * @param {Object|string} [dimInfo] If string (like 'x'), dimType defaults 'number'.
 *        If "dimInfo.ordinalParseAndSave", ordinal value can be parsed.
 */
function converDataValue(value, dimInfo) {
    // Performance sensitive.
    var dimType = dimInfo && dimInfo.type;
    if (dimType === 'ordinal') {
        // If given value is a category string
        var ordinalMeta = dimInfo && dimInfo.ordinalMeta;
        return ordinalMeta
            ? ordinalMeta.parseAndCollect(value)
            : value;
    }

    if (dimType === 'time'
        // spead up when using timestamp
        && typeof value !== 'number'
        && value != null
        && value !== '-'
    ) {
        value = +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
        // If string (like '-'), using '+' parse to NaN
        // If object, also parse to NaN
        : +value;
}

// ??? FIXME can these logic be more neat: getRawValue, getRawDataItem,
// Consider persistent.
// Caution: why use raw value to display on label or tooltip?
// A reason is to avoid format. For example time value we do not know
// how to format is expected. More over, if stack is used, calculated
// value may be 0.91000000001, which have brings trouble to display.
// TODO: consider how to treat null/undefined/NaN when display?
/**
 * @param {module:echarts/data/List} data
 * @param {number} dataIndex
 * @param {string|number} [dim] dimName or dimIndex
 * @return {Array.<number>|string|number} can be null/undefined.
 */
function retrieveRawValue(data, dataIndex, dim) {
    if (!data) {
        return;
    }

    // Consider data may be not persistent.
    var dataItem = data.getRawDataItem(dataIndex);

    if (dataItem == null) {
        return;
    }

    var sourceFormat = data.getProvider().getSource().sourceFormat;
    var dimName;
    var dimIndex;

    var dimInfo = data.getDimensionInfo(dim);
    if (dimInfo) {
        dimName = dimInfo.name;
        dimIndex = dimInfo.index;
    }

    return rawValueGetters[sourceFormat](dataItem, dataIndex, dimIndex, dimName);
}

/**
 * Compatible with some cases (in pie, map) like:
 * data: [{name: 'xx', value: 5, selected: true}, ...]
 * where only sourceFormat is 'original' and 'objectRows' supported.
 *
 * ??? TODO
 * Supported detail options in data item when using 'arrayRows'.
 *
 * @param {module:echarts/data/List} data
 * @param {number} dataIndex
 * @param {string} attr like 'selected'
 */
function retrieveRawAttr(data, dataIndex, attr) {
    if (!data) {
        return;
    }

    var sourceFormat = data.getProvider().getSource().sourceFormat;

    if (sourceFormat !== SOURCE_FORMAT_ORIGINAL
        && sourceFormat !== SOURCE_FORMAT_OBJECT_ROWS
    ) {
        return;
    }

    var dataItem = data.getRawDataItem(dataIndex);
    if (sourceFormat === SOURCE_FORMAT_ORIGINAL && !isObject$1(dataItem)) {
        dataItem = null;
    }
    if (dataItem) {
        return dataItem[attr];
    }
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var DIMENSION_LABEL_REG = /\{@(.+?)\}/g;

// PENDING A little ugly
var dataFormatMixin = {
    /**
     * Get params for formatter
     * @param {number} dataIndex
     * @param {string} [dataType]
     * @return {Object}
     */
    getDataParams: function (dataIndex, dataType) {
        var data = this.getData(dataType);
        var rawValue = this.getRawValue(dataIndex, dataType);
        var rawDataIndex = data.getRawIndex(dataIndex);
        var name = data.getName(dataIndex);
        var itemOpt = data.getRawDataItem(dataIndex);
        var color = data.getItemVisual(dataIndex, 'color');
        var borderColor = data.getItemVisual(dataIndex, 'borderColor');
        var tooltipModel = this.ecModel.getComponent('tooltip');
        var renderModeOption = tooltipModel && tooltipModel.get('renderMode');
        var renderMode = getTooltipRenderMode(renderModeOption);
        var mainType = this.mainType;
        var isSeries = mainType === 'series';
        var userOutput = data.userOutput;

        return {
            componentType: mainType,
            componentSubType: this.subType,
            componentIndex: this.componentIndex,
            seriesType: isSeries ? this.subType : null,
            seriesIndex: this.seriesIndex,
            seriesId: isSeries ? this.id : null,
            seriesName: isSeries ? this.name : null,
            name: name,
            dataIndex: rawDataIndex,
            data: itemOpt,
            dataType: dataType,
            value: rawValue,
            color: color,
            borderColor: borderColor,
            dimensionNames: userOutput ? userOutput.dimensionNames : null,
            encode: userOutput ? userOutput.encode : null,
            marker: getTooltipMarker({
                color: color,
                renderMode: renderMode
            }),

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

    /**
     * Format label
     * @param {number} dataIndex
     * @param {string} [status='normal'] 'normal' or 'emphasis'
     * @param {string} [dataType]
     * @param {number} [dimIndex] Only used in some chart that
     *        use formatter in different dimensions, like radar.
     * @param {string} [labelProp='label']
     * @return {string} If not formatter, return null/undefined
     */
    getFormattedLabel: function (dataIndex, status, dataType, dimIndex, labelProp) {
        status = status || 'normal';
        var data = this.getData(dataType);
        var itemModel = data.getItemModel(dataIndex);

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

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

        if (typeof formatter === 'function') {
            params.status = status;
            params.dimensionIndex = dimIndex;
            return formatter(params);
        }
        else if (typeof formatter === 'string') {
            var str = formatTpl(formatter, params);

            // Support 'aaa{@[3]}bbb{@product}ccc'.
            // Do not support '}' in dim name util have to.
            return str.replace(DIMENSION_LABEL_REG, function (origin, dim) {
                var len = dim.length;
                if (dim.charAt(0) === '[' && dim.charAt(len - 1) === ']') {
                    dim = +dim.slice(1, len - 1); // Also: '[]' => 0
                }
                return retrieveRawValue(data, dataIndex, dim);
            });
        }
    },

    /**
     * Get raw value in option
     * @param {number} idx
     * @param {string} [dataType]
     * @return {Array|number|string}
     */
    getRawValue: function (idx, dataType) {
        return retrieveRawValue(this.getData(dataType), idx);
    },

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

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * @param {Object} define
 * @return See the return of `createTask`.
 */
function createTask(define) {
    return new Task(define);
}

/**
 * @constructor
 * @param {Object} define
 * @param {Function} define.reset Custom reset
 * @param {Function} [define.plan] Returns 'reset' indicate reset immediately.
 * @param {Function} [define.count] count is used to determin data task.
 * @param {Function} [define.onDirty] count is used to determin data task.
 */
function Task(define) {
    define = define || {};

    this._reset = define.reset;
    this._plan = define.plan;
    this._count = define.count;
    this._onDirty = define.onDirty;

    this._dirty = true;

    // Context must be specified implicitly, to
    // avoid miss update context when model changed.
    this.context;
}

var taskProto = Task.prototype;

/**
 * @param {Object} performArgs
 * @param {number} [performArgs.step] Specified step.
 * @param {number} [performArgs.skip] Skip customer perform call.
 * @param {number} [performArgs.modBy] Sampling window size.
 * @param {number} [performArgs.modDataCount] Sampling count.
 */
taskProto.perform = function (performArgs) {
    var upTask = this._upstream;
    var skip = performArgs && performArgs.skip;

    // TODO some refactor.
    // Pull data. Must pull data each time, because context.data
    // may be updated by Series.setData.
    if (this._dirty && upTask) {
        var context = this.context;
        context.data = context.outputData = upTask.context.outputData;
    }

    if (this.__pipeline) {
        this.__pipeline.currentTask = this;
    }

    var planResult;
    if (this._plan && !skip) {
        planResult = this._plan(this.context);
    }

    // Support sharding by mod, which changes the render sequence and makes the rendered graphic
    // elements uniformed distributed when progress, especially when moving or zooming.
    var lastModBy = normalizeModBy(this._modBy);
    var lastModDataCount = this._modDataCount || 0;
    var modBy = normalizeModBy(performArgs && performArgs.modBy);
    var modDataCount = performArgs && performArgs.modDataCount || 0;
    if (lastModBy !== modBy || lastModDataCount !== modDataCount) {
        planResult = 'reset';
    }

    function normalizeModBy(val) {
        !(val >= 1) && (val = 1); // jshint ignore:line
        return val;
    }

    var forceFirstProgress;
    if (this._dirty || planResult === 'reset') {
        this._dirty = false;
        forceFirstProgress = reset(this, skip);
    }

    this._modBy = modBy;
    this._modDataCount = modDataCount;

    var step = performArgs && performArgs.step;

    if (upTask) {

        if (__DEV__) {
            assert$1(upTask._outputDueEnd != null);
        }
        this._dueEnd = upTask._outputDueEnd;
    }
    // DataTask or overallTask
    else {
        if (__DEV__) {
            assert$1(!this._progress || this._count);
        }
        this._dueEnd = this._count ? this._count(this.context) : Infinity;
    }

    // Note: Stubs, that its host overall task let it has progress, has progress.
    // If no progress, pass index from upstream to downstream each time plan called.
    if (this._progress) {
        var start = this._dueIndex;
        var end = Math.min(
            step != null ? this._dueIndex + step : Infinity,
            this._dueEnd
        );

        if (!skip && (forceFirstProgress || start < end)) {
            var progress = this._progress;
            if (isArray(progress)) {
                for (var i = 0; i < progress.length; i++) {
                    doProgress(this, progress[i], start, end, modBy, modDataCount);
                }
            }
            else {
                doProgress(this, progress, start, end, modBy, modDataCount);
            }
        }

        this._dueIndex = end;
        // If no `outputDueEnd`, assume that output data and
        // input data is the same, so use `dueIndex` as `outputDueEnd`.
        var outputDueEnd = this._settedOutputEnd != null
            ? this._settedOutputEnd : end;

        if (__DEV__) {
            // ??? Can not rollback.
            assert$1(outputDueEnd >= this._outputDueEnd);
        }

        this._outputDueEnd = outputDueEnd;
    }
    else {
        // (1) Some overall task has no progress.
        // (2) Stubs, that its host overall task do not let it has progress, has no progress.
        // This should always be performed so it can be passed to downstream.
        this._dueIndex = this._outputDueEnd = this._settedOutputEnd != null
            ? this._settedOutputEnd : this._dueEnd;
    }

    return this.unfinished();
};

var iterator = (function () {

    var end;
    var current;
    var modBy;
    var modDataCount;
    var winCount;

    var it = {
        reset: function (s, e, sStep, sCount) {
            current = s;
            end = e;

            modBy = sStep;
            modDataCount = sCount;
            winCount = Math.ceil(modDataCount / modBy);

            it.next = (modBy > 1 && modDataCount > 0) ? modNext : sequentialNext;
        }
    };

    return it;

    function sequentialNext() {
        return current < end ? current++ : null;
    }

    function modNext() {
        var dataIndex = (current % winCount) * modBy + Math.ceil(current / winCount);
        var result = current >= end
            ? null
            : dataIndex < modDataCount
            ? dataIndex
            // If modDataCount is smaller than data.count() (consider `appendData` case),
            // Use normal linear rendering mode.
            : current;
        current++;
        return result;
    }
})();

taskProto.dirty = function () {
    this._dirty = true;
    this._onDirty && this._onDirty(this.context);
};

function doProgress(taskIns, progress, start, end, modBy, modDataCount) {
    iterator.reset(start, end, modBy, modDataCount);
    taskIns._callingProgress = progress;
    taskIns._callingProgress({
        start: start, end: end, count: end - start, next: iterator.next
    }, taskIns.context);
}

function reset(taskIns, skip) {
    taskIns._dueIndex = taskIns._outputDueEnd = taskIns._dueEnd = 0;
    taskIns._settedOutputEnd = null;

    var progress;
    var forceFirstProgress;

    if (!skip && taskIns._reset) {
        progress = taskIns._reset(taskIns.context);
        if (progress && progress.progress) {
            forceFirstProgress = progress.forceFirstProgress;
            progress = progress.progress;
        }
        // To simplify no progress checking, array must has item.
        if (isArray(progress) && !progress.length) {
            progress = null;
        }
    }

    taskIns._progress = progress;
    taskIns._modBy = taskIns._modDataCount = null;

    var downstream = taskIns._downstream;
    downstream && downstream.dirty();

    return forceFirstProgress;
}

/**
 * @return {boolean}
 */
taskProto.unfinished = function () {
    return this._progress && this._dueIndex < this._dueEnd;
};

/**
 * @param {Object} downTask The downstream task.
 * @return {Object} The downstream task.
 */
taskProto.pipe = function (downTask) {
    if (__DEV__) {
        assert$1(downTask && !downTask._disposed && downTask !== this);
    }

    // If already downstream, do not dirty downTask.
    if (this._downstream !== downTask || this._dirty) {
        this._downstream = downTask;
        downTask._upstream = this;
        downTask.dirty();
    }
};

taskProto.dispose = function () {
    if (this._disposed) {
        return;
    }

    this._upstream && (this._upstream._downstream = null);
    this._downstream && (this._downstream._upstream = null);

    this._dirty = false;
    this._disposed = true;
};

taskProto.getUpstream = function () {
    return this._upstream;
};

taskProto.getDownstream = function () {
    return this._downstream;
};

taskProto.setOutputEnd = function (end) {
    // This only happend in dataTask, dataZoom, map, currently.
    // where dataZoom do not set end each time, but only set
    // when reset. So we should record the setted end, in case
    // that the stub of dataZoom perform again and earse the
    // setted end by upstream.
    this._outputDueEnd = this._settedOutputEnd = end;
};


///////////////////////////////////////////////////////////
// For stream debug (Should be commented out after used!)
// Usage: printTask(this, 'begin');
// Usage: printTask(this, null, {someExtraProp});
// function printTask(task, prefix, extra) {
//     window.ecTaskUID == null && (window.ecTaskUID = 0);
//     task.uidDebug == null && (task.uidDebug = `task_${window.ecTaskUID++}`);
//     task.agent && task.agent.uidDebug == null && (task.agent.uidDebug = `task_${window.ecTaskUID++}`);
//     var props = [];
//     if (task.__pipeline) {
//         var val = `${task.__idxInPipeline}/${task.__pipeline.tail.__idxInPipeline} ${task.agent ? '(stub)' : ''}`;
//         props.push({text: 'idx', value: val});
//     } else {
//         var stubCount = 0;
//         task.agentStubMap.each(() => stubCount++);
//         props.push({text: 'idx', value: `overall (stubs: ${stubCount})`});
//     }
//     props.push({text: 'uid', value: task.uidDebug});
//     if (task.__pipeline) {
//         props.push({text: 'pid', value: task.__pipeline.id});
//         task.agent && props.push(
//             {text: 'stubFor', value: task.agent.uidDebug}
//         );
//     }
//     props.push(
//         {text: 'dirty', value: task._dirty},
//         {text: 'dueIndex', value: task._dueIndex},
//         {text: 'dueEnd', value: task._dueEnd},
//         {text: 'outputDueEnd', value: task._outputDueEnd}
//     );
//     if (extra) {
//         Object.keys(extra).forEach(key => {
//             props.push({text: key, value: extra[key]});
//         });
//     }
//     var args = ['color: blue'];
//     var msg = `%c[${prefix || 'T'}] %c` + props.map(item => (
//         args.push('color: black', 'color: red'),
//         `${item.text}: %c${item.value}`
//     )).join('%c, ');
//     console.log.apply(console, [msg].concat(args));
//     // console.log(this);
// }

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var inner$4 = makeInner();

var SeriesModel = ComponentModel.extend({

    type: 'series.__base__',

    /**
     * @readOnly
     */
    seriesIndex: 0,

    // coodinateSystem will be injected in the echarts/CoordinateSystem
    coordinateSystem: null,

    /**
     * @type {Object}
     * @protected
     */
    defaultOption: null,

    /**
     * legend visual provider to the legend component
     * @type {Object}
     */
    // PENDING
    legendVisualProvider: null,

    /**
     * Access path of color for visual
     */
    visualColorAccessPath: 'itemStyle.color',

    /**
     * Access path of borderColor for visual
     */
    visualBorderColorAccessPath: 'itemStyle.borderColor',

    /**
     * Support merge layout params.
     * Only support 'box' now (left/right/top/bottom/width/height).
     * @type {string|Object} Object can be {ignoreSize: true}
     * @readOnly
     */
    layoutMode: null,

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

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

        this.dataTask = createTask({
            count: dataTaskCount,
            reset: dataTaskReset
        });
        this.dataTask.context = {model: this};

        this.mergeDefaultAndTheme(option, ecModel);

        prepareSource(this);


        var data = this.getInitialData(option, ecModel);
        wrapData(data, this);
        this.dataTask.context.data = data;

        if (__DEV__) {
            assert$1(data, 'getInitialData returned invalid data.');
        }

        /**
         * @type {module:echarts/data/List|module:echarts/data/Tree|module:echarts/data/Graph}
         * @private
         */
        inner$4(this).dataBeforeProcessed = data;

        // If we reverse the order (make data firstly, and then make
        // dataBeforeProcessed by cloneShallow), cloneShallow will
        // cause data.graph.data !== data when using
        // module:echarts/data/Graph or module:echarts/data/Tree.
        // See module:echarts/data/helper/linkList

        // Theoretically, it is unreasonable to call `seriesModel.getData()` in the model
        // init or merge stage, because the data can be restored. So we do not `restoreData`
        // and `setData` here, which forbids calling `seriesModel.getData()` in this stage.
        // Call `seriesModel.getRawData()` instead.
        // this.restoreData();

        autoSeriesName(this);
    },

    /**
     * Util for merge default and theme to option
     * @param  {Object} option
     * @param  {module:echarts/model/Global} ecModel
     */
    mergeDefaultAndTheme: function (option, ecModel) {
        var layoutMode = this.layoutMode;
        var inputPositionParams = layoutMode
            ? getLayoutParams(option) : {};

        // Backward compat: using subType on theme.
        // But if name duplicate between series subType
        // (for example: parallel) add component mainType,
        // add suffix 'Series'.
        var themeSubType = this.subType;
        if (ComponentModel.hasClass(themeSubType)) {
            themeSubType += 'Series';
        }
        merge(
            option,
            ecModel.getTheme().get(this.subType)
        );
        merge(option, this.getDefaultOption());

        // Default label emphasis `show`
        defaultEmphasis(option, 'label', ['show']);

        this.fillDataTextStyle(option.data);

        if (layoutMode) {
            mergeLayoutParam(option, inputPositionParams, layoutMode);
        }
    },

    mergeOption: function (newSeriesOption, ecModel) {
        // this.settingTask.dirty();

        newSeriesOption = merge(this.option, newSeriesOption, true);
        this.fillDataTextStyle(newSeriesOption.data);

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

        prepareSource(this);

        var data = this.getInitialData(newSeriesOption, ecModel);
        wrapData(data, this);
        this.dataTask.dirty();
        this.dataTask.context.data = data;

        inner$4(this).dataBeforeProcessed = data;

        autoSeriesName(this);
    },

    fillDataTextStyle: function (data) {
        // Default data label emphasis `show`
        // FIXME Tree structure data ?
        // FIXME Performance ?
        if (data && !isTypedArray(data)) {
            var props = ['show'];
            for (var i = 0; i < data.length; i++) {
                if (data[i] && data[i].label) {
                    defaultEmphasis(data[i], 'label', props);
                }
            }
        }
    },

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

    /**
     * Append data to list
     * @param {Object} params
     * @param {Array|TypedArray} params.data
     */
    appendData: function (params) {
        // FIXME ???
        // (1) If data from dataset, forbidden append.
        // (2) support append data of dataset.
        var data = this.getRawData();
        data.appendData(params.data);
    },

    /**
     * Consider some method like `filter`, `map` need make new data,
     * We should make sure that `seriesModel.getData()` get correct
     * data in the stream procedure. So we fetch data from upstream
     * each time `task.perform` called.
     * @param {string} [dataType]
     * @return {module:echarts/data/List}
     */
    getData: function (dataType) {
        var task = getCurrentTask(this);
        if (task) {
            var data = task.context.data;
            return dataType == null ? data : data.getLinkedData(dataType);
        }
        else {
            // When series is not alive (that may happen when click toolbox
            // restore or setOption with not merge mode), series data may
            // be still need to judge animation or something when graphic
            // elements want to know whether fade out.
            return inner$4(this).data;
        }
    },

    /**
     * @param {module:echarts/data/List} data
     */
    setData: function (data) {
        var task = getCurrentTask(this);
        if (task) {
            var context = task.context;
            // Consider case: filter, data sample.
            if (context.data !== data && task.modifyOutputEnd) {
                task.setOutputEnd(data.count());
            }
            context.outputData = data;
            // Caution: setData should update context.data,
            // Because getData may be called multiply in a
            // single stage and expect to get the data just
            // set. (For example, AxisProxy, x y both call
            // getData and setDate sequentially).
            // So the context.data should be fetched from
            // upstream each time when a stage starts to be
            // performed.
            if (task !== this.dataTask) {
                context.data = data;
            }
        }
        inner$4(this).data = data;
    },

    /**
     * @see {module:echarts/data/helper/sourceHelper#getSource}
     * @return {module:echarts/data/Source} source
     */
    getSource: function () {
        return getSource(this);
    },

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

    /**
     * Get base axis if has coordinate system and has axis.
     * By default use coordSys.getBaseAxis();
     * Can be overrided for some chart.
     * @return {type} description
     */
    getBaseAxis: function () {
        var coordSys = this.coordinateSystem;
        return coordSys && coordSys.getBaseAxis && coordSys.getBaseAxis();
    },

    // FIXME
    /**
     * Default tooltip formatter
     *
     * @param {number} dataIndex
     * @param {boolean} [multipleSeries=false]
     * @param {number} [dataType]
     * @param {string} [renderMode='html'] valid values: 'html' and 'richText'.
     *                                     'html' is used for rendering tooltip in extra DOM form, and the result
     *                                     string is used as DOM HTML content.
     *                                     'richText' is used for rendering tooltip in rich text form, for those where
     *                                     DOM operation is not supported.
     * @return {Object} formatted tooltip with `html` and `markers`
     */
    formatTooltip: function (dataIndex, multipleSeries, dataType, renderMode) {

        var series = this;
        renderMode = renderMode || 'html';
        var newLine = renderMode === 'html' ? '<br/>' : '\n';
        var isRichText = renderMode === 'richText';
        var markers = {};
        var markerId = 0;

        function formatArrayValue(value) {
            // ??? TODO refactor these logic.
            // check: category-no-encode-has-axis-data in dataset.html
            var vertially = reduce(value, function (vertially, val, idx) {
                var dimItem = data.getDimensionInfo(idx);
                return vertially |= dimItem && dimItem.tooltip !== false && dimItem.displayName != null;
            }, 0);

            var result = [];

            tooltipDims.length
                ? each$1(tooltipDims, function (dim) {
                    setEachItem(retrieveRawValue(data, dataIndex, dim), dim);
                })
                // By default, all dims is used on tooltip.
                : each$1(value, setEachItem);

            function setEachItem(val, dim) {
                var dimInfo = data.getDimensionInfo(dim);
                // If `dimInfo.tooltip` is not set, show tooltip.
                if (!dimInfo || dimInfo.otherDims.tooltip === false) {
                    return;
                }
                var dimType = dimInfo.type;
                var markName = 'sub' + series.seriesIndex + 'at' + markerId;
                var dimHead = getTooltipMarker({
                    color: color,
                    type: 'subItem',
                    renderMode: renderMode,
                    markerId: markName
                });

                var dimHeadStr = typeof dimHead === 'string' ? dimHead : dimHead.content;
                var valStr = (vertially
                        ? dimHeadStr + encodeHTML(dimInfo.displayName || '-') + ': '
                        : ''
                    )
                    // FIXME should not format time for raw data?
                    + encodeHTML(dimType === 'ordinal'
                        ? val + ''
                        : dimType === 'time'
                        ? (multipleSeries ? '' : formatTime('yyyy/MM/dd hh:mm:ss', val))
                        : addCommas(val)
                    );
                valStr && result.push(valStr);

                if (isRichText) {
                    markers[markName] = color;
                    ++markerId;
                }
            }

            var newLine = vertially ? (isRichText ? '\n' : '<br/>') : '';
            var content = newLine + result.join(newLine || ', ');
            return {
                renderMode: renderMode,
                content: content,
                style: markers
            };
        }

        function formatSingleValue(val) {
            // return encodeHTML(addCommas(val));
            return {
                renderMode: renderMode,
                content: encodeHTML(addCommas(val)),
                style: markers
            };
        }

        var data = this.getData();
        var tooltipDims = data.mapDimension('defaultedTooltip', true);
        var tooltipDimLen = tooltipDims.length;
        var value = this.getRawValue(dataIndex);
        var isValueArr = isArray(value);

        var color = data.getItemVisual(dataIndex, 'color');
        if (isObject$1(color) && color.colorStops) {
            color = (color.colorStops[0] || {}).color;
        }
        color = color || 'transparent';

        // Complicated rule for pretty tooltip.
        var formattedValue = (tooltipDimLen > 1 || (isValueArr && !tooltipDimLen))
            ? formatArrayValue(value)
            : tooltipDimLen
            ? formatSingleValue(retrieveRawValue(data, dataIndex, tooltipDims[0]))
            : formatSingleValue(isValueArr ? value[0] : value);
        var content = formattedValue.content;

        var markName = series.seriesIndex + 'at' + markerId;
        var colorEl = getTooltipMarker({
            color: color,
            type: 'item',
            renderMode: renderMode,
            markerId: markName
        });
        markers[markName] = color;
        ++markerId;

        var name = data.getName(dataIndex);

        var seriesName = this.name;
        if (!isNameSpecified(this)) {
            seriesName = '';
        }
        seriesName = seriesName
            ? encodeHTML(seriesName) + (!multipleSeries ? newLine : ': ')
            : '';

        var colorStr = typeof colorEl === 'string' ? colorEl : colorEl.content;
        var html = !multipleSeries
            ? seriesName + colorStr
                + (name
                    ? encodeHTML(name) + ': ' + content
                    : content
                )
            : colorStr + seriesName + content;

        return {
            html: html,
            markers: markers
        };
    },

    /**
     * @return {boolean}
     */
    isAnimationEnabled: function () {
        if (env$1.node) {
            return false;
        }

        var animationEnabled = this.getShallow('animation');
        if (animationEnabled) {
            if (this.getData().count() > this.getShallow('animationThreshold')) {
                animationEnabled = false;
            }
        }
        return animationEnabled;
    },

    restoreData: function () {
        this.dataTask.dirty();
    },

    getColorFromPalette: function (name, scope, requestColorNum) {
        var ecModel = this.ecModel;
        // PENDING
        var color = colorPaletteMixin.getColorFromPalette.call(this, name, scope, requestColorNum);
        if (!color) {
            color = ecModel.getColorFromPalette(name, scope, requestColorNum);
        }
        return color;
    },

    /**
     * Use `data.mapDimension(coordDim, true)` instead.
     * @deprecated
     */
    coordDimToDataDim: function (coordDim) {
        return this.getRawData().mapDimension(coordDim, true);
    },

    /**
     * Get progressive rendering count each step
     * @return {number}
     */
    getProgressive: function () {
        return this.get('progressive');
    },

    /**
     * Get progressive rendering count each step
     * @return {number}
     */
    getProgressiveThreshold: function () {
        return this.get('progressiveThreshold');
    },

    /**
     * Get data indices for show tooltip content. See tooltip.
     * @abstract
     * @param {Array.<string>|string} dim
     * @param {Array.<number>} value
     * @param {module:echarts/coord/single/SingleAxis} baseAxis
     * @return {Object} {dataIndices, nestestValue}.
     */
    getAxisTooltipData: null,

    /**
     * See tooltip.
     * @abstract
     * @param {number} dataIndex
     * @return {Array.<number>} Point of tooltip. null/undefined can be returned.
     */
    getTooltipPosition: null,

    /**
     * @see {module:echarts/stream/Scheduler}
     */
    pipeTask: null,

    /**
     * Convinient for override in extended class.
     * @protected
     * @type {Function}
     */
    preventIncremental: null,

    /**
     * @public
     * @readOnly
     * @type {Object}
     */
    pipelineContext: null

});


mixin(SeriesModel, dataFormatMixin);
mixin(SeriesModel, colorPaletteMixin);

/**
 * MUST be called after `prepareSource` called
 * Here we need to make auto series, especially for auto legend. But we
 * do not modify series.name in option to avoid side effects.
 */
function autoSeriesName(seriesModel) {
    // User specified name has higher priority, otherwise it may cause
    // series can not be queried unexpectedly.
    var name = seriesModel.name;
    if (!isNameSpecified(seriesModel)) {
        seriesModel.name = getSeriesAutoName(seriesModel) || name;
    }
}

function getSeriesAutoName(seriesModel) {
    var data = seriesModel.getRawData();
    var dataDims = data.mapDimension('seriesName', true);
    var nameArr = [];
    each$1(dataDims, function (dataDim) {
        var dimInfo = data.getDimensionInfo(dataDim);
        dimInfo.displayName && nameArr.push(dimInfo.displayName);
    });
    return nameArr.join(' ');
}

function dataTaskCount(context) {
    return context.model.getRawData().count();
}

function dataTaskReset(context) {
    var seriesModel = context.model;
    seriesModel.setData(seriesModel.getRawData().cloneShallow());
    return dataTaskProgress;
}

function dataTaskProgress(param, context) {
    // Avoid repead cloneShallow when data just created in reset.
    if (context.outputData && param.end > context.outputData.count()) {
        context.model.getRawData().cloneShallow(context.outputData);
    }
}

// TODO refactor
function wrapData(data, seriesModel) {
    each$1(data.CHANGABLE_METHODS, function (methodName) {
        data.wrapMethod(methodName, curry(onDataSelfChange, seriesModel));
    });
}

function onDataSelfChange(seriesModel) {
    var task = getCurrentTask(seriesModel);
    if (task) {
        // Consider case: filter, selectRange
        task.setOutputEnd(this.count());
    }
}

function getCurrentTask(seriesModel) {
    var scheduler = (seriesModel.ecModel || {}).scheduler;
    var pipeline = scheduler && scheduler.getPipeline(seriesModel.uid);

    if (pipeline) {
        // When pipline finished, the currrentTask keep the last
        // task (renderTask).
        var task = pipeline.currentTask;
        if (task) {
            var agentStubMap = task.agentStubMap;
            if (agentStubMap) {
                task = agentStubMap.get(seriesModel.uid);
            }
        }
        return task;
    }
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var Component$1 = function () {
    /**
     * @type {module:zrender/container/Group}
     * @readOnly
     */
    this.group = new Group();

    /**
     * @type {string}
     * @readOnly
     */
    this.uid = getUID('viewComponent');
};

Component$1.prototype = {

    constructor: Component$1,

    init: function (ecModel, api) {},

    render: function (componentModel, ecModel, api, payload) {},

    dispose: function () {},

    /**
     * @param {string} eventType
     * @param {Object} query
     * @param {module:zrender/Element} targetEl
     * @param {Object} packedEvent
     * @return {boolen} Pass only when return `true`.
     */
    filterForExposedEvent: null

};

var componentProto = Component$1.prototype;
componentProto.updateView =
    componentProto.updateLayout =
    componentProto.updateVisual =
    function (seriesModel, ecModel, api, payload) {
        // Do nothing;
    };
// Enable Component.extend.
enableClassExtend(Component$1);

// Enable capability of registerClass, getClass, hasClass, registerSubTypeDefaulter and so on.
enableClassManagement(Component$1, {registerWhenExtend: true});

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * @return {string} If large mode changed, return string 'reset';
 */
var createRenderPlanner = function () {
    var inner = makeInner();

    return function (seriesModel) {
        var fields = inner(seriesModel);
        var pipelineContext = seriesModel.pipelineContext;

        var originalLarge = fields.large;
        var originalProgressive = fields.progressiveRender;

        // FIXME: if the planner works on a filtered series, `pipelineContext` does not
        // exists. See #11611 . Probably we need to modify this structure, see the comment
        // on `performRawSeries` in `Schedular.js`.
        var large = fields.large = pipelineContext && pipelineContext.large;
        var progressive = fields.progressiveRender = pipelineContext && pipelineContext.progressiveRender;

        return !!((originalLarge ^ large) || (originalProgressive ^ progressive)) && 'reset';
    };
};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var inner$5 = makeInner();
var renderPlanner = createRenderPlanner();

function Chart() {

    /**
     * @type {module:zrender/container/Group}
     * @readOnly
     */
    this.group = new Group();

    /**
     * @type {string}
     * @readOnly
     */
    this.uid = getUID('viewChart');

    this.renderTask = createTask({
        plan: renderTaskPlan,
        reset: renderTaskReset
    });
    this.renderTask.context = {view: this};
}

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

    /**
     * Rendering preparation in progressive mode.
     * @param  {module:echarts/model/Series} seriesModel
     * @param  {module:echarts/model/Global} ecModel
     * @param  {module:echarts/ExtensionAPI} api
     * @param  {Object} payload
     */
    incrementalPrepareRender: null,

    /**
     * Render in progressive mode.
     * @param  {Object} params See taskParams in `stream/task.js`
     * @param  {module:echarts/model/Series} seriesModel
     * @param  {module:echarts/model/Global} ecModel
     * @param  {module:echarts/ExtensionAPI} api
     * @param  {Object} payload
     */
    incrementalRender: null,

    /**
     * Update transform directly.
     * @param  {module:echarts/model/Series} seriesModel
     * @param  {module:echarts/model/Global} ecModel
     * @param  {module:echarts/ExtensionAPI} api
     * @param  {Object} payload
     * @return {Object} {update: true}
     */
    updateTransform: null,

    /**
     * The view contains the given point.
     * @interface
     * @param {Array.<number>} point
     * @return {boolean}
     */
    // containPoint: function () {}

    /**
     * @param {string} eventType
     * @param {Object} query
     * @param {module:zrender/Element} targetEl
     * @param {Object} packedEvent
     * @return {boolen} Pass only when return `true`.
     */
    filterForExposedEvent: null

};

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 'normal'|'emphasis'
 * @param {number} highlightDigit
 */
function elSetState(el, state, highlightDigit) {
    if (el) {
        el.trigger(state, highlightDigit);
        if (el.isGroup
            // Simple optimize.
            && !isHighDownDispatcher(el)
        ) {
            for (var i = 0, len = el.childCount(); i < len; i++) {
                elSetState(el.childAt(i), state, highlightDigit);
            }
        }
    }
}

/**
 * @param {module:echarts/data/List} data
 * @param {Object} payload
 * @param {string} state 'normal'|'emphasis'
 */
function toggleHighlight(data, payload, state) {
    var dataIndex = queryDataIndex(data, payload);

    var highlightDigit = (payload && payload.highlightKey != null)
        ? getHighlightDigit(payload.highlightKey)
        : null;

    if (dataIndex != null) {
        each$1(normalizeToArray(dataIndex), function (dataIdx) {
            elSetState(data.getItemGraphicEl(dataIdx), state, highlightDigit);
        });
    }
    else {
        data.eachItemGraphicEl(function (el) {
            elSetState(el, state, highlightDigit);
        });
    }
}

// Enable Chart.extend.
enableClassExtend(Chart, ['dispose']);

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

Chart.markUpdateMethod = function (payload, methodName) {
    inner$5(payload).updateMethod = methodName;
};

function renderTaskPlan(context) {
    return renderPlanner(context.model);
}

function renderTaskReset(context) {
    var seriesModel = context.model;
    var ecModel = context.ecModel;
    var api = context.api;
    var payload = context.payload;
    // ???! remove updateView updateVisual
    var progressiveRender = seriesModel.pipelineContext.progressiveRender;
    var view = context.view;

    var updateMethod = payload && inner$5(payload).updateMethod;
    var methodName = progressiveRender
        ? 'incrementalPrepareRender'
        : (updateMethod && view[updateMethod])
        ? updateMethod
        // `appendData` is also supported when data amount
        // is less than progressive threshold.
        : 'render';

    if (methodName !== 'render') {
        view[methodName](seriesModel, ecModel, api, payload);
    }

    return progressMethodMap[methodName];
}

var progressMethodMap = {
    incrementalPrepareRender: {
        progress: function (params, context) {
            context.view.incrementalRender(
                params, context.model, context.ecModel, context.api, context.payload
            );
        }
    },
    render: {
        // Put view.render in `progress` to support appendData. But in this case
        // view.render should not be called in reset, otherwise it will be called
        // twise. Use `forceFirstProgress` to make sure that view.render is called
        // in any cases.
        forceFirstProgress: true,
        progress: function (params, context) {
            context.view.render(
                context.model, context.ecModel, context.api, context.payload
            );
        }
    }
};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/


var ORIGIN_METHOD = '\0__throttleOriginMethod';
var RATE = '\0__throttleRate';
var THROTTLE_TYPE = '\0__throttleType';

/**
 * @public
 * @param {(Function)} fn
 * @param {number} [delay=0] Unit: ms.
 * @param {boolean} [debounce=false]
 *        true: If call interval less than `delay`, only the last call works.
 *        false: If call interval less than `delay, call works on fixed rate.
 * @return {(Function)} throttled fn.
 */
function throttle(fn, delay, debounce) {

    var currCall;
    var lastCall = 0;
    var lastExec = 0;
    var timer = null;
    var diff;
    var scope;
    var args;
    var debounceNextCall;

    delay = delay || 0;

    function exec() {
        lastExec = (new Date()).getTime();
        timer = null;
        fn.apply(scope, args || []);
    }

    var cb = function () {
        currCall = (new Date()).getTime();
        scope = this;
        args = arguments;
        var thisDelay = debounceNextCall || delay;
        var thisDebounce = debounceNextCall || debounce;
        debounceNextCall = null;
        diff = currCall - (thisDebounce ? lastCall : lastExec) - thisDelay;

        clearTimeout(timer);

        // Here we should make sure that: the `exec` SHOULD NOT be called later
        // than a new call of `cb`, that is, preserving the command order. Consider
        // calculating "scale rate" when roaming as an example. When a call of `cb`
        // happens, either the `exec` is called dierectly, or the call is delayed.
        // But the delayed call should never be later than next call of `cb`. Under
        // this assurance, we can simply update view state each time `dispatchAction`
        // triggered by user roaming, but not need to add extra code to avoid the
        // state being "rolled-back".
        if (thisDebounce) {
            timer = setTimeout(exec, thisDelay);
        }
        else {
            if (diff >= 0) {
                exec();
            }
            else {
                timer = setTimeout(exec, -diff);
            }
        }

        lastCall = currCall;
    };

    /**
     * Clear throttle.
     * @public
     */
    cb.clear = function () {
        if (timer) {
            clearTimeout(timer);
            timer = null;
        }
    };

    /**
     * Enable debounce once.
     */
    cb.debounceNextCall = function (debounceDelay) {
        debounceNextCall = debounceDelay;
    };

    return cb;
}

/**
 * Create throttle method or update throttle rate.
 *
 * @example
 * ComponentView.prototype.render = function () {
 *     ...
 *     throttle.createOrUpdate(
 *         this,
 *         '_dispatchAction',
 *         this.model.get('throttle'),
 *         'fixRate'
 *     );
 * };
 * ComponentView.prototype.remove = function () {
 *     throttle.clear(this, '_dispatchAction');
 * };
 * ComponentView.prototype.dispose = function () {
 *     throttle.clear(this, '_dispatchAction');
 * };
 *
 * @public
 * @param {Object} obj
 * @param {string} fnAttr
 * @param {number} [rate]
 * @param {string} [throttleType='fixRate'] 'fixRate' or 'debounce'
 * @return {Function} throttled function.
 */
function createOrUpdate(obj, fnAttr, rate, throttleType) {
    var fn = obj[fnAttr];

    if (!fn) {
        return;
    }

    var originFn = fn[ORIGIN_METHOD] || fn;
    var lastThrottleType = fn[THROTTLE_TYPE];
    var lastRate = fn[RATE];

    if (lastRate !== rate || lastThrottleType !== throttleType) {
        if (rate == null || !throttleType) {
            return (obj[fnAttr] = originFn);
        }

        fn = obj[fnAttr] = throttle(
            originFn, rate, throttleType === 'debounce'
        );
        fn[ORIGIN_METHOD] = originFn;
        fn[THROTTLE_TYPE] = throttleType;
        fn[RATE] = rate;
    }

    return fn;
}

/**
 * Clear throttle. Example see throttle.createOrUpdate.
 *
 * @public
 * @param {Object} obj
 * @param {string} fnAttr
 */
function clear(obj, fnAttr) {
    var fn = obj[fnAttr];
    if (fn && fn[ORIGIN_METHOD]) {
        obj[fnAttr] = fn[ORIGIN_METHOD];
    }
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var seriesColor = {
    createOnAllSeries: true,
    performRawSeries: true,
    reset: function (seriesModel, ecModel) {
        var data = seriesModel.getData();
        var colorAccessPath = (seriesModel.visualColorAccessPath || 'itemStyle.color').split('.');
        // Set in itemStyle
        var color = seriesModel.get(colorAccessPath);
        var colorCallback = (isFunction$1(color) && !(color instanceof Gradient))
            ? color : null;
        // Default color
        if (!color || colorCallback) {
            color = seriesModel.getColorFromPalette(
                // TODO series count changed.
                seriesModel.name, null, ecModel.getSeriesCount()
            );
        }

        data.setVisual('color', color);

        var borderColorAccessPath = (seriesModel.visualBorderColorAccessPath || 'itemStyle.borderColor').split('.');
        var borderColor = seriesModel.get(borderColorAccessPath);
        data.setVisual('borderColor', borderColor);

        // Only visible series has each data be visual encoded
        if (!ecModel.isSeriesFiltered(seriesModel)) {
            if (colorCallback) {
                data.each(function (idx) {
                    data.setItemVisual(
                        idx, 'color', colorCallback(seriesModel.getDataParams(idx))
                    );
                });
            }

            // itemStyle in each data item
            var dataEach = function (data, idx) {
                var itemModel = data.getItemModel(idx);
                var color = itemModel.get(colorAccessPath, true);
                var borderColor = itemModel.get(borderColorAccessPath, true);
                if (color != null) {
                    data.setItemVisual(idx, 'color', color);
                }
                if (borderColor != null) {
                    data.setItemVisual(idx, 'borderColor', borderColor);
                }
            };

            return { dataEach: data.hasItemOption ? dataEach : null };
        }
    }
};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * Language: (Simplified) Chinese.
 */

var lang = {
    legend: {
        selector: {
            all: '全选',
            inverse: '反选'
        }
    },
    toolbox: {
        brush: {
            title: {
                rect: '矩形选择',
                polygon: '圈选',
                lineX: '横向选择',
                lineY: '纵向选择',
                keep: '保持选择',
                clear: '清除选择'
            }
        },
        dataView: {
            title: '数据视图',
            lang: ['数据视图', '关闭', '刷新']
        },
        dataZoom: {
            title: {
                zoom: '区域缩放',
                back: '区域缩放还原'
            }
        },
        magicType: {
            title: {
                line: '切换为折线图',
                bar: '切换为柱状图',
                stack: '切换为堆叠',
                tiled: '切换为平铺'
            }
        },
        restore: {
            title: '还原'
        },
        saveAsImage: {
            title: '保存为图片',
            lang: ['右键另存为图片']
        }
    },
    series: {
        typeNames: {
            pie: '饼图',
            bar: '柱状图',
            line: '折线图',
            scatter: '散点图',
            effectScatter: '涟漪散点图',
            radar: '雷达图',
            tree: '树图',
            treemap: '矩形树图',
            boxplot: '箱型图',
            candlestick: 'K线图',
            k: 'K线图',
            heatmap: '热力图',
            map: '地图',
            parallel: '平行坐标图',
            lines: '线图',
            graph: '关系图',
            sankey: '桑基图',
            funnel: '漏斗图',
            gauge: '仪表盘图',
            pictorialBar: '象形柱图',
            themeRiver: '主题河流图',
            sunburst: '旭日图'
        }
    },
    aria: {
        general: {
            withTitle: '这是一个关于“{title}”的图表。',
            withoutTitle: '这是一个图表，'
        },
        series: {
            single: {
                prefix: '',
                withName: '图表类型是{seriesType}，表示{seriesName}。',
                withoutName: '图表类型是{seriesType}。'
            },
            multiple: {
                prefix: '它由{seriesCount}个图表系列组成。',
                withName: '第{seriesId}个系列是一个表示{seriesName}的{seriesType}，',
                withoutName: '第{seriesId}个系列是一个{seriesType}，',
                separator: {
                    middle: '；',
                    end: '。'
                }
            }
        },
        data: {
            allData: '其数据是——',
            partialData: '其中，前{displayCnt}项是——',
            withName: '{name}的数据是{value}',
            withoutName: '{value}',
            separator: {
                middle: '，',
                end: ''
            }
        }
    }
};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var aria = function (dom, ecModel) {
    var ariaModel = ecModel.getModel('aria');
    if (!ariaModel.get('show')) {
        return;
    }
    else if (ariaModel.get('description')) {
        dom.setAttribute('aria-label', ariaModel.get('description'));
        return;
    }

    var seriesCnt = 0;
    ecModel.eachSeries(function (seriesModel, idx) {
        ++seriesCnt;
    }, this);

    var maxDataCnt = ariaModel.get('data.maxCount') || 10;
    var maxSeriesCnt = ariaModel.get('series.maxCount') || 10;
    var displaySeriesCnt = Math.min(seriesCnt, maxSeriesCnt);

    var ariaLabel;
    if (seriesCnt < 1) {
        // No series, no aria label
        return;
    }
    else {
        var title = getTitle();
        if (title) {
            ariaLabel = replace(getConfig('general.withTitle'), {
                title: title
            });
        }
        else {
            ariaLabel = getConfig('general.withoutTitle');
        }

        var seriesLabels = [];
        var prefix = seriesCnt > 1
            ? 'series.multiple.prefix'
            : 'series.single.prefix';
        ariaLabel += replace(getConfig(prefix), { seriesCount: seriesCnt });

        ecModel.eachSeries(function (seriesModel, idx) {
            if (idx < displaySeriesCnt) {
                var seriesLabel;

                var seriesName = seriesModel.get('name');
                var seriesTpl = 'series.'
                    + (seriesCnt > 1 ? 'multiple' : 'single') + '.';
                seriesLabel = getConfig(seriesName
                    ? seriesTpl + 'withName'
                    : seriesTpl + 'withoutName');

                seriesLabel = replace(seriesLabel, {
                    seriesId: seriesModel.seriesIndex,
                    seriesName: seriesModel.get('name'),
                    seriesType: getSeriesTypeName(seriesModel.subType)
                });

                var data = seriesModel.getData();
                window.data = data;
                if (data.count() > maxDataCnt) {
                    // Show part of data
                    seriesLabel += replace(getConfig('data.partialData'), {
                        displayCnt: maxDataCnt
                    });
                }
                else {
                    seriesLabel += getConfig('data.allData');
                }

                var dataLabels = [];
                for (var i = 0; i < data.count(); i++) {
                    if (i < maxDataCnt) {
                        var name = data.getName(i);
                        var value = retrieveRawValue(data, i);
                        dataLabels.push(
                            replace(
                                name
                                    ? getConfig('data.withName')
                                    : getConfig('data.withoutName'),
                                {
                                    name: name,
                                    value: value
                                }
                            )
                        );
                    }
                }
                seriesLabel += dataLabels
                    .join(getConfig('data.separator.middle'))
                    + getConfig('data.separator.end');

                seriesLabels.push(seriesLabel);
            }
        });

        ariaLabel += seriesLabels
            .join(getConfig('series.multiple.separator.middle'))
            + getConfig('series.multiple.separator.end');

        dom.setAttribute('aria-label', ariaLabel);
    }

    function replace(str, keyValues) {
        if (typeof str !== 'string') {
            return str;
        }

        var result = str;
        each$1(keyValues, function (value, key) {
            result = result.replace(
                new RegExp('\\{\\s*' + key + '\\s*\\}', 'g'),
                value
            );
        });
        return result;
    }

    function getConfig(path) {
        var userConfig = ariaModel.get(path);
        if (userConfig == null) {
            var pathArr = path.split('.');
            var result = lang.aria;
            for (var i = 0; i < pathArr.length; ++i) {
                result = result[pathArr[i]];
            }
            return result;
        }
        else {
            return userConfig;
        }
    }

    function getTitle() {
        var title = ecModel.getModel('title').option;
        if (title && title.length) {
            title = title[0];
        }
        return title && title.text;
    }

    function getSeriesTypeName(type) {
        return lang.series.typeNames[type] || '自定义图';
    }
};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var PI$1 = 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}
 */
var loadingDefault = function (api, opts) {
    opts = opts || {};
    defaults(opts, {
        text: 'loading',
        textColor: '#000',
        fontSize: '12px',
        maskColor: 'rgba(255, 255, 255, 0.8)',
        showSpinner: true,
        color: '#c23531',
        spinnerRadius: 10,
        lineWidth: 5,
        zlevel: 0
    });
    var group = new Group();
    var mask = new Rect({
        style: {
            fill: opts.maskColor
        },
        zlevel: opts.zlevel,
        z: 10000
    });
    group.add(mask);
    var font = opts.fontSize + ' sans-serif';
    var labelRect = new Rect({
        style: {
            fill: 'none',
            text: opts.text,
            font: font,
            textPosition: 'right',
            textDistance: 10,
            textFill: opts.textColor
        },
        zlevel: opts.zlevel,
        z: 10001
    });
    group.add(labelRect);
    if (opts.showSpinner) {
        var arc = new Arc({
            shape: {
                startAngle: -PI$1 / 2,
                endAngle: -PI$1 / 2 + 0.1,
                r: opts.spinnerRadius
            },
            style: {
                stroke: opts.color,
                lineCap: 'round',
                lineWidth: opts.lineWidth
            },
            zlevel: opts.zlevel,
            z: 10001
        });
        arc.animateShape(true)
            .when(1000, {
                endAngle: PI$1 * 3 / 2
            })
            .start('circularInOut');
        arc.animateShape(true)
            .when(1000, {
                startAngle: PI$1 * 3 / 2
            })
            .delay(300)
            .start('circularInOut');
        group.add(arc);
    }
    // Inject resize
    group.resize = function () {
        var textWidth = getWidth(opts.text, font);
        var r = opts.showSpinner ? opts.spinnerRadius : 0;
        // cx = (containerWidth - arcDiameter - textDistance - textWidth) / 2
        // textDistance needs to be calculated when both animation and text exist
        var cx = (api.getWidth() - r * 2 - (opts.showSpinner && textWidth ? 10 : 0) - textWidth) / 2
               // only show the text
               - (opts.showSpinner ? 0 : textWidth / 2);
        var cy = api.getHeight() / 2;
        opts.showSpinner && arc.setShape({
            cx: cx,
            cy: cy
        });
        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;
};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * @module echarts/stream/Scheduler
 */

/**
 * @constructor
 */
function Scheduler(ecInstance, api, dataProcessorHandlers, visualHandlers) {
    this.ecInstance = ecInstance;
    this.api = api;
    this.unfinished;

    // Fix current processors in case that in some rear cases that
    // processors might be registered after echarts instance created.
    // Register processors incrementally for a echarts instance is
    // not supported by this stream architecture.
    var dataProcessorHandlers = this._dataProcessorHandlers = dataProcessorHandlers.slice();
    var visualHandlers = this._visualHandlers = visualHandlers.slice();
    this._allHandlers = dataProcessorHandlers.concat(visualHandlers);

    /**
     * @private
     * @type {
     *     [handlerUID: string]: {
     *         seriesTaskMap?: {
     *             [seriesUID: string]: Task
     *         },
     *         overallTask?: Task
     *     }
     * }
     */
    this._stageTaskMap = createHashMap();
}

var proto = Scheduler.prototype;

/**
 * @param {module:echarts/model/Global} ecModel
 * @param {Object} payload
 */
proto.restoreData = function (ecModel, payload) {
    // TODO: Only restore needed series and components, but not all components.
    // Currently `restoreData` of all of the series and component will be called.
    // But some independent components like `title`, `legend`, `graphic`, `toolbox`,
    // `tooltip`, `axisPointer`, etc, do not need series refresh when `setOption`,
    // and some components like coordinate system, axes, dataZoom, visualMap only
    // need their target series refresh.
    // (1) If we are implementing this feature some day, we should consider these cases:
    // if a data processor depends on a component (e.g., dataZoomProcessor depends
    // on the settings of `dataZoom`), it should be re-performed if the component
    // is modified by `setOption`.
    // (2) If a processor depends on sevral series, speicified by its `getTargetSeries`,
    // it should be re-performed when the result array of `getTargetSeries` changed.
    // We use `dependencies` to cover these issues.
    // (3) How to update target series when coordinate system related components modified.

    // TODO: simply the dirty mechanism? Check whether only the case here can set tasks dirty,
    // and this case all of the tasks will be set as dirty.

    ecModel.restoreData(payload);

    // Theoretically an overall task not only depends on each of its target series, but also
    // depends on all of the series.
    // The overall task is not in pipeline, and `ecModel.restoreData` only set pipeline tasks
    // dirty. If `getTargetSeries` of an overall task returns nothing, we should also ensure
    // that the overall task is set as dirty and to be performed, otherwise it probably cause
    // state chaos. So we have to set dirty of all of the overall tasks manually, otherwise it
    // probably cause state chaos (consider `dataZoomProcessor`).
    this._stageTaskMap.each(function (taskRecord) {
        var overallTask = taskRecord.overallTask;
        overallTask && overallTask.dirty();
    });
};

// If seriesModel provided, incremental threshold is check by series data.
proto.getPerformArgs = function (task, isBlock) {
    // For overall task
    if (!task.__pipeline) {
        return;
    }

    var pipeline = this._pipelineMap.get(task.__pipeline.id);
    var pCtx = pipeline.context;
    var incremental = !isBlock
        && pipeline.progressiveEnabled
        && (!pCtx || pCtx.progressiveRender)
        && task.__idxInPipeline > pipeline.blockIndex;

    var step = incremental ? pipeline.step : null;
    var modDataCount = pCtx && pCtx.modDataCount;
    var modBy = modDataCount != null ? Math.ceil(modDataCount / step) : null;

    return {step: step, modBy: modBy, modDataCount: modDataCount};
};

proto.getPipeline = function (pipelineId) {
    return this._pipelineMap.get(pipelineId);
};

/**
 * Current, progressive rendering starts from visual and layout.
 * Always detect render mode in the same stage, avoiding that incorrect
 * detection caused by data filtering.
 * Caution:
 * `updateStreamModes` use `seriesModel.getData()`.
 */
proto.updateStreamModes = function (seriesModel, view) {
    var pipeline = this._pipelineMap.get(seriesModel.uid);
    var data = seriesModel.getData();
    var dataLen = data.count();

    // `progressiveRender` means that can render progressively in each
    // animation frame. Note that some types of series do not provide
    // `view.incrementalPrepareRender` but support `chart.appendData`. We
    // use the term `incremental` but not `progressive` to describe the
    // case that `chart.appendData`.
    var progressiveRender = pipeline.progressiveEnabled
        && view.incrementalPrepareRender
        && dataLen >= pipeline.threshold;

    var large = seriesModel.get('large') && dataLen >= seriesModel.get('largeThreshold');

    // TODO: modDataCount should not updated if `appendData`, otherwise cause whole repaint.
    // see `test/candlestick-large3.html`
    var modDataCount = seriesModel.get('progressiveChunkMode') === 'mod' ? dataLen : null;

    seriesModel.pipelineContext = pipeline.context = {
        progressiveRender: progressiveRender,
        modDataCount: modDataCount,
        large: large
    };
};

proto.restorePipelines = function (ecModel) {
    var scheduler = this;
    var pipelineMap = scheduler._pipelineMap = createHashMap();

    ecModel.eachSeries(function (seriesModel) {
        var progressive = seriesModel.getProgressive();
        var pipelineId = seriesModel.uid;

        pipelineMap.set(pipelineId, {
            id: pipelineId,
            head: null,
            tail: null,
            threshold: seriesModel.getProgressiveThreshold(),
            progressiveEnabled: progressive
                && !(seriesModel.preventIncremental && seriesModel.preventIncremental()),
            blockIndex: -1,
            step: Math.round(progressive || 700),
            count: 0
        });

        pipe(scheduler, seriesModel, seriesModel.dataTask);
    });
};

proto.prepareStageTasks = function () {
    var stageTaskMap = this._stageTaskMap;
    var ecModel = this.ecInstance.getModel();
    var api = this.api;

    each$1(this._allHandlers, function (handler) {
        var record = stageTaskMap.get(handler.uid) || stageTaskMap.set(handler.uid, []);

        handler.reset && createSeriesStageTask(this, handler, record, ecModel, api);
        handler.overallReset && createOverallStageTask(this, handler, record, ecModel, api);
    }, this);
};

proto.prepareView = function (view, model, ecModel, api) {
    var renderTask = view.renderTask;
    var context = renderTask.context;

    context.model = model;
    context.ecModel = ecModel;
    context.api = api;

    renderTask.__block = !view.incrementalPrepareRender;

    pipe(this, model, renderTask);
};


proto.performDataProcessorTasks = function (ecModel, payload) {
    // If we do not use `block` here, it should be considered when to update modes.
    performStageTasks(this, this._dataProcessorHandlers, ecModel, payload, {block: true});
};

// opt
// opt.visualType: 'visual' or 'layout'
// opt.setDirty
proto.performVisualTasks = function (ecModel, payload, opt) {
    performStageTasks(this, this._visualHandlers, ecModel, payload, opt);
};

function performStageTasks(scheduler, stageHandlers, ecModel, payload, opt) {
    opt = opt || {};
    var unfinished;

    each$1(stageHandlers, function (stageHandler, idx) {
        if (opt.visualType && opt.visualType !== stageHandler.visualType) {
            return;
        }

        var stageHandlerRecord = scheduler._stageTaskMap.get(stageHandler.uid);
        var seriesTaskMap = stageHandlerRecord.seriesTaskMap;
        var overallTask = stageHandlerRecord.overallTask;

        if (overallTask) {
            var overallNeedDirty;
            var agentStubMap = overallTask.agentStubMap;
            agentStubMap.each(function (stub) {
                if (needSetDirty(opt, stub)) {
                    stub.dirty();
                    overallNeedDirty = true;
                }
            });
            overallNeedDirty && overallTask.dirty();
            updatePayload(overallTask, payload);
            var performArgs = scheduler.getPerformArgs(overallTask, opt.block);
            // Execute stubs firstly, which may set the overall task dirty,
            // then execute the overall task. And stub will call seriesModel.setData,
            // which ensures that in the overallTask seriesModel.getData() will not
            // return incorrect data.
            agentStubMap.each(function (stub) {
                stub.perform(performArgs);
            });
            unfinished |= overallTask.perform(performArgs);
        }
        else if (seriesTaskMap) {
            seriesTaskMap.each(function (task, pipelineId) {
                if (needSetDirty(opt, task)) {
                    task.dirty();
                }
                var performArgs = scheduler.getPerformArgs(task, opt.block);
                // FIXME
                // if intending to decalare `performRawSeries` in handlers, only
                // stream-independent (specifically, data item independent) operations can be
                // performed. Because is a series is filtered, most of the tasks will not
                // be performed. A stream-dependent operation probably cause wrong biz logic.
                // Perhaps we should not provide a separate callback for this case instead
                // of providing the config `performRawSeries`. The stream-dependent operaions
                // and stream-independent operations should better not be mixed.
                performArgs.skip = !stageHandler.performRawSeries
                    && ecModel.isSeriesFiltered(task.context.model);
                updatePayload(task, payload);
                unfinished |= task.perform(performArgs);
            });
        }
    });

    function needSetDirty(opt, task) {
        return opt.setDirty && (!opt.dirtyMap || opt.dirtyMap.get(task.__pipeline.id));
    }

    scheduler.unfinished |= unfinished;
}

proto.performSeriesTasks = function (ecModel) {
    var unfinished;

    ecModel.eachSeries(function (seriesModel) {
        // Progress to the end for dataInit and dataRestore.
        unfinished |= seriesModel.dataTask.perform();
    });

    this.unfinished |= unfinished;
};

proto.plan = function () {
    // Travel pipelines, check block.
    this._pipelineMap.each(function (pipeline) {
        var task = pipeline.tail;
        do {
            if (task.__block) {
                pipeline.blockIndex = task.__idxInPipeline;
                break;
            }
            task = task.getUpstream();
        }
        while (task);
    });
};

var updatePayload = proto.updatePayload = function (task, payload) {
    payload !== 'remain' && (task.context.payload = payload);
};

function createSeriesStageTask(scheduler, stageHandler, stageHandlerRecord, ecModel, api) {
    var seriesTaskMap = stageHandlerRecord.seriesTaskMap
        || (stageHandlerRecord.seriesTaskMap = createHashMap());
    var seriesType = stageHandler.seriesType;
    var getTargetSeries = stageHandler.getTargetSeries;

    // If a stageHandler should cover all series, `createOnAllSeries` should be declared mandatorily,
    // to avoid some typo or abuse. Otherwise if an extension do not specify a `seriesType`,
    // it works but it may cause other irrelevant charts blocked.
    if (stageHandler.createOnAllSeries) {
        ecModel.eachRawSeries(create);
    }
    else if (seriesType) {
        ecModel.eachRawSeriesByType(seriesType, create);
    }
    else if (getTargetSeries) {
        getTargetSeries(ecModel, api).each(create);
    }

    function create(seriesModel) {
        var pipelineId = seriesModel.uid;

        // Init tasks for each seriesModel only once.
        // Reuse original task instance.
        var task = seriesTaskMap.get(pipelineId)
            || seriesTaskMap.set(pipelineId, createTask({
                plan: seriesTaskPlan,
                reset: seriesTaskReset,
                count: seriesTaskCount
            }));
        task.context = {
            model: seriesModel,
            ecModel: ecModel,
            api: api,
            useClearVisual: stageHandler.isVisual && !stageHandler.isLayout,
            plan: stageHandler.plan,
            reset: stageHandler.reset,
            scheduler: scheduler
        };
        pipe(scheduler, seriesModel, task);
    }

    // Clear unused series tasks.
    var pipelineMap = scheduler._pipelineMap;
    seriesTaskMap.each(function (task, pipelineId) {
        if (!pipelineMap.get(pipelineId)) {
            task.dispose();
            seriesTaskMap.removeKey(pipelineId);
        }
    });
}

function createOverallStageTask(scheduler, stageHandler, stageHandlerRecord, ecModel, api) {
    var overallTask = stageHandlerRecord.overallTask = stageHandlerRecord.overallTask
        // For overall task, the function only be called on reset stage.
        || createTask({reset: overallTaskReset});

    overallTask.context = {
        ecModel: ecModel,
        api: api,
        overallReset: stageHandler.overallReset,
        scheduler: scheduler
    };

    // Reuse orignal stubs.
    var agentStubMap = overallTask.agentStubMap = overallTask.agentStubMap || createHashMap();

    var seriesType = stageHandler.seriesType;
    var getTargetSeries = stageHandler.getTargetSeries;
    var overallProgress = true;
    var modifyOutputEnd = stageHandler.modifyOutputEnd;

    // An overall task with seriesType detected or has `getTargetSeries`, we add
    // stub in each pipelines, it will set the overall task dirty when the pipeline
    // progress. Moreover, to avoid call the overall task each frame (too frequent),
    // we set the pipeline block.
    if (seriesType) {
        ecModel.eachRawSeriesByType(seriesType, createStub);
    }
    else if (getTargetSeries) {
        getTargetSeries(ecModel, api).each(createStub);
    }
    // Otherwise, (usually it is legancy case), the overall task will only be
    // executed when upstream dirty. Otherwise the progressive rendering of all
    // pipelines will be disabled unexpectedly. But it still needs stubs to receive
    // dirty info from upsteam.
    else {
        overallProgress = false;
        each$1(ecModel.getSeries(), createStub);
    }

    function createStub(seriesModel) {
        var pipelineId = seriesModel.uid;
        var stub = agentStubMap.get(pipelineId);
        if (!stub) {
            stub = agentStubMap.set(pipelineId, createTask(
                {reset: stubReset, onDirty: stubOnDirty}
            ));
            // When the result of `getTargetSeries` changed, the overallTask
            // should be set as dirty and re-performed.
            overallTask.dirty();
        }
        stub.context = {
            model: seriesModel,
            overallProgress: overallProgress,
            modifyOutputEnd: modifyOutputEnd
        };
        stub.agent = overallTask;
        stub.__block = overallProgress;

        pipe(scheduler, seriesModel, stub);
    }

    // Clear unused stubs.
    var pipelineMap = scheduler._pipelineMap;
    agentStubMap.each(function (stub, pipelineId) {
        if (!pipelineMap.get(pipelineId)) {
            stub.dispose();
            // When the result of `getTargetSeries` changed, the overallTask
            // should be set as dirty and re-performed.
            overallTask.dirty();
            agentStubMap.removeKey(pipelineId);
        }
    });
}

function overallTaskReset(context) {
    context.overallReset(
        context.ecModel, context.api, context.payload
    );
}

function stubReset(context, upstreamContext) {
    return context.overallProgress && stubProgress;
}

function stubProgress() {
    this.agent.dirty();
    this.getDownstream().dirty();
}

function stubOnDirty() {
    this.agent && this.agent.dirty();
}

function seriesTaskPlan(context) {
    return context.plan && context.plan(
        context.model, context.ecModel, context.api, context.payload
    );
}

function seriesTaskReset(context) {
    if (context.useClearVisual) {
        context.data.clearAllVisual();
    }
    var resetDefines = context.resetDefines = normalizeToArray(context.reset(
        context.model, context.ecModel, context.api, context.payload
    ));
    return resetDefines.length > 1
        ? map(resetDefines, function (v, idx) {
            return makeSeriesTaskProgress(idx);
        })
        : singleSeriesTaskProgress;
}

var singleSeriesTaskProgress = makeSeriesTaskProgress(0);

function makeSeriesTaskProgress(resetDefineIdx) {
    return function (params, context) {
        var data = context.data;
        var resetDefine = context.resetDefines[resetDefineIdx];

        if (resetDefine && resetDefine.dataEach) {
            for (var i = params.start; i < params.end; i++) {
                resetDefine.dataEach(data, i);
            }
        }
        else if (resetDefine && resetDefine.progress) {
            resetDefine.progress(params, data);
        }
    };
}

function seriesTaskCount(context) {
    return context.data.count();
}

function pipe(scheduler, seriesModel, task) {
    var pipelineId = seriesModel.uid;
    var pipeline = scheduler._pipelineMap.get(pipelineId);
    !pipeline.head && (pipeline.head = task);
    pipeline.tail && pipeline.tail.pipe(task);
    pipeline.tail = task;
    task.__idxInPipeline = pipeline.count++;
    task.__pipeline = pipeline;
}

Scheduler.wrapStageHandler = function (stageHandler, visualType) {
    if (isFunction$1(stageHandler)) {
        stageHandler = {
            overallReset: stageHandler,
            seriesType: detectSeriseType(stageHandler)
        };
    }

    stageHandler.uid = getUID('stageHandler');
    visualType && (stageHandler.visualType = visualType);

    return stageHandler;
};



/**
 * Only some legacy stage handlers (usually in echarts extensions) are pure function.
 * To ensure that they can work normally, they should work in block mode, that is,
 * they should not be started util the previous tasks finished. So they cause the
 * progressive rendering disabled. We try to detect the series type, to narrow down
 * the block range to only the series type they concern, but not all series.
 */
function detectSeriseType(legacyFunc) {
    seriesType = null;
    try {
        // Assume there is no async when calling `eachSeriesByType`.
        legacyFunc(ecModelMock, apiMock);
    }
    catch (e) {
    }
    return seriesType;
}

var ecModelMock = {};
var apiMock = {};
var seriesType;

mockMethods(ecModelMock, GlobalModel);
mockMethods(apiMock, ExtensionAPI);
ecModelMock.eachSeriesByType = ecModelMock.eachRawSeriesByType = function (type) {
    seriesType = type;
};
ecModelMock.eachComponent = function (cond) {
    if (cond.mainType === 'series' && cond.subType) {
        seriesType = cond.subType;
    }
};

function mockMethods(target, Clz) {
    /* eslint-disable */
    for (var name in Clz.prototype) {
        // Do not use hasOwnProperty
        target[name] = noop;
    }
    /* eslint-enable */
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var colorAll = [
    '#37A2DA', '#32C5E9', '#67E0E3', '#9FE6B8', '#FFDB5C', '#ff9f7f',
    '#fb7293', '#E062AE', '#E690D1', '#e7bcf3', '#9d96f5', '#8378EA', '#96BFFF'
];

var lightTheme = {

    color: colorAll,

    colorLayer: [
        ['#37A2DA', '#ffd85c', '#fd7b5f'],
        ['#37A2DA', '#67E0E3', '#FFDB5C', '#ff9f7f', '#E062AE', '#9d96f5'],
        ['#37A2DA', '#32C5E9', '#9FE6B8', '#FFDB5C', '#ff9f7f', '#fb7293', '#e7bcf3', '#8378EA', '#96BFFF'],
        colorAll
    ]
};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var contrastColor = '#eee';
var axisCommon = function () {
    return {
        axisLine: {
            lineStyle: {
                color: contrastColor
            }
        },
        axisTick: {
            lineStyle: {
                color: contrastColor
            }
        },
        axisLabel: {
            textStyle: {
                color: contrastColor
            }
        },
        splitLine: {
            lineStyle: {
                type: 'dashed',
                color: '#aaa'
            }
        },
        splitArea: {
            areaStyle: {
                color: contrastColor
            }
        }
    };
};

var colorPalette = [
    '#dd6b66', '#759aa0', '#e69d87', '#8dc1a9', '#ea7e53',
    '#eedd78', '#73a373', '#73b9bc', '#7289ab', '#91ca8c', '#f49f42'
];
var theme = {
    color: colorPalette,
    backgroundColor: '#333',
    tooltip: {
        axisPointer: {
            lineStyle: {
                color: contrastColor
            },
            crossStyle: {
                color: contrastColor
            },
            label: {
                color: '#000'
            }
        }
    },
    legend: {
        textStyle: {
            color: contrastColor
        }
    },
    textStyle: {
        color: contrastColor
    },
    title: {
        textStyle: {
            color: contrastColor
        }
    },
    toolbox: {
        iconStyle: {
            normal: {
                borderColor: contrastColor
            }
        }
    },
    dataZoom: {
        textStyle: {
            color: contrastColor
        }
    },
    visualMap: {
        textStyle: {
            color: contrastColor
        }
    },
    timeline: {
        lineStyle: {
            color: contrastColor
        },
        itemStyle: {
            normal: {
                color: colorPalette[1]
            }
        },
        label: {
            normal: {
                textStyle: {
                    color: contrastColor
                }
            }
        },
        controlStyle: {
            normal: {
                color: contrastColor,
                borderColor: contrastColor
            }
        }
    },
    timeAxis: axisCommon(),
    logAxis: axisCommon(),
    valueAxis: axisCommon(),
    categoryAxis: axisCommon(),

    line: {
        symbol: 'circle'
    },
    graph: {
        color: colorPalette
    },
    gauge: {
        title: {
            textStyle: {
                color: contrastColor
            }
        }
    },
    candlestick: {
        itemStyle: {
            normal: {
                color: '#FD1050',
                color0: '#0CF49B',
                borderColor: '#FD1050',
                borderColor0: '#0CF49B'
            }
        }
    }
};
theme.categoryAxis.splitLine.show = false;

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * This module is imported by echarts directly.
 *
 * Notice:
 * Always keep this file exists for backward compatibility.
 * Because before 4.1.0, dataset is an optional component,
 * some users may import this module manually.
 */

ComponentModel.extend({

    type: 'dataset',

    /**
     * @protected
     */
    defaultOption: {

        // 'row', 'column'
        seriesLayoutBy: SERIES_LAYOUT_BY_COLUMN,

        // null/'auto': auto detect header, see "module:echarts/data/helper/sourceHelper"
        sourceHeader: null,

        dimensions: null,

        source: null
    },

    optionUpdated: function () {
        detectSourceFormat(this);
    }

});

Component$1.extend({

    type: 'dataset'

});

/**
 * 椭圆形状
 * @module zrender/graphic/shape/Ellipse
 */

var Ellipse = Path.extend({

    type: 'ellipse',

    shape: {
        cx: 0, cy: 0,
        rx: 0, ry: 0
    },

    buildPath: function (ctx, shape) {
        var k = 0.5522848;
        var x = shape.cx;
        var y = shape.cy;
        var a = shape.rx;
        var b = shape.ry;
        var ox = a * k; // 水平控制点偏移量
        var oy = b * k; // 垂直控制点偏移量
        // 从椭圆的左端点开始顺时针绘制四条三次贝塞尔曲线
        ctx.moveTo(x - a, y);
        ctx.bezierCurveTo(x - a, y - oy, x - ox, y - b, x, y - b);
        ctx.bezierCurveTo(x + ox, y - b, x + a, y - oy, x + a, y);
        ctx.bezierCurveTo(x + a, y + oy, x + ox, y + b, x, y + b);
        ctx.bezierCurveTo(x - ox, y + b, x - a, y + oy, x - a, y);
        ctx.closePath();
    }
});

// import RadialGradient from '../graphic/RadialGradient';
// import Pattern from '../graphic/Pattern';
// import * as vector from '../core/vector';
// Most of the values can be separated by comma and/or white space.
var DILIMITER_REG = /[\s,]+/;

/**
 * For big svg string, this method might be time consuming.
 *
 * @param {string} svg xml string
 * @return {Object} xml root.
 */
function parseXML(svg) {
    if (isString(svg)) {
        var parser = new DOMParser();
        svg = parser.parseFromString(svg, 'text/xml');
    }

    // Document node. If using $.get, doc node may be input.
    if (svg.nodeType === 9) {
        svg = svg.firstChild;
    }
    // nodeName of <!DOCTYPE svg> is also 'svg'.
    while (svg.nodeName.toLowerCase() !== 'svg' || svg.nodeType !== 1) {
        svg = svg.nextSibling;
    }

    return svg;
}

function SVGParser() {
    this._defs = {};
    this._root = null;

    this._isDefine = false;
    this._isText = false;
}

SVGParser.prototype.parse = function (xml, opt) {
    opt = opt || {};

    var svg = parseXML(xml);

    if (!svg) {
        throw new Error('Illegal svg');
    }

    var root = new Group();
    this._root = root;
    // parse view port
    var viewBox = svg.getAttribute('viewBox') || '';

    // If width/height not specified, means "100%" of `opt.width/height`.
    // TODO: Other percent value not supported yet.
    var width = parseFloat(svg.getAttribute('width') || opt.width);
    var height = parseFloat(svg.getAttribute('height') || opt.height);
    // If width/height not specified, set as null for output.
    isNaN(width) && (width = null);
    isNaN(height) && (height = null);

    // Apply inline style on svg element.
    parseAttributes(svg, root, null, true);

    var child = svg.firstChild;
    while (child) {
        this._parseNode(child, root);
        child = child.nextSibling;
    }

    var viewBoxRect;
    var viewBoxTransform;

    if (viewBox) {
        var viewBoxArr = trim(viewBox).split(DILIMITER_REG);
        // Some invalid case like viewBox: 'none'.
        if (viewBoxArr.length >= 4) {
            viewBoxRect = {
                x: parseFloat(viewBoxArr[0] || 0),
                y: parseFloat(viewBoxArr[1] || 0),
                width: parseFloat(viewBoxArr[2]),
                height: parseFloat(viewBoxArr[3])
            };
        }
    }

    if (viewBoxRect && width != null && height != null) {
        viewBoxTransform = makeViewBoxTransform(viewBoxRect, width, height);

        if (!opt.ignoreViewBox) {
            // If set transform on the output group, it probably bring trouble when
            // some users only intend to show the clipped content inside the viewBox,
            // but not intend to transform the output group. So we keep the output
            // group no transform. If the user intend to use the viewBox as a
            // camera, just set `opt.ignoreViewBox` as `true` and set transfrom
            // manually according to the viewBox info in the output of this method.
            var elRoot = root;
            root = new Group();
            root.add(elRoot);
            elRoot.scale = viewBoxTransform.scale.slice();
            elRoot.position = viewBoxTransform.position.slice();
        }
    }

    // Some shapes might be overflow the viewport, which should be
    // clipped despite whether the viewBox is used, as the SVG does.
    if (!opt.ignoreRootClip && width != null && height != null) {
        root.setClipPath(new Rect({
            shape: {x: 0, y: 0, width: width, height: height}
        }));
    }

    // Set width/height on group just for output the viewport size.
    return {
        root: root,
        width: width,
        height: height,
        viewBoxRect: viewBoxRect,
        viewBoxTransform: viewBoxTransform
    };
};

SVGParser.prototype._parseNode = function (xmlNode, parentGroup) {

    var nodeName = xmlNode.nodeName.toLowerCase();

    // TODO
    // support <style>...</style> in svg, where nodeName is 'style',
    // CSS classes is defined globally wherever the style tags are declared.

    if (nodeName === 'defs') {
        // define flag
        this._isDefine = true;
    }
    else if (nodeName === 'text') {
        this._isText = true;
    }

    var el;
    if (this._isDefine) {
        var parser = defineParsers[nodeName];
        if (parser) {
            var def = parser.call(this, xmlNode);
            var id = xmlNode.getAttribute('id');
            if (id) {
                this._defs[id] = def;
            }
        }
    }
    else {
        var parser = nodeParsers[nodeName];
        if (parser) {
            el = parser.call(this, xmlNode, parentGroup);
            parentGroup.add(el);
        }
    }

    var child = xmlNode.firstChild;
    while (child) {
        if (child.nodeType === 1) {
            this._parseNode(child, el);
        }
        // Is text
        if (child.nodeType === 3 && this._isText) {
            this._parseText(child, el);
        }
        child = child.nextSibling;
    }

    // Quit define
    if (nodeName === 'defs') {
        this._isDefine = false;
    }
    else if (nodeName === 'text') {
        this._isText = false;
    }
};

SVGParser.prototype._parseText = function (xmlNode, parentGroup) {
    if (xmlNode.nodeType === 1) {
        var dx = xmlNode.getAttribute('dx') || 0;
        var dy = xmlNode.getAttribute('dy') || 0;
        this._textX += parseFloat(dx);
        this._textY += parseFloat(dy);
    }

    var text = new Text({
        style: {
            text: xmlNode.textContent,
            transformText: true
        },
        position: [this._textX || 0, this._textY || 0]
    });

    inheritStyle(parentGroup, text);
    parseAttributes(xmlNode, text, this._defs);

    var fontSize = text.style.fontSize;
    if (fontSize && fontSize < 9) {
        // PENDING
        text.style.fontSize = 9;
        text.scale = text.scale || [1, 1];
        text.scale[0] *= fontSize / 9;
        text.scale[1] *= fontSize / 9;
    }

    var rect = text.getBoundingRect();
    this._textX += rect.width;

    parentGroup.add(text);

    return text;
};

var nodeParsers = {
    'g': function (xmlNode, parentGroup) {
        var g = new Group();
        inheritStyle(parentGroup, g);
        parseAttributes(xmlNode, g, this._defs);

        return g;
    },
    'rect': function (xmlNode, parentGroup) {
        var rect = new Rect();
        inheritStyle(parentGroup, rect);
        parseAttributes(xmlNode, rect, this._defs);

        rect.setShape({
            x: parseFloat(xmlNode.getAttribute('x') || 0),
            y: parseFloat(xmlNode.getAttribute('y') || 0),
            width: parseFloat(xmlNode.getAttribute('width') || 0),
            height: parseFloat(xmlNode.getAttribute('height') || 0)
        });

        // console.log(xmlNode.getAttribute('transform'));
        // console.log(rect.transform);

        return rect;
    },
    'circle': function (xmlNode, parentGroup) {
        var circle = new Circle();
        inheritStyle(parentGroup, circle);
        parseAttributes(xmlNode, circle, this._defs);

        circle.setShape({
            cx: parseFloat(xmlNode.getAttribute('cx') || 0),
            cy: parseFloat(xmlNode.getAttribute('cy') || 0),
            r: parseFloat(xmlNode.getAttribute('r') || 0)
        });

        return circle;
    },
    'line': function (xmlNode, parentGroup) {
        var line = new Line();
        inheritStyle(parentGroup, line);
        parseAttributes(xmlNode, line, this._defs);

        line.setShape({
            x1: parseFloat(xmlNode.getAttribute('x1') || 0),
            y1: parseFloat(xmlNode.getAttribute('y1') || 0),
            x2: parseFloat(xmlNode.getAttribute('x2') || 0),
            y2: parseFloat(xmlNode.getAttribute('y2') || 0)
        });

        return line;
    },
    'ellipse': function (xmlNode, parentGroup) {
        var ellipse = new Ellipse();
        inheritStyle(parentGroup, ellipse);
        parseAttributes(xmlNode, ellipse, this._defs);

        ellipse.setShape({
            cx: parseFloat(xmlNode.getAttribute('cx') || 0),
            cy: parseFloat(xmlNode.getAttribute('cy') || 0),
            rx: parseFloat(xmlNode.getAttribute('rx') || 0),
            ry: parseFloat(xmlNode.getAttribute('ry') || 0)
        });
        return ellipse;
    },
    'polygon': function (xmlNode, parentGroup) {
        var points = xmlNode.getAttribute('points');
        if (points) {
            points = parsePoints(points);
        }
        var polygon = new Polygon({
            shape: {
                points: points || []
            }
        });

        inheritStyle(parentGroup, polygon);
        parseAttributes(xmlNode, polygon, this._defs);

        return polygon;
    },
    'polyline': function (xmlNode, parentGroup) {
        var path = new Path();
        inheritStyle(parentGroup, path);
        parseAttributes(xmlNode, path, this._defs);

        var points = xmlNode.getAttribute('points');
        if (points) {
            points = parsePoints(points);
        }
        var polyline = new Polyline({
            shape: {
                points: points || []
            }
        });

        return polyline;
    },
    'image': function (xmlNode, parentGroup) {
        var img = new ZImage();
        inheritStyle(parentGroup, img);
        parseAttributes(xmlNode, img, this._defs);

        img.setStyle({
            image: xmlNode.getAttribute('xlink:href'),
            x: xmlNode.getAttribute('x'),
            y: xmlNode.getAttribute('y'),
            width: xmlNode.getAttribute('width'),
            height: xmlNode.getAttribute('height')
        });

        return img;
    },
    'text': function (xmlNode, parentGroup) {
        var x = xmlNode.getAttribute('x') || 0;
        var y = xmlNode.getAttribute('y') || 0;
        var dx = xmlNode.getAttribute('dx') || 0;
        var dy = xmlNode.getAttribute('dy') || 0;

        this._textX = parseFloat(x) + parseFloat(dx);
        this._textY = parseFloat(y) + parseFloat(dy);

        var g = new Group();
        inheritStyle(parentGroup, g);
        parseAttributes(xmlNode, g, this._defs);

        return g;
    },
    'tspan': function (xmlNode, parentGroup) {
        var x = xmlNode.getAttribute('x');
        var y = xmlNode.getAttribute('y');
        if (x != null) {
            // new offset x
            this._textX = parseFloat(x);
        }
        if (y != null) {
            // new offset y
            this._textY = parseFloat(y);
        }
        var dx = xmlNode.getAttribute('dx') || 0;
        var dy = xmlNode.getAttribute('dy') || 0;

        var g = new Group();

        inheritStyle(parentGroup, g);
        parseAttributes(xmlNode, g, this._defs);


        this._textX += dx;
        this._textY += dy;

        return g;
    },
    'path': function (xmlNode, parentGroup) {
        // TODO svg fill rule
        // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/fill-rule
        // path.style.globalCompositeOperation = 'xor';
        var d = xmlNode.getAttribute('d') || '';

        // Performance sensitive.

        var path = createFromString(d);

        inheritStyle(parentGroup, path);
        parseAttributes(xmlNode, path, this._defs);

        return path;
    }
};

var defineParsers = {

    'lineargradient': function (xmlNode) {
        var x1 = parseInt(xmlNode.getAttribute('x1') || 0, 10);
        var y1 = parseInt(xmlNode.getAttribute('y1') || 0, 10);
        var x2 = parseInt(xmlNode.getAttribute('x2') || 10, 10);
        var y2 = parseInt(xmlNode.getAttribute('y2') || 0, 10);

        var gradient = new LinearGradient(x1, y1, x2, y2);

        _parseGradientColorStops(xmlNode, gradient);

        return gradient;
    },

    'radialgradient': function (xmlNode) {

    }
};

function _parseGradientColorStops(xmlNode, gradient) {

    var stop = xmlNode.firstChild;

    while (stop) {
        if (stop.nodeType === 1) {
            var offset = stop.getAttribute('offset');
            if (offset.indexOf('%') > 0) {  // percentage
                offset = parseInt(offset, 10) / 100;
            }
            else if (offset) {    // number from 0 to 1
                offset = parseFloat(offset);
            }
            else {
                offset = 0;
            }

            var stopColor = stop.getAttribute('stop-color') || '#000000';

            gradient.addColorStop(offset, stopColor);
        }
        stop = stop.nextSibling;
    }
}

function inheritStyle(parent, child) {
    if (parent && parent.__inheritedStyle) {
        if (!child.__inheritedStyle) {
            child.__inheritedStyle = {};
        }
        defaults(child.__inheritedStyle, parent.__inheritedStyle);
    }
}

function parsePoints(pointsString) {
    var list = trim(pointsString).split(DILIMITER_REG);
    var points = [];

    for (var i = 0; i < list.length; i += 2) {
        var x = parseFloat(list[i]);
        var y = parseFloat(list[i + 1]);
        points.push([x, y]);
    }
    return points;
}

var attributesMap = {
    'fill': 'fill',
    'stroke': 'stroke',
    'stroke-width': 'lineWidth',
    'opacity': 'opacity',
    'fill-opacity': 'fillOpacity',
    'stroke-opacity': 'strokeOpacity',
    'stroke-dasharray': 'lineDash',
    'stroke-dashoffset': 'lineDashOffset',
    'stroke-linecap': 'lineCap',
    'stroke-linejoin': 'lineJoin',
    'stroke-miterlimit': 'miterLimit',
    'font-family': 'fontFamily',
    'font-size': 'fontSize',
    'font-style': 'fontStyle',
    'font-weight': 'fontWeight',

    'text-align': 'textAlign',
    'alignment-baseline': 'textBaseline'
};

function parseAttributes(xmlNode, el, defs, onlyInlineStyle) {
    var zrStyle = el.__inheritedStyle || {};
    var isTextEl = el.type === 'text';

    // TODO Shadow
    if (xmlNode.nodeType === 1) {
        parseTransformAttribute(xmlNode, el);

        extend(zrStyle, parseStyleAttribute(xmlNode));

        if (!onlyInlineStyle) {
            for (var svgAttrName in attributesMap) {
                if (attributesMap.hasOwnProperty(svgAttrName)) {
                    var attrValue = xmlNode.getAttribute(svgAttrName);
                    if (attrValue != null) {
                        zrStyle[attributesMap[svgAttrName]] = attrValue;
                    }
                }
            }
        }
    }

    var elFillProp = isTextEl ? 'textFill' : 'fill';
    var elStrokeProp = isTextEl ? 'textStroke' : 'stroke';

    el.style = el.style || new Style();
    var elStyle = el.style;

    zrStyle.fill != null && elStyle.set(elFillProp, getPaint(zrStyle.fill, defs));
    zrStyle.stroke != null && elStyle.set(elStrokeProp, getPaint(zrStyle.stroke, defs));

    each$1([
        'lineWidth', 'opacity', 'fillOpacity', 'strokeOpacity', 'miterLimit', 'fontSize'
    ], function (propName) {
        var elPropName = (propName === 'lineWidth' && isTextEl) ? 'textStrokeWidth' : propName;
        zrStyle[propName] != null && elStyle.set(elPropName, parseFloat(zrStyle[propName]));
    });

    if (!zrStyle.textBaseline || zrStyle.textBaseline === 'auto') {
        zrStyle.textBaseline = 'alphabetic';
    }
    if (zrStyle.textBaseline === 'alphabetic') {
        zrStyle.textBaseline = 'bottom';
    }
    if (zrStyle.textAlign === 'start') {
        zrStyle.textAlign = 'left';
    }
    if (zrStyle.textAlign === 'end') {
        zrStyle.textAlign = 'right';
    }

    each$1(['lineDashOffset', 'lineCap', 'lineJoin',
        'fontWeight', 'fontFamily', 'fontStyle', 'textAlign', 'textBaseline'
    ], function (propName) {
        zrStyle[propName] != null && elStyle.set(propName, zrStyle[propName]);
    });

    if (zrStyle.lineDash) {
        el.style.lineDash = trim(zrStyle.lineDash).split(DILIMITER_REG);
    }

    if (elStyle[elStrokeProp] && elStyle[elStrokeProp] !== 'none') {
        // enable stroke
        el[elStrokeProp] = true;
    }

    el.__inheritedStyle = zrStyle;
}


var urlRegex = /url\(\s*#(.*?)\)/;
function getPaint(str, defs) {
    // if (str === 'none') {
    //     return;
    // }
    var urlMatch = defs && str && str.match(urlRegex);
    if (urlMatch) {
        var url = trim(urlMatch[1]);
        var def = defs[url];
        return def;
    }
    return str;
}

var transformRegex = /(translate|scale|rotate|skewX|skewY|matrix)\(([\-\s0-9\.e,]*)\)/g;

function parseTransformAttribute(xmlNode, node) {
    var transform = xmlNode.getAttribute('transform');
    if (transform) {
        transform = transform.replace(/,/g, ' ');
        var m = null;
        var transformOps = [];
        transform.replace(transformRegex, function (str, type, value) {
            transformOps.push(type, value);
        });
        for (var i = transformOps.length - 1; i > 0; i -= 2) {
            var value = transformOps[i];
            var type = transformOps[i - 1];
            m = m || create$1();
            switch (type) {
                case 'translate':
                    value = trim(value).split(DILIMITER_REG);
                    translate(m, m, [parseFloat(value[0]), parseFloat(value[1] || 0)]);
                    break;
                case 'scale':
                    value = trim(value).split(DILIMITER_REG);
                    scale$1(m, m, [parseFloat(value[0]), parseFloat(value[1] || value[0])]);
                    break;
                case 'rotate':
                    value = trim(value).split(DILIMITER_REG);
                    rotate(m, m, parseFloat(value[0]));
                    break;
                case 'skew':
                    value = trim(value).split(DILIMITER_REG);
                    console.warn('Skew transform is not supported yet');
                    break;
                case 'matrix':
                    var value = trim(value).split(DILIMITER_REG);
                    m[0] = parseFloat(value[0]);
                    m[1] = parseFloat(value[1]);
                    m[2] = parseFloat(value[2]);
                    m[3] = parseFloat(value[3]);
                    m[4] = parseFloat(value[4]);
                    m[5] = parseFloat(value[5]);
                    break;
            }
        }
        node.setLocalTransform(m);
    }
}

// Value may contain space.
var styleRegex = /([^\s:;]+)\s*:\s*([^:;]+)/g;
function parseStyleAttribute(xmlNode) {
    var style = xmlNode.getAttribute('style');
    var result = {};

    if (!style) {
        return result;
    }

    var styleList = {};
    styleRegex.lastIndex = 0;
    var styleRegResult;
    while ((styleRegResult = styleRegex.exec(style)) != null) {
        styleList[styleRegResult[1]] = styleRegResult[2];
    }

    for (var svgAttrName in attributesMap) {
        if (attributesMap.hasOwnProperty(svgAttrName) && styleList[svgAttrName] != null) {
            result[attributesMap[svgAttrName]] = styleList[svgAttrName];
        }
    }

    return result;
}

/**
 * @param {Array.<number>} viewBoxRect
 * @param {number} width
 * @param {number} height
 * @return {Object} {scale, position}
 */
function makeViewBoxTransform(viewBoxRect, width, height) {
    var scaleX = width / viewBoxRect.width;
    var scaleY = height / viewBoxRect.height;
    var scale = Math.min(scaleX, scaleY);
    // preserveAspectRatio 'xMidYMid'
    var viewBoxScale = [scale, scale];
    var viewBoxPosition = [
        -(viewBoxRect.x + viewBoxRect.width / 2) * scale + width / 2,
        -(viewBoxRect.y + viewBoxRect.height / 2) * scale + height / 2
    ];

    return {
        scale: viewBoxScale,
        position: viewBoxPosition
    };
}

/**
 * @param {string|XMLElement} xml
 * @param {Object} [opt]
 * @param {number} [opt.width] Default width if svg width not specified or is a percent value.
 * @param {number} [opt.height] Default height if svg height not specified or is a percent value.
 * @param {boolean} [opt.ignoreViewBox]
 * @param {boolean} [opt.ignoreRootClip]
 * @return {Object} result:
 * {
 *     root: Group, The root of the the result tree of zrender shapes,
 *     width: number, the viewport width of the SVG,
 *     height: number, the viewport height of the SVG,
 *     viewBoxRect: {x, y, width, height}, the declared viewBox rect of the SVG, if exists,
 *     viewBoxTransform: the {scale, position} calculated by viewBox and viewport, is exists.
 * }
 */

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var storage = createHashMap();

// For minimize the code size of common echarts package,
// do not put too much logic in this module.

var mapDataStorage = {

    // The format of record: see `echarts.registerMap`.
    // Compatible with previous `echarts.registerMap`.
    registerMap: function (mapName, rawGeoJson, rawSpecialAreas) {

        var records;

        if (isArray(rawGeoJson)) {
            records = rawGeoJson;
        }
        else if (rawGeoJson.svg) {
            records = [{
                type: 'svg',
                source: rawGeoJson.svg,
                specialAreas: rawGeoJson.specialAreas
            }];
        }
        else {
            // Backward compatibility.
            if (rawGeoJson.geoJson && !rawGeoJson.features) {
                rawSpecialAreas = rawGeoJson.specialAreas;
                rawGeoJson = rawGeoJson.geoJson;
            }
            records = [{
                type: 'geoJSON',
                source: rawGeoJson,
                specialAreas: rawSpecialAreas
            }];
        }

        each$1(records, function (record) {
            var type = record.type;
            type === 'geoJson' && (type = record.type = 'geoJSON');

            var parse = parsers[type];

            if (__DEV__) {
                assert$1(parse, 'Illegal map type: ' + type);
            }

            parse(record);
        });

        return storage.set(mapName, records);
    },

    retrieveMap: function (mapName) {
        return storage.get(mapName);
    }

};

var parsers = {

    geoJSON: function (record) {
        var source = record.source;
        record.geoJSON = !isString(source)
            ? source
            : (typeof JSON !== 'undefined' && JSON.parse)
            ? JSON.parse(source)
            : (new Function('return (' + source + ');'))();
    },

    // Only perform parse to XML object here, which might be time
    // consiming for large SVG.
    // Although convert XML to zrender element is also time consiming,
    // if we do it here, the clone of zrender elements has to be
    // required. So we do it once for each geo instance, util real
    // performance issues call for optimizing it.
    svg: function (record) {
        record.svgXML = parseXML(record.source);
    }

};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/
var assert = assert$1;
var each = each$1;
var isFunction = isFunction$1;
var isObject = isObject$1;
var parseClassType = ComponentModel.parseClassType;

var version = '4.9.0';

var dependencies = {
    zrender: '4.3.2'
};

var TEST_FRAME_REMAIN_TIME = 1;

var PRIORITY_PROCESSOR_FILTER = 1000;
var PRIORITY_PROCESSOR_SERIES_FILTER = 800;
var PRIORITY_PROCESSOR_DATASTACK = 900;
var PRIORITY_PROCESSOR_STATISTIC = 5000;

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

var PRIORITY = {
    PROCESSOR: {
        FILTER: PRIORITY_PROCESSOR_FILTER,
        SERIES_FILTER: PRIORITY_PROCESSOR_SERIES_FILTER,
        STATISTIC: PRIORITY_PROCESSOR_STATISTIC
    },
    VISUAL: {
        LAYOUT: PRIORITY_VISUAL_LAYOUT,
        PROGRESSIVE_LAYOUT: PRIORITY_VISUAL_PROGRESSIVE_LAYOUT,
        GLOBAL: PRIORITY_VISUAL_GLOBAL,
        CHART: PRIORITY_VISUAL_CHART,
        POST_CHART_LAYOUT: PRIORITY_VISUAL_POST_CHART_LAYOUT,
        COMPONENT: PRIORITY_VISUAL_COMPONENT,
        BRUSH: PRIORITY_VISUAL_BRUSH
    }
};

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


function createRegisterEventWithLowercaseName(method, ignoreDisposed) {
    return function (eventName, handler, context) {
        if (!ignoreDisposed && this._disposed) {
            disposedWarning(this.id);
            return;
        }

        // Event name is all lowercase
        eventName = eventName && eventName.toLowerCase();
        Eventful.prototype[method].call(this, eventName, handler, context);
    };
}

/**
 * @module echarts~MessageCenter
 */
function MessageCenter() {
    Eventful.call(this);
}
MessageCenter.prototype.on = createRegisterEventWithLowercaseName('on', true);
MessageCenter.prototype.off = createRegisterEventWithLowercaseName('off', true);
MessageCenter.prototype.one = createRegisterEventWithLowercaseName('one', true);
mixin(MessageCenter, Eventful);

/**
 * @module echarts~ECharts
 */
function ECharts(dom, theme$$1, opts) {
    opts = opts || {};

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

    /**
     * @type {string}
     */
    this.id;

    /**
     * Group id
     * @type {string}
     */
    this.group;

    /**
     * @type {HTMLElement}
     * @private
     */
    this._dom = dom;

    var defaultRenderer = 'canvas';
    if (__DEV__) {
        defaultRenderer = (
            typeof window === 'undefined' ? global : window
        ).__ECHARTS__DEFAULT__RENDERER__ || defaultRenderer;
    }

    /**
     * @type {module:zrender/ZRender}
     * @private
     */
    var zr = this._zr = init$1(dom, {
        renderer: opts.renderer || defaultRenderer,
        devicePixelRatio: opts.devicePixelRatio,
        width: opts.width,
        height: opts.height
    });

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

    var theme$$1 = clone(theme$$1);
    theme$$1 && backwardCompat(theme$$1, true);
    /**
     * @type {Object}
     * @private
     */
    this._theme = theme$$1;

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

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

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

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

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

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

    // Sort on demand
    function prioritySortFunc(a, b) {
        return a.__prio - b.__prio;
    }
    sort(visualFuncs, prioritySortFunc);
    sort(dataProcessorFuncs, prioritySortFunc);

    /**
     * @type {module:echarts/stream/Scheduler}
     */
    this._scheduler = new Scheduler(this, api, dataProcessorFuncs, visualFuncs);

    Eventful.call(this, this._ecEventProcessor = new EventProcessor());

    /**
     * @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 = bind(this.resize, this);

    // Can't dispatch action during rendering procedure
    this._pendingActions = [];

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

    bindRenderedEvent(zr, this);

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

var echartsProto = ECharts.prototype;

echartsProto._onframe = function () {
    if (this._disposed) {
        return;
    }

    var scheduler = this._scheduler;

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

        this[IN_MAIN_PROCESS] = true;

        prepare(this);
        updateMethods.update.call(this);

        this[IN_MAIN_PROCESS] = false;

        this[OPTION_UPDATED] = false;

        flushPendingActions.call(this, silent);

        triggerUpdatedEvent.call(this, silent);
    }
    // Avoid do both lazy update and progress in one frame.
    else if (scheduler.unfinished) {
        // Stream progress.
        var remainTime = TEST_FRAME_REMAIN_TIME;
        var ecModel = this._model;
        var api = this._api;
        scheduler.unfinished = false;
        do {
            var startTime = +new Date();

            scheduler.performSeriesTasks(ecModel);

            // Currently dataProcessorFuncs do not check threshold.
            scheduler.performDataProcessorTasks(ecModel);

            updateStreamModes(this, ecModel);

            // Do not update coordinate system here. Because that coord system update in
            // each frame is not a good user experience. So we follow the rule that
            // the extent of the coordinate system is determin in the first frame (the
            // frame is executed immedietely after task reset.
            // this._coordSysMgr.update(ecModel, api);

            // console.log('--- ec frame visual ---', remainTime);
            scheduler.performVisualTasks(ecModel);

            renderSeries(this, this._model, api, 'remain');

            remainTime -= (+new Date() - startTime);
        }
        while (remainTime > 0 && scheduler.unfinished);

        // Call flush explicitly for trigger finished event.
        if (!scheduler.unfinished) {
            this._zr.flush();
        }
        // Else, zr flushing be ensue within the same frame,
        // because zr flushing is after onframe event.
    }
};

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

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

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

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

    this[IN_MAIN_PROCESS] = true;

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

    this._model.setOption(option, optionPreprocessorFuncs);

    if (lazyUpdate) {
        this[OPTION_UPDATED] = {silent: silent};
        this[IN_MAIN_PROCESS] = false;
    }
    else {
        prepare(this);

        updateMethods.update.call(this);

        // Ensure zr refresh sychronously, and then pixel in canvas can be
        // fetched after `setOption`.
        this._zr.flush();

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

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

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

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

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

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

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

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

/**
 * Get canvas which has all thing rendered
 * @param {Object} opts
 * @param {string} [opts.backgroundColor]
 * @return {string}
 */
echartsProto.getRenderedCanvas = function (opts) {
    if (!env$1.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
    // Never works before in init animation, so remove it.
    // zrUtil.each(list, function (el) {
    //     el.stopAnimation(true);
    // });
    return zr.painter.getRenderedCanvas(opts);
};

/**
 * Get svg data url
 * @return {string}
 */
echartsProto.getSvgDataURL = function () {
    if (!env$1.svgSupported) {
        return;
    }

    var zr = this._zr;
    var list = zr.storage.getDisplayList();
    // Stop animations
    each$1(list, function (el) {
        el.stopAnimation(true);
    });

    return zr.painter.toDataURL();
};

/**
 * @return {string}
 * @param {Object} opts
 * @param {string} [opts.type='png']
 * @param {string} [opts.pixelRatio=1]
 * @param {string} [opts.backgroundColor]
 * @param {string} [opts.excludeComponents]
 */
echartsProto.getDataURL = function (opts) {
    if (this._disposed) {
        disposedWarning(this.id);
        return;
    }

    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._zr.painter.getType() === 'svg'
        ? this.getSvgDataURL()
        : 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 (this._disposed) {
        disposedWarning(this.id);
        return;
    }

    if (!env$1.canvasSupported) {
        return;
    }
    var isSvg = opts.type === 'svg';
    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;

        each$1(instances, function (chart, id) {
            if (chart.group === groupId) {
                var canvas = isSvg
                    ? chart.getZr().painter.getSvgDom().innerHTML
                    : chart.getRenderedCanvas(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 = createCanvas();
        var zr = init$1(targetCanvas, {
            renderer: isSvg ? 'svg' : 'canvas'
        });
        zr.resize({
            width: width,
            height: height
        });

        if (isSvg) {
            var content = '';
            each(canvasList, function (item) {
                var x = item.left - left;
                var y = item.top - top;
                content += '<g transform="translate(' + x + ','
                    + y + ')">' + item.dom + '</g>';
            });
            zr.painter.getSvgRoot().innerHTML = content;

            if (opts.connectedBackgroundColor) {
                zr.painter.setBackgroundColor(opts.connectedBackgroundColor);
            }

            zr.refreshImmediately();
            return zr.painter.toDataURL();
        }
        else {
            // Background between the charts
            if (opts.connectedBackgroundColor) {
                zr.add(new Rect({
                    shape: {
                        x: 0,
                        y: 0,
                        width: width,
                        height: height
                    },
                    style: {
                        fill: opts.connectedBackgroundColor
                    }
                }));
            }

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

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

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

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

function doConvertPixel(methodName, finder, value) {
    if (this._disposed) {
        disposedWarning(this.id);
        return;
    }

    var ecModel = this._model;
    var coordSysList = this._coordSysMgr.getCoordinateSystems();
    var result;

    finder = parseFinder(ecModel, finder);

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

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

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

    var ecModel = this._model;
    var result;

    finder = parseFinder(ecModel, finder);

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

    return !!result;
};

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

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

    var seriesModel = finder.seriesModel;

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

    var data = seriesModel.getData();

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

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

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

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

var updateMethods = {

    prepareAndUpdate: function (payload) {
        prepare(this);
        updateMethods.update.call(this, payload);
    },

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

        var ecModel = this._model;
        var api = this._api;
        var zr = this._zr;
        var coordSysMgr = this._coordSysMgr;
        var scheduler = this._scheduler;

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

        scheduler.restoreData(ecModel, payload);

        scheduler.performSeriesTasks(ecModel);

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

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

        scheduler.performDataProcessorTasks(ecModel, payload);

        // Current stream render is not supported in data process. So we can update
        // stream modes after data processing, where the filtered data is used to
        // deteming whether use progressive rendering.
        updateStreamModes(this, ecModel);

        // We update stream modes before coordinate system updated, then the modes info
        // can be fetched when coord sys updating (consider the barGrid extent fix). But
        // the drawback is the full coord info can not be fetched. Fortunately this full
        // coord is not requied in stream mode updater currently.
        coordSysMgr.update(ecModel, api);

        clearColorPalette(ecModel);
        scheduler.performVisualTasks(ecModel, payload);

        render(this, ecModel, api, payload);

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

        // In IE8
        if (!env$1.canvasSupported) {
            var colorArr = parse(backgroundColor);
            backgroundColor = stringify(colorArr, 'rgb');
            if (colorArr[3] === 0) {
                backgroundColor = 'transparent';
            }
        }
        else {
            zr.setBackgroundColor(backgroundColor);
        }

        performPostUpdateFuncs(ecModel, api);

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

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

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

        // ChartView.markUpdateMethod(payload, 'updateTransform');

        var componentDirtyList = [];
        ecModel.eachComponent(function (componentType, componentModel) {
            var componentView = ecIns.getViewOfComponentModel(componentModel);
            if (componentView && componentView.__alive) {
                if (componentView.updateTransform) {
                    var result = componentView.updateTransform(componentModel, ecModel, api, payload);
                    result && result.update && componentDirtyList.push(componentView);
                }
                else {
                    componentDirtyList.push(componentView);
                }
            }
        });

        var seriesDirtyMap = createHashMap();
        ecModel.eachSeries(function (seriesModel) {
            var chartView = ecIns._chartsMap[seriesModel.__viewId];
            if (chartView.updateTransform) {
                var result = chartView.updateTransform(seriesModel, ecModel, api, payload);
                result && result.update && seriesDirtyMap.set(seriesModel.uid, 1);
            }
            else {
                seriesDirtyMap.set(seriesModel.uid, 1);
            }
        });

        clearColorPalette(ecModel);
        // Keep pipe to the exist pipeline because it depends on the render task of the full pipeline.
        // this._scheduler.performVisualTasks(ecModel, payload, 'layout', true);
        this._scheduler.performVisualTasks(
            ecModel, payload, {setDirty: true, dirtyMap: seriesDirtyMap}
        );

        // Currently, not call render of components. Geo render cost a lot.
        // renderComponents(ecIns, ecModel, api, payload, componentDirtyList);
        renderSeries(ecIns, ecModel, api, payload, seriesDirtyMap);

        performPostUpdateFuncs(ecModel, this._api);
    },

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

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

        Chart.markUpdateMethod(payload, 'updateView');

        clearColorPalette(ecModel);

        // Keep pipe to the exist pipeline because it depends on the render task of the full pipeline.
        this._scheduler.performVisualTasks(ecModel, payload, {setDirty: true});

        render(this, this._model, this._api, payload);

        performPostUpdateFuncs(ecModel, this._api);
    },

    /**
     * @param {Object} payload
     * @private
     */
    updateVisual: function (payload) {
        updateMethods.update.call(this, payload);

        // var ecModel = this._model;

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

        // ChartView.markUpdateMethod(payload, 'updateVisual');

        // clearColorPalette(ecModel);

        // // Keep pipe to the exist pipeline because it depends on the render task of the full pipeline.
        // this._scheduler.performVisualTasks(ecModel, payload, {visualType: 'visual', setDirty: true});

        // render(this, this._model, this._api, payload);

        // performPostUpdateFuncs(ecModel, this._api);
    },

    /**
     * @param {Object} payload
     * @private
     */
    updateLayout: function (payload) {
        updateMethods.update.call(this, payload);

        // var ecModel = this._model;

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

        // ChartView.markUpdateMethod(payload, 'updateLayout');

        // // Keep pipe to the exist pipeline because it depends on the render task of the full pipeline.
        // // this._scheduler.performVisualTasks(ecModel, payload, 'layout', true);
        // this._scheduler.performVisualTasks(ecModel, payload, {setDirty: true});

        // render(this, this._model, this._api, payload);

        // performPostUpdateFuncs(ecModel, this._api);
    }
};

function prepare(ecIns) {
    var ecModel = ecIns._model;
    var scheduler = ecIns._scheduler;

    scheduler.restorePipelines(ecModel);

    scheduler.prepareStageTasks();

    prepareView(ecIns, 'component', ecModel, scheduler);

    prepareView(ecIns, 'chart', ecModel, scheduler);

    scheduler.plan();
}

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

    // broadcast
    if (!mainType) {
        // FIXME
        // Chart will not be update directly here, except set dirty.
        // But there is no such scenario now.
        each(ecIns._componentsViews.concat(ecIns._chartsViews), callView);
        return;
    }

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

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

    var excludeSeriesId = payload.excludeSeriesId;
    if (excludeSeriesId != null) {
        excludeSeriesId = createHashMap(normalizeToArray(excludeSeriesId));
    }

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

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

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

    this._zr.resize(opts);

    var ecModel = this._model;

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

    if (!ecModel) {
        return;
    }

    var optionChanged = ecModel.resetOption('media');

    var silent = opts && opts.silent;

    this[IN_MAIN_PROCESS] = true;

    optionChanged && prepare(this);
    updateMethods.update.call(this);

    this[IN_MAIN_PROCESS] = false;

    flushPendingActions.call(this, silent);

    triggerUpdatedEvent.call(this, silent);
};

function updateStreamModes(ecIns, ecModel) {
    var chartsMap = ecIns._chartsMap;
    var scheduler = ecIns._scheduler;
    ecModel.eachSeries(function (seriesModel) {
        scheduler.updateStreamModes(seriesModel, chartsMap[seriesModel.__viewId]);
    });
}

/**
 * Show loading effect
 * @param  {string} [name='default']
 * @param  {Object} [cfg]
 */
echartsProto.showLoading = function (name, cfg) {
    if (this._disposed) {
        disposedWarning(this.id);
        return;
    }

    if (isObject(name)) {
        cfg = name;
        name = '';
    }
    name = name || 'default';

    this.hideLoading();
    if (!loadingEffects[name]) {
        if (__DEV__) {
            console.warn('Loading effects ' + name + ' not exists.');
        }
        return;
    }
    var el = loadingEffects[name](this._api, cfg);
    var zr = this._zr;
    this._loadingFX = el;

    zr.add(el);
};

/**
 * Hide loading effect
 */
echartsProto.hideLoading = function () {
    if (this._disposed) {
        disposedWarning(this.id);
        return;
    }

    this._loadingFX && this._zr.remove(this._loadingFX);
    this._loadingFX = null;
};

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

/**
 * @pubilc
 * @param {Object} payload
 * @param {string} [payload.type] Action type
 * @param {Object|boolean} [opt] If pass boolean, means opt.silent
 * @param {boolean} [opt.silent=false] Whether trigger events.
 * @param {boolean} [opt.flush=undefined]
 *                  true: Flush immediately, and then pixel in canvas can be fetched
 *                      immediately. Caution: it might affect performance.
 *                  false: Not flush.
 *                  undefined: Auto decide whether perform flush.
 */
echartsProto.dispatchAction = function (payload, opt) {
    if (this._disposed) {
        disposedWarning(this.id);
        return;
    }

    if (!isObject(opt)) {
        opt = {silent: !!opt};
    }

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

    // Avoid dispatch action before setOption. Especially in `connect`.
    if (!this._model) {
        return;
    }

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

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

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

    flushPendingActions.call(this, opt.silent);

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

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

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

    this[IN_MAIN_PROCESS] = true;

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

    var eventObjBatch = [];
    var eventObj;
    var isHighDown = payloadType === 'highlight' || payloadType === 'downplay';

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

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

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

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

    this[IN_MAIN_PROCESS] = false;

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

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

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

/**
 * Event `rendered` is triggered when zr
 * rendered. It is useful for realtime
 * snapshot (reflect animation).
 *
 * Event `finished` is triggered when:
 * (1) zrender rendering finished.
 * (2) initial animation finished.
 * (3) progressive rendering finished.
 * (4) no pending action.
 * (5) no delayed setOption needs to be processed.
 */
function bindRenderedEvent(zr, ecIns) {
    zr.on('rendered', function () {

        ecIns.trigger('rendered');

        // The `finished` event should not be triggered repeatly,
        // so it should only be triggered when rendering indeed happend
        // in zrender. (Consider the case that dipatchAction is keep
        // triggering when mouse move).
        if (
            // Although zr is dirty if initial animation is not finished
            // and this checking is called on frame, we also check
            // animation finished for robustness.
            zr.animation.isFinished()
            && !ecIns[OPTION_UPDATED]
            && !ecIns._scheduler.unfinished
            && !ecIns._pendingActions.length
        ) {
            ecIns.trigger('finished');
        }
    });
}

/**
 * @param {Object} params
 * @param {number} params.seriesIndex
 * @param {Array|TypedArray} params.data
 */
echartsProto.appendData = function (params) {
    if (this._disposed) {
        disposedWarning(this.id);
        return;
    }

    var seriesIndex = params.seriesIndex;
    var ecModel = this.getModel();
    var seriesModel = ecModel.getSeriesByIndex(seriesIndex);

    if (__DEV__) {
        assert(params.data && seriesModel);
    }

    seriesModel.appendData(params);

    // Note: `appendData` does not support that update extent of coordinate
    // system, util some scenario require that. In the expected usage of
    // `appendData`, the initial extent of coordinate system should better
    // be fixed by axis `min`/`max` setting or initial data, otherwise if
    // the extent changed while `appendData`, the location of the painted
    // graphic elements have to be changed, which make the usage of
    // `appendData` meaningless.

    this._scheduler.unfinished = true;
};

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

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

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

    isComponent
        ? ecModel.eachComponent(function (componentType, model) {
            componentType !== 'series' && doPrepare(model);
        })
        : ecModel.eachSeries(doPrepare);

    function doPrepare(model) {
        // Consider: id same and type changed.
        var viewId = '_ec_' + model.id + '_' + model.type;
        var view = viewMap[viewId];
        if (!view) {
            var classType = parseClassType(model.type);
            var Clazz = isComponent
                ? Component$1.getClass(classType.main, classType.sub)
                : Chart.getClass(classType.sub);

            if (__DEV__) {
                assert(Clazz, classType.sub + ' does not exist.');
            }

            view = new Clazz();
            view.init(ecModel, api);
            viewMap[viewId] = view;
            viewList.push(view);
            zr.add(view.group);
        }

        model.__viewId = view.__id = viewId;
        view.__alive = true;
        view.__model = model;
        view.group.__ecComponentInfo = {
            mainType: model.mainType,
            index: model.componentIndex
        };
        !isComponent && scheduler.prepareView(view, model, ecModel, api);
    }

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

// /**
//  * Encode visual infomation from data after data processing
//  *
//  * @param {module:echarts/model/Global} ecModel
//  * @param {object} layout
//  * @param {boolean} [layoutFilter] `true`: only layout,
//  *                                 `false`: only not layout,
//  *                                 `null`/`undefined`: all.
//  * @param {string} taskBaseTag
//  * @private
//  */
// function startVisualEncoding(ecIns, ecModel, api, payload, layoutFilter) {
//     each(visualFuncs, function (visual, index) {
//         var isLayout = visual.isLayout;
//         if (layoutFilter == null
//             || (layoutFilter === false && !isLayout)
//             || (layoutFilter === true && isLayout)
//         ) {
//             visual.func(ecModel, api, payload);
//         }
//     });
// }

function clearColorPalette(ecModel) {
    ecModel.clearColorPalette();
    ecModel.eachSeries(function (seriesModel) {
        seriesModel.clearColorPalette();
    });
}

function render(ecIns, ecModel, api, payload) {

    renderComponents(ecIns, ecModel, api, payload);

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

    renderSeries(ecIns, ecModel, api, payload);

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

function renderComponents(ecIns, ecModel, api, payload, dirtyList) {
    each(dirtyList || ecIns._componentsViews, function (componentView) {
        var componentModel = componentView.__model;
        componentView.render(componentModel, ecModel, api, payload);

        updateZ(componentModel, componentView);
    });
}

/**
 * Render each chart and component
 * @private
 */
function renderSeries(ecIns, ecModel, api, payload, dirtyMap) {
    // Render all charts
    var scheduler = ecIns._scheduler;
    var unfinished;
    ecModel.eachSeries(function (seriesModel) {
        var chartView = ecIns._chartsMap[seriesModel.__viewId];
        chartView.__alive = true;

        var renderTask = chartView.renderTask;
        scheduler.updatePayload(renderTask, payload);

        if (dirtyMap && dirtyMap.get(seriesModel.uid)) {
            renderTask.dirty();
        }

        unfinished |= renderTask.perform(scheduler.getPerformArgs(renderTask));

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

        updateZ(seriesModel, chartView);

        updateBlend(seriesModel, chartView);
    });
    scheduler.unfinished |= unfinished;

    // If use hover layer
    updateHoverLayerStatus(ecIns, ecModel);

    // Add aria
    aria(ecIns._zr.dom, ecModel);
}

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


var MOUSE_EVENT_NAMES = [
    'click', 'dblclick', 'mouseover', 'mouseout', 'mousemove',
    'mousedown', 'mouseup', 'globalout', 'contextmenu'
];

/**
 * @private
 */
echartsProto._initEvents = function () {
    each(MOUSE_EVENT_NAMES, function (eveName) {
        var handler = function (e) {
            var ecModel = this.getModel();
            var el = e.target;
            var params;
            var isGlobalOut = eveName === 'globalout';

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

            // Contract: if params prepared in mouse event,
            // these properties must be specified:
            // {
            //    componentType: string (component main type)
            //    componentIndex: number
            // }
            // Otherwise event query can not work.

            if (params) {
                var componentType = params.componentType;
                var componentIndex = params.componentIndex;
                // Special handling for historic reason: when trigger by
                // markLine/markPoint/markArea, the componentType is
                // 'markLine'/'markPoint'/'markArea', but we should better
                // enable them to be queried by seriesIndex, since their
                // option is set in each series.
                if (componentType === 'markLine'
                    || componentType === 'markPoint'
                    || componentType === 'markArea'
                ) {
                    componentType = 'series';
                    componentIndex = params.seriesIndex;
                }
                var model = componentType && componentIndex != null
                    && ecModel.getComponent(componentType, componentIndex);
                var view = model && this[
                    model.mainType === 'series' ? '_chartsMap' : '_componentsMap'
                ][model.__viewId];

                if (__DEV__) {
                    // `event.componentType` and `event[componentTpype + 'Index']` must not
                    // be missed, otherwise there is no way to distinguish source component.
                    // See `dataFormat.getDataParams`.
                    if (!isGlobalOut && !(model && view)) {
                        console.warn('model or view can not be found by params');
                    }
                }

                params.event = e;
                params.type = eveName;

                this._ecEventProcessor.eventInfo = {
                    targetEl: el,
                    packedEvent: params,
                    model: model,
                    view: view
                };

                this.trigger(eveName, params);
            }
        };
        // Consider that some component (like tooltip, brush, ...)
        // register zr event handler, but user event handler might
        // do anything, such as call `setOption` or `dispatchAction`,
        // which probably update any of the content and probably
        // cause problem if it is called previous other inner handlers.
        handler.zrEventfulCallAtLast = true;
        this._zr.on(eveName, handler, this);
    }, this);

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

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

/**
 * Clear
 */
echartsProto.clear = function () {
    if (this._disposed) {
        disposedWarning(this.id);
        return;
    }
    this.setOption({ series: [] }, true);
};

/**
 * Dispose instance
 */
echartsProto.dispose = function () {
    if (this._disposed) {
        disposedWarning(this.id);
        return;
    }
    this._disposed = true;

    setAttribute(this.getDom(), DOM_ATTRIBUTE_KEY, '');

    var api = this._api;
    var ecModel = this._model;

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

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

    delete instances[this.id];
};

mixin(ECharts, Eventful);

function disposedWarning(id) {
    if (__DEV__) {
        console.warn('Instance ' + id + ' has been disposed');
    }
}

function updateHoverLayerStatus(ecIns, ecModel) {
    var zr = ecIns._zr;
    var storage = zr.storage;
    var elCount = 0;

    storage.traverse(function (el) {
        elCount++;
    });

    if (elCount > ecModel.get('hoverLayerThreshold') && !env$1.node) {
        ecModel.eachSeries(function (seriesModel) {
            if (seriesModel.preventUsingHoverLayer) {
                return;
            }
            var chartView = ecIns._chartsMap[seriesModel.__viewId];
            if (chartView.__alive) {
                chartView.group.traverse(function (el) {
                    // Don't switch back.
                    el.useHoverLayer = true;
                });
            }
        });
    }
}

/**
 * Update chart progressive and blend.
 * @param {module:echarts/model/Series|module:echarts/model/Component} model
 * @param {module:echarts/view/Component|module:echarts/view/Chart} view
 */
function updateBlend(seriesModel, chartView) {
    var blendMode = seriesModel.get('blendMode') || null;
    if (__DEV__) {
        if (!env$1.canvasSupported && blendMode && blendMode !== 'source-over') {
            console.warn('Only canvas support blendMode');
        }
    }
    chartView.group.traverse(function (el) {
        // FIXME marker and other components
        if (!el.isGroup) {
            // Only set if blendMode is changed. In case element is incremental and don't wan't to rerender.
            if (el.style.blend !== blendMode) {
                el.setStyle('blend', blendMode);
            }
        }
        if (el.eachPendingDisplayable) {
            el.eachPendingDisplayable(function (displayable) {
                displayable.setStyle('blend', blendMode);
            });
        }
    });
}

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

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


/**
 * @class
 * Usage of query:
 * `chart.on('click', query, handler);`
 * The `query` can be:
 * + The component type query string, only `mainType` or `mainType.subType`,
 *   like: 'xAxis', 'series', 'xAxis.category' or 'series.line'.
 * + The component query object, like:
 *   `{seriesIndex: 2}`, `{seriesName: 'xx'}`, `{seriesId: 'some'}`,
 *   `{xAxisIndex: 2}`, `{xAxisName: 'xx'}`, `{xAxisId: 'some'}`.
 * + The data query object, like:
 *   `{dataIndex: 123}`, `{dataType: 'link'}`, `{name: 'some'}`.
 * + The other query object (cmponent customized query), like:
 *   `{element: 'some'}` (only available in custom series).
 *
 * Caveat: If a prop in the `query` object is `null/undefined`, it is the
 * same as there is no such prop in the `query` object.
 */
function EventProcessor() {
    // These info required: targetEl, packedEvent, model, view
    this.eventInfo;
}
EventProcessor.prototype = {
    constructor: EventProcessor,

    normalizeQuery: function (query) {
        var cptQuery = {};
        var dataQuery = {};
        var otherQuery = {};

        // `query` is `mainType` or `mainType.subType` of component.
        if (isString(query)) {
            var condCptType = parseClassType(query);
            // `.main` and `.sub` may be ''.
            cptQuery.mainType = condCptType.main || null;
            cptQuery.subType = condCptType.sub || null;
        }
        // `query` is an object, convert to {mainType, index, name, id}.
        else {
            // `xxxIndex`, `xxxName`, `xxxId`, `name`, `dataIndex`, `dataType` is reserved,
            // can not be used in `compomentModel.filterForExposedEvent`.
            var suffixes = ['Index', 'Name', 'Id'];
            var dataKeys = {name: 1, dataIndex: 1, dataType: 1};
            each$1(query, function (val, key) {
                var reserved = false;
                for (var i = 0; i < suffixes.length; i++) {
                    var propSuffix = suffixes[i];
                    var suffixPos = key.lastIndexOf(propSuffix);
                    if (suffixPos > 0 && suffixPos === key.length - propSuffix.length) {
                        var mainType = key.slice(0, suffixPos);
                        // Consider `dataIndex`.
                        if (mainType !== 'data') {
                            cptQuery.mainType = mainType;
                            cptQuery[propSuffix.toLowerCase()] = val;
                            reserved = true;
                        }
                    }
                }
                if (dataKeys.hasOwnProperty(key)) {
                    dataQuery[key] = val;
                    reserved = true;
                }
                if (!reserved) {
                    otherQuery[key] = val;
                }
            });
        }

        return {
            cptQuery: cptQuery,
            dataQuery: dataQuery,
            otherQuery: otherQuery
        };
    },

    filter: function (eventType, query, args) {
        // They should be assigned before each trigger call.
        var eventInfo = this.eventInfo;

        if (!eventInfo) {
            return true;
        }

        var targetEl = eventInfo.targetEl;
        var packedEvent = eventInfo.packedEvent;
        var model = eventInfo.model;
        var view = eventInfo.view;

        // For event like 'globalout'.
        if (!model || !view) {
            return true;
        }

        var cptQuery = query.cptQuery;
        var dataQuery = query.dataQuery;

        return check(cptQuery, model, 'mainType')
            && check(cptQuery, model, 'subType')
            && check(cptQuery, model, 'index', 'componentIndex')
            && check(cptQuery, model, 'name')
            && check(cptQuery, model, 'id')
            && check(dataQuery, packedEvent, 'name')
            && check(dataQuery, packedEvent, 'dataIndex')
            && check(dataQuery, packedEvent, 'dataType')
            && (!view.filterForExposedEvent || view.filterForExposedEvent(
                eventType, query.otherQuery, targetEl, packedEvent
            ));

        function check(query, host, prop, propOnHost) {
            return query[prop] == null || host[propOnHost || prop] === query[prop];
        }
    },

    afterTrigger: function () {
        // Make sure the eventInfo wont be used in next trigger.
        this.eventInfo = null;
    }
};


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

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

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

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

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

/**
 * Visual encoding functions of each stage
 * @type {Array.<Object.<string, Function>>}
 */
var visualFuncs = [];

/**
 * Theme storage
 * @type {Object.<key, Object>}
 */
var themeStorage = {};
/**
 * Loading effects
 */
var loadingEffects = {};

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

var idBase = new Date() - 0;
var groupIdBase = new Date() - 0;
var DOM_ATTRIBUTE_KEY = '_echarts_instance_';

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

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

    each(eventActionMap, function (actionType, eventType) {
        chart._messageCenter.on(eventType, function (event) {
            if (connectedGroups[chart.group] && chart[STATUS_KEY] !== STATUS_PENDING) {
                if (event && event.escapeConnect) {
                    return;
                }

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

                each(instances, function (otherChart) {
                    if (otherChart !== chart && otherChart.group === chart.group) {
                        otherCharts.push(otherChart);
                    }
                });

                updateConnectedChartsStatus(otherCharts, STATUS_PENDING);
                each(otherCharts, function (otherChart) {
                    if (otherChart[STATUS_KEY] !== STATUS_UPDATING) {
                        otherChart.dispatchAction(action);
                    }
                });
                updateConnectedChartsStatus(otherCharts, STATUS_UPDATED);
            }
        });
    });
}

/**
 * @param {HTMLElement} dom
 * @param {Object} [theme]
 * @param {Object} opts
 * @param {number} [opts.devicePixelRatio] Use window.devicePixelRatio by default
 * @param {string} [opts.renderer] Can choose 'canvas' or 'svg' to render the chart.
 * @param {number} [opts.width] Use clientWidth of the input `dom` by default.
 *                              Can be 'auto' (the same as null/undefined)
 * @param {number} [opts.height] Use clientHeight of the input `dom` by default.
 *                               Can be 'auto' (the same as null/undefined)
 */
function init(dom, theme$$1, opts) {
    if (__DEV__) {
        // Check version
        if ((version$1.replace('.', '') - 0) < (dependencies.zrender.replace('.', '') - 0)) {
            throw new Error(
                'zrender/src ' + version$1
                + ' is too old for ECharts ' + version
                + '. Current version need ZRender '
                + dependencies.zrender + '+'
            );
        }

        if (!dom) {
            throw new Error('Initialize failed: invalid dom.');
        }
    }

    var existInstance = getInstanceByDom(dom);
    if (existInstance) {
        if (__DEV__) {
            console.warn('There is a chart instance already initialized on the dom.');
        }
        return existInstance;
    }

    if (__DEV__) {
        if (isDom(dom)
            && dom.nodeName.toUpperCase() !== 'CANVAS'
            && (
                (!dom.clientWidth && (!opts || opts.width == null))
                || (!dom.clientHeight && (!opts || opts.height == null))
            )
        ) {
            console.warn('Can\'t get DOM width or height. Please check '
            + 'dom.clientWidth and dom.clientHeight. They should not be 0.'
            + 'For example, you may need to call this in the callback '
            + 'of window.onload.');
        }
    }

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

    setAttribute(dom, DOM_ATTRIBUTE_KEY, chart.id);

    enableConnect(chart);

    return chart;
}

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

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

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

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

/**
 * @param  {HTMLElement} dom
 * @return {echarts~ECharts}
 */
function getInstanceByDom(dom) {
    return instances[getAttribute(dom, DOM_ATTRIBUTE_KEY)];
}

/**
 * @param {string} key
 * @return {echarts~ECharts}
 */
function getInstanceById(key) {
    return instances[key];
}

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

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

/**
 * @param {number} [priority=1000]
 * @param {Object|Function} processor
 */
function registerProcessor(priority, processor) {
    normalizeRegister(dataProcessorFuncs, priority, processor, PRIORITY_PROCESSOR_FILTER);
}

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

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

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

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

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

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

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

/**
 * Layout is a special stage of visual encoding
 * Most visual encoding like color are common for different chart
 * But each chart has it's own layout algorithm
 *
 * @param {number} [priority=1000]
 * @param {Function} layoutTask
 */
function registerLayout(priority, layoutTask) {
    normalizeRegister(visualFuncs, priority, layoutTask, PRIORITY_VISUAL_LAYOUT, 'layout');
}

/**
 * @param {number} [priority=3000]
 * @param {module:echarts/stream/Task} visualTask
 */
function registerVisual(priority, visualTask) {
    normalizeRegister(visualFuncs, priority, visualTask, PRIORITY_VISUAL_CHART, 'visual');
}

/**
 * @param {Object|Function} fn: {seriesType, createOnAllSeries, performRawSeries, reset}
 */
function normalizeRegister(targetList, priority, fn, defaultPriority, visualType) {
    if (isFunction(priority) || isObject(priority)) {
        fn = priority;
        priority = defaultPriority;
    }

    if (__DEV__) {
        if (isNaN(priority) || priority == null) {
            throw new Error('Illegal priority');
        }
        // Check duplicate
        each(targetList, function (wrap) {
            assert(wrap.__raw !== fn);
        });
    }

    var stageHandler = Scheduler.wrapStageHandler(fn, visualType);

    stageHandler.__prio = priority;
    stageHandler.__raw = fn;
    targetList.push(stageHandler);

    return stageHandler;
}

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

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

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

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

/**
 * @param {Object} opts
 * @param {string} [superClass]
 */
function extendChartView(opts/*, superClass*/) {
    // var Clazz = ChartView;
    // if (superClass) {
    //     superClass = superClass.replace('series.', '');
    //     var classType = parseClassType(superClass);
    //     Clazz = ChartView.getClass(classType.main, true);
    // }
    return Chart.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);
 *     });
 */
function setCanvasCreator(creator) {
    $override('createCanvas', creator);
}

/**
 * @param {string} mapName
 * @param {Array.<Object>|Object|string} geoJson
 * @param {Object} [specialAreas]
 *
 * @example GeoJSON
 *     $.get('USA.json', function (geoJson) {
 *         echarts.registerMap('USA', geoJson);
 *         // Or
 *         echarts.registerMap('USA', {
 *             geoJson: geoJson,
 *             specialAreas: {}
 *         })
 *     });
 *
 *     $.get('airport.svg', function (svg) {
 *         echarts.registerMap('airport', {
 *             svg: svg
 *         }
 *     });
 *
 *     echarts.registerMap('eu', [
 *         {svg: eu-topographic.svg},
 *         {geoJSON: eu.json}
 *     ])
 */
function registerMap(mapName, geoJson, specialAreas) {
    mapDataStorage.registerMap(mapName, geoJson, specialAreas);
}

/**
 * @param {string} mapName
 * @return {Object}
 */
function getMap(mapName) {
    // For backward compatibility, only return the first one.
    var records = mapDataStorage.retrieveMap(mapName);
    return records && records[0] && {
        geoJson: records[0].geoJSON,
        specialAreas: records[0].specialAreas
    };
}

registerVisual(PRIORITY_VISUAL_GLOBAL, seriesColor);
registerPreprocessor(backwardCompat);
registerProcessor(PRIORITY_PROCESSOR_DATASTACK, dataStack);
registerLoading('default', loadingDefault);

// Default actions

registerAction({
    type: 'highlight',
    event: 'highlight',
    update: 'highlight'
}, noop);

registerAction({
    type: 'downplay',
    event: 'downplay',
    update: 'downplay'
}, noop);

// Default theme
registerTheme('light', lightTheme);
registerTheme('dark', theme);

// For backward compatibility, where the namespace `dataTool` will
// be mounted on `echarts` is the extension `dataTool` is imported.
var dataTool = {};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/


function defaultKeyGetter(item) {
    return item;
}

/**
 * @param {Array} oldArr
 * @param {Array} newArr
 * @param {Function} oldKeyGetter
 * @param {Function} newKeyGetter
 * @param {Object} [context] Can be visited by this.context in callback.
 */
function DataDiffer(oldArr, newArr, oldKeyGetter, newKeyGetter, context) {
    this._old = oldArr;
    this._new = newArr;

    this._oldKeyGetter = oldKeyGetter || defaultKeyGetter;
    this._newKeyGetter = newKeyGetter || defaultKeyGetter;

    this.context = context;
}

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 oldDataIndexMap = {};
        var newDataIndexMap = {};
        var oldDataKeyArr = [];
        var newDataKeyArr = [];
        var i;

        initIndexMap(oldArr, oldDataIndexMap, oldDataKeyArr, '_oldKeyGetter', this);
        initIndexMap(newArr, newDataIndexMap, newDataKeyArr, '_newKeyGetter', this);

        for (i = 0; i < oldArr.length; i++) {
            var key = oldDataKeyArr[i];
            var idx = newDataIndexMap[key];

            // idx can never be empty array here. see 'set null' logic below.
            if (idx != null) {
                // Consider there is duplicate key (for example, use dataItem.name as key).
                // We should make sure every item in newArr and oldArr can be visited.
                var len = idx.length;
                if (len) {
                    len === 1 && (newDataIndexMap[key] = null);
                    idx = idx.shift();
                }
                else {
                    newDataIndexMap[key] = null;
                }
                this._update && this._update(idx, i);
            }
            else {
                this._remove && this._remove(i);
            }
        }

        for (var i = 0; i < newDataKeyArr.length; i++) {
            var key = newDataKeyArr[i];
            if (newDataIndexMap.hasOwnProperty(key)) {
                var idx = newDataIndexMap[key];
                if (idx == null) {
                    continue;
                }
                // idx can never be empty array here. see 'set null' logic above.
                if (!idx.length) {
                    this._add && this._add(idx);
                }
                else {
                    for (var j = 0, len = idx.length; j < len; j++) {
                        this._add && this._add(idx[j]);
                    }
                }
            }
        }
    }
};

function initIndexMap(arr, map, keyArr, keyGetterName, dataDiffer) {
    for (var i = 0; i < arr.length; i++) {
        // Add prefix to avoid conflict with Object.prototype.
        var key = '_ec_' + dataDiffer[keyGetterName](arr[i], i);
        var existence = map[key];
        if (existence == null) {
            keyArr.push(key);
            map[key] = i;
        }
        else {
            if (!existence.length) {
                map[key] = existence = [existence];
            }
            existence.push(i);
        }
    }
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var OTHER_DIMENSIONS = createHashMap([
    'tooltip', 'label', 'itemName', 'itemId', 'seriesName'
]);

function summarizeDimensions(data) {
    var summary = {};
    var encode = summary.encode = {};
    var notExtraCoordDimMap = createHashMap();
    var defaultedLabel = [];
    var defaultedTooltip = [];

    // See the comment of `List.js#userOutput`.
    var userOutput = summary.userOutput = {
        dimensionNames: data.dimensions.slice(),
        encode: {}
    };

    each$1(data.dimensions, function (dimName) {
        var dimItem = data.getDimensionInfo(dimName);

        var coordDim = dimItem.coordDim;
        if (coordDim) {
            if (__DEV__) {
                assert$1(OTHER_DIMENSIONS.get(coordDim) == null);
            }

            var coordDimIndex = dimItem.coordDimIndex;
            getOrCreateEncodeArr(encode, coordDim)[coordDimIndex] = dimName;

            if (!dimItem.isExtraCoord) {
                notExtraCoordDimMap.set(coordDim, 1);

                // Use the last coord dim (and label friendly) as default label,
                // because when dataset is used, it is hard to guess which dimension
                // can be value dimension. If both show x, y on label is not look good,
                // and conventionally y axis is focused more.
                if (mayLabelDimType(dimItem.type)) {
                    defaultedLabel[0] = dimName;
                }

                // User output encode do not contain generated coords.
                // And it only has index. User can use index to retrieve value from the raw item array.
                getOrCreateEncodeArr(userOutput.encode, coordDim)[coordDimIndex] = dimItem.index;
            }
            if (dimItem.defaultTooltip) {
                defaultedTooltip.push(dimName);
            }
        }

        OTHER_DIMENSIONS.each(function (v, otherDim) {
            var encodeArr = getOrCreateEncodeArr(encode, otherDim);

            var dimIndex = dimItem.otherDims[otherDim];
            if (dimIndex != null && dimIndex !== false) {
                encodeArr[dimIndex] = dimItem.name;
            }
        });
    });

    var dataDimsOnCoord = [];
    var encodeFirstDimNotExtra = {};

    notExtraCoordDimMap.each(function (v, coordDim) {
        var dimArr = encode[coordDim];
        // ??? FIXME extra coord should not be set in dataDimsOnCoord.
        // But should fix the case that radar axes: simplify the logic
        // of `completeDimension`, remove `extraPrefix`.
        encodeFirstDimNotExtra[coordDim] = dimArr[0];
        // Not necessary to remove duplicate, because a data
        // dim canot on more than one coordDim.
        dataDimsOnCoord = dataDimsOnCoord.concat(dimArr);
    });

    summary.dataDimsOnCoord = dataDimsOnCoord;
    summary.encodeFirstDimNotExtra = encodeFirstDimNotExtra;

    var encodeLabel = encode.label;
    // FIXME `encode.label` is not recommanded, because formatter can not be set
    // in this way. Use label.formatter instead. May be remove this approach someday.
    if (encodeLabel && encodeLabel.length) {
        defaultedLabel = encodeLabel.slice();
    }

    var encodeTooltip = encode.tooltip;
    if (encodeTooltip && encodeTooltip.length) {
        defaultedTooltip = encodeTooltip.slice();
    }
    else if (!defaultedTooltip.length) {
        defaultedTooltip = defaultedLabel.slice();
    }

    encode.defaultedLabel = defaultedLabel;
    encode.defaultedTooltip = defaultedTooltip;

    return summary;
}

function getOrCreateEncodeArr(encode, dim) {
    if (!encode.hasOwnProperty(dim)) {
        encode[dim] = [];
    }
    return encode[dim];
}

function getDimensionTypeByAxis(axisType) {
    return axisType === 'category'
        ? 'ordinal'
        : axisType === 'time'
        ? 'time'
        : 'float';
}

function mayLabelDimType(dimType) {
    // In most cases, ordinal and time do not suitable for label.
    // Ordinal info can be displayed on axis. Time is too long.
    return !(dimType === 'ordinal' || dimType === 'time');
}

// function findTheLastDimMayLabel(data) {
//     // Get last value dim
//     var dimensions = data.dimensions.slice();
//     var valueType;
//     var valueDim;
//     while (dimensions.length && (
//         valueDim = dimensions.pop(),
//         valueType = data.getDimensionInfo(valueDim).type,
//         valueType === 'ordinal' || valueType === 'time'
//     )) {} // jshint ignore:line
//     return valueDim;
// }

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * @class
 * @param {Object|DataDimensionInfo} [opt] All of the fields will be shallow copied.
 */
function DataDimensionInfo(opt) {
    if (opt != null) {
        extend(this, opt);
    }

    /**
     * Dimension name.
     * Mandatory.
     * @type {string}
     */
    // this.name;

    /**
     * The origin name in dimsDef, see source helper.
     * If displayName given, the tooltip will displayed vertically.
     * Optional.
     * @type {string}
     */
    // this.displayName;

    /**
     * Which coordSys dimension this dimension mapped to.
     * A `coordDim` can be a "coordSysDim" that the coordSys required
     * (for example, an item in `coordSysDims` of `model/referHelper#CoordSysInfo`),
     * or an generated "extra coord name" if does not mapped to any "coordSysDim"
     * (That is determined by whether `isExtraCoord` is `true`).
     * Mandatory.
     * @type {string}
     */
    // this.coordDim;

    /**
     * The index of this dimension in `series.encode[coordDim]`.
     * Mandatory.
     * @type {number}
     */
    // this.coordDimIndex;

    /**
     * Dimension type. The enumerable values are the key of
     * `dataCtors` of `data/List`.
     * Optional.
     * @type {string}
     */
    // this.type;

    /**
     * This index of this dimension info in `data/List#_dimensionInfos`.
     * Mandatory after added to `data/List`.
     * @type {number}
     */
    // this.index;

    /**
     * The format of `otherDims` is:
     * ```js
     * {
     *     tooltip: number optional,
     *     label: number optional,
     *     itemName: number optional,
     *     seriesName: number optional,
     * }
     * ```
     *
     * A `series.encode` can specified these fields:
     * ```js
     * encode: {
     *     // "3, 1, 5" is the index of data dimension.
     *     tooltip: [3, 1, 5],
     *     label: [0, 3],
     *     ...
     * }
     * ```
     * `otherDims` is the parse result of the `series.encode` above, like:
     * ```js
     * // Suppose the index of this data dimension is `3`.
     * this.otherDims = {
     *     // `3` is at the index `0` of the `encode.tooltip`
     *     tooltip: 0,
     *     // `3` is at the index `1` of the `encode.tooltip`
     *     label: 1
     * };
     * ```
     *
     * This prop should never be `null`/`undefined` after initialized.
     * @type {Object}
     */
    this.otherDims = {};

    /**
     * Be `true` if this dimension is not mapped to any "coordSysDim" that the
     * "coordSys" required.
     * Mandatory.
     * @type {boolean}
     */
    // this.isExtraCoord;

    /**
     * @type {module:data/OrdinalMeta}
     */
    // this.ordinalMeta;

    /**
     * Whether to create inverted indices.
     * @type {boolean}
     */
    // this.createInvertedIndices;
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/* global Float64Array, Int32Array, Uint32Array, Uint16Array */

/**
 * List for data storage
 * @module echarts/data/List
 */

var isObject$4 = isObject$1;

var UNDEFINED = 'undefined';
var INDEX_NOT_FOUND = -1;

// Use prefix to avoid index to be the same as otherIdList[idx],
// which will cause weird udpate animation.
var ID_PREFIX = 'e\0\0';

var dataCtors = {
    'float': typeof Float64Array === UNDEFINED
        ? Array : Float64Array,
    'int': typeof Int32Array === UNDEFINED
        ? Array : Int32Array,
    // Ordinal data type can be string or int
    'ordinal': Array,
    'number': Array,
    'time': Array
};

// Caution: MUST not use `new CtorUint32Array(arr, 0, len)`, because the Ctor of array is
// different from the Ctor of typed array.
var CtorUint32Array = typeof Uint32Array === UNDEFINED ? Array : Uint32Array;
var CtorInt32Array = typeof Int32Array === UNDEFINED ? Array : Int32Array;
var CtorUint16Array = typeof Uint16Array === UNDEFINED ? Array : Uint16Array;

function getIndicesCtor(list) {
    // The possible max value in this._indicies is always this._rawCount despite of filtering.
    return list._rawCount > 65535 ? CtorUint32Array : CtorUint16Array;
}

function cloneChunk(originalChunk) {
    var Ctor = originalChunk.constructor;
    // Only shallow clone is enough when Array.
    return Ctor === Array ? originalChunk.slice() : new Ctor(originalChunk);
}

var TRANSFERABLE_PROPERTIES = [
    'hasItemOption', '_nameList', '_idList', '_invertedIndicesMap',
    '_rawData', '_chunkSize', '_chunkCount', '_dimValueGetter',
    '_count', '_rawCount', '_nameDimIdx', '_idDimIdx'
];
var CLONE_PROPERTIES = [
    '_extent', '_approximateExtent', '_rawExtent'
];

function transferProperties(target, source) {
    each$1(TRANSFERABLE_PROPERTIES.concat(source.__wrappedMethods || []), function (propName) {
        if (source.hasOwnProperty(propName)) {
            target[propName] = source[propName];
        }
    });

    target.__wrappedMethods = source.__wrappedMethods;

    each$1(CLONE_PROPERTIES, function (propName) {
        target[propName] = clone(source[propName]);
    });

    target._calculationInfo = extend(source._calculationInfo);
}





/**
 * @constructor
 * @alias module:echarts/data/List
 *
 * @param {Array.<string|Object|module:data/DataDimensionInfo>} dimensions
 *      For example, ['someDimName', {name: 'someDimName', type: 'someDimType'}, ...].
 *      Dimensions should be concrete names like x, y, z, lng, lat, angle, radius
 * @param {module:echarts/model/Model} hostModel
 */
var List = function (dimensions, hostModel) {

    dimensions = dimensions || ['x', 'y'];

    var dimensionInfos = {};
    var dimensionNames = [];
    var invertedIndicesMap = {};

    for (var i = 0; i < dimensions.length; i++) {
        // Use the original dimensions[i], where other flag props may exists.
        var dimensionInfo = dimensions[i];

        if (isString(dimensionInfo)) {
            dimensionInfo = new DataDimensionInfo({name: dimensionInfo});
        }
        else if (!(dimensionInfo instanceof DataDimensionInfo)) {
            dimensionInfo = new DataDimensionInfo(dimensionInfo);
        }

        var dimensionName = dimensionInfo.name;
        dimensionInfo.type = dimensionInfo.type || 'float';
        if (!dimensionInfo.coordDim) {
            dimensionInfo.coordDim = dimensionName;
            dimensionInfo.coordDimIndex = 0;
        }

        dimensionInfo.otherDims = dimensionInfo.otherDims || {};
        dimensionNames.push(dimensionName);
        dimensionInfos[dimensionName] = dimensionInfo;

        dimensionInfo.index = i;

        if (dimensionInfo.createInvertedIndices) {
            invertedIndicesMap[dimensionName] = [];
        }
    }

    /**
     * @readOnly
     * @type {Array.<string>}
     */
    this.dimensions = dimensionNames;

    /**
     * Infomation of each data dimension, like data type.
     * @type {Object}
     */
    this._dimensionInfos = dimensionInfos;

    /**
     * @type {module:echarts/model/Model}
     */
    this.hostModel = hostModel;

    /**
     * @type {module:echarts/model/Model}
     */
    this.dataType;

    /**
     * Indices stores the indices of data subset after filtered.
     * This data subset will be used in chart.
     * @type {Array.<number>}
     * @readOnly
     */
    this._indices = null;

    this._count = 0;
    this._rawCount = 0;

    /**
     * Data storage
     * @type {Object.<key, Array.<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 = [];

    /**
     * Global visual properties after visual coding
     * @type {Object}
     * @private
     */
    this._visual = {};

    /**
     * Globel layout properties.
     * @type {Object}
     * @private
     */
    this._layout = {};

    /**
     * Item visual properties after visual coding
     * @type {Array.<Object>}
     * @private
     */
    this._itemVisuals = [];

    /**
     * Key: visual type, Value: boolean
     * @type {Object}
     * @readOnly
     */
    this.hasItemVisual = {};

    /**
     * Item layout properties after layout
     * @type {Array.<Object>}
     * @private
     */
    this._itemLayouts = [];

    /**
     * Graphic elemnents
     * @type {Array.<module:zrender/Element>}
     * @private
     */
    this._graphicEls = [];

    /**
     * Max size of each chunk.
     * @type {number}
     * @private
     */
    this._chunkSize = 1e5;

    /**
     * @type {number}
     * @private
     */
    this._chunkCount = 0;

    /**
     * @type {Array.<Array|Object>}
     * @private
     */
    this._rawData;

    /**
     * Raw extent will not be cloned, but only transfered.
     * It will not be calculated util needed.
     * key: dim,
     * value: {end: number, extent: Array.<number>}
     * @type {Object}
     * @private
     */
    this._rawExtent = {};

    /**
     * @type {Object}
     * @private
     */
    this._extent = {};

    /**
     * key: dim
     * value: extent
     * @type {Object}
     * @private
     */
    this._approximateExtent = {};

    /**
     * Cache summary info for fast visit. See "dimensionHelper".
     * @type {Object}
     * @private
     */
    this._dimensionsSummary = summarizeDimensions(this);

    /**
     * @type {Object.<Array|TypedArray>}
     * @private
     */
    this._invertedIndicesMap = invertedIndicesMap;

    /**
     * @type {Object}
     * @private
     */
    this._calculationInfo = {};

    /**
     * User output info of this data.
     * DO NOT use it in other places!
     *
     * When preparing user params for user callbacks, we have
     * to clone these inner data structures to prevent users
     * from modifying them to effect built-in logic. And for
     * performance consideration we make this `userOutput` to
     * avoid clone them too many times.
     *
     * @type {Object}
     * @readOnly
     */
    this.userOutput = this._dimensionsSummary.userOutput;
};

var listProto = List.prototype;

listProto.type = 'list';

/**
 * If each data item has it's own option
 * @type {boolean}
 */
listProto.hasItemOption = true;

/**
 * The meanings of the input parameter `dim`:
 *
 * + If dim is a number (e.g., `1`), it means the index of the dimension.
 *   For example, `getDimension(0)` will return 'x' or 'lng' or 'radius'.
 * + If dim is a number-like string (e.g., `"1"`):
 *     + If there is the same concrete dim name defined in `this.dimensions`, it means that concrete name.
 *     + If not, it will be converted to a number, which means the index of the dimension.
 *        (why? because of the backward compatbility. We have been tolerating number-like string in
 *        dimension setting, although now it seems that it is not a good idea.)
 *     For example, `visualMap[i].dimension: "1"` is the same meaning as `visualMap[i].dimension: 1`,
 *     if no dimension name is defined as `"1"`.
 * + If dim is a not-number-like string, it means the concrete dim name.
 *   For example, it can be be default name `"x"`, `"y"`, `"z"`, `"lng"`, `"lat"`, `"angle"`, `"radius"`,
 *   or customized in `dimensions` property of option like `"age"`.
 *
 * Get dimension name
 * @param {string|number} dim See above.
 * @return {string} Concrete dim name.
 */
listProto.getDimension = function (dim) {
    if (typeof dim === 'number'
        // If being a number-like string but not being defined a dimension name.
        || (!isNaN(dim) && !this._dimensionInfos.hasOwnProperty(dim))
    ) {
        dim = this.dimensions[dim];
    }
    return dim;
};

/**
 * Get type and calculation 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) {
    // Do not clone, because there may be categories in dimInfo.
    return this._dimensionInfos[this.getDimension(dim)];
};

/**
 * @return {Array.<string>} concrete dimension name list on coord.
 */
listProto.getDimensionsOnCoord = function () {
    return this._dimensionsSummary.dataDimsOnCoord.slice();
};

/**
 * @param {string} coordDim
 * @param {number} [idx] A coordDim may map to more than one data dim.
 *        If idx is `true`, return a array of all mapped dims.
 *        If idx is not specified, return the first dim not extra.
 * @return {string|Array.<string>} concrete data dim.
 *        If idx is number, and not found, return null/undefined.
 *        If idx is `true`, and not found, return empty array (always return array).
 */
listProto.mapDimension = function (coordDim, idx) {
    var dimensionsSummary = this._dimensionsSummary;

    if (idx == null) {
        return dimensionsSummary.encodeFirstDimNotExtra[coordDim];
    }

    var dims = dimensionsSummary.encode[coordDim];
    return idx === true
        // always return array if idx is `true`
        ? (dims || []).slice()
        : (dims && dims[idx]);
};

/**
 * Initialize from data
 * @param {Array.<Object|number|Array>} data source or data or data provider.
 * @param {Array.<string>} [nameLIst] The name of a datum is used on data diff and
 *        default label/tooltip.
 *        A name can be specified in encode.itemName,
 *        or dataItem.name (only for series option data),
 *        or provided in nameList from outside.
 * @param {Function} [dimValueGetter] (dataItem, dimName, dataIndex, dimIndex) => number
 */
listProto.initData = function (data, nameList, dimValueGetter) {

    var notProvider = Source.isInstance(data) || isArrayLike(data);
    if (notProvider) {
        data = new DefaultDataProvider(data, this.dimensions.length);
    }

    if (__DEV__) {
        if (!notProvider && (typeof data.getItem !== 'function' || typeof data.count !== 'function')) {
            throw new Error('Inavlid data provider.');
        }
    }

    this._rawData = data;

    // Clear
    this._storage = {};
    this._indices = null;

    this._nameList = nameList || [];

    this._idList = [];

    this._nameRepeatCount = {};

    if (!dimValueGetter) {
        this.hasItemOption = false;
    }

    /**
     * @readOnly
     */
    this.defaultDimValueGetter = defaultDimValueGetters[
        this._rawData.getSource().sourceFormat
    ];
    // Default dim value getter
    this._dimValueGetter = dimValueGetter = dimValueGetter
        || this.defaultDimValueGetter;
    this._dimValueGetterArrayRows = defaultDimValueGetters.arrayRows;

    // Reset raw extent.
    this._rawExtent = {};

    this._initDataFromProvider(0, data.count());

    // If data has no item option.
    if (data.pure) {
        this.hasItemOption = false;
    }
};

listProto.getProvider = function () {
    return this._rawData;
};

/**
 * Caution: Can be only called on raw data (before `this._indices` created).
 */
listProto.appendData = function (data) {
    if (__DEV__) {
        assert$1(!this._indices, 'appendData can only be called on raw data.');
    }

    var rawData = this._rawData;
    var start = this.count();
    rawData.appendData(data);
    var end = rawData.count();
    if (!rawData.persistent) {
        end += start;
    }
    this._initDataFromProvider(start, end);
};

/**
 * Caution: Can be only called on raw data (before `this._indices` created).
 * This method does not modify `rawData` (`dataProvider`), but only
 * add values to storage.
 *
 * The final count will be increased by `Math.max(values.length, names.length)`.
 *
 * @param {Array.<Array.<*>>} values That is the SourceType: 'arrayRows', like
 *        [
 *            [12, 33, 44],
 *            [NaN, 43, 1],
 *            ['-', 'asdf', 0]
 *        ]
 *        Each item is exaclty cooresponding to a dimension.
 * @param {Array.<string>} [names]
 */
listProto.appendValues = function (values, names) {
    var chunkSize = this._chunkSize;
    var storage = this._storage;
    var dimensions = this.dimensions;
    var dimLen = dimensions.length;
    var rawExtent = this._rawExtent;

    var start = this.count();
    var end = start + Math.max(values.length, names ? names.length : 0);
    var originalChunkCount = this._chunkCount;

    for (var i = 0; i < dimLen; i++) {
        var dim = dimensions[i];
        if (!rawExtent[dim]) {
            rawExtent[dim] = getInitialExtent();
        }
        if (!storage[dim]) {
            storage[dim] = [];
        }
        prepareChunks(storage, this._dimensionInfos[dim], chunkSize, originalChunkCount, end);
        this._chunkCount = storage[dim].length;
    }

    var emptyDataItem = new Array(dimLen);
    for (var idx = start; idx < end; idx++) {
        var sourceIdx = idx - start;
        var chunkIndex = Math.floor(idx / chunkSize);
        var chunkOffset = idx % chunkSize;

        // Store the data by dimensions
        for (var k = 0; k < dimLen; k++) {
            var dim = dimensions[k];
            var val = this._dimValueGetterArrayRows(
                values[sourceIdx] || emptyDataItem, dim, sourceIdx, k
            );
            storage[dim][chunkIndex][chunkOffset] = val;

            var dimRawExtent = rawExtent[dim];
            val < dimRawExtent[0] && (dimRawExtent[0] = val);
            val > dimRawExtent[1] && (dimRawExtent[1] = val);
        }

        if (names) {
            this._nameList[idx] = names[sourceIdx];
        }
    }

    this._rawCount = this._count = end;

    // Reset data extent
    this._extent = {};

    prepareInvertedIndex(this);
};

listProto._initDataFromProvider = function (start, end) {
    // Optimize.
    if (start >= end) {
        return;
    }

    var chunkSize = this._chunkSize;
    var rawData = this._rawData;
    var storage = this._storage;
    var dimensions = this.dimensions;
    var dimLen = dimensions.length;
    var dimensionInfoMap = this._dimensionInfos;
    var nameList = this._nameList;
    var idList = this._idList;
    var rawExtent = this._rawExtent;
    var nameRepeatCount = this._nameRepeatCount = {};
    var nameDimIdx;

    var originalChunkCount = this._chunkCount;
    for (var i = 0; i < dimLen; i++) {
        var dim = dimensions[i];
        if (!rawExtent[dim]) {
            rawExtent[dim] = getInitialExtent();
        }

        var dimInfo = dimensionInfoMap[dim];
        if (dimInfo.otherDims.itemName === 0) {
            nameDimIdx = this._nameDimIdx = i;
        }
        if (dimInfo.otherDims.itemId === 0) {
            this._idDimIdx = i;
        }

        if (!storage[dim]) {
            storage[dim] = [];
        }

        prepareChunks(storage, dimInfo, chunkSize, originalChunkCount, end);

        this._chunkCount = storage[dim].length;
    }

    var dataItem = new Array(dimLen);
    for (var idx = start; idx < end; idx++) {
        // NOTICE: Try not to write things into dataItem
        dataItem = rawData.getItem(idx, dataItem);
        // 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 category
        // Use a tempValue to normalize the value to be a (x, y) value
        var chunkIndex = Math.floor(idx / chunkSize);
        var chunkOffset = idx % chunkSize;

        // Store the data by dimensions
        for (var k = 0; k < dimLen; k++) {
            var dim = dimensions[k];
            var dimStorage = storage[dim][chunkIndex];
            // PENDING NULL is empty or zero
            var val = this._dimValueGetter(dataItem, dim, idx, k);
            dimStorage[chunkOffset] = val;

            var dimRawExtent = rawExtent[dim];
            val < dimRawExtent[0] && (dimRawExtent[0] = val);
            val > dimRawExtent[1] && (dimRawExtent[1] = val);
        }

        // ??? FIXME not check by pure but sourceFormat?
        // TODO refactor these logic.
        if (!rawData.pure) {
            var name = nameList[idx];

            if (dataItem && name == null) {
                // If dataItem is {name: ...}, it has highest priority.
                // That is appropriate for many common cases.
                if (dataItem.name != null) {
                    // There is no other place to persistent dataItem.name,
                    // so save it to nameList.
                    nameList[idx] = name = dataItem.name;
                }
                else if (nameDimIdx != null) {
                    var nameDim = dimensions[nameDimIdx];
                    var nameDimChunk = storage[nameDim][chunkIndex];
                    if (nameDimChunk) {
                        name = nameDimChunk[chunkOffset];
                        var ordinalMeta = dimensionInfoMap[nameDim].ordinalMeta;
                        if (ordinalMeta && ordinalMeta.categories.length) {
                            name = ordinalMeta.categories[name];
                        }
                    }
                }
            }

            // Try using the id in option
            // id or name is used on dynamical data, mapping old and new items.
            var id = dataItem == null ? null : dataItem.id;

            if (id == null && name != null) {
                // 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 != null && (idList[idx] = id);
        }
    }

    if (!rawData.persistent && rawData.clean) {
        // Clean unused data if data source is typed array.
        rawData.clean();
    }

    this._rawCount = this._count = end;

    // Reset data extent
    this._extent = {};

    prepareInvertedIndex(this);
};

function prepareChunks(storage, dimInfo, chunkSize, chunkCount, end) {
    var DataCtor = dataCtors[dimInfo.type];
    var lastChunkIndex = chunkCount - 1;
    var dim = dimInfo.name;
    var resizeChunkArray = storage[dim][lastChunkIndex];
    if (resizeChunkArray && resizeChunkArray.length < chunkSize) {
        var newStore = new DataCtor(Math.min(end - lastChunkIndex * chunkSize, chunkSize));
        // The cost of the copy is probably inconsiderable
        // within the initial chunkSize.
        for (var j = 0; j < resizeChunkArray.length; j++) {
            newStore[j] = resizeChunkArray[j];
        }
        storage[dim][lastChunkIndex] = newStore;
    }

    // Create new chunks.
    for (var k = chunkCount * chunkSize; k < end; k += chunkSize) {
        storage[dim].push(new DataCtor(Math.min(end - k, chunkSize)));
    }
}

function prepareInvertedIndex(list) {
    var invertedIndicesMap = list._invertedIndicesMap;
    each$1(invertedIndicesMap, function (invertedIndices, dim) {
        var dimInfo = list._dimensionInfos[dim];

        // Currently, only dimensions that has ordinalMeta can create inverted indices.
        var ordinalMeta = dimInfo.ordinalMeta;
        if (ordinalMeta) {
            invertedIndices = invertedIndicesMap[dim] = new CtorInt32Array(
                ordinalMeta.categories.length
            );
            // The default value of TypedArray is 0. To avoid miss
            // mapping to 0, we should set it as INDEX_NOT_FOUND.
            for (var i = 0; i < invertedIndices.length; i++) {
                invertedIndices[i] = INDEX_NOT_FOUND;
            }
            for (var i = 0; i < list._count; i++) {
                // Only support the case that all values are distinct.
                invertedIndices[list.get(dim, i)] = i;
            }
        }
    });
}

function getRawValueFromStore(list, dimIndex, rawIndex) {
    var val;
    if (dimIndex != null) {
        var chunkSize = list._chunkSize;
        var chunkIndex = Math.floor(rawIndex / chunkSize);
        var chunkOffset = rawIndex % chunkSize;
        var dim = list.dimensions[dimIndex];
        var chunk = list._storage[dim][chunkIndex];
        if (chunk) {
            val = chunk[chunkOffset];
            var ordinalMeta = list._dimensionInfos[dim].ordinalMeta;
            if (ordinalMeta && ordinalMeta.categories.length) {
                val = ordinalMeta.categories[val];
            }
        }
    }
    return val;
}

/**
 * @return {number}
 */
listProto.count = function () {
    return this._count;
};

listProto.getIndices = function () {
    var newIndices;

    var indices = this._indices;
    if (indices) {
        var Ctor = indices.constructor;
        var thisCount = this._count;
        // `new Array(a, b, c)` is different from `new Uint32Array(a, b, c)`.
        if (Ctor === Array) {
            newIndices = new Ctor(thisCount);
            for (var i = 0; i < thisCount; i++) {
                newIndices[i] = indices[i];
            }
        }
        else {
            newIndices = new Ctor(indices.buffer, 0, thisCount);
        }
    }
    else {
        var Ctor = getIndicesCtor(this);
        var newIndices = new Ctor(this.count());
        for (var i = 0; i < newIndices.length; i++) {
            newIndices[i] = i;
        }
    }

    return newIndices;
};

/**
 * Get value. Return NaN if idx is out of range.
 * @param {string} dim Dim must be concrete name.
 * @param {number} idx
 * @param {boolean} stack
 * @return {number}
 */
listProto.get = function (dim, idx /*, stack */) {
    if (!(idx >= 0 && idx < this._count)) {
        return NaN;
    }
    var storage = this._storage;
    if (!storage[dim]) {
        // TODO Warn ?
        return NaN;
    }

    idx = this.getRawIndex(idx);

    var chunkIndex = Math.floor(idx / this._chunkSize);
    var chunkOffset = idx % this._chunkSize;

    var chunkStore = storage[dim][chunkIndex];
    var value = chunkStore[chunkOffset];
    // FIXME ordinal data type is not stackable
    // if (stack) {
    //     var dimensionInfo = this._dimensionInfos[dim];
    //     if (dimensionInfo && dimensionInfo.stackable) {
    //         var stackedOn = this.stackedOn;
    //         while (stackedOn) {
    //             // Get no stacked data of stacked on
    //             var stackedValue = stackedOn.get(dim, idx);
    //             // Considering positive stack, negative stack and empty data
    //             if ((value >= 0 && stackedValue > 0)  // Positive stack
    //                 || (value <= 0 && stackedValue < 0) // Negative stack
    //             ) {
    //                 value += stackedValue;
    //             }
    //             stackedOn = stackedOn.stackedOn;
    //         }
    //     }
    // }

    return value;
};

/**
 * @param {string} dim concrete dim
 * @param {number} rawIndex
 * @return {number|string}
 */
listProto.getByRawIndex = function (dim, rawIdx) {
    if (!(rawIdx >= 0 && rawIdx < this._rawCount)) {
        return NaN;
    }
    var dimStore = this._storage[dim];
    if (!dimStore) {
        // TODO Warn ?
        return NaN;
    }

    var chunkIndex = Math.floor(rawIdx / this._chunkSize);
    var chunkOffset = rawIdx % this._chunkSize;
    var chunkStore = dimStore[chunkIndex];
    return chunkStore[chunkOffset];
};

/**
 * FIXME Use `get` on chrome maybe slow(in filterSelf and selectRange).
 * Hack a much simpler _getFast
 * @private
 */
listProto._getFast = function (dim, rawIdx) {
    var chunkIndex = Math.floor(rawIdx / this._chunkSize);
    var chunkOffset = rawIdx % this._chunkSize;
    var chunkStore = this._storage[dim][chunkIndex];
    return chunkStore[chunkOffset];
};

/**
 * Get value for multi dimensions.
 * @param {Array.<string>} [dimensions] If ignored, using all dimensions.
 * @param {number} idx
 * @return {number}
 */
listProto.getValues = function (dimensions, idx /*, stack */) {
    var values = [];

    if (!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 '-'
 * Only check the coord dimensions.
 * @param {string} dim
 * @param {number} idx
 * @return {number}
 */
listProto.hasValue = function (idx) {
    var dataDimsOnCoord = this._dimensionsSummary.dataDimsOnCoord;
    for (var i = 0, len = dataDimsOnCoord.length; i < len; i++) {
        // Ordinal type originally can be string or number.
        // But when an ordinal type is used on coord, it can
        // not be string but only number. So we can also use isNaN.
        if (isNaN(this.get(dataDimsOnCoord[i], idx))) {
            return false;
        }
    }
    return true;
};

/**
 * Get extent of data in one dimension
 * @param {string} dim
 * @param {boolean} stack
 */
listProto.getDataExtent = function (dim /*, stack */) {
    // Make sure use concrete dim as cache name.
    dim = this.getDimension(dim);
    var dimData = this._storage[dim];
    var initialExtent = getInitialExtent();

    // stack = !!((stack || false) && this.getCalculationInfo(dim));

    if (!dimData) {
        return initialExtent;
    }

    // Make more strict checkings to ensure hitting cache.
    var currEnd = this.count();
    // var cacheName = [dim, !!stack].join('_');
    // var cacheName = dim;

    // Consider the most cases when using data zoom, `getDataExtent`
    // happened before filtering. We cache raw extent, which is not
    // necessary to be cleared and recalculated when restore data.
    var useRaw = !this._indices; // && !stack;
    var dimExtent;

    if (useRaw) {
        return this._rawExtent[dim].slice();
    }
    dimExtent = this._extent[dim];
    if (dimExtent) {
        return dimExtent.slice();
    }
    dimExtent = initialExtent;

    var min = dimExtent[0];
    var max = dimExtent[1];

    for (var i = 0; i < currEnd; i++) {
        // var value = stack ? this.get(dim, i, true) : this._getFast(dim, this.getRawIndex(i));
        var value = this._getFast(dim, this.getRawIndex(i));
        value < min && (min = value);
        value > max && (max = value);
    }

    dimExtent = [min, max];

    this._extent[dim] = dimExtent;

    return dimExtent;
};

/**
 * Optimize for the scenario that data is filtered by a given extent.
 * Consider that if data amount is more than hundreds of thousand,
 * extent calculation will cost more than 10ms and the cache will
 * be erased because of the filtering.
 */
listProto.getApproximateExtent = function (dim /*, stack */) {
    dim = this.getDimension(dim);
    return this._approximateExtent[dim] || this.getDataExtent(dim /*, stack */);
};

listProto.setApproximateExtent = function (extent, dim /*, stack */) {
    dim = this.getDimension(dim);
    this._approximateExtent[dim] = extent.slice();
};

/**
 * @param {string} key
 * @return {*}
 */
listProto.getCalculationInfo = function (key) {
    return this._calculationInfo[key];
};

/**
 * @param {string|Object} key or k-v object
 * @param {*} [value]
 */
listProto.setCalculationInfo = function (key, value) {
    isObject$4(key)
        ? extend(this._calculationInfo, key)
        : (this._calculationInfo[key] = value);
};

/**
 * Get sum of data in one dimension
 * @param {string} dim
 */
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;
};

/**
 * Get median of data in one dimension
 * @param {string} dim
 */
listProto.getMedian = function (dim /*, stack */) {
    var dimDataArray = [];
    // map all data of one dimension
    this.each(dim, function (val, idx) {
        if (!isNaN(val)) {
            dimDataArray.push(val);
        }
    });

    // TODO
    // Use quick select?

    // immutability & sort
    var sortedDimDataArray = [].concat(dimDataArray).sort(function (a, b) {
        return a - b;
    });
    var len = this.count();
    // calculate median
    return len === 0
        ? 0
        : len % 2 === 1
        ? sortedDimDataArray[(len - 1) / 2]
        : (sortedDimDataArray[len / 2] + sortedDimDataArray[len / 2 - 1]) / 2;
};

// /**
//  * Retreive the index with given value
//  * @param {string} dim Concrete dimension.
//  * @param {number} value
//  * @return {number}
//  */
// Currently incorrect: should return dataIndex but not rawIndex.
// Do not fix it until this method is to be used somewhere.
// FIXME Precision of float value
// listProto.indexOf = function (dim, value) {
//     var storage = this._storage;
//     var dimData = storage[dim];
//     var chunkSize = this._chunkSize;
//     if (dimData) {
//         for (var i = 0, len = this.count(); i < len; i++) {
//             var chunkIndex = Math.floor(i / chunkSize);
//             var chunkOffset = i % chunkSize;
//             if (dimData[chunkIndex][chunkOffset] === value) {
//                 return i;
//             }
//         }
//     }
//     return -1;
// };

/**
 * Only support the dimension which inverted index created.
 * Do not support other cases until required.
 * @param {string} concrete dim
 * @param {number|string} value
 * @return {number} rawIndex
 */
listProto.rawIndexOf = function (dim, value) {
    var invertedIndices = dim && this._invertedIndicesMap[dim];
    if (__DEV__) {
        if (!invertedIndices) {
            throw new Error('Do not supported yet');
        }
    }
    var rawIndex = invertedIndices[value];
    if (rawIndex == null || isNaN(rawIndex)) {
        return INDEX_NOT_FOUND;
    }
    return rawIndex;
};

/**
 * Retreive the index with given name
 * @param {number} idx
 * @param {number} name
 * @return {number}
 */
listProto.indexOfName = function (name) {
    for (var i = 0, len = this.count(); i < len; i++) {
        if (this.getName(i) === name) {
            return i;
        }
    }

    return -1;
};

/**
 * Retreive the index with given raw data index
 * @param {number} idx
 * @param {number} name
 * @return {number}
 */
listProto.indexOfRawIndex = function (rawIndex) {
    if (rawIndex >= this._rawCount || rawIndex < 0) {
        return -1;
    }

    if (!this._indices) {
        return rawIndex;
    }

    // Indices are ascending
    var indices = this._indices;

    // If rawIndex === dataIndex
    var rawDataIndex = indices[rawIndex];
    if (rawDataIndex != null && rawDataIndex < this._count && rawDataIndex === rawIndex) {
        return rawIndex;
    }

    var left = 0;
    var right = this._count - 1;
    while (left <= right) {
        var mid = (left + right) / 2 | 0;
        if (indices[mid] < rawIndex) {
            left = mid + 1;
        }
        else if (indices[mid] > rawIndex) {
            right = mid - 1;
        }
        else {
            return mid;
        }
    }
    return -1;
};

/**
 * Retreive the index of nearest value
 * @param {string} dim
 * @param {number} value
 * @param {number} [maxDistance=Infinity]
 * @return {Array.<number>} If and only if multiple indices has
 *        the same value, they are put to the result.
 */
listProto.indicesOfNearest = function (dim, value, maxDistance) {
    var storage = this._storage;
    var dimData = storage[dim];
    var nearestIndices = [];

    if (!dimData) {
        return nearestIndices;
    }

    if (maxDistance == null) {
        maxDistance = Infinity;
    }

    var minDist = Infinity;
    var minDiff = -1;
    var nearestIndicesLen = 0;

    // Check the test case of `test/ut/spec/data/List.js`.
    for (var i = 0, len = this.count(); i < len; i++) {
        var diff = value - this.get(dim, i);
        var dist = Math.abs(diff);
        if (dist <= maxDistance) {
            // When the `value` is at the middle of `this.get(dim, i)` and `this.get(dim, i+1)`,
            // we'd better not push both of them to `nearestIndices`, otherwise it is easy to
            // get more than one item in `nearestIndices` (more specifically, in `tooltip`).
            // So we chose the one that `diff >= 0` in this csae.
            // But if `this.get(dim, i)` and `this.get(dim, j)` get the same value, both of them
            // should be push to `nearestIndices`.
            if (dist < minDist
                || (dist === minDist && diff >= 0 && minDiff < 0)
            ) {
                minDist = dist;
                minDiff = diff;
                nearestIndicesLen = 0;
            }
            if (diff === minDiff) {
                nearestIndices[nearestIndicesLen++] = i;
            }
        }
    }
    nearestIndices.length = nearestIndicesLen;

    return nearestIndices;
};

/**
 * Get raw data index
 * @param {number} idx
 * @return {number}
 */
listProto.getRawIndex = getRawIndexWithoutIndices;

function getRawIndexWithoutIndices(idx) {
    return idx;
}

function getRawIndexWithIndices(idx) {
    if (idx < this._count && idx >= 0) {
        return this._indices[idx];
    }
    return -1;
}

/**
 * Get raw data item
 * @param {number} idx
 * @return {number}
 */
listProto.getRawDataItem = function (idx) {
    if (!this._rawData.persistent) {
        var val = [];
        for (var i = 0; i < this.dimensions.length; i++) {
            var dim = this.dimensions[i];
            val.push(this.get(dim, idx));
        }
        return val;
    }
    else {
        return this._rawData.getItem(this.getRawIndex(idx));
    }
};

/**
 * @param {number} idx
 * @param {boolean} [notDefaultIdx=false]
 * @return {string}
 */
listProto.getName = function (idx) {
    var rawIndex = this.getRawIndex(idx);
    return this._nameList[rawIndex]
        || getRawValueFromStore(this, this._nameDimIdx, rawIndex)
        || '';
};

/**
 * @param {number} idx
 * @param {boolean} [notDefaultIdx=false]
 * @return {string}
 */
listProto.getId = function (idx) {
    return getId(this, this.getRawIndex(idx));
};

function getId(list, rawIndex) {
    var id = list._idList[rawIndex];
    if (id == null) {
        id = getRawValueFromStore(list, list._idDimIdx, rawIndex);
    }
    if (id == null) {
        // FIXME Check the usage in graph, should not use prefix.
        id = ID_PREFIX + rawIndex;
    }
    return id;
}

function normalizeDimensions(dimensions) {
    if (!isArray(dimensions)) {
        dimensions = [dimensions];
    }
    return dimensions;
}

function validateDimensions(list, dims) {
    for (var i = 0; i < dims.length; i++) {
        // stroage may be empty when no data, so use
        // dimensionInfos to check.
        if (!list._dimensionInfos[dims[i]]) {
            console.error('Unkown dimension ' + dims[i]);
        }
    }
}

/**
 * Data iteration
 * @param {string|Array.<string>}
 * @param {Function} cb
 * @param {*} [context=this]
 *
 * @example
 *  list.each('x', function (x, idx) {});
 *  list.each(['x', 'y'], function (x, y, idx) {});
 *  list.each(function (idx) {})
 */
listProto.each = function (dims, cb, context, contextCompat) {
    'use strict';

    if (!this._count) {
        return;
    }

    if (typeof dims === 'function') {
        contextCompat = context;
        context = cb;
        cb = dims;
        dims = [];
    }

    // contextCompat just for compat echarts3
    context = context || contextCompat || this;

    dims = map(normalizeDimensions(dims), this.getDimension, this);

    if (__DEV__) {
        validateDimensions(this, dims);
    }

    var dimSize = dims.length;

    for (var i = 0; i < this.count(); i++) {
        // Simple optimization
        switch (dimSize) {
            case 0:
                cb.call(context, i);
                break;
            case 1:
                cb.call(context, this.get(dims[0], i), i);
                break;
            case 2:
                cb.call(context, this.get(dims[0], i), this.get(dims[1], i), i);
                break;
            default:
                var k = 0;
                var value = [];
                for (; k < dimSize; k++) {
                    value[k] = this.get(dims[k], i);
                }
                // Index
                value[k] = i;
                cb.apply(context, value);
        }
    }
};

/**
 * Data filter
 * @param {string|Array.<string>}
 * @param {Function} cb
 * @param {*} [context=this]
 */
listProto.filterSelf = function (dimensions, cb, context, contextCompat) {
    'use strict';

    if (!this._count) {
        return;
    }

    if (typeof dimensions === 'function') {
        contextCompat = context;
        context = cb;
        cb = dimensions;
        dimensions = [];
    }

    // contextCompat just for compat echarts3
    context = context || contextCompat || this;

    dimensions = map(
        normalizeDimensions(dimensions), this.getDimension, this
    );

    if (__DEV__) {
        validateDimensions(this, dimensions);
    }


    var count = this.count();
    var Ctor = getIndicesCtor(this);
    var newIndices = new Ctor(count);
    var value = [];
    var dimSize = dimensions.length;

    var offset = 0;
    var dim0 = dimensions[0];

    for (var i = 0; i < count; i++) {
        var keep;
        var rawIdx = this.getRawIndex(i);
        // Simple optimization
        if (dimSize === 0) {
            keep = cb.call(context, i);
        }
        else if (dimSize === 1) {
            var val = this._getFast(dim0, rawIdx);
            keep = cb.call(context, val, i);
        }
        else {
            for (var k = 0; k < dimSize; k++) {
                value[k] = this._getFast(dim0, rawIdx);
            }
            value[k] = i;
            keep = cb.apply(context, value);
        }
        if (keep) {
            newIndices[offset++] = rawIdx;
        }
    }

    // Set indices after filtered.
    if (offset < count) {
        this._indices = newIndices;
    }
    this._count = offset;
    // Reset data extent
    this._extent = {};

    this.getRawIndex = this._indices ? getRawIndexWithIndices : getRawIndexWithoutIndices;

    return this;
};

/**
 * Select data in range. (For optimization of filter)
 * (Manually inline code, support 5 million data filtering in data zoom.)
 */
listProto.selectRange = function (range) {
    'use strict';

    if (!this._count) {
        return;
    }

    var dimensions = [];
    for (var dim in range) {
        if (range.hasOwnProperty(dim)) {
            dimensions.push(dim);
        }
    }

    if (__DEV__) {
        validateDimensions(this, dimensions);
    }

    var dimSize = dimensions.length;
    if (!dimSize) {
        return;
    }

    var originalCount = this.count();
    var Ctor = getIndicesCtor(this);
    var newIndices = new Ctor(originalCount);

    var offset = 0;
    var dim0 = dimensions[0];

    var min = range[dim0][0];
    var max = range[dim0][1];

    var quickFinished = false;
    if (!this._indices) {
        // Extreme optimization for common case. About 2x faster in chrome.
        var idx = 0;
        if (dimSize === 1) {
            var dimStorage = this._storage[dimensions[0]];
            for (var k = 0; k < this._chunkCount; k++) {
                var chunkStorage = dimStorage[k];
                var len = Math.min(this._count - k * this._chunkSize, this._chunkSize);
                for (var i = 0; i < len; i++) {
                    var val = chunkStorage[i];
                    // NaN will not be filtered. Consider the case, in line chart, empty
                    // value indicates the line should be broken. But for the case like
                    // scatter plot, a data item with empty value will not be rendered,
                    // but the axis extent may be effected if some other dim of the data
                    // item has value. Fortunately it is not a significant negative effect.
                    if (
                        (val >= min && val <= max) || isNaN(val)
                    ) {
                        newIndices[offset++] = idx;
                    }
                    idx++;
                }
            }
            quickFinished = true;
        }
        else if (dimSize === 2) {
            var dimStorage = this._storage[dim0];
            var dimStorage2 = this._storage[dimensions[1]];
            var min2 = range[dimensions[1]][0];
            var max2 = range[dimensions[1]][1];
            for (var k = 0; k < this._chunkCount; k++) {
                var chunkStorage = dimStorage[k];
                var chunkStorage2 = dimStorage2[k];
                var len = Math.min(this._count - k * this._chunkSize, this._chunkSize);
                for (var i = 0; i < len; i++) {
                    var val = chunkStorage[i];
                    var val2 = chunkStorage2[i];
                    // Do not filter NaN, see comment above.
                    if ((
                            (val >= min && val <= max) || isNaN(val)
                        )
                        && (
                            (val2 >= min2 && val2 <= max2) || isNaN(val2)
                        )
                    ) {
                        newIndices[offset++] = idx;
                    }
                    idx++;
                }
            }
            quickFinished = true;
        }
    }
    if (!quickFinished) {
        if (dimSize === 1) {
            for (var i = 0; i < originalCount; i++) {
                var rawIndex = this.getRawIndex(i);
                var val = this._getFast(dim0, rawIndex);
                // Do not filter NaN, see comment above.
                if (
                    (val >= min && val <= max) || isNaN(val)
                ) {
                    newIndices[offset++] = rawIndex;
                }
            }
        }
        else {
            for (var i = 0; i < originalCount; i++) {
                var keep = true;
                var rawIndex = this.getRawIndex(i);
                for (var k = 0; k < dimSize; k++) {
                    var dimk = dimensions[k];
                    var val = this._getFast(dim, rawIndex);
                    // Do not filter NaN, see comment above.
                    if (val < range[dimk][0] || val > range[dimk][1]) {
                        keep = false;
                    }
                }
                if (keep) {
                    newIndices[offset++] = this.getRawIndex(i);
                }
            }
        }
    }

    // Set indices after filtered.
    if (offset < originalCount) {
        this._indices = newIndices;
    }
    this._count = offset;
    // Reset data extent
    this._extent = {};

    this.getRawIndex = this._indices ? getRawIndexWithIndices : getRawIndexWithoutIndices;

    return this;
};

/**
 * Data mapping to a plain array
 * @param {string|Array.<string>} [dimensions]
 * @param {Function} cb
 * @param {*} [context=this]
 * @return {Array}
 */
listProto.mapArray = function (dimensions, cb, context, contextCompat) {
    'use strict';

    if (typeof dimensions === 'function') {
        contextCompat = context;
        context = cb;
        cb = dimensions;
        dimensions = [];
    }

    // contextCompat just for compat echarts3
    context = context || contextCompat || this;

    var result = [];
    this.each(dimensions, function () {
        result.push(cb && cb.apply(this, arguments));
    }, context);
    return result;
};

// Data in excludeDimensions is copied, otherwise transfered.
function cloneListForMapAndSample(original, excludeDimensions) {
    var allDimensions = original.dimensions;
    var list = new List(
        map(allDimensions, original.getDimensionInfo, original),
        original.hostModel
    );
    // FIXME If needs stackedOn, value may already been stacked
    transferProperties(list, original);

    var storage = list._storage = {};
    var originalStorage = original._storage;

    // Init storage
    for (var i = 0; i < allDimensions.length; i++) {
        var dim = allDimensions[i];
        if (originalStorage[dim]) {
            // Notice that we do not reset invertedIndicesMap here, becuase
            // there is no scenario of mapping or sampling ordinal dimension.
            if (indexOf(excludeDimensions, dim) >= 0) {
                storage[dim] = cloneDimStore(originalStorage[dim]);
                list._rawExtent[dim] = getInitialExtent();
                list._extent[dim] = null;
            }
            else {
                // Direct reference for other dimensions
                storage[dim] = originalStorage[dim];
            }
        }
    }
    return list;
}

function cloneDimStore(originalDimStore) {
    var newDimStore = new Array(originalDimStore.length);
    for (var j = 0; j < originalDimStore.length; j++) {
        newDimStore[j] = cloneChunk(originalDimStore[j]);
    }
    return newDimStore;
}

function getInitialExtent() {
    return [Infinity, -Infinity];
}

/**
 * Data mapping to a new List with given dimensions
 * @param {string|Array.<string>} dimensions
 * @param {Function} cb
 * @param {*} [context=this]
 * @return {Array}
 */
listProto.map = function (dimensions, cb, context, contextCompat) {
    'use strict';

    // contextCompat just for compat echarts3
    context = context || contextCompat || this;

    dimensions = map(
        normalizeDimensions(dimensions), this.getDimension, this
    );

    if (__DEV__) {
        validateDimensions(this, dimensions);
    }

    var list = cloneListForMapAndSample(this, dimensions);

    // Following properties are all immutable.
    // So we can reference to the same value
    list._indices = this._indices;
    list.getRawIndex = list._indices ? getRawIndexWithIndices : getRawIndexWithoutIndices;

    var storage = list._storage;

    var tmpRetValue = [];
    var chunkSize = this._chunkSize;
    var dimSize = dimensions.length;
    var dataCount = this.count();
    var values = [];
    var rawExtent = list._rawExtent;

    for (var dataIndex = 0; dataIndex < dataCount; dataIndex++) {
        for (var dimIndex = 0; dimIndex < dimSize; dimIndex++) {
            values[dimIndex] = this.get(dimensions[dimIndex], dataIndex /*, stack */);
        }
        values[dimSize] = dataIndex;

        var retValue = cb && cb.apply(context, values);
        if (retValue != null) {
            // a number or string (in oridinal dimension)?
            if (typeof retValue !== 'object') {
                tmpRetValue[0] = retValue;
                retValue = tmpRetValue;
            }

            var rawIndex = this.getRawIndex(dataIndex);
            var chunkIndex = Math.floor(rawIndex / chunkSize);
            var chunkOffset = rawIndex % chunkSize;

            for (var i = 0; i < retValue.length; i++) {
                var dim = dimensions[i];
                var val = retValue[i];
                var rawExtentOnDim = rawExtent[dim];

                var dimStore = storage[dim];
                if (dimStore) {
                    dimStore[chunkIndex][chunkOffset] = val;
                }

                if (val < rawExtentOnDim[0]) {
                    rawExtentOnDim[0] = val;
                }
                if (val > rawExtentOnDim[1]) {
                    rawExtentOnDim[1] = val;
                }
            }
        }
    }

    return list;
};

/**
 * Large data down sampling on given dimension
 * @param {string} dimension
 * @param {number} rate
 * @param {Function} sampleValue
 * @param {Function} sampleIndex Sample index for name and id
 */
listProto.downSample = function (dimension, rate, sampleValue, sampleIndex) {
    var list = cloneListForMapAndSample(this, [dimension]);
    var targetStorage = list._storage;

    var frameValues = [];
    var frameSize = Math.floor(1 / rate);

    var dimStore = targetStorage[dimension];
    var len = this.count();
    var chunkSize = this._chunkSize;
    var rawExtentOnDim = list._rawExtent[dimension];

    var newIndices = new (getIndicesCtor(this))(len);

    var offset = 0;
    for (var i = 0; i < len; i += frameSize) {
        // Last frame
        if (frameSize > len - i) {
            frameSize = len - i;
            frameValues.length = frameSize;
        }
        for (var k = 0; k < frameSize; k++) {
            var dataIdx = this.getRawIndex(i + k);
            var originalChunkIndex = Math.floor(dataIdx / chunkSize);
            var originalChunkOffset = dataIdx % chunkSize;
            frameValues[k] = dimStore[originalChunkIndex][originalChunkOffset];
        }
        var value = sampleValue(frameValues);
        var sampleFrameIdx = this.getRawIndex(
            Math.min(i + sampleIndex(frameValues, value) || 0, len - 1)
        );
        var sampleChunkIndex = Math.floor(sampleFrameIdx / chunkSize);
        var sampleChunkOffset = sampleFrameIdx % chunkSize;
        // Only write value on the filtered data
        dimStore[sampleChunkIndex][sampleChunkOffset] = value;

        if (value < rawExtentOnDim[0]) {
            rawExtentOnDim[0] = value;
        }
        if (value > rawExtentOnDim[1]) {
            rawExtentOnDim[1] = value;
        }

        newIndices[offset++] = sampleFrameIdx;
    }

    list._count = offset;
    list._indices = newIndices;

    list.getRawIndex = getRawIndexWithIndices;

    return list;
};

/**
 * Get model of one data item.
 *
 * @param {number} idx
 */
// FIXME Model proxy ?
listProto.getItemModel = function (idx) {
    var hostModel = this.hostModel;
    return new Model(this.getRawDataItem(idx), hostModel, hostModel && hostModel.ecModel);
};

/**
 * Create a data differ
 * @param {module:echarts/data/List} otherList
 * @return {module:echarts/data/DataDiffer}
 */
listProto.diff = function (otherList) {
    var thisList = this;

    return new DataDiffer(
        otherList ? otherList.getIndices() : [],
        this.getIndices(),
        function (idx) {
            return getId(otherList, idx);
        },
        function (idx) {
            return getId(thisList, 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$4(key)) {
        for (var name in key) {
            if (key.hasOwnProperty(name)) {
                this.setVisual(name, key[name]);
            }
        }
        return;
    }
    this._visual = this._visual || {};
    this._visual[key] = val;
};

/**
 * Set layout property.
 * @param {string|Object} key
 * @param {*} [val]
 */
listProto.setLayout = function (key, val) {
    if (isObject$4(key)) {
        for (var name in key) {
            if (key.hasOwnProperty(name)) {
                this.setLayout(name, key[name]);
            }
        }
        return;
    }
    this._layout[key] = val;
};

/**
 * Get layout property.
 * @param  {string} key.
 * @return {*}
 */
listProto.getLayout = function (key) {
    return this._layout[key];
};

/**
 * Get layout of single data item
 * @param {number} idx
 */
listProto.getItemLayout = function (idx) {
    return this._itemLayouts[idx];
};

/**
 * Set layout of single data item
 * @param {number} idx
 * @param {Object} layout
 * @param {boolean=} [merge=false]
 */
listProto.setItemLayout = function (idx, layout, merge$$1) {
    this._itemLayouts[idx] = merge$$1
        ? extend(this._itemLayouts[idx] || {}, layout)
        : layout;
};

/**
 * Clear all layout of single data item
 */
listProto.clearItemLayouts = function () {
    this._itemLayouts.length = 0;
};

/**
 * Get visual property of single data item
 * @param {number} idx
 * @param {string} key
 * @param {boolean} [ignoreParent=false]
 */
listProto.getItemVisual = function (idx, key, ignoreParent) {
    var itemVisual = this._itemVisuals[idx];
    var val = itemVisual && itemVisual[key];
    if (val == null && !ignoreParent) {
        // Use global visual property
        return this.getVisual(key);
    }
    return val;
};

/**
 * Set visual property of single data item
 *
 * @param {number} idx
 * @param {string|Object} key
 * @param {*} [value]
 *
 * @example
 *  setItemVisual(0, 'color', color);
 *  setItemVisual(0, {
 *      'color': color
 *  });
 */
listProto.setItemVisual = function (idx, key, value) {
    var itemVisual = this._itemVisuals[idx] || {};
    var hasItemVisual = this.hasItemVisual;
    this._itemVisuals[idx] = itemVisual;

    if (isObject$4(key)) {
        for (var name in key) {
            if (key.hasOwnProperty(name)) {
                itemVisual[name] = key[name];
                hasItemVisual[name] = true;
            }
        }
        return;
    }
    itemVisual[key] = value;
    hasItemVisual[key] = true;
};

/**
 * Clear itemVisuals and list visual.
 */
listProto.clearAllVisual = function () {
    this._visual = {};
    this._itemVisuals = [];
    this.hasItemVisual = {};
};

var setItemDataAndSeriesIndex = function (child) {
    child.seriesIndex = this.seriesIndex;
    child.dataIndex = this.dataIndex;
    child.dataType = this.dataType;
};
/**
 * Set graphic element relative to data. It can be set as null
 * @param {number} idx
 * @param {module:zrender/Element} [el]
 */
listProto.setItemGraphicEl = function (idx, el) {
    var hostModel = this.hostModel;

    if (el) {
        // Add data index and series index for indexing the data by element
        // Useful in tooltip
        el.dataIndex = idx;
        el.dataType = this.dataType;
        el.seriesIndex = hostModel && hostModel.seriesIndex;
        if (el.type === 'group') {
            el.traverse(setItemDataAndSeriesIndex, el);
        }
    }

    this._graphicEls[idx] = el;
};

/**
 * @param {number} idx
 * @return {module:zrender/Element}
 */
listProto.getItemGraphicEl = function (idx) {
    return this._graphicEls[idx];
};

/**
 * @param {Function} cb
 * @param {*} context
 */
listProto.eachItemGraphicEl = function (cb, context) {
    each$1(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 (list) {
    if (!list) {
        var dimensionInfoList = map(this.dimensions, this.getDimensionInfo, this);
        list = new List(dimensionInfoList, this.hostModel);
    }

    // FIXME
    list._storage = this._storage;

    transferProperties(list, this);

    // Clone will not change the data extent and indices
    if (this._indices) {
        var Ctor = this._indices.constructor;
        list._indices = new Ctor(this._indices);
    }
    else {
        list._indices = null;
    }
    list.getRawIndex = list._indices ? getRawIndexWithIndices : getRawIndexWithoutIndices;

    return list;
};

/**
 * Wrap some method to add more feature
 * @param {string} methodName
 * @param {Function} injectFunction
 */
listProto.wrapMethod = function (methodName, injectFunction) {
    var originalMethod = this[methodName];
    if (typeof originalMethod !== 'function') {
        return;
    }
    this.__wrappedMethods = this.__wrappedMethods || [];
    this.__wrappedMethods.push(methodName);
    this[methodName] = function () {
        var res = originalMethod.apply(this, arguments);
        return injectFunction.apply(this, [res].concat(slice(arguments)));
    };
};

// Methods that create a new list based on this list should be listed here.
// Notice that those method should `RETURN` the new list.
listProto.TRANSFERABLE_METHODS = ['cloneShallow', 'downSample', 'map'];
// Methods that change indices of this list should be listed here.
listProto.CHANGABLE_METHODS = ['filterSelf', 'selectRange'];

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * @deprecated
 * Use `echarts/data/helper/createDimensions` instead.
 */

/**
 * @see {module:echarts/test/ut/spec/data/completeDimensions}
 *
 * This method builds the relationship between:
 * + "what the coord sys or series requires (see `sysDims`)",
 * + "what the user defines (in `encode` and `dimensions`, see `opt.dimsDef` and `opt.encodeDef`)"
 * + "what the data source provids (see `source`)".
 *
 * Some guess strategy will be adapted if user does not define something.
 * If no 'value' dimension specified, the first no-named dimension will be
 * named as 'value'.
 *
 * @param {Array.<string>} sysDims Necessary dimensions, like ['x', 'y'], which
 *      provides not only dim template, but also default order.
 *      properties: 'name', 'type', 'displayName'.
 *      `name` of each item provides default coord name.
 *      [{dimsDef: [string|Object, ...]}, ...] dimsDef of sysDim item provides default dim name, and
 *                                    provide dims count that the sysDim required.
 *      [{ordinalMeta}] can be specified.
 * @param {module:echarts/data/Source|Array|Object} source or data (for compatibal with pervious)
 * @param {Object} [opt]
 * @param {Array.<Object|string>} [opt.dimsDef] option.series.dimensions User defined dimensions
 *      For example: ['asdf', {name, type}, ...].
 * @param {Object|HashMap} [opt.encodeDef] option.series.encode {x: 2, y: [3, 1], tooltip: [1, 2], label: 3}
 * @param {Function} [opt.encodeDefaulter] Called if no `opt.encodeDef` exists.
 *      If not specified, auto find the next available data dim.
 *      param source {module:data/Source}
 *      param dimCount {number}
 *      return {Object} encode Never be `null/undefined`.
 * @param {string} [opt.generateCoord] Generate coord dim with the given name.
 *      If not specified, extra dim names will be:
 *      'value', 'value0', 'value1', ...
 * @param {number} [opt.generateCoordCount] By default, the generated dim name is `generateCoord`.
 *      If `generateCoordCount` specified, the generated dim names will be:
 *      `generateCoord` + 0, `generateCoord` + 1, ...
 *      can be Infinity, indicate that use all of the remain columns.
 * @param {number} [opt.dimCount] If not specified, guess by the first data item.
 * @return {Array.<module:data/DataDimensionInfo>}
 */
function completeDimensions(sysDims, source, opt) {
    if (!Source.isInstance(source)) {
        source = Source.seriesDataToSource(source);
    }

    opt = opt || {};
    sysDims = (sysDims || []).slice();
    var dimsDef = (opt.dimsDef || []).slice();
    var dataDimNameMap = createHashMap();
    var coordDimNameMap = createHashMap();
    // var valueCandidate;
    var result = [];

    var dimCount = getDimCount(source, sysDims, dimsDef, opt.dimCount);

    // Apply user defined dims (`name` and `type`) and init result.
    for (var i = 0; i < dimCount; i++) {
        var dimDefItem = dimsDef[i] = extend(
            {}, isObject$1(dimsDef[i]) ? dimsDef[i] : {name: dimsDef[i]}
        );
        var userDimName = dimDefItem.name;
        var resultItem = result[i] = new DataDimensionInfo();
        // Name will be applied later for avoiding duplication.
        if (userDimName != null && dataDimNameMap.get(userDimName) == null) {
            // Only if `series.dimensions` is defined in option
            // displayName, will be set, and dimension will be diplayed vertically in
            // tooltip by default.
            resultItem.name = resultItem.displayName = userDimName;
            dataDimNameMap.set(userDimName, i);
        }
        dimDefItem.type != null && (resultItem.type = dimDefItem.type);
        dimDefItem.displayName != null && (resultItem.displayName = dimDefItem.displayName);
    }

    var encodeDef = opt.encodeDef;
    if (!encodeDef && opt.encodeDefaulter) {
        encodeDef = opt.encodeDefaulter(source, dimCount);
    }
    encodeDef = createHashMap(encodeDef);

    // Set `coordDim` and `coordDimIndex` by `encodeDef` and normalize `encodeDef`.
    encodeDef.each(function (dataDims, coordDim) {
        dataDims = normalizeToArray(dataDims).slice();

        // Note: It is allowed that `dataDims.length` is `0`, e.g., options is
        // `{encode: {x: -1, y: 1}}`. Should not filter anything in
        // this case.
        if (dataDims.length === 1 && !isString(dataDims[0]) && dataDims[0] < 0) {
            encodeDef.set(coordDim, false);
            return;
        }

        var validDataDims = encodeDef.set(coordDim, []);
        each$1(dataDims, function (resultDimIdx, idx) {
            // The input resultDimIdx can be dim name or index.
            isString(resultDimIdx) && (resultDimIdx = dataDimNameMap.get(resultDimIdx));
            if (resultDimIdx != null && resultDimIdx < dimCount) {
                validDataDims[idx] = resultDimIdx;
                applyDim(result[resultDimIdx], coordDim, idx);
            }
        });
    });

    // Apply templetes and default order from `sysDims`.
    var availDimIdx = 0;
    each$1(sysDims, function (sysDimItem, sysDimIndex) {
        var coordDim;
        var sysDimItem;
        var sysDimItemDimsDef;
        var sysDimItemOtherDims;
        if (isString(sysDimItem)) {
            coordDim = sysDimItem;
            sysDimItem = {};
        }
        else {
            coordDim = sysDimItem.name;
            var ordinalMeta = sysDimItem.ordinalMeta;
            sysDimItem.ordinalMeta = null;
            sysDimItem = clone(sysDimItem);
            sysDimItem.ordinalMeta = ordinalMeta;
            // `coordDimIndex` should not be set directly.
            sysDimItemDimsDef = sysDimItem.dimsDef;
            sysDimItemOtherDims = sysDimItem.otherDims;
            sysDimItem.name = sysDimItem.coordDim = sysDimItem.coordDimIndex =
                sysDimItem.dimsDef = sysDimItem.otherDims = null;
        }

        var dataDims = encodeDef.get(coordDim);

        // negative resultDimIdx means no need to mapping.
        if (dataDims === false) {
            return;
        }

        var dataDims = normalizeToArray(dataDims);

        // dimensions provides default dim sequences.
        if (!dataDims.length) {
            for (var i = 0; i < (sysDimItemDimsDef && sysDimItemDimsDef.length || 1); i++) {
                while (availDimIdx < result.length && result[availDimIdx].coordDim != null) {
                    availDimIdx++;
                }
                availDimIdx < result.length && dataDims.push(availDimIdx++);
            }
        }

        // Apply templates.
        each$1(dataDims, function (resultDimIdx, coordDimIndex) {
            var resultItem = result[resultDimIdx];
            applyDim(defaults(resultItem, sysDimItem), coordDim, coordDimIndex);
            if (resultItem.name == null && sysDimItemDimsDef) {
                var sysDimItemDimsDefItem = sysDimItemDimsDef[coordDimIndex];
                !isObject$1(sysDimItemDimsDefItem) && (sysDimItemDimsDefItem = {name: sysDimItemDimsDefItem});
                resultItem.name = resultItem.displayName = sysDimItemDimsDefItem.name;
                resultItem.defaultTooltip = sysDimItemDimsDefItem.defaultTooltip;
            }
            // FIXME refactor, currently only used in case: {otherDims: {tooltip: false}}
            sysDimItemOtherDims && defaults(resultItem.otherDims, sysDimItemOtherDims);
        });
    });

    function applyDim(resultItem, coordDim, coordDimIndex) {
        if (OTHER_DIMENSIONS.get(coordDim) != null) {
            resultItem.otherDims[coordDim] = coordDimIndex;
        }
        else {
            resultItem.coordDim = coordDim;
            resultItem.coordDimIndex = coordDimIndex;
            coordDimNameMap.set(coordDim, true);
        }
    }

    // Make sure the first extra dim is 'value'.
    var generateCoord = opt.generateCoord;
    var generateCoordCount = opt.generateCoordCount;
    var fromZero = generateCoordCount != null;
    generateCoordCount = generateCoord ? (generateCoordCount || 1) : 0;
    var extra = generateCoord || 'value';

    // Set dim `name` and other `coordDim` and other props.
    for (var resultDimIdx = 0; resultDimIdx < dimCount; resultDimIdx++) {
        var resultItem = result[resultDimIdx] = result[resultDimIdx] || new DataDimensionInfo();
        var coordDim = resultItem.coordDim;

        if (coordDim == null) {
            resultItem.coordDim = genName(
                extra, coordDimNameMap, fromZero
            );
            resultItem.coordDimIndex = 0;
            if (!generateCoord || generateCoordCount <= 0) {
                resultItem.isExtraCoord = true;
            }
            generateCoordCount--;
        }

        resultItem.name == null && (resultItem.name = genName(
            resultItem.coordDim,
            dataDimNameMap
        ));

        if (resultItem.type == null
            && (
                guessOrdinal(source, resultDimIdx, resultItem.name) === BE_ORDINAL.Must
                // Consider the case:
                // {
                //    dataset: {source: [
                //        ['2001', 123],
                //        ['2002', 456],
                //        ...
                //        ['The others', 987],
                //    ]},
                //    series: {type: 'pie'}
                // }
                // The first colum should better be treated as a "ordinal" although it
                // might not able to be detected as an "ordinal" by `guessOrdinal`.
                || (resultItem.isExtraCoord
                    && (resultItem.otherDims.itemName != null
                        || resultItem.otherDims.seriesName != null
                    )
                )
            )
        ) {
            resultItem.type = 'ordinal';
        }
    }

    return result;
}

// ??? TODO
// Originally detect dimCount by data[0]. Should we
// optimize it to only by sysDims and dimensions and encode.
// So only necessary dims will be initialized.
// But
// (1) custom series should be considered. where other dims
// may be visited.
// (2) sometimes user need to calcualte bubble size or use visualMap
// on other dimensions besides coordSys needed.
// So, dims that is not used by system, should be shared in storage?
function getDimCount(source, sysDims, dimsDef, optDimCount) {
    // Note that the result dimCount should not small than columns count
    // of data, otherwise `dataDimNameMap` checking will be incorrect.
    var dimCount = Math.max(
        source.dimensionsDetectCount || 1,
        sysDims.length,
        dimsDef.length,
        optDimCount || 0
    );
    each$1(sysDims, function (sysDimItem) {
        var sysDimItemDimsDef = sysDimItem.dimsDef;
        sysDimItemDimsDef && (dimCount = Math.max(dimCount, sysDimItemDimsDef.length));
    });
    return dimCount;
}

function genName(name, map$$1, fromZero) {
    if (fromZero || map$$1.get(name) != null) {
        var i = 0;
        while (map$$1.get(name + i) != null) {
            i++;
        }
        name += i;
    }
    map$$1.set(name, true);
    return name;
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * Substitute `completeDimensions`.
 * `completeDimensions` is to be deprecated.
 */
/**
 * @param {module:echarts/data/Source|module:echarts/data/List} source or data.
 * @param {Object|Array} [opt]
 * @param {Array.<string|Object>} [opt.coordDimensions=[]]
 * @param {number} [opt.dimensionsCount]
 * @param {string} [opt.generateCoord]
 * @param {string} [opt.generateCoordCount]
 * @param {Array.<string|Object>} [opt.dimensionsDefine=source.dimensionsDefine] Overwrite source define.
 * @param {Object|HashMap} [opt.encodeDefine=source.encodeDefine] Overwrite source define.
 * @param {Function} [opt.encodeDefaulter] Make default encode if user not specified.
 * @return {Array.<Object>} dimensionsInfo
 */
var createDimensions = function (source, opt) {
    opt = opt || {};
    return completeDimensions(opt.coordDimensions || [], source, {
        dimsDef: opt.dimensionsDefine || source.dimensionsDefine,
        encodeDef: opt.encodeDefine || source.encodeDefine,
        dimCount: opt.dimensionsCount,
        encodeDefaulter: opt.encodeDefaulter,
        generateCoord: opt.generateCoord,
        generateCoordCount: opt.generateCoordCount
    });
};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * Helper for model references.
 * There are many manners to refer axis/coordSys.
 */

// TODO
// merge relevant logic to this file?
// check: "modelHelper" of tooltip and "BrushTargetManager".

/**
 * @class
 * For example:
 * {
 *     coordSysName: 'cartesian2d',
 *     coordSysDims: ['x', 'y', ...],
 *     axisMap: HashMap({
 *         x: xAxisModel,
 *         y: yAxisModel
 *     }),
 *     categoryAxisMap: HashMap({
 *         x: xAxisModel,
 *         y: undefined
 *     }),
 *     // The index of the first category axis in `coordSysDims`.
 *     // `null/undefined` means no category axis exists.
 *     firstCategoryDimIndex: 1,
 *     // To replace user specified encode.
 * }
 */
function CoordSysInfo(coordSysName) {
    /**
     * @type {string}
     */
    this.coordSysName = coordSysName;
    /**
     * @type {Array.<string>}
     */
    this.coordSysDims = [];
    /**
     * @type {module:zrender/core/util#HashMap}
     */
    this.axisMap = createHashMap();
    /**
     * @type {module:zrender/core/util#HashMap}
     */
    this.categoryAxisMap = createHashMap();
    /**
     * @type {number}
     */
    this.firstCategoryDimIndex = null;
}

/**
 * @return {module:model/referHelper#CoordSysInfo}
 */
function getCoordSysInfoBySeries(seriesModel) {
    var coordSysName = seriesModel.get('coordinateSystem');
    var result = new CoordSysInfo(coordSysName);
    var fetch = fetchers[coordSysName];
    if (fetch) {
        fetch(seriesModel, result, result.axisMap, result.categoryAxisMap);
        return result;
    }
}

var fetchers = {

    cartesian2d: function (seriesModel, result, axisMap, categoryAxisMap) {
        var xAxisModel = seriesModel.getReferringComponents('xAxis')[0];
        var yAxisModel = seriesModel.getReferringComponents('yAxis')[0];

        if (__DEV__) {
            if (!xAxisModel) {
                throw new Error('xAxis "' + retrieve(
                    seriesModel.get('xAxisIndex'),
                    seriesModel.get('xAxisId'),
                    0
                ) + '" not found');
            }
            if (!yAxisModel) {
                throw new Error('yAxis "' + retrieve(
                    seriesModel.get('xAxisIndex'),
                    seriesModel.get('yAxisId'),
                    0
                ) + '" not found');
            }
        }

        result.coordSysDims = ['x', 'y'];
        axisMap.set('x', xAxisModel);
        axisMap.set('y', yAxisModel);

        if (isCategory(xAxisModel)) {
            categoryAxisMap.set('x', xAxisModel);
            result.firstCategoryDimIndex = 0;
        }
        if (isCategory(yAxisModel)) {
            categoryAxisMap.set('y', yAxisModel);
            result.firstCategoryDimIndex == null & (result.firstCategoryDimIndex = 1);
        }
    },

    singleAxis: function (seriesModel, result, axisMap, categoryAxisMap) {
        var singleAxisModel = seriesModel.getReferringComponents('singleAxis')[0];

        if (__DEV__) {
            if (!singleAxisModel) {
                throw new Error('singleAxis should be specified.');
            }
        }

        result.coordSysDims = ['single'];
        axisMap.set('single', singleAxisModel);

        if (isCategory(singleAxisModel)) {
            categoryAxisMap.set('single', singleAxisModel);
            result.firstCategoryDimIndex = 0;
        }
    },

    polar: function (seriesModel, result, axisMap, categoryAxisMap) {
        var polarModel = seriesModel.getReferringComponents('polar')[0];
        var radiusAxisModel = polarModel.findAxisModel('radiusAxis');
        var angleAxisModel = polarModel.findAxisModel('angleAxis');

        if (__DEV__) {
            if (!angleAxisModel) {
                throw new Error('angleAxis option not found');
            }
            if (!radiusAxisModel) {
                throw new Error('radiusAxis option not found');
            }
        }

        result.coordSysDims = ['radius', 'angle'];
        axisMap.set('radius', radiusAxisModel);
        axisMap.set('angle', angleAxisModel);

        if (isCategory(radiusAxisModel)) {
            categoryAxisMap.set('radius', radiusAxisModel);
            result.firstCategoryDimIndex = 0;
        }
        if (isCategory(angleAxisModel)) {
            categoryAxisMap.set('angle', angleAxisModel);
            result.firstCategoryDimIndex == null && (result.firstCategoryDimIndex = 1);
        }
    },

    geo: function (seriesModel, result, axisMap, categoryAxisMap) {
        result.coordSysDims = ['lng', 'lat'];
    },

    parallel: function (seriesModel, result, axisMap, categoryAxisMap) {
        var ecModel = seriesModel.ecModel;
        var parallelModel = ecModel.getComponent(
            'parallel', seriesModel.get('parallelIndex')
        );
        var coordSysDims = result.coordSysDims = parallelModel.dimensions.slice();

        each$1(parallelModel.parallelAxisIndex, function (axisIndex, index) {
            var axisModel = ecModel.getComponent('parallelAxis', axisIndex);
            var axisDim = coordSysDims[index];
            axisMap.set(axisDim, axisModel);

            if (isCategory(axisModel) && result.firstCategoryDimIndex == null) {
                categoryAxisMap.set(axisDim, axisModel);
                result.firstCategoryDimIndex = index;
            }
        });
    }
};

function isCategory(axisModel) {
    return axisModel.get('type') === 'category';
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * Note that it is too complicated to support 3d stack by value
 * (have to create two-dimension inverted index), so in 3d case
 * we just support that stacked by index.
 *
 * @param {module:echarts/model/Series} seriesModel
 * @param {Array.<string|Object>} dimensionInfoList The same as the input of <module:echarts/data/List>.
 *        The input dimensionInfoList will be modified.
 * @param {Object} [opt]
 * @param {boolean} [opt.stackedCoordDimension=''] Specify a coord dimension if needed.
 * @param {boolean} [opt.byIndex=false]
 * @return {Object} calculationInfo
 * {
 *     stackedDimension: string
 *     stackedByDimension: string
 *     isStackedByIndex: boolean
 *     stackedOverDimension: string
 *     stackResultDimension: string
 * }
 */
function enableDataStack(seriesModel, dimensionInfoList, opt) {
    opt = opt || {};
    var byIndex = opt.byIndex;
    var stackedCoordDimension = opt.stackedCoordDimension;

    // Compatibal: when `stack` is set as '', do not stack.
    var mayStack = !!(seriesModel && seriesModel.get('stack'));
    var stackedByDimInfo;
    var stackedDimInfo;
    var stackResultDimension;
    var stackedOverDimension;

    each$1(dimensionInfoList, function (dimensionInfo, index) {
        if (isString(dimensionInfo)) {
            dimensionInfoList[index] = dimensionInfo = {name: dimensionInfo};
        }

        if (mayStack && !dimensionInfo.isExtraCoord) {
            // Find the first ordinal dimension as the stackedByDimInfo.
            if (!byIndex && !stackedByDimInfo && dimensionInfo.ordinalMeta) {
                stackedByDimInfo = dimensionInfo;
            }
            // Find the first stackable dimension as the stackedDimInfo.
            if (!stackedDimInfo
                && dimensionInfo.type !== 'ordinal'
                && dimensionInfo.type !== 'time'
                && (!stackedCoordDimension || stackedCoordDimension === dimensionInfo.coordDim)
            ) {
                stackedDimInfo = dimensionInfo;
            }
        }
    });

    if (stackedDimInfo && !byIndex && !stackedByDimInfo) {
        // Compatible with previous design, value axis (time axis) only stack by index.
        // It may make sense if the user provides elaborately constructed data.
        byIndex = true;
    }

    // Add stack dimension, they can be both calculated by coordinate system in `unionExtent`.
    // That put stack logic in List is for using conveniently in echarts extensions, but it
    // might not be a good way.
    if (stackedDimInfo) {
        // Use a weird name that not duplicated with other names.
        stackResultDimension = '__\0ecstackresult';
        stackedOverDimension = '__\0ecstackedover';

        // Create inverted index to fast query index by value.
        if (stackedByDimInfo) {
            stackedByDimInfo.createInvertedIndices = true;
        }

        var stackedDimCoordDim = stackedDimInfo.coordDim;
        var stackedDimType = stackedDimInfo.type;
        var stackedDimCoordIndex = 0;

        each$1(dimensionInfoList, function (dimensionInfo) {
            if (dimensionInfo.coordDim === stackedDimCoordDim) {
                stackedDimCoordIndex++;
            }
        });

        dimensionInfoList.push({
            name: stackResultDimension,
            coordDim: stackedDimCoordDim,
            coordDimIndex: stackedDimCoordIndex,
            type: stackedDimType,
            isExtraCoord: true,
            isCalculationCoord: true
        });

        stackedDimCoordIndex++;

        dimensionInfoList.push({
            name: stackedOverDimension,
            // This dimension contains stack base (generally, 0), so do not set it as
            // `stackedDimCoordDim` to avoid extent calculation, consider log scale.
            coordDim: stackedOverDimension,
            coordDimIndex: stackedDimCoordIndex,
            type: stackedDimType,
            isExtraCoord: true,
            isCalculationCoord: true
        });
    }

    return {
        stackedDimension: stackedDimInfo && stackedDimInfo.name,
        stackedByDimension: stackedByDimInfo && stackedByDimInfo.name,
        isStackedByIndex: byIndex,
        stackedOverDimension: stackedOverDimension,
        stackResultDimension: stackResultDimension
    };
}

/**
 * @param {module:echarts/data/List} data
 * @param {string} stackedDim
 */
function isDimensionStacked(data, stackedDim /*, stackedByDim*/) {
    // Each single series only maps to one pair of axis. So we do not need to
    // check stackByDim, whatever stacked by a dimension or stacked by index.
    return !!stackedDim && stackedDim === data.getCalculationInfo('stackedDimension');
        // && (
        //     stackedByDim != null
        //         ? stackedByDim === data.getCalculationInfo('stackedByDimension')
        //         : data.getCalculationInfo('isStackedByIndex')
        // );
}

/**
 * @param {module:echarts/data/List} data
 * @param {string} targetDim
 * @param {string} [stackedByDim] If not input this parameter, check whether
 *                                stacked by index.
 * @return {string} dimension
 */
function getStackedDimension(data, targetDim) {
    return isDimensionStacked(data, targetDim)
        ? data.getCalculationInfo('stackResultDimension')
        : targetDim;
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * @param {module:echarts/data/Source|Array} source Or raw data.
 * @param {module:echarts/model/Series} seriesModel
 * @param {Object} [opt]
 * @param {string} [opt.generateCoord]
 * @param {boolean} [opt.useEncodeDefaulter]
 */
function createListFromArray(source, seriesModel, opt) {
    opt = opt || {};

    if (!Source.isInstance(source)) {
        source = Source.seriesDataToSource(source);
    }

    var coordSysName = seriesModel.get('coordinateSystem');
    var registeredCoordSys = CoordinateSystemManager.get(coordSysName);

    var coordSysInfo = getCoordSysInfoBySeries(seriesModel);

    var coordSysDimDefs;

    if (coordSysInfo) {
        coordSysDimDefs = map(coordSysInfo.coordSysDims, function (dim) {
            var dimInfo = {name: dim};
            var axisModel = coordSysInfo.axisMap.get(dim);
            if (axisModel) {
                var axisType = axisModel.get('type');
                dimInfo.type = getDimensionTypeByAxis(axisType);
                // dimInfo.stackable = isStackable(axisType);
            }
            return dimInfo;
        });
    }

    if (!coordSysDimDefs) {
        // Get dimensions from registered coordinate system
        coordSysDimDefs = (registeredCoordSys && (
            registeredCoordSys.getDimensionsInfo
                ? registeredCoordSys.getDimensionsInfo()
                : registeredCoordSys.dimensions.slice()
        )) || ['x', 'y'];
    }

    var dimInfoList = createDimensions(source, {
        coordDimensions: coordSysDimDefs,
        generateCoord: opt.generateCoord,
        encodeDefaulter: opt.useEncodeDefaulter
            ? curry(makeSeriesEncodeForAxisCoordSys, coordSysDimDefs, seriesModel)
            : null
    });

    var firstCategoryDimIndex;
    var hasNameEncode;
    coordSysInfo && each$1(dimInfoList, function (dimInfo, dimIndex) {
        var coordDim = dimInfo.coordDim;
        var categoryAxisModel = coordSysInfo.categoryAxisMap.get(coordDim);
        if (categoryAxisModel) {
            if (firstCategoryDimIndex == null) {
                firstCategoryDimIndex = dimIndex;
            }
            dimInfo.ordinalMeta = categoryAxisModel.getOrdinalMeta();
        }
        if (dimInfo.otherDims.itemName != null) {
            hasNameEncode = true;
        }
    });
    if (!hasNameEncode && firstCategoryDimIndex != null) {
        dimInfoList[firstCategoryDimIndex].otherDims.itemName = 0;
    }

    var stackCalculationInfo = enableDataStack(seriesModel, dimInfoList);

    var list = new List(dimInfoList, seriesModel);

    list.setCalculationInfo(stackCalculationInfo);

    var dimValueGetter = (firstCategoryDimIndex != null && isNeedCompleteOrdinalData(source))
        ? function (itemOpt, dimName, dataIndex, dimIndex) {
            // Use dataIndex as ordinal value in categoryAxis
            return dimIndex === firstCategoryDimIndex
                ? dataIndex
                : this.defaultDimValueGetter(itemOpt, dimName, dataIndex, dimIndex);
        }
        : null;

    list.hasItemOption = false;
    list.initData(source, null, dimValueGetter);

    return list;
}

function isNeedCompleteOrdinalData(source) {
    if (source.sourceFormat === SOURCE_FORMAT_ORIGINAL) {
        var sampleItem = firstDataNotNull(source.data || []);
        return sampleItem != null
            && !isArray(getDataItemValue(sampleItem));
    }
}

function firstDataNotNull(data) {
    var i = 0;
    while (i < data.length && data[i] == null) {
        i++;
    }
    return data[i];
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * // Scale class management
 * @module echarts/scale/Scale
 */

/**
 * @param {Object} [setting]
 */
function Scale(setting) {
    this._setting = setting || {};

    /**
     * Extent
     * @type {Array.<number>}
     * @protected
     */
    this._extent = [Infinity, -Infinity];

    /**
     * Step is calculated in adjustExtent
     * @type {Array.<number>}
     * @protected
     */
    this._interval = 0;

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

/**
 * Parse input val to valid inner number.
 * @param {*} val
 * @return {number}
 */
Scale.prototype.parse = function (val) {
    // Notice: This would be a trap here, If the implementation
    // of this method depends on extent, and this method is used
    // before extent set (like in dataZoom), it would be wrong.
    // Nevertheless, parse does not depend on extent generally.
    return val;
};

Scale.prototype.getSetting = function (name) {
    return this._setting[name];
};

Scale.prototype.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}
 */
Scale.prototype.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}
 */
Scale.prototype.scale = function (val) {
    var extent = this._extent;
    return val * (extent[1] - extent[0]) + extent[0];
};

/**
 * Set extent from data
 * @param {Array.<number>} other
 */
Scale.prototype.unionExtent = function (other) {
    var extent = this._extent;
    other[0] < extent[0] && (extent[0] = other[0]);
    other[1] > extent[1] && (extent[1] = other[1]);
    // not setExtent because in log axis it may transformed to power
    // this.setExtent(extent[0], extent[1]);
};

/**
 * Set extent from data
 * @param {module:echarts/data/List} data
 * @param {string} dim
 */
Scale.prototype.unionExtentFromData = function (data, dim) {
    this.unionExtent(data.getApproximateExtent(dim));
};

/**
 * Get extent
 * @return {Array.<number>}
 */
Scale.prototype.getExtent = function () {
    return this._extent.slice();
};

/**
 * Set extent
 * @param {number} start
 * @param {number} end
 */
Scale.prototype.setExtent = function (start, end) {
    var thisExtent = this._extent;
    if (!isNaN(start)) {
        thisExtent[0] = start;
    }
    if (!isNaN(end)) {
        thisExtent[1] = end;
    }
};

/**
 * When axis extent depends on data and no data exists,
 * axis ticks should not be drawn, which is named 'blank'.
 */
Scale.prototype.isBlank = function () {
    return this._isBlank;
},

/**
 * When axis extent depends on data and no data exists,
 * axis ticks should not be drawn, which is named 'blank'.
 */
Scale.prototype.setBlank = function (isBlank) {
    this._isBlank = isBlank;
};

/**
 * @abstract
 * @param {*} tick
 * @return {string} label of the tick.
 */
Scale.prototype.getLabel = null;


enableClassExtend(Scale);
enableClassManagement(Scale, {
    registerWhenExtend: true
});

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * @constructor
 * @param {Object} [opt]
 * @param {Object} [opt.categories=[]]
 * @param {Object} [opt.needCollect=false]
 * @param {Object} [opt.deduplication=false]
 */
function OrdinalMeta(opt) {

    /**
     * @readOnly
     * @type {Array.<string>}
     */
    this.categories = opt.categories || [];

    /**
     * @private
     * @type {boolean}
     */
    this._needCollect = opt.needCollect;

    /**
     * @private
     * @type {boolean}
     */
    this._deduplication = opt.deduplication;

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

/**
 * @param {module:echarts/model/Model} axisModel
 * @return {module:echarts/data/OrdinalMeta}
 */
OrdinalMeta.createByAxisModel = function (axisModel) {
    var option = axisModel.option;
    var data = option.data;
    var categories = data && map(data, getName);

    return new OrdinalMeta({
        categories: categories,
        needCollect: !categories,
        // deduplication is default in axis.
        deduplication: option.dedplication !== false
    });
};

var proto$1 = OrdinalMeta.prototype;

/**
 * @param {string} category
 * @return {number} ordinal
 */
proto$1.getOrdinal = function (category) {
    return getOrCreateMap(this).get(category);
};

/**
 * @param {*} category
 * @return {number} The ordinal. If not found, return NaN.
 */
proto$1.parseAndCollect = function (category) {
    var index;
    var needCollect = this._needCollect;

    // The value of category dim can be the index of the given category set.
    // This feature is only supported when !needCollect, because we should
    // consider a common case: a value is 2017, which is a number but is
    // expected to be tread as a category. This case usually happen in dataset,
    // where it happent to be no need of the index feature.
    if (typeof category !== 'string' && !needCollect) {
        return category;
    }

    // Optimize for the scenario:
    // category is ['2012-01-01', '2012-01-02', ...], where the input
    // data has been ensured not duplicate and is large data.
    // Notice, if a dataset dimension provide categroies, usually echarts
    // should remove duplication except user tell echarts dont do that
    // (set axis.deduplication = false), because echarts do not know whether
    // the values in the category dimension has duplication (consider the
    // parallel-aqi example)
    if (needCollect && !this._deduplication) {
        index = this.categories.length;
        this.categories[index] = category;
        return index;
    }

    var map$$1 = getOrCreateMap(this);
    index = map$$1.get(category);

    if (index == null) {
        if (needCollect) {
            index = this.categories.length;
            this.categories[index] = category;
            map$$1.set(category, index);
        }
        else {
            index = NaN;
        }
    }

    return index;
};

// Consider big data, do not create map until needed.
function getOrCreateMap(ordinalMeta) {
    return ordinalMeta._map || (
        ordinalMeta._map = createHashMap(ordinalMeta.categories)
    );
}

function getName(obj) {
    if (isObject$1(obj) && obj.value != null) {
        return obj.value;
    }
    else {
        return obj + '';
    }
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * Linear continuous scale
 * @module echarts/coord/scale/Ordinal
 *
 * http://en.wikipedia.org/wiki/Level_of_measurement
 */

// FIXME only one data

var scaleProto = Scale.prototype;

var OrdinalScale = Scale.extend({

    type: 'ordinal',

    /**
     * @param {module:echarts/data/OrdianlMeta|Array.<string>} ordinalMeta
     */
    init: function (ordinalMeta, extent) {
        // Caution: Should not use instanceof, consider ec-extensions using
        // import approach to get OrdinalMeta class.
        if (!ordinalMeta || isArray(ordinalMeta)) {
            ordinalMeta = new OrdinalMeta({categories: ordinalMeta});
        }
        this._ordinalMeta = ordinalMeta;
        this._extent = extent || [0, ordinalMeta.categories.length - 1];
    },

    parse: function (val) {
        return typeof val === 'string'
            ? this._ordinalMeta.getOrdinal(val)
            // val might be float.
            : Math.round(val);
    },

    contain: function (rank) {
        rank = this.parse(rank);
        return scaleProto.contain.call(this, rank)
            && this._ordinalMeta.categories[rank] != null;
    },

    /**
     * Normalize given rank or name to linear [0, 1]
     * @param {number|string} [val]
     * @return {number}
     */
    normalize: function (val) {
        return scaleProto.normalize.call(this, this.parse(val));
    },

    scale: function (val) {
        return Math.round(scaleProto.scale.call(this, val));
    },

    /**
     * @return {Array}
     */
    getTicks: function () {
        var ticks = [];
        var extent = this._extent;
        var rank = extent[0];

        while (rank <= extent[1]) {
            ticks.push(rank);
            rank++;
        }

        return ticks;
    },

    /**
     * Get item on rank n
     * @param {number} n
     * @return {string}
     */
    getLabel: function (n) {
        if (!this.isBlank()) {
            // Note that if no data, ordinalMeta.categories is an empty array.
            return this._ordinalMeta.categories[n];
        }
    },

    /**
     * @return {number}
     */
    count: function () {
        return this._extent[1] - this._extent[0] + 1;
    },

    /**
     * @override
     */
    unionExtentFromData: function (data, dim) {
        this.unionExtent(data.getApproximateExtent(dim));
    },

    getOrdinalMeta: function () {
        return this._ordinalMeta;
    },

    niceTicks: noop,
    niceExtent: noop
});

/**
 * @return {module:echarts/scale/Time}
 */
OrdinalScale.create = function () {
    return new OrdinalScale();
};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * For testable.
 */

var roundNumber$1 = round$1;

/**
 * @param {Array.<number>} extent Both extent[0] and extent[1] should be valid number.
 *                                Should be extent[0] < extent[1].
 * @param {number} splitNumber splitNumber should be >= 1.
 * @param {number} [minInterval]
 * @param {number} [maxInterval]
 * @return {Object} {interval, intervalPrecision, niceTickExtent}
 */
function intervalScaleNiceTicks(extent, splitNumber, minInterval, maxInterval) {
    var result = {};
    var span = extent[1] - extent[0];

    var interval = result.interval = nice(span / splitNumber, true);
    if (minInterval != null && interval < minInterval) {
        interval = result.interval = minInterval;
    }
    if (maxInterval != null && interval > maxInterval) {
        interval = result.interval = maxInterval;
    }
    // Tow more digital for tick.
    var precision = result.intervalPrecision = getIntervalPrecision(interval);
    // Niced extent inside original extent
    var niceTickExtent = result.niceTickExtent = [
        roundNumber$1(Math.ceil(extent[0] / interval) * interval, precision),
        roundNumber$1(Math.floor(extent[1] / interval) * interval, precision)
    ];

    fixExtent(niceTickExtent, extent);

    return result;
}

/**
 * @param {number} interval
 * @return {number} interval precision
 */
function getIntervalPrecision(interval) {
    // Tow more digital for tick.
    return getPrecisionSafe(interval) + 2;
}

function clamp(niceTickExtent, idx, extent) {
    niceTickExtent[idx] = Math.max(Math.min(niceTickExtent[idx], extent[1]), extent[0]);
}

// In some cases (e.g., splitNumber is 1), niceTickExtent may be out of extent.
function fixExtent(niceTickExtent, extent) {
    !isFinite(niceTickExtent[0]) && (niceTickExtent[0] = extent[0]);
    !isFinite(niceTickExtent[1]) && (niceTickExtent[1] = extent[1]);
    clamp(niceTickExtent, 0, extent);
    clamp(niceTickExtent, 1, extent);
    if (niceTickExtent[0] > niceTickExtent[1]) {
        niceTickExtent[0] = niceTickExtent[1];
    }
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * Interval scale
 * @module echarts/scale/Interval
 */


var roundNumber = round$1;

/**
 * @alias module:echarts/coord/scale/Interval
 * @constructor
 */
var IntervalScale = Scale.extend({

    type: 'interval',

    _interval: 0,

    _intervalPrecision: 2,

    setExtent: function (start, end) {
        var thisExtent = this._extent;
        //start,end may be a Number like '25',so...
        if (!isNaN(start)) {
            thisExtent[0] = parseFloat(start);
        }
        if (!isNaN(end)) {
            thisExtent[1] = parseFloat(end);
        }
    },

    unionExtent: function (other) {
        var extent = this._extent;
        other[0] < extent[0] && (extent[0] = other[0]);
        other[1] > extent[1] && (extent[1] = other[1]);

        // unionExtent may called by it's sub classes
        IntervalScale.prototype.setExtent.call(this, extent[0], extent[1]);
    },
    /**
     * Get interval
     */
    getInterval: function () {
        return this._interval;
    },

    /**
     * Set interval
     */
    setInterval: function (interval) {
        this._interval = interval;
        // Dropped auto calculated niceExtent and use user setted extent
        // We assume user wan't to set both interval, min, max to get a better result
        this._niceExtent = this._extent.slice();

        this._intervalPrecision = getIntervalPrecision(interval);
    },

    /**
     * @param {boolean} [expandToNicedExtent=false] If expand the ticks to niced extent.
     * @return {Array.<number>}
     */
    getTicks: function (expandToNicedExtent) {
        var interval = this._interval;
        var extent = this._extent;
        var niceTickExtent = this._niceExtent;
        var intervalPrecision = this._intervalPrecision;

        var ticks = [];
        // If interval is 0, return [];
        if (!interval) {
            return ticks;
        }

        // Consider this case: using dataZoom toolbox, zoom and zoom.
        var safeLimit = 10000;

        if (extent[0] < niceTickExtent[0]) {
            if (expandToNicedExtent) {
                ticks.push(roundNumber(niceTickExtent[0] - interval, intervalPrecision));
            }
            else {
                ticks.push(extent[0]);
            }
        }
        var tick = niceTickExtent[0];

        while (tick <= niceTickExtent[1]) {
            ticks.push(tick);
            // Avoid rounding error
            tick = roundNumber(tick + interval, intervalPrecision);
            if (tick === ticks[ticks.length - 1]) {
                // Consider out of safe float point, e.g.,
                // -3711126.9907707 + 2e-10 === -3711126.9907707
                break;
            }
            if (ticks.length > safeLimit) {
                return [];
            }
        }
        // Consider this case: the last item of ticks is smaller
        // than niceTickExtent[1] and niceTickExtent[1] === extent[1].
        var lastNiceTick = ticks.length ? ticks[ticks.length - 1] : niceTickExtent[1];
        if (extent[1] > lastNiceTick) {
            if (expandToNicedExtent) {
                ticks.push(roundNumber(lastNiceTick + interval, intervalPrecision));
            }
            else {
                ticks.push(extent[1]);
            }
        }

        return ticks;
    },

    /**
     * @param {number} [splitNumber=5]
     * @return {Array.<Array.<number>>}
     */
    getMinorTicks: function (splitNumber) {
        var ticks = this.getTicks(true);
        var minorTicks = [];
        var extent = this.getExtent();

        for (var i = 1; i < ticks.length; i++) {
            var nextTick = ticks[i];
            var prevTick = ticks[i - 1];
            var count = 0;
            var minorTicksGroup = [];
            var interval = nextTick - prevTick;
            var minorInterval = interval / splitNumber;

            while (count < splitNumber - 1) {
                var minorTick = round$1(prevTick + (count + 1) * minorInterval);

                // For the first and last interval. The count may be less than splitNumber.
                if (minorTick > extent[0] && minorTick < extent[1]) {
                    minorTicksGroup.push(minorTick);
                }
                count++;
            }
            minorTicks.push(minorTicksGroup);
        }

        return minorTicks;
    },

    /**
     * @param {number} data
     * @param {Object} [opt]
     * @param {number|string} [opt.precision] If 'auto', use nice presision.
     * @param {boolean} [opt.pad] returns 1.50 but not 1.5 if precision is 2.
     * @return {string}
     */
    getLabel: function (data, opt) {
        if (data == null) {
            return '';
        }

        var precision = opt && opt.precision;

        if (precision == null) {
            precision = getPrecisionSafe(data) || 0;
        }
        else if (precision === 'auto') {
            // Should be more precise then tick.
            precision = this._intervalPrecision;
        }

        // (1) If `precision` is set, 12.005 should be display as '12.00500'.
        // (2) Use roundNumber (toFixed) to avoid scientific notation like '3.5e-7'.
        data = roundNumber(data, precision, true);

        return addCommas(data);
    },

    /**
     * Update interval and extent of intervals for nice ticks
     *
     * @param {number} [splitNumber = 5] Desired number of ticks
     * @param {number} [minInterval]
     * @param {number} [maxInterval]
     */
    niceTicks: function (splitNumber, minInterval, maxInterval) {
        splitNumber = splitNumber || 5;
        var extent = this._extent;
        var span = extent[1] - extent[0];
        if (!isFinite(span)) {
            return;
        }
        // User may set axis min 0 and data are all negative
        // FIXME If it needs to reverse ?
        if (span < 0) {
            span = -span;
            extent.reverse();
        }

        var result = intervalScaleNiceTicks(
            extent, splitNumber, minInterval, maxInterval
        );

        this._intervalPrecision = result.intervalPrecision;
        this._interval = result.interval;
        this._niceExtent = result.niceTickExtent;
    },

    /**
     * Nice extent.
     * @param {Object} opt
     * @param {number} [opt.splitNumber = 5] Given approx tick number
     * @param {boolean} [opt.fixMin=false]
     * @param {boolean} [opt.fixMax=false]
     * @param {boolean} [opt.minInterval]
     * @param {boolean} [opt.maxInterval]
     */
    niceExtent: function (opt) {
        var extent = this._extent;
        // If extent start and end are same, expand them
        if (extent[0] === extent[1]) {
            if (extent[0] !== 0) {
                // Expand extent
                var expandSize = extent[0];
                // In the fowllowing case
                //      Axis has been fixed max 100
                //      Plus data are all 100 and axis extent are [100, 100].
                // Extend to the both side will cause expanded max is larger than fixed max.
                // So only expand to the smaller side.
                if (!opt.fixMax) {
                    extent[1] += expandSize / 2;
                    extent[0] -= expandSize / 2;
                }
                else {
                    extent[0] -= expandSize / 2;
                }
            }
            else {
                extent[1] = 1;
            }
        }
        var span = extent[1] - extent[0];
        // If there are no data and extent are [Infinity, -Infinity]
        if (!isFinite(span)) {
            extent[0] = 0;
            extent[1] = 1;
        }

        this.niceTicks(opt.splitNumber, opt.minInterval, opt.maxInterval);

        // var extent = this._extent;
        var interval = this._interval;

        if (!opt.fixMin) {
            extent[0] = roundNumber(Math.floor(extent[0] / interval) * interval);
        }
        if (!opt.fixMax) {
            extent[1] = roundNumber(Math.ceil(extent[1] / interval) * interval);
        }
    }
});

/**
 * @return {module:echarts/scale/Time}
 */
IntervalScale.create = function () {
    return new IntervalScale();
};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/* global Float32Array */

var STACK_PREFIX = '__ec_stack_';
var LARGE_BAR_MIN_WIDTH = 0.5;

var LargeArr = typeof Float32Array !== 'undefined' ? Float32Array : Array;

function getSeriesStackId(seriesModel) {
    return seriesModel.get('stack') || STACK_PREFIX + seriesModel.seriesIndex;
}

function getAxisKey(axis) {
    return axis.dim + axis.index;
}

/**
 * @param {Object} opt
 * @param {module:echarts/coord/Axis} opt.axis Only support category axis currently.
 * @param {number} opt.count Positive interger.
 * @param {number} [opt.barWidth]
 * @param {number} [opt.barMaxWidth]
 * @param {number} [opt.barMinWidth]
 * @param {number} [opt.barGap]
 * @param {number} [opt.barCategoryGap]
 * @return {Object} {width, offset, offsetCenter} If axis.type is not 'category', return undefined.
 */


function prepareLayoutBarSeries(seriesType, ecModel) {
    var seriesModels = [];
    ecModel.eachSeriesByType(seriesType, function (seriesModel) {
        // Check series coordinate, do layout for cartesian2d only
        if (isOnCartesian(seriesModel) && !isInLargeMode(seriesModel)) {
            seriesModels.push(seriesModel);
        }
    });
    return seriesModels;
}


/**
 * Map from (baseAxis.dim + '_' + baseAxis.index) to min gap of two adjacent
 * values.
 * This works for time axes, value axes, and log axes.
 * For a single time axis, return value is in the form like
 * {'x_0': [1000000]}.
 * The value of 1000000 is in milliseconds.
 */
function getValueAxesMinGaps(barSeries) {
    /**
     * Map from axis.index to values.
     * For a single time axis, axisValues is in the form like
     * {'x_0': [1495555200000, 1495641600000, 1495728000000]}.
     * Items in axisValues[x], e.g. 1495555200000, are time values of all
     * series.
     */
    var axisValues = {};
    each$1(barSeries, function (seriesModel) {
        var cartesian = seriesModel.coordinateSystem;
        var baseAxis = cartesian.getBaseAxis();
        if (baseAxis.type !== 'time' && baseAxis.type !== 'value') {
            return;
        }

        var data = seriesModel.getData();
        var key = baseAxis.dim + '_' + baseAxis.index;
        var dim = data.mapDimension(baseAxis.dim);
        for (var i = 0, cnt = data.count(); i < cnt; ++i) {
            var value = data.get(dim, i);
            if (!axisValues[key]) {
                // No previous data for the axis
                axisValues[key] = [value];
            }
            else {
                // No value in previous series
                axisValues[key].push(value);
            }
            // Ignore duplicated time values in the same axis
        }
    });

    var axisMinGaps = [];
    for (var key in axisValues) {
        if (axisValues.hasOwnProperty(key)) {
            var valuesInAxis = axisValues[key];
            if (valuesInAxis) {
                // Sort axis values into ascending order to calculate gaps
                valuesInAxis.sort(function (a, b) {
                    return a - b;
                });

                var min = null;
                for (var j = 1; j < valuesInAxis.length; ++j) {
                    var delta = valuesInAxis[j] - valuesInAxis[j - 1];
                    if (delta > 0) {
                        // Ignore 0 delta because they are of the same axis value
                        min = min === null ? delta : Math.min(min, delta);
                    }
                }
                // Set to null if only have one data
                axisMinGaps[key] = min;
            }
        }
    }
    return axisMinGaps;
}

function makeColumnLayout(barSeries) {
    var axisMinGaps = getValueAxesMinGaps(barSeries);

    var seriesInfoList = [];
    each$1(barSeries, function (seriesModel) {
        var cartesian = seriesModel.coordinateSystem;
        var baseAxis = cartesian.getBaseAxis();
        var axisExtent = baseAxis.getExtent();

        var bandWidth;
        if (baseAxis.type === 'category') {
            bandWidth = baseAxis.getBandWidth();
        }
        else if (baseAxis.type === 'value' || baseAxis.type === 'time') {
            var key = baseAxis.dim + '_' + baseAxis.index;
            var minGap = axisMinGaps[key];
            var extentSpan = Math.abs(axisExtent[1] - axisExtent[0]);
            var scale = baseAxis.scale.getExtent();
            var scaleSpan = Math.abs(scale[1] - scale[0]);
            bandWidth = minGap
                ? extentSpan / scaleSpan * minGap
                : extentSpan; // When there is only one data value
        }
        else {
            var data = seriesModel.getData();
            bandWidth = Math.abs(axisExtent[1] - axisExtent[0]) / data.count();
        }

        var barWidth = parsePercent$1(
            seriesModel.get('barWidth'), bandWidth
        );
        var barMaxWidth = parsePercent$1(
            seriesModel.get('barMaxWidth'), bandWidth
        );
        var barMinWidth = parsePercent$1(
            // barMinWidth by default is 1 in cartesian. Because in value axis,
            // the auto-calculated bar width might be less than 1.
            seriesModel.get('barMinWidth') || 1, bandWidth
        );
        var barGap = seriesModel.get('barGap');
        var barCategoryGap = seriesModel.get('barCategoryGap');

        seriesInfoList.push({
            bandWidth: bandWidth,
            barWidth: barWidth,
            barMaxWidth: barMaxWidth,
            barMinWidth: barMinWidth,
            barGap: barGap,
            barCategoryGap: barCategoryGap,
            axisKey: getAxisKey(baseAxis),
            stackId: getSeriesStackId(seriesModel)
        });
    });

    return doCalBarWidthAndOffset(seriesInfoList);
}

function doCalBarWidthAndOffset(seriesInfoList) {
    // Columns info on each category axis. Key is cartesian name
    var columnsMap = {};

    each$1(seriesInfoList, function (seriesInfo, idx) {
        var axisKey = seriesInfo.axisKey;
        var bandWidth = seriesInfo.bandWidth;
        var columnsOnAxis = columnsMap[axisKey] || {
            bandWidth: bandWidth,
            remainedWidth: bandWidth,
            autoWidthCount: 0,
            categoryGap: '20%',
            gap: '30%',
            stacks: {}
        };
        var stacks = columnsOnAxis.stacks;
        columnsMap[axisKey] = columnsOnAxis;

        var stackId = seriesInfo.stackId;

        if (!stacks[stackId]) {
            columnsOnAxis.autoWidthCount++;
        }
        stacks[stackId] = stacks[stackId] || {
            width: 0,
            maxWidth: 0
        };

        // Caution: In a single coordinate system, these barGrid attributes
        // will be shared by series. Consider that they have default values,
        // only the attributes set on the last series will work.
        // Do not change this fact unless there will be a break change.

        var barWidth = seriesInfo.barWidth;
        if (barWidth && !stacks[stackId].width) {
            // See #6312, do not restrict width.
            stacks[stackId].width = barWidth;
            barWidth = Math.min(columnsOnAxis.remainedWidth, barWidth);
            columnsOnAxis.remainedWidth -= barWidth;
        }

        var barMaxWidth = seriesInfo.barMaxWidth;
        barMaxWidth && (stacks[stackId].maxWidth = barMaxWidth);
        var barMinWidth = seriesInfo.barMinWidth;
        barMinWidth && (stacks[stackId].minWidth = barMinWidth);
        var barGap = seriesInfo.barGap;
        (barGap != null) && (columnsOnAxis.gap = barGap);
        var barCategoryGap = seriesInfo.barCategoryGap;
        (barCategoryGap != null) && (columnsOnAxis.categoryGap = barCategoryGap);
    });

    var result = {};

    each$1(columnsMap, function (columnsOnAxis, coordSysName) {

        result[coordSysName] = {};

        var stacks = columnsOnAxis.stacks;
        var bandWidth = columnsOnAxis.bandWidth;
        var categoryGap = parsePercent$1(columnsOnAxis.categoryGap, bandWidth);
        var barGapPercent = parsePercent$1(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
        each$1(stacks, function (column) {
            var maxWidth = column.maxWidth;
            var minWidth = column.minWidth;

            if (!column.width) {
                var finalWidth = autoWidth;
                if (maxWidth && maxWidth < finalWidth) {
                    finalWidth = Math.min(maxWidth, remainedWidth);
                }
                // `minWidth` has higher priority. `minWidth` decide that wheter the
                // bar is able to be visible. So `minWidth` should not be restricted
                // by `maxWidth` or `remainedWidth` (which is from `bandWidth`). In
                // the extreme cases for `value` axis, bars are allowed to overlap
                // with each other if `minWidth` specified.
                if (minWidth && minWidth > finalWidth) {
                    finalWidth = minWidth;
                }
                if (finalWidth !== autoWidth) {
                    column.width = finalWidth;
                    remainedWidth -= finalWidth + barGapPercent * finalWidth;
                    autoWidthCount--;
                }
            }
            else {
                // `barMinWidth/barMaxWidth` has higher priority than `barWidth`, as
                // CSS does. Becuase barWidth can be a percent value, where
                // `barMaxWidth` can be used to restrict the final width.
                var finalWidth = column.width;
                if (maxWidth) {
                    finalWidth = Math.min(finalWidth, maxWidth);
                }
                // `minWidth` has higher priority, as described above
                if (minWidth) {
                    finalWidth = Math.max(finalWidth, minWidth);
                }
                column.width = finalWidth;
                remainedWidth -= finalWidth + barGapPercent * finalWidth;
                autoWidthCount--;
            }
        });

        // Recalculate width again
        autoWidth = (remainedWidth - categoryGap)
            / (autoWidthCount + (autoWidthCount - 1) * barGapPercent);

        autoWidth = Math.max(autoWidth, 0);


        var widthSum = 0;
        var lastColumn;
        each$1(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;
        each$1(stacks, function (column, stackId) {
            result[coordSysName][stackId] = result[coordSysName][stackId] || {
                bandWidth: bandWidth,
                offset: offset,
                width: column.width
            };

            offset += column.width * (1 + barGapPercent);
        });
    });

    return result;
}

/**
 * @param {Object} barWidthAndOffset The result of makeColumnLayout
 * @param {module:echarts/coord/Axis} axis
 * @param {module:echarts/model/Series} [seriesModel] If not provided, return all.
 * @return {Object} {stackId: {offset, width}} or {offset, width} if seriesModel provided.
 */
function retrieveColumnLayout(barWidthAndOffset, axis, seriesModel) {
    if (barWidthAndOffset && axis) {
        var result = barWidthAndOffset[getAxisKey(axis)];
        if (result != null && seriesModel != null) {
            result = result[getSeriesStackId(seriesModel)];
        }
        return result;
    }
}

/**
 * @param {string} seriesType
 * @param {module:echarts/model/Global} ecModel
 */
function layout(seriesType, ecModel) {

    var seriesModels = prepareLayoutBarSeries(seriesType, ecModel);
    var barWidthAndOffset = makeColumnLayout(seriesModels);

    var lastStackCoords = {};
    each$1(seriesModels, function (seriesModel) {

        var data = seriesModel.getData();
        var cartesian = seriesModel.coordinateSystem;
        var baseAxis = cartesian.getBaseAxis();

        var stackId = getSeriesStackId(seriesModel);
        var columnLayoutInfo = barWidthAndOffset[getAxisKey(baseAxis)][stackId];
        var columnOffset = columnLayoutInfo.offset;
        var columnWidth = columnLayoutInfo.width;
        var valueAxis = cartesian.getOtherAxis(baseAxis);

        var barMinHeight = seriesModel.get('barMinHeight') || 0;

        lastStackCoords[stackId] = lastStackCoords[stackId] || [];
        data.setLayout({
            bandWidth: columnLayoutInfo.bandWidth,
            offset: columnOffset,
            size: columnWidth
        });

        var valueDim = data.mapDimension(valueAxis.dim);
        var baseDim = data.mapDimension(baseAxis.dim);
        var stacked = isDimensionStacked(data, valueDim /*, baseDim*/);
        var isValueAxisH = valueAxis.isHorizontal();

        var valueAxisStart = getValueAxisStart(baseAxis, valueAxis, stacked);

        for (var idx = 0, len = data.count(); idx < len; idx++) {
            var value = data.get(valueDim, idx);
            var baseValue = data.get(baseDim, idx);

            var sign = value >= 0 ? 'p' : 'n';
            var baseCoord = valueAxisStart;

            // Because of the barMinHeight, we can not use the value in
            // stackResultDimension directly.
            if (stacked) {
                // Only ordinal axis can be stacked.
                if (!lastStackCoords[stackId][baseValue]) {
                    lastStackCoords[stackId][baseValue] = {
                        p: valueAxisStart, // Positive stack
                        n: valueAxisStart  // Negative stack
                    };
                }
                // Should also consider #4243
                baseCoord = lastStackCoords[stackId][baseValue][sign];
            }

            var x;
            var y;
            var width;
            var height;

            if (isValueAxisH) {
                var coord = cartesian.dataToPoint([value, baseValue]);
                x = baseCoord;
                y = coord[1] + columnOffset;
                width = coord[0] - valueAxisStart;
                height = columnWidth;

                if (Math.abs(width) < barMinHeight) {
                    width = (width < 0 ? -1 : 1) * barMinHeight;
                }
                // Ignore stack from NaN value
                if (!isNaN(width)) {
                    stacked && (lastStackCoords[stackId][baseValue][sign] += width);
                }
            }
            else {
                var coord = cartesian.dataToPoint([baseValue, value]);
                x = coord[0] + columnOffset;
                y = baseCoord;
                width = columnWidth;
                height = coord[1] - valueAxisStart;

                if (Math.abs(height) < barMinHeight) {
                    // Include zero to has a positive bar
                    height = (height <= 0 ? -1 : 1) * barMinHeight;
                }
                // Ignore stack from NaN value
                if (!isNaN(height)) {
                    stacked && (lastStackCoords[stackId][baseValue][sign] += height);
                }
            }

            data.setItemLayout(idx, {
                x: x,
                y: y,
                width: width,
                height: height
            });
        }

    }, this);
}

// TODO: Do not support stack in large mode yet.
var largeLayout = {

    seriesType: 'bar',

    plan: createRenderPlanner(),

    reset: function (seriesModel) {
        if (!isOnCartesian(seriesModel) || !isInLargeMode(seriesModel)) {
            return;
        }

        var data = seriesModel.getData();
        var cartesian = seriesModel.coordinateSystem;
        var coordLayout = cartesian.grid.getRect();
        var baseAxis = cartesian.getBaseAxis();
        var valueAxis = cartesian.getOtherAxis(baseAxis);
        var valueDim = data.mapDimension(valueAxis.dim);
        var baseDim = data.mapDimension(baseAxis.dim);
        var valueAxisHorizontal = valueAxis.isHorizontal();
        var valueDimIdx = valueAxisHorizontal ? 0 : 1;

        var barWidth = retrieveColumnLayout(
            makeColumnLayout([seriesModel]), baseAxis, seriesModel
        ).width;
        if (!(barWidth > LARGE_BAR_MIN_WIDTH)) { // jshint ignore:line
            barWidth = LARGE_BAR_MIN_WIDTH;
        }

        return {progress: progress};

        function progress(params, data) {
            var count = params.count;
            var largePoints = new LargeArr(count * 2);
            var largeBackgroundPoints = new LargeArr(count * 2);
            var largeDataIndices = new LargeArr(count);
            var dataIndex;
            var coord = [];
            var valuePair = [];
            var pointsOffset = 0;
            var idxOffset = 0;

            while ((dataIndex = params.next()) != null) {
                valuePair[valueDimIdx] = data.get(valueDim, dataIndex);
                valuePair[1 - valueDimIdx] = data.get(baseDim, dataIndex);

                coord = cartesian.dataToPoint(valuePair, null, coord);
                // Data index might not be in order, depends on `progressiveChunkMode`.
                largeBackgroundPoints[pointsOffset] = valueAxisHorizontal
                    ? coordLayout.x + coordLayout.width : coord[0];
                largePoints[pointsOffset++] = coord[0];
                largeBackgroundPoints[pointsOffset] = valueAxisHorizontal
                    ? coord[1] : coordLayout.y + coordLayout.height;
                largePoints[pointsOffset++] = coord[1];
                largeDataIndices[idxOffset++] = dataIndex;
            }

            data.setLayout({
                largePoints: largePoints,
                largeDataIndices: largeDataIndices,
                largeBackgroundPoints: largeBackgroundPoints,
                barWidth: barWidth,
                valueAxisStart: getValueAxisStart(baseAxis, valueAxis, false),
                backgroundStart: valueAxisHorizontal ? coordLayout.x : coordLayout.y,
                valueAxisHorizontal: valueAxisHorizontal
            });
        }
    }
};

function isOnCartesian(seriesModel) {
    return seriesModel.coordinateSystem && seriesModel.coordinateSystem.type === 'cartesian2d';
}

function isInLargeMode(seriesModel) {
    return seriesModel.pipelineContext && seriesModel.pipelineContext.large;
}

// See cases in `test/bar-start.html` and `#7412`, `#8747`.
function getValueAxisStart(baseAxis, valueAxis, stacked) {
    return valueAxis.toGlobalCoord(valueAxis.dataToCoord(valueAxis.type === 'log' ? 1 : 0));
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/*
* A third-party license is embeded for some of the code in this file:
* The "scaleLevels" was originally copied from "d3.js" with some
* modifications made for this project.
* (See more details in the comment on the definition of "scaleLevels" below.)
* The use of the source code of this file is also subject to the terms
* and consitions of the license of "d3.js" (BSD-3Clause, see
* </licenses/LICENSE-d3>).
*/


// [About UTC and local time zone]:
// In most cases, `number.parseDate` will treat input data string as local time
// (except time zone is specified in time string). And `format.formateTime` returns
// local time by default. option.useUTC is false by default. This design have
// concidered these common case:
// (1) Time that is persistent in server is in UTC, but it is needed to be diplayed
// in local time by default.
// (2) By default, the input data string (e.g., '2011-01-02') should be displayed
// as its original time, without any time difference.

var intervalScaleProto = IntervalScale.prototype;

var mathCeil = Math.ceil;
var mathFloor = Math.floor;
var ONE_SECOND = 1000;
var ONE_MINUTE = ONE_SECOND * 60;
var ONE_HOUR = ONE_MINUTE * 60;
var ONE_DAY = ONE_HOUR * 24;

// FIXME 公用？
var bisect = function (a, x, lo, hi) {
    while (lo < hi) {
        var mid = lo + hi >>> 1;
        if (a[mid][1] < x) {
            lo = mid + 1;
        }
        else {
            hi = mid;
        }
    }
    return lo;
};

/**
 * @alias module:echarts/coord/scale/Time
 * @constructor
 */
var TimeScale = IntervalScale.extend({
    type: 'time',

    /**
     * @override
     */
    getLabel: function (val) {
        var stepLvl = this._stepLvl;

        var date = new Date(val);

        return formatTime(stepLvl[0], date, this.getSetting('useUTC'));
    },

    /**
     * @override
     */
    niceExtent: function (opt) {
        var extent = this._extent;
        // If extent start and end are same, expand them
        if (extent[0] === extent[1]) {
            // Expand extent
            extent[0] -= ONE_DAY;
            extent[1] += ONE_DAY;
        }
        // If there are no data and extent are [Infinity, -Infinity]
        if (extent[1] === -Infinity && extent[0] === Infinity) {
            var d = new Date();
            extent[1] = +new Date(d.getFullYear(), d.getMonth(), d.getDate());
            extent[0] = extent[1] - ONE_DAY;
        }

        this.niceTicks(opt.splitNumber, opt.minInterval, opt.maxInterval);

        // var extent = this._extent;
        var interval = this._interval;

        if (!opt.fixMin) {
            extent[0] = round$1(mathFloor(extent[0] / interval) * interval);
        }
        if (!opt.fixMax) {
            extent[1] = round$1(mathCeil(extent[1] / interval) * interval);
        }
    },

    /**
     * @override
     */
    niceTicks: function (approxTickNum, minInterval, maxInterval) {
        approxTickNum = approxTickNum || 10;

        var extent = this._extent;
        var span = extent[1] - extent[0];
        var approxInterval = span / approxTickNum;

        if (minInterval != null && approxInterval < minInterval) {
            approxInterval = minInterval;
        }
        if (maxInterval != null && approxInterval > maxInterval) {
            approxInterval = maxInterval;
        }

        var scaleLevelsLen = scaleLevels.length;
        var idx = bisect(scaleLevels, approxInterval, 0, scaleLevelsLen);

        var level = scaleLevels[Math.min(idx, scaleLevelsLen - 1)];
        var interval = level[1];
        // Same with interval scale if span is much larger than 1 year
        if (level[0] === 'year') {
            var yearSpan = span / interval;

            // From "Nice Numbers for Graph Labels" of Graphic Gems
            // var niceYearSpan = numberUtil.nice(yearSpan, false);
            var yearStep = nice(yearSpan / approxTickNum, true);

            interval *= yearStep;
        }

        var timezoneOffset = this.getSetting('useUTC')
            ? 0 : (new Date(+extent[0] || +extent[1])).getTimezoneOffset() * 60 * 1000;
        var niceExtent = [
            Math.round(mathCeil((extent[0] - timezoneOffset) / interval) * interval + timezoneOffset),
            Math.round(mathFloor((extent[1] - timezoneOffset) / interval) * interval + timezoneOffset)
        ];

        fixExtent(niceExtent, extent);

        this._stepLvl = level;
        // Interval will be used in getTicks
        this._interval = interval;
        this._niceExtent = niceExtent;
    },

    parse: function (val) {
        // val might be float.
        return +parseDate(val);
    }
});

each$1(['contain', 'normalize'], function (methodName) {
    TimeScale.prototype[methodName] = function (val) {
        return intervalScaleProto[methodName].call(this, this.parse(val));
    };
});

/**
 * This implementation was originally copied from "d3.js"
 * <https://github.com/d3/d3/blob/b516d77fb8566b576088e73410437494717ada26/src/time/scale.js>
 * with some modifications made for this program.
 * See the license statement at the head of this file.
 */
var scaleLevels = [
    // Format              interval
    ['hh:mm:ss', ONE_SECOND],          // 1s
    ['hh:mm:ss', ONE_SECOND * 5],      // 5s
    ['hh:mm:ss', ONE_SECOND * 10],     // 10s
    ['hh:mm:ss', ONE_SECOND * 15],     // 15s
    ['hh:mm:ss', ONE_SECOND * 30],     // 30s
    ['hh:mm\nMM-dd', ONE_MINUTE],      // 1m
    ['hh:mm\nMM-dd', ONE_MINUTE * 5],  // 5m
    ['hh:mm\nMM-dd', ONE_MINUTE * 10], // 10m
    ['hh:mm\nMM-dd', ONE_MINUTE * 15], // 15m
    ['hh:mm\nMM-dd', ONE_MINUTE * 30], // 30m
    ['hh:mm\nMM-dd', ONE_HOUR],        // 1h
    ['hh:mm\nMM-dd', ONE_HOUR * 2],    // 2h
    ['hh:mm\nMM-dd', ONE_HOUR * 6],    // 6h
    ['hh:mm\nMM-dd', ONE_HOUR * 12],   // 12h
    ['MM-dd\nyyyy', ONE_DAY],          // 1d
    ['MM-dd\nyyyy', ONE_DAY * 2],      // 2d
    ['MM-dd\nyyyy', ONE_DAY * 3],      // 3d
    ['MM-dd\nyyyy', ONE_DAY * 4],      // 4d
    ['MM-dd\nyyyy', ONE_DAY * 5],      // 5d
    ['MM-dd\nyyyy', ONE_DAY * 6],      // 6d
    ['week', ONE_DAY * 7],             // 7d
    ['MM-dd\nyyyy', ONE_DAY * 10],     // 10d
    ['week', ONE_DAY * 14],            // 2w
    ['week', ONE_DAY * 21],            // 3w
    ['month', ONE_DAY * 31],           // 1M
    ['week', ONE_DAY * 42],            // 6w
    ['month', ONE_DAY * 62],           // 2M
    ['week', ONE_DAY * 70],            // 10w
    ['quarter', ONE_DAY * 95],         // 3M
    ['month', ONE_DAY * 31 * 4],       // 4M
    ['month', ONE_DAY * 31 * 5],       // 5M
    ['half-year', ONE_DAY * 380 / 2],  // 6M
    ['month', ONE_DAY * 31 * 8],       // 8M
    ['month', ONE_DAY * 31 * 10],      // 10M
    ['year', ONE_DAY * 380]            // 1Y
];

/**
 * @param {module:echarts/model/Model}
 * @return {module:echarts/scale/Time}
 */
TimeScale.create = function (model) {
    return new TimeScale({useUTC: model.ecModel.get('useUTC')});
};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * Log scale
 * @module echarts/scale/Log
 */

// Use some method of IntervalScale
var scaleProto$1 = Scale.prototype;
var intervalScaleProto$1 = IntervalScale.prototype;

var getPrecisionSafe$1 = getPrecisionSafe;
var roundingErrorFix = round$1;

var mathFloor$1 = Math.floor;
var mathCeil$1 = Math.ceil;
var mathPow$1 = Math.pow;

var mathLog = Math.log;

var LogScale = Scale.extend({

    type: 'log',

    base: 10,

    $constructor: function () {
        Scale.apply(this, arguments);
        this._originalScale = new IntervalScale();
    },

    /**
     * @param {boolean} [expandToNicedExtent=false] If expand the ticks to niced extent.
     * @return {Array.<number>}
     */
    getTicks: function (expandToNicedExtent) {
        var originalScale = this._originalScale;
        var extent = this._extent;
        var originalExtent = originalScale.getExtent();

        return map(intervalScaleProto$1.getTicks.call(this, expandToNicedExtent), function (val) {
            var powVal = round$1(mathPow$1(this.base, val));

            // Fix #4158
            powVal = (val === extent[0] && originalScale.__fixMin)
                ? fixRoundingError(powVal, originalExtent[0])
                : powVal;
            powVal = (val === extent[1] && originalScale.__fixMax)
                ? fixRoundingError(powVal, originalExtent[1])
                : powVal;

            return powVal;
        }, this);
    },

    /**
     * @param {number} splitNumber
     * @return {Array.<Array.<number>>}
     */
    getMinorTicks: intervalScaleProto$1.getMinorTicks,

    /**
     * @param {number} val
     * @return {string}
     */
    getLabel: intervalScaleProto$1.getLabel,

    /**
     * @param  {number} val
     * @return {number}
     */
    scale: function (val) {
        val = scaleProto$1.scale.call(this, val);
        return mathPow$1(this.base, val);
    },

    /**
     * @param {number} start
     * @param {number} end
     */
    setExtent: function (start, end) {
        var base = this.base;
        start = mathLog(start) / mathLog(base);
        end = mathLog(end) / mathLog(base);
        intervalScaleProto$1.setExtent.call(this, start, end);
    },

    /**
     * @return {number} end
     */
    getExtent: function () {
        var base = this.base;
        var extent = scaleProto$1.getExtent.call(this);
        extent[0] = mathPow$1(base, extent[0]);
        extent[1] = mathPow$1(base, extent[1]);

        // Fix #4158
        var originalScale = this._originalScale;
        var originalExtent = originalScale.getExtent();
        originalScale.__fixMin && (extent[0] = fixRoundingError(extent[0], originalExtent[0]));
        originalScale.__fixMax && (extent[1] = fixRoundingError(extent[1], originalExtent[1]));

        return extent;
    },

    /**
     * @param  {Array.<number>} extent
     */
    unionExtent: function (extent) {
        this._originalScale.unionExtent(extent);

        var base = this.base;
        extent[0] = mathLog(extent[0]) / mathLog(base);
        extent[1] = mathLog(extent[1]) / mathLog(base);
        scaleProto$1.unionExtent.call(this, extent);
    },

    /**
     * @override
     */
    unionExtentFromData: function (data, dim) {
        // TODO
        // filter value that <= 0
        this.unionExtent(data.getApproximateExtent(dim));
    },

    /**
     * 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 = quantity(span);
        var err = approxTickNum / span * interval;

        // Filter ticks to get closer to the desired count.
        if (err <= 0.5) {
            interval *= 10;
        }

        // Interval should be integer
        while (!isNaN(interval) && Math.abs(interval) < 1 && Math.abs(interval) > 0) {
            interval *= 10;
        }

        var niceExtent = [
            round$1(mathCeil$1(extent[0] / interval) * interval),
            round$1(mathFloor$1(extent[1] / interval) * interval)
        ];

        this._interval = interval;
        this._niceExtent = niceExtent;
    },

    /**
     * Nice extent.
     * @override
     */
    niceExtent: function (opt) {
        intervalScaleProto$1.niceExtent.call(this, opt);

        var originalScale = this._originalScale;
        originalScale.__fixMin = opt.fixMin;
        originalScale.__fixMax = opt.fixMax;
    }

});

each$1(['contain', 'normalize'], function (methodName) {
    LogScale.prototype[methodName] = function (val) {
        val = mathLog(val) / mathLog(this.base);
        return scaleProto$1[methodName].call(this, val);
    };
});

LogScale.create = function () {
    return new LogScale();
};

function fixRoundingError(val, originalVal) {
    return roundingErrorFix(val, getPrecisionSafe$1(originalVal));
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * Get axis scale extent before niced.
 * Item of returned array can only be number (including Infinity and NaN).
 */
function getScaleExtent(scale, model) {
    var scaleType = scale.type;

    var min = model.getMin();
    var max = model.getMax();
    var originalExtent = scale.getExtent();

    var axisDataLen;
    var boundaryGap;
    var span;
    if (scaleType === 'ordinal') {
        axisDataLen = model.getCategories().length;
    }
    else {
        boundaryGap = model.get('boundaryGap');
        if (!isArray(boundaryGap)) {
            boundaryGap = [boundaryGap || 0, boundaryGap || 0];
        }
        if (typeof boundaryGap[0] === 'boolean') {
            if (__DEV__) {
                console.warn('Boolean type for boundaryGap is only '
                    + 'allowed for ordinal axis. Please use string in '
                    + 'percentage instead, e.g., "20%". Currently, '
                    + 'boundaryGap is set to be 0.');
            }
            boundaryGap = [0, 0];
        }
        boundaryGap[0] = parsePercent$1(boundaryGap[0], 1);
        boundaryGap[1] = parsePercent$1(boundaryGap[1], 1);
        span = (originalExtent[1] - originalExtent[0])
            || Math.abs(originalExtent[0]);
    }

    // Notice: When min/max is not set (that is, when there are null/undefined,
    // which is the most common case), these cases should be ensured:
    // (1) For 'ordinal', show all axis.data.
    // (2) For others:
    //      + `boundaryGap` is applied (if min/max set, boundaryGap is
    //      disabled).
    //      + If `needCrossZero`, min/max should be zero, otherwise, min/max should
    //      be the result that originalExtent enlarged by boundaryGap.
    // (3) If no data, it should be ensured that `scale.setBlank` is set.

    // FIXME
    // (1) When min/max is 'dataMin' or 'dataMax', should boundaryGap be able to used?
    // (2) When `needCrossZero` and all data is positive/negative, should it be ensured
    // that the results processed by boundaryGap are positive/negative?

    if (min === 'dataMin') {
        min = originalExtent[0];
    }
    else if (typeof min === 'function') {
        min = min({
            min: originalExtent[0],
            max: originalExtent[1]
        });
    }

    if (max === 'dataMax') {
        max = originalExtent[1];
    }
    else if (typeof max === 'function') {
        max = max({
            min: originalExtent[0],
            max: originalExtent[1]
        });
    }

    var fixMin = min != null;
    var fixMax = max != null;

    if (min == null) {
        min = scaleType === 'ordinal'
            ? (axisDataLen ? 0 : NaN)
            : originalExtent[0] - boundaryGap[0] * span;
    }
    if (max == null) {
        max = scaleType === 'ordinal'
            ? (axisDataLen ? axisDataLen - 1 : NaN)
            : originalExtent[1] + boundaryGap[1] * span;
    }

    (min == null || !isFinite(min)) && (min = NaN);
    (max == null || !isFinite(max)) && (max = NaN);

    scale.setBlank(
        eqNaN(min)
        || eqNaN(max)
        || (scaleType === 'ordinal' && !scale.getOrdinalMeta().categories.length)
    );

    // Evaluate if axis needs cross zero
    if (model.getNeedCrossZero()) {
        // Axis is over zero and min is not set
        if (min > 0 && max > 0 && !fixMin) {
            min = 0;
        }
        // Axis is under zero and max is not set
        if (min < 0 && max < 0 && !fixMax) {
            max = 0;
        }
    }

    // If bars are placed on a base axis of type time or interval account for axis boundary overflow and current axis
    // is base axis
    // FIXME
    // (1) Consider support value axis, where below zero and axis `onZero` should be handled properly.
    // (2) Refactor the logic with `barGrid`. Is it not need to `makeBarWidthAndOffsetInfo` twice with different extent?
    //     Should not depend on series type `bar`?
    // (3) Fix that might overlap when using dataZoom.
    // (4) Consider other chart types using `barGrid`?
    // See #6728, #4862, `test/bar-overflow-time-plot.html`
    var ecModel = model.ecModel;
    if (ecModel && (scaleType === 'time' /*|| scaleType === 'interval' */)) {
        var barSeriesModels = prepareLayoutBarSeries('bar', ecModel);
        var isBaseAxisAndHasBarSeries;

        each$1(barSeriesModels, function (seriesModel) {
            isBaseAxisAndHasBarSeries |= seriesModel.getBaseAxis() === model.axis;
        });

        if (isBaseAxisAndHasBarSeries) {
            // Calculate placement of bars on axis
            var barWidthAndOffset = makeColumnLayout(barSeriesModels);

            // Adjust axis min and max to account for overflow
            var adjustedScale = adjustScaleForOverflow(min, max, model, barWidthAndOffset);
            min = adjustedScale.min;
            max = adjustedScale.max;
        }
    }

    return {
        extent: [min, max],
        // "fix" means "fixed", the value should not be
        // changed in the subsequent steps.
        fixMin: fixMin,
        fixMax: fixMax
    };
}

function adjustScaleForOverflow(min, max, model, barWidthAndOffset) {

    // Get Axis Length
    var axisExtent = model.axis.getExtent();
    var axisLength = axisExtent[1] - axisExtent[0];

    // Get bars on current base axis and calculate min and max overflow
    var barsOnCurrentAxis = retrieveColumnLayout(barWidthAndOffset, model.axis);
    if (barsOnCurrentAxis === undefined) {
        return {min: min, max: max};
    }

    var minOverflow = Infinity;
    each$1(barsOnCurrentAxis, function (item) {
        minOverflow = Math.min(item.offset, minOverflow);
    });
    var maxOverflow = -Infinity;
    each$1(barsOnCurrentAxis, function (item) {
        maxOverflow = Math.max(item.offset + item.width, maxOverflow);
    });
    minOverflow = Math.abs(minOverflow);
    maxOverflow = Math.abs(maxOverflow);
    var totalOverFlow = minOverflow + maxOverflow;

    // Calulate required buffer based on old range and overflow
    var oldRange = max - min;
    var oldRangePercentOfNew = (1 - (minOverflow + maxOverflow) / axisLength);
    var overflowBuffer = ((oldRange / oldRangePercentOfNew) - oldRange);

    max += overflowBuffer * (maxOverflow / totalOverFlow);
    min -= overflowBuffer * (minOverflow / totalOverFlow);

    return {min: min, max: max};
}

function niceScaleExtent(scale, model) {
    var extentInfo = getScaleExtent(scale, model);
    var extent = extentInfo.extent;

    var splitNumber = model.get('splitNumber');

    if (scale.type === 'log') {
        scale.base = model.get('logBase');
    }

    var scaleType = scale.type;
    scale.setExtent(extent[0], extent[1]);
    scale.niceExtent({
        splitNumber: splitNumber,
        fixMin: extentInfo.fixMin,
        fixMax: extentInfo.fixMax,
        minInterval: (scaleType === 'interval' || scaleType === 'time')
            ? model.get('minInterval') : null,
        maxInterval: (scaleType === 'interval' || scaleType === 'time')
            ? model.get('maxInterval') : null
    });

    // If some one specified the min, max. And the default calculated interval
    // is not good enough. He can specify the interval. It is often appeared
    // in angle axis with angle 0 - 360. Interval calculated in interval scale is hard
    // to be 60.
    // FIXME
    var interval = model.get('interval');
    if (interval != null) {
        scale.setInterval && scale.setInterval(interval);
    }
}

/**
 * @param {module:echarts/model/Model} model
 * @param {string} [axisType] Default retrieve from model.type
 * @return {module:echarts/scale/*}
 */
function createScaleByModel(model, axisType) {
    axisType = axisType || model.get('type');
    if (axisType) {
        switch (axisType) {
            // Buildin scale
            case 'category':
                return new OrdinalScale(
                    model.getOrdinalMeta
                        ? model.getOrdinalMeta()
                        : 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
 */
function ifAxisCrossZero(axis) {
    var dataExtent = axis.scale.getExtent();
    var min = dataExtent[0];
    var max = dataExtent[1];
    return !((min > 0 && max > 0) || (min < 0 && max < 0));
}

/**
 * @param {module:echarts/coord/Axis} axis
 * @return {Function} Label formatter function.
 *         param: {number} tickValue,
 *         param: {number} idx, the index in all ticks.
 *                         If category axis, this param is not requied.
 *         return: {string} label string.
 */
function makeLabelFormatter(axis) {
    var labelFormatter = axis.getLabelModel().get('formatter');
    var categoryTickStart = axis.type === 'category' ? axis.scale.getExtent()[0] : null;

    if (typeof labelFormatter === 'string') {
        labelFormatter = (function (tpl) {
            return function (val) {
                // For category axis, get raw value; for numeric axis,
                // get foramtted label like '1,333,444'.
                val = axis.scale.getLabel(val);
                return tpl.replace('{value}', val != null ? val : '');
            };
        })(labelFormatter);
        // Consider empty array
        return labelFormatter;
    }
    else if (typeof labelFormatter === 'function') {
        return function (tickValue, idx) {
            // The original intention of `idx` is "the index of the tick in all ticks".
            // But the previous implementation of category axis do not consider the
            // `axisLabel.interval`, which cause that, for example, the `interval` is
            // `1`, then the ticks "name5", "name7", "name9" are displayed, where the
            // corresponding `idx` are `0`, `2`, `4`, but not `0`, `1`, `2`. So we keep
            // the definition here for back compatibility.
            if (categoryTickStart != null) {
                idx = tickValue - categoryTickStart;
            }
            return labelFormatter(getAxisRawValue(axis, tickValue), idx);
        };
    }
    else {
        return function (tick) {
            return axis.scale.getLabel(tick);
        };
    }
}

function getAxisRawValue(axis, value) {
    // In category axis with data zoom, tick is not the original
    // index of axis.data. So tick should not be exposed to user
    // in category axis.
    return axis.type === 'category' ? axis.scale.getLabel(value) : value;
}

/**
 * @param {module:echarts/coord/Axis} axis
 * @return {module:zrender/core/BoundingRect} Be null/undefined if no labels.
 */
function estimateLabelUnionRect(axis) {
    var axisModel = axis.model;
    var scale = axis.scale;

    if (!axisModel.get('axisLabel.show') || scale.isBlank()) {
        return;
    }

    var isCategory = axis.type === 'category';

    var realNumberScaleTicks;
    var tickCount;
    var categoryScaleExtent = scale.getExtent();

    // Optimize for large category data, avoid call `getTicks()`.
    if (isCategory) {
        tickCount = scale.count();
    }
    else {
        realNumberScaleTicks = scale.getTicks();
        tickCount = realNumberScaleTicks.length;
    }

    var axisLabelModel = axis.getLabelModel();
    var labelFormatter = makeLabelFormatter(axis);

    var rect;
    var step = 1;
    // Simple optimization for large amount of labels
    if (tickCount > 40) {
        step = Math.ceil(tickCount / 40);
    }
    for (var i = 0; i < tickCount; i += step) {
        var tickValue = realNumberScaleTicks ? realNumberScaleTicks[i] : categoryScaleExtent[0] + i;
        var label = labelFormatter(tickValue);
        var unrotatedSingleRect = axisLabelModel.getTextRect(label);
        var singleRect = rotateTextRect(unrotatedSingleRect, axisLabelModel.get('rotate') || 0);

        rect ? rect.union(singleRect) : (rect = singleRect);
    }

    return rect;
}

function rotateTextRect(textRect, rotate) {
    var rotateRadians = rotate * Math.PI / 180;
    var boundingBox = textRect.plain();
    var beforeWidth = boundingBox.width;
    var beforeHeight = boundingBox.height;
    var afterWidth = beforeWidth * Math.abs(Math.cos(rotateRadians)) + Math.abs(beforeHeight * Math.sin(rotateRadians));
    var afterHeight = beforeWidth * Math.abs(Math.sin(rotateRadians)) + Math.abs(beforeHeight * Math.cos(rotateRadians));
    var rotatedRect = new BoundingRect(boundingBox.x, boundingBox.y, afterWidth, afterHeight);

    return rotatedRect;
}

/**
 * @param {module:echarts/src/model/Model} model axisLabelModel or axisTickModel
 * @return {number|String} Can be null|'auto'|number|function
 */
function getOptionCategoryInterval(model) {
    var interval = model.get('interval');
    return interval == null ? 'auto' : interval;
}

/**
 * Set `categoryInterval` as 0 implicitly indicates that
 * show all labels reguardless of overlap.
 * @param {Object} axis axisModel.axis
 * @return {boolean}
 */
function shouldShowAllLabels(axis) {
    return axis.type === 'category'
        && getOptionCategoryInterval(axis.getLabelModel()) === 0;
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

// import * as axisHelper from './axisHelper';

var axisModelCommonMixin = {

    /**
     * @param {boolean} origin
     * @return {number|string} min value or 'dataMin' or null/undefined (means auto) or NaN
     */
    getMin: function (origin) {
        var option = this.option;
        var min = (!origin && option.rangeStart != null)
            ? option.rangeStart : option.min;

        if (this.axis
            && min != null
            && min !== 'dataMin'
            && typeof min !== 'function'
            && !eqNaN(min)
        ) {
            min = this.axis.scale.parse(min);
        }
        return min;
    },

    /**
     * @param {boolean} origin
     * @return {number|string} max value or 'dataMax' or null/undefined (means auto) or NaN
     */
    getMax: function (origin) {
        var option = this.option;
        var max = (!origin && option.rangeEnd != null)
            ? option.rangeEnd : option.max;

        if (this.axis
            && max != null
            && max !== 'dataMax'
            && typeof max !== 'function'
            && !eqNaN(max)
        ) {
            max = this.axis.scale.parse(max);
        }
        return max;
    },

    /**
     * @return {boolean}
     */
    getNeedCrossZero: function () {
        var option = this.option;
        return (option.rangeStart != null || option.rangeEnd != null)
            ? false : !option.scale;
    },

    /**
     * Should be implemented by each axis model if necessary.
     * @return {module:echarts/model/Component} coordinate system model
     */
    getCoordSysModel: noop,

    /**
     * @param {number} rangeStart Can only be finite number or null/undefined or NaN.
     * @param {number} rangeEnd Can only be finite number or null/undefined or NaN.
     */
    setRange: function (rangeStart, rangeEnd) {
        this.option.rangeStart = rangeStart;
        this.option.rangeEnd = rangeEnd;
    },

    /**
     * Reset range
     */
    resetRange: function () {
        // rangeStart and rangeEnd is readonly.
        this.option.rangeStart = this.option.rangeEnd = null;
    }
};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

// Symbol factory

/**
 * Triangle shape
 * @inner
 */
var Triangle = 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 = 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 = 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);

        var cpLen = r * 0.6;
        var cpLen2 = r * 0.7;

        path.moveTo(x - dx, cy + dy);

        path.arc(
            x, cy, r,
            Math.PI - angle,
            Math.PI * 2 + angle
        );
        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 = 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: Line,

    rect: Rect,

    roundRect: Rect,

    square: Rect,

    circle: 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 = {};
each$1(symbolCtors, function (Ctor, name) {
    symbolBuildProxies[name] = new Ctor();
});

var SymbolClz = extendShape({

    type: 'symbol',

    shape: {
        symbolType: '',
        x: 0,
        y: 0,
        width: 0,
        height: 0
    },

    calculateTextPosition: function (out, style, rect) {
        var res = calculateTextPosition(out, style, rect);
        var shape = this.shape;
        if (shape && shape.symbolType === 'pin' && style.textPosition === 'inside') {
            res.y = rect.y + rect.height * 0.4;
        }
        return res;
    },

    buildPath: function (ctx, shape, inBundle) {
        var symbolType = shape.symbolType;
        if (symbolType !== 'none') {
            var proxySymbol = symbolBuildProxies[symbolType];
            if (!proxySymbol) {
                // Default rect
                symbolType = 'rect';
                proxySymbol = symbolBuildProxies[symbolType];
            }
            symbolShapeMakers[symbolType](
                shape.x, shape.y, shape.width, shape.height, proxySymbol.shape
            );
            proxySymbol.buildPath(ctx, proxySymbol.shape, inBundle);
        }
    }
});

// Provide setColor helper method to avoid determine if set the fill or stroke outside
function symbolPathSetColor(color, innerColor) {
    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 = innerColor || '#fff';
        }
        else {
            // FIXME 判断图形默认是填充还是描边，使用 onlyStroke ?
            symbolStyle.fill && (symbolStyle.fill = color);
            symbolStyle.stroke && (symbolStyle.stroke = color);
        }
        this.dirty(false);
    }
}

/**
 * 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
 * @param {boolean} [keepAspect=false] whether to keep the ratio of w/h,
 *                            for path and image only.
 */
function createSymbol(symbolType, x, y, w, h, color, keepAspect) {
    // TODO Support image object, DynamicImage.

    var isEmpty = symbolType.indexOf('empty') === 0;
    if (isEmpty) {
        symbolType = symbolType.substr(5, 1).toLowerCase() + symbolType.substr(6);
    }
    var symbolPath;

    if (symbolType.indexOf('image://') === 0) {
        symbolPath = makeImage(
            symbolType.slice(8),
            new BoundingRect(x, y, w, h),
            keepAspect ? 'center' : 'cover'
        );
    }
    else if (symbolType.indexOf('path://') === 0) {
        symbolPath = makePath(
            symbolType.slice(7),
            {},
            new BoundingRect(x, y, w, h),
            keepAspect ? 'center' : 'cover'
        );
    }
    else {
        symbolPath = new SymbolClz({
            shape: {
                symbolType: symbolType,
                x: x,
                y: y,
                width: w,
                height: h
            }
        });
    }

    symbolPath.__isEmptyBrush = isEmpty;

    symbolPath.setColor = symbolPathSetColor;

    symbolPath.setColor(color);

    return symbolPath;
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

// import createGraphFromNodeEdge from './chart/helper/createGraphFromNodeEdge';
/**
 * Create a muti dimension List structure from seriesModel.
 * @param  {module:echarts/model/Model} seriesModel
 * @return {module:echarts/data/List} list
 */
function createList(seriesModel) {
    return createListFromArray(seriesModel.getSource(), seriesModel);
}

var dataStack$1 = {
    isDimensionStacked: isDimensionStacked,
    enableDataStack: enableDataStack,
    getStackedDimension: getStackedDimension
};

/**
 * Create scale
 * @param {Array.<number>} dataExtent
 * @param {Object|module:echarts/Model} option
 */
function createScale(dataExtent, option) {
    var axisModel = option;
    if (!Model.isInstance(option)) {
        axisModel = new Model(option);
        mixin(axisModel, axisModelCommonMixin);
    }

    var scale = createScaleByModel(axisModel);
    scale.setExtent(dataExtent[0], dataExtent[1]);

    niceScaleExtent(scale, axisModel);
    return scale;
}

/**
 * Mixin common methods to axis model,
 *
 * Inlcude methods
 * `getFormattedLabels() => Array.<string>`
 * `getCategories() => Array.<string>`
 * `getMin(origin: boolean) => number`
 * `getMax(origin: boolean) => number`
 * `getNeedCrossZero() => boolean`
 * `setRange(start: number, end: number)`
 * `resetRange()`
 */
function mixinAxisModelCommonMethods(Model$$1) {
    mixin(Model$$1, axisModelCommonMixin);
}

var helper = (Object.freeze || Object)({
	createList: createList,
	getLayoutRect: getLayoutRect,
	dataStack: dataStack$1,
	createScale: createScale,
	mixinAxisModelCommonMethods: mixinAxisModelCommonMethods,
	completeDimensions: completeDimensions,
	createDimensions: createDimensions,
	createSymbol: createSymbol
});

var EPSILON$3 = 1e-8;

function isAroundEqual$1(a, b) {
    return Math.abs(a - b) < EPSILON$3;
}

function contain$1(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$1(p[0], p0[0]) || !isAroundEqual$1(p[1], p0[1])) {
        w += windingLine(p[0], p[1], p0[0], p0[1], x, y);
    }

    return w !== 0;
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * @module echarts/coord/geo/Region
 */

/**
 * @param {string|Region} name
 * @param {Array} geometries
 * @param {Array.<number>} cp
 */
function Region(name, geometries, cp) {

    /**
     * @type {string}
     * @readOnly
     */
    this.name = name;

    /**
     * @type {Array.<Array>}
     * @readOnly
     */
    this.geometries = geometries;

    if (!cp) {
        var rect = this.getBoundingRect();
        cp = [
            rect.x + rect.width / 2,
            rect.y + rect.height / 2
        ];
    }
    else {
        cp = [cp[0], cp[1]];
    }
    /**
     * @type {Array.<number>}
     */
    this.center = cp;
}

Region.prototype = {

    constructor: Region,

    properties: null,

    /**
     * @return {module:zrender/core/BoundingRect}
     */
    getBoundingRect: function () {
        var rect = this._rect;
        if (rect) {
            return rect;
        }

        var MAX_NUMBER = Number.MAX_VALUE;
        var min$$1 = [MAX_NUMBER, MAX_NUMBER];
        var max$$1 = [-MAX_NUMBER, -MAX_NUMBER];
        var min2 = [];
        var max2 = [];
        var geometries = this.geometries;
        for (var i = 0; i < geometries.length; i++) {
            // Only support polygon
            if (geometries[i].type !== 'polygon') {
                continue;
            }
            // Doesn't consider hole
            var exterior = geometries[i].exterior;
            fromPoints(exterior, min2, max2);
            min(min$$1, min$$1, min2);
            max(max$$1, max$$1, max2);
        }
        // No data
        if (i === 0) {
            min$$1[0] = min$$1[1] = max$$1[0] = max$$1[1] = 0;
        }

        return (this._rect = new BoundingRect(
            min$$1[0], min$$1[1], max$$1[0] - min$$1[0], max$$1[1] - min$$1[1]
        ));
    },

    /**
     * @param {<Array.<number>} coord
     * @return {boolean}
     */
    contain: function (coord) {
        var rect = this.getBoundingRect();
        var geometries = this.geometries;
        if (!rect.contain(coord[0], coord[1])) {
            return false;
        }
        loopGeo: for (var i = 0, len$$1 = geometries.length; i < len$$1; i++) {
            // Only support polygon.
            if (geometries[i].type !== 'polygon') {
                continue;
            }
            var exterior = geometries[i].exterior;
            var interiors = geometries[i].interiors;
            if (contain$1(exterior, coord[0], coord[1])) {
                // Not in the region if point is in the hole.
                for (var k = 0; k < (interiors ? interiors.length : 0); k++) {
                    if (contain$1(interiors[k])) {
                        continue loopGeo;
                    }
                }
                return true;
            }
        }
        return false;
    },

    transformTo: function (x, y, width, height) {
        var rect = this.getBoundingRect();
        var aspect = rect.width / rect.height;
        if (!width) {
            width = aspect * height;
        }
        else if (!height) {
            height = width / aspect;
        }
        var target = new BoundingRect(x, y, width, height);
        var transform = rect.calculateTransform(target);
        var geometries = this.geometries;
        for (var i = 0; i < geometries.length; i++) {
            // Only support polygon.
            if (geometries[i].type !== 'polygon') {
                continue;
            }
            var exterior = geometries[i].exterior;
            var interiors = geometries[i].interiors;
            for (var p = 0; p < exterior.length; p++) {
                applyTransform(exterior[p], exterior[p], transform);
            }
            for (var h = 0; h < (interiors ? interiors.length : 0); h++) {
                for (var p = 0; p < interiors[h].length; p++) {
                    applyTransform(interiors[h][p], interiors[h][p], transform);
                }
            }
        }
        rect = this._rect;
        rect.copy(target);
        // Update center
        this.center = [
            rect.x + rect.width / 2,
            rect.y + rect.height / 2
        ];
    },

    cloneShallow: function (name) {
        name == null && (name = this.name);
        var newRegion = new Region(name, this.geometries, this.center);
        newRegion._rect = this._rect;
        newRegion.transformTo = null; // Simply avoid to be called.
        return newRegion;
    }
};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * Parse and decode geo json
 * @module echarts/coord/geo/parseGeoJson
 */

function decode(json) {
    if (!json.UTF8Encoding) {
        return json;
    }
    var encodeScale = json.UTF8Scale;
    if (encodeScale == null) {
        encodeScale = 1024;
    }

    var features = json.features;

    for (var f = 0; f < features.length; f++) {
        var feature = features[f];
        var geometry = feature.geometry;
        var coordinates = geometry.coordinates;
        var encodeOffsets = geometry.encodeOffsets;

        for (var c = 0; c < coordinates.length; c++) {
            var coordinate = coordinates[c];

            if (geometry.type === 'Polygon') {
                coordinates[c] = decodePolygon(
                    coordinate,
                    encodeOffsets[c],
                    encodeScale
                );
            }
            else if (geometry.type === 'MultiPolygon') {
                for (var c2 = 0; c2 < coordinate.length; c2++) {
                    var polygon = coordinate[c2];
                    coordinate[c2] = decodePolygon(
                        polygon,
                        encodeOffsets[c][c2],
                        encodeScale
                    );
                }
            }
        }
    }
    // Has been decoded
    json.UTF8Encoding = false;
    return json;
}

function decodePolygon(coordinate, encodeOffsets, encodeScale) {
    var result = [];
    var prevX = encodeOffsets[0];
    var prevY = encodeOffsets[1];

    for (var i = 0; i < coordinate.length; i += 2) {
        var x = coordinate.charCodeAt(i) - 64;
        var y = coordinate.charCodeAt(i + 1) - 64;
        // ZigZag decoding
        x = (x >> 1) ^ (-(x & 1));
        y = (y >> 1) ^ (-(y & 1));
        // Delta deocding
        x += prevX;
        y += prevY;

        prevX = x;
        prevY = y;
        // Dequantize
        result.push([x / encodeScale, y / encodeScale]);
    }

    return result;
}

/**
 * @alias module:echarts/coord/geo/parseGeoJson
 * @param {Object} geoJson
 * @param {string} nameProperty
 * @return {module:zrender/container/Group}
 */
var parseGeoJSON = function (geoJson, nameProperty) {

    decode(geoJson);

    return map(filter(geoJson.features, function (featureObj) {
        // Output of mapshaper may have geometry null
        return featureObj.geometry
            && featureObj.properties
            && featureObj.geometry.coordinates.length > 0;
    }), function (featureObj) {
        var properties = featureObj.properties;
        var geo = featureObj.geometry;

        var coordinates = geo.coordinates;

        var geometries = [];
        if (geo.type === 'Polygon') {
            geometries.push({
                type: 'polygon',
                // According to the GeoJSON specification.
                // First must be exterior, and the rest are all interior(holes).
                exterior: coordinates[0],
                interiors: coordinates.slice(1)
            });
        }
        if (geo.type === 'MultiPolygon') {
            each$1(coordinates, function (item) {
                if (item[0]) {
                    geometries.push({
                        type: 'polygon',
                        exterior: item[0],
                        interiors: item.slice(1)
                    });
                }
            });
        }

        var region = new Region(
            properties[nameProperty || 'name'],
            geometries,
            properties.cp
        );
        region.properties = properties;
        return region;
    });
};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var inner$6 = makeInner();

/**
 * @param {module:echats/coord/Axis} axis
 * @return {Object} {
 *     labels: [{
 *         formattedLabel: string,
 *         rawLabel: string,
 *         tickValue: number
 *     }, ...],
 *     labelCategoryInterval: number
 * }
 */
function createAxisLabels(axis) {
    // Only ordinal scale support tick interval
    return axis.type === 'category'
        ? makeCategoryLabels(axis)
        : makeRealNumberLabels(axis);
}

/**
 * @param {module:echats/coord/Axis} axis
 * @param {module:echarts/model/Model} tickModel For example, can be axisTick, splitLine, splitArea.
 * @return {Object} {
 *     ticks: Array.<number>
 *     tickCategoryInterval: number
 * }
 */
function createAxisTicks(axis, tickModel) {
    // Only ordinal scale support tick interval
    return axis.type === 'category'
        ? makeCategoryTicks(axis, tickModel)
        : {ticks: axis.scale.getTicks()};
}

function makeCategoryLabels(axis) {
    var labelModel = axis.getLabelModel();
    var result = makeCategoryLabelsActually(axis, labelModel);

    return (!labelModel.get('show') || axis.scale.isBlank())
        ? {labels: [], labelCategoryInterval: result.labelCategoryInterval}
        : result;
}

function makeCategoryLabelsActually(axis, labelModel) {
    var labelsCache = getListCache(axis, 'labels');
    var optionLabelInterval = getOptionCategoryInterval(labelModel);
    var result = listCacheGet(labelsCache, optionLabelInterval);

    if (result) {
        return result;
    }

    var labels;
    var numericLabelInterval;

    if (isFunction$1(optionLabelInterval)) {
        labels = makeLabelsByCustomizedCategoryInterval(axis, optionLabelInterval);
    }
    else {
        numericLabelInterval = optionLabelInterval === 'auto'
            ? makeAutoCategoryInterval(axis) : optionLabelInterval;
        labels = makeLabelsByNumericCategoryInterval(axis, numericLabelInterval);
    }

    // Cache to avoid calling interval function repeatly.
    return listCacheSet(labelsCache, optionLabelInterval, {
        labels: labels, labelCategoryInterval: numericLabelInterval
    });
}

function makeCategoryTicks(axis, tickModel) {
    var ticksCache = getListCache(axis, 'ticks');
    var optionTickInterval = getOptionCategoryInterval(tickModel);
    var result = listCacheGet(ticksCache, optionTickInterval);

    if (result) {
        return result;
    }

    var ticks;
    var tickCategoryInterval;

    // Optimize for the case that large category data and no label displayed,
    // we should not return all ticks.
    if (!tickModel.get('show') || axis.scale.isBlank()) {
        ticks = [];
    }

    if (isFunction$1(optionTickInterval)) {
        ticks = makeLabelsByCustomizedCategoryInterval(axis, optionTickInterval, true);
    }
    // Always use label interval by default despite label show. Consider this
    // scenario, Use multiple grid with the xAxis sync, and only one xAxis shows
    // labels. `splitLine` and `axisTick` should be consistent in this case.
    else if (optionTickInterval === 'auto') {
        var labelsResult = makeCategoryLabelsActually(axis, axis.getLabelModel());
        tickCategoryInterval = labelsResult.labelCategoryInterval;
        ticks = map(labelsResult.labels, function (labelItem) {
            return labelItem.tickValue;
        });
    }
    else {
        tickCategoryInterval = optionTickInterval;
        ticks = makeLabelsByNumericCategoryInterval(axis, tickCategoryInterval, true);
    }

    // Cache to avoid calling interval function repeatly.
    return listCacheSet(ticksCache, optionTickInterval, {
        ticks: ticks, tickCategoryInterval: tickCategoryInterval
    });
}

function makeRealNumberLabels(axis) {
    var ticks = axis.scale.getTicks();
    var labelFormatter = makeLabelFormatter(axis);
    return {
        labels: map(ticks, function (tickValue, idx) {
            return {
                formattedLabel: labelFormatter(tickValue, idx),
                rawLabel: axis.scale.getLabel(tickValue),
                tickValue: tickValue
            };
        })
    };
}

// Large category data calculation is performence sensitive, and ticks and label
// probably be fetched by multiple times. So we cache the result.
// axis is created each time during a ec process, so we do not need to clear cache.
function getListCache(axis, prop) {
    // Because key can be funciton, and cache size always be small, we use array cache.
    return inner$6(axis)[prop] || (inner$6(axis)[prop] = []);
}

function listCacheGet(cache, key) {
    for (var i = 0; i < cache.length; i++) {
        if (cache[i].key === key) {
            return cache[i].value;
        }
    }
}

function listCacheSet(cache, key, value) {
    cache.push({key: key, value: value});
    return value;
}

function makeAutoCategoryInterval(axis) {
    var result = inner$6(axis).autoInterval;
    return result != null
        ? result
        : (inner$6(axis).autoInterval = axis.calculateCategoryInterval());
}

/**
 * Calculate interval for category axis ticks and labels.
 * To get precise result, at least one of `getRotate` and `isHorizontal`
 * should be implemented in axis.
 */
function calculateCategoryInterval(axis) {
    var params = fetchAutoCategoryIntervalCalculationParams(axis);
    var labelFormatter = makeLabelFormatter(axis);
    var rotation = (params.axisRotate - params.labelRotate) / 180 * Math.PI;

    var ordinalScale = axis.scale;
    var ordinalExtent = ordinalScale.getExtent();
    // Providing this method is for optimization:
    // avoid generating a long array by `getTicks`
    // in large category data case.
    var tickCount = ordinalScale.count();

    if (ordinalExtent[1] - ordinalExtent[0] < 1) {
        return 0;
    }

    var step = 1;
    // Simple optimization. Empirical value: tick count should less than 40.
    if (tickCount > 40) {
        step = Math.max(1, Math.floor(tickCount / 40));
    }
    var tickValue = ordinalExtent[0];
    var unitSpan = axis.dataToCoord(tickValue + 1) - axis.dataToCoord(tickValue);
    var unitW = Math.abs(unitSpan * Math.cos(rotation));
    var unitH = Math.abs(unitSpan * Math.sin(rotation));

    var maxW = 0;
    var maxH = 0;

    // Caution: Performance sensitive for large category data.
    // Consider dataZoom, we should make appropriate step to avoid O(n) loop.
    for (; tickValue <= ordinalExtent[1]; tickValue += step) {
        var width = 0;
        var height = 0;

        // Not precise, do not consider align and vertical align
        // and each distance from axis line yet.
        var rect = getBoundingRect(
            labelFormatter(tickValue), params.font, 'center', 'top'
        );
        // Magic number
        width = rect.width * 1.3;
        height = rect.height * 1.3;

        // Min size, void long loop.
        maxW = Math.max(maxW, width, 7);
        maxH = Math.max(maxH, height, 7);
    }

    var dw = maxW / unitW;
    var dh = maxH / unitH;
    // 0/0 is NaN, 1/0 is Infinity.
    isNaN(dw) && (dw = Infinity);
    isNaN(dh) && (dh = Infinity);
    var interval = Math.max(0, Math.floor(Math.min(dw, dh)));

    var cache = inner$6(axis.model);
    var axisExtent = axis.getExtent();
    var lastAutoInterval = cache.lastAutoInterval;
    var lastTickCount = cache.lastTickCount;

    // Use cache to keep interval stable while moving zoom window,
    // otherwise the calculated interval might jitter when the zoom
    // window size is close to the interval-changing size.
    // For example, if all of the axis labels are `a, b, c, d, e, f, g`.
    // The jitter will cause that sometimes the displayed labels are
    // `a, d, g` (interval: 2) sometimes `a, c, e`(interval: 1).
    if (lastAutoInterval != null
        && lastTickCount != null
        && Math.abs(lastAutoInterval - interval) <= 1
        && Math.abs(lastTickCount - tickCount) <= 1
        // Always choose the bigger one, otherwise the critical
        // point is not the same when zooming in or zooming out.
        && lastAutoInterval > interval
        // If the axis change is caused by chart resize, the cache should not
        // be used. Otherwise some hiden labels might not be shown again.
        && cache.axisExtend0 === axisExtent[0]
        && cache.axisExtend1 === axisExtent[1]
    ) {
        interval = lastAutoInterval;
    }
    // Only update cache if cache not used, otherwise the
    // changing of interval is too insensitive.
    else {
        cache.lastTickCount = tickCount;
        cache.lastAutoInterval = interval;
        cache.axisExtend0 = axisExtent[0];
        cache.axisExtend1 = axisExtent[1];
    }

    return interval;
}

function fetchAutoCategoryIntervalCalculationParams(axis) {
    var labelModel = axis.getLabelModel();
    return {
        axisRotate: axis.getRotate
            ? axis.getRotate()
            : (axis.isHorizontal && !axis.isHorizontal())
            ? 90
            : 0,
        labelRotate: labelModel.get('rotate') || 0,
        font: labelModel.getFont()
    };
}

function makeLabelsByNumericCategoryInterval(axis, categoryInterval, onlyTick) {
    var labelFormatter = makeLabelFormatter(axis);
    var ordinalScale = axis.scale;
    var ordinalExtent = ordinalScale.getExtent();
    var labelModel = axis.getLabelModel();
    var result = [];

    // TODO: axisType: ordinalTime, pick the tick from each month/day/year/...

    var step = Math.max((categoryInterval || 0) + 1, 1);
    var startTick = ordinalExtent[0];
    var tickCount = ordinalScale.count();

    // Calculate start tick based on zero if possible to keep label consistent
    // while zooming and moving while interval > 0. Otherwise the selection
    // of displayable ticks and symbols probably keep changing.
    // 3 is empirical value.
    if (startTick !== 0 && step > 1 && tickCount / step > 2) {
        startTick = Math.round(Math.ceil(startTick / step) * step);
    }

    // (1) Only add min max label here but leave overlap checking
    // to render stage, which also ensure the returned list
    // suitable for splitLine and splitArea rendering.
    // (2) Scales except category always contain min max label so
    // do not need to perform this process.
    var showAllLabel = shouldShowAllLabels(axis);
    var includeMinLabel = labelModel.get('showMinLabel') || showAllLabel;
    var includeMaxLabel = labelModel.get('showMaxLabel') || showAllLabel;

    if (includeMinLabel && startTick !== ordinalExtent[0]) {
        addItem(ordinalExtent[0]);
    }

    // Optimize: avoid generating large array by `ordinalScale.getTicks()`.
    var tickValue = startTick;
    for (; tickValue <= ordinalExtent[1]; tickValue += step) {
        addItem(tickValue);
    }

    if (includeMaxLabel && tickValue - step !== ordinalExtent[1]) {
        addItem(ordinalExtent[1]);
    }

    function addItem(tVal) {
        result.push(onlyTick
            ? tVal
            : {
                formattedLabel: labelFormatter(tVal),
                rawLabel: ordinalScale.getLabel(tVal),
                tickValue: tVal
            }
        );
    }

    return result;
}

// When interval is function, the result `false` means ignore the tick.
// It is time consuming for large category data.
function makeLabelsByCustomizedCategoryInterval(axis, categoryInterval, onlyTick) {
    var ordinalScale = axis.scale;
    var labelFormatter = makeLabelFormatter(axis);
    var result = [];

    each$1(ordinalScale.getTicks(), function (tickValue) {
        var rawLabel = ordinalScale.getLabel(tickValue);
        if (categoryInterval(tickValue, rawLabel)) {
            result.push(onlyTick
                ? tickValue
                : {
                    formattedLabel: labelFormatter(tickValue),
                    rawLabel: rawLabel,
                    tickValue: tickValue
                }
            );
        }
    });

    return result;
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var NORMALIZED_EXTENT = [0, 1];

/**
 * Base class of Axis.
 * @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.scale.contain(data);
    },

    /**
     * Get coord extent.
     * @return {Array.<number>}
     */
    getExtent: function () {
        return this._extent.slice();
    },

    /**
     * Get precision used for formatting
     * @param {Array.<number>} [dataExtent]
     * @return {number}
     */
    getPixelPrecision: function (dataExtent) {
        return 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 an ordinal scale
     * @param {number} data
     * @param  {boolean} clamp
     * @return {number}
     */
    dataToCoord: function (data, clamp) {
        var extent = this._extent;
        var scale = this.scale;
        data = scale.normalize(data);

        if (this.onBand && scale.type === 'ordinal') {
            extent = extent.slice();
            fixExtentWithBands(extent, scale.count());
        }

        return linearMap(data, NORMALIZED_EXTENT, extent, clamp);
    },

    /**
     * Convert coord to data. Data is the rank if it has an ordinal scale
     * @param {number} coord
     * @param  {boolean} clamp
     * @return {number}
     */
    coordToData: function (coord, clamp) {
        var extent = this._extent;
        var scale = this.scale;

        if (this.onBand && scale.type === 'ordinal') {
            extent = extent.slice();
            fixExtentWithBands(extent, scale.count());
        }

        var t = linearMap(coord, extent, NORMALIZED_EXTENT, clamp);

        return this.scale.scale(t);
    },

    /**
     * Convert pixel point to data in axis
     * @param {Array.<number>} point
     * @param  {boolean} clamp
     * @return {number} data
     */
    pointToData: function (point, clamp) {
        // Should be implemented in derived class if necessary.
    },

    /**
     * Different from `zrUtil.map(axis.getTicks(), axis.dataToCoord, axis)`,
     * `axis.getTicksCoords` considers `onBand`, which is used by
     * `boundaryGap:true` of category axis and splitLine and splitArea.
     * @param {Object} [opt]
     * @param {Model} [opt.tickModel=axis.model.getModel('axisTick')]
     * @param {boolean} [opt.clamp] If `true`, the first and the last
     *        tick must be at the axis end points. Otherwise, clip ticks
     *        that outside the axis extent.
     * @return {Array.<Object>} [{
     *     coord: ...,
     *     tickValue: ...
     * }, ...]
     */
    getTicksCoords: function (opt) {
        opt = opt || {};

        var tickModel = opt.tickModel || this.getTickModel();
        var result = createAxisTicks(this, tickModel);
        var ticks = result.ticks;

        var ticksCoords = map(ticks, function (tickValue) {
            return {
                coord: this.dataToCoord(tickValue),
                tickValue: tickValue
            };
        }, this);

        var alignWithLabel = tickModel.get('alignWithLabel');

        fixOnBandTicksCoords(
            this, ticksCoords, alignWithLabel, opt.clamp
        );

        return ticksCoords;
    },

    /**
     * @return {Array.<Array.<Object>>} [{ coord: ..., tickValue: ...}]
     */
    getMinorTicksCoords: function () {
        if (this.scale.type === 'ordinal') {
            // Category axis doesn't support minor ticks
            return [];
        }

        var minorTickModel = this.model.getModel('minorTick');
        var splitNumber = minorTickModel.get('splitNumber');
        // Protection.
        if (!(splitNumber > 0 && splitNumber < 100)) {
            splitNumber = 5;
        }
        var minorTicks = this.scale.getMinorTicks(splitNumber);
        var minorTicksCoords = map(minorTicks, function (minorTicksGroup) {
            return map(minorTicksGroup, function (minorTick) {
                return {
                    coord: this.dataToCoord(minorTick),
                    tickValue: minorTick
                };
            }, this);
        }, this);
        return minorTicksCoords;
    },

    /**
     * @return {Array.<Object>} [{
     *     formattedLabel: string,
     *     rawLabel: axis.scale.getLabel(tickValue)
     *     tickValue: number
     * }, ...]
     */
    getViewLabels: function () {
        return createAxisLabels(this).labels;
    },

    /**
     * @return {module:echarts/coord/model/Model}
     */
    getLabelModel: function () {
        return this.model.getModel('axisLabel');
    },

    /**
     * Notice here we only get the default tick model. For splitLine
     * or splitArea, we should pass the splitLineModel or splitAreaModel
     * manually when calling `getTicksCoords`.
     * In GL, this method may be overrided to:
     * `axisModel.getModel('axisTick', grid3DModel.getModel('axisTick'));`
     * @return {module:echarts/coord/model/Model}
     */
    getTickModel: function () {
        return this.model.getModel('axisTick');
    },

    /**
     * Get width of band
     * @return {number}
     */
    getBandWidth: function () {
        var axisExtent = this._extent;
        var dataExtent = this.scale.getExtent();

        var len = dataExtent[1] - dataExtent[0] + (this.onBand ? 1 : 0);
        // Fix #2728, avoid NaN when only one data.
        len === 0 && (len = 1);

        var size = Math.abs(axisExtent[1] - axisExtent[0]);

        return Math.abs(size) / len;
    },

    /**
     * @abstract
     * @return {boolean} Is horizontal
     */
    isHorizontal: null,

    /**
     * @abstract
     * @return {number} Get axis rotate, by degree.
     */
    getRotate: null,

    /**
     * Only be called in category axis.
     * Can be overrided, consider other axes like in 3D.
     * @return {number} Auto interval for cateogry axis tick and label
     */
    calculateCategoryInterval: function () {
        return calculateCategoryInterval(this);
    }

};

function fixExtentWithBands(extent, nTick) {
    var size = extent[1] - extent[0];
    var len = nTick;
    var margin = size / len / 2;
    extent[0] += margin;
    extent[1] -= margin;
}

// If axis has labels [1, 2, 3, 4]. Bands on the axis are
// |---1---|---2---|---3---|---4---|.
// So the displayed ticks and splitLine/splitArea should between
// each data item, otherwise cause misleading (e.g., split tow bars
// of a single data item when there are two bar series).
// Also consider if tickCategoryInterval > 0 and onBand, ticks and
// splitLine/spliteArea should layout appropriately corresponding
// to displayed labels. (So we should not use `getBandWidth` in this
// case).
function fixOnBandTicksCoords(axis, ticksCoords, alignWithLabel, clamp) {
    var ticksLen = ticksCoords.length;

    if (!axis.onBand || alignWithLabel || !ticksLen) {
        return;
    }

    var axisExtent = axis.getExtent();
    var last;
    var diffSize;
    if (ticksLen === 1) {
        ticksCoords[0].coord = axisExtent[0];
        last = ticksCoords[1] = {coord: axisExtent[0]};
    }
    else {
        var crossLen = ticksCoords[ticksLen - 1].tickValue - ticksCoords[0].tickValue;
        var shift = (ticksCoords[ticksLen - 1].coord - ticksCoords[0].coord) / crossLen;

        each$1(ticksCoords, function (ticksItem) {
            ticksItem.coord -= shift / 2;
        });

        var dataExtent = axis.scale.getExtent();
        diffSize = 1 + dataExtent[1] - ticksCoords[ticksLen - 1].tickValue;

        last = {coord: ticksCoords[ticksLen - 1].coord + shift * diffSize};

        ticksCoords.push(last);
    }

    var inverse = axisExtent[0] > axisExtent[1];

    // Handling clamp.
    if (littleThan(ticksCoords[0].coord, axisExtent[0])) {
        clamp ? (ticksCoords[0].coord = axisExtent[0]) : ticksCoords.shift();
    }
    if (clamp && littleThan(axisExtent[0], ticksCoords[0].coord)) {
        ticksCoords.unshift({coord: axisExtent[0]});
    }
    if (littleThan(axisExtent[1], last.coord)) {
        clamp ? (last.coord = axisExtent[1]) : ticksCoords.pop();
    }
    if (clamp && littleThan(last.coord, axisExtent[1])) {
        ticksCoords.push({coord: axisExtent[1]});
    }

    function littleThan(a, b) {
        // Avoid rounding error cause calculated tick coord different with extent.
        // It may cause an extra unecessary tick added.
        a = round$1(a);
        b = round$1(b);
        return inverse ? a > b : a < b;
    }
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * Do not mount those modules on 'src/echarts' for better tree shaking.
 */

var parseGeoJson = parseGeoJSON;

var ecUtil = {};
each$1(
    [
        'map', 'each', 'filter', 'indexOf', 'inherits', 'reduce', 'filter',
        'bind', 'curry', 'isArray', 'isString', 'isObject', 'isFunction',
        'extend', 'defaults', 'clone', 'merge'
    ],
    function (name) {
        ecUtil[name] = zrUtil[name];
    }
);
var graphic$1 = {};
each$1(
    [
        'extendShape', 'extendPath', 'makePath', 'makeImage',
        'mergePath', 'resizePath', 'createIcon',
        'setHoverStyle', 'setLabelStyle', 'setTextStyle', 'setText',
        'getFont', 'updateProps', 'initProps', 'getTransform',
        'clipPointsByRect', 'clipRectByRect',
        'registerShape', 'getShapeClass',
        'Group',
        'Image',
        'Text',
        'Circle',
        'Sector',
        'Ring',
        'Polygon',
        'Polyline',
        'Rect',
        'Line',
        'BezierCurve',
        'Arc',
        'IncrementalDisplayable',
        'CompoundPath',
        'LinearGradient',
        'RadialGradient',
        'BoundingRect'
    ],
    function (name) {
        graphic$1[name] = graphic[name];
    }
);

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

SeriesModel.extend({

    type: 'series.line',

    dependencies: ['grid', 'polar'],

    getInitialData: function (option, ecModel) {
        if (__DEV__) {
            var coordSys = option.coordinateSystem;
            if (coordSys !== 'polar' && coordSys !== 'cartesian2d') {
                throw new Error('Line not support coordinateSystem besides cartesian and polar');
            }
        }
        return createListFromArray(this.getSource(), this, {useEncodeDefaulter: true});
    },

    defaultOption: {
        zlevel: 0,
        z: 2,
        coordinateSystem: 'cartesian2d',
        legendHoverLink: true,

        hoverAnimation: true,
        // stack: null
        // xAxisIndex: 0,
        // yAxisIndex: 0,

        // polarIndex: 0,

        // If clip the overflow value
        clip: true,
        // cursor: null,

        label: {
            position: 'top'
        },
        // itemStyle: {
        // },

        lineStyle: {
            width: 2,
            type: 'solid'
        },
        // areaStyle: {
            // origin of areaStyle. Valid values:
            // `'auto'/null/undefined`: from axisLine to data
            // `'start'`: from min to data
            // `'end'`: from data to max
            // origin: 'auto'
        // },
        // false, 'start', 'end', 'middle'
        step: false,

        // Disabled if step is true
        smooth: false,
        smoothMonotone: null,
        symbol: 'emptyCircle',
        symbolSize: 4,
        symbolRotate: null,

        showSymbol: true,
        // `false`: follow the label interval strategy.
        // `true`: show all symbols.
        // `'auto'`: If possible, show all symbols, otherwise
        //           follow the label interval strategy.
        showAllSymbol: 'auto',

        // Whether to connect break point.
        connectNulls: false,

        // Sampling for large data. Can be: 'average', 'max', 'min', 'sum'.
        sampling: 'none',

        animationEasing: 'linear',

        // Disable progressive
        progressive: 0,
        hoverLayerThreshold: Infinity
    }
});

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * @param {module:echarts/data/List} data
 * @param {number} dataIndex
 * @return {string} label string. Not null/undefined
 */
function getDefaultLabel(data, dataIndex) {
    var labelDims = data.mapDimension('defaultedLabel', true);
    var len = labelDims.length;

    // Simple optimization (in lots of cases, label dims length is 1)
    if (len === 1) {
        return retrieveRawValue(data, dataIndex, labelDims[0]);
    }
    else if (len) {
        var vals = [];
        for (var i = 0; i < labelDims.length; i++) {
            var val = retrieveRawValue(data, dataIndex, labelDims[i]);
            vals.push(val);
        }
        return vals.join(' ');
    }
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * @module echarts/chart/helper/Symbol
 */

/**
 * @constructor
 * @alias {module:echarts/chart/helper/Symbol}
 * @param {module:echarts/data/List} data
 * @param {number} idx
 * @extends {module:zrender/graphic/Group}
 */
function SymbolClz$1(data, idx, seriesScope) {
    Group.call(this);
    this.updateData(data, idx, seriesScope);
}

var symbolProto = SymbolClz$1.prototype;

/**
 * @public
 * @static
 * @param {module:echarts/data/List} data
 * @param {number} dataIndex
 * @return {Array.<number>} [width, height]
 */
var getSymbolSize = SymbolClz$1.getSymbolSize = function (data, idx) {
    var symbolSize = data.getItemVisual(idx, 'symbolSize');
    return symbolSize instanceof Array
        ? symbolSize.slice()
        : [+symbolSize, +symbolSize];
};

function getScale(symbolSize) {
    return [symbolSize[0] / 2, symbolSize[1] / 2];
}

function driftSymbol(dx, dy) {
    this.parent.drift(dx, dy);
}

symbolProto._createSymbol = function (
    symbolType,
    data,
    idx,
    symbolSize,
    keepAspect
) {
    // Remove paths created before
    this.removeAll();

    var color = data.getItemVisual(idx, 'color');

    // var symbolPath = createSymbol(
    //     symbolType, -0.5, -0.5, 1, 1, color
    // );
    // If width/height are set too small (e.g., set to 1) on ios10
    // and macOS Sierra, a circle stroke become a rect, no matter what
    // the scale is set. So we set width/height as 2. See #4150.
    var symbolPath = createSymbol(
        symbolType, -1, -1, 2, 2, color, keepAspect
    );

    symbolPath.attr({
        z2: 100,
        culling: true,
        scale: getScale(symbolSize)
    });
    // Rewrite drift method
    symbolPath.drift = driftSymbol;

    this._symbolType = symbolType;

    this.add(symbolPath);
};

/**
 * Stop animation
 * @param {boolean} toLastFrame
 */
symbolProto.stopSymbolAnimation = function (toLastFrame) {
    this.childAt(0).stopAnimation(toLastFrame);
};

/**
 * FIXME:
 * Caution: This method breaks the encapsulation of this module,
 * but it indeed brings convenience. So do not use the method
 * unless you detailedly know all the implements of `Symbol`,
 * especially animation.
 *
 * Get symbol path element.
 */
symbolProto.getSymbolPath = function () {
    return this.childAt(0);
};

/**
 * Get scale(aka, current symbol size).
 * Including the change caused by animation
 */
symbolProto.getScale = function () {
    return this.childAt(0).scale;
};

/**
 * Highlight symbol
 */
symbolProto.highlight = function () {
    this.childAt(0).trigger('emphasis');
};

/**
 * Downplay symbol
 */
symbolProto.downplay = function () {
    this.childAt(0).trigger('normal');
};

/**
 * @param {number} zlevel
 * @param {number} z
 */
symbolProto.setZ = function (zlevel, z) {
    var symbolPath = this.childAt(0);
    symbolPath.zlevel = zlevel;
    symbolPath.z = z;
};

symbolProto.setDraggable = function (draggable) {
    var symbolPath = this.childAt(0);
    symbolPath.draggable = draggable;
    symbolPath.cursor = draggable ? 'move' : symbolPath.cursor;
};

/**
 * Update symbol properties
 * @param {module:echarts/data/List} data
 * @param {number} idx
 * @param {Object} [seriesScope]
 * @param {Object} [seriesScope.itemStyle]
 * @param {Object} [seriesScope.hoverItemStyle]
 * @param {Object} [seriesScope.symbolRotate]
 * @param {Object} [seriesScope.symbolOffset]
 * @param {module:echarts/model/Model} [seriesScope.labelModel]
 * @param {module:echarts/model/Model} [seriesScope.hoverLabelModel]
 * @param {boolean} [seriesScope.hoverAnimation]
 * @param {Object} [seriesScope.cursorStyle]
 * @param {module:echarts/model/Model} [seriesScope.itemModel]
 * @param {string} [seriesScope.symbolInnerColor]
 * @param {Object} [seriesScope.fadeIn=false]
 */
symbolProto.updateData = function (data, idx, seriesScope) {
    this.silent = false;

    var symbolType = data.getItemVisual(idx, 'symbol') || 'circle';
    var seriesModel = data.hostModel;
    var symbolSize = getSymbolSize(data, idx);
    var isInit = symbolType !== this._symbolType;

    if (isInit) {
        var keepAspect = data.getItemVisual(idx, 'symbolKeepAspect');
        this._createSymbol(symbolType, data, idx, symbolSize, keepAspect);
    }
    else {
        var symbolPath = this.childAt(0);
        symbolPath.silent = false;
        updateProps(symbolPath, {
            scale: getScale(symbolSize)
        }, seriesModel, idx);
    }

    this._updateCommon(data, idx, symbolSize, seriesScope);

    if (isInit) {
        var symbolPath = this.childAt(0);
        var fadeIn = seriesScope && seriesScope.fadeIn;

        var target = {scale: symbolPath.scale.slice()};
        fadeIn && (target.style = {opacity: symbolPath.style.opacity});

        symbolPath.scale = [0, 0];
        fadeIn && (symbolPath.style.opacity = 0);

        initProps(symbolPath, target, seriesModel, idx);
    }

    this._seriesModel = seriesModel;
};

// Update common properties
var normalStyleAccessPath = ['itemStyle'];
var emphasisStyleAccessPath = ['emphasis', 'itemStyle'];
var normalLabelAccessPath = ['label'];
var emphasisLabelAccessPath = ['emphasis', 'label'];

/**
 * @param {module:echarts/data/List} data
 * @param {number} idx
 * @param {Array.<number>} symbolSize
 * @param {Object} [seriesScope]
 */
symbolProto._updateCommon = function (data, idx, symbolSize, seriesScope) {
    var symbolPath = this.childAt(0);
    var seriesModel = data.hostModel;
    var color = data.getItemVisual(idx, 'color');

    // Reset style
    if (symbolPath.type !== 'image') {
        symbolPath.useStyle({
            strokeNoScale: true
        });
    }
    else {
        symbolPath.setStyle({
            opacity: 1,
            shadowBlur: null,
            shadowOffsetX: null,
            shadowOffsetY: null,
            shadowColor: null
        });
    }

    var itemStyle = seriesScope && seriesScope.itemStyle;
    var hoverItemStyle = seriesScope && seriesScope.hoverItemStyle;
    var symbolOffset = seriesScope && seriesScope.symbolOffset;
    var labelModel = seriesScope && seriesScope.labelModel;
    var hoverLabelModel = seriesScope && seriesScope.hoverLabelModel;
    var hoverAnimation = seriesScope && seriesScope.hoverAnimation;
    var cursorStyle = seriesScope && seriesScope.cursorStyle;

    if (!seriesScope || data.hasItemOption) {
        var itemModel = (seriesScope && seriesScope.itemModel)
            ? seriesScope.itemModel : data.getItemModel(idx);

        // Color must be excluded.
        // Because symbol provide setColor individually to set fill and stroke
        itemStyle = itemModel.getModel(normalStyleAccessPath).getItemStyle(['color']);
        hoverItemStyle = itemModel.getModel(emphasisStyleAccessPath).getItemStyle();

        symbolOffset = itemModel.getShallow('symbolOffset');

        labelModel = itemModel.getModel(normalLabelAccessPath);
        hoverLabelModel = itemModel.getModel(emphasisLabelAccessPath);
        hoverAnimation = itemModel.getShallow('hoverAnimation');
        cursorStyle = itemModel.getShallow('cursor');
    }
    else {
        hoverItemStyle = extend({}, hoverItemStyle);
    }

    var elStyle = symbolPath.style;

    var symbolRotate = data.getItemVisual(idx, 'symbolRotate');

    symbolPath.attr('rotation', (symbolRotate || 0) * Math.PI / 180 || 0);

    if (symbolOffset) {
        symbolPath.attr('position', [
            parsePercent$1(symbolOffset[0], symbolSize[0]),
            parsePercent$1(symbolOffset[1], symbolSize[1])
        ]);
    }

    cursorStyle && symbolPath.attr('cursor', cursorStyle);

    // PENDING setColor before setStyle!!!
    symbolPath.setColor(color, seriesScope && seriesScope.symbolInnerColor);

    symbolPath.setStyle(itemStyle);

    var opacity = data.getItemVisual(idx, 'opacity');
    if (opacity != null) {
        elStyle.opacity = opacity;
    }

    var liftZ = data.getItemVisual(idx, 'liftZ');
    var z2Origin = symbolPath.__z2Origin;
    if (liftZ != null) {
        if (z2Origin == null) {
            symbolPath.__z2Origin = symbolPath.z2;
            symbolPath.z2 += liftZ;
        }
    }
    else if (z2Origin != null) {
        symbolPath.z2 = z2Origin;
        symbolPath.__z2Origin = null;
    }

    var useNameLabel = seriesScope && seriesScope.useNameLabel;

    setLabelStyle(
        elStyle, hoverItemStyle, labelModel, hoverLabelModel,
        {
            labelFetcher: seriesModel,
            labelDataIndex: idx,
            defaultText: getLabelDefaultText,
            isRectText: true,
            autoColor: color
        }
    );

    // Do not execute util needed.
    function getLabelDefaultText(idx, opt) {
        return useNameLabel ? data.getName(idx) : getDefaultLabel(data, idx);
    }

    symbolPath.__symbolOriginalScale = getScale(symbolSize);
    symbolPath.hoverStyle = hoverItemStyle;
    symbolPath.highDownOnUpdate = (
        hoverAnimation && seriesModel.isAnimationEnabled()
    ) ? highDownOnUpdate : null;

    setHoverStyle(symbolPath);
};

function highDownOnUpdate(fromState, toState) {
    // Do not support this hover animation util some scenario required.
    // Animation can only be supported in hover layer when using `el.incremetal`.
    if (this.incremental || this.useHoverLayer) {
        return;
    }

    if (toState === 'emphasis') {
        var scale = this.__symbolOriginalScale;
        var ratio = scale[1] / scale[0];
        var emphasisOpt = {
            scale: [
                Math.max(scale[0] * 1.1, scale[0] + 3),
                Math.max(scale[1] * 1.1, scale[1] + 3 * ratio)
            ]
        };
        // FIXME
        // modify it after support stop specified animation.
        // toState === fromState
        //     ? (this.stopAnimation(), this.attr(emphasisOpt))
        this.animateTo(emphasisOpt, 400, 'elasticOut');
    }
    else if (toState === 'normal') {
        this.animateTo({
            scale: this.__symbolOriginalScale
        }, 400, 'elasticOut');
    }
}

/**
 * @param {Function} cb
 * @param {Object} [opt]
 * @param {Object} [opt.keepLabel=true]
 */
symbolProto.fadeOut = function (cb, opt) {
    var symbolPath = this.childAt(0);
    // Avoid mistaken hover when fading out
    this.silent = symbolPath.silent = true;
    // Not show text when animating
    !(opt && opt.keepLabel) && (symbolPath.style.text = null);

    updateProps(
        symbolPath,
        {
            style: {opacity: 0},
            scale: [0, 0]
        },
        this._seriesModel,
        this.dataIndex,
        cb
    );
};

inherits(SymbolClz$1, Group);

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * @module echarts/chart/helper/SymbolDraw
 */

/**
 * @constructor
 * @alias module:echarts/chart/helper/SymbolDraw
 * @param {module:zrender/graphic/Group} [symbolCtor]
 */
function SymbolDraw(symbolCtor) {
    this.group = new Group();

    this._symbolCtor = symbolCtor || SymbolClz$1;
}

var symbolDrawProto = SymbolDraw.prototype;

function symbolNeedsDraw(data, point, idx, opt) {
    return point && !isNaN(point[0]) && !isNaN(point[1])
        && !(opt.isIgnore && opt.isIgnore(idx))
        // We do not set clipShape on group, because it will cut part of
        // the symbol element shape. We use the same clip shape here as
        // the line clip.
        && !(opt.clipShape && !opt.clipShape.contain(point[0], point[1]))
        && data.getItemVisual(idx, 'symbol') !== 'none';
}

/**
 * Update symbols draw by new data
 * @param {module:echarts/data/List} data
 * @param {Object} [opt] Or isIgnore
 * @param {Function} [opt.isIgnore]
 * @param {Object} [opt.clipShape]
 */
symbolDrawProto.updateData = function (data, opt) {
    opt = normalizeUpdateOpt(opt);

    var group = this.group;
    var seriesModel = data.hostModel;
    var oldData = this._data;
    var SymbolCtor = this._symbolCtor;

    var seriesScope = makeSeriesScope(data);

    // There is no oldLineData only when first rendering or switching from
    // stream mode to normal mode, where previous elements should be removed.
    if (!oldData) {
        group.removeAll();
    }

    data.diff(oldData)
        .add(function (newIdx) {
            var point = data.getItemLayout(newIdx);
            if (symbolNeedsDraw(data, point, newIdx, opt)) {
                var symbolEl = new SymbolCtor(data, newIdx, seriesScope);
                symbolEl.attr('position', point);
                data.setItemGraphicEl(newIdx, symbolEl);
                group.add(symbolEl);
            }
        })
        .update(function (newIdx, oldIdx) {
            var symbolEl = oldData.getItemGraphicEl(oldIdx);
            var point = data.getItemLayout(newIdx);
            if (!symbolNeedsDraw(data, point, newIdx, opt)) {
                group.remove(symbolEl);
                return;
            }
            if (!symbolEl) {
                symbolEl = new SymbolCtor(data, newIdx);
                symbolEl.attr('position', point);
            }
            else {
                symbolEl.updateData(data, newIdx, seriesScope);
                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.isPersistent = function () {
    return true;
};

symbolDrawProto.updateLayout = function () {
    var data = this._data;
    if (data) {
        // Not use animation
        data.eachItemGraphicEl(function (el, idx) {
            var point = data.getItemLayout(idx);
            el.attr('position', point);
        });
    }
};

symbolDrawProto.incrementalPrepareUpdate = function (data) {
    this._seriesScope = makeSeriesScope(data);
    this._data = null;
    this.group.removeAll();
};

/**
 * Update symbols draw by new data
 * @param {module:echarts/data/List} data
 * @param {Object} [opt] Or isIgnore
 * @param {Function} [opt.isIgnore]
 * @param {Object} [opt.clipShape]
 */
symbolDrawProto.incrementalUpdate = function (taskParams, data, opt) {
    opt = normalizeUpdateOpt(opt);

    function updateIncrementalAndHover(el) {
        if (!el.isGroup) {
            el.incremental = el.useHoverLayer = true;
        }
    }
    for (var idx = taskParams.start; idx < taskParams.end; idx++) {
        var point = data.getItemLayout(idx);
        if (symbolNeedsDraw(data, point, idx, opt)) {
            var el = new this._symbolCtor(data, idx, this._seriesScope);
            el.traverse(updateIncrementalAndHover);
            el.attr('position', point);
            this.group.add(el);
            data.setItemGraphicEl(idx, el);
        }
    }
};

function normalizeUpdateOpt(opt) {
    if (opt != null && !isObject$1(opt)) {
        opt = {isIgnore: opt};
    }
    return opt || {};
}

symbolDrawProto.remove = function (enableAnimation) {
    var group = this.group;
    var data = this._data;
    // Incremental model do not have this._data.
    if (data && enableAnimation) {
        data.eachItemGraphicEl(function (el) {
            el.fadeOut(function () {
                group.remove(el);
            });
        });
    }
    else {
        group.removeAll();
    }
};

function makeSeriesScope(data) {
    var seriesModel = data.hostModel;
    return {
        itemStyle: seriesModel.getModel('itemStyle').getItemStyle(['color']),
        hoverItemStyle: seriesModel.getModel('emphasis.itemStyle').getItemStyle(),
        symbolRotate: seriesModel.get('symbolRotate'),
        symbolOffset: seriesModel.get('symbolOffset'),
        hoverAnimation: seriesModel.get('hoverAnimation'),
        labelModel: seriesModel.getModel('label'),
        hoverLabelModel: seriesModel.getModel('emphasis.label'),
        cursorStyle: seriesModel.get('cursor')
    };
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * @param {Object} coordSys
 * @param {module:echarts/data/List} data
 * @param {string} valueOrigin lineSeries.option.areaStyle.origin
 */
function prepareDataCoordInfo(coordSys, data, valueOrigin) {
    var baseAxis = coordSys.getBaseAxis();
    var valueAxis = coordSys.getOtherAxis(baseAxis);
    var valueStart = getValueStart(valueAxis, valueOrigin);

    var baseAxisDim = baseAxis.dim;
    var valueAxisDim = valueAxis.dim;
    var valueDim = data.mapDimension(valueAxisDim);
    var baseDim = data.mapDimension(baseAxisDim);
    var baseDataOffset = valueAxisDim === 'x' || valueAxisDim === 'radius' ? 1 : 0;

    var dims = map(coordSys.dimensions, function (coordDim) {
        return data.mapDimension(coordDim);
    });

    var stacked;
    var stackResultDim = data.getCalculationInfo('stackResultDimension');
    if (stacked |= isDimensionStacked(data, dims[0] /*, dims[1]*/)) { // jshint ignore:line
        dims[0] = stackResultDim;
    }
    if (stacked |= isDimensionStacked(data, dims[1] /*, dims[0]*/)) { // jshint ignore:line
        dims[1] = stackResultDim;
    }

    return {
        dataDimsForPoint: dims,
        valueStart: valueStart,
        valueAxisDim: valueAxisDim,
        baseAxisDim: baseAxisDim,
        stacked: !!stacked,
        valueDim: valueDim,
        baseDim: baseDim,
        baseDataOffset: baseDataOffset,
        stackedOverDimension: data.getCalculationInfo('stackedOverDimension')
    };
}

function getValueStart(valueAxis, valueOrigin) {
    var valueStart = 0;
    var extent = valueAxis.scale.getExtent();

    if (valueOrigin === 'start') {
        valueStart = extent[0];
    }
    else if (valueOrigin === 'end') {
        valueStart = extent[1];
    }
    // auto
    else {
        // Both positive
        if (extent[0] > 0) {
            valueStart = extent[0];
        }
        // Both negative
        else if (extent[1] < 0) {
            valueStart = extent[1];
        }
        // If is one positive, and one negative, onZero shall be true
    }

    return valueStart;
}

function getStackedOnPoint(dataCoordInfo, coordSys, data, idx) {
    var value = NaN;
    if (dataCoordInfo.stacked) {
        value = data.get(data.getCalculationInfo('stackedOverDimension'), idx);
    }
    if (isNaN(value)) {
        value = dataCoordInfo.valueStart;
    }

    var baseDataOffset = dataCoordInfo.baseDataOffset;
    var stackedData = [];
    stackedData[baseDataOffset] = data.get(dataCoordInfo.baseDim, idx);
    stackedData[1 - baseDataOffset] = value;

    return coordSys.dataToPoint(stackedData);
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

// var arrayDiff = require('zrender/src/core/arrayDiff');
// 'zrender/src/core/arrayDiff' has been used before, but it did
// not do well in performance when roam with fixed dataZoom window.

// function convertToIntId(newIdList, oldIdList) {
//     // Generate int id instead of string id.
//     // Compare string maybe slow in score function of arrDiff

//     // Assume id in idList are all unique
//     var idIndicesMap = {};
//     var idx = 0;
//     for (var i = 0; i < newIdList.length; i++) {
//         idIndicesMap[newIdList[i]] = idx;
//         newIdList[i] = idx++;
//     }
//     for (var i = 0; i < oldIdList.length; i++) {
//         var oldId = oldIdList[i];
//         // Same with newIdList
//         if (idIndicesMap[oldId]) {
//             oldIdList[i] = idIndicesMap[oldId];
//         }
//         else {
//             oldIdList[i] = idx++;
//         }
//     }
// }

function diffData(oldData, newData) {
    var diffResult = [];

    newData.diff(oldData)
        .add(function (idx) {
            diffResult.push({cmd: '+', idx: idx});
        })
        .update(function (newIdx, oldIdx) {
            diffResult.push({cmd: '=', idx: oldIdx, idx1: newIdx});
        })
        .remove(function (idx) {
            diffResult.push({cmd: '-', idx: idx});
        })
        .execute();

    return diffResult;
}

var lineAnimationDiff = function (
    oldData, newData,
    oldStackedOnPoints, newStackedOnPoints,
    oldCoordSys, newCoordSys,
    oldValueOrigin, newValueOrigin
) {
    var diff = diffData(oldData, newData);

    // var newIdList = newData.mapArray(newData.getId);
    // var oldIdList = oldData.mapArray(oldData.getId);

    // convertToIntId(newIdList, oldIdList);

    // // FIXME One data ?
    // diff = arrayDiff(oldIdList, newIdList);

    var currPoints = [];
    var nextPoints = [];
    // Points for stacking base line
    var currStackedPoints = [];
    var nextStackedPoints = [];

    var status = [];
    var sortedIndices = [];
    var rawIndices = [];

    var newDataOldCoordInfo = prepareDataCoordInfo(oldCoordSys, newData, oldValueOrigin);
    var oldDataNewCoordInfo = prepareDataCoordInfo(newCoordSys, oldData, newValueOrigin);

    for (var i = 0; i < diff.length; i++) {
        var diffItem = diff[i];
        var pointAdded = true;

        // FIXME, animation is not so perfect when dataZoom window moves fast
        // Which is in case remvoing or add more than one data in the tail or head
        switch (diffItem.cmd) {
            case '=':
                var currentPt = oldData.getItemLayout(diffItem.idx);
                var nextPt = newData.getItemLayout(diffItem.idx1);
                // If previous data is NaN, use next point directly
                if (isNaN(currentPt[0]) || isNaN(currentPt[1])) {
                    currentPt = nextPt.slice();
                }
                currPoints.push(currentPt);
                nextPoints.push(nextPt);

                currStackedPoints.push(oldStackedOnPoints[diffItem.idx]);
                nextStackedPoints.push(newStackedOnPoints[diffItem.idx1]);

                rawIndices.push(newData.getRawIndex(diffItem.idx1));
                break;
            case '+':
                var idx = diffItem.idx;
                currPoints.push(
                    oldCoordSys.dataToPoint([
                        newData.get(newDataOldCoordInfo.dataDimsForPoint[0], idx),
                        newData.get(newDataOldCoordInfo.dataDimsForPoint[1], idx)
                    ])
                );

                nextPoints.push(newData.getItemLayout(idx).slice());

                currStackedPoints.push(
                    getStackedOnPoint(newDataOldCoordInfo, 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(oldDataNewCoordInfo.dataDimsForPoint[0], idx),
                        oldData.get(oldDataNewCoordInfo.dataDimsForPoint[1], idx)
                    ]));

                    currStackedPoints.push(oldStackedOnPoints[idx]);
                    nextStackedPoints.push(
                        getStackedOnPoint(oldDataNewCoordInfo, 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
    };
};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

// Poly path support NaN point

var vec2Min = min;
var vec2Max = max;

var scaleAndAdd$1 = scaleAndAdd;
var v2Copy = copy;

// Temporary variable
var v = [];
var cp0 = [];
var cp1 = [];

function isPointNull(p) {
    return isNaN(p[0]) || isNaN(p[1]);
}

function drawSegment(
    ctx, points, start, segLen, allLen,
    dir, smoothMin, smoothMax, smooth, smoothMonotone, connectNulls
) {
    // if (smoothMonotone == null) {
    //     if (isMono(points, 'x')) {
    //         return drawMono(ctx, points, start, segLen, allLen,
    //             dir, smoothMin, smoothMax, smooth, 'x', connectNulls);
    //     }
    //     else if (isMono(points, 'y')) {
    //         return drawMono(ctx, points, start, segLen, allLen,
    //             dir, smoothMin, smoothMax, smooth, 'y', connectNulls);
    //     }
    //     else {
    //         return drawNonMono.apply(this, arguments);
    //     }
    // }
    // else if (smoothMonotone !== 'none' && isMono(points, smoothMonotone)) {
    //     return drawMono.apply(this, arguments);
    // }
    // else {
    //     return drawNonMono.apply(this, arguments);
    // }
    if (smoothMonotone === 'none' || !smoothMonotone) {
        return drawNonMono.apply(this, arguments);
    }
    else {
        return drawMono.apply(this, arguments);
    }
}

/**
 * Check if points is in monotone.
 *
 * @param {number[][]} points         Array of points which is in [x, y] form
 * @param {string}     smoothMonotone 'x', 'y', or 'none', stating for which
 *                                    dimension that is checking.
 *                                    If is 'none', `drawNonMono` should be
 *                                    called.
 *                                    If is undefined, either being monotone
 *                                    in 'x' or 'y' will call `drawMono`.
 */
// function isMono(points, smoothMonotone) {
//     if (points.length <= 1) {
//         return true;
//     }

//     var dim = smoothMonotone === 'x' ? 0 : 1;
//     var last = points[0][dim];
//     var lastDiff = 0;
//     for (var i = 1; i < points.length; ++i) {
//         var diff = points[i][dim] - last;
//         if (!isNaN(diff) && !isNaN(lastDiff)
//             && diff !== 0 && lastDiff !== 0
//             && ((diff >= 0) !== (lastDiff >= 0))
//         ) {
//             return false;
//         }
//         if (!isNaN(diff) && diff !== 0) {
//             lastDiff = diff;
//             last = points[i][dim];
//         }
//     }
//     return true;
// }

/**
 * Draw smoothed line in monotone, in which only vertical or horizontal bezier
 * control points will be used. This should be used when points are monotone
 * either in x or y dimension.
 */
function drawMono(
    ctx, points, start, segLen, allLen,
    dir, smoothMin, smoothMax, smooth, smoothMonotone, connectNulls
) {
    var prevIdx = 0;
    var idx = start;
    for (var k = 0; k < segLen; k++) {
        var p = points[idx];
        if (idx >= allLen || idx < 0) {
            break;
        }
        if (isPointNull(p)) {
            if (connectNulls) {
                idx += dir;
                continue;
            }
            break;
        }

        if (idx === start) {
            ctx[dir > 0 ? 'moveTo' : 'lineTo'](p[0], p[1]);
        }
        else {
            if (smooth > 0) {
                var prevP = points[prevIdx];
                var dim = smoothMonotone === 'y' ? 1 : 0;

                // Length of control point to p, either in x or y, but not both
                var ctrlLen = (p[dim] - prevP[dim]) * smooth;

                v2Copy(cp0, prevP);
                cp0[dim] = prevP[dim] + ctrlLen;

                v2Copy(cp1, p);
                cp1[dim] = p[dim] - ctrlLen;

                ctx.bezierCurveTo(
                    cp0[0], cp0[1],
                    cp1[0], cp1[1],
                    p[0], p[1]
                );
            }
            else {
                ctx.lineTo(p[0], p[1]);
            }
        }

        prevIdx = idx;
        idx += dir;
    }

    return k;
}

/**
 * Draw smoothed line in non-monotone, in may cause undesired curve in extreme
 * situations. This should be used when points are non-monotone neither in x or
 * y dimension.
 */
function drawNonMono(
    ctx, points, start, segLen, allLen,
    dir, smoothMin, smoothMax, smooth, smoothMonotone, connectNulls
) {
    var prevIdx = 0;
    var idx = start;
    for (var k = 0; k < segLen; k++) {
        var p = points[idx];
        if (idx >= allLen || idx < 0) {
            break;
        }
        if (isPointNull(p)) {
            if (connectNulls) {
                idx += dir;
                continue;
            }
            break;
        }

        if (idx === start) {
            ctx[dir > 0 ? 'moveTo' : 'lineTo'](p[0], p[1]);
            v2Copy(cp0, p);
        }
        else {
            if (smooth > 0) {
                var nextIdx = idx + dir;
                var nextP = points[nextIdx];
                if (connectNulls) {
                    // Find next point not null
                    while (nextP && isPointNull(points[nextIdx])) {
                        nextIdx += dir;
                        nextP = points[nextIdx];
                    }
                }

                var ratioNextSeg = 0.5;
                var prevP = points[prevIdx];
                var nextP = points[nextIdx];
                // Last point
                if (!nextP || isPointNull(nextP)) {
                    v2Copy(cp1, p);
                }
                else {
                    // If next data is null in not connect case
                    if (isPointNull(nextP) && !connectNulls) {
                        nextP = p;
                    }

                    sub(v, nextP, prevP);

                    var lenPrevSeg;
                    var lenNextSeg;
                    if (smoothMonotone === 'x' || smoothMonotone === 'y') {
                        var dim = smoothMonotone === 'x' ? 0 : 1;
                        lenPrevSeg = Math.abs(p[dim] - prevP[dim]);
                        lenNextSeg = Math.abs(p[dim] - nextP[dim]);
                    }
                    else {
                        lenPrevSeg = dist(p, prevP);
                        lenNextSeg = dist(p, nextP);
                    }

                    // Use ratio of seg length
                    ratioNextSeg = lenNextSeg / (lenNextSeg + lenPrevSeg);

                    scaleAndAdd$1(cp1, p, v, -smooth * (1 - ratioNextSeg));
                }
                // Smooth constraint
                vec2Min(cp0, cp0, smoothMax);
                vec2Max(cp0, cp0, smoothMin);
                vec2Min(cp1, cp1, smoothMax);
                vec2Max(cp1, cp1, smoothMin);

                ctx.bezierCurveTo(
                    cp0[0], cp0[1],
                    cp1[0], cp1[1],
                    p[0], p[1]
                );
                // cp0 of next segment
                scaleAndAdd$1(cp0, p, v, smooth * ratioNextSeg);
            }
            else {
                ctx.lineTo(p[0], p[1]);
            }
        }

        prevIdx = idx;
        idx += dir;
    }

    return k;
}

function getBoundingBox(points, smoothConstraint) {
    var ptMin = [Infinity, Infinity];
    var ptMax = [-Infinity, -Infinity];
    if (smoothConstraint) {
        for (var i = 0; i < points.length; i++) {
            var pt = points[i];
            if (pt[0] < ptMin[0]) {
                ptMin[0] = pt[0];
            }
            if (pt[1] < ptMin[1]) {
                ptMin[1] = pt[1];
            }
            if (pt[0] > ptMax[0]) {
                ptMax[0] = pt[0];
            }
            if (pt[1] > ptMax[1]) {
                ptMax[1] = pt[1];
            }
        }
    }
    return {
        min: smoothConstraint ? ptMin : ptMax,
        max: smoothConstraint ? ptMax : ptMin
    };
}

var Polyline$1 = Path.extend({

    type: 'ec-polyline',

    shape: {
        points: [],

        smooth: 0,

        smoothConstraint: true,

        smoothMonotone: null,

        connectNulls: false
    },

    style: {
        fill: null,

        stroke: '#000'
    },

    brush: fixClipWithShadow(Path.prototype.brush),

    buildPath: function (ctx, shape) {
        var points = shape.points;

        var i = 0;
        var len$$1 = points.length;

        var result = getBoundingBox(points, shape.smoothConstraint);

        if (shape.connectNulls) {
            // Must remove first and last null values avoid draw error in polygon
            for (; len$$1 > 0; len$$1--) {
                if (!isPointNull(points[len$$1 - 1])) {
                    break;
                }
            }
            for (; i < len$$1; i++) {
                if (!isPointNull(points[i])) {
                    break;
                }
            }
        }
        while (i < len$$1) {
            i += drawSegment(
                ctx, points, i, len$$1, len$$1,
                1, result.min, result.max, shape.smooth,
                shape.smoothMonotone, shape.connectNulls
            ) + 1;
        }
    }
});

var Polygon$1 = Path.extend({

    type: 'ec-polygon',

    shape: {
        points: [],

        // Offset between stacked base points and points
        stackedOnPoints: [],

        smooth: 0,

        stackedOnSmooth: 0,

        smoothConstraint: true,

        smoothMonotone: null,

        connectNulls: false
    },

    brush: fixClipWithShadow(Path.prototype.brush),

    buildPath: function (ctx, shape) {
        var points = shape.points;
        var stackedOnPoints = shape.stackedOnPoints;

        var i = 0;
        var len$$1 = points.length;
        var smoothMonotone = shape.smoothMonotone;
        var bbox = getBoundingBox(points, shape.smoothConstraint);
        var stackedOnBBox = getBoundingBox(stackedOnPoints, shape.smoothConstraint);

        if (shape.connectNulls) {
            // Must remove first and last null values avoid draw error in polygon
            for (; len$$1 > 0; len$$1--) {
                if (!isPointNull(points[len$$1 - 1])) {
                    break;
                }
            }
            for (; i < len$$1; i++) {
                if (!isPointNull(points[i])) {
                    break;
                }
            }
        }
        while (i < len$$1) {
            var k = drawSegment(
                ctx, points, i, len$$1, len$$1,
                1, bbox.min, bbox.max, shape.smooth,
                smoothMonotone, shape.connectNulls
            );
            drawSegment(
                ctx, stackedOnPoints, i + k - 1, k, len$$1,
                -1, stackedOnBBox.min, stackedOnBBox.max, shape.stackedOnSmooth,
                smoothMonotone, shape.connectNulls
            );
            i += k + 1;

            ctx.closePath();
        }
    }
});

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/
function createGridClipPath(cartesian, hasAnimation, seriesModel) {
    var rect = cartesian.getArea();
    var isHorizontal = cartesian.getBaseAxis().isHorizontal();

    var x = rect.x;
    var y = rect.y;
    var width = rect.width;
    var height = rect.height;

    var lineWidth = seriesModel.get('lineStyle.width') || 2;
    // Expand the clip path a bit to avoid the border is clipped and looks thinner
    x -= lineWidth / 2;
    y -= lineWidth / 2;
    width += lineWidth;
    height += lineWidth;

    // fix: https://github.com/apache/incubator-echarts/issues/11369
    x = Math.floor(x);
    width = Math.round(width);

    var clipPath = new Rect({
        shape: {
            x: x,
            y: y,
            width: width,
            height: height
        }
    });

    if (hasAnimation) {
        clipPath.shape[isHorizontal ? 'width' : 'height'] = 0;
        initProps(clipPath, {
            shape: {
                width: width,
                height: height
            }
        }, seriesModel);
    }

    return clipPath;
}

function createPolarClipPath(polar, hasAnimation, seriesModel) {
    var sectorArea = polar.getArea();
    // Avoid float number rounding error for symbol on the edge of axis extent.

    var clipPath = new Sector({
        shape: {
            cx: round$1(polar.cx, 1),
            cy: round$1(polar.cy, 1),
            r0: round$1(sectorArea.r0, 1),
            r: round$1(sectorArea.r, 1),
            startAngle: sectorArea.startAngle,
            endAngle: sectorArea.endAngle,
            clockwise: sectorArea.clockwise
        }
    });

    if (hasAnimation) {
        clipPath.shape.endAngle = sectorArea.startAngle;
        initProps(clipPath, {
            shape: {
                endAngle: sectorArea.endAngle
            }
        }, seriesModel);
    }
    return clipPath;
}

function createClipPath(coordSys, hasAnimation, seriesModel) {
    if (!coordSys) {
        return null;
    }
    else if (coordSys.type === 'polar') {
        return createPolarClipPath(coordSys, hasAnimation, seriesModel);
    }
    else if (coordSys.type === 'cartesian2d') {
        return createGridClipPath(coordSys, hasAnimation, seriesModel);
    }
    return null;
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

// FIXME step not support polar

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 getBoundingDiff(points1, points2) {
    var min1 = [];
    var max1 = [];

    var min2 = [];
    var max2 = [];

    fromPoints(points1, min1, max1);
    fromPoints(points2, min2, max2);

    // Get a max value from each corner of two boundings.
    return Math.max(
        Math.abs(min1[0] - min2[0]),
        Math.abs(min1[1] - min2[1]),

        Math.abs(max1[0] - max2[0]),
        Math.abs(max1[1] - max2[1])
    );
}

function getSmooth(smooth) {
    return typeof (smooth) === 'number' ? smooth : (smooth ? 0.5 : 0);
}

/**
 * @param {module:echarts/coord/cartesian/Cartesian2D|module:echarts/coord/polar/Polar} coordSys
 * @param {module:echarts/data/List} data
 * @param {Object} dataCoordInfo
 * @param {Array.<Array.<number>>} points
 */
function getStackedOnPoints(coordSys, data, dataCoordInfo) {
    if (!dataCoordInfo.valueDim) {
        return [];
    }

    var points = [];
    for (var idx = 0, len = data.count(); idx < len; idx++) {
        points.push(getStackedOnPoint(dataCoordInfo, coordSys, data, idx));
    }

    return points;
}

function turnPointsIntoStep(points, coordSys, stepTurnAt) {
    var baseAxis = coordSys.getBaseAxis();
    var baseIndex = baseAxis.dim === 'x' || baseAxis.dim === 'radius' ? 0 : 1;

    var stepPoints = [];
    for (var i = 0; i < points.length - 1; i++) {
        var nextPt = points[i + 1];
        var pt = points[i];
        stepPoints.push(pt);

        var stepPt = [];
        switch (stepTurnAt) {
            case 'end':
                stepPt[baseIndex] = nextPt[baseIndex];
                stepPt[1 - baseIndex] = pt[1 - baseIndex];
                // default is start
                stepPoints.push(stepPt);
                break;
            case 'middle':
                // default is start
                var middle = (pt[baseIndex] + nextPt[baseIndex]) / 2;
                var stepPt2 = [];
                stepPt[baseIndex] = stepPt2[baseIndex] = middle;
                stepPt[1 - baseIndex] = pt[1 - baseIndex];
                stepPt2[1 - baseIndex] = nextPt[1 - baseIndex];
                stepPoints.push(stepPt);
                stepPoints.push(stepPt2);
                break;
            default:
                stepPt[baseIndex] = pt[baseIndex];
                stepPt[1 - baseIndex] = nextPt[1 - baseIndex];
                // default is start
                stepPoints.push(stepPt);
        }
    }
    // Last points
    points[i] && stepPoints.push(points[i]);
    return stepPoints;
}

function getVisualGradient(data, coordSys) {
    var visualMetaList = data.getVisual('visualMeta');
    if (!visualMetaList || !visualMetaList.length || !data.count()) {
        // When data.count() is 0, gradient range can not be calculated.
        return;
    }

    if (coordSys.type !== 'cartesian2d') {
        if (__DEV__) {
            console.warn('Visual map on line style is only supported on cartesian2d.');
        }
        return;
    }

    var coordDim;
    var visualMeta;

    for (var i = visualMetaList.length - 1; i >= 0; i--) {
        var dimIndex = visualMetaList[i].dimension;
        var dimName = data.dimensions[dimIndex];
        var dimInfo = data.getDimensionInfo(dimName);
        coordDim = dimInfo && dimInfo.coordDim;
        // Can only be x or y
        if (coordDim === 'x' || coordDim === 'y') {
            visualMeta = visualMetaList[i];
            break;
        }
    }

    if (!visualMeta) {
        if (__DEV__) {
            console.warn('Visual map on line style only support x or y dimension.');
        }
        return;
    }

    // If the area to be rendered is bigger than area defined by LinearGradient,
    // the canvas spec prescribes that the color of the first stop and the last
    // stop should be used. But if two stops are added at offset 0, in effect
    // browsers use the color of the second stop to render area outside
    // LinearGradient. So we can only infinitesimally extend area defined in
    // LinearGradient to render `outerColors`.

    var axis = coordSys.getAxis(coordDim);

    // dataToCoor mapping may not be linear, but must be monotonic.
    var colorStops = map(visualMeta.stops, function (stop) {
        return {
            coord: axis.toGlobalCoord(axis.dataToCoord(stop.value)),
            color: stop.color
        };
    });
    var stopLen = colorStops.length;
    var outerColors = visualMeta.outerColors.slice();

    if (stopLen && colorStops[0].coord > colorStops[stopLen - 1].coord) {
        colorStops.reverse();
        outerColors.reverse();
    }

    var tinyExtent = 10; // Arbitrary value: 10px
    var minCoord = colorStops[0].coord - tinyExtent;
    var maxCoord = colorStops[stopLen - 1].coord + tinyExtent;
    var coordSpan = maxCoord - minCoord;

    if (coordSpan < 1e-3) {
        return 'transparent';
    }

    each$1(colorStops, function (stop) {
        stop.offset = (stop.coord - minCoord) / coordSpan;
    });
    colorStops.push({
        offset: stopLen ? colorStops[stopLen - 1].offset : 0.5,
        color: outerColors[1] || 'transparent'
    });
    colorStops.unshift({ // notice colorStops.length have been changed.
        offset: stopLen ? colorStops[0].offset : 0.5,
        color: outerColors[0] || 'transparent'
    });

    // zrUtil.each(colorStops, function (colorStop) {
    //     // Make sure each offset has rounded px to avoid not sharp edge
    //     colorStop.offset = (Math.round(colorStop.offset * (end - start) + start) - start) / (end - start);
    // });

    var gradient = new LinearGradient(0, 0, 0, 0, colorStops, true);
    gradient[coordDim] = minCoord;
    gradient[coordDim + '2'] = maxCoord;

    return gradient;
}

function getIsIgnoreFunc(seriesModel, data, coordSys) {
    var showAllSymbol = seriesModel.get('showAllSymbol');
    var isAuto = showAllSymbol === 'auto';

    if (showAllSymbol && !isAuto) {
        return;
    }

    var categoryAxis = coordSys.getAxesByScale('ordinal')[0];
    if (!categoryAxis) {
        return;
    }

    // Note that category label interval strategy might bring some weird effect
    // in some scenario: users may wonder why some of the symbols are not
    // displayed. So we show all symbols as possible as we can.
    if (isAuto
        // Simplify the logic, do not determine label overlap here.
        && canShowAllSymbolForCategory(categoryAxis, data)
    ) {
        return;
    }

    // Otherwise follow the label interval strategy on category axis.
    var categoryDataDim = data.mapDimension(categoryAxis.dim);
    var labelMap = {};

    each$1(categoryAxis.getViewLabels(), function (labelItem) {
        labelMap[labelItem.tickValue] = 1;
    });

    return function (dataIndex) {
        return !labelMap.hasOwnProperty(data.get(categoryDataDim, dataIndex));
    };
}

function canShowAllSymbolForCategory(categoryAxis, data) {
    // In mose cases, line is monotonous on category axis, and the label size
    // is close with each other. So we check the symbol size and some of the
    // label size alone with the category axis to estimate whether all symbol
    // can be shown without overlap.
    var axisExtent = categoryAxis.getExtent();
    var availSize = Math.abs(axisExtent[1] - axisExtent[0]) / categoryAxis.scale.count();
    isNaN(availSize) && (availSize = 0); // 0/0 is NaN.

    // Sampling some points, max 5.
    var dataLen = data.count();
    var step = Math.max(1, Math.round(dataLen / 5));
    for (var dataIndex = 0; dataIndex < dataLen; dataIndex += step) {
        if (SymbolClz$1.getSymbolSize(
                data, dataIndex
            // Only for cartesian, where `isHorizontal` exists.
            )[categoryAxis.isHorizontal() ? 1 : 0]
            // Empirical number
            * 1.5 > availSize
        ) {
            return false;
        }
    }

    return true;
}

function createLineClipPath(coordSys, hasAnimation, seriesModel) {
    if (coordSys.type === 'cartesian2d') {
        var isHorizontal = coordSys.getBaseAxis().isHorizontal();
        var clipPath = createGridClipPath(coordSys, hasAnimation, seriesModel);
        // Expand clip shape to avoid clipping when line value exceeds axis
        if (!seriesModel.get('clip', true)) {
            var rectShape = clipPath.shape;
            var expandSize = Math.max(rectShape.width, rectShape.height);
            if (isHorizontal) {
                rectShape.y -= expandSize;
                rectShape.height += expandSize * 2;
            }
            else {
                rectShape.x -= expandSize;
                rectShape.width += expandSize * 2;
            }
        }
        return clipPath;
    }
    else {
        return createPolarClipPath(coordSys, hasAnimation, seriesModel);
    }

}

Chart.extend({

    type: 'line',

    init: function () {
        var lineGroup = new Group();

        var symbolDraw = new SymbolDraw();
        this.group.add(symbolDraw.group);

        this._symbolDraw = symbolDraw;
        this._lineGroup = lineGroup;
    },

    render: function (seriesModel, ecModel, api) {
        var coordSys = seriesModel.coordinateSystem;
        var group = this.group;
        var data = seriesModel.getData();
        var lineStyleModel = seriesModel.getModel('lineStyle');
        var areaStyleModel = seriesModel.getModel('areaStyle');

        var points = data.mapArray(data.getItemLayout);

        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 valueOrigin = areaStyleModel.get('origin');
        var dataCoordInfo = prepareDataCoordInfo(coordSys, data, valueOrigin);

        var stackedOnPoints = getStackedOnPoints(coordSys, data, dataCoordInfo);

        var showSymbol = seriesModel.get('showSymbol');

        var isIgnoreFunc = showSymbol && !isCoordSysPolar
            && getIsIgnoreFunc(seriesModel, data, coordSys);

        // Remove temporary symbols
        var oldData = this._data;
        oldData && oldData.eachItemGraphicEl(function (el, idx) {
            if (el.__temp) {
                group.remove(el);
                oldData.setItemGraphicEl(idx, null);
            }
        });

        // Remove previous created symbols if showSymbol changed to false
        if (!showSymbol) {
            symbolDraw.remove();
        }

        group.add(lineGroup);

        // FIXME step not support polar
        var step = !isCoordSysPolar && seriesModel.get('step');
        var clipShapeForSymbol;
        if (coordSys && coordSys.getArea && seriesModel.get('clip', true)) {
            clipShapeForSymbol = coordSys.getArea();
            // Avoid float number rounding error for symbol on the edge of axis extent.
            // See #7913 and `test/dataZoom-clip.html`.
            if (clipShapeForSymbol.width != null) {
                clipShapeForSymbol.x -= 0.1;
                clipShapeForSymbol.y -= 0.1;
                clipShapeForSymbol.width += 0.2;
                clipShapeForSymbol.height += 0.2;
            }
            else if (clipShapeForSymbol.r0) {
                clipShapeForSymbol.r0 -= 0.5;
                clipShapeForSymbol.r1 += 0.5;
            }
        }
        this._clipShapeForSymbol = clipShapeForSymbol;
        // Initialization animation or coordinate system changed
        if (
            !(polyline && prevCoordSys.type === coordSys.type && step === this._step)
        ) {
            showSymbol && symbolDraw.updateData(data, {
                isIgnore: isIgnoreFunc,
                clipShape: clipShapeForSymbol
            });

            if (step) {
                // TODO If stacked series is not step
                points = turnPointsIntoStep(points, coordSys, step);
                stackedOnPoints = turnPointsIntoStep(stackedOnPoints, coordSys, step);
            }

            polyline = this._newPolyline(points, coordSys, hasAnimation);
            if (isAreaChart) {
                polygon = this._newPolygon(
                    points, stackedOnPoints,
                    coordSys, hasAnimation
                );
            }
            lineGroup.setClipPath(createLineClipPath(coordSys, true, seriesModel));
        }
        else {
            if (isAreaChart && !polygon) {
                // If areaStyle is added
                polygon = this._newPolygon(
                    points, stackedOnPoints,
                    coordSys, hasAnimation
                );
            }
            else if (polygon && !isAreaChart) {
                // If areaStyle is removed
                lineGroup.remove(polygon);
                polygon = this._polygon = null;
            }

            // Update clipPath
            lineGroup.setClipPath(createLineClipPath(coordSys, false, seriesModel));

            // Always update, or it is wrong in the case turning on legend
            // because points are not changed
            showSymbol && symbolDraw.updateData(data, {
                isIgnore: isIgnoreFunc,
                clipShape: clipShapeForSymbol
            });

            // Stop symbol animation and sync with line points
            // FIXME performance?
            data.eachItemGraphicEl(function (el) {
                el.stopAnimation(true);
            });

            // In the case data zoom triggerred refreshing frequently
            // Data may not change if line has a category axis. So it should animate nothing
            if (!isPointsSame(this._stackedOnPoints, stackedOnPoints)
                || !isPointsSame(this._points, points)
            ) {
                if (hasAnimation) {
                    this._updateAnimation(
                        data, stackedOnPoints, coordSys, api, step, valueOrigin
                    );
                }
                else {
                    // Not do it in update with animation
                    if (step) {
                        // TODO If stacked series is not step
                        points = turnPointsIntoStep(points, coordSys, step);
                        stackedOnPoints = turnPointsIntoStep(stackedOnPoints, coordSys, step);
                    }

                    polyline.setShape({
                        points: points
                    });
                    polygon && polygon.setShape({
                        points: points,
                        stackedOnPoints: stackedOnPoints
                    });
                }
            }
        }

        var visualColor = getVisualGradient(data, coordSys) || data.getVisual('color');

        polyline.useStyle(defaults(
            // Use color in lineStyle first
            lineStyleModel.getLineStyle(),
            {
                fill: 'none',
                stroke: visualColor,
                lineJoin: 'bevel'
            }
        ));

        var smooth = seriesModel.get('smooth');
        smooth = getSmooth(seriesModel.get('smooth'));
        polyline.setShape({
            smooth: smooth,
            smoothMonotone: seriesModel.get('smoothMonotone'),
            connectNulls: seriesModel.get('connectNulls')
        });

        if (polygon) {
            var stackedOnSeries = data.getCalculationInfo('stackedOnSeries');
            var stackedOnSmooth = 0;

            polygon.useStyle(defaults(
                areaStyleModel.getAreaStyle(),
                {
                    fill: visualColor,
                    opacity: 0.7,
                    lineJoin: 'bevel'
                }
            ));

            if (stackedOnSeries) {
                stackedOnSmooth = getSmooth(stackedOnSeries.get('smooth'));
            }

            polygon.setShape({
                smooth: smooth,
                stackedOnSmooth: stackedOnSmooth,
                smoothMonotone: seriesModel.get('smoothMonotone'),
                connectNulls: seriesModel.get('connectNulls')
            });
        }

        this._data = data;
        // Save the coordinate system for transition animation when data changed
        this._coordSys = coordSys;
        this._stackedOnPoints = stackedOnPoints;
        this._points = points;
        this._step = step;
        this._valueOrigin = valueOrigin;
    },

    dispose: function () {},

    highlight: function (seriesModel, ecModel, api, payload) {
        var data = seriesModel.getData();
        var dataIndex = queryDataIndex(data, payload);

        if (!(dataIndex instanceof Array) && dataIndex != null && dataIndex >= 0) {
            var symbol = data.getItemGraphicEl(dataIndex);
            if (!symbol) {
                // Create a temporary symbol if it is not exists
                var pt = data.getItemLayout(dataIndex);
                if (!pt) {
                    // Null data
                    return;
                }
                // fix #11360: should't draw symbol outside clipShapeForSymbol
                if (this._clipShapeForSymbol && !this._clipShapeForSymbol.contain(pt[0], pt[1])) {
                    return;
                }
                symbol = new SymbolClz$1(data, dataIndex);
                symbol.position = pt;
                symbol.setZ(
                    seriesModel.get('zlevel'),
                    seriesModel.get('z')
                );
                symbol.ignore = isNaN(pt[0]) || isNaN(pt[1]);
                symbol.__temp = true;
                data.setItemGraphicEl(dataIndex, symbol);

                // Stop scale animation
                symbol.stopSymbolAnimation(true);

                this.group.add(symbol);
            }
            symbol.highlight();
        }
        else {
            // Highlight whole series
            Chart.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 {
            // FIXME
            // can not downplay completely.
            // Downplay whole series
            Chart.prototype.downplay.call(
                this, seriesModel, ecModel, api, payload
            );
        }
    },

    /**
     * @param {module:zrender/container/Group} group
     * @param {Array.<Array.<number>>} points
     * @private
     */
    _newPolyline: function (points) {
        var polyline = this._polyline;
        // Remove previous created polyline
        if (polyline) {
            this._lineGroup.remove(polyline);
        }

        polyline = new Polyline$1({
            shape: {
                points: points
            },
            silent: true,
            z2: 10
        });

        this._lineGroup.add(polyline);

        this._polyline = polyline;

        return polyline;
    },

    /**
     * @param {module:zrender/container/Group} group
     * @param {Array.<Array.<number>>} stackedOnPoints
     * @param {Array.<Array.<number>>} points
     * @private
     */
    _newPolygon: function (points, stackedOnPoints) {
        var polygon = this._polygon;
        // Remove previous created polygon
        if (polygon) {
            this._lineGroup.remove(polygon);
        }

        polygon = new Polygon$1({
            shape: {
                points: points,
                stackedOnPoints: stackedOnPoints
            },
            silent: true
        });

        this._lineGroup.add(polygon);

        this._polygon = polygon;
        return polygon;
    },

    /**
     * @private
     */
    // FIXME Two value axis
    _updateAnimation: function (data, stackedOnPoints, coordSys, api, step, valueOrigin) {
        var polyline = this._polyline;
        var polygon = this._polygon;
        var seriesModel = data.hostModel;

        var diff = lineAnimationDiff(
            this._data, data,
            this._stackedOnPoints, stackedOnPoints,
            this._coordSys, coordSys,
            this._valueOrigin, valueOrigin
        );

        var current = diff.current;
        var stackedOnCurrent = diff.stackedOnCurrent;
        var next = diff.next;
        var stackedOnNext = diff.stackedOnNext;
        if (step) {
            // TODO If stacked series is not step
            current = turnPointsIntoStep(diff.current, coordSys, step);
            stackedOnCurrent = turnPointsIntoStep(diff.stackedOnCurrent, coordSys, step);
            next = turnPointsIntoStep(diff.next, coordSys, step);
            stackedOnNext = turnPointsIntoStep(diff.stackedOnNext, coordSys, step);
        }
        // Don't apply animation if diff is large.
        // For better result and avoid memory explosion problems like
        // https://github.com/apache/incubator-echarts/issues/12229
        if (getBoundingDiff(current, next) > 3000
            || (polygon && getBoundingDiff(stackedOnCurrent, stackedOnNext) > 3000)
        ) {
            polyline.setShape({
                points: next
            });
            if (polygon) {
                polygon.setShape({
                    points: next,
                    stackedOnPoints: stackedOnNext
                });
            }
            return;
        }

        // `diff.current` is subset of `current` (which should be ensured by
        // turnPointsIntoStep), so points in `__points` can be updated when
        // points in `current` are update during animation.
        polyline.shape.__points = diff.current;
        polyline.shape.points = current;

        updateProps(polyline, {
            shape: {
                points: next
            }
        }, seriesModel);

        if (polygon) {
            polygon.setShape({
                points: current,
                stackedOnPoints: stackedOnCurrent
            });
            updateProps(polygon, {
                shape: {
                    points: next,
                    stackedOnPoints: stackedOnNext
                }
            }, seriesModel);
        }

        var updatedDataInfo = [];
        var diffStatus = diff.status;

        for (var i = 0; i < diffStatus.length; i++) {
            var cmd = diffStatus[i].cmd;
            if (cmd === '=') {
                var el = data.getItemGraphicEl(diffStatus[i].idx1);
                if (el) {
                    updatedDataInfo.push({
                        el: el,
                        ptIdx: i    // Index of points
                    });
                }
            }
        }

        if (polyline.animators && polyline.animators.length) {
            polyline.animators[0].during(function () {
                for (var i = 0; i < updatedDataInfo.length; i++) {
                    var el = updatedDataInfo[i].el;
                    el.attr('position', polyline.shape.__points[updatedDataInfo[i].ptIdx]);
                }
            });
        }
    },

    remove: function (ecModel) {
        var group = this.group;
        var oldData = this._data;
        this._lineGroup.removeAll();
        this._symbolDraw.remove(true);
        // Remove temporary created elements when highlighting
        oldData && oldData.eachItemGraphicEl(function (el, idx) {
            if (el.__temp) {
                group.remove(el);
                oldData.setItemGraphicEl(idx, null);
            }
        });

        this._polyline =
            this._polygon =
            this._coordSys =
            this._points =
            this._stackedOnPoints =
            this._data = null;
    }
});

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var visualSymbol = function (seriesType, defaultSymbolType, legendSymbol) {
    // Encoding visual for all series include which is filtered for legend drawing
    return {
        seriesType: seriesType,

        // For legend.
        performRawSeries: true,

        reset: function (seriesModel, ecModel, api) {
            var data = seriesModel.getData();

            var symbolType = seriesModel.get('symbol');
            var symbolSize = seriesModel.get('symbolSize');
            var keepAspect = seriesModel.get('symbolKeepAspect');
            var symbolRotate = seriesModel.get('symbolRotate');

            var hasSymbolTypeCallback = isFunction$1(symbolType);
            var hasSymbolSizeCallback = isFunction$1(symbolSize);
            var hasSymbolRotateCallback = isFunction$1(symbolRotate);
            var hasCallback = hasSymbolTypeCallback || hasSymbolSizeCallback || hasSymbolRotateCallback;
            var seriesSymbol = (!hasSymbolTypeCallback && symbolType) ? symbolType : defaultSymbolType;
            var seriesSymbolSize = !hasSymbolSizeCallback ? symbolSize : null;
            data.setVisual({
                legendSymbol: legendSymbol || seriesSymbol,
                // If seting callback functions on `symbol` or `symbolSize`, for simplicity and avoiding
                // to bring trouble, we do not pick a reuslt from one of its calling on data item here,
                // but just use the default value. Callback on `symbol` or `symbolSize` is convenient in
                // some cases but generally it is not recommanded.
                symbol: seriesSymbol,
                symbolSize: seriesSymbolSize,
                symbolKeepAspect: keepAspect,
                symbolRotate: symbolRotate
            });

            // Only visible series has each data be visual encoded
            if (ecModel.isSeriesFiltered(seriesModel)) {
                return;
            }

            function dataEach(data, idx) {
                if (hasCallback) {
                    var rawValue = seriesModel.getRawValue(idx);
                    var params = seriesModel.getDataParams(idx);
                    hasSymbolTypeCallback && data.setItemVisual(idx, 'symbol', symbolType(rawValue, params));
                    hasSymbolSizeCallback && data.setItemVisual(idx, 'symbolSize', symbolSize(rawValue, params));
                    hasSymbolRotateCallback && data.setItemVisual(idx, 'symbolRotate', symbolRotate(rawValue, params));
                }

                if (data.hasItemOption) {
                    var itemModel = data.getItemModel(idx);
                    var itemSymbolType = itemModel.getShallow('symbol', true);
                    var itemSymbolSize = itemModel.getShallow('symbolSize', true);
                    var itemSymbolRotate = itemModel.getShallow('symbolRotate', true);
                    var itemSymbolKeepAspect = itemModel.getShallow('symbolKeepAspect', true);

                    // If has item symbol
                    if (itemSymbolType != null) {
                        data.setItemVisual(idx, 'symbol', itemSymbolType);
                    }
                    if (itemSymbolSize != null) {
                        // PENDING Transform symbolSize ?
                        data.setItemVisual(idx, 'symbolSize', itemSymbolSize);
                    }
                    if (itemSymbolRotate != null) {
                         data.setItemVisual(idx, 'symbolRotate', itemSymbolRotate);
                    }
                    if (itemSymbolKeepAspect != null) {
                        data.setItemVisual(idx, 'symbolKeepAspect', itemSymbolKeepAspect);
                    }
                }
            }

            return { dataEach: (data.hasItemOption || hasCallback) ? dataEach : null };
        }
    };
};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/* global Float32Array */

var pointsLayout = function (seriesType) {
    return {
        seriesType: seriesType,

        plan: createRenderPlanner(),

        reset: function (seriesModel) {
            var data = seriesModel.getData();
            var coordSys = seriesModel.coordinateSystem;
            var pipelineContext = seriesModel.pipelineContext;
            var isLargeRender = pipelineContext.large;

            if (!coordSys) {
                return;
            }

            var dims = map(coordSys.dimensions, function (dim) {
                return data.mapDimension(dim);
            }).slice(0, 2);
            var dimLen = dims.length;

            var stackResultDim = data.getCalculationInfo('stackResultDimension');
            if (isDimensionStacked(data, dims[0] /*, dims[1]*/)) {
                dims[0] = stackResultDim;
            }
            if (isDimensionStacked(data, dims[1] /*, dims[0]*/)) {
                dims[1] = stackResultDim;
            }

            function progress(params, data) {
                var segCount = params.end - params.start;
                var points = isLargeRender && new Float32Array(segCount * dimLen);

                for (var i = params.start, offset = 0, tmpIn = [], tmpOut = []; i < params.end; i++) {
                    var point;

                    if (dimLen === 1) {
                        var x = data.get(dims[0], i);
                        point = !isNaN(x) && coordSys.dataToPoint(x, null, tmpOut);
                    }
                    else {
                        var x = tmpIn[0] = data.get(dims[0], i);
                        var y = tmpIn[1] = data.get(dims[1], i);
                        // Also {Array.<number>}, not undefined to avoid if...else... statement
                        point = !isNaN(x) && !isNaN(y) && coordSys.dataToPoint(tmpIn, null, tmpOut);
                    }

                    if (isLargeRender) {
                        points[offset++] = point ? point[0] : NaN;
                        points[offset++] = point ? point[1] : NaN;
                    }
                    else {
                        data.setItemLayout(i, (point && point.slice()) || [NaN, NaN]);
                    }
                }

                isLargeRender && data.setLayout('symbolPoints', points);
            }

            return dimLen && {progress: progress};
        }
    };
};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/


var samplers = {
    average: function (frame) {
        var sum = 0;
        var count = 0;
        for (var i = 0; i < frame.length; i++) {
            if (!isNaN(frame[i])) {
                sum += frame[i];
                count++;
            }
        }
        // Return NaN if count is 0
        return count === 0 ? NaN : sum / count;
    },
    sum: function (frame) {
        var sum = 0;
        for (var i = 0; i < frame.length; i++) {
            // Ignore NaN
            sum += frame[i] || 0;
        }
        return sum;
    },
    max: function (frame) {
        var max = -Infinity;
        for (var i = 0; i < frame.length; i++) {
            frame[i] > max && (max = frame[i]);
        }
        // NaN will cause illegal axis extent.
        return isFinite(max) ? max : NaN;
    },
    min: function (frame) {
        var min = Infinity;
        for (var i = 0; i < frame.length; i++) {
            frame[i] < min && (min = frame[i]);
        }
        // NaN will cause illegal axis extent.
        return isFinite(min) ? min : NaN;
    },
    // TODO
    // Median
    nearest: function (frame) {
        return frame[0];
    }
};

var indexSampler = function (frame, value) {
    return Math.round(frame.length / 2);
};

var dataSample = function (seriesType) {
    return {

        seriesType: seriesType,

        modifyOutputEnd: true,

        reset: function (seriesModel, ecModel, api) {
            var data = seriesModel.getData();
            var sampling = seriesModel.get('sampling');
            var coordSys = seriesModel.coordinateSystem;
            // Only cartesian2d support down sampling
            if (coordSys.type === 'cartesian2d' && sampling) {
                var baseAxis = coordSys.getBaseAxis();
                var valueAxis = coordSys.getOtherAxis(baseAxis);
                var extent = baseAxis.getExtent();
                // Coordinste system has been resized
                var size = Math.abs(extent[1] - extent[0]);
                var rate = Math.round(data.count() / size);
                if (rate > 1) {
                    var sampler;
                    if (typeof sampling === 'string') {
                        sampler = samplers[sampling];
                    }
                    else if (typeof sampling === 'function') {
                        sampler = sampling;
                    }
                    if (sampler) {
                        // Only support sample the first dim mapped from value axis.
                        seriesModel.setData(data.downSample(
                            data.mapDimension(valueAxis.dim), 1 / rate, sampler, indexSampler
                        ));
                    }
                }
            }
        }
    };
};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * Cartesian coordinate system
 * @module  echarts/coord/Cartesian
 *
 */

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 map(this._dimList, dimAxisMapper, this);
    },

    /**
     * Get axes list by given scale type
     */
    getAxesByScale: function (scaleType) {
        scaleType = scaleType.toLowerCase();
        return 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;
    }
};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/


function Cartesian2D(name) {

    Cartesian.call(this, name);
}

Cartesian2D.prototype = {

    constructor: Cartesian2D,

    type: 'cartesian2d',

    /**
     * @type {Array.<string>}
     * @readOnly
     */
    dimensions: ['x', 'y'],

    /**
     * Base axis will be used on stacking.
     *
     * @return {module:echarts/coord/cartesian/Axis2D}
     */
    getBaseAxis: function () {
        return this.getAxesByScale('ordinal')[0]
            || this.getAxesByScale('time')[0]
            || this.getAxis('x');
    },

    /**
     * If contain point
     * @param {Array.<number>} point
     * @return {boolean}
     */
    containPoint: function (point) {
        var axisX = this.getAxis('x');
        var axisY = this.getAxis('y');
        return axisX.contain(axisX.toLocalCoord(point[0]))
            && axisY.contain(axisY.toLocalCoord(point[1]));
    },

    /**
     * If contain data
     * @param {Array.<number>} data
     * @return {boolean}
     */
    containData: function (data) {
        return this.getAxis('x').containData(data[0])
            && this.getAxis('y').containData(data[1]);
    },

    /**
     * @param {Array.<number>} data
     * @param {Array.<number>} out
     * @return {Array.<number>}
     */
    dataToPoint: function (data, reserved, out) {
        var xAxis = this.getAxis('x');
        var yAxis = this.getAxis('y');
        out = out || [];
        out[0] = xAxis.toGlobalCoord(xAxis.dataToCoord(data[0]));
        out[1] = yAxis.toGlobalCoord(yAxis.dataToCoord(data[1]));
        return out;
    },

    /**
     * @param {Array.<number>} data
     * @param {Array.<number>} out
     * @return {Array.<number>}
     */
    clampData: function (data, out) {
        var xScale = this.getAxis('x').scale;
        var yScale = this.getAxis('y').scale;
        var xAxisExtent = xScale.getExtent();
        var yAxisExtent = yScale.getExtent();
        var x = xScale.parse(data[0]);
        var y = yScale.parse(data[1]);
        out = out || [];
        out[0] = Math.min(
            Math.max(Math.min(xAxisExtent[0], xAxisExtent[1]), x),
            Math.max(xAxisExtent[0], xAxisExtent[1])
        );
        out[1] = Math.min(
            Math.max(Math.min(yAxisExtent[0], yAxisExtent[1]), y),
            Math.max(yAxisExtent[0], yAxisExtent[1])
        );

        return out;
    },

    /**
     * @param {Array.<number>} point
     * @param {Array.<number>} out
     * @return {Array.<number>}
     */
    pointToData: function (point, out) {
        var xAxis = this.getAxis('x');
        var yAxis = this.getAxis('y');
        out = out || [];
        out[0] = xAxis.coordToData(xAxis.toLocalCoord(point[0]));
        out[1] = yAxis.coordToData(yAxis.toLocalCoord(point[1]));
        return out;
    },

    /**
     * Get other axis
     * @param {module:echarts/coord/cartesian/Axis2D} axis
     */
    getOtherAxis: function (axis) {
        return this.getAxis(axis.dim === 'x' ? 'y' : 'x');
    },

    /**
     * Get rect area of cartesian.
     * Area will have a contain function to determine if a point is in the coordinate system.
     * @return {BoundingRect}
     */
    getArea: function () {
        var xExtent = this.getAxis('x').getGlobalExtent();
        var yExtent = this.getAxis('y').getGlobalExtent();
        var x = Math.min(xExtent[0], xExtent[1]);
        var y = Math.min(yExtent[0], yExtent[1]);
        var width = Math.max(xExtent[0], xExtent[1]) - x;
        var height = Math.max(yExtent[0], yExtent[1]) - y;

        var rect = new BoundingRect(x, y, width, height);
        return rect;
    }

};

inherits(Cartesian2D, Cartesian);

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

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

    /**
     * Implemented in <module:echarts/coord/cartesian/Grid>.
     * @return {Array.<module:echarts/coord/cartesian/Axis2D>}
     *         If not on zero of other axis, return null/undefined.
     *         If no axes, return an empty array.
     */
    getAxesOnZeroOf: null,

    /**
     * Axis model
     * @param {module:echarts/coord/cartesian/AxisModel}
     */
    model: null,

    isHorizontal: function () {
        var position = this.position;
        return position === 'top' || position === 'bottom';
    },

    /**
     * Each item cooresponds to this.getExtent(), which
     * means globalExtent[0] may greater than globalExtent[1],
     * unless `asc` is input.
     *
     * @param {boolean} [asc]
     * @return {Array.<number>}
     */
    getGlobalExtent: function (asc) {
        var ret = this.getExtent();
        ret[0] = this.toGlobalCoord(ret[0]);
        ret[1] = this.toGlobalCoord(ret[1]);
        asc && ret[0] > ret[1] && ret.reverse();
        return ret;
    },

    getOtherAxis: function () {
        this.grid.getOtherAxis();
    },

    /**
     * @override
     */
    pointToData: function (point, clamp) {
        return this.coordToData(this.toLocalCoord(point[this.dim === 'x' ? 0 : 1]), clamp);
    },

    /**
     * Transform global coord to local coord,
     * i.e. var localCoord = axis.toLocalCoord(80);
     * designate by module:echarts/coord/cartesian/Grid.
     * @type {Function}
     */
    toLocalCoord: null,

    /**
     * Transform global coord to local coord,
     * i.e. var globalCoord = axis.toLocalCoord(40);
     * designate by module:echarts/coord/cartesian/Grid.
     * @type {Function}
     */
    toGlobalCoord: null

};

inherits(Axis2D, Axis);

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var defaultOption = {
    show: true,
    zlevel: 0,
    z: 0,
    // Inverse the axis.
    inverse: false,

    // Axis name displayed.
    name: '',
    // 'start' | 'middle' | 'end'
    nameLocation: 'end',
    // By degree. By default auto rotate by nameLocation.
    nameRotate: null,
    nameTruncate: {
        maxWidth: null,
        ellipsis: '...',
        placeholder: '.'
    },
    // Use global text style by default.
    nameTextStyle: {},
    // The gap between axisName and axisLine.
    nameGap: 15,

    // Default `false` to support tooltip.
    silent: false,
    // Default `false` to avoid legacy user event listener fail.
    triggerEvent: false,

    tooltip: {
        show: false
    },

    axisPointer: {},

    axisLine: {
        show: true,
        onZero: true,
        onZeroAxisIndex: null,
        lineStyle: {
            color: '#333',
            width: 1,
            type: 'solid'
        },
        // The arrow at both ends the the axis.
        symbol: ['none', 'none'],
        symbolSize: [10, 15]
    },
    axisTick: {
        show: true,
        // Whether axisTick is inside the grid or outside the grid.
        inside: false,
        // The length of axisTick.
        length: 5,
        lineStyle: {
            width: 1
        }
    },
    axisLabel: {
        show: true,
        // Whether axisLabel is inside the grid or outside the grid.
        inside: false,
        rotate: 0,
        // true | false | null/undefined (auto)
        showMinLabel: null,
        // true | false | null/undefined (auto)
        showMaxLabel: null,
        margin: 8,
        // formatter: null,
        fontSize: 12
    },
    splitLine: {
        show: true,
        lineStyle: {
            color: ['#ccc'],
            width: 1,
            type: 'solid'
        }
    },
    splitArea: {
        show: false,
        areaStyle: {
            color: ['rgba(250,250,250,0.3)', 'rgba(200,200,200,0.3)']
        }
    }
};

var axisDefault = {};

axisDefault.categoryAxis = merge({
    // The gap at both ends of the axis. For categoryAxis, boolean.
    boundaryGap: true,
    // Set false to faster category collection.
    // Only usefull in the case like: category is
    // ['2012-01-01', '2012-01-02', ...], where the input
    // data has been ensured not duplicate and is large data.
    // null means "auto":
    // if axis.data provided, do not deduplication,
    // else do deduplication.
    deduplication: null,
    // splitArea: {
        // show: false
    // },
    splitLine: {
        show: false
    },
    axisTick: {
        // If tick is align with label when boundaryGap is true
        alignWithLabel: false,
        interval: 'auto'
    },
    axisLabel: {
        interval: 'auto'
    }
}, defaultOption);

axisDefault.valueAxis = merge({
    // The gap at both ends of the axis. For value axis, [GAP, GAP], where
    // `GAP` can be an absolute pixel number (like `35`), or percent (like `'30%'`)
    boundaryGap: [0, 0],

    // TODO
    // min/max: [30, datamin, 60] or [20, datamin] or [datamin, 60]

    // Min value of the axis. can be:
    // + a number
    // + 'dataMin': use the min value in data.
    // + null/undefined: auto decide min value (consider pretty look and boundaryGap).
    // min: null,

    // Max value of the axis. can be:
    // + a number
    // + 'dataMax': use the max value in data.
    // + null/undefined: auto decide max value (consider pretty look and boundaryGap).
    // max: null,

    // Readonly prop, specifies start value of the range when using data zoom.
    // rangeStart: null

    // Readonly prop, specifies end value of the range when using data zoom.
    // rangeEnd: null

    // Optional value can be:
    // + `false`: always include value 0.
    // + `true`: the extent do not consider value 0.
    // scale: false,

    // AxisTick and axisLabel and splitLine are caculated based on splitNumber.
    splitNumber: 5,

    // Interval specifies the span of the ticks is mandatorily.
    // interval: null

    // Specify min interval when auto calculate tick interval.
    // minInterval: null

    // Specify max interval when auto calculate tick interval.
    // maxInterval: null

    minorTick: {
        // Minor tick, not available for cateogry axis.
        show: false,
        // Split number of minor ticks. The value should be in range of (0, 100)
        splitNumber: 5,
        // Lenght of minor tick
        length: 3,

        // Same inside with axisTick

        // Line style
        lineStyle: {
            // Default to be same with axisTick
        }
    },

    minorSplitLine: {
        show: false,

        lineStyle: {
            color: '#eee',
            width: 1
        }
    }
}, defaultOption);

axisDefault.timeAxis = defaults({
    scale: true,
    min: 'dataMin',
    max: 'dataMax'
}, axisDefault.valueAxis);

axisDefault.logAxis = defaults({
    scale: true,
    logBase: 10
}, axisDefault.valueAxis);

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

// 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]
 */
var axisModelCreator = function (axisName, BaseAxisModelClass, axisTypeDefaulter, extraDefaultOption) {

    each$1(AXIS_TYPES, function (axisType) {

        BaseAxisModelClass.extend({

            /**
             * @readOnly
             */
            type: axisName + 'Axis.' + axisType,

            mergeDefaultAndTheme: function (option, ecModel) {
                var layoutMode = this.layoutMode;
                var inputPositionParams = layoutMode
                    ? getLayoutParams(option) : {};

                var themeModel = ecModel.getTheme();
                merge(option, themeModel.get(axisType + 'Axis'));
                merge(option, this.getDefaultOption());

                option.type = axisTypeDefaulter(axisName, option);

                if (layoutMode) {
                    mergeLayoutParam(option, inputPositionParams, layoutMode);
                }
            },

            /**
             * @override
             */
            optionUpdated: function () {
                var thisOption = this.option;
                if (thisOption.type === 'category') {
                    this.__ordinalMeta = OrdinalMeta.createByAxisModel(this);
                }
            },

            /**
             * Should not be called before all of 'getInitailData' finished.
             * Because categories are collected during initializing data.
             */
            getCategories: function (rawData) {
                var option = this.option;
                // FIXME
                // warning if called before all of 'getInitailData' finished.
                if (option.type === 'category') {
                    if (rawData) {
                        return option.data;
                    }
                    return this.__ordinalMeta.categories;
                }
            },

            getOrdinalMeta: function () {
                return this.__ordinalMeta;
            },

            defaultOption: mergeAll(
                [
                    {},
                    axisDefault[axisType + 'Axis'],
                    extraDefaultOption
                ],
                true
            )
        });
    });

    ComponentModel.registerSubTypeDefaulter(
        axisName + 'Axis',
        curry(axisTypeDefaulter, axisName)
    );
};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var AxisModel = ComponentModel.extend({

    type: 'cartesian2dAxis',

    /**
     * @type {module:echarts/coord/cartesian/Axis2D}
     */
    axis: null,

    /**
     * @override
     */
    init: function () {
        AxisModel.superApply(this, 'init', arguments);
        this.resetRange();
    },

    /**
     * @override
     */
    mergeOption: function () {
        AxisModel.superApply(this, 'mergeOption', arguments);
        this.resetRange();
    },

    /**
     * @override
     */
    restoreData: function () {
        AxisModel.superApply(this, 'restoreData', arguments);
        this.resetRange();
    },

    /**
     * @override
     * @return {module:echarts/model/Component}
     */
    getCoordSysModel: function () {
        return this.ecModel.queryComponents({
            mainType: 'grid',
            index: this.option.gridIndex,
            id: this.option.gridId
        })[0];
    }

});

function getAxisType(axisDim, option) {
    // Default axis with data is category axis
    return option.type || (option.data ? 'category' : 'value');
}

merge(AxisModel.prototype, axisModelCommonMixin);

var extraOption = {
    // gridIndex: 0,
    // gridId: '',

    // Offset is for multiple axis on the same position
    offset: 0
};

axisModelCreator('x', AxisModel, getAxisType, extraOption);
axisModelCreator('y', AxisModel, getAxisType, extraOption);

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

// Grid 是在有直角坐标系的时候必须要存在的
// 所以这里也要被 Cartesian2D 依赖

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

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * Grid is a region which contains at most 4 cartesian systems
 *
 * TODO Default cartesian
 */

// Depends on GridModel, AxisModel, which performs preprocess.
/**
 * Check if the axis is used in the specified grid
 * @inner
 */
function isAxisUsedInTheGrid(axisModel, gridModel, ecModel) {
    return axisModel.getCoordSysModel() === gridModel;
}

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, Array.<module:echarts/coord/cartesian/Axis2D>>}
     * @private
     */
    this._axesMap = {};

    /**
     * @type {Array.<module:echarts/coord/cartesian/Axis2D>}
     * @private
     */
    this._axesList = [];

    this._initCartesian(gridModel, ecModel, api);

    this.model = gridModel;
}

var gridProto = Grid.prototype;

gridProto.type = 'grid';

gridProto.axisPointerEnabled = true;

gridProto.getRect = function () {
    return this._rect;
};

gridProto.update = function (ecModel, api) {

    var axesMap = this._axesMap;

    this._updateScale(ecModel, this.model);

    each$1(axesMap.x, function (xAxis) {
        niceScaleExtent(xAxis.scale, xAxis.model);
    });
    each$1(axesMap.y, function (yAxis) {
        niceScaleExtent(yAxis.scale, yAxis.model);
    });

    // Key: axisDim_axisIndex, value: boolean, whether onZero target.
    var onZeroRecords = {};

    each$1(axesMap.x, function (xAxis) {
        fixAxisOnZero(axesMap, 'y', xAxis, onZeroRecords);
    });
    each$1(axesMap.y, function (yAxis) {
        fixAxisOnZero(axesMap, 'x', yAxis, onZeroRecords);
    });

    // Resize again if containLabel is enabled
    // FIXME It may cause getting wrong grid size in data processing stage
    this.resize(this.model, api);
};

function fixAxisOnZero(axesMap, otherAxisDim, axis, onZeroRecords) {

    axis.getAxesOnZeroOf = function () {
        // TODO: onZero of multiple axes.
        return otherAxisOnZeroOf ? [otherAxisOnZeroOf] : [];
    };

    // onZero can not be enabled in these two situations:
    // 1. When any other axis is a category axis.
    // 2. When no axis is cross 0 point.
    var otherAxes = axesMap[otherAxisDim];

    var otherAxisOnZeroOf;
    var axisModel = axis.model;
    var onZero = axisModel.get('axisLine.onZero');
    var onZeroAxisIndex = axisModel.get('axisLine.onZeroAxisIndex');

    if (!onZero) {
        return;
    }

    // If target axis is specified.
    if (onZeroAxisIndex != null) {
        if (canOnZeroToAxis(otherAxes[onZeroAxisIndex])) {
            otherAxisOnZeroOf = otherAxes[onZeroAxisIndex];
        }
    }
    else {
        // Find the first available other axis.
        for (var idx in otherAxes) {
            if (otherAxes.hasOwnProperty(idx)
                && canOnZeroToAxis(otherAxes[idx])
                // Consider that two Y axes on one value axis,
                // if both onZero, the two Y axes overlap.
                && !onZeroRecords[getOnZeroRecordKey(otherAxes[idx])]
            ) {
                otherAxisOnZeroOf = otherAxes[idx];
                break;
            }
        }
    }

    if (otherAxisOnZeroOf) {
        onZeroRecords[getOnZeroRecordKey(otherAxisOnZeroOf)] = true;
    }

    function getOnZeroRecordKey(axis) {
        return axis.dim + '_' + axis.index;
    }
}

function canOnZeroToAxis(axis) {
    return axis && axis.type !== 'category' && axis.type !== 'time' && ifAxisCrossZero(axis);
}

/**
 * Resize the grid
 * @param {module:echarts/coord/cartesian/GridModel} gridModel
 * @param {module:echarts/ExtensionAPI} api
 */
gridProto.resize = function (gridModel, api, ignoreContainLabel) {

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

    this._rect = gridRect;

    var axesList = this._axesList;

    adjustAxes();

    // Minus label size
    if (!ignoreContainLabel && gridModel.get('containLabel')) {
        each$1(axesList, function (axis) {
            if (!axis.model.get('axisLabel.inside')) {
                var labelUnionRect = estimateLabelUnionRect(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$1(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]);
            updateAxisTransform(axis, isHorizontal ? gridRect.x : gridRect.y);
        });
    }
};

/**
 * @param {string} axisType
 * @param {number} [axisIndex]
 */
gridProto.getAxis = function (axisType, axisIndex) {
    var axesMapOnDim = this._axesMap[axisType];
    if (axesMapOnDim != null) {
        if (axisIndex == null) {
            // Find first axis
            for (var name in axesMapOnDim) {
                if (axesMapOnDim.hasOwnProperty(name)) {
                    return axesMapOnDim[name];
                }
            }
        }
        return axesMapOnDim[axisIndex];
    }
};

/**
 * @return {Array.<module:echarts/coord/Axis>}
 */
gridProto.getAxes = function () {
    return this._axesList.slice();
};

/**
 * Usage:
 *      grid.getCartesian(xAxisIndex, yAxisIndex);
 *      grid.getCartesian(xAxisIndex);
 *      grid.getCartesian(null, yAxisIndex);
 *      grid.getCartesian({xAxisIndex: ..., yAxisIndex: ...});
 *
 * @param {number|Object} [xAxisIndex]
 * @param {number} [yAxisIndex]
 */
gridProto.getCartesian = function (xAxisIndex, yAxisIndex) {
    if (xAxisIndex != null && yAxisIndex != null) {
        var key = 'x' + xAxisIndex + 'y' + yAxisIndex;
        return this._coordsMap[key];
    }

    if (isObject$1(xAxisIndex)) {
        yAxisIndex = xAxisIndex.yAxisIndex;
        xAxisIndex = xAxisIndex.xAxisIndex;
    }
    // When only xAxisIndex or yAxisIndex given, find its first cartesian.
    for (var i = 0, coordList = this._coordsList; i < coordList.length; i++) {
        if (coordList[i].getAxis('x').index === xAxisIndex
            || coordList[i].getAxis('y').index === yAxisIndex
        ) {
            return coordList[i];
        }
    }
};

gridProto.getCartesians = function () {
    return this._coordsList.slice();
};

/**
 * @implements
 * see {module:echarts/CoodinateSystem}
 */
gridProto.convertToPixel = function (ecModel, finder, value) {
    var target = this._findConvertTarget(ecModel, finder);

    return target.cartesian
        ? target.cartesian.dataToPoint(value)
        : target.axis
        ? target.axis.toGlobalCoord(target.axis.dataToCoord(value))
        : null;
};

/**
 * @implements
 * see {module:echarts/CoodinateSystem}
 */
gridProto.convertFromPixel = function (ecModel, finder, value) {
    var target = this._findConvertTarget(ecModel, finder);

    return target.cartesian
        ? target.cartesian.pointToData(value)
        : target.axis
        ? target.axis.coordToData(target.axis.toLocalCoord(value))
        : null;
};

/**
 * @inner
 */
gridProto._findConvertTarget = function (ecModel, finder) {
    var seriesModel = finder.seriesModel;
    var xAxisModel = finder.xAxisModel
        || (seriesModel && seriesModel.getReferringComponents('xAxis')[0]);
    var yAxisModel = finder.yAxisModel
        || (seriesModel && seriesModel.getReferringComponents('yAxis')[0]);
    var gridModel = finder.gridModel;
    var coordsList = this._coordsList;
    var cartesian;
    var axis;

    if (seriesModel) {
        cartesian = seriesModel.coordinateSystem;
        indexOf(coordsList, cartesian) < 0 && (cartesian = null);
    }
    else if (xAxisModel && yAxisModel) {
        cartesian = this.getCartesian(xAxisModel.componentIndex, yAxisModel.componentIndex);
    }
    else if (xAxisModel) {
        axis = this.getAxis('x', xAxisModel.componentIndex);
    }
    else if (yAxisModel) {
        axis = this.getAxis('y', yAxisModel.componentIndex);
    }
    // Lowest priority.
    else if (gridModel) {
        var grid = gridModel.coordinateSystem;
        if (grid === this) {
            cartesian = this._coordsList[0];
        }
    }

    return {cartesian: cartesian, axis: axis};
};

/**
 * @implements
 * see {module:echarts/CoodinateSystem}
 */
gridProto.containPoint = function (point) {
    var coord = this._coordsList[0];
    if (coord) {
        return coord.containPoint(point);
    }
};

/**
 * Initialize cartesian coordinate systems
 * @private
 */
gridProto._initCartesian = function (gridModel, ecModel, api) {
    var axisPositionUsed = {
        left: false,
        right: false,
        top: false,
        bottom: false
    };

    var axesMap = {
        x: {},
        y: {}
    };
    var axesCount = {
        x: 0,
        y: 0
    };

    /// Create axis
    ecModel.eachComponent('xAxis', createAxisCreator('x'), this);
    ecModel.eachComponent('yAxis', createAxisCreator('y'), this);

    if (!axesCount.x || !axesCount.y) {
        // Roll back when there no either x or y axis
        this._axesMap = {};
        this._axesList = [];
        return;
    }

    this._axesMap = axesMap;

    /// Create cartesian2d
    each$1(axesMap.x, function (xAxis, xAxisIndex) {
        each$1(axesMap.y, function (yAxis, yAxisIndex) {
            var key = 'x' + xAxisIndex + 'y' + yAxisIndex;
            var cartesian = new Cartesian2D(key);

            cartesian.grid = this;
            cartesian.model = gridModel;

            this._coordsMap[key] = cartesian;
            this._coordsList.push(cartesian);

            cartesian.addAxis(xAxis);
            cartesian.addAxis(yAxis);
        }, this);
    }, this);

    function createAxisCreator(axisType) {
        return function (axisModel, idx) {
            if (!isAxisUsedInTheGrid(axisModel, gridModel, ecModel)) {
                return;
            }

            var axisPosition = axisModel.get('position');
            if (axisType === 'x') {
                // Fix position
                if (axisPosition !== 'top' && axisPosition !== 'bottom') {
                    // Default bottom of X
                    axisPosition = axisPositionUsed.bottom ? 'top' : 'bottom';
                }
            }
            else {
                // Fix position
                if (axisPosition !== 'left' && axisPosition !== 'right') {
                    // Default left of Y
                    axisPosition = axisPositionUsed.left ? 'right' : 'left';
                }
            }
            axisPositionUsed[axisPosition] = true;

            var axis = new Axis2D(
                axisType, createScaleByModel(axisModel),
                [0, 0],
                axisModel.get('type'),
                axisPosition
            );

            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;

            // Inject grid info axis
            axis.grid = this;

            // Index of axis, can be used as key
            axis.index = idx;

            this._axesList.push(axis);

            axesMap[axisType][idx] = axis;
            axesCount[axisType]++;
        };
    }
};

/**
 * Update cartesian properties from series
 * @param  {module:echarts/model/Option} option
 * @private
 */
gridProto._updateScale = function (ecModel, gridModel) {
    // Reset scale
    each$1(this._axesList, function (axis) {
        axis.scale.setExtent(Infinity, -Infinity);
    });
    ecModel.eachSeries(function (seriesModel) {
        if (isCartesian2D(seriesModel)) {
            var axesModels = findAxesModels(seriesModel, ecModel);
            var xAxisModel = axesModels[0];
            var yAxisModel = axesModels[1];

            if (!isAxisUsedInTheGrid(xAxisModel, gridModel, ecModel)
                || !isAxisUsedInTheGrid(yAxisModel, gridModel, ecModel)
            ) {
                return;
            }

            var cartesian = this.getCartesian(
                xAxisModel.componentIndex, yAxisModel.componentIndex
            );
            var data = seriesModel.getData();
            var xAxis = cartesian.getAxis('x');
            var yAxis = cartesian.getAxis('y');

            if (data.type === 'list') {
                unionExtent(data, xAxis, seriesModel);
                unionExtent(data, yAxis, seriesModel);
            }
        }
    }, this);

    function unionExtent(data, axis, seriesModel) {
        each$1(data.mapDimension(axis.dim, true), function (dim) {
            axis.scale.unionExtentFromData(
                // For example, the extent of the orginal dimension
                // is [0.1, 0.5], the extent of the `stackResultDimension`
                // is [7, 9], the final extent should not include [0.1, 0.5].
                data, getStackedDimension(data, dim)
            );
        });
    }
};

/**
 * @param {string} [dim] 'x' or 'y' or 'auto' or null/undefined
 * @return {Object} {baseAxes: [], otherAxes: []}
 */
gridProto.getTooltipAxes = function (dim) {
    var baseAxes = [];
    var otherAxes = [];

    each$1(this.getCartesians(), function (cartesian) {
        var baseAxis = (dim != null && dim !== 'auto')
            ? cartesian.getAxis(dim) : cartesian.getBaseAxis();
        var otherAxis = cartesian.getOtherAxis(baseAxis);
        indexOf(baseAxes, baseAxis) < 0 && baseAxes.push(baseAxis);
        indexOf(otherAxes, otherAxis) < 0 && otherAxes.push(otherAxis);
    });

    return {baseAxes: baseAxes, otherAxes: otherAxes};
};

/**
 * @inner
 */
function updateAxisTransform(axis, coordBase) {
    var axisExtent = axis.getExtent();
    var axisExtentSum = axisExtent[0] + axisExtent[1];

    // Fast transform
    axis.toGlobalCoord = axis.dim === 'x'
        ? function (coord) {
            return coord + coordBase;
        }
        : function (coord) {
            return axisExtentSum - coord + coordBase;
        };
    axis.toLocalCoord = axis.dim === 'x'
        ? function (coord) {
            return coord - coordBase;
        }
        : function (coord) {
            return axisExtentSum - coord + coordBase;
        };
}

var axesTypes = ['xAxis', 'yAxis'];
/**
 * @inner
 */
function findAxesModels(seriesModel, ecModel) {
    return map(axesTypes, function (axisType) {
        var axisModel = seriesModel.getReferringComponents(axisType)[0];

        if (__DEV__) {
            if (!axisModel) {
                throw new Error(axisType + ' "' + retrieve(
                    seriesModel.get(axisType + 'Index'),
                    seriesModel.get(axisType + 'Id'),
                    0
                ) + '" not found');
            }
        }
        return axisModel;
    });
}

/**
 * @inner
 */
function isCartesian2D(seriesModel) {
    return seriesModel.get('coordinateSystem') === 'cartesian2d';
}

Grid.create = function (ecModel, api) {
    var grids = [];
    ecModel.eachComponent('grid', function (gridModel, idx) {
        var grid = new Grid(gridModel, ecModel, api);
        grid.name = 'grid_' + idx;
        // dataSampling requires axis extent, so resize
        // should be performed in create stage.
        grid.resize(gridModel, api, true);

        gridModel.coordinateSystem = grid;

        grids.push(grid);
    });

    // Inject the coordinateSystems into seriesModel
    ecModel.eachSeries(function (seriesModel) {
        if (!isCartesian2D(seriesModel)) {
            return;
        }

        var axesModels = findAxesModels(seriesModel, ecModel);
        var xAxisModel = axesModels[0];
        var yAxisModel = axesModels[1];

        var gridModel = xAxisModel.getCoordSysModel();

        if (__DEV__) {
            if (!gridModel) {
                throw new Error(
                    'Grid "' + retrieve(
                        xAxisModel.get('gridIndex'),
                        xAxisModel.get('gridId'),
                        0
                    ) + '" not found'
                );
            }
            if (xAxisModel.getCoordSysModel() !== yAxisModel.getCoordSysModel()) {
                throw new Error('xAxis and yAxis must use the same grid');
            }
        }

        var grid = gridModel.coordinateSystem;

        seriesModel.coordinateSystem = grid.getCartesian(
            xAxisModel.componentIndex, yAxisModel.componentIndex
        );
    });

    return grids;
};

// For deciding which dimensions to use when creating list data
Grid.dimensions = Grid.prototype.dimensions = Cartesian2D.prototype.dimensions;

CoordinateSystemManager.register('cartesian2d', Grid);

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var PI$2 = 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' or 'center'.
 * @param {number} [opt.tickDirection=1] 1 or -1
 * @param {number} [opt.labelDirection=1] 1 or -1
 * @param {number} [opt.labelOffset=0] Usefull when onZero.
 * @param {string} [opt.axisLabelShow] default get from axisModel.
 * @param {string} [opt.axisName] default get from axisModel.
 * @param {number} [opt.axisNameAvailableWidth]
 * @param {number} [opt.labelRotate] by degree, default get from axisModel.
 * @param {number} [opt.strokeContainThreshold] Default label interval when label
 * @param {number} [opt.nameTruncateMaxWidth]
 */
var AxisBuilder = function (axisModel, opt) {

    /**
     * @readOnly
     */
    this.opt = opt;

    /**
     * @readOnly
     */
    this.axisModel = axisModel;

    // Default value
    defaults(
        opt,
        {
            labelOffset: 0,
            nameDirection: 1,
            tickDirection: 1,
            labelDirection: 1,
            silent: true
        }
    );

    /**
     * @readOnly
     */
    this.group = new Group();

    // FIXME Not use a seperate text group?
    var dumbGroup = new Group({
        position: opt.position.slice(),
        rotation: opt.rotation
    });

    // this.group.add(dumbGroup);
    // this._dumbGroup = dumbGroup;

    dumbGroup.updateTransform();
    this._transform = dumbGroup.transform;

    this._dumbGroup = dumbGroup;
};

AxisBuilder.prototype = {

    constructor: AxisBuilder,

    hasBuilder: function (name) {
        return !!builders[name];
    },

    add: function (name) {
        builders[name].call(this);
    },

    getGroup: function () {
        return this.group;
    }

};

var builders = {

    /**
     * @private
     */
    axisLine: function () {
        var opt = this.opt;
        var axisModel = this.axisModel;

        if (!axisModel.get('axisLine.show')) {
            return;
        }

        var extent = this.axisModel.axis.getExtent();

        var matrix = this._transform;
        var pt1 = [extent[0], 0];
        var pt2 = [extent[1], 0];
        if (matrix) {
            applyTransform(pt1, pt1, matrix);
            applyTransform(pt2, pt2, matrix);
        }

        var lineStyle = extend(
            {
                lineCap: 'round'
            },
            axisModel.getModel('axisLine.lineStyle').getLineStyle()
        );

        this.group.add(new Line({
            // Id for animation
            anid: 'line',
            subPixelOptimize: true,
            shape: {
                x1: pt1[0],
                y1: pt1[1],
                x2: pt2[0],
                y2: pt2[1]
            },
            style: lineStyle,
            strokeContainThreshold: opt.strokeContainThreshold || 5,
            silent: true,
            z2: 1
        }));

        var arrows = axisModel.get('axisLine.symbol');
        var arrowSize = axisModel.get('axisLine.symbolSize');

        var arrowOffset = axisModel.get('axisLine.symbolOffset') || 0;
        if (typeof arrowOffset === 'number') {
            arrowOffset = [arrowOffset, arrowOffset];
        }

        if (arrows != null) {
            if (typeof arrows === 'string') {
                // Use the same arrow for start and end point
                arrows = [arrows, arrows];
            }
            if (typeof arrowSize === 'string'
                || typeof arrowSize === 'number'
            ) {
                // Use the same size for width and height
                arrowSize = [arrowSize, arrowSize];
            }

            var symbolWidth = arrowSize[0];
            var symbolHeight = arrowSize[1];

            each$1([{
                rotate: opt.rotation + Math.PI / 2,
                offset: arrowOffset[0],
                r: 0
            }, {
                rotate: opt.rotation - Math.PI / 2,
                offset: arrowOffset[1],
                r: Math.sqrt((pt1[0] - pt2[0]) * (pt1[0] - pt2[0])
                    + (pt1[1] - pt2[1]) * (pt1[1] - pt2[1]))
            }], function (point, index) {
                if (arrows[index] !== 'none' && arrows[index] != null) {
                    var symbol = createSymbol(
                        arrows[index],
                        -symbolWidth / 2,
                        -symbolHeight / 2,
                        symbolWidth,
                        symbolHeight,
                        lineStyle.stroke,
                        true
                    );

                    // Calculate arrow position with offset
                    var r = point.r + point.offset;
                    var pos = [
                        pt1[0] + r * Math.cos(opt.rotation),
                        pt1[1] - r * Math.sin(opt.rotation)
                    ];

                    symbol.attr({
                        rotation: point.rotate,
                        position: pos,
                        silent: true,
                        z2: 11
                    });
                    this.group.add(symbol);
                }
            }, this);
        }
    },

    /**
     * @private
     */
    axisTickLabel: function () {
        var axisModel = this.axisModel;
        var opt = this.opt;

        var ticksEls = buildAxisMajorTicks(this, axisModel, opt);
        var labelEls = buildAxisLabel(this, axisModel, opt);

        fixMinMaxLabelShow(axisModel, labelEls, ticksEls);

        buildAxisMinorTicks(this, axisModel, opt);
    },

    /**
     * @private
     */
    axisName: function () {
        var opt = this.opt;
        var axisModel = this.axisModel;
        var name = retrieve(opt.axisName, axisModel.get('name'));

        if (!name) {
            return;
        }

        var nameLocation = axisModel.get('nameLocation');
        var nameDirection = opt.nameDirection;
        var textStyleModel = axisModel.getModel('nameTextStyle');
        var gap = axisModel.get('nameGap') || 0;

        var extent = this.axisModel.axis.getExtent();
        var gapSignal = extent[0] > extent[1] ? -1 : 1;
        var pos = [
            nameLocation === 'start'
                ? extent[0] - gapSignal * gap
                : nameLocation === 'end'
                ? extent[1] + gapSignal * gap
                : (extent[0] + extent[1]) / 2, // 'middle'
            // Reuse labelOffset.
            isNameLocationCenter(nameLocation) ? opt.labelOffset + nameDirection * gap : 0
        ];

        var labelLayout;

        var nameRotation = axisModel.get('nameRotate');
        if (nameRotation != null) {
            nameRotation = nameRotation * PI$2 / 180; // To radian.
        }

        var axisNameAvailableWidth;

        if (isNameLocationCenter(nameLocation)) {
            labelLayout = innerTextLayout(
                opt.rotation,
                nameRotation != null ? nameRotation : opt.rotation, // Adapt to axis.
                nameDirection
            );
        }
        else {
            labelLayout = endTextLayout(
                opt, nameLocation, nameRotation || 0, extent
            );

            axisNameAvailableWidth = opt.axisNameAvailableWidth;
            if (axisNameAvailableWidth != null) {
                axisNameAvailableWidth = Math.abs(
                    axisNameAvailableWidth / Math.sin(labelLayout.rotation)
                );
                !isFinite(axisNameAvailableWidth) && (axisNameAvailableWidth = null);
            }
        }

        var textFont = textStyleModel.getFont();

        var truncateOpt = axisModel.get('nameTruncate', true) || {};
        var ellipsis = truncateOpt.ellipsis;
        var maxWidth = retrieve(
            opt.nameTruncateMaxWidth, truncateOpt.maxWidth, axisNameAvailableWidth
        );
        // FIXME
        // truncate rich text? (consider performance)
        var truncatedText = (ellipsis != null && maxWidth != null)
            ? truncateText$1(
                name, maxWidth, textFont, ellipsis,
                {minChar: 2, placeholder: truncateOpt.placeholder}
            )
            : name;

        var tooltipOpt = axisModel.get('tooltip', true);

        var mainType = axisModel.mainType;
        var formatterParams = {
            componentType: mainType,
            name: name,
            $vars: ['name']
        };
        formatterParams[mainType + 'Index'] = axisModel.componentIndex;

        var textEl = new Text({
            // Id for animation
            anid: 'name',

            __fullText: name,
            __truncatedText: truncatedText,

            position: pos,
            rotation: labelLayout.rotation,
            silent: isLabelSilent(axisModel),
            z2: 1,
            tooltip: (tooltipOpt && tooltipOpt.show)
                ? extend({
                    content: name,
                    formatter: function () {
                        return name;
                    },
                    formatterParams: formatterParams
                }, tooltipOpt)
                : null
        });

        setTextStyle(textEl.style, textStyleModel, {
            text: truncatedText,
            textFont: textFont,
            textFill: textStyleModel.getTextColor()
                || axisModel.get('axisLine.lineStyle.color'),
            textAlign: textStyleModel.get('align')
                || labelLayout.textAlign,
            textVerticalAlign: textStyleModel.get('verticalAlign')
                || labelLayout.textVerticalAlign
        });

        if (axisModel.get('triggerEvent')) {
            textEl.eventData = makeAxisEventDataBase(axisModel);
            textEl.eventData.targetType = 'axisName';
            textEl.eventData.name = name;
        }

        // FIXME
        this._dumbGroup.add(textEl);
        textEl.updateTransform();

        this.group.add(textEl);

        textEl.decomposeTransform();
    }

};

var makeAxisEventDataBase = AxisBuilder.makeAxisEventDataBase = function (axisModel) {
    var eventData = {
        componentType: axisModel.mainType,
        componentIndex: axisModel.componentIndex
    };
    eventData[axisModel.mainType + 'Index'] = axisModel.componentIndex;
    return eventData;
};

/**
 * @public
 * @static
 * @param {Object} opt
 * @param {number} axisRotation in radian
 * @param {number} textRotation in radian
 * @param {number} direction
 * @return {Object} {
 *  rotation, // according to axis
 *  textAlign,
 *  textVerticalAlign
 * }
 */
var innerTextLayout = AxisBuilder.innerTextLayout = function (axisRotation, textRotation, direction) {
    var rotationDiff = remRadian(textRotation - axisRotation);
    var textAlign;
    var textVerticalAlign;

    if (isRadianAroundZero(rotationDiff)) { // Label is parallel with axis line.
        textVerticalAlign = direction > 0 ? 'top' : 'bottom';
        textAlign = 'center';
    }
    else if (isRadianAroundZero(rotationDiff - PI$2)) { // Label is inverse parallel with axis line.
        textVerticalAlign = direction > 0 ? 'bottom' : 'top';
        textAlign = 'center';
    }
    else {
        textVerticalAlign = 'middle';

        if (rotationDiff > 0 && rotationDiff < PI$2) {
            textAlign = direction > 0 ? 'right' : 'left';
        }
        else {
            textAlign = direction > 0 ? 'left' : 'right';
        }
    }

    return {
        rotation: rotationDiff,
        textAlign: textAlign,
        textVerticalAlign: textVerticalAlign
    };
};

function endTextLayout(opt, textPosition, textRotate, extent) {
    var rotationDiff = remRadian(textRotate - opt.rotation);
    var textAlign;
    var textVerticalAlign;
    var inverse = extent[0] > extent[1];
    var onLeft = (textPosition === 'start' && !inverse)
        || (textPosition !== 'start' && inverse);

    if (isRadianAroundZero(rotationDiff - PI$2 / 2)) {
        textVerticalAlign = onLeft ? 'bottom' : 'top';
        textAlign = 'center';
    }
    else if (isRadianAroundZero(rotationDiff - PI$2 * 1.5)) {
        textVerticalAlign = onLeft ? 'top' : 'bottom';
        textAlign = 'center';
    }
    else {
        textVerticalAlign = 'middle';
        if (rotationDiff < PI$2 * 1.5 && rotationDiff > PI$2 / 2) {
            textAlign = onLeft ? 'left' : 'right';
        }
        else {
            textAlign = onLeft ? 'right' : 'left';
        }
    }

    return {
        rotation: rotationDiff,
        textAlign: textAlign,
        textVerticalAlign: textVerticalAlign
    };
}

var isLabelSilent = AxisBuilder.isLabelSilent = function (axisModel) {
    var tooltipOpt = axisModel.get('tooltip');
    return axisModel.get('silent')
        // Consider mouse cursor, add these restrictions.
        || !(
            axisModel.get('triggerEvent') || (tooltipOpt && tooltipOpt.show)
        );
};

function fixMinMaxLabelShow(axisModel, labelEls, tickEls) {
    if (shouldShowAllLabels(axisModel.axis)) {
        return;
    }

    // If min or max are user set, we need to check
    // If the tick on min(max) are overlap on their neighbour tick
    // If they are overlapped, we need to hide the min(max) tick label
    var showMinLabel = axisModel.get('axisLabel.showMinLabel');
    var showMaxLabel = axisModel.get('axisLabel.showMaxLabel');

    // FIXME
    // Have not consider onBand yet, where tick els is more than label els.

    labelEls = labelEls || [];
    tickEls = tickEls || [];

    var firstLabel = labelEls[0];
    var nextLabel = labelEls[1];
    var lastLabel = labelEls[labelEls.length - 1];
    var prevLabel = labelEls[labelEls.length - 2];

    var firstTick = tickEls[0];
    var nextTick = tickEls[1];
    var lastTick = tickEls[tickEls.length - 1];
    var prevTick = tickEls[tickEls.length - 2];

    if (showMinLabel === false) {
        ignoreEl(firstLabel);
        ignoreEl(firstTick);
    }
    else if (isTwoLabelOverlapped(firstLabel, nextLabel)) {
        if (showMinLabel) {
            ignoreEl(nextLabel);
            ignoreEl(nextTick);
        }
        else {
            ignoreEl(firstLabel);
            ignoreEl(firstTick);
        }
    }

    if (showMaxLabel === false) {
        ignoreEl(lastLabel);
        ignoreEl(lastTick);
    }
    else if (isTwoLabelOverlapped(prevLabel, lastLabel)) {
        if (showMaxLabel) {
            ignoreEl(prevLabel);
            ignoreEl(prevTick);
        }
        else {
            ignoreEl(lastLabel);
            ignoreEl(lastTick);
        }
    }
}

function ignoreEl(el) {
    el && (el.ignore = true);
}

function isTwoLabelOverlapped(current, next, labelLayout) {
    // current and next has the same rotation.
    var firstRect = current && current.getBoundingRect().clone();
    var nextRect = next && next.getBoundingRect().clone();

    if (!firstRect || !nextRect) {
        return;
    }

    // When checking intersect of two rotated labels, we use mRotationBack
    // to avoid that boundingRect is enlarge when using `boundingRect.applyTransform`.
    var mRotationBack = identity([]);
    rotate(mRotationBack, mRotationBack, -current.rotation);

    firstRect.applyTransform(mul$1([], mRotationBack, current.getLocalTransform()));
    nextRect.applyTransform(mul$1([], mRotationBack, next.getLocalTransform()));

    return firstRect.intersect(nextRect);
}

function isNameLocationCenter(nameLocation) {
    return nameLocation === 'middle' || nameLocation === 'center';
}


function createTicks(ticksCoords, tickTransform, tickEndCoord, tickLineStyle, aniid) {
    var tickEls = [];
    var pt1 = [];
    var pt2 = [];
    for (var i = 0; i < ticksCoords.length; i++) {
        var tickCoord = ticksCoords[i].coord;

        pt1[0] = tickCoord;
        pt1[1] = 0;
        pt2[0] = tickCoord;
        pt2[1] = tickEndCoord;

        if (tickTransform) {
            applyTransform(pt1, pt1, tickTransform);
            applyTransform(pt2, pt2, tickTransform);
        }
        // Tick line, Not use group transform to have better line draw
        var tickEl = new Line({
            // Id for animation
            anid: aniid + '_' + ticksCoords[i].tickValue,
            subPixelOptimize: true,
            shape: {
                x1: pt1[0],
                y1: pt1[1],
                x2: pt2[0],
                y2: pt2[1]
            },
            style: tickLineStyle,
            z2: 2,
            silent: true
        });
        tickEls.push(tickEl);
    }
    return tickEls;
}

function buildAxisMajorTicks(axisBuilder, axisModel, opt) {
    var axis = axisModel.axis;

    var tickModel = axisModel.getModel('axisTick');

    if (!tickModel.get('show') || axis.scale.isBlank()) {
        return;
    }

    var lineStyleModel = tickModel.getModel('lineStyle');
    var tickEndCoord = opt.tickDirection * tickModel.get('length');

    var ticksCoords = axis.getTicksCoords();

    var ticksEls = createTicks(ticksCoords, axisBuilder._transform, tickEndCoord, defaults(
        lineStyleModel.getLineStyle(),
        {
            stroke: axisModel.get('axisLine.lineStyle.color')
        }
    ), 'ticks');

    for (var i = 0; i < ticksEls.length; i++) {
        axisBuilder.group.add(ticksEls[i]);
    }

    return ticksEls;
}

function buildAxisMinorTicks(axisBuilder, axisModel, opt) {
    var axis = axisModel.axis;

    var minorTickModel = axisModel.getModel('minorTick');

    if (!minorTickModel.get('show') || axis.scale.isBlank()) {
        return;
    }

    var minorTicksCoords = axis.getMinorTicksCoords();
    if (!minorTicksCoords.length) {
        return;
    }

    var lineStyleModel = minorTickModel.getModel('lineStyle');
    var tickEndCoord = opt.tickDirection * minorTickModel.get('length');

    var minorTickLineStyle = defaults(
        lineStyleModel.getLineStyle(),
        defaults(
            axisModel.getModel('axisTick').getLineStyle(),
            {
                stroke: axisModel.get('axisLine.lineStyle.color')
            }
        )
    );

    for (var i = 0; i < minorTicksCoords.length; i++) {
        var minorTicksEls = createTicks(
            minorTicksCoords[i], axisBuilder._transform, tickEndCoord, minorTickLineStyle, 'minorticks_' + i
        );
        for (var k = 0; k < minorTicksEls.length; k++) {
            axisBuilder.group.add(minorTicksEls[k]);
        }
    }
}

function buildAxisLabel(axisBuilder, axisModel, opt) {
    var axis = axisModel.axis;
    var show = retrieve(opt.axisLabelShow, axisModel.get('axisLabel.show'));

    if (!show || axis.scale.isBlank()) {
        return;
    }

    var labelModel = axisModel.getModel('axisLabel');
    var labelMargin = labelModel.get('margin');
    var labels = axis.getViewLabels();

    // Special label rotate.
    var labelRotation = (
        retrieve(opt.labelRotate, labelModel.get('rotate')) || 0
    ) * PI$2 / 180;

    var labelLayout = innerTextLayout(opt.rotation, labelRotation, opt.labelDirection);
    var rawCategoryData = axisModel.getCategories && axisModel.getCategories(true);

    var labelEls = [];
    var silent = isLabelSilent(axisModel);
    var triggerEvent = axisModel.get('triggerEvent');

    each$1(labels, function (labelItem, index) {
        var tickValue = labelItem.tickValue;
        var formattedLabel = labelItem.formattedLabel;
        var rawLabel = labelItem.rawLabel;

        var itemLabelModel = labelModel;
        if (rawCategoryData && rawCategoryData[tickValue] && rawCategoryData[tickValue].textStyle) {
            itemLabelModel = new Model(
                rawCategoryData[tickValue].textStyle, labelModel, axisModel.ecModel
            );
        }

        var textColor = itemLabelModel.getTextColor()
            || axisModel.get('axisLine.lineStyle.color');

        var tickCoord = axis.dataToCoord(tickValue);
        var pos = [
            tickCoord,
            opt.labelOffset + opt.labelDirection * labelMargin
        ];

        var textEl = new Text({
            // Id for animation
            anid: 'label_' + tickValue,
            position: pos,
            rotation: labelLayout.rotation,
            silent: silent,
            z2: 10
        });

        setTextStyle(textEl.style, itemLabelModel, {
            text: formattedLabel,
            textAlign: itemLabelModel.getShallow('align', true)
                || labelLayout.textAlign,
            textVerticalAlign: itemLabelModel.getShallow('verticalAlign', true)
                || itemLabelModel.getShallow('baseline', true)
                || labelLayout.textVerticalAlign,
            textFill: typeof textColor === 'function'
                ? textColor(
                    // (1) In category axis with data zoom, tick is not the original
                    // index of axis.data. So tick should not be exposed to user
                    // in category axis.
                    // (2) Compatible with previous version, which always use formatted label as
                    // input. But in interval scale the formatted label is like '223,445', which
                    // maked user repalce ','. So we modify it to return original val but remain
                    // it as 'string' to avoid error in replacing.
                    axis.type === 'category'
                        ? rawLabel
                        : axis.type === 'value'
                        ? tickValue + ''
                        : tickValue,
                    index
                )
                : textColor
        });

        // Pack data for mouse event
        if (triggerEvent) {
            textEl.eventData = makeAxisEventDataBase(axisModel);
            textEl.eventData.targetType = 'axisLabel';
            textEl.eventData.value = rawLabel;
        }

        // FIXME
        axisBuilder._dumbGroup.add(textEl);
        textEl.updateTransform();

        labelEls.push(textEl);
        axisBuilder.group.add(textEl);

        textEl.decomposeTransform();

    });

    return labelEls;
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var each$6 = each$1;
var curry$1 = curry;

// Build axisPointerModel, mergin tooltip.axisPointer model for each axis.
// allAxesInfo should be updated when setOption performed.
function collect(ecModel, api) {
    var result = {
        /**
         * key: makeKey(axis.model)
         * value: {
         *      axis,
         *      coordSys,
         *      axisPointerModel,
         *      triggerTooltip,
         *      involveSeries,
         *      snap,
         *      seriesModels,
         *      seriesDataCount
         * }
         */
        axesInfo: {},
        seriesInvolved: false,
        /**
         * key: makeKey(coordSys.model)
         * value: Object: key makeKey(axis.model), value: axisInfo
         */
        coordSysAxesInfo: {},
        coordSysMap: {}
    };

    collectAxesInfo(result, ecModel, api);

    // Check seriesInvolved for performance, in case too many series in some chart.
    result.seriesInvolved && collectSeriesInfo(result, ecModel);

    return result;
}

function collectAxesInfo(result, ecModel, api) {
    var globalTooltipModel = ecModel.getComponent('tooltip');
    var globalAxisPointerModel = ecModel.getComponent('axisPointer');
    // links can only be set on global.
    var linksOption = globalAxisPointerModel.get('link', true) || [];
    var linkGroups = [];

    // Collect axes info.
    each$6(api.getCoordinateSystems(), function (coordSys) {
        // Some coordinate system do not support axes, like geo.
        if (!coordSys.axisPointerEnabled) {
            return;
        }

        var coordSysKey = makeKey(coordSys.model);
        var axesInfoInCoordSys = result.coordSysAxesInfo[coordSysKey] = {};
        result.coordSysMap[coordSysKey] = coordSys;

        // Set tooltip (like 'cross') is a convienent way to show axisPointer
        // for user. So we enable seting tooltip on coordSys model.
        var coordSysModel = coordSys.model;
        var baseTooltipModel = coordSysModel.getModel('tooltip', globalTooltipModel);

        each$6(coordSys.getAxes(), curry$1(saveTooltipAxisInfo, false, null));

        // If axis tooltip used, choose tooltip axis for each coordSys.
        // Notice this case: coordSys is `grid` but not `cartesian2D` here.
        if (coordSys.getTooltipAxes
            && globalTooltipModel
            // If tooltip.showContent is set as false, tooltip will not
            // show but axisPointer will show as normal.
            && baseTooltipModel.get('show')
        ) {
            // Compatible with previous logic. But series.tooltip.trigger: 'axis'
            // or series.data[n].tooltip.trigger: 'axis' are not support any more.
            var triggerAxis = baseTooltipModel.get('trigger') === 'axis';
            var cross = baseTooltipModel.get('axisPointer.type') === 'cross';
            var tooltipAxes = coordSys.getTooltipAxes(baseTooltipModel.get('axisPointer.axis'));
            if (triggerAxis || cross) {
                each$6(tooltipAxes.baseAxes, curry$1(
                    saveTooltipAxisInfo, cross ? 'cross' : true, triggerAxis
                ));
            }
            if (cross) {
                each$6(tooltipAxes.otherAxes, curry$1(saveTooltipAxisInfo, 'cross', false));
            }
        }

        // fromTooltip: true | false | 'cross'
        // triggerTooltip: true | false | null
        function saveTooltipAxisInfo(fromTooltip, triggerTooltip, axis) {
            var axisPointerModel = axis.model.getModel('axisPointer', globalAxisPointerModel);

            var axisPointerShow = axisPointerModel.get('show');
            if (!axisPointerShow || (
                axisPointerShow === 'auto'
                && !fromTooltip
                && !isHandleTrigger(axisPointerModel)
            )) {
                return;
            }

            if (triggerTooltip == null) {
                triggerTooltip = axisPointerModel.get('triggerTooltip');
            }

            axisPointerModel = fromTooltip
                ? makeAxisPointerModel(
                    axis, baseTooltipModel, globalAxisPointerModel, ecModel,
                    fromTooltip, triggerTooltip
                )
                : axisPointerModel;

            var snap = axisPointerModel.get('snap');
            var key = makeKey(axis.model);
            var involveSeries = triggerTooltip || snap || axis.type === 'category';

            // If result.axesInfo[key] exist, override it (tooltip has higher priority).
            var axisInfo = result.axesInfo[key] = {
                key: key,
                axis: axis,
                coordSys: coordSys,
                axisPointerModel: axisPointerModel,
                triggerTooltip: triggerTooltip,
                involveSeries: involveSeries,
                snap: snap,
                useHandle: isHandleTrigger(axisPointerModel),
                seriesModels: []
            };
            axesInfoInCoordSys[key] = axisInfo;
            result.seriesInvolved |= involveSeries;

            var groupIndex = getLinkGroupIndex(linksOption, axis);
            if (groupIndex != null) {
                var linkGroup = linkGroups[groupIndex] || (linkGroups[groupIndex] = {axesInfo: {}});
                linkGroup.axesInfo[key] = axisInfo;
                linkGroup.mapper = linksOption[groupIndex].mapper;
                axisInfo.linkGroup = linkGroup;
            }
        }
    });
}

function makeAxisPointerModel(
    axis, baseTooltipModel, globalAxisPointerModel, ecModel, fromTooltip, triggerTooltip
) {
    var tooltipAxisPointerModel = baseTooltipModel.getModel('axisPointer');
    var volatileOption = {};

    each$6(
        [
            'type', 'snap', 'lineStyle', 'shadowStyle', 'label',
            'animation', 'animationDurationUpdate', 'animationEasingUpdate', 'z'
        ],
        function (field) {
            volatileOption[field] = clone(tooltipAxisPointerModel.get(field));
        }
    );

    // category axis do not auto snap, otherwise some tick that do not
    // has value can not be hovered. value/time/log axis default snap if
    // triggered from tooltip and trigger tooltip.
    volatileOption.snap = axis.type !== 'category' && !!triggerTooltip;

    // Compatibel with previous behavior, tooltip axis do not show label by default.
    // Only these properties can be overrided from tooltip to axisPointer.
    if (tooltipAxisPointerModel.get('type') === 'cross') {
        volatileOption.type = 'line';
    }
    var labelOption = volatileOption.label || (volatileOption.label = {});
    // Follow the convention, do not show label when triggered by tooltip by default.
    labelOption.show == null && (labelOption.show = false);

    if (fromTooltip === 'cross') {
        // When 'cross', both axes show labels.
        var tooltipAxisPointerLabelShow = tooltipAxisPointerModel.get('label.show');
        labelOption.show = tooltipAxisPointerLabelShow != null ? tooltipAxisPointerLabelShow : true;
        // If triggerTooltip, this is a base axis, which should better not use cross style
        // (cross style is dashed by default)
        if (!triggerTooltip) {
            var crossStyle = volatileOption.lineStyle = tooltipAxisPointerModel.get('crossStyle');
            crossStyle && defaults(labelOption, crossStyle.textStyle);
        }
    }

    return axis.model.getModel(
        'axisPointer',
        new Model(volatileOption, globalAxisPointerModel, ecModel)
    );
}

function collectSeriesInfo(result, ecModel) {
    // Prepare data for axis trigger
    ecModel.eachSeries(function (seriesModel) {

        // Notice this case: this coordSys is `cartesian2D` but not `grid`.
        var coordSys = seriesModel.coordinateSystem;
        var seriesTooltipTrigger = seriesModel.get('tooltip.trigger', true);
        var seriesTooltipShow = seriesModel.get('tooltip.show', true);
        if (!coordSys
            || seriesTooltipTrigger === 'none'
            || seriesTooltipTrigger === false
            || seriesTooltipTrigger === 'item'
            || seriesTooltipShow === false
            || seriesModel.get('axisPointer.show', true) === false
        ) {
            return;
        }

        each$6(result.coordSysAxesInfo[makeKey(coordSys.model)], function (axisInfo) {
            var axis = axisInfo.axis;
            if (coordSys.getAxis(axis.dim) === axis) {
                axisInfo.seriesModels.push(seriesModel);
                axisInfo.seriesDataCount == null && (axisInfo.seriesDataCount = 0);
                axisInfo.seriesDataCount += seriesModel.getData().count();
            }
        });

    }, this);
}

/**
 * For example:
 * {
 *     axisPointer: {
 *         links: [{
 *             xAxisIndex: [2, 4],
 *             yAxisIndex: 'all'
 *         }, {
 *             xAxisId: ['a5', 'a7'],
 *             xAxisName: 'xxx'
 *         }]
 *     }
 * }
 */
function getLinkGroupIndex(linksOption, axis) {
    var axisModel = axis.model;
    var dim = axis.dim;
    for (var i = 0; i < linksOption.length; i++) {
        var linkOption = linksOption[i] || {};
        if (checkPropInLink(linkOption[dim + 'AxisId'], axisModel.id)
            || checkPropInLink(linkOption[dim + 'AxisIndex'], axisModel.componentIndex)
            || checkPropInLink(linkOption[dim + 'AxisName'], axisModel.name)
        ) {
            return i;
        }
    }
}

function checkPropInLink(linkPropValue, axisPropValue) {
    return linkPropValue === 'all'
        || (isArray(linkPropValue) && indexOf(linkPropValue, axisPropValue) >= 0)
        || linkPropValue === axisPropValue;
}

function fixValue(axisModel) {
    var axisInfo = getAxisInfo(axisModel);
    if (!axisInfo) {
        return;
    }

    var axisPointerModel = axisInfo.axisPointerModel;
    var scale = axisInfo.axis.scale;
    var option = axisPointerModel.option;
    var status = axisPointerModel.get('status');
    var value = axisPointerModel.get('value');

    // Parse init value for category and time axis.
    if (value != null) {
        value = scale.parse(value);
    }

    var useHandle = isHandleTrigger(axisPointerModel);
    // If `handle` used, `axisPointer` will always be displayed, so value
    // and status should be initialized.
    if (status == null) {
        option.status = useHandle ? 'show' : 'hide';
    }

    var extent = scale.getExtent().slice();
    extent[0] > extent[1] && extent.reverse();

    if (// Pick a value on axis when initializing.
        value == null
        // If both `handle` and `dataZoom` are used, value may be out of axis extent,
        // where we should re-pick a value to keep `handle` displaying normally.
        || value > extent[1]
    ) {
        // Make handle displayed on the end of the axis when init, which looks better.
        value = extent[1];
    }
    if (value < extent[0]) {
        value = extent[0];
    }

    option.value = value;

    if (useHandle) {
        option.status = axisInfo.axis.scale.isBlank() ? 'hide' : 'show';
    }
}

function getAxisInfo(axisModel) {
    var coordSysAxesInfo = (axisModel.ecModel.getComponent('axisPointer') || {}).coordSysAxesInfo;
    return coordSysAxesInfo && coordSysAxesInfo.axesInfo[makeKey(axisModel)];
}

function getAxisPointerModel(axisModel) {
    var axisInfo = getAxisInfo(axisModel);
    return axisInfo && axisInfo.axisPointerModel;
}

function isHandleTrigger(axisPointerModel) {
    return !!axisPointerModel.get('handle.show');
}

/**
 * @param {module:echarts/model/Model} model
 * @return {string} unique key
 */
function makeKey(model) {
    return model.type + '||' + model.id;
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * Base class of AxisView.
 */
var AxisView = extendComponentView({

    type: 'axis',

    /**
     * @private
     */
    _axisPointer: null,

    /**
     * @protected
     * @type {string}
     */
    axisPointerClass: null,

    /**
     * @override
     */
    render: function (axisModel, ecModel, api, payload) {
        // FIXME
        // This process should proformed after coordinate systems updated
        // (axis scale updated), and should be performed each time update.
        // So put it here temporarily, although it is not appropriate to
        // put a model-writing procedure in `view`.
        this.axisPointerClass && fixValue(axisModel);

        AxisView.superApply(this, 'render', arguments);

        updateAxisPointer(this, axisModel, ecModel, api, payload, true);
    },

    /**
     * Action handler.
     * @public
     * @param {module:echarts/coord/cartesian/AxisModel} axisModel
     * @param {module:echarts/model/Global} ecModel
     * @param {module:echarts/ExtensionAPI} api
     * @param {Object} payload
     */
    updateAxisPointer: function (axisModel, ecModel, api, payload, force) {
        updateAxisPointer(this, axisModel, ecModel, api, payload, false);
    },

    /**
     * @override
     */
    remove: function (ecModel, api) {
        var axisPointer = this._axisPointer;
        axisPointer && axisPointer.remove(api);
        AxisView.superApply(this, 'remove', arguments);
    },

    /**
     * @override
     */
    dispose: function (ecModel, api) {
        disposeAxisPointer(this, api);
        AxisView.superApply(this, 'dispose', arguments);
    }

});

function updateAxisPointer(axisView, axisModel, ecModel, api, payload, forceRender) {
    var Clazz = AxisView.getAxisPointerClass(axisView.axisPointerClass);
    if (!Clazz) {
        return;
    }
    var axisPointerModel = getAxisPointerModel(axisModel);
    axisPointerModel
        ? (axisView._axisPointer || (axisView._axisPointer = new Clazz()))
            .render(axisModel, axisPointerModel, api, forceRender)
        : disposeAxisPointer(axisView, api);
}

function disposeAxisPointer(axisView, ecModel, api) {
    var axisPointer = axisView._axisPointer;
    axisPointer && axisPointer.dispose(ecModel, api);
    axisView._axisPointer = null;
}

var axisPointerClazz = [];

AxisView.registerAxisPointerClass = function (type, clazz) {
    if (__DEV__) {
        if (axisPointerClazz[type]) {
            throw new Error('axisPointer ' + type + ' exists');
        }
    }
    axisPointerClazz[type] = clazz;
};

AxisView.getAxisPointerClass = function (type) {
    return type && axisPointerClazz[type];
};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * Can only be called after coordinate system creation stage.
 * (Can be called before coordinate system update stage).
 *
 * @param {Object} opt {labelInside}
 * @return {Object} {
 *  position, rotation, labelDirection, labelOffset,
 *  tickDirection, labelRotate, z2
 * }
 */
function layout$1(gridModel, axisModel, opt) {
    opt = opt || {};
    var grid = gridModel.coordinateSystem;
    var axis = axisModel.axis;
    var layout = {};
    var otherAxisOnZeroOf = axis.getAxesOnZeroOf()[0];

    var rawAxisPosition = axis.position;
    var axisPosition = otherAxisOnZeroOf ? 'onZero' : rawAxisPosition;
    var axisDim = axis.dim;

    var rect = grid.getRect();
    var rectBound = [rect.x, rect.x + rect.width, rect.y, rect.y + rect.height];
    var idx = {left: 0, right: 1, top: 0, bottom: 1, onZero: 2};
    var axisOffset = axisModel.get('offset') || 0;

    var posBound = axisDim === 'x'
        ? [rectBound[2] - axisOffset, rectBound[3] + axisOffset]
        : [rectBound[0] - axisOffset, rectBound[1] + axisOffset];

    if (otherAxisOnZeroOf) {
        var onZeroCoord = otherAxisOnZeroOf.toGlobalCoord(otherAxisOnZeroOf.dataToCoord(0));
        posBound[idx.onZero] = Math.max(Math.min(onZeroCoord, posBound[1]), posBound[0]);
    }

    // Axis position
    layout.position = [
        axisDim === 'y' ? posBound[idx[axisPosition]] : rectBound[0],
        axisDim === 'x' ? posBound[idx[axisPosition]] : rectBound[3]
    ];

    // Axis rotation
    layout.rotation = Math.PI / 2 * (axisDim === 'x' ? 0 : 1);

    // Tick and label direction, x y is axisDim
    var dirMap = {top: -1, bottom: 1, left: -1, right: 1};

    layout.labelDirection = layout.tickDirection = layout.nameDirection = dirMap[rawAxisPosition];
    layout.labelOffset = otherAxisOnZeroOf ? posBound[idx[rawAxisPosition]] - posBound[idx.onZero] : 0;

    if (axisModel.get('axisTick.inside')) {
        layout.tickDirection = -layout.tickDirection;
    }
    if (retrieve(opt.labelInside, axisModel.get('axisLabel.inside'))) {
        layout.labelDirection = -layout.labelDirection;
    }

    // Special label rotation
    var labelRotate = axisModel.get('axisLabel.rotate');
    layout.labelRotate = axisPosition === 'top' ? -labelRotate : labelRotate;

    // Over splitLine and splitArea
    layout.z2 = 1;

    return layout;
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

function rectCoordAxisBuildSplitArea(axisView, axisGroup, axisModel, gridModel) {
    var axis = axisModel.axis;

    if (axis.scale.isBlank()) {
        return;
    }

    var splitAreaModel = axisModel.getModel('splitArea');
    var areaStyleModel = splitAreaModel.getModel('areaStyle');
    var areaColors = areaStyleModel.get('color');

    var gridRect = gridModel.coordinateSystem.getRect();

    var ticksCoords = axis.getTicksCoords({
        tickModel: splitAreaModel,
        clamp: true
    });

    if (!ticksCoords.length) {
        return;
    }

    // For Making appropriate splitArea animation, the color and anid
    // should be corresponding to previous one if possible.
    var areaColorsLen = areaColors.length;
    var lastSplitAreaColors = axisView.__splitAreaColors;
    var newSplitAreaColors = createHashMap();
    var colorIndex = 0;
    if (lastSplitAreaColors) {
        for (var i = 0; i < ticksCoords.length; i++) {
            var cIndex = lastSplitAreaColors.get(ticksCoords[i].tickValue);
            if (cIndex != null) {
                colorIndex = (cIndex + (areaColorsLen - 1) * i) % areaColorsLen;
                break;
            }
        }
    }

    var prev = axis.toGlobalCoord(ticksCoords[0].coord);

    var areaStyle = areaStyleModel.getAreaStyle();
    areaColors = isArray(areaColors) ? areaColors : [areaColors];

    for (var i = 1; i < ticksCoords.length; i++) {
        var tickCoord = axis.toGlobalCoord(ticksCoords[i].coord);

        var x;
        var y;
        var width;
        var height;
        if (axis.isHorizontal()) {
            x = prev;
            y = gridRect.y;
            width = tickCoord - x;
            height = gridRect.height;
            prev = x + width;
        }
        else {
            x = gridRect.x;
            y = prev;
            width = gridRect.width;
            height = tickCoord - y;
            prev = y + height;
        }

        var tickValue = ticksCoords[i - 1].tickValue;
        tickValue != null && newSplitAreaColors.set(tickValue, colorIndex);

        axisGroup.add(new Rect({
            anid: tickValue != null ? 'area_' + tickValue : null,
            shape: {
                x: x,
                y: y,
                width: width,
                height: height
            },
            style: defaults({
                fill: areaColors[colorIndex]
            }, areaStyle),
            silent: true
        }));

        colorIndex = (colorIndex + 1) % areaColorsLen;
    }

    axisView.__splitAreaColors = newSplitAreaColors;
}

function rectCoordAxisHandleRemove(axisView) {
    axisView.__splitAreaColors = null;
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var axisBuilderAttrs = [
    'axisLine', 'axisTickLabel', 'axisName'
];
var selfBuilderAttrs = [
    'splitArea', 'splitLine', 'minorSplitLine'
];

var CartesianAxisView = AxisView.extend({

    type: 'cartesianAxis',

    axisPointerClass: 'CartesianAxisPointer',

    /**
     * @override
     */
    render: function (axisModel, ecModel, api, payload) {

        this.group.removeAll();

        var oldAxisGroup = this._axisGroup;
        this._axisGroup = new Group();

        this.group.add(this._axisGroup);

        if (!axisModel.get('show')) {
            return;
        }

        var gridModel = axisModel.getCoordSysModel();

        var layout = layout$1(gridModel, axisModel);

        var axisBuilder = new AxisBuilder(axisModel, layout);

        each$1(axisBuilderAttrs, axisBuilder.add, axisBuilder);

        this._axisGroup.add(axisBuilder.getGroup());

        each$1(selfBuilderAttrs, function (name) {
            if (axisModel.get(name + '.show')) {
                this['_' + name](axisModel, gridModel);
            }
        }, this);

        groupTransition(oldAxisGroup, this._axisGroup, axisModel);

        CartesianAxisView.superCall(this, 'render', axisModel, ecModel, api, payload);
    },

    remove: function () {
        rectCoordAxisHandleRemove(this);
    },

    /**
     * @param {module:echarts/coord/cartesian/AxisModel} axisModel
     * @param {module:echarts/coord/cartesian/GridModel} gridModel
     * @private
     */
    _splitLine: function (axisModel, gridModel) {
        var axis = axisModel.axis;

        if (axis.scale.isBlank()) {
            return;
        }

        var splitLineModel = axisModel.getModel('splitLine');
        var lineStyleModel = splitLineModel.getModel('lineStyle');
        var lineColors = lineStyleModel.get('color');

        lineColors = isArray(lineColors) ? lineColors : [lineColors];

        var gridRect = gridModel.coordinateSystem.getRect();
        var isHorizontal = axis.isHorizontal();

        var lineCount = 0;

        var ticksCoords = axis.getTicksCoords({
            tickModel: splitLineModel
        });

        var p1 = [];
        var p2 = [];

        var lineStyle = lineStyleModel.getLineStyle();
        for (var i = 0; i < ticksCoords.length; i++) {
            var tickCoord = axis.toGlobalCoord(ticksCoords[i].coord);

            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;
            var tickValue = ticksCoords[i].tickValue;
            this._axisGroup.add(new Line({
                anid: tickValue != null ? 'line_' + ticksCoords[i].tickValue : null,
                subPixelOptimize: true,
                shape: {
                    x1: p1[0],
                    y1: p1[1],
                    x2: p2[0],
                    y2: p2[1]
                },
                style: defaults({
                    stroke: lineColors[colorIndex]
                }, lineStyle),
                silent: true
            }));
        }
    },

    /**
     * @param {module:echarts/coord/cartesian/AxisModel} axisModel
     * @param {module:echarts/coord/cartesian/GridModel} gridModel
     * @private
     */
    _minorSplitLine: function (axisModel, gridModel) {
        var axis = axisModel.axis;

        var minorSplitLineModel = axisModel.getModel('minorSplitLine');
        var lineStyleModel = minorSplitLineModel.getModel('lineStyle');

        var gridRect = gridModel.coordinateSystem.getRect();
        var isHorizontal = axis.isHorizontal();

        var minorTicksCoords = axis.getMinorTicksCoords();
        if (!minorTicksCoords.length) {
            return;
        }
        var p1 = [];
        var p2 = [];

        var lineStyle = lineStyleModel.getLineStyle();


        for (var i = 0; i < minorTicksCoords.length; i++) {
            for (var k = 0; k < minorTicksCoords[i].length; k++) {
                var tickCoord = axis.toGlobalCoord(minorTicksCoords[i][k].coord);

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

                this._axisGroup.add(new Line({
                    anid: 'minor_line_' + minorTicksCoords[i][k].tickValue,
                    subPixelOptimize: true,
                    shape: {
                        x1: p1[0],
                        y1: p1[1],
                        x2: p2[0],
                        y2: p2[1]
                    },
                    style: lineStyle,
                    silent: true
                }));
            }
        }
    },

    /**
     * @param {module:echarts/coord/cartesian/AxisModel} axisModel
     * @param {module:echarts/coord/cartesian/GridModel} gridModel
     * @private
     */
    _splitArea: function (axisModel, gridModel) {
        rectCoordAxisBuildSplitArea(this, this._axisGroup, axisModel, gridModel);
    }
});

CartesianAxisView.extend({
    type: 'xAxis'
});
CartesianAxisView.extend({
    type: 'yAxis'
});

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

// Grid view
extendComponentView({

    type: 'grid',

    render: function (gridModel, ecModel) {
        this.group.removeAll();
        if (gridModel.get('show')) {
            this.group.add(new Rect({
                shape: gridModel.coordinateSystem.getRect(),
                style: defaults({
                    fill: gridModel.get('backgroundColor')
                }, gridModel.getItemStyle()),
                silent: true,
                z2: -1
            }));
        }
    }

});

registerPreprocessor(function (option) {
    // Only create grid when need
    if (option.xAxis && option.yAxis && !option.grid) {
        option.grid = {};
    }
});

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

// In case developer forget to include grid component
registerVisual(visualSymbol('line', 'circle', 'line'));
registerLayout(pointsLayout('line'));

// Down sample after filter
registerProcessor(
    PRIORITY.PROCESSOR.STATISTIC,
    dataSample('line')
);

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var BaseBarSeries = SeriesModel.extend({

    type: 'series.__base_bar__',

    getInitialData: function (option, ecModel) {
        return createListFromArray(this.getSource(), this, {useEncodeDefaulter: true});
    },

    getMarkerPosition: function (value) {
        var coordSys = this.coordinateSystem;
        if (coordSys) {
            // PENDING if clamp ?
            var pt = coordSys.dataToPoint(coordSys.clampData(value));
            var data = this.getData();
            var offset = data.getLayout('offset');
            var size = data.getLayout('size');
            var offsetIndex = coordSys.getBaseAxis().isHorizontal() ? 0 : 1;
            pt[offsetIndex] += offset + size / 2;
            return pt;
        }
        return [NaN, NaN];
    },

    defaultOption: {
        zlevel: 0,                  // 一级层叠
        z: 2,                       // 二级层叠
        coordinateSystem: 'cartesian2d',
        legendHoverLink: true,
        // stack: null

        // Cartesian coordinate system
        // xAxisIndex: 0,
        // yAxisIndex: 0,

        // 最小高度改为0
        barMinHeight: 0,
        // 最小角度为0，仅对极坐标系下的柱状图有效
        barMinAngle: 0,
        // cursor: null,

        large: false,
        largeThreshold: 400,
        progressive: 3e3,
        progressiveChunkMode: 'mod',

        // barMaxWidth: null,

        // In cartesian, the default value is 1. Otherwise null.
        // barMinWidth: null,

        // 默认自适应
        // barWidth: null,
        // 柱间距离，默认为柱形宽度的30%，可设固定值
        // barGap: '30%',
        // 类目间柱形距离，默认为类目间距的20%，可设固定值
        // barCategoryGap: '20%',
        // label: {
        //      show: false
        // },
        itemStyle: {},
        emphasis: {}
    }
});

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

BaseBarSeries.extend({

    type: 'series.bar',

    dependencies: ['grid', 'polar'],

    brushSelector: 'rect',

    /**
     * @override
     */
    getProgressive: function () {
        // Do not support progressive in normal mode.
        return this.get('large')
            ? this.get('progressive')
            : false;
    },

    /**
     * @override
     */
    getProgressiveThreshold: function () {
        // Do not support progressive in normal mode.
        var progressiveThreshold = this.get('progressiveThreshold');
        var largeThreshold = this.get('largeThreshold');
        if (largeThreshold > progressiveThreshold) {
            progressiveThreshold = largeThreshold;
        }
        return progressiveThreshold;
    },

    defaultOption: {
        // If clipped
        // Only available on cartesian2d
        clip: true,

        // If use caps on two sides of bars
        // Only available on tangential polar bar
        roundCap: false,

        showBackground: false,
        backgroundStyle: {
            color: 'rgba(180, 180, 180, 0.2)',
            borderColor: null,
            borderWidth: 0,
            borderType: 'solid',
            borderRadius: 0,
            shadowBlur: 0,
            shadowColor: null,
            shadowOffsetX: 0,
            shadowOffsetY: 0,
            opacity: 1
        }
    }
});

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

function setLabel(
    normalStyle, hoverStyle, itemModel, color, seriesModel, dataIndex, labelPositionOutside
) {
    var labelModel = itemModel.getModel('label');
    var hoverLabelModel = itemModel.getModel('emphasis.label');

    setLabelStyle(
        normalStyle, hoverStyle, labelModel, hoverLabelModel,
        {
            labelFetcher: seriesModel,
            labelDataIndex: dataIndex,
            defaultText: getDefaultLabel(seriesModel.getData(), dataIndex),
            isRectText: true,
            autoColor: color
        }
    );

    fixPosition(normalStyle);
    fixPosition(hoverStyle);
}

function fixPosition(style, labelPositionOutside) {
    if (style.textPosition === 'outside') {
        style.textPosition = labelPositionOutside;
    }
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var getBarItemStyle = makeStyleMapper(
    [
        ['fill', 'color'],
        ['stroke', 'borderColor'],
        ['lineWidth', 'borderWidth'],
        // Compatitable with 2
        ['stroke', 'barBorderColor'],
        ['lineWidth', 'barBorderWidth'],
        ['opacity'],
        ['shadowBlur'],
        ['shadowOffsetX'],
        ['shadowOffsetY'],
        ['shadowColor']
    ]
);

var barItemStyle = {
    getBarItemStyle: function (excludes) {
        var style = getBarItemStyle(this, excludes);
        if (this.getBorderLineDash) {
            var lineDash = this.getBorderLineDash();
            lineDash && (style.lineDash = lineDash);
        }
        return style;
    }
};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * Sausage: similar to sector, but have half circle on both sides
 * @public
 */
var Sausage = extendShape({

    type: 'sausage',

    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;
        var y = shape.cy;
        var r0 = Math.max(shape.r0 || 0, 0);
        var r = Math.max(shape.r, 0);
        var dr = (r - r0) * 0.5;
        var rCenter = r0 + dr;
        var startAngle = shape.startAngle;
        var endAngle = shape.endAngle;
        var clockwise = shape.clockwise;

        var unitStartX = Math.cos(startAngle);
        var unitStartY = Math.sin(startAngle);
        var unitEndX = Math.cos(endAngle);
        var unitEndY = Math.sin(endAngle);

        var lessThanCircle = clockwise
            ? endAngle - startAngle < Math.PI * 2
            : startAngle - endAngle < Math.PI * 2;

        if (lessThanCircle) {
            ctx.moveTo(unitStartX * r0 + x, unitStartY * r0 + y);

            ctx.arc(
                unitStartX * rCenter + x, unitStartY * rCenter + y, dr,
                -Math.PI + startAngle, startAngle, !clockwise
            );
        }

        ctx.arc(x, y, r, startAngle, endAngle, !clockwise);

        ctx.moveTo(unitEndX * r + x, unitEndY * r + y);

        ctx.arc(
            unitEndX * rCenter + x, unitEndY * rCenter + y, dr,
            endAngle - Math.PI * 2, endAngle - Math.PI, !clockwise
        );

        if (r0 !== 0) {
            ctx.arc(x, y, r0, endAngle, startAngle, clockwise);

            ctx.moveTo(unitStartX * r0 + x, unitEndY * r0 + y);
        }

        ctx.closePath();
    }
});

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var BAR_BORDER_WIDTH_QUERY = ['itemStyle', 'barBorderWidth'];
var _eventPos = [0, 0];

// FIXME
// Just for compatible with ec2.
extend(Model.prototype, barItemStyle);

function getClipArea(coord, data) {
    var coordSysClipArea = coord.getArea && coord.getArea();
    if (coord.type === 'cartesian2d') {
        var baseAxis = coord.getBaseAxis();
        // When boundaryGap is false or using time axis. bar may exceed the grid.
        // We should not clip this part.
        // See test/bar2.html
        if (baseAxis.type !== 'category' || !baseAxis.onBand) {
            var expandWidth = data.getLayout('bandWidth');
            if (baseAxis.isHorizontal()) {
                coordSysClipArea.x -= expandWidth;
                coordSysClipArea.width += expandWidth * 2;
            }
            else {
                coordSysClipArea.y -= expandWidth;
                coordSysClipArea.height += expandWidth * 2;
            }
        }
    }

    return coordSysClipArea;
}

extendChartView({

    type: 'bar',

    render: function (seriesModel, ecModel, api) {
        this._updateDrawMode(seriesModel);

        var coordinateSystemType = seriesModel.get('coordinateSystem');

        if (coordinateSystemType === 'cartesian2d'
            || coordinateSystemType === 'polar'
        ) {
            this._isLargeDraw
                ? this._renderLarge(seriesModel, ecModel, api)
                : this._renderNormal(seriesModel, ecModel, api);
        }
        else if (__DEV__) {
            console.warn('Only cartesian2d and polar supported for bar.');
        }

        return this.group;
    },

    incrementalPrepareRender: function (seriesModel, ecModel, api) {
        this._clear();
        this._updateDrawMode(seriesModel);
    },

    incrementalRender: function (params, seriesModel, ecModel, api) {
        // Do not support progressive in normal mode.
        this._incrementalRenderLarge(params, seriesModel);
    },

    _updateDrawMode: function (seriesModel) {
        var isLargeDraw = seriesModel.pipelineContext.large;
        if (this._isLargeDraw == null || isLargeDraw ^ this._isLargeDraw) {
            this._isLargeDraw = isLargeDraw;
            this._clear();
        }
    },

    _renderNormal: function (seriesModel, ecModel, api) {
        var group = this.group;
        var data = seriesModel.getData();
        var oldData = this._data;

        var coord = seriesModel.coordinateSystem;
        var baseAxis = coord.getBaseAxis();
        var isHorizontalOrRadial;

        if (coord.type === 'cartesian2d') {
            isHorizontalOrRadial = baseAxis.isHorizontal();
        }
        else if (coord.type === 'polar') {
            isHorizontalOrRadial = baseAxis.dim === 'angle';
        }

        var animationModel = seriesModel.isAnimationEnabled() ? seriesModel : null;

        var needsClip = seriesModel.get('clip', true);
        var coordSysClipArea = getClipArea(coord, data);
        // If there is clipPath created in large mode. Remove it.
        group.removeClipPath();
        // We don't use clipPath in normal mode because we needs a perfect animation
        // And don't want the label are clipped.

        var roundCap = seriesModel.get('roundCap', true);

        var drawBackground = seriesModel.get('showBackground', true);
        var backgroundModel = seriesModel.getModel('backgroundStyle');
        var barBorderRadius = backgroundModel.get('barBorderRadius') || 0;

        var bgEls = [];
        var oldBgEls = this._backgroundEls || [];

        var createBackground = function (dataIndex) {
            var bgLayout = getLayout[coord.type](data, dataIndex);
            var bgEl = createBackgroundEl(coord, isHorizontalOrRadial, bgLayout);
            bgEl.useStyle(backgroundModel.getBarItemStyle());
            // Only cartesian2d support borderRadius.
            if (coord.type === 'cartesian2d') {
                bgEl.setShape('r', barBorderRadius);
            }
            bgEls[dataIndex] = bgEl;
            return bgEl;
        };

        data.diff(oldData)
            .add(function (dataIndex) {
                var itemModel = data.getItemModel(dataIndex);
                var layout = getLayout[coord.type](data, dataIndex, itemModel);

                if (drawBackground) {
                    createBackground(dataIndex);
                }

                // If dataZoom in filteMode: 'empty', the baseValue can be set as NaN in "axisProxy".
                if (!data.hasValue(dataIndex)) {
                    return;
                }

                if (needsClip) {
                    // Clip will modify the layout params.
                    // And return a boolean to determine if the shape are fully clipped.
                    var isClipped = clip[coord.type](coordSysClipArea, layout);
                    if (isClipped) {
                        group.remove(el);
                        return;
                    }
                }

                var el = elementCreator[coord.type](
                    dataIndex, layout, isHorizontalOrRadial, animationModel, false, roundCap
                );
                data.setItemGraphicEl(dataIndex, el);
                group.add(el);

                updateStyle(
                    el, data, dataIndex, itemModel, layout,
                    seriesModel, isHorizontalOrRadial, coord.type === 'polar'
                );
            })
            .update(function (newIndex, oldIndex) {
                var itemModel = data.getItemModel(newIndex);
                var layout = getLayout[coord.type](data, newIndex, itemModel);

                if (drawBackground) {
                    var bgEl;
                    if (oldBgEls.length === 0) {
                        bgEl = createBackground(oldIndex);
                    }
                    else {
                        bgEl = oldBgEls[oldIndex];
                        bgEl.useStyle(backgroundModel.getBarItemStyle());
                        // Only cartesian2d support borderRadius.
                        if (coord.type === 'cartesian2d') {
                            bgEl.setShape('r', barBorderRadius);
                        }
                        bgEls[newIndex] = bgEl;
                    }

                    var bgLayout = getLayout[coord.type](data, newIndex);
                    var shape = createBackgroundShape(isHorizontalOrRadial, bgLayout, coord);
                    updateProps(bgEl, { shape: shape }, animationModel, newIndex);
                }

                var el = oldData.getItemGraphicEl(oldIndex);
                if (!data.hasValue(newIndex)) {
                    group.remove(el);
                    return;
                }

                if (needsClip) {
                    var isClipped = clip[coord.type](coordSysClipArea, layout);
                    if (isClipped) {
                        group.remove(el);
                        return;
                    }
                }

                if (el) {
                    updateProps(el, {shape: layout}, animationModel, newIndex);
                }
                else {
                    el = elementCreator[coord.type](
                        newIndex, layout, isHorizontalOrRadial, animationModel, true, roundCap
                    );
                }

                data.setItemGraphicEl(newIndex, el);
                // Add back
                group.add(el);

                updateStyle(
                    el, data, newIndex, itemModel, layout,
                    seriesModel, isHorizontalOrRadial, coord.type === 'polar'
                );
            })
            .remove(function (dataIndex) {
                var el = oldData.getItemGraphicEl(dataIndex);
                if (coord.type === 'cartesian2d') {
                    el && removeRect(dataIndex, animationModel, el);
                }
                else {
                    el && removeSector(dataIndex, animationModel, el);
                }
            })
            .execute();

        var bgGroup = this._backgroundGroup || (this._backgroundGroup = new Group());
        bgGroup.removeAll();

        for (var i = 0; i < bgEls.length; ++i) {
            bgGroup.add(bgEls[i]);
        }
        group.add(bgGroup);
        this._backgroundEls = bgEls;

        this._data = data;
    },

    _renderLarge: function (seriesModel, ecModel, api) {
        this._clear();
        createLarge(seriesModel, this.group);

        // Use clipPath in large mode.
        var clipPath = seriesModel.get('clip', true)
            ? createClipPath(seriesModel.coordinateSystem, false, seriesModel)
            : null;
        if (clipPath) {
            this.group.setClipPath(clipPath);
        }
        else {
            this.group.removeClipPath();
        }
    },

    _incrementalRenderLarge: function (params, seriesModel) {
        this._removeBackground();
        createLarge(seriesModel, this.group, true);
    },

    dispose: noop,

    remove: function (ecModel) {
        this._clear(ecModel);
    },

    _clear: function (ecModel) {
        var group = this.group;
        var data = this._data;
        if (ecModel && ecModel.get('animation') && data && !this._isLargeDraw) {
            this._removeBackground();
            this._backgroundEls = [];

            data.eachItemGraphicEl(function (el) {
                if (el.type === 'sector') {
                    removeSector(el.dataIndex, ecModel, el);
                }
                else {
                    removeRect(el.dataIndex, ecModel, el);
                }
            });
        }
        else {
            group.removeAll();
        }
        this._data = null;
    },

    _removeBackground: function () {
        this.group.remove(this._backgroundGroup);
        this._backgroundGroup = null;
    }

});

var mathMax$4 = Math.max;
var mathMin$4 = Math.min;

var clip = {
    cartesian2d: function (coordSysBoundingRect, layout) {
        var signWidth = layout.width < 0 ? -1 : 1;
        var signHeight = layout.height < 0 ? -1 : 1;
        // Needs positive width and height
        if (signWidth < 0) {
            layout.x += layout.width;
            layout.width = -layout.width;
        }
        if (signHeight < 0) {
            layout.y += layout.height;
            layout.height = -layout.height;
        }

        var x = mathMax$4(layout.x, coordSysBoundingRect.x);
        var x2 = mathMin$4(layout.x + layout.width, coordSysBoundingRect.x + coordSysBoundingRect.width);
        var y = mathMax$4(layout.y, coordSysBoundingRect.y);
        var y2 = mathMin$4(layout.y + layout.height, coordSysBoundingRect.y + coordSysBoundingRect.height);

        layout.x = x;
        layout.y = y;
        layout.width = x2 - x;
        layout.height = y2 - y;

        var clipped = layout.width < 0 || layout.height < 0;

        // Reverse back
        if (signWidth < 0) {
            layout.x += layout.width;
            layout.width = -layout.width;
        }
        if (signHeight < 0) {
            layout.y += layout.height;
            layout.height = -layout.height;
        }

        return clipped;
    },

    polar: function (coordSysClipArea, layout) {
        var signR = layout.r0 <= layout.r ? 1 : -1;
        // Make sure r is larger than r0
        if (signR < 0) {
            var r = layout.r;
            layout.r = layout.r0;
            layout.r0 = r;
        }

        var r = mathMin$4(layout.r, coordSysClipArea.r);
        var r0 = mathMax$4(layout.r0, coordSysClipArea.r0);

        layout.r = r;
        layout.r0 = r0;

        var clipped = r - r0 < 0;

        // Reverse back
        if (signR < 0) {
            var r = layout.r;
            layout.r = layout.r0;
            layout.r0 = r;
        }

        return clipped;
    }
};

var elementCreator = {

    cartesian2d: function (
        dataIndex, layout, isHorizontal,
        animationModel, isUpdate
    ) {
        var rect = new Rect({
            shape: extend({}, layout),
            z2: 1
        });

        rect.name = 'item';

        // Animation
        if (animationModel) {
            var rectShape = rect.shape;
            var animateProperty = isHorizontal ? 'height' : 'width';
            var animateTarget = {};
            rectShape[animateProperty] = 0;
            animateTarget[animateProperty] = layout[animateProperty];
            graphic[isUpdate ? 'updateProps' : 'initProps'](rect, {
                shape: animateTarget
            }, animationModel, dataIndex);
        }

        return rect;
    },

    polar: function (
        dataIndex, layout, isRadial,
        animationModel, isUpdate, roundCap
    ) {
        // Keep the same logic with bar in catesion: use end value to control
        // direction. Notice that if clockwise is true (by default), the sector
        // will always draw clockwisely, no matter whether endAngle is greater
        // or less than startAngle.
        var clockwise = layout.startAngle < layout.endAngle;

        var ShapeClass = (!isRadial && roundCap) ? Sausage : Sector;

        var sector = new ShapeClass({
            shape: defaults({clockwise: clockwise}, layout),
            z2: 1
        });

        sector.name = 'item';

        // Animation
        if (animationModel) {
            var sectorShape = sector.shape;
            var animateProperty = isRadial ? 'r' : 'endAngle';
            var animateTarget = {};
            sectorShape[animateProperty] = isRadial ? 0 : layout.startAngle;
            animateTarget[animateProperty] = layout[animateProperty];
            graphic[isUpdate ? 'updateProps' : 'initProps'](sector, {
                shape: animateTarget
            }, animationModel, dataIndex);
        }

        return sector;
    }
};

function removeRect(dataIndex, animationModel, el) {
    // Not show text when animating
    el.style.text = null;
    updateProps(el, {
        shape: {
            width: 0
        }
    }, animationModel, dataIndex, function () {
        el.parent && el.parent.remove(el);
    });
}

function removeSector(dataIndex, animationModel, el) {
    // Not show text when animating
    el.style.text = null;
    updateProps(el, {
        shape: {
            r: el.shape.r0
        }
    }, animationModel, dataIndex, function () {
        el.parent && el.parent.remove(el);
    });
}

var getLayout = {
    // itemModel is only used to get borderWidth, which is not needed
    // when calculating bar background layout.
    cartesian2d: function (data, dataIndex, itemModel) {
        var layout = data.getItemLayout(dataIndex);
        var fixedLineWidth = itemModel ? getLineWidth(itemModel, layout) : 0;

        // fix layout with lineWidth
        var signX = layout.width > 0 ? 1 : -1;
        var signY = layout.height > 0 ? 1 : -1;
        return {
            x: layout.x + signX * fixedLineWidth / 2,
            y: layout.y + signY * fixedLineWidth / 2,
            width: layout.width - signX * fixedLineWidth,
            height: layout.height - signY * fixedLineWidth
        };
    },

    polar: function (data, dataIndex, itemModel) {
        var layout = data.getItemLayout(dataIndex);
        return {
            cx: layout.cx,
            cy: layout.cy,
            r0: layout.r0,
            r: layout.r,
            startAngle: layout.startAngle,
            endAngle: layout.endAngle
        };
    }
};

function isZeroOnPolar(layout) {
    return layout.startAngle != null
        && layout.endAngle != null
        && layout.startAngle === layout.endAngle;
}

function updateStyle(
    el, data, dataIndex, itemModel, layout, seriesModel, isHorizontal, isPolar
) {
    var color = data.getItemVisual(dataIndex, 'color');
    var opacity = data.getItemVisual(dataIndex, 'opacity');
    var stroke = data.getVisual('borderColor');
    var itemStyleModel = itemModel.getModel('itemStyle');
    var hoverStyle = itemModel.getModel('emphasis.itemStyle').getBarItemStyle();

    if (!isPolar) {
        el.setShape('r', itemStyleModel.get('barBorderRadius') || 0);
    }

    el.useStyle(defaults(
        {
            stroke: isZeroOnPolar(layout) ? 'none' : stroke,
            fill: isZeroOnPolar(layout) ? 'none' : color,
            opacity: opacity
        },
        itemStyleModel.getBarItemStyle()
    ));

    var cursorStyle = itemModel.getShallow('cursor');
    cursorStyle && el.attr('cursor', cursorStyle);

    var labelPositionOutside = isHorizontal
        ? (layout.height > 0 ? 'bottom' : 'top')
        : (layout.width > 0 ? 'left' : 'right');

    if (!isPolar) {
        setLabel(
            el.style, hoverStyle, itemModel, color,
            seriesModel, dataIndex, labelPositionOutside
        );
    }
    if (isZeroOnPolar(layout)) {
        hoverStyle.fill = hoverStyle.stroke = 'none';
    }
    setHoverStyle(el, hoverStyle);
}

// In case width or height are too small.
function getLineWidth(itemModel, rawLayout) {
    var lineWidth = itemModel.get(BAR_BORDER_WIDTH_QUERY) || 0;
    // width or height may be NaN for empty data
    var width = isNaN(rawLayout.width) ? Number.MAX_VALUE : Math.abs(rawLayout.width);
    var height = isNaN(rawLayout.height) ? Number.MAX_VALUE : Math.abs(rawLayout.height);
    return Math.min(lineWidth, width, height);
}


var LargePath = Path.extend({

    type: 'largeBar',

    shape: {points: []},

    buildPath: function (ctx, shape) {
        // Drawing lines is more efficient than drawing
        // a whole line or drawing rects.
        var points = shape.points;
        var startPoint = this.__startPoint;
        var baseDimIdx = this.__baseDimIdx;

        for (var i = 0; i < points.length; i += 2) {
            startPoint[baseDimIdx] = points[i + baseDimIdx];
            ctx.moveTo(startPoint[0], startPoint[1]);
            ctx.lineTo(points[i], points[i + 1]);
        }
    }
});

function createLarge(seriesModel, group, incremental) {
    // TODO support polar
    var data = seriesModel.getData();
    var startPoint = [];
    var baseDimIdx = data.getLayout('valueAxisHorizontal') ? 1 : 0;
    startPoint[1 - baseDimIdx] = data.getLayout('valueAxisStart');

    var largeDataIndices = data.getLayout('largeDataIndices');
    var barWidth = data.getLayout('barWidth');

    var backgroundModel = seriesModel.getModel('backgroundStyle');
    var drawBackground = seriesModel.get('showBackground', true);

    if (drawBackground) {
        var points = data.getLayout('largeBackgroundPoints');
        var backgroundStartPoint = [];
        backgroundStartPoint[1 - baseDimIdx] = data.getLayout('backgroundStart');

        var bgEl = new LargePath({
            shape: {points: points},
            incremental: !!incremental,
            __startPoint: backgroundStartPoint,
            __baseDimIdx: baseDimIdx,
            __largeDataIndices: largeDataIndices,
            __barWidth: barWidth,
            silent: true,
            z2: 0
        });
        setLargeBackgroundStyle(bgEl, backgroundModel, data);
        group.add(bgEl);
    }

    var el = new LargePath({
        shape: {points: data.getLayout('largePoints')},
        incremental: !!incremental,
        __startPoint: startPoint,
        __baseDimIdx: baseDimIdx,
        __largeDataIndices: largeDataIndices,
        __barWidth: barWidth
    });
    group.add(el);
    setLargeStyle(el, seriesModel, data);

    // Enable tooltip and user mouse/touch event handlers.
    el.seriesIndex = seriesModel.seriesIndex;

    if (!seriesModel.get('silent')) {
        el.on('mousedown', largePathUpdateDataIndex);
        el.on('mousemove', largePathUpdateDataIndex);
    }
}

// Use throttle to avoid frequently traverse to find dataIndex.
var largePathUpdateDataIndex = throttle(function (event) {
    var largePath = this;
    var dataIndex = largePathFindDataIndex(largePath, event.offsetX, event.offsetY);
    largePath.dataIndex = dataIndex >= 0 ? dataIndex : null;
}, 30, false);

function largePathFindDataIndex(largePath, x, y) {
    var baseDimIdx = largePath.__baseDimIdx;
    var valueDimIdx = 1 - baseDimIdx;
    var points = largePath.shape.points;
    var largeDataIndices = largePath.__largeDataIndices;
    var barWidthHalf = Math.abs(largePath.__barWidth / 2);
    var startValueVal = largePath.__startPoint[valueDimIdx];

    _eventPos[0] = x;
    _eventPos[1] = y;
    var pointerBaseVal = _eventPos[baseDimIdx];
    var pointerValueVal = _eventPos[1 - baseDimIdx];
    var baseLowerBound = pointerBaseVal - barWidthHalf;
    var baseUpperBound = pointerBaseVal + barWidthHalf;

    for (var i = 0, len = points.length / 2; i < len; i++) {
        var ii = i * 2;
        var barBaseVal = points[ii + baseDimIdx];
        var barValueVal = points[ii + valueDimIdx];
        if (
            barBaseVal >= baseLowerBound && barBaseVal <= baseUpperBound
            && (
                startValueVal <= barValueVal
                    ? (pointerValueVal >= startValueVal && pointerValueVal <= barValueVal)
                    : (pointerValueVal >= barValueVal && pointerValueVal <= startValueVal)
            )
        ) {
            return largeDataIndices[i];
        }
    }

    return -1;
}

function setLargeStyle(el, seriesModel, data) {
    var borderColor = data.getVisual('borderColor') || data.getVisual('color');
    var itemStyle = seriesModel.getModel('itemStyle').getItemStyle(['color', 'borderColor']);

    el.useStyle(itemStyle);
    el.style.fill = null;
    el.style.stroke = borderColor;
    el.style.lineWidth = data.getLayout('barWidth');
}

function setLargeBackgroundStyle(el, backgroundModel, data) {
    var borderColor = backgroundModel.get('borderColor') || backgroundModel.get('color');
    var itemStyle = backgroundModel.getItemStyle(['color', 'borderColor']);

    el.useStyle(itemStyle);
    el.style.fill = null;
    el.style.stroke = borderColor;
    el.style.lineWidth = data.getLayout('barWidth');
}

function createBackgroundShape(isHorizontalOrRadial, layout, coord) {
    var coordLayout;
    var isPolar = coord.type === 'polar';
    if (isPolar) {
        coordLayout = coord.getArea();
    }
    else {
        coordLayout = coord.grid.getRect();
    }

    if (isPolar) {
        return {
            cx: coordLayout.cx,
            cy: coordLayout.cy,
            r0: isHorizontalOrRadial ? coordLayout.r0 : layout.r0,
            r: isHorizontalOrRadial ? coordLayout.r : layout.r,
            startAngle: isHorizontalOrRadial ? layout.startAngle : 0,
            endAngle: isHorizontalOrRadial ? layout.endAngle : Math.PI * 2
        };
    }
    else {
        return {
            x: isHorizontalOrRadial ? layout.x : coordLayout.x,
            y: isHorizontalOrRadial ? coordLayout.y : layout.y,
            width: isHorizontalOrRadial ? layout.width : coordLayout.width,
            height: isHorizontalOrRadial ? coordLayout.height : layout.height
        };
    }
}

function createBackgroundEl(coord, isHorizontalOrRadial, layout) {
    var ElementClz = coord.type === 'polar' ? Sector : Rect;
    return new ElementClz({
        shape: createBackgroundShape(isHorizontalOrRadial, layout, coord),
        silent: true,
        z2: 0
    });
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

// In case developer forget to include grid component
registerLayout(PRIORITY.VISUAL.LAYOUT, curry(layout, 'bar'));
// Use higher prority to avoid to be blocked by other overall layout, which do not
// only exist in this module, but probably also exist in other modules, like `barPolar`.
registerLayout(PRIORITY.VISUAL.PROGRESSIVE_LAYOUT, largeLayout);

registerVisual({
    seriesType: 'bar',
    reset: function (seriesModel) {
        // Visual coding for legend
        seriesModel.getData().setVisual('legendSymbol', 'roundRect');
    }
});

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/


/**
 * [Usage]:
 * (1)
 * createListSimply(seriesModel, ['value']);
 * (2)
 * createListSimply(seriesModel, {
 *     coordDimensions: ['value'],
 *     dimensionsCount: 5
 * });
 *
 * @param {module:echarts/model/Series} seriesModel
 * @param {Object|Array.<string|Object>} opt opt or coordDimensions
 *        The options in opt, see `echarts/data/helper/createDimensions`
 * @param {Array.<string>} [nameList]
 * @return {module:echarts/data/List}
 */
var createListSimply = function (seriesModel, opt, nameList) {
    opt = isArray(opt) && {coordDimensions: opt} || extend({}, opt);

    var source = seriesModel.getSource();

    var dimensionsInfo = createDimensions(source, opt);

    var list = new List(dimensionsInfo, seriesModel);
    list.initData(source, nameList);

    return list;
};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

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

var dataSelectableMixin = {

    /**
     * @param {Array.<Object>} targetList [{name, value, selected}, ...]
     *        If targetList is an array, it should like [{name: ..., value: ...}, ...].
     *        If targetList is a "List", it must have coordDim: 'value' dimension and name.
     */
    updateSelectedMap: function (targetList) {
        this._targetList = isArray(targetList) ? targetList.slice() : [];

        this._selectTargetMap = reduce(targetList || [], function (targetMap, target) {
            targetMap.set(target.name, target);
            return targetMap;
        }, createHashMap());
    },

    /**
     * Either name or id should be passed as input here.
     * If both of them are defined, id is used.
     *
     * @param {string|undefined} name name of data
     * @param {number|undefined} id dataIndex of data
     */
    // PENGING If selectedMode is null ?
    select: function (name, id) {
        var target = id != null
            ? this._targetList[id]
            : this._selectTargetMap.get(name);
        var selectedMode = this.get('selectedMode');
        if (selectedMode === 'single') {
            this._selectTargetMap.each(function (target) {
                target.selected = false;
            });
        }
        target && (target.selected = true);
    },

    /**
     * Either name or id should be passed as input here.
     * If both of them are defined, id is used.
     *
     * @param {string|undefined} name name of data
     * @param {number|undefined} id dataIndex of data
     */
    unSelect: function (name, id) {
        var target = id != null
            ? this._targetList[id]
            : this._selectTargetMap.get(name);
        // var selectedMode = this.get('selectedMode');
        // selectedMode !== 'single' && target && (target.selected = false);
        target && (target.selected = false);
    },

    /**
     * Either name or id should be passed as input here.
     * If both of them are defined, id is used.
     *
     * @param {string|undefined} name name of data
     * @param {number|undefined} id dataIndex of data
     */
    toggleSelected: function (name, id) {
        var target = id != null
            ? this._targetList[id]
            : this._selectTargetMap.get(name);
        if (target != null) {
            this[target.selected ? 'unSelect' : 'select'](name, id);
            return target.selected;
        }
    },

    /**
     * Either name or id should be passed as input here.
     * If both of them are defined, id is used.
     *
     * @param {string|undefined} name name of data
     * @param {number|undefined} id dataIndex of data
     */
    isSelected: function (name, id) {
        var target = id != null
            ? this._targetList[id]
            : this._selectTargetMap.get(name);
        return target && target.selected;
    }
};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/


/**
 * LegendVisualProvider is an bridge that pick encoded color from data and
 * provide to the legend component.
 * @param {Function} getDataWithEncodedVisual Function to get data after filtered. It stores all the encoding info
 * @param {Function} getRawData Function to get raw data before filtered.
 */
function LegendVisualProvider(getDataWithEncodedVisual, getRawData) {
    this.getAllNames = function () {
        var rawData = getRawData();
        // We find the name from the raw data. In case it's filtered by the legend component.
        // Normally, the name can be found in rawData, but can't be found in filtered data will display as gray.
        return rawData.mapArray(rawData.getName);
    };

    this.containName = function (name) {
        var rawData = getRawData();
        return rawData.indexOfName(name) >= 0;
    };

    this.indexOfName = function (name) {
        // Only get data when necessary.
        // Because LegendVisualProvider constructor may be new in the stage that data is not prepared yet.
        // Invoking Series#getData immediately will throw an error.
        var dataWithEncodedVisual = getDataWithEncodedVisual();
        return dataWithEncodedVisual.indexOfName(name);
    };

    this.getItemVisual = function (dataIndex, key) {
        // Get encoded visual properties from final filtered data.
        var dataWithEncodedVisual = getDataWithEncodedVisual();
        return dataWithEncodedVisual.getItemVisual(dataIndex, key);
    };
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var PieSeries = extendSeriesModel({

    type: 'series.pie',

    // Overwrite
    init: function (option) {
        PieSeries.superApply(this, 'init', arguments);

        // Enable legend selection for each data item
        // Use a function instead of direct access because data reference may changed
        this.legendVisualProvider = new LegendVisualProvider(
            bind(this.getData, this), bind(this.getRawData, this)
        );

        this.updateSelectedMap(this._createSelectableList());

        this._defaultLabelLine(option);
    },

    // Overwrite
    mergeOption: function (newOption) {
        PieSeries.superCall(this, 'mergeOption', newOption);

        this.updateSelectedMap(this._createSelectableList());
    },

    getInitialData: function (option, ecModel) {
        return createListSimply(this, {
            coordDimensions: ['value'],
            encodeDefaulter: curry(makeSeriesEncodeForNameBased, this)
        });
    },

    _createSelectableList: function () {
        var data = this.getRawData();
        var valueDim = data.mapDimension('value');
        var targetList = [];
        for (var i = 0, len = data.count(); i < len; i++) {
            targetList.push({
                name: data.getName(i),
                value: data.get(valueDim, i),
                selected: retrieveRawAttr(data, i, 'selected')
            });
        }
        return targetList;
    },

    // Overwrite
    getDataParams: function (dataIndex) {
        var data = this.getData();
        var params = PieSeries.superCall(this, 'getDataParams', dataIndex);
        // FIXME toFixed?

        var valueList = [];
        data.each(data.mapDimension('value'), function (value) {
            valueList.push(value);
        });

        params.percent = getPercentWithPrecision(
            valueList,
            dataIndex,
            data.hostModel.get('percentPrecision')
        );

        params.$vars.push('percent');
        return params;
    },

    _defaultLabelLine: function (option) {
        // Extend labelLine emphasis
        defaultEmphasis(option, 'labelLine', ['show']);

        var labelLineNormalOpt = option.labelLine;
        var labelLineEmphasisOpt = option.emphasis.labelLine;
        // Not show label line if `label.normal.show = false`
        labelLineNormalOpt.show = labelLineNormalOpt.show
            && option.label.show;
        labelLineEmphasisOpt.show = labelLineEmphasisOpt.show
            && option.emphasis.label.show;
    },

    defaultOption: {
        zlevel: 0,
        z: 2,
        legendHoverLink: true,

        hoverAnimation: true,
        // 默认全局居中
        center: ['50%', '50%'],
        radius: [0, '75%'],
        // 默认顺时针
        clockwise: true,
        startAngle: 90,
        // 最小角度改为0
        minAngle: 0,

        // If the angle of a sector less than `minShowLabelAngle`,
        // the label will not be displayed.
        minShowLabelAngle: 0,

        // 选中时扇区偏移量
        selectedOffset: 10,
        // 高亮扇区偏移量
        hoverOffset: 10,

        // If use strategy to avoid label overlapping
        avoidLabelOverlap: true,
        // 选择模式，默认关闭，可选single，multiple
        // selectedMode: false,
        // 南丁格尔玫瑰图模式，'radius'（半径） | 'area'（面积）
        // roseType: null,

        percentPrecision: 2,

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

        // cursor: null,

        left: 0,
        top: 0,
        right: 0,
        bottom: 0,
        width: null,
        height: null,

        label: {
            // If rotate around circle
            rotate: false,
            show: true,
            // 'outer', 'inside', 'center'
            position: 'outer',
            // 'none', 'labelLine', 'edge'. Works only when position is 'outer'
            alignTo: 'none',
            // Closest distance between label and chart edge.
            // Works only position is 'outer' and alignTo is 'edge'.
            margin: '25%',
            // Works only position is 'outer' and alignTo is not 'edge'.
            bleedMargin: 10,
            // Distance between text and label line.
            distanceToLabelLine: 5
            // formatter: 标签文本格式器，同Tooltip.formatter，不支持异步回调
            // 默认使用全局文本样式，详见TEXTSTYLE
            // distance: 当position为inner时有效，为label位置到圆心的距离与圆半径(环状图为内外半径和)的比例系数
        },
        // Enabled when label.normal.position is 'outer'
        labelLine: {
            show: true,
            // 引导线两段中的第一段长度
            length: 15,
            // 引导线两段中的第二段长度
            length2: 15,
            smooth: false,
            lineStyle: {
                // color: 各异,
                width: 1,
                type: 'solid'
            }
        },
        itemStyle: {
            borderWidth: 1
        },

        // Animation type. Valid values: expansion, scale
        animationType: 'expansion',

        // Animation type when update. Valid values: transition, expansion
        animationTypeUpdate: 'transition',

        animationEasing: 'cubicOut'
    }
});

mixin(PieSeries, dataSelectableMixin);

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

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

    Group.call(this);

    var sector = new Sector({
        z2: 2
    });
    var polyline = new Polyline();
    var text = new Text();
    this.add(sector);
    this.add(polyline);
    this.add(text);

    this.updateData(data, idx, true);
}

var piePieceProto = PiePiece.prototype;

piePieceProto.updateData = function (data, idx, firstCreate) {

    var sector = this.childAt(0);
    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 sectorShape = extend({}, layout);
    sectorShape.label = null;

    var animationTypeUpdate = seriesModel.getShallow('animationTypeUpdate');

    if (firstCreate) {
        sector.setShape(sectorShape);

        var animationType = seriesModel.getShallow('animationType');
        if (animationType === 'scale') {
            sector.shape.r = layout.r0;
            initProps(sector, {
                shape: {
                    r: layout.r
                }
            }, seriesModel, idx);
        }
        // Expansion
        else {
            sector.shape.endAngle = layout.startAngle;
            updateProps(sector, {
                shape: {
                    endAngle: layout.endAngle
                }
            }, seriesModel, idx);
        }

    }
    else {
        if (animationTypeUpdate === 'expansion') {
            // Sectors are set to be target shape and an overlaying clipPath is used for animation
            sector.setShape(sectorShape);
        }
        else {
            // Transition animation from the old shape
            updateProps(sector, {
                shape: sectorShape
            }, seriesModel, idx);
        }
    }

    // Update common style
    var visualColor = data.getItemVisual(idx, 'color');

    sector.useStyle(
        defaults(
            {
                lineJoin: 'bevel',
                fill: visualColor
            },
            itemModel.getModel('itemStyle').getItemStyle()
        )
    );
    sector.hoverStyle = itemModel.getModel('emphasis.itemStyle').getItemStyle();

    var cursorStyle = itemModel.getShallow('cursor');
    cursorStyle && sector.attr('cursor', cursorStyle);

    // Toggle selected
    toggleItemSelected(
        this,
        data.getItemLayout(idx),
        seriesModel.isSelected(data.getName(idx)),
        seriesModel.get('selectedOffset'),
        seriesModel.get('animation')
    );

    // Label and text animation should be applied only for transition type animation when update
    var withAnimation = !firstCreate && animationTypeUpdate === 'transition';
    this._updateLabel(data, idx, withAnimation);

    this.highDownOnUpdate = !seriesModel.get('silent')
        ? function (fromState, toState) {
            var hasAnimation = seriesModel.isAnimationEnabled() && itemModel.get('hoverAnimation');
            if (toState === 'emphasis') {
                labelLine.ignore = labelLine.hoverIgnore;
                labelText.ignore = labelText.hoverIgnore;

                // Sector may has animation of updating data. Force to move to the last frame
                // Or it may stopped on the wrong shape
                if (hasAnimation) {
                    sector.stopAnimation(true);
                    sector.animateTo({
                        shape: {
                            r: layout.r + seriesModel.get('hoverOffset')
                        }
                    }, 300, 'elasticOut');
                }
            }
            else {
                labelLine.ignore = labelLine.normalIgnore;
                labelText.ignore = labelText.normalIgnore;

                if (hasAnimation) {
                    sector.stopAnimation(true);
                    sector.animateTo({
                        shape: {
                            r: layout.r
                        }
                    }, 300, 'elasticOut');
                }
            }
        }
        : null;

    setHoverStyle(this);
};

piePieceProto._updateLabel = function (data, idx, withAnimation) {

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

    if (!labelLayout || isNaN(labelLayout.x) || isNaN(labelLayout.y)) {
        labelText.ignore = labelText.normalIgnore = labelText.hoverIgnore =
        labelLine.ignore = labelLine.normalIgnore = labelLine.hoverIgnore = true;
        return;
    }

    var targetLineShape = {
        points: labelLayout.linePoints || [
            [labelLayout.x, labelLayout.y], [labelLayout.x, labelLayout.y], [labelLayout.x, labelLayout.y]
        ]
    };
    var targetTextStyle = {
        x: labelLayout.x,
        y: labelLayout.y
    };
    if (withAnimation) {
        updateProps(labelLine, {
            shape: targetLineShape
        }, seriesModel, idx);

        updateProps(labelText, {
            style: targetTextStyle
        }, seriesModel, idx);
    }
    else {
        labelLine.attr({
            shape: targetLineShape
        });
        labelText.attr({
            style: targetTextStyle
        });
    }

    labelText.attr({
        rotation: labelLayout.rotation,
        origin: [labelLayout.x, labelLayout.y],
        z2: 10
    });

    var labelModel = itemModel.getModel('label');
    var labelHoverModel = itemModel.getModel('emphasis.label');
    var labelLineModel = itemModel.getModel('labelLine');
    var labelLineHoverModel = itemModel.getModel('emphasis.labelLine');
    var visualColor = data.getItemVisual(idx, 'color');

    setLabelStyle(
        labelText.style, labelText.hoverStyle = {}, labelModel, labelHoverModel,
        {
            labelFetcher: data.hostModel,
            labelDataIndex: idx,
            defaultText: labelLayout.text,
            autoColor: visualColor,
            useInsideStyle: !!labelLayout.inside
        },
        {
            textAlign: labelLayout.textAlign,
            textVerticalAlign: labelLayout.verticalAlign,
            opacity: data.getItemVisual(idx, 'opacity')
        }
    );

    labelText.ignore = labelText.normalIgnore = !labelModel.get('show');
    labelText.hoverIgnore = !labelHoverModel.get('show');

    labelLine.ignore = labelLine.normalIgnore = !labelLineModel.get('show');
    labelLine.hoverIgnore = !labelLineHoverModel.get('show');

    // Default use item visual color
    labelLine.setStyle({
        stroke: visualColor,
        opacity: data.getItemVisual(idx, 'opacity')
    });
    labelLine.setStyle(labelLineModel.getModel('lineStyle').getLineStyle());

    labelLine.hoverStyle = labelLineHoverModel.getModel('lineStyle').getLineStyle();

    var smooth = labelLineModel.get('smooth');
    if (smooth && smooth === true) {
        smooth = 0.4;
    }
    labelLine.setShape({
        smooth: smooth
    });
};

inherits(PiePiece, Group);


// Pie view
var PieView = Chart.extend({

    type: 'pie',

    init: function () {
        var sectorGroup = new Group();
        this._sectorGroup = sectorGroup;
    },

    render: function (seriesModel, ecModel, api, payload) {
        if (payload && (payload.from === this.uid)) {
            return;
        }

        var data = seriesModel.getData();
        var oldData = this._data;
        var group = this.group;

        var hasAnimation = ecModel.get('animation');
        var isFirstRender = !oldData;
        var animationType = seriesModel.get('animationType');
        var animationTypeUpdate = seriesModel.get('animationTypeUpdate');

        var onSectorClick = curry(
            updateDataSelected, this.uid, seriesModel, hasAnimation, api
        );

        var selectedMode = seriesModel.get('selectedMode');
        data.diff(oldData)
            .add(function (idx) {
                var piePiece = new PiePiece(data, idx);
                // Default expansion animation
                if (isFirstRender && animationType !== 'scale') {
                    piePiece.eachChild(function (child) {
                        child.stopAnimation(true);
                    });
                }

                selectedMode && piePiece.on('click', onSectorClick);

                data.setItemGraphicEl(idx, piePiece);

                group.add(piePiece);
            })
            .update(function (newIdx, oldIdx) {
                var piePiece = oldData.getItemGraphicEl(oldIdx);

                if (!isFirstRender && animationTypeUpdate !== 'transition') {
                    piePiece.eachChild(function (child) {
                        child.stopAnimation(true);
                    });
                }

                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 && data.count() > 0
            && (isFirstRender ? animationType !== 'scale' : animationTypeUpdate !== 'transition')
        ) {
            var shape = data.getItemLayout(0);
            for (var s = 1; isNaN(shape.startAngle) && s < data.count(); ++s) {
                shape = data.getItemLayout(s);
            }

            var r = Math.max(api.getWidth(), api.getHeight()) / 2;

            var removeClipPath = bind(group.removeClipPath, group);
            group.setClipPath(this._createClipPath(
                shape.cx, shape.cy, r, shape.startAngle, shape.clockwise, removeClipPath, seriesModel, isFirstRender
            ));
        }
        else {
            // clipPath is used in first-time animation, so remove it when otherwise. See: #8994
            group.removeClipPath();
        }

        this._data = data;
    },

    dispose: function () {},

    _createClipPath: function (
        cx, cy, r, startAngle, clockwise, cb, seriesModel, isFirstRender
    ) {
        var clipPath = new Sector({
            shape: {
                cx: cx,
                cy: cy,
                r0: 0,
                r: r,
                startAngle: startAngle,
                endAngle: startAngle,
                clockwise: clockwise
            }
        });

        var initOrUpdate = isFirstRender ? initProps : updateProps;
        initOrUpdate(clipPath, {
            shape: {
                endAngle: startAngle + (clockwise ? 1 : -1) * Math.PI * 2
            }
        }, seriesModel, cb);

        return clipPath;
    },

    /**
     * @implement
     */
    containPoint: function (point, seriesModel) {
        var data = seriesModel.getData();
        var itemLayout = data.getItemLayout(0);
        if (itemLayout) {
            var dx = point[0] - itemLayout.cx;
            var dy = point[1] - itemLayout.cy;
            var radius = Math.sqrt(dx * dx + dy * dy);
            return radius <= itemLayout.r && radius >= itemLayout.r0;
        }
    }

});

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var createDataSelectAction = function (seriesType, actionInfos) {
    each$1(actionInfos, function (actionInfo) {
        actionInfo.update = 'updateView';
        /**
         * @payload
         * @property {string} seriesName
         * @property {string} name
         */
        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,
                            payload.dataIndex
                        );
                    }
                    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,
                seriesId: payload.seriesId
            };
        });
    });
};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

// Pick color from palette for each data item.
// Applicable for charts that require applying color palette
// in data level (like pie, funnel, chord).
var dataColor = function (seriesType) {
    return {
        getTargetSeries: function (ecModel) {
            // Pie and funnel may use diferrent scope
            var paletteScope = {};
            var seiresModelMap = createHashMap();

            ecModel.eachSeriesByType(seriesType, function (seriesModel) {
                seriesModel.__paletteScope = paletteScope;
                seiresModelMap.set(seriesModel.uid, seriesModel);
            });

            return seiresModelMap;
        },
        reset: function (seriesModel, ecModel) {
            var dataAll = seriesModel.getRawData();
            var idxMap = {};
            var data = seriesModel.getData();

            data.each(function (idx) {
                var rawIdx = data.getRawIndex(idx);
                idxMap[rawIdx] = idx;
            });

            dataAll.each(function (rawIdx) {
                var filteredIdx = idxMap[rawIdx];

                // If series.itemStyle.normal.color is a function. itemVisual may be encoded
                var singleDataColor = filteredIdx != null
                    && data.getItemVisual(filteredIdx, 'color', true);

                var singleDataBorderColor = filteredIdx != null
                    && data.getItemVisual(filteredIdx, 'borderColor', true);

                var itemModel;
                if (!singleDataColor || !singleDataBorderColor) {
                    // FIXME Performance
                    itemModel = dataAll.getItemModel(rawIdx);
                }

                if (!singleDataColor) {
                    var color = itemModel.get('itemStyle.color')
                        || seriesModel.getColorFromPalette(
                            dataAll.getName(rawIdx) || (rawIdx + ''), seriesModel.__paletteScope,
                            dataAll.count()
                        );
                    // Data is not filtered
                    if (filteredIdx != null) {
                        data.setItemVisual(filteredIdx, 'color', color);
                    }
                }

                if (!singleDataBorderColor) {
                    var borderColor = itemModel.get('itemStyle.borderColor');

                    // Data is not filtered
                    if (filteredIdx != null) {
                        data.setItemVisual(filteredIdx, 'borderColor', borderColor);
                    }
                }
            });
        }
    };
};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

// FIXME emphasis label position is not same with normal label position

var RADIAN$1 = Math.PI / 180;

function adjustSingleSide(list, cx, cy, r, dir, viewWidth, viewHeight, viewLeft, viewTop, farthestX) {
    list.sort(function (a, b) {
        return a.y - b.y;
    });

    function shiftDown(start, end, delta, dir) {
        for (var j = start; j < end; j++) {
            if (list[j].y + delta > viewTop + viewHeight) {
                break;
            }

            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--) {
            if (list[j].y - delta < viewTop) {
                break;
            }

            list[j].y -= delta;
            if (j > 0
                && list[j].y > list[j - 1].y + list[j - 1].height
            ) {
                break;
            }
        }
    }

    function changeX(list, isDownList, cx, cy, r, dir) {
        var lastDeltaX = dir > 0
            ? isDownList                // right-side
                ? Number.MAX_VALUE      // down
                : 0                     // up
            : isDownList                // left-side
                ? Number.MAX_VALUE      // down
                : 0;                    // up

        for (var i = 0, l = list.length; i < l; i++) {
            if (list[i].labelAlignTo !== 'none') {
                continue;
            }

            var deltaY = Math.abs(list[i].y - cy);
            var length = list[i].len;
            var length2 = list[i].len2;
            var deltaX = (deltaY < r + length)
                ? Math.sqrt(
                        (r + length + length2) * (r + length + length2)
                        - deltaY * deltaY
                    )
                : Math.abs(list[i].x - cx);
            if (isDownList && deltaX >= lastDeltaX) {
                // right-down, left-down
                deltaX = lastDeltaX - 10;
            }
            if (!isDownList && deltaX <= lastDeltaX) {
                // right-up, left-up
                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++) {
        if (list[i].position === 'outer' && list[i].labelAlignTo === 'labelLine') {
            var dx = list[i].x - farthestX;
            list[i].linePoints[1][0] += dx;
            list[i].x = farthestX;
        }

        delta = list[i].y - lastY;
        if (delta < 0) {
            shiftDown(i, len, -delta, dir);
        }
        lastY = list[i].y + list[i].height;
    }
    if (viewHeight - lastY < 0) {
        shiftUp(len - 1, lastY - viewHeight);
    }
    for (var i = 0; i < len; i++) {
        if (list[i].y >= cy) {
            downList.push(list[i]);
        }
        else {
            upList.push(list[i]);
        }
    }
    changeX(upList, false, cx, cy, r, dir);
    changeX(downList, true, cx, cy, r, dir);
}

function avoidOverlap(labelLayoutList, cx, cy, r, viewWidth, viewHeight, viewLeft, viewTop) {
    var leftList = [];
    var rightList = [];
    var leftmostX = Number.MAX_VALUE;
    var rightmostX = -Number.MAX_VALUE;
    for (var i = 0; i < labelLayoutList.length; i++) {
        if (isPositionCenter(labelLayoutList[i])) {
            continue;
        }
        if (labelLayoutList[i].x < cx) {
            leftmostX = Math.min(leftmostX, labelLayoutList[i].x);
            leftList.push(labelLayoutList[i]);
        }
        else {
            rightmostX = Math.max(rightmostX, labelLayoutList[i].x);
            rightList.push(labelLayoutList[i]);
        }
    }

    adjustSingleSide(rightList, cx, cy, r, 1, viewWidth, viewHeight, viewLeft, viewTop, rightmostX);
    adjustSingleSide(leftList, cx, cy, r, -1, viewWidth, viewHeight, viewLeft, viewTop, leftmostX);

    for (var i = 0; i < labelLayoutList.length; i++) {
        var layout = labelLayoutList[i];
        if (isPositionCenter(layout)) {
            continue;
        }

        var linePoints = layout.linePoints;
        if (linePoints) {
            var isAlignToEdge = layout.labelAlignTo === 'edge';

            var realTextWidth = layout.textRect.width;
            var targetTextWidth;
            if (isAlignToEdge) {
                if (layout.x < cx) {
                    targetTextWidth = linePoints[2][0] - layout.labelDistance
                            - viewLeft - layout.labelMargin;
                }
                else {
                    targetTextWidth = viewLeft + viewWidth - layout.labelMargin
                            - linePoints[2][0] - layout.labelDistance;
                }
            }
            else {
                if (layout.x < cx) {
                    targetTextWidth = layout.x - viewLeft - layout.bleedMargin;
                }
                else {
                    targetTextWidth = viewLeft + viewWidth - layout.x - layout.bleedMargin;
                }
            }
            if (targetTextWidth < layout.textRect.width) {
                layout.text = truncateText(layout.text, targetTextWidth, layout.font);
                if (layout.labelAlignTo === 'edge') {
                    realTextWidth = getWidth(layout.text, layout.font);
                }
            }

            var dist = linePoints[1][0] - linePoints[2][0];
            if (isAlignToEdge) {
                if (layout.x < cx) {
                    linePoints[2][0] = viewLeft + layout.labelMargin + realTextWidth + layout.labelDistance;
                }
                else {
                    linePoints[2][0] = viewLeft + viewWidth - layout.labelMargin
                            - realTextWidth - layout.labelDistance;
                }
            }
            else {
                if (layout.x < cx) {
                    linePoints[2][0] = layout.x + layout.labelDistance;
                }
                else {
                    linePoints[2][0] = layout.x - layout.labelDistance;
                }
                linePoints[1][0] = linePoints[2][0] + dist;
            }
            linePoints[1][1] = linePoints[2][1] = layout.y;
        }
    }
}

function isPositionCenter(layout) {
    // Not change x for center label
    return layout.position === 'center';
}

var labelLayout = function (seriesModel, r, viewWidth, viewHeight, viewLeft, viewTop) {
    var data = seriesModel.getData();
    var labelLayoutList = [];
    var cx;
    var cy;
    var hasLabelRotate = false;
    var minShowLabelRadian = (seriesModel.get('minShowLabelAngle') || 0) * RADIAN$1;

    data.each(function (idx) {
        var layout = data.getItemLayout(idx);

        var itemModel = data.getItemModel(idx);
        var labelModel = itemModel.getModel('label');
        // Use position in normal or emphasis
        var labelPosition = labelModel.get('position') || itemModel.get('emphasis.label.position');
        var labelDistance = labelModel.get('distanceToLabelLine');
        var labelAlignTo = labelModel.get('alignTo');
        var labelMargin = parsePercent$1(labelModel.get('margin'), viewWidth);
        var bleedMargin = labelModel.get('bleedMargin');
        var font = labelModel.getFont();

        var labelLineModel = itemModel.getModel('labelLine');
        var labelLineLen = labelLineModel.get('length');
        labelLineLen = parsePercent$1(labelLineLen, viewWidth);
        var labelLineLen2 = labelLineModel.get('length2');
        labelLineLen2 = parsePercent$1(labelLineLen2, viewWidth);

        if (layout.angle < minShowLabelRadian) {
            return;
        }

        var midAngle = (layout.startAngle + layout.endAngle) / 2;
        var dx = Math.cos(midAngle);
        var dy = Math.sin(midAngle);

        var textX;
        var textY;
        var linePoints;
        var textAlign;

        cx = layout.cx;
        cy = layout.cy;

        var text = seriesModel.getFormattedLabel(idx, 'normal')
                || data.getName(idx);
        var textRect = getBoundingRect(
            text, font, textAlign, 'top'
        );

        var isLabelInside = labelPosition === 'inside' || labelPosition === 'inner';
        if (labelPosition === 'center') {
            textX = layout.cx;
            textY = layout.cy;
            textAlign = 'center';
        }
        else {
            var x1 = (isLabelInside ? (layout.r + layout.r0) / 2 * dx : layout.r * dx) + cx;
            var y1 = (isLabelInside ? (layout.r + layout.r0) / 2 * dy : layout.r * dy) + cy;

            textX = x1 + dx * 3;
            textY = y1 + dy * 3;

            if (!isLabelInside) {
                // For roseType
                var x2 = x1 + dx * (labelLineLen + r - layout.r);
                var y2 = y1 + dy * (labelLineLen + r - layout.r);
                var x3 = x2 + ((dx < 0 ? -1 : 1) * labelLineLen2);
                var y3 = y2;

                if (labelAlignTo === 'edge') {
                    // Adjust textX because text align of edge is opposite
                    textX = dx < 0
                        ? viewLeft + labelMargin
                        : viewLeft + viewWidth - labelMargin;
                }
                else {
                    textX = x3 + (dx < 0 ? -labelDistance : labelDistance);
                }
                textY = y3;
                linePoints = [[x1, y1], [x2, y2], [x3, y3]];
            }

            textAlign = isLabelInside
                ? 'center'
                : (labelAlignTo === 'edge'
                    ? (dx > 0 ? 'right' : 'left')
                    : (dx > 0 ? 'left' : 'right'));
        }

        var labelRotate;
        var rotate = labelModel.get('rotate');
        if (typeof rotate === 'number') {
            labelRotate = rotate * (Math.PI / 180);
        }
        else {
            labelRotate = rotate
                ? (dx < 0 ? -midAngle + Math.PI : -midAngle)
                : 0;
        }

        hasLabelRotate = !!labelRotate;
        layout.label = {
            x: textX,
            y: textY,
            position: labelPosition,
            height: textRect.height,
            len: labelLineLen,
            len2: labelLineLen2,
            linePoints: linePoints,
            textAlign: textAlign,
            verticalAlign: 'middle',
            rotation: labelRotate,
            inside: isLabelInside,
            labelDistance: labelDistance,
            labelAlignTo: labelAlignTo,
            labelMargin: labelMargin,
            bleedMargin: bleedMargin,
            textRect: textRect,
            text: text,
            font: font
        };

        // Not layout the inside label
        if (!isLabelInside) {
            labelLayoutList.push(layout.label);
        }
    });
    if (!hasLabelRotate && seriesModel.get('avoidLabelOverlap')) {
        avoidOverlap(labelLayoutList, cx, cy, r, viewWidth, viewHeight, viewLeft, viewTop);
    }
};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/


var PI2$4 = Math.PI * 2;
var RADIAN = Math.PI / 180;

function getViewRect(seriesModel, api) {
    return getLayoutRect(
        seriesModel.getBoxLayoutParams(), {
            width: api.getWidth(),
            height: api.getHeight()
        }
    );
}

var pieLayout = function (seriesType, ecModel, api, payload) {
    ecModel.eachSeriesByType(seriesType, function (seriesModel) {
        var data = seriesModel.getData();
        var valueDim = data.mapDimension('value');
        var viewRect = getViewRect(seriesModel, api);

        var center = seriesModel.get('center');
        var radius = seriesModel.get('radius');

        if (!isArray(radius)) {
            radius = [0, radius];
        }
        if (!isArray(center)) {
            center = [center, center];
        }

        var width = parsePercent$1(viewRect.width, api.getWidth());
        var height = parsePercent$1(viewRect.height, api.getHeight());
        var size = Math.min(width, height);
        var cx = parsePercent$1(center[0], width) + viewRect.x;
        var cy = parsePercent$1(center[1], height) + viewRect.y;
        var r0 = parsePercent$1(radius[0], size / 2);
        var r = parsePercent$1(radius[1], size / 2);

        var startAngle = -seriesModel.get('startAngle') * RADIAN;

        var minAngle = seriesModel.get('minAngle') * RADIAN;

        var validDataCount = 0;
        data.each(valueDim, function (value) {
            !isNaN(value) && validDataCount++;
        });

        var sum = data.getSum(valueDim);
        // Sum may be 0
        var unitRadian = Math.PI / (sum || validDataCount) * 2;

        var clockwise = seriesModel.get('clockwise');

        var roseType = seriesModel.get('roseType');
        var stillShowZeroSum = seriesModel.get('stillShowZeroSum');

        // [0...max]
        var extent = data.getDataExtent(valueDim);
        extent[0] = 0;

        // In the case some sector angle is smaller than minAngle
        var restAngle = PI2$4;
        var valueSumLargerThanMinAngle = 0;

        var currentAngle = startAngle;
        var dir = clockwise ? 1 : -1;

        data.each(valueDim, function (value, idx) {
            var angle;
            if (isNaN(value)) {
                data.setItemLayout(idx, {
                    angle: NaN,
                    startAngle: NaN,
                    endAngle: NaN,
                    clockwise: clockwise,
                    cx: cx,
                    cy: cy,
                    r0: r0,
                    r: roseType
                        ? NaN
                        : r,
                    viewRect: viewRect
                });
                return;
            }

            // FIXME 兼容 2.0 但是 roseType 是 area 的时候才是这样？
            if (roseType !== 'area') {
                angle = (sum === 0 && stillShowZeroSum)
                    ? unitRadian : (value * unitRadian);
            }
            else {
                angle = PI2$4 / validDataCount;
            }

            if (angle < minAngle) {
                angle = minAngle;
                restAngle -= minAngle;
            }
            else {
                valueSumLargerThanMinAngle += value;
            }

            var endAngle = currentAngle + dir * angle;
            data.setItemLayout(idx, {
                angle: angle,
                startAngle: currentAngle,
                endAngle: endAngle,
                clockwise: clockwise,
                cx: cx,
                cy: cy,
                r0: r0,
                r: roseType
                    ? linearMap(value, extent, [r0, r])
                    : r,
                viewRect: viewRect
            });

            currentAngle = endAngle;
        });

        // Some sector is constrained by minAngle
        // Rest sectors needs recalculate angle
        if (restAngle < PI2$4 && validDataCount) {
            // Average the angle if rest angle is not enough after all angles is
            // Constrained by minAngle
            if (restAngle <= 1e-3) {
                var angle = PI2$4 / validDataCount;
                data.each(valueDim, function (value, idx) {
                    if (!isNaN(value)) {
                        var layout = data.getItemLayout(idx);
                        layout.angle = angle;
                        layout.startAngle = startAngle + dir * idx * angle;
                        layout.endAngle = startAngle + dir * (idx + 1) * angle;
                    }
                });
            }
            else {
                unitRadian = restAngle / valueSumLargerThanMinAngle;
                currentAngle = startAngle;
                data.each(valueDim, function (value, idx) {
                    if (!isNaN(value)) {
                        var layout = data.getItemLayout(idx);
                        var angle = layout.angle === minAngle
                            ? minAngle : value * unitRadian;
                        layout.startAngle = currentAngle;
                        layout.endAngle = currentAngle + dir * angle;
                        currentAngle += dir * angle;
                    }
                });
            }
        }

        labelLayout(seriesModel, r, viewRect.width, viewRect.height, viewRect.x, viewRect.y);
    });
};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var dataFilter = function (seriesType) {
    return {
        seriesType: seriesType,
        reset: function (seriesModel, ecModel) {
            var legendModels = ecModel.findComponents({
                mainType: 'legend'
            });
            if (!legendModels || !legendModels.length) {
                return;
            }
            var data = seriesModel.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;
            });
        }
    };
};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

createDataSelectAction('pie', [{
    type: 'pieToggleSelect',
    event: 'pieselectchanged',
    method: 'toggleSelected'
}, {
    type: 'pieSelect',
    event: 'pieselected',
    method: 'select'
}, {
    type: 'pieUnSelect',
    event: 'pieunselected',
    method: 'unSelect'
}]);

registerVisual(dataColor('pie'));
registerLayout(curry(pieLayout, 'pie'));
registerProcessor(dataFilter('pie'));

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

SeriesModel.extend({

    type: 'series.scatter',

    dependencies: ['grid', 'polar', 'geo', 'singleAxis', 'calendar'],

    getInitialData: function (option, ecModel) {
        return createListFromArray(this.getSource(), this, {useEncodeDefaulter: true});
    },

    brushSelector: 'point',

    getProgressive: function () {
        var progressive = this.option.progressive;
        if (progressive == null) {
            // PENDING
            return this.option.large ? 5e3 : this.get('progressive');
        }
        return progressive;
    },

    getProgressiveThreshold: function () {
        var progressiveThreshold = this.option.progressiveThreshold;
        if (progressiveThreshold == null) {
            // PENDING
            return this.option.large ? 1e4 : this.get('progressiveThreshold');
        }
        return progressiveThreshold;
    },

    defaultOption: {
        coordinateSystem: 'cartesian2d',
        zlevel: 0,
        z: 2,
        legendHoverLink: true,

        hoverAnimation: true,
        // Cartesian coordinate system
        // xAxisIndex: 0,
        // yAxisIndex: 0,

        // Polar coordinate system
        // polarIndex: 0,

        // Geo coordinate system
        // geoIndex: 0,

        // symbol: null,        // 图形类型
        symbolSize: 10,          // 图形大小，半宽（半径）参数，当图形为方向或菱形则总宽度为symbolSize * 2
        // symbolRotate: null,  // 图形旋转控制

        large: false,
        // Available when large is true
        largeThreshold: 2000,
        // cursor: null,

        // label: {
            // show: false
            // distance: 5,
            // formatter: 标签文本格式器，同Tooltip.formatter，不支持异步回调
            // position: 默认自适应，水平布局为'top'，垂直布局为'right'，可选为
            //           'inside'|'left'|'right'|'top'|'bottom'
            // 默认使用全局文本样式，详见TEXTSTYLE
        // },
        itemStyle: {
            opacity: 0.8
            // color: 各异
        },

        // If clip the overflow graphics
        // Works on cartesian / polar series
        clip: true

        // progressive: null
    }

});

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/* global Float32Array */

// TODO Batch by color

var BOOST_SIZE_THRESHOLD = 4;

var LargeSymbolPath = extendShape({

    shape: {
        points: null
    },

    symbolProxy: null,

    softClipShape: null,

    buildPath: function (path, shape) {
        var points = shape.points;
        var size = shape.size;

        var symbolProxy = this.symbolProxy;
        var symbolProxyShape = symbolProxy.shape;
        var ctx = path.getContext ? path.getContext() : path;
        var canBoost = ctx && size[0] < BOOST_SIZE_THRESHOLD;

        // Do draw in afterBrush.
        if (canBoost) {
            return;
        }

        for (var i = 0; i < points.length;) {
            var x = points[i++];
            var y = points[i++];

            if (isNaN(x) || isNaN(y)) {
                continue;
            }
            if (this.softClipShape && !this.softClipShape.contain(x, y)) {
                continue;
            }

            symbolProxyShape.x = x - size[0] / 2;
            symbolProxyShape.y = y - size[1] / 2;
            symbolProxyShape.width = size[0];
            symbolProxyShape.height = size[1];

            symbolProxy.buildPath(path, symbolProxyShape, true);
        }
    },

    afterBrush: function (ctx) {
        var shape = this.shape;
        var points = shape.points;
        var size = shape.size;
        var canBoost = size[0] < BOOST_SIZE_THRESHOLD;

        if (!canBoost) {
            return;
        }

        this.setTransform(ctx);
        // PENDING If style or other canvas status changed?
        for (var i = 0; i < points.length;) {
            var x = points[i++];
            var y = points[i++];
            if (isNaN(x) || isNaN(y)) {
                continue;
            }
            if (this.softClipShape && !this.softClipShape.contain(x, y)) {
                continue;
            }
            // fillRect is faster than building a rect path and draw.
            // And it support light globalCompositeOperation.
            ctx.fillRect(
                x - size[0] / 2, y - size[1] / 2,
                size[0], size[1]
            );
        }

        this.restoreTransform(ctx);
    },

    findDataIndex: function (x, y) {
        // TODO ???
        // Consider transform

        var shape = this.shape;
        var points = shape.points;
        var size = shape.size;

        var w = Math.max(size[0], 4);
        var h = Math.max(size[1], 4);

        // Not consider transform
        // Treat each element as a rect
        // top down traverse
        for (var idx = points.length / 2 - 1; idx >= 0; idx--) {
            var i = idx * 2;
            var x0 = points[i] - w / 2;
            var y0 = points[i + 1] - h / 2;
            if (x >= x0 && y >= y0 && x <= x0 + w && y <= y0 + h) {
                return idx;
            }
        }

        return -1;
    }
});

function LargeSymbolDraw() {
    this.group = new Group();
}

var largeSymbolProto = LargeSymbolDraw.prototype;

largeSymbolProto.isPersistent = function () {
    return !this._incremental;
};

/**
 * Update symbols draw by new data
 * @param {module:echarts/data/List} data
 * @param {Object} opt
 * @param {Object} [opt.clipShape]
 */
largeSymbolProto.updateData = function (data, opt) {
    this.group.removeAll();
    var symbolEl = new LargeSymbolPath({
        rectHover: true,
        cursor: 'default'
    });

    symbolEl.setShape({
        points: data.getLayout('symbolPoints')
    });
    this._setCommon(symbolEl, data, false, opt);
    this.group.add(symbolEl);

    this._incremental = null;
};

largeSymbolProto.updateLayout = function (data) {
    if (this._incremental) {
        return;
    }

    var points = data.getLayout('symbolPoints');
    this.group.eachChild(function (child) {
        if (child.startIndex != null) {
            var len = (child.endIndex - child.startIndex) * 2;
            var byteOffset = child.startIndex * 4 * 2;
            points = new Float32Array(points.buffer, byteOffset, len);
        }
        child.setShape('points', points);
    });
};

largeSymbolProto.incrementalPrepareUpdate = function (data) {
    this.group.removeAll();

    this._clearIncremental();
    // Only use incremental displayables when data amount is larger than 2 million.
    // PENDING Incremental data?
    if (data.count() > 2e6) {
        if (!this._incremental) {
            this._incremental = new IncrementalDisplayble({
                silent: true
            });
        }
        this.group.add(this._incremental);
    }
    else {
        this._incremental = null;
    }
};

largeSymbolProto.incrementalUpdate = function (taskParams, data, opt) {
    var symbolEl;
    if (this._incremental) {
        symbolEl = new LargeSymbolPath();
        this._incremental.addDisplayable(symbolEl, true);
    }
    else {
        symbolEl = new LargeSymbolPath({
            rectHover: true,
            cursor: 'default',
            startIndex: taskParams.start,
            endIndex: taskParams.end
        });
        symbolEl.incremental = true;
        this.group.add(symbolEl);
    }

    symbolEl.setShape({
        points: data.getLayout('symbolPoints')
    });
    this._setCommon(symbolEl, data, !!this._incremental, opt);
};

largeSymbolProto._setCommon = function (symbolEl, data, isIncremental, opt) {
    var hostModel = data.hostModel;

    opt = opt || {};
    // TODO
    // if (data.hasItemVisual.symbolSize) {
    //     // TODO typed array?
    //     symbolEl.setShape('sizes', data.mapArray(
    //         function (idx) {
    //             var size = data.getItemVisual(idx, 'symbolSize');
    //             return (size instanceof Array) ? size : [size, size];
    //         }
    //     ));
    // }
    // else {
    var size = data.getVisual('symbolSize');
    symbolEl.setShape('size', (size instanceof Array) ? size : [size, size]);
    // }

    symbolEl.softClipShape = opt.clipShape || null;
    // Create symbolProxy to build path for each data
    symbolEl.symbolProxy = createSymbol(
        data.getVisual('symbol'), 0, 0, 0, 0
    );
    // Use symbolProxy setColor method
    symbolEl.setColor = symbolEl.symbolProxy.setColor;

    var extrudeShadow = symbolEl.shape.size[0] < BOOST_SIZE_THRESHOLD;
    symbolEl.useStyle(
        // Draw shadow when doing fillRect is extremely slow.
        hostModel.getModel('itemStyle').getItemStyle(extrudeShadow ? ['color', 'shadowBlur', 'shadowColor'] : ['color'])
    );

    var visualColor = data.getVisual('color');
    if (visualColor) {
        symbolEl.setColor(visualColor);
    }

    if (!isIncremental) {
        // Enable tooltip
        // PENDING May have performance issue when path is extremely large
        symbolEl.seriesIndex = hostModel.seriesIndex;
        symbolEl.on('mousemove', function (e) {
            symbolEl.dataIndex = null;
            var dataIndex = symbolEl.findDataIndex(e.offsetX, e.offsetY);
            if (dataIndex >= 0) {
                // Provide dataIndex for tooltip
                symbolEl.dataIndex = dataIndex + (symbolEl.startIndex || 0);
            }
        });
    }
};

largeSymbolProto.remove = function () {
    this._clearIncremental();
    this._incremental = null;
    this.group.removeAll();
};

largeSymbolProto._clearIncremental = function () {
    var incremental = this._incremental;
    if (incremental) {
        incremental.clearDisplaybles();
    }
};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

extendChartView({

    type: 'scatter',

    render: function (seriesModel, ecModel, api) {
        var data = seriesModel.getData();

        var symbolDraw = this._updateSymbolDraw(data, seriesModel);

        symbolDraw.updateData(data, {
            // TODO
            // If this parameter should be a shape or a bounding volume
            // shape will be more general.
            // But bounding volume like bounding rect will be much faster in the contain calculation
            clipShape: this._getClipShape(seriesModel)
        });

        this._finished = true;
    },

    incrementalPrepareRender: function (seriesModel, ecModel, api) {
        var data = seriesModel.getData();
        var symbolDraw = this._updateSymbolDraw(data, seriesModel);

        symbolDraw.incrementalPrepareUpdate(data);

        this._finished = false;
    },

    incrementalRender: function (taskParams, seriesModel, ecModel) {
        this._symbolDraw.incrementalUpdate(taskParams, seriesModel.getData(), {
            clipShape: this._getClipShape(seriesModel)
        });

        this._finished = taskParams.end === seriesModel.getData().count();
    },

    updateTransform: function (seriesModel, ecModel, api) {
        var data = seriesModel.getData();
        // Must mark group dirty and make sure the incremental layer will be cleared
        // PENDING
        this.group.dirty();

        if (!this._finished || data.count() > 1e4 || !this._symbolDraw.isPersistent()) {
            return {
                update: true
            };
        }
        else {
            var res = pointsLayout().reset(seriesModel);
            if (res.progress) {
                res.progress({ start: 0, end: data.count() }, data);
            }

            this._symbolDraw.updateLayout(data);
        }
    },

    _getClipShape: function (seriesModel) {
        var coordSys = seriesModel.coordinateSystem;
        var clipArea = coordSys && coordSys.getArea && coordSys.getArea();
        return seriesModel.get('clip', true) ? clipArea : null;
    },

    _updateSymbolDraw: function (data, seriesModel) {
        var symbolDraw = this._symbolDraw;
        var pipelineContext = seriesModel.pipelineContext;
        var isLargeDraw = pipelineContext.large;

        if (!symbolDraw || isLargeDraw !== this._isLargeDraw) {
            symbolDraw && symbolDraw.remove();
            symbolDraw = this._symbolDraw = isLargeDraw
                ? new LargeSymbolDraw()
                : new SymbolDraw();
            this._isLargeDraw = isLargeDraw;
            this.group.removeAll();
        }

        this.group.add(symbolDraw.group);

        return symbolDraw;
    },

    remove: function (ecModel, api) {
        this._symbolDraw && this._symbolDraw.remove(true);
        this._symbolDraw = null;
    },

    dispose: function () {}
});

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

// import * as zrUtil from 'zrender/src/core/util';

// In case developer forget to include grid component
registerVisual(visualSymbol('scatter', 'circle'));
registerLayout(pointsLayout('scatter'));

// echarts.registerProcessor(function (ecModel, api) {
//     ecModel.eachSeriesByType('scatter', function (seriesModel) {
//         var data = seriesModel.getData();
//         var coordSys = seriesModel.coordinateSystem;
//         if (coordSys.type !== 'geo') {
//             return;
//         }
//         var startPt = coordSys.pointToData([0, 0]);
//         var endPt = coordSys.pointToData([api.getWidth(), api.getHeight()]);

//         var dims = zrUtil.map(coordSys.dimensions, function (dim) {
//             return data.mapDimension(dim);
//         });
//         var range = {};
//         range[dims[0]] = [Math.min(startPt[0], endPt[0]), Math.max(startPt[0], endPt[0])];
//         range[dims[1]] = [Math.min(startPt[1], endPt[1]), Math.max(startPt[1], endPt[1])];

//         data.selectRange(range);
//     });
// });

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var _nonShapeGraphicElements = {

    // Reserved but not supported in graphic component.
    path: null,
    compoundPath: null,

    // Supported in graphic component.
    group: Group,
    image: ZImage,
    text: Text
};

// -------------
// Preprocessor
// -------------

registerPreprocessor(function (option) {
    var graphicOption = option.graphic;

    // Convert
    // {graphic: [{left: 10, type: 'circle'}, ...]}
    // or
    // {graphic: {left: 10, type: 'circle'}}
    // to
    // {graphic: [{elements: [{left: 10, type: 'circle'}, ...]}]}
    if (isArray(graphicOption)) {
        if (!graphicOption[0] || !graphicOption[0].elements) {
            option.graphic = [{elements: graphicOption}];
        }
        else {
            // Only one graphic instance can be instantiated. (We dont
            // want that too many views are created in echarts._viewMap)
            option.graphic = [option.graphic[0]];
        }
    }
    else if (graphicOption && !graphicOption.elements) {
        option.graphic = [{elements: [graphicOption]}];
    }
});

// ------
// Model
// ------

var GraphicModel = extendComponentModel({

    type: 'graphic',

    defaultOption: {

        // Extra properties for each elements:
        //
        // left/right/top/bottom: (like 12, '22%', 'center', default undefined)
        //      If left/rigth is set, shape.x/shape.cx/position will not be used.
        //      If top/bottom is set, shape.y/shape.cy/position will not be used.
        //      This mechanism is useful when you want to position a group/element
        //      against the right side or the center of this container.
        //
        // width/height: (can only be pixel value, default 0)
        //      Only be used to specify contianer(group) size, if needed. And
        //      can not be percentage value (like '33%'). See the reason in the
        //      layout algorithm below.
        //
        // bounding: (enum: 'all' (default) | 'raw')
        //      Specify how to calculate boundingRect when locating.
        //      'all': Get uioned and transformed boundingRect
        //          from both itself and its descendants.
        //          This mode simplies confining a group of elements in the bounding
        //          of their ancester container (e.g., using 'right: 0').
        //      'raw': Only use the boundingRect of itself and before transformed.
        //          This mode is similar to css behavior, which is useful when you
        //          want an element to be able to overflow its container. (Consider
        //          a rotated circle needs to be located in a corner.)
        // info: custom info. enables user to mount some info on elements and use them
        //      in event handlers. Update them only when user specified, otherwise, remain.

        // Note: elements is always behind its ancestors in this elements array.
        elements: [],
        parentId: null
    },

    /**
     * Save el options for the sake of the performance (only update modified graphics).
     * The order is the same as those in option. (ancesters -> descendants)
     *
     * @private
     * @type {Array.<Object>}
     */
    _elOptionsToUpdate: null,

    /**
     * @override
     */
    mergeOption: function (option) {
        // Prevent default merge to elements
        var elements = this.option.elements;
        this.option.elements = null;

        GraphicModel.superApply(this, 'mergeOption', arguments);

        this.option.elements = elements;
    },

    /**
     * @override
     */
    optionUpdated: function (newOption, isInit) {
        var thisOption = this.option;
        var newList = (isInit ? thisOption : newOption).elements;
        var existList = thisOption.elements = isInit ? [] : thisOption.elements;

        var flattenedList = [];
        this._flatten(newList, flattenedList);

        var mappingResult = mappingToExists(existList, flattenedList);
        makeIdAndName(mappingResult);

        // Clear elOptionsToUpdate
        var elOptionsToUpdate = this._elOptionsToUpdate = [];

        each$1(mappingResult, function (resultItem, index) {
            var newElOption = resultItem.option;

            if (__DEV__) {
                assert$1(
                    isObject$1(newElOption) || resultItem.exist,
                    'Empty graphic option definition'
                );
            }

            if (!newElOption) {
                return;
            }

            elOptionsToUpdate.push(newElOption);

            setKeyInfoToNewElOption(resultItem, newElOption);

            mergeNewElOptionToExist(existList, index, newElOption);

            setLayoutInfoToExist(existList[index], newElOption);

        }, this);

        // Clean
        for (var i = existList.length - 1; i >= 0; i--) {
            if (existList[i] == null) {
                existList.splice(i, 1);
            }
            else {
                // $action should be volatile, otherwise option gotten from
                // `getOption` will contain unexpected $action.
                delete existList[i].$action;
            }
        }
    },

    /**
     * Convert
     * [{
     *  type: 'group',
     *  id: 'xx',
     *  children: [{type: 'circle'}, {type: 'polygon'}]
     * }]
     * to
     * [
     *  {type: 'group', id: 'xx'},
     *  {type: 'circle', parentId: 'xx'},
     *  {type: 'polygon', parentId: 'xx'}
     * ]
     *
     * @private
     * @param {Array.<Object>} optionList option list
     * @param {Array.<Object>} result result of flatten
     * @param {Object} parentOption parent option
     */
    _flatten: function (optionList, result, parentOption) {
        each$1(optionList, function (option) {
            if (!option) {
                return;
            }

            if (parentOption) {
                option.parentOption = parentOption;
            }

            result.push(option);

            var children = option.children;
            if (option.type === 'group' && children) {
                this._flatten(children, result, option);
            }
            // Deleting for JSON output, and for not affecting group creation.
            delete option.children;
        }, this);
    },

    // FIXME
    // Pass to view using payload? setOption has a payload?
    useElOptionsToUpdate: function () {
        var els = this._elOptionsToUpdate;
        // Clear to avoid render duplicately when zooming.
        this._elOptionsToUpdate = null;
        return els;
    }
});

// -----
// View
// -----

extendComponentView({

    type: 'graphic',

    /**
     * @override
     */
    init: function (ecModel, api) {

        /**
         * @private
         * @type {module:zrender/core/util.HashMap}
         */
        this._elMap = createHashMap();

        /**
         * @private
         * @type {module:echarts/graphic/GraphicModel}
         */
        this._lastGraphicModel;
    },

    /**
     * @override
     */
    render: function (graphicModel, ecModel, api) {

        // Having leveraged between use cases and algorithm complexity, a very
        // simple layout mechanism is used:
        // The size(width/height) can be determined by itself or its parent (not
        // implemented yet), but can not by its children. (Top-down travel)
        // The location(x/y) can be determined by the bounding rect of itself
        // (can including its descendants or not) and the size of its parent.
        // (Bottom-up travel)

        // When `chart.clear()` or `chart.setOption({...}, true)` with the same id,
        // view will be reused.
        if (graphicModel !== this._lastGraphicModel) {
            this._clear();
        }
        this._lastGraphicModel = graphicModel;

        this._updateElements(graphicModel);
        this._relocate(graphicModel, api);
    },

    /**
     * Update graphic elements.
     *
     * @private
     * @param {Object} graphicModel graphic model
     */
    _updateElements: function (graphicModel) {
        var elOptionsToUpdate = graphicModel.useElOptionsToUpdate();

        if (!elOptionsToUpdate) {
            return;
        }

        var elMap = this._elMap;
        var rootGroup = this.group;

        // Top-down tranverse to assign graphic settings to each elements.
        each$1(elOptionsToUpdate, function (elOption) {
            var $action = elOption.$action;
            var id = elOption.id;
            var existEl = elMap.get(id);
            var parentId = elOption.parentId;
            var targetElParent = parentId != null ? elMap.get(parentId) : rootGroup;

            var elOptionStyle = elOption.style;
            if (elOption.type === 'text' && elOptionStyle) {
                // In top/bottom mode, textVerticalAlign should not be used, which cause
                // inaccurately locating.
                if (elOption.hv && elOption.hv[1]) {
                    elOptionStyle.textVerticalAlign = elOptionStyle.textBaseline = null;
                }

                // Compatible with previous setting: both support fill and textFill,
                // stroke and textStroke.
                !elOptionStyle.hasOwnProperty('textFill') && elOptionStyle.fill && (
                    elOptionStyle.textFill = elOptionStyle.fill
                );
                !elOptionStyle.hasOwnProperty('textStroke') && elOptionStyle.stroke && (
                    elOptionStyle.textStroke = elOptionStyle.stroke
                );
            }

            // Remove unnecessary props to avoid potential problems.
            var elOptionCleaned = getCleanedElOption(elOption);

            // For simple, do not support parent change, otherwise reorder is needed.
            if (__DEV__) {
                existEl && assert$1(
                    targetElParent === existEl.parent,
                    'Changing parent is not supported.'
                );
            }

            if (!$action || $action === 'merge') {
                existEl
                    ? existEl.attr(elOptionCleaned)
                    : createEl(id, targetElParent, elOptionCleaned, elMap);
            }
            else if ($action === 'replace') {
                removeEl(existEl, elMap);
                createEl(id, targetElParent, elOptionCleaned, elMap);
            }
            else if ($action === 'remove') {
                removeEl(existEl, elMap);
            }

            var el = elMap.get(id);
            if (el) {
                el.__ecGraphicWidthOption = elOption.width;
                el.__ecGraphicHeightOption = elOption.height;
                setEventData(el, graphicModel, elOption);
            }
        });
    },

    /**
     * Locate graphic elements.
     *
     * @private
     * @param {Object} graphicModel graphic model
     * @param {module:echarts/ExtensionAPI} api extension API
     */
    _relocate: function (graphicModel, api) {
        var elOptions = graphicModel.option.elements;
        var rootGroup = this.group;
        var elMap = this._elMap;
        var apiWidth = api.getWidth();
        var apiHeight = api.getHeight();

        // Top-down to calculate percentage width/height of group
        for (var i = 0; i < elOptions.length; i++) {
            var elOption = elOptions[i];
            var el = elMap.get(elOption.id);

            if (!el || !el.isGroup) {
                continue;
            }
            var parentEl = el.parent;
            var isParentRoot = parentEl === rootGroup;
            // Like 'position:absolut' in css, default 0.
            el.__ecGraphicWidth = parsePercent$1(
                el.__ecGraphicWidthOption,
                isParentRoot ? apiWidth : parentEl.__ecGraphicWidth
            ) || 0;
            el.__ecGraphicHeight = parsePercent$1(
                el.__ecGraphicHeightOption,
                isParentRoot ? apiHeight : parentEl.__ecGraphicHeight
            ) || 0;
        }

        // Bottom-up tranvese all elements (consider ec resize) to locate elements.
        for (var i = elOptions.length - 1; i >= 0; i--) {
            var elOption = elOptions[i];
            var el = elMap.get(elOption.id);

            if (!el) {
                continue;
            }

            var parentEl = el.parent;
            var containerInfo = parentEl === rootGroup
                ? {
                    width: apiWidth,
                    height: apiHeight
                }
                : {
                    width: parentEl.__ecGraphicWidth,
                    height: parentEl.__ecGraphicHeight
                };

            // PENDING
            // Currently, when `bounding: 'all'`, the union bounding rect of the group
            // does not include the rect of [0, 0, group.width, group.height], which
            // is probably weird for users. Should we make a break change for it?
            positionElement(
                el, elOption, containerInfo, null,
                {hv: elOption.hv, boundingMode: elOption.bounding}
            );
        }
    },

    /**
     * Clear all elements.
     *
     * @private
     */
    _clear: function () {
        var elMap = this._elMap;
        elMap.each(function (el) {
            removeEl(el, elMap);
        });
        this._elMap = createHashMap();
    },

    /**
     * @override
     */
    dispose: function () {
        this._clear();
    }
});

function createEl(id, targetElParent, elOption, elMap) {
    var graphicType = elOption.type;

    if (__DEV__) {
        assert$1(graphicType, 'graphic type MUST be set');
    }

    var Clz = _nonShapeGraphicElements.hasOwnProperty(graphicType)
        // Those graphic elements are not shapes. They should not be
        // overwritten by users, so do them first.
        ? _nonShapeGraphicElements[graphicType]
        : getShapeClass(graphicType);

    if (__DEV__) {
        assert$1(Clz, 'graphic type can not be found');
    }

    var el = new Clz(elOption);
    targetElParent.add(el);
    elMap.set(id, el);
    el.__ecGraphicId = id;
}

function removeEl(existEl, elMap) {
    var existElParent = existEl && existEl.parent;
    if (existElParent) {
        existEl.type === 'group' && existEl.traverse(function (el) {
            removeEl(el, elMap);
        });
        elMap.removeKey(existEl.__ecGraphicId);
        existElParent.remove(existEl);
    }
}

// Remove unnecessary props to avoid potential problems.
function getCleanedElOption(elOption) {
    elOption = extend({}, elOption);
    each$1(
        ['id', 'parentId', '$action', 'hv', 'bounding'].concat(LOCATION_PARAMS),
        function (name) {
            delete elOption[name];
        }
    );
    return elOption;
}

function isSetLoc(obj, props) {
    var isSet;
    each$1(props, function (prop) {
        obj[prop] != null && obj[prop] !== 'auto' && (isSet = true);
    });
    return isSet;
}

function setKeyInfoToNewElOption(resultItem, newElOption) {
    var existElOption = resultItem.exist;

    // Set id and type after id assigned.
    newElOption.id = resultItem.keyInfo.id;
    !newElOption.type && existElOption && (newElOption.type = existElOption.type);

    // Set parent id if not specified
    if (newElOption.parentId == null) {
        var newElParentOption = newElOption.parentOption;
        if (newElParentOption) {
            newElOption.parentId = newElParentOption.id;
        }
        else if (existElOption) {
            newElOption.parentId = existElOption.parentId;
        }
    }

    // Clear
    newElOption.parentOption = null;
}

function mergeNewElOptionToExist(existList, index, newElOption) {
    // Update existing options, for `getOption` feature.
    var newElOptCopy = extend({}, newElOption);
    var existElOption = existList[index];

    var $action = newElOption.$action || 'merge';
    if ($action === 'merge') {
        if (existElOption) {

            if (__DEV__) {
                var newType = newElOption.type;
                assert$1(
                    !newType || existElOption.type === newType,
                    'Please set $action: "replace" to change `type`'
                );
            }

            // We can ensure that newElOptCopy and existElOption are not
            // the same object, so `merge` will not change newElOptCopy.
            merge(existElOption, newElOptCopy, true);
            // Rigid body, use ignoreSize.
            mergeLayoutParam(existElOption, newElOptCopy, {ignoreSize: true});
            // Will be used in render.
            copyLayoutParams(newElOption, existElOption);
        }
        else {
            existList[index] = newElOptCopy;
        }
    }
    else if ($action === 'replace') {
        existList[index] = newElOptCopy;
    }
    else if ($action === 'remove') {
        // null will be cleaned later.
        existElOption && (existList[index] = null);
    }
}

function setLayoutInfoToExist(existItem, newElOption) {
    if (!existItem) {
        return;
    }
    existItem.hv = newElOption.hv = [
        // Rigid body, dont care `width`.
        isSetLoc(newElOption, ['left', 'right']),
        // Rigid body, dont care `height`.
        isSetLoc(newElOption, ['top', 'bottom'])
    ];
    // Give default group size. Otherwise layout error may occur.
    if (existItem.type === 'group') {
        existItem.width == null && (existItem.width = newElOption.width = 0);
        existItem.height == null && (existItem.height = newElOption.height = 0);
    }
}

function setEventData(el, graphicModel, elOption) {
    var eventData = el.eventData;
    // Simple optimize for large amount of elements that no need event.
    if (!el.silent && !el.ignore && !eventData) {
        eventData = el.eventData = {
            componentType: 'graphic',
            componentIndex: graphicModel.componentIndex,
            name: el.name
        };
    }

    // `elOption.info` enables user to mount some info on
    // elements and use them in event handlers.
    if (eventData) {
        eventData.info = el.info;
    }
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * @param {Object} finder contains {seriesIndex, dataIndex, dataIndexInside}
 * @param {module:echarts/model/Global} ecModel
 * @return {Object} {point: [x, y], el: ...} point Will not be null.
 */
var findPointFromSeries = function (finder, ecModel) {
    var point = [];
    var seriesIndex = finder.seriesIndex;
    var seriesModel;
    if (seriesIndex == null || !(
        seriesModel = ecModel.getSeriesByIndex(seriesIndex)
    )) {
        return {point: []};
    }

    var data = seriesModel.getData();
    var dataIndex = queryDataIndex(data, finder);
    if (dataIndex == null || dataIndex < 0 || isArray(dataIndex)) {
        return {point: []};
    }

    var el = data.getItemGraphicEl(dataIndex);
    var coordSys = seriesModel.coordinateSystem;

    if (seriesModel.getTooltipPosition) {
        point = seriesModel.getTooltipPosition(dataIndex) || [];
    }
    else if (coordSys && coordSys.dataToPoint) {
        point = coordSys.dataToPoint(
            data.getValues(
                map(coordSys.dimensions, function (dim) {
                    return data.mapDimension(dim);
                }), dataIndex, true
            )
        ) || [];
    }
    else if (el) {
        // Use graphic bounding rect
        var rect = el.getBoundingRect().clone();
        rect.applyTransform(el.transform);
        point = [
            rect.x + rect.width / 2,
            rect.y + rect.height / 2
        ];
    }

    return {point: point, el: el};
};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var each$7 = each$1;
var curry$2 = curry;
var inner$7 = makeInner();

/**
 * Basic logic: check all axis, if they do not demand show/highlight,
 * then hide/downplay them.
 *
 * @param {Object} coordSysAxesInfo
 * @param {Object} payload
 * @param {string} [payload.currTrigger] 'click' | 'mousemove' | 'leave'
 * @param {Array.<number>} [payload.x] x and y, which are mandatory, specify a point to
 *              trigger axisPointer and tooltip.
 * @param {Array.<number>} [payload.y] x and y, which are mandatory, specify a point to
 *              trigger axisPointer and tooltip.
 * @param {Object} [payload.seriesIndex] finder, optional, restrict target axes.
 * @param {Object} [payload.dataIndex] finder, restrict target axes.
 * @param {Object} [payload.axesInfo] finder, restrict target axes.
 *        [{
 *          axisDim: 'x'|'y'|'angle'|...,
 *          axisIndex: ...,
 *          value: ...
 *        }, ...]
 * @param {Function} [payload.dispatchAction]
 * @param {Object} [payload.tooltipOption]
 * @param {Object|Array.<number>|Function} [payload.position] Tooltip position,
 *        which can be specified in dispatchAction
 * @param {module:echarts/model/Global} ecModel
 * @param {module:echarts/ExtensionAPI} api
 * @return {Object} content of event obj for echarts.connect.
 */
var axisTrigger = function (payload, ecModel, api) {
    var currTrigger = payload.currTrigger;
    var point = [payload.x, payload.y];
    var finder = payload;
    var dispatchAction = payload.dispatchAction || bind(api.dispatchAction, api);
    var coordSysAxesInfo = ecModel.getComponent('axisPointer').coordSysAxesInfo;

    // Pending
    // See #6121. But we are not able to reproduce it yet.
    if (!coordSysAxesInfo) {
        return;
    }

    if (illegalPoint(point)) {
        // Used in the default behavior of `connection`: use the sample seriesIndex
        // and dataIndex. And also used in the tooltipView trigger.
        point = findPointFromSeries({
            seriesIndex: finder.seriesIndex,
            // Do not use dataIndexInside from other ec instance.
            // FIXME: auto detect it?
            dataIndex: finder.dataIndex
        }, ecModel).point;
    }
    var isIllegalPoint = illegalPoint(point);

    // Axis and value can be specified when calling dispatchAction({type: 'updateAxisPointer'}).
    // Notice: In this case, it is difficult to get the `point` (which is necessary to show
    // tooltip, so if point is not given, we just use the point found by sample seriesIndex
    // and dataIndex.
    var inputAxesInfo = finder.axesInfo;

    var axesInfo = coordSysAxesInfo.axesInfo;
    var shouldHide = currTrigger === 'leave' || illegalPoint(point);
    var outputFinder = {};

    var showValueMap = {};
    var dataByCoordSys = {list: [], map: {}};
    var updaters = {
        showPointer: curry$2(showPointer, showValueMap),
        showTooltip: curry$2(showTooltip, dataByCoordSys)
    };

    // Process for triggered axes.
    each$7(coordSysAxesInfo.coordSysMap, function (coordSys, coordSysKey) {
        // If a point given, it must be contained by the coordinate system.
        var coordSysContainsPoint = isIllegalPoint || coordSys.containPoint(point);

        each$7(coordSysAxesInfo.coordSysAxesInfo[coordSysKey], function (axisInfo, key) {
            var axis = axisInfo.axis;
            var inputAxisInfo = findInputAxisInfo(inputAxesInfo, axisInfo);
            // If no inputAxesInfo, no axis is restricted.
            if (!shouldHide && coordSysContainsPoint && (!inputAxesInfo || inputAxisInfo)) {
                var val = inputAxisInfo && inputAxisInfo.value;
                if (val == null && !isIllegalPoint) {
                    val = axis.pointToData(point);
                }
                val != null && processOnAxis(axisInfo, val, updaters, false, outputFinder);
            }
        });
    });

    // Process for linked axes.
    var linkTriggers = {};
    each$7(axesInfo, function (tarAxisInfo, tarKey) {
        var linkGroup = tarAxisInfo.linkGroup;

        // If axis has been triggered in the previous stage, it should not be triggered by link.
        if (linkGroup && !showValueMap[tarKey]) {
            each$7(linkGroup.axesInfo, function (srcAxisInfo, srcKey) {
                var srcValItem = showValueMap[srcKey];
                // If srcValItem exist, source axis is triggered, so link to target axis.
                if (srcAxisInfo !== tarAxisInfo && srcValItem) {
                    var val = srcValItem.value;
                    linkGroup.mapper && (val = tarAxisInfo.axis.scale.parse(linkGroup.mapper(
                        val, makeMapperParam(srcAxisInfo), makeMapperParam(tarAxisInfo)
                    )));
                    linkTriggers[tarAxisInfo.key] = val;
                }
            });
        }
    });
    each$7(linkTriggers, function (val, tarKey) {
        processOnAxis(axesInfo[tarKey], val, updaters, true, outputFinder);
    });

    updateModelActually(showValueMap, axesInfo, outputFinder);
    dispatchTooltipActually(dataByCoordSys, point, payload, dispatchAction);
    dispatchHighDownActually(axesInfo, dispatchAction, api);

    return outputFinder;
};

function processOnAxis(axisInfo, newValue, updaters, dontSnap, outputFinder) {
    var axis = axisInfo.axis;

    if (axis.scale.isBlank() || !axis.containData(newValue)) {
        return;
    }

    if (!axisInfo.involveSeries) {
        updaters.showPointer(axisInfo, newValue);
        return;
    }

    // Heavy calculation. So put it after axis.containData checking.
    var payloadInfo = buildPayloadsBySeries(newValue, axisInfo);
    var payloadBatch = payloadInfo.payloadBatch;
    var snapToValue = payloadInfo.snapToValue;

    // Fill content of event obj for echarts.connect.
    // By default use the first involved series data as a sample to connect.
    if (payloadBatch[0] && outputFinder.seriesIndex == null) {
        extend(outputFinder, payloadBatch[0]);
    }

    // If no linkSource input, this process is for collecting link
    // target, where snap should not be accepted.
    if (!dontSnap && axisInfo.snap) {
        if (axis.containData(snapToValue) && snapToValue != null) {
            newValue = snapToValue;
        }
    }

    updaters.showPointer(axisInfo, newValue, payloadBatch, outputFinder);
    // Tooltip should always be snapToValue, otherwise there will be
    // incorrect "axis value ~ series value" mapping displayed in tooltip.
    updaters.showTooltip(axisInfo, payloadInfo, snapToValue);
}

function buildPayloadsBySeries(value, axisInfo) {
    var axis = axisInfo.axis;
    var dim = axis.dim;
    var snapToValue = value;
    var payloadBatch = [];
    var minDist = Number.MAX_VALUE;
    var minDiff = -1;

    each$7(axisInfo.seriesModels, function (series, idx) {
        var dataDim = series.getData().mapDimension(dim, true);
        var seriesNestestValue;
        var dataIndices;

        if (series.getAxisTooltipData) {
            var result = series.getAxisTooltipData(dataDim, value, axis);
            dataIndices = result.dataIndices;
            seriesNestestValue = result.nestestValue;
        }
        else {
            dataIndices = series.getData().indicesOfNearest(
                dataDim[0],
                value,
                // Add a threshold to avoid find the wrong dataIndex
                // when data length is not same.
                // false,
                axis.type === 'category' ? 0.5 : null
            );
            if (!dataIndices.length) {
                return;
            }
            seriesNestestValue = series.getData().get(dataDim[0], dataIndices[0]);
        }

        if (seriesNestestValue == null || !isFinite(seriesNestestValue)) {
            return;
        }

        var diff = value - seriesNestestValue;
        var dist = Math.abs(diff);
        // Consider category case
        if (dist <= minDist) {
            if (dist < minDist || (diff >= 0 && minDiff < 0)) {
                minDist = dist;
                minDiff = diff;
                snapToValue = seriesNestestValue;
                payloadBatch.length = 0;
            }
            each$7(dataIndices, function (dataIndex) {
                payloadBatch.push({
                    seriesIndex: series.seriesIndex,
                    dataIndexInside: dataIndex,
                    dataIndex: series.getData().getRawIndex(dataIndex)
                });
            });
        }
    });

    return {
        payloadBatch: payloadBatch,
        snapToValue: snapToValue
    };
}

function showPointer(showValueMap, axisInfo, value, payloadBatch) {
    showValueMap[axisInfo.key] = {value: value, payloadBatch: payloadBatch};
}

function showTooltip(dataByCoordSys, axisInfo, payloadInfo, value) {
    var payloadBatch = payloadInfo.payloadBatch;
    var axis = axisInfo.axis;
    var axisModel = axis.model;
    var axisPointerModel = axisInfo.axisPointerModel;

    // If no data, do not create anything in dataByCoordSys,
    // whose length will be used to judge whether dispatch action.
    if (!axisInfo.triggerTooltip || !payloadBatch.length) {
        return;
    }

    var coordSysModel = axisInfo.coordSys.model;
    var coordSysKey = makeKey(coordSysModel);
    var coordSysItem = dataByCoordSys.map[coordSysKey];
    if (!coordSysItem) {
        coordSysItem = dataByCoordSys.map[coordSysKey] = {
            coordSysId: coordSysModel.id,
            coordSysIndex: coordSysModel.componentIndex,
            coordSysType: coordSysModel.type,
            coordSysMainType: coordSysModel.mainType,
            dataByAxis: []
        };
        dataByCoordSys.list.push(coordSysItem);
    }

    coordSysItem.dataByAxis.push({
        axisDim: axis.dim,
        axisIndex: axisModel.componentIndex,
        axisType: axisModel.type,
        axisId: axisModel.id,
        value: value,
        // Caustion: viewHelper.getValueLabel is actually on "view stage", which
        // depends that all models have been updated. So it should not be performed
        // here. Considering axisPointerModel used here is volatile, which is hard
        // to be retrieve in TooltipView, we prepare parameters here.
        valueLabelOpt: {
            precision: axisPointerModel.get('label.precision'),
            formatter: axisPointerModel.get('label.formatter')
        },
        seriesDataIndices: payloadBatch.slice()
    });
}

function updateModelActually(showValueMap, axesInfo, outputFinder) {
    var outputAxesInfo = outputFinder.axesInfo = [];
    // Basic logic: If no 'show' required, 'hide' this axisPointer.
    each$7(axesInfo, function (axisInfo, key) {
        var option = axisInfo.axisPointerModel.option;
        var valItem = showValueMap[key];

        if (valItem) {
            !axisInfo.useHandle && (option.status = 'show');
            option.value = valItem.value;
            // For label formatter param and highlight.
            option.seriesDataIndices = (valItem.payloadBatch || []).slice();
        }
        // When always show (e.g., handle used), remain
        // original value and status.
        else {
            // If hide, value still need to be set, consider
            // click legend to toggle axis blank.
            !axisInfo.useHandle && (option.status = 'hide');
        }

        // If status is 'hide', should be no info in payload.
        option.status === 'show' && outputAxesInfo.push({
            axisDim: axisInfo.axis.dim,
            axisIndex: axisInfo.axis.model.componentIndex,
            value: option.value
        });
    });
}

function dispatchTooltipActually(dataByCoordSys, point, payload, dispatchAction) {
    // Basic logic: If no showTip required, hideTip will be dispatched.
    if (illegalPoint(point) || !dataByCoordSys.list.length) {
        dispatchAction({type: 'hideTip'});
        return;
    }

    // In most case only one axis (or event one series is used). It is
    // convinient to fetch payload.seriesIndex and payload.dataIndex
    // dirtectly. So put the first seriesIndex and dataIndex of the first
    // axis on the payload.
    var sampleItem = ((dataByCoordSys.list[0].dataByAxis[0] || {}).seriesDataIndices || [])[0] || {};

    dispatchAction({
        type: 'showTip',
        escapeConnect: true,
        x: point[0],
        y: point[1],
        tooltipOption: payload.tooltipOption,
        position: payload.position,
        dataIndexInside: sampleItem.dataIndexInside,
        dataIndex: sampleItem.dataIndex,
        seriesIndex: sampleItem.seriesIndex,
        dataByCoordSys: dataByCoordSys.list
    });
}

function dispatchHighDownActually(axesInfo, dispatchAction, api) {
    // FIXME
    // highlight status modification shoule be a stage of main process?
    // (Consider confilct (e.g., legend and axisPointer) and setOption)

    var zr = api.getZr();
    var highDownKey = 'axisPointerLastHighlights';
    var lastHighlights = inner$7(zr)[highDownKey] || {};
    var newHighlights = inner$7(zr)[highDownKey] = {};

    // Update highlight/downplay status according to axisPointer model.
    // Build hash map and remove duplicate incidentally.
    each$7(axesInfo, function (axisInfo, key) {
        var option = axisInfo.axisPointerModel.option;
        option.status === 'show' && each$7(option.seriesDataIndices, function (batchItem) {
            var key = batchItem.seriesIndex + ' | ' + batchItem.dataIndex;
            newHighlights[key] = batchItem;
        });
    });

    // Diff.
    var toHighlight = [];
    var toDownplay = [];
    each$1(lastHighlights, function (batchItem, key) {
        !newHighlights[key] && toDownplay.push(batchItem);
    });
    each$1(newHighlights, function (batchItem, key) {
        !lastHighlights[key] && toHighlight.push(batchItem);
    });

    toDownplay.length && api.dispatchAction({
        type: 'downplay', escapeConnect: true, batch: toDownplay
    });
    toHighlight.length && api.dispatchAction({
        type: 'highlight', escapeConnect: true, batch: toHighlight
    });
}

function findInputAxisInfo(inputAxesInfo, axisInfo) {
    for (var i = 0; i < (inputAxesInfo || []).length; i++) {
        var inputAxisInfo = inputAxesInfo[i];
        if (axisInfo.axis.dim === inputAxisInfo.axisDim
            && axisInfo.axis.model.componentIndex === inputAxisInfo.axisIndex
        ) {
            return inputAxisInfo;
        }
    }
}

function makeMapperParam(axisInfo) {
    var axisModel = axisInfo.axis.model;
    var item = {};
    var dim = item.axisDim = axisInfo.axis.dim;
    item.axisIndex = item[dim + 'AxisIndex'] = axisModel.componentIndex;
    item.axisName = item[dim + 'AxisName'] = axisModel.name;
    item.axisId = item[dim + 'AxisId'] = axisModel.id;
    return item;
}

function illegalPoint(point) {
    return !point || point[0] == null || isNaN(point[0]) || point[1] == null || isNaN(point[1]);
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var AxisPointerModel = extendComponentModel({

    type: 'axisPointer',

    coordSysAxesInfo: null,

    defaultOption: {
        // 'auto' means that show when triggered by tooltip or handle.
        show: 'auto',
        // 'click' | 'mousemove' | 'none'
        triggerOn: null, // set default in AxisPonterView.js

        zlevel: 0,
        z: 50,

        type: 'line', // 'line' 'shadow' 'cross' 'none'.
        // axispointer triggered by tootip determine snap automatically,
        // see `modelHelper`.
        snap: false,
        triggerTooltip: true,

        value: null,
        status: null, // Init value depends on whether handle is used.

        // [group0, group1, ...]
        // Each group can be: {
        //      mapper: function () {},
        //      singleTooltip: 'multiple',  // 'multiple' or 'single'
        //      xAxisId: ...,
        //      yAxisName: ...,
        //      angleAxisIndex: ...
        // }
        // mapper: can be ignored.
        //      input: {axisInfo, value}
        //      output: {axisInfo, value}
        link: [],

        // Do not set 'auto' here, otherwise global animation: false
        // will not effect at this axispointer.
        animation: null,
        animationDurationUpdate: 200,

        lineStyle: {
            color: '#aaa',
            width: 1,
            type: 'solid'
        },

        shadowStyle: {
            color: 'rgba(150,150,150,0.3)'
        },

        label: {
            show: true,
            formatter: null, // string | Function
            precision: 'auto', // Or a number like 0, 1, 2 ...
            margin: 3,
            color: '#fff',
            padding: [5, 7, 5, 7],
            backgroundColor: 'auto', // default: axis line color
            borderColor: null,
            borderWidth: 0,
            shadowBlur: 3,
            shadowColor: '#aaa'
            // Considering applicability, common style should
            // better not have shadowOffset.
            // shadowOffsetX: 0,
            // shadowOffsetY: 2
        },

        handle: {
            show: false,
            /* eslint-disable */
            icon: 'M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4h1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7v-1.2h6.6z M13.3,22H6.7v-1.2h6.6z M13.3,19.6H6.7v-1.2h6.6z', // jshint ignore:line
            /* eslint-enable */
            size: 45,
            // handle margin is from symbol center to axis, which is stable when circular move.
            margin: 50,
            // color: '#1b8bbd'
            // color: '#2f4554'
            color: '#333',
            shadowBlur: 3,
            shadowColor: '#aaa',
            shadowOffsetX: 0,
            shadowOffsetY: 2,

            // For mobile performance
            throttle: 40
        }
    }

});

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var inner$8 = makeInner();
var each$8 = each$1;

/**
 * @param {string} key
 * @param {module:echarts/ExtensionAPI} api
 * @param {Function} handler
 *      param: {string} currTrigger
 *      param: {Array.<number>} point
 */
function register(key, api, handler) {
    if (env$1.node) {
        return;
    }

    var zr = api.getZr();
    inner$8(zr).records || (inner$8(zr).records = {});

    initGlobalListeners(zr, api);

    var record = inner$8(zr).records[key] || (inner$8(zr).records[key] = {});
    record.handler = handler;
}

function initGlobalListeners(zr, api) {
    if (inner$8(zr).initialized) {
        return;
    }

    inner$8(zr).initialized = true;

    useHandler('click', curry(doEnter, 'click'));
    useHandler('mousemove', curry(doEnter, 'mousemove'));
    // useHandler('mouseout', onLeave);
    useHandler('globalout', onLeave);

    function useHandler(eventType, cb) {
        zr.on(eventType, function (e) {
            var dis = makeDispatchAction(api);

            each$8(inner$8(zr).records, function (record) {
                record && cb(record, e, dis.dispatchAction);
            });

            dispatchTooltipFinally(dis.pendings, api);
        });
    }
}

function dispatchTooltipFinally(pendings, api) {
    var showLen = pendings.showTip.length;
    var hideLen = pendings.hideTip.length;

    var actuallyPayload;
    if (showLen) {
        actuallyPayload = pendings.showTip[showLen - 1];
    }
    else if (hideLen) {
        actuallyPayload = pendings.hideTip[hideLen - 1];
    }
    if (actuallyPayload) {
        actuallyPayload.dispatchAction = null;
        api.dispatchAction(actuallyPayload);
    }
}

function onLeave(record, e, dispatchAction) {
    record.handler('leave', null, dispatchAction);
}

function doEnter(currTrigger, record, e, dispatchAction) {
    record.handler(currTrigger, e, dispatchAction);
}

function makeDispatchAction(api) {
    var pendings = {
        showTip: [],
        hideTip: []
    };
    // FIXME
    // better approach?
    // 'showTip' and 'hideTip' can be triggered by axisPointer and tooltip,
    // which may be conflict, (axisPointer call showTip but tooltip call hideTip);
    // So we have to add "final stage" to merge those dispatched actions.
    var dispatchAction = function (payload) {
        var pendingList = pendings[payload.type];
        if (pendingList) {
            pendingList.push(payload);
        }
        else {
            payload.dispatchAction = dispatchAction;
            api.dispatchAction(payload);
        }
    };

    return {
        dispatchAction: dispatchAction,
        pendings: pendings
    };
}

/**
 * @param {string} key
 * @param {module:echarts/ExtensionAPI} api
 */
function unregister(key, api) {
    if (env$1.node) {
        return;
    }
    var zr = api.getZr();
    var record = (inner$8(zr).records || {})[key];
    if (record) {
        inner$8(zr).records[key] = null;
    }
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var AxisPointerView = extendComponentView({

    type: 'axisPointer',

    render: function (globalAxisPointerModel, ecModel, api) {
        var globalTooltipModel = ecModel.getComponent('tooltip');
        var triggerOn = globalAxisPointerModel.get('triggerOn')
            || (globalTooltipModel && globalTooltipModel.get('triggerOn') || 'mousemove|click');

        // Register global listener in AxisPointerView to enable
        // AxisPointerView to be independent to Tooltip.
        register(
            'axisPointer',
            api,
            function (currTrigger, e, dispatchAction) {
                // If 'none', it is not controlled by mouse totally.
                if (triggerOn !== 'none'
                    && (currTrigger === 'leave' || triggerOn.indexOf(currTrigger) >= 0)
                ) {
                    dispatchAction({
                        type: 'updateAxisPointer',
                        currTrigger: currTrigger,
                        x: e && e.offsetX,
                        y: e && e.offsetY
                    });
                }
            }
        );
    },

    /**
     * @override
     */
    remove: function (ecModel, api) {
        unregister(api.getZr(), 'axisPointer');
        AxisPointerView.superApply(this._model, 'remove', arguments);
    },

    /**
     * @override
     */
    dispose: function (ecModel, api) {
        unregister('axisPointer', api);
        AxisPointerView.superApply(this._model, 'dispose', arguments);
    }

});

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var inner$9 = makeInner();
var clone$4 = clone;
var bind$1 = bind;

/**
 * Base axis pointer class in 2D.
 * Implemenents {module:echarts/component/axis/IAxisPointer}.
 */
function BaseAxisPointer() {
}

BaseAxisPointer.prototype = {

    /**
     * @private
     */
    _group: null,

    /**
     * @private
     */
    _lastGraphicKey: null,

    /**
     * @private
     */
    _handle: null,

    /**
     * @private
     */
    _dragging: false,

    /**
     * @private
     */
    _lastValue: null,

    /**
     * @private
     */
    _lastStatus: null,

    /**
     * @private
     */
    _payloadInfo: null,

    /**
     * In px, arbitrary value. Do not set too small,
     * no animation is ok for most cases.
     * @protected
     */
    animationThreshold: 15,

    /**
     * @implement
     */
    render: function (axisModel, axisPointerModel, api, forceRender) {
        var value = axisPointerModel.get('value');
        var status = axisPointerModel.get('status');

        // Bind them to `this`, not in closure, otherwise they will not
        // be replaced when user calling setOption in not merge mode.
        this._axisModel = axisModel;
        this._axisPointerModel = axisPointerModel;
        this._api = api;

        // Optimize: `render` will be called repeatly during mouse move.
        // So it is power consuming if performing `render` each time,
        // especially on mobile device.
        if (!forceRender
            && this._lastValue === value
            && this._lastStatus === status
        ) {
            return;
        }
        this._lastValue = value;
        this._lastStatus = status;

        var group = this._group;
        var handle = this._handle;

        if (!status || status === 'hide') {
            // Do not clear here, for animation better.
            group && group.hide();
            handle && handle.hide();
            return;
        }
        group && group.show();
        handle && handle.show();

        // Otherwise status is 'show'
        var elOption = {};
        this.makeElOption(elOption, value, axisModel, axisPointerModel, api);

        // Enable change axis pointer type.
        var graphicKey = elOption.graphicKey;
        if (graphicKey !== this._lastGraphicKey) {
            this.clear(api);
        }
        this._lastGraphicKey = graphicKey;

        var moveAnimation = this._moveAnimation =
            this.determineAnimation(axisModel, axisPointerModel);

        if (!group) {
            group = this._group = new Group();
            this.createPointerEl(group, elOption, axisModel, axisPointerModel);
            this.createLabelEl(group, elOption, axisModel, axisPointerModel);
            api.getZr().add(group);
        }
        else {
            var doUpdateProps = curry(updateProps$1, axisPointerModel, moveAnimation);
            this.updatePointerEl(group, elOption, doUpdateProps, axisPointerModel);
            this.updateLabelEl(group, elOption, doUpdateProps, axisPointerModel);
        }

        updateMandatoryProps(group, axisPointerModel, true);

        this._renderHandle(value);
    },

    /**
     * @implement
     */
    remove: function (api) {
        this.clear(api);
    },

    /**
     * @implement
     */
    dispose: function (api) {
        this.clear(api);
    },

    /**
     * @protected
     */
    determineAnimation: function (axisModel, axisPointerModel) {
        var animation = axisPointerModel.get('animation');
        var axis = axisModel.axis;
        var isCategoryAxis = axis.type === 'category';
        var useSnap = axisPointerModel.get('snap');

        // Value axis without snap always do not snap.
        if (!useSnap && !isCategoryAxis) {
            return false;
        }

        if (animation === 'auto' || animation == null) {
            var animationThreshold = this.animationThreshold;
            if (isCategoryAxis && axis.getBandWidth() > animationThreshold) {
                return true;
            }

            // It is important to auto animation when snap used. Consider if there is
            // a dataZoom, animation will be disabled when too many points exist, while
            // it will be enabled for better visual effect when little points exist.
            if (useSnap) {
                var seriesDataCount = getAxisInfo(axisModel).seriesDataCount;
                var axisExtent = axis.getExtent();
                // Approximate band width
                return Math.abs(axisExtent[0] - axisExtent[1]) / seriesDataCount > animationThreshold;
            }

            return false;
        }

        return animation === true;
    },

    /**
     * add {pointer, label, graphicKey} to elOption
     * @protected
     */
    makeElOption: function (elOption, value, axisModel, axisPointerModel, api) {
        // Shoule be implemenented by sub-class.
    },

    /**
     * @protected
     */
    createPointerEl: function (group, elOption, axisModel, axisPointerModel) {
        var pointerOption = elOption.pointer;
        if (pointerOption) {
            var pointerEl = inner$9(group).pointerEl = new graphic[pointerOption.type](
                clone$4(elOption.pointer)
            );
            group.add(pointerEl);
        }
    },

    /**
     * @protected
     */
    createLabelEl: function (group, elOption, axisModel, axisPointerModel) {
        if (elOption.label) {
            var labelEl = inner$9(group).labelEl = new Rect(
                clone$4(elOption.label)
            );

            group.add(labelEl);
            updateLabelShowHide(labelEl, axisPointerModel);
        }
    },

    /**
     * @protected
     */
    updatePointerEl: function (group, elOption, updateProps$$1) {
        var pointerEl = inner$9(group).pointerEl;
        if (pointerEl && elOption.pointer) {
            pointerEl.setStyle(elOption.pointer.style);
            updateProps$$1(pointerEl, {shape: elOption.pointer.shape});
        }
    },

    /**
     * @protected
     */
    updateLabelEl: function (group, elOption, updateProps$$1, axisPointerModel) {
        var labelEl = inner$9(group).labelEl;
        if (labelEl) {
            labelEl.setStyle(elOption.label.style);
            updateProps$$1(labelEl, {
                // Consider text length change in vertical axis, animation should
                // be used on shape, otherwise the effect will be weird.
                shape: elOption.label.shape,
                position: elOption.label.position
            });

            updateLabelShowHide(labelEl, axisPointerModel);
        }
    },

    /**
     * @private
     */
    _renderHandle: function (value) {
        if (this._dragging || !this.updateHandleTransform) {
            return;
        }

        var axisPointerModel = this._axisPointerModel;
        var zr = this._api.getZr();
        var handle = this._handle;
        var handleModel = axisPointerModel.getModel('handle');

        var status = axisPointerModel.get('status');
        if (!handleModel.get('show') || !status || status === 'hide') {
            handle && zr.remove(handle);
            this._handle = null;
            return;
        }

        var isInit;
        if (!this._handle) {
            isInit = true;
            handle = this._handle = createIcon(
                handleModel.get('icon'),
                {
                    cursor: 'move',
                    draggable: true,
                    onmousemove: function (e) {
                        // Fot mobile devicem, prevent screen slider on the button.
                        stop(e.event);
                    },
                    onmousedown: bind$1(this._onHandleDragMove, this, 0, 0),
                    drift: bind$1(this._onHandleDragMove, this),
                    ondragend: bind$1(this._onHandleDragEnd, this)
                }
            );
            zr.add(handle);
        }

        updateMandatoryProps(handle, axisPointerModel, false);

        // update style
        var includeStyles = [
            'color', 'borderColor', 'borderWidth', 'opacity',
            'shadowColor', 'shadowBlur', 'shadowOffsetX', 'shadowOffsetY'
        ];
        handle.setStyle(handleModel.getItemStyle(null, includeStyles));

        // update position
        var handleSize = handleModel.get('size');
        if (!isArray(handleSize)) {
            handleSize = [handleSize, handleSize];
        }
        handle.attr('scale', [handleSize[0] / 2, handleSize[1] / 2]);

        createOrUpdate(
            this,
            '_doDispatchAxisPointer',
            handleModel.get('throttle') || 0,
            'fixRate'
        );

        this._moveHandleToValue(value, isInit);
    },

    /**
     * @private
     */
    _moveHandleToValue: function (value, isInit) {
        updateProps$1(
            this._axisPointerModel,
            !isInit && this._moveAnimation,
            this._handle,
            getHandleTransProps(this.getHandleTransform(
                value, this._axisModel, this._axisPointerModel
            ))
        );
    },

    /**
     * @private
     */
    _onHandleDragMove: function (dx, dy) {
        var handle = this._handle;
        if (!handle) {
            return;
        }

        this._dragging = true;

        // Persistent for throttle.
        var trans = this.updateHandleTransform(
            getHandleTransProps(handle),
            [dx, dy],
            this._axisModel,
            this._axisPointerModel
        );
        this._payloadInfo = trans;

        handle.stopAnimation();
        handle.attr(getHandleTransProps(trans));
        inner$9(handle).lastProp = null;

        this._doDispatchAxisPointer();
    },

    /**
     * Throttled method.
     * @private
     */
    _doDispatchAxisPointer: function () {
        var handle = this._handle;
        if (!handle) {
            return;
        }

        var payloadInfo = this._payloadInfo;
        var axisModel = this._axisModel;
        this._api.dispatchAction({
            type: 'updateAxisPointer',
            x: payloadInfo.cursorPoint[0],
            y: payloadInfo.cursorPoint[1],
            tooltipOption: payloadInfo.tooltipOption,
            axesInfo: [{
                axisDim: axisModel.axis.dim,
                axisIndex: axisModel.componentIndex
            }]
        });
    },

    /**
     * @private
     */
    _onHandleDragEnd: function (moveAnimation) {
        this._dragging = false;
        var handle = this._handle;
        if (!handle) {
            return;
        }

        var value = this._axisPointerModel.get('value');
        // Consider snap or categroy axis, handle may be not consistent with
        // axisPointer. So move handle to align the exact value position when
        // drag ended.
        this._moveHandleToValue(value);

        // For the effect: tooltip will be shown when finger holding on handle
        // button, and will be hidden after finger left handle button.
        this._api.dispatchAction({
            type: 'hideTip'
        });
    },

    /**
     * Should be implemenented by sub-class if support `handle`.
     * @protected
     * @param {number} value
     * @param {module:echarts/model/Model} axisModel
     * @param {module:echarts/model/Model} axisPointerModel
     * @return {Object} {position: [x, y], rotation: 0}
     */
    getHandleTransform: null,

    /**
     * * Should be implemenented by sub-class if support `handle`.
     * @protected
     * @param {Object} transform {position, rotation}
     * @param {Array.<number>} delta [dx, dy]
     * @param {module:echarts/model/Model} axisModel
     * @param {module:echarts/model/Model} axisPointerModel
     * @return {Object} {position: [x, y], rotation: 0, cursorPoint: [x, y]}
     */
    updateHandleTransform: null,

    /**
     * @private
     */
    clear: function (api) {
        this._lastValue = null;
        this._lastStatus = null;

        var zr = api.getZr();
        var group = this._group;
        var handle = this._handle;
        if (zr && group) {
            this._lastGraphicKey = null;
            group && zr.remove(group);
            handle && zr.remove(handle);
            this._group = null;
            this._handle = null;
            this._payloadInfo = null;
        }
    },

    /**
     * @protected
     */
    doClear: function () {
        // Implemented by sub-class if necessary.
    },

    /**
     * @protected
     * @param {Array.<number>} xy
     * @param {Array.<number>} wh
     * @param {number} [xDimIndex=0] or 1
     */
    buildLabel: function (xy, wh, xDimIndex) {
        xDimIndex = xDimIndex || 0;
        return {
            x: xy[xDimIndex],
            y: xy[1 - xDimIndex],
            width: wh[xDimIndex],
            height: wh[1 - xDimIndex]
        };
    }
};

BaseAxisPointer.prototype.constructor = BaseAxisPointer;


function updateProps$1(animationModel, moveAnimation, el, props) {
    // Animation optimize.
    if (!propsEqual(inner$9(el).lastProp, props)) {
        inner$9(el).lastProp = props;
        moveAnimation
            ? updateProps(el, props, animationModel)
            : (el.stopAnimation(), el.attr(props));
    }
}

function propsEqual(lastProps, newProps) {
    if (isObject$1(lastProps) && isObject$1(newProps)) {
        var equals = true;
        each$1(newProps, function (item, key) {
            equals = equals && propsEqual(lastProps[key], item);
        });
        return !!equals;
    }
    else {
        return lastProps === newProps;
    }
}

function updateLabelShowHide(labelEl, axisPointerModel) {
    labelEl[axisPointerModel.get('label.show') ? 'show' : 'hide']();
}

function getHandleTransProps(trans) {
    return {
        position: trans.position.slice(),
        rotation: trans.rotation || 0
    };
}

function updateMandatoryProps(group, axisPointerModel, silent) {
    var z = axisPointerModel.get('z');
    var zlevel = axisPointerModel.get('zlevel');

    group && group.traverse(function (el) {
        if (el.type !== 'group') {
            z != null && (el.z = z);
            zlevel != null && (el.zlevel = zlevel);
            el.silent = silent;
        }
    });
}

enableClassExtend(BaseAxisPointer);

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * @param {module:echarts/model/Model} axisPointerModel
 */
function buildElStyle(axisPointerModel) {
    var axisPointerType = axisPointerModel.get('type');
    var styleModel = axisPointerModel.getModel(axisPointerType + 'Style');
    var style;
    if (axisPointerType === 'line') {
        style = styleModel.getLineStyle();
        style.fill = null;
    }
    else if (axisPointerType === 'shadow') {
        style = styleModel.getAreaStyle();
        style.stroke = null;
    }
    return style;
}

/**
 * @param {Function} labelPos {align, verticalAlign, position}
 */
function buildLabelElOption(
    elOption, axisModel, axisPointerModel, api, labelPos
) {
    var value = axisPointerModel.get('value');
    var text = getValueLabel(
        value, axisModel.axis, axisModel.ecModel,
        axisPointerModel.get('seriesDataIndices'),
        {
            precision: axisPointerModel.get('label.precision'),
            formatter: axisPointerModel.get('label.formatter')
        }
    );
    var labelModel = axisPointerModel.getModel('label');
    var paddings = normalizeCssArray$1(labelModel.get('padding') || 0);

    var font = labelModel.getFont();
    var textRect = getBoundingRect(text, font);

    var position = labelPos.position;
    var width = textRect.width + paddings[1] + paddings[3];
    var height = textRect.height + paddings[0] + paddings[2];

    // Adjust by align.
    var align = labelPos.align;
    align === 'right' && (position[0] -= width);
    align === 'center' && (position[0] -= width / 2);
    var verticalAlign = labelPos.verticalAlign;
    verticalAlign === 'bottom' && (position[1] -= height);
    verticalAlign === 'middle' && (position[1] -= height / 2);

    // Not overflow ec container
    confineInContainer(position, width, height, api);

    var bgColor = labelModel.get('backgroundColor');
    if (!bgColor || bgColor === 'auto') {
        bgColor = axisModel.get('axisLine.lineStyle.color');
    }

    elOption.label = {
        shape: {x: 0, y: 0, width: width, height: height, r: labelModel.get('borderRadius')},
        position: position.slice(),
        // TODO: rich
        style: {
            text: text,
            textFont: font,
            textFill: labelModel.getTextColor(),
            textPosition: 'inside',
            textPadding: paddings,
            fill: bgColor,
            stroke: labelModel.get('borderColor') || 'transparent',
            lineWidth: labelModel.get('borderWidth') || 0,
            shadowBlur: labelModel.get('shadowBlur'),
            shadowColor: labelModel.get('shadowColor'),
            shadowOffsetX: labelModel.get('shadowOffsetX'),
            shadowOffsetY: labelModel.get('shadowOffsetY')
        },
        // Lable should be over axisPointer.
        z2: 10
    };
}

// Do not overflow ec container
function confineInContainer(position, width, height, api) {
    var viewWidth = api.getWidth();
    var viewHeight = api.getHeight();
    position[0] = Math.min(position[0] + width, viewWidth) - width;
    position[1] = Math.min(position[1] + height, viewHeight) - height;
    position[0] = Math.max(position[0], 0);
    position[1] = Math.max(position[1], 0);
}

/**
 * @param {number} value
 * @param {module:echarts/coord/Axis} axis
 * @param {module:echarts/model/Global} ecModel
 * @param {Object} opt
 * @param {Array.<Object>} seriesDataIndices
 * @param {number|string} opt.precision 'auto' or a number
 * @param {string|Function} opt.formatter label formatter
 */
function getValueLabel(value, axis, ecModel, seriesDataIndices, opt) {
    value = axis.scale.parse(value);
    var text = axis.scale.getLabel(
        // If `precision` is set, width can be fixed (like '12.00500'), which
        // helps to debounce when when moving label.
        value, {precision: opt.precision}
    );
    var formatter = opt.formatter;

    if (formatter) {
        var params = {
            value: getAxisRawValue(axis, value),
            axisDimension: axis.dim,
            axisIndex: axis.index,
            seriesData: []
        };
        each$1(seriesDataIndices, function (idxItem) {
            var series = ecModel.getSeriesByIndex(idxItem.seriesIndex);
            var dataIndex = idxItem.dataIndexInside;
            var dataParams = series && series.getDataParams(dataIndex);
            dataParams && params.seriesData.push(dataParams);
        });

        if (isString(formatter)) {
            text = formatter.replace('{value}', text);
        }
        else if (isFunction$1(formatter)) {
            text = formatter(params);
        }
    }

    return text;
}

/**
 * @param {module:echarts/coord/Axis} axis
 * @param {number} value
 * @param {Object} layoutInfo {
 *  rotation, position, labelOffset, labelDirection, labelMargin
 * }
 */
function getTransformedPosition(axis, value, layoutInfo) {
    var transform = create$1();
    rotate(transform, transform, layoutInfo.rotation);
    translate(transform, transform, layoutInfo.position);

    return applyTransform$1([
        axis.dataToCoord(value),
        (layoutInfo.labelOffset || 0)
            + (layoutInfo.labelDirection || 1) * (layoutInfo.labelMargin || 0)
    ], transform);
}

function buildCartesianSingleLabelElOption(
    value, elOption, layoutInfo, axisModel, axisPointerModel, api
) {
    var textLayout = AxisBuilder.innerTextLayout(
        layoutInfo.rotation, 0, layoutInfo.labelDirection
    );
    layoutInfo.labelMargin = axisPointerModel.get('label.margin');
    buildLabelElOption(elOption, axisModel, axisPointerModel, api, {
        position: getTransformedPosition(axisModel.axis, value, layoutInfo),
        align: textLayout.textAlign,
        verticalAlign: textLayout.textVerticalAlign
    });
}

/**
 * @param {Array.<number>} p1
 * @param {Array.<number>} p2
 * @param {number} [xDimIndex=0] or 1
 */
function makeLineShape(p1, p2, xDimIndex) {
    xDimIndex = xDimIndex || 0;
    return {
        x1: p1[xDimIndex],
        y1: p1[1 - xDimIndex],
        x2: p2[xDimIndex],
        y2: p2[1 - xDimIndex]
    };
}

/**
 * @param {Array.<number>} xy
 * @param {Array.<number>} wh
 * @param {number} [xDimIndex=0] or 1
 */
function makeRectShape(xy, wh, xDimIndex) {
    xDimIndex = xDimIndex || 0;
    return {
        x: xy[xDimIndex],
        y: xy[1 - xDimIndex],
        width: wh[xDimIndex],
        height: wh[1 - xDimIndex]
    };
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var CartesianAxisPointer = BaseAxisPointer.extend({

    /**
     * @override
     */
    makeElOption: function (elOption, value, axisModel, axisPointerModel, api) {
        var axis = axisModel.axis;
        var grid = axis.grid;
        var axisPointerType = axisPointerModel.get('type');
        var otherExtent = getCartesian(grid, axis).getOtherAxis(axis).getGlobalExtent();
        var pixelValue = axis.toGlobalCoord(axis.dataToCoord(value, true));

        if (axisPointerType && axisPointerType !== 'none') {
            var elStyle = buildElStyle(axisPointerModel);
            var pointerOption = pointerShapeBuilder[axisPointerType](
                axis, pixelValue, otherExtent
            );
            pointerOption.style = elStyle;
            elOption.graphicKey = pointerOption.type;
            elOption.pointer = pointerOption;
        }

        var layoutInfo = layout$1(grid.model, axisModel);
        buildCartesianSingleLabelElOption(
            value, elOption, layoutInfo, axisModel, axisPointerModel, api
        );
    },

    /**
     * @override
     */
    getHandleTransform: function (value, axisModel, axisPointerModel) {
        var layoutInfo = layout$1(axisModel.axis.grid.model, axisModel, {
            labelInside: false
        });
        layoutInfo.labelMargin = axisPointerModel.get('handle.margin');
        return {
            position: getTransformedPosition(axisModel.axis, value, layoutInfo),
            rotation: layoutInfo.rotation + (layoutInfo.labelDirection < 0 ? Math.PI : 0)
        };
    },

    /**
     * @override
     */
    updateHandleTransform: function (transform, delta, axisModel, axisPointerModel) {
        var axis = axisModel.axis;
        var grid = axis.grid;
        var axisExtent = axis.getGlobalExtent(true);
        var otherExtent = getCartesian(grid, axis).getOtherAxis(axis).getGlobalExtent();
        var dimIndex = axis.dim === 'x' ? 0 : 1;

        var currPosition = transform.position;
        currPosition[dimIndex] += delta[dimIndex];
        currPosition[dimIndex] = Math.min(axisExtent[1], currPosition[dimIndex]);
        currPosition[dimIndex] = Math.max(axisExtent[0], currPosition[dimIndex]);

        var cursorOtherValue = (otherExtent[1] + otherExtent[0]) / 2;
        var cursorPoint = [cursorOtherValue, cursorOtherValue];
        cursorPoint[dimIndex] = currPosition[dimIndex];

        // Make tooltip do not overlap axisPointer and in the middle of the grid.
        var tooltipOptions = [{verticalAlign: 'middle'}, {align: 'center'}];

        return {
            position: currPosition,
            rotation: transform.rotation,
            cursorPoint: cursorPoint,
            tooltipOption: tooltipOptions[dimIndex]
        };
    }

});

function getCartesian(grid, axis) {
    var opt = {};
    opt[axis.dim + 'AxisIndex'] = axis.index;
    return grid.getCartesian(opt);
}

var pointerShapeBuilder = {

    line: function (axis, pixelValue, otherExtent) {
        var targetShape = makeLineShape(
            [pixelValue, otherExtent[0]],
            [pixelValue, otherExtent[1]],
            getAxisDimIndex(axis)
        );
        return {
            type: 'Line',
            subPixelOptimize: true,
            shape: targetShape
        };
    },

    shadow: function (axis, pixelValue, otherExtent) {
        var bandWidth = Math.max(1, axis.getBandWidth());
        var span = otherExtent[1] - otherExtent[0];
        return {
            type: 'Rect',
            shape: makeRectShape(
                [pixelValue - bandWidth / 2, otherExtent[0]],
                [bandWidth, span],
                getAxisDimIndex(axis)
            )
        };
    }
};

function getAxisDimIndex(axis) {
    return axis.dim === 'x' ? 0 : 1;
}

AxisView.registerAxisPointerClass('CartesianAxisPointer', CartesianAxisPointer);

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

// CartesianAxisPointer is not supposed to be required here. But consider
// echarts.simple.js and online build tooltip, which only require gridSimple,
// CartesianAxisPointer should be able to required somewhere.
registerPreprocessor(function (option) {
    // Always has a global axisPointerModel for default setting.
    if (option) {
        (!option.axisPointer || option.axisPointer.length === 0)
            && (option.axisPointer = {});

        var link = option.axisPointer.link;
        // Normalize to array to avoid object mergin. But if link
        // is not set, remain null/undefined, otherwise it will
        // override existent link setting.
        if (link && !isArray(link)) {
            option.axisPointer.link = [link];
        }
    }
});

// This process should proformed after coordinate systems created
// and series data processed. So put it on statistic processing stage.
registerProcessor(PRIORITY.PROCESSOR.STATISTIC, function (ecModel, api) {
    // Build axisPointerModel, mergin tooltip.axisPointer model for each axis.
    // allAxesInfo should be updated when setOption performed.
    ecModel.getComponent('axisPointer').coordSysAxesInfo =
        collect(ecModel, api);
});

// Broadcast to all views.
registerAction({
    type: 'updateAxisPointer',
    event: 'updateAxisPointer',
    update: ':updateAxisPointer'
}, axisTrigger);

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

extendComponentModel({

    type: 'tooltip',

    dependencies: ['axisPointer'],

    defaultOption: {
        zlevel: 0,

        z: 60,

        show: true,

        // tooltip主体内容
        showContent: true,

        // 'trigger' only works on coordinate system.
        // 'item' | 'axis' | 'none'
        trigger: 'item',

        // 'click' | 'mousemove' | 'none'
        triggerOn: 'mousemove|click',

        alwaysShowContent: false,

        displayMode: 'single', // 'single' | 'multipleByCoordSys'

        renderMode: 'auto', // 'auto' | 'html' | 'richText'
        // 'auto': use html by default, and use non-html if `document` is not defined
        // 'html': use html for tooltip
        // 'richText': use canvas, svg, and etc. for tooltip

        // 位置 {Array} | {Function}
        // position: null
        // Consider triggered from axisPointer handle, verticalAlign should be 'middle'
        // align: null,
        // verticalAlign: null,

        // 是否约束 content 在 viewRect 中。默认 false 是为了兼容以前版本。
        confine: false,

        // 内容格式器：{string}（Template） ¦ {Function}
        // formatter: null

        showDelay: 0,

        // 隐藏延迟，单位ms
        hideDelay: 100,

        // 动画变换时间，单位s
        transitionDuration: 0.4,

        enterable: false,

        // 提示背景颜色，默认为透明度为0.7的黑色
        backgroundColor: 'rgba(50,50,50,0.7)',

        // 提示边框颜色
        borderColor: '#333',

        // 提示边框圆角，单位px，默认为4
        borderRadius: 4,

        // 提示边框线宽，单位px，默认为0（无边框）
        borderWidth: 0,

        // 提示内边距，单位px，默认各方向内边距为5，
        // 接受数组分别设定上右下左边距，同css
        padding: 5,

        // Extra css text
        extraCssText: '',

        // 坐标轴指示器，坐标轴触发有效
        axisPointer: {
            // 默认为直线
            // 可选为：'line' | 'shadow' | 'cross'
            type: 'line',

            // type 为 line 的时候有效，指定 tooltip line 所在的轴，可选
            // 可选 'x' | 'y' | 'angle' | 'radius' | 'auto'
            // 默认 'auto'，会选择类型为 category 的轴，对于双数值轴，笛卡尔坐标系会默认选择 x 轴
            // 极坐标系会默认选择 angle 轴
            axis: 'auto',

            animation: 'auto',
            animationDurationUpdate: 200,
            animationEasingUpdate: 'exponentialOut',

            crossStyle: {
                color: '#999',
                width: 1,
                type: 'dashed',

                // TODO formatter
                textStyle: {}
            }

            // lineStyle and shadowStyle should not be specified here,
            // otherwise it will always override those styles on option.axisPointer.
        },
        textStyle: {
            color: '#fff',
            fontSize: 14
        }
    }
});

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var each$10 = each$1;
var toCamelCase$1 = toCamelCase;

var vendors = ['', '-webkit-', '-moz-', '-o-'];

var gCssText = 'position:absolute;display:block;border-style:solid;white-space:nowrap;z-index:9999999;';

/**
 * @param {number} duration
 * @return {string}
 * @inner
 */
function assembleTransition(duration) {
    var transitionCurve = 'cubic-bezier(0.23, 1, 0.32, 1)';
    var transitionText = 'left ' + duration + 's ' + transitionCurve + ','
                        + 'top ' + duration + 's ' + transitionCurve;
    return 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());

    var lineHeight = textStyleModel.get('lineHeight');
    if (lineHeight == null) {
        lineHeight = Math.round(fontSize * 3 / 2);
    }

    fontSize
        && cssText.push('line-height:' + lineHeight + 'px');

    var shadowColor = textStyleModel.get('textShadowColor');
    var shadowBlur = textStyleModel.get('textShadowBlur') || 0;
    var shadowOffsetX = textStyleModel.get('textShadowOffsetX') || 0;
    var shadowOffsetY = textStyleModel.get('textShadowOffsetY') || 0;
    shadowBlur
        && cssText.push('text-shadow:' + shadowOffsetX + 'px ' + shadowOffsetY + 'px '
            + shadowBlur + 'px ' + shadowColor);

    each$10(['decoration', 'align'], function (name) {
        var val = textStyleModel.get(name);
        val && cssText.push('text-' + name + ':' + val);
    });

    return cssText.join(';');
}

/**
 * @param {Object} tooltipModel
 * @return {string}
 * @inner
 */
function assembleCssText(tooltipModel) {

    var cssText = [];

    var transitionDuration = tooltipModel.get('transitionDuration');
    var backgroundColor = tooltipModel.get('backgroundColor');
    var textStyleModel = tooltipModel.getModel('textStyle');
    var padding = tooltipModel.get('padding');

    // Animation transition. Do not animate when transitionDuration is 0.
    transitionDuration
        && cssText.push(assembleTransition(transitionDuration));

    if (backgroundColor) {
        if (env$1.canvasSupported) {
            cssText.push('background-Color:' + backgroundColor);
        }
        else {
            // for ie
            cssText.push(
                'background-Color:#' + toHex(backgroundColor)
            );
            cssText.push('filter:alpha(opacity=70)');
        }
    }

    // Border style
    each$10(['width', 'color', 'radius'], function (name) {
        var borderName = 'border-' + name;
        var camelCase = toCamelCase$1(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:' + normalizeCssArray$1(padding).join('px ') + 'px');
    }

    return cssText.join(';') + ';';
}

// If not able to make, do not modify the input `out`.
function makeStyleCoord(out, zr, appendToBody, zrX, zrY) {
    var zrPainter = zr && zr.painter;

    if (appendToBody) {
        var zrViewportRoot = zrPainter && zrPainter.getViewportRoot();
        if (zrViewportRoot) {
            // Some APPs might use scale on body, so we support CSS transform here.
            transformLocalCoord(out, zrViewportRoot, document.body, zrX, zrY);
        }
    }
    else {
        out[0] = zrX;
        out[1] = zrY;
        // xy should be based on canvas root. But tooltipContent is
        // the sibling of canvas root. So padding of ec container
        // should be considered here.
        var viewportRootOffset = zrPainter && zrPainter.getViewportRootOffset();
        if (viewportRootOffset) {
            out[0] += viewportRootOffset.offsetLeft;
            out[1] += viewportRootOffset.offsetTop;
        }
    }
    out[2] = out[0] / zr.getWidth(); // The ratio of left to width
    out[3] = out[1] / zr.getHeight(); // The ratio of top to height
}

/**
 * @alias module:echarts/component/tooltip/TooltipContent
 * @param {HTMLElement} container
 * @param {ExtensionAPI} api
 * @param {Object} [opt]
 * @param {boolean} [opt.appendToBody]
 *        `false`: the DOM element will be inside the container. Default value.
 *        `true`: the DOM element will be appended to HTML body, which avoid
 *                some overflow clip but intrude outside of the container.
 * @constructor
 */
function TooltipContent(container, api, opt) {
    if (env$1.wxa) {
        return null;
    }

    var el = document.createElement('div');
    el.domBelongToZr = true;
    this.el = el;
    var zr = this._zr = api.getZr();
    var appendToBody = this._appendToBody = opt && opt.appendToBody;

    this._styleCoord = [0, 0, 0, 0]; // [left, top, left/width, top/height]

    makeStyleCoord(this._styleCoord, zr, appendToBody, api.getWidth() / 2, api.getHeight() / 2);

    if (appendToBody) {
        document.body.appendChild(el);
    }
    else {
        container.appendChild(el);
    }

    this._container = container;

    this._show = false;

    /**
     * @private
     */
    this._hideTimeout;

    // FIXME
    // Is it needed to trigger zr event manually if
    // the browser do not support `pointer-events: none`.

    var self = this;
    el.onmouseenter = function () {
        // clear the timeout in hideLater and keep showing tooltip
        if (self._enterable) {
            clearTimeout(self._hideTimeout);
            self._show = true;
        }
        self._inContent = true;
    };
    el.onmousemove = function (e) {
        e = e || window.event;
        if (!self._enterable) {
            // `pointer-events: none` is set to tooltip content div
            // if `enterable` is set as `false`, and `el.onmousemove`
            // can not be triggered. But in browser that do not
            // support `pointer-events`, we need to do this:
            // Try trigger zrender event to avoid mouse
            // in and out shape too frequently
            var handler = zr.handler;
            var zrViewportRoot = zr.painter.getViewportRoot();
            normalizeEvent(zrViewportRoot, e, true);
            handler.dispatch('mousemove', e);
        }
    };
    el.onmouseleave = function () {
        if (self._enterable) {
            if (self._show) {
                self.hideLater(self._hideDelay);
            }
        }
        self._inContent = false;
    };
}

TooltipContent.prototype = {

    constructor: TooltipContent,

    /**
     * @private
     * @type {boolean}
     */
    _enterable: true,

    /**
     * Update when tooltip is rendered
     */
    update: function (tooltipModel) {
        // FIXME
        // Move this logic to ec main?
        var container = this._container;
        var stl = container.currentStyle
            || document.defaultView.getComputedStyle(container);
        var domStyle = container.style;
        if (domStyle.position !== 'absolute' && stl.position !== 'absolute') {
            domStyle.position = 'relative';
        }
        var alwaysShowContent = tooltipModel.get('alwaysShowContent');
        alwaysShowContent && this._moveTooltipIfResized();
        // Hide the tooltip
        // PENDING
        // this.hide();
    },

    /**
     * when `alwaysShowContent` is true,
     * we should move the tooltip after chart resized
     */
    _moveTooltipIfResized: function () {
        var ratioX = this._styleCoord[2]; // The ratio of left to width
        var ratioY = this._styleCoord[3]; // The ratio of top to height
        var realX = ratioX * this._zr.getWidth();
        var realY = ratioY * this._zr.getHeight();
        this.moveTo(realX, realY);
    },

    show: function (tooltipModel) {
        clearTimeout(this._hideTimeout);
        var el = this.el;
        var styleCoord = this._styleCoord;

        el.style.cssText = gCssText + assembleCssText(tooltipModel)
            // Because of the reason described in:
            // http://stackoverflow.com/questions/21125587/css3-transition-not-working-in-chrome-anymore
            // we should set initial value to `left` and `top`.
            + ';left:' + styleCoord[0] + 'px;top:' + styleCoord[1] + 'px;'
            + (tooltipModel.get('extraCssText') || '');

        el.style.display = el.innerHTML ? 'block' : 'none';

        // If mouse occasionally move over the tooltip, a mouseout event will be
        // triggered by canvas, and cause some unexpectable result like dragging
        // stop, "unfocusAdjacency". Here `pointer-events: none` is used to solve
        // it. Although it is not supported by IE8~IE10, fortunately it is a rare
        // scenario.
        el.style.pointerEvents = this._enterable ? 'auto' : 'none';

        this._show = true;
    },

    setContent: function (content) {
        this.el.innerHTML = content == null ? '' : content;
    },

    setEnterable: function (enterable) {
        this._enterable = enterable;
    },

    getSize: function () {
        var el = this.el;
        return [el.clientWidth, el.clientHeight];
    },

    moveTo: function (zrX, zrY) {
        var styleCoord = this._styleCoord;
        makeStyleCoord(styleCoord, this._zr, this._appendToBody, zrX, zrY);

        var style = this.el.style;
        style.left = styleCoord[0] + 'px';
        style.top = styleCoord[1] + 'px';
    },

    hide: function () {
        this.el.style.display = 'none';
        this._show = false;
    },

    hideLater: function (time) {
        if (this._show && !(this._inContent && this._enterable)) {
            if (time) {
                this._hideDelay = time;
                // Set show false to avoid invoke hideLater multiple times
                this._show = false;
                this._hideTimeout = setTimeout(bind(this.hide, this), time);
            }
            else {
                this.hide();
            }
        }
    },

    isShow: function () {
        return this._show;
    },

    dispose: function () {
        this.el.parentNode.removeChild(this.el);
    },

    getOuterSize: function () {
        var width = this.el.clientWidth;
        var height = this.el.clientHeight;

        // Consider browser compatibility.
        // IE8 does not support getComputedStyle.
        if (document.defaultView && document.defaultView.getComputedStyle) {
            var stl = document.defaultView.getComputedStyle(this.el);
            if (stl) {
                width += parseInt(stl.borderLeftWidth, 10) + parseInt(stl.borderRightWidth, 10);
                height += parseInt(stl.borderTopWidth, 10) + parseInt(stl.borderBottomWidth, 10);
            }
        }

        return {width: width, height: height};
    }

};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

// import Group from 'zrender/src/container/Group';
function makeStyleCoord$1(out, zr, zrX, zrY) {
    out[0] = zrX;
    out[1] = zrY;
    out[2] = out[0] / zr.getWidth(); // The ratio of left to width
    out[3] = out[1] / zr.getHeight(); // The ratio of top to height
}

/**
 * @alias module:echarts/component/tooltip/TooltipRichContent
 * @constructor
 */
function TooltipRichContent(api) {

    var zr = this._zr = api.getZr();

    this._styleCoord = [0, 0, 0, 0]; // [left, top, left/width, top/height]

    makeStyleCoord$1(this._styleCoord, zr, api.getWidth() / 2, api.getHeight() / 2);

    this._show = false;

    /**
     * @private
     */
    this._hideTimeout;
}

TooltipRichContent.prototype = {

    constructor: TooltipRichContent,

    /**
     * @private
     * @type {boolean}
     */
    _enterable: true,

    /**
     * Update when tooltip is rendered
     */
    update: function (tooltipModel) {
        var alwaysShowContent = tooltipModel.get('alwaysShowContent');
        alwaysShowContent && this._moveTooltipIfResized();
    },

    /**
     * when `alwaysShowContent` is true,
     * we should move the tooltip after chart resized
     */
    _moveTooltipIfResized: function () {
        var ratioX = this._styleCoord[2]; // The ratio of left to width
        var ratioY = this._styleCoord[3]; // The ratio of top to height
        var realX = ratioX * this._zr.getWidth();
        var realY = ratioY * this._zr.getHeight();
        this.moveTo(realX, realY);
    },

    show: function (tooltipModel) {
        if (this._hideTimeout) {
            clearTimeout(this._hideTimeout);
        }

        this.el.attr('show', true);
        this._show = true;
    },

    /**
     * Set tooltip content
     *
     * @param {string} content rich text string of content
     * @param {Object} markerRich rich text style
     * @param {Object} tooltipModel tooltip model
     */
    setContent: function (content, markerRich, tooltipModel) {
        if (this.el) {
            this._zr.remove(this.el);
        }

        var markers = {};
        var text = content;
        var prefix = '{marker';
        var suffix = '|}';
        var startId = text.indexOf(prefix);
        while (startId >= 0) {
            var endId = text.indexOf(suffix);
            var name = text.substr(startId + prefix.length, endId - startId - prefix.length);
            if (name.indexOf('sub') > -1) {
                markers['marker' + name] = {
                    textWidth: 4,
                    textHeight: 4,
                    textBorderRadius: 2,
                    textBackgroundColor: markerRich[name],
                    // TODO: textOffset is not implemented for rich text
                    textOffset: [3, 0]
                };
            }
            else {
                markers['marker' + name] = {
                    textWidth: 10,
                    textHeight: 10,
                    textBorderRadius: 5,
                    textBackgroundColor: markerRich[name]
                };
            }

            text = text.substr(endId + 1);
            startId = text.indexOf('{marker');
        }

        var textStyleModel = tooltipModel.getModel('textStyle');
        var fontSize = textStyleModel.get('fontSize');
        var lineHeight = tooltipModel.get('textLineHeight');
        if (lineHeight == null) {
            lineHeight = Math.round(fontSize * 3 / 2);
        }

        this.el = new Text({
            style: setTextStyle({}, textStyleModel, {
                rich: markers,
                text: content,
                textBackgroundColor: tooltipModel.get('backgroundColor'),
                textBorderRadius: tooltipModel.get('borderRadius'),
                textFill: tooltipModel.get('textStyle.color'),
                textPadding: tooltipModel.get('padding'),
                textLineHeight: lineHeight
            }),
            z: tooltipModel.get('z')
        });
        this._zr.add(this.el);

        var self = this;
        this.el.on('mouseover', function () {
            // clear the timeout in hideLater and keep showing tooltip
            if (self._enterable) {
                clearTimeout(self._hideTimeout);
                self._show = true;
            }
            self._inContent = true;
        });
        this.el.on('mouseout', function () {
            if (self._enterable) {
                if (self._show) {
                    self.hideLater(self._hideDelay);
                }
            }
            self._inContent = false;
        });
    },

    setEnterable: function (enterable) {
        this._enterable = enterable;
    },

    getSize: function () {
        var bounding = this.el.getBoundingRect();
        return [bounding.width, bounding.height];
    },

    moveTo: function (x, y) {
        if (this.el) {
            var styleCoord = this._styleCoord;
            makeStyleCoord$1(styleCoord, this._zr, x, y);
            this.el.attr('position', [styleCoord[0], styleCoord[1]]);
        }
    },

    hide: function () {
        if (this.el) {
            this.el.hide();
        }
        this._show = false;
    },

    hideLater: function (time) {
        if (this._show && !(this._inContent && this._enterable)) {
            if (time) {
                this._hideDelay = time;
                // Set show false to avoid invoke hideLater multiple times
                this._show = false;
                this._hideTimeout = setTimeout(bind(this.hide, this), time);
            }
            else {
                this.hide();
            }
        }
    },

    isShow: function () {
        return this._show;
    },

    dispose: function () {
        clearTimeout(this._hideTimeout);

        if (this.el) {
            this._zr.remove(this.el);
        }
    },

    getOuterSize: function () {
        var size = this.getSize();
        return {
            width: size[0],
            height: size[1]
        };
    }
};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var bind$2 = bind;
var each$9 = each$1;
var parsePercent$2 = parsePercent$1;

var proxyRect = new Rect({
    shape: {x: -1, y: -1, width: 2, height: 2}
});

extendComponentView({

    type: 'tooltip',

    init: function (ecModel, api) {
        if (env$1.node) {
            return;
        }

        var tooltipModel = ecModel.getComponent('tooltip');
        var renderMode = tooltipModel.get('renderMode');
        this._renderMode = getTooltipRenderMode(renderMode);

        var tooltipContent;
        if (this._renderMode === 'html') {
            tooltipContent = new TooltipContent(api.getDom(), api, {
                appendToBody: tooltipModel.get('appendToBody', true)
            });
            this._newLine = '<br/>';
        }
        else {
            tooltipContent = new TooltipRichContent(api);
            this._newLine = '\n';
        }

        this._tooltipContent = tooltipContent;
    },

    render: function (tooltipModel, ecModel, api) {
        if (env$1.node) {
            return;
        }

        // Reset
        this.group.removeAll();

        /**
         * @private
         * @type {module:echarts/component/tooltip/TooltipModel}
         */
        this._tooltipModel = tooltipModel;

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

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

        /**
         * Should be cleaned when render.
         * @private
         * @type {Array.<Array.<Object>>}
         */
        this._lastDataByCoordSys = null;

        /**
         * @private
         * @type {boolean}
         */
        this._alwaysShowContent = tooltipModel.get('alwaysShowContent');

        var tooltipContent = this._tooltipContent;
        tooltipContent.update(tooltipModel);
        tooltipContent.setEnterable(tooltipModel.get('enterable'));

        this._initGlobalListener();

        this._keepShow();
    },

    _initGlobalListener: function () {
        var tooltipModel = this._tooltipModel;
        var triggerOn = tooltipModel.get('triggerOn');

        register(
            'itemTooltip',
            this._api,
            bind$2(function (currTrigger, e, dispatchAction) {
                // If 'none', it is not controlled by mouse totally.
                if (triggerOn !== 'none') {
                    if (triggerOn.indexOf(currTrigger) >= 0) {
                        this._tryShow(e, dispatchAction);
                    }
                    else if (currTrigger === 'leave') {
                        this._hide(dispatchAction);
                    }
                }
            }, this)
        );
    },

    _keepShow: function () {
        var tooltipModel = this._tooltipModel;
        var ecModel = this._ecModel;
        var api = this._api;

        // Try to keep the tooltip show when refreshing
        if (this._lastX != null
            && this._lastY != null
            // When user is willing to control tooltip totally using API,
            // self.manuallyShowTip({x, y}) might cause tooltip hide,
            // which is not expected.
            && tooltipModel.get('triggerOn') !== 'none'
        ) {
            var self = this;
            clearTimeout(this._refreshUpdateTimeout);
            this._refreshUpdateTimeout = setTimeout(function () {
                // Show tip next tick after other charts are rendered
                // In case highlight action has wrong result
                // FIXME
                !api.isDisposed() && self.manuallyShowTip(tooltipModel, ecModel, api, {
                    x: self._lastX,
                    y: self._lastY
                });
            });
        }
    },

    /**
     * Show tip manually by
     * dispatchAction({
     *     type: 'showTip',
     *     x: 10,
     *     y: 10
     * });
     * Or
     * dispatchAction({
     *      type: 'showTip',
     *      seriesIndex: 0,
     *      dataIndex or dataIndexInside or name
     * });
     *
     *  TODO Batch
     */
    manuallyShowTip: function (tooltipModel, ecModel, api, payload) {
        if (payload.from === this.uid || env$1.node) {
            return;
        }

        var dispatchAction = makeDispatchAction$1(payload, api);

        // Reset ticket
        this._ticket = '';

        // When triggered from axisPointer.
        var dataByCoordSys = payload.dataByCoordSys;

        if (payload.tooltip && payload.x != null && payload.y != null) {
            var el = proxyRect;
            el.position = [payload.x, payload.y];
            el.update();
            el.tooltip = payload.tooltip;
            // Manually show tooltip while view is not using zrender elements.
            this._tryShow({
                offsetX: payload.x,
                offsetY: payload.y,
                target: el
            }, dispatchAction);
        }
        else if (dataByCoordSys) {
            this._tryShow({
                offsetX: payload.x,
                offsetY: payload.y,
                position: payload.position,
                dataByCoordSys: payload.dataByCoordSys,
                tooltipOption: payload.tooltipOption
            }, dispatchAction);
        }
        else if (payload.seriesIndex != null) {

            if (this._manuallyAxisShowTip(tooltipModel, ecModel, api, payload)) {
                return;
            }

            var pointInfo = findPointFromSeries(payload, ecModel);
            var cx = pointInfo.point[0];
            var cy = pointInfo.point[1];
            if (cx != null && cy != null) {
                this._tryShow({
                    offsetX: cx,
                    offsetY: cy,
                    position: payload.position,
                    target: pointInfo.el
                }, dispatchAction);
            }
        }
        else if (payload.x != null && payload.y != null) {
            // FIXME
            // should wrap dispatchAction like `axisPointer/globalListener` ?
            api.dispatchAction({
                type: 'updateAxisPointer',
                x: payload.x,
                y: payload.y
            });

            this._tryShow({
                offsetX: payload.x,
                offsetY: payload.y,
                position: payload.position,
                target: api.getZr().findHover(payload.x, payload.y).target
            }, dispatchAction);
        }
    },

    manuallyHideTip: function (tooltipModel, ecModel, api, payload) {
        var tooltipContent = this._tooltipContent;

        if (!this._alwaysShowContent && this._tooltipModel) {
            tooltipContent.hideLater(this._tooltipModel.get('hideDelay'));
        }

        this._lastX = this._lastY = null;

        if (payload.from !== this.uid) {
            this._hide(makeDispatchAction$1(payload, api));
        }
    },

    // Be compatible with previous design, that is, when tooltip.type is 'axis' and
    // dispatchAction 'showTip' with seriesIndex and dataIndex will trigger axis pointer
    // and tooltip.
    _manuallyAxisShowTip: function (tooltipModel, ecModel, api, payload) {
        var seriesIndex = payload.seriesIndex;
        var dataIndex = payload.dataIndex;
        var coordSysAxesInfo = ecModel.getComponent('axisPointer').coordSysAxesInfo;

        if (seriesIndex == null || dataIndex == null || coordSysAxesInfo == null) {
            return;
        }

        var seriesModel = ecModel.getSeriesByIndex(seriesIndex);
        if (!seriesModel) {
            return;
        }

        var data = seriesModel.getData();
        var tooltipModel = buildTooltipModel([
            data.getItemModel(dataIndex),
            seriesModel,
            (seriesModel.coordinateSystem || {}).model,
            tooltipModel
        ]);

        if (tooltipModel.get('trigger') !== 'axis') {
            return;
        }

        api.dispatchAction({
            type: 'updateAxisPointer',
            seriesIndex: seriesIndex,
            dataIndex: dataIndex,
            position: payload.position
        });

        return true;
    },

    _tryShow: function (e, dispatchAction) {
        var el = e.target;
        var tooltipModel = this._tooltipModel;

        if (!tooltipModel) {
            return;
        }

        // Save mouse x, mouse y. So we can try to keep showing the tip if chart is refreshed
        this._lastX = e.offsetX;
        this._lastY = e.offsetY;

        var dataByCoordSys = e.dataByCoordSys;
        if (dataByCoordSys && dataByCoordSys.length) {
            this._showAxisTooltip(dataByCoordSys, e);
        }
        // Always show item tooltip if mouse is on the element with dataIndex
        else if (el && el.dataIndex != null) {
            this._lastDataByCoordSys = null;
            this._showSeriesItemTooltip(e, el, dispatchAction);
        }
        // Tooltip provided directly. Like legend.
        else if (el && el.tooltip) {
            this._lastDataByCoordSys = null;
            this._showComponentItemTooltip(e, el, dispatchAction);
        }
        else {
            this._lastDataByCoordSys = null;
            this._hide(dispatchAction);
        }
    },

    _showOrMove: function (tooltipModel, cb) {
        // showDelay is used in this case: tooltip.enterable is set
        // as true. User intent to move mouse into tooltip and click
        // something. `showDelay` makes it easier to enter the content
        // but tooltip do not move immediately.
        var delay = tooltipModel.get('showDelay');
        cb = bind(cb, this);
        clearTimeout(this._showTimout);
        delay > 0
            ? (this._showTimout = setTimeout(cb, delay))
            : cb();
    },

    _showAxisTooltip: function (dataByCoordSys, e) {
        var ecModel = this._ecModel;
        var globalTooltipModel = this._tooltipModel;

        var point = [e.offsetX, e.offsetY];

        var singleDefaultHTML = [];
        var singleParamsList = [];
        var singleTooltipModel = buildTooltipModel([
            e.tooltipOption,
            globalTooltipModel
        ]);

        var renderMode = this._renderMode;
        var newLine = this._newLine;

        var markers = {};

        each$9(dataByCoordSys, function (itemCoordSys) {
            // var coordParamList = [];
            // var coordDefaultHTML = [];
            // var coordTooltipModel = buildTooltipModel([
            //     e.tooltipOption,
            //     itemCoordSys.tooltipOption,
            //     ecModel.getComponent(itemCoordSys.coordSysMainType, itemCoordSys.coordSysIndex),
            //     globalTooltipModel
            // ]);
            // var displayMode = coordTooltipModel.get('displayMode');
            // var paramsList = displayMode === 'single' ? singleParamsList : [];

            each$9(itemCoordSys.dataByAxis, function (item) {
                var axisModel = ecModel.getComponent(item.axisDim + 'Axis', item.axisIndex);
                var axisValue = item.value;
                var seriesDefaultHTML = [];

                if (!axisModel || axisValue == null) {
                    return;
                }

                var valueLabel = getValueLabel(
                    axisValue, axisModel.axis, ecModel,
                    item.seriesDataIndices,
                    item.valueLabelOpt
                );

                each$1(item.seriesDataIndices, function (idxItem) {
                    var series = ecModel.getSeriesByIndex(idxItem.seriesIndex);
                    var dataIndex = idxItem.dataIndexInside;
                    var dataParams = series && series.getDataParams(dataIndex);
                    dataParams.axisDim = item.axisDim;
                    dataParams.axisIndex = item.axisIndex;
                    dataParams.axisType = item.axisType;
                    dataParams.axisId = item.axisId;
                    dataParams.axisValue = getAxisRawValue(axisModel.axis, axisValue);
                    dataParams.axisValueLabel = valueLabel;

                    if (dataParams) {
                        singleParamsList.push(dataParams);
                        var seriesTooltip = series.formatTooltip(dataIndex, true, null, renderMode);

                        var html;
                        if (isObject$1(seriesTooltip)) {
                            html = seriesTooltip.html;
                            var newMarkers = seriesTooltip.markers;
                            merge(markers, newMarkers);
                        }
                        else {
                            html = seriesTooltip;
                        }
                        seriesDefaultHTML.push(html);
                    }
                });

                // Default tooltip content
                // FIXME
                // (1) should be the first data which has name?
                // (2) themeRiver, firstDataIndex is array, and first line is unnecessary.
                var firstLine = valueLabel;
                if (renderMode !== 'html') {
                    singleDefaultHTML.push(seriesDefaultHTML.join(newLine));
                }
                else {
                    singleDefaultHTML.push(
                        (firstLine ? encodeHTML(firstLine) + newLine : '')
                        + seriesDefaultHTML.join(newLine)
                    );
                }
            });
        }, this);

        // In most case, the second axis is shown upper than the first one.
        singleDefaultHTML.reverse();
        singleDefaultHTML = singleDefaultHTML.join(this._newLine + this._newLine);

        var positionExpr = e.position;
        this._showOrMove(singleTooltipModel, function () {
            if (this._updateContentNotChangedOnAxis(dataByCoordSys)) {
                this._updatePosition(
                    singleTooltipModel,
                    positionExpr,
                    point[0], point[1],
                    this._tooltipContent,
                    singleParamsList
                );
            }
            else {
                this._showTooltipContent(
                    singleTooltipModel, singleDefaultHTML, singleParamsList, Math.random(),
                    point[0], point[1], positionExpr, undefined, markers
                );
            }
        });

        // Do not trigger events here, because this branch only be entered
        // from dispatchAction.
    },

    _showSeriesItemTooltip: function (e, el, dispatchAction) {
        var ecModel = this._ecModel;
        // Use dataModel in element if possible
        // Used when mouseover on a element like markPoint or edge
        // In which case, the data is not main data in series.
        var seriesIndex = el.seriesIndex;
        var seriesModel = ecModel.getSeriesByIndex(seriesIndex);

        // For example, graph link.
        var dataModel = el.dataModel || seriesModel;
        var dataIndex = el.dataIndex;
        var dataType = el.dataType;
        var data = dataModel.getData(dataType);

        var tooltipModel = buildTooltipModel([
            data.getItemModel(dataIndex),
            dataModel,
            seriesModel && (seriesModel.coordinateSystem || {}).model,
            this._tooltipModel
        ]);

        var tooltipTrigger = tooltipModel.get('trigger');
        if (tooltipTrigger != null && tooltipTrigger !== 'item') {
            return;
        }

        var params = dataModel.getDataParams(dataIndex, dataType);
        var seriesTooltip = dataModel.formatTooltip(dataIndex, false, dataType, this._renderMode);
        var defaultHtml;
        var markers;
        if (isObject$1(seriesTooltip)) {
            defaultHtml = seriesTooltip.html;
            markers = seriesTooltip.markers;
        }
        else {
            defaultHtml = seriesTooltip;
            markers = null;
        }

        var asyncTicket = 'item_' + dataModel.name + '_' + dataIndex;

        this._showOrMove(tooltipModel, function () {
            this._showTooltipContent(
                tooltipModel, defaultHtml, params, asyncTicket,
                e.offsetX, e.offsetY, e.position, e.target, markers
            );
        });

        // FIXME
        // duplicated showtip if manuallyShowTip is called from dispatchAction.
        dispatchAction({
            type: 'showTip',
            dataIndexInside: dataIndex,
            dataIndex: data.getRawIndex(dataIndex),
            seriesIndex: seriesIndex,
            from: this.uid
        });
    },

    _showComponentItemTooltip: function (e, el, dispatchAction) {
        var tooltipOpt = el.tooltip;
        if (typeof tooltipOpt === 'string') {
            var content = tooltipOpt;
            tooltipOpt = {
                content: content,
                // Fixed formatter
                formatter: content
            };
        }
        var subTooltipModel = new Model(tooltipOpt, this._tooltipModel, this._ecModel);
        var defaultHtml = subTooltipModel.get('content');
        var asyncTicket = Math.random();

        // Do not check whether `trigger` is 'none' here, because `trigger`
        // only works on coordinate system. In fact, we have not found case
        // that requires setting `trigger` nothing on component yet.

        this._showOrMove(subTooltipModel, function () {
            this._showTooltipContent(
                subTooltipModel, defaultHtml, subTooltipModel.get('formatterParams') || {},
                asyncTicket, e.offsetX, e.offsetY, e.position, el
            );
        });

        // If not dispatch showTip, tip may be hide triggered by axis.
        dispatchAction({
            type: 'showTip',
            from: this.uid
        });
    },

    _showTooltipContent: function (
        tooltipModel, defaultHtml, params, asyncTicket, x, y, positionExpr, el, markers
    ) {
        // Reset ticket
        this._ticket = '';

        if (!tooltipModel.get('showContent') || !tooltipModel.get('show')) {
            return;
        }

        var tooltipContent = this._tooltipContent;

        var formatter = tooltipModel.get('formatter');
        positionExpr = positionExpr || tooltipModel.get('position');
        var html = defaultHtml;

        if (formatter && typeof formatter === 'string') {
            html = formatTpl(formatter, params, true);
        }
        else if (typeof formatter === 'function') {
            var callback = bind$2(function (cbTicket, html) {
                if (cbTicket === this._ticket) {
                    tooltipContent.setContent(html, markers, tooltipModel);
                    this._updatePosition(
                        tooltipModel, positionExpr, x, y, tooltipContent, params, el
                    );
                }
            }, this);
            this._ticket = asyncTicket;
            html = formatter(params, asyncTicket, callback);
        }

        tooltipContent.setContent(html, markers, tooltipModel);
        tooltipContent.show(tooltipModel);

        this._updatePosition(
            tooltipModel, positionExpr, x, y, tooltipContent, params, el
        );
    },

    /**
     * @param  {string|Function|Array.<number>|Object} positionExpr
     * @param  {number} x Mouse x
     * @param  {number} y Mouse y
     * @param  {boolean} confine Whether confine tooltip content in view rect.
     * @param  {Object|<Array.<Object>} params
     * @param  {module:zrender/Element} el target element
     * @param  {module:echarts/ExtensionAPI} api
     * @return {Array.<number>}
     */
    _updatePosition: function (tooltipModel, positionExpr, x, y, content, params, el) {
        var viewWidth = this._api.getWidth();
        var viewHeight = this._api.getHeight();

        positionExpr = positionExpr || tooltipModel.get('position');

        var contentSize = content.getSize();
        var align = tooltipModel.get('align');
        var vAlign = tooltipModel.get('verticalAlign');
        var rect = el && el.getBoundingRect().clone();
        el && rect.applyTransform(el.transform);

        if (typeof positionExpr === 'function') {
            // Callback of position can be an array or a string specify the position
            positionExpr = positionExpr([x, y], params, content.el, rect, {
                viewSize: [viewWidth, viewHeight],
                contentSize: contentSize.slice()
            });
        }

        if (isArray(positionExpr)) {
            x = parsePercent$2(positionExpr[0], viewWidth);
            y = parsePercent$2(positionExpr[1], viewHeight);
        }
        else if (isObject$1(positionExpr)) {
            positionExpr.width = contentSize[0];
            positionExpr.height = contentSize[1];
            var layoutRect = getLayoutRect(
                positionExpr, {width: viewWidth, height: viewHeight}
            );
            x = layoutRect.x;
            y = layoutRect.y;
            align = null;
            // When positionExpr is left/top/right/bottom,
            // align and verticalAlign will not work.
            vAlign = null;
        }
        // Specify tooltip position by string 'top' 'bottom' 'left' 'right' around graphic element
        else if (typeof positionExpr === 'string' && el) {
            var pos = calcTooltipPosition(
                positionExpr, rect, contentSize
            );
            x = pos[0];
            y = pos[1];
        }
        else {
            var pos = refixTooltipPosition(
                x, y, content, viewWidth, viewHeight, align ? null : 20, vAlign ? null : 20
            );
            x = pos[0];
            y = pos[1];
        }

        align && (x -= isCenterAlign(align) ? contentSize[0] / 2 : align === 'right' ? contentSize[0] : 0);
        vAlign && (y -= isCenterAlign(vAlign) ? contentSize[1] / 2 : vAlign === 'bottom' ? contentSize[1] : 0);

        if (tooltipModel.get('confine')) {
            var pos = confineTooltipPosition(
                x, y, content, viewWidth, viewHeight
            );
            x = pos[0];
            y = pos[1];
        }

        content.moveTo(x, y);
    },

    // FIXME
    // Should we remove this but leave this to user?
    _updateContentNotChangedOnAxis: function (dataByCoordSys) {
        var lastCoordSys = this._lastDataByCoordSys;
        var contentNotChanged = !!lastCoordSys
            && lastCoordSys.length === dataByCoordSys.length;

        contentNotChanged && each$9(lastCoordSys, function (lastItemCoordSys, indexCoordSys) {
            var lastDataByAxis = lastItemCoordSys.dataByAxis || {};
            var thisItemCoordSys = dataByCoordSys[indexCoordSys] || {};
            var thisDataByAxis = thisItemCoordSys.dataByAxis || [];
            contentNotChanged &= lastDataByAxis.length === thisDataByAxis.length;

            contentNotChanged && each$9(lastDataByAxis, function (lastItem, indexAxis) {
                var thisItem = thisDataByAxis[indexAxis] || {};
                var lastIndices = lastItem.seriesDataIndices || [];
                var newIndices = thisItem.seriesDataIndices || [];

                contentNotChanged
                    &= lastItem.value === thisItem.value
                    && lastItem.axisType === thisItem.axisType
                    && lastItem.axisId === thisItem.axisId
                    && lastIndices.length === newIndices.length;

                contentNotChanged && each$9(lastIndices, function (lastIdxItem, j) {
                    var newIdxItem = newIndices[j];
                    contentNotChanged
                        &= lastIdxItem.seriesIndex === newIdxItem.seriesIndex
                        && lastIdxItem.dataIndex === newIdxItem.dataIndex;
                });
            });
        });

        this._lastDataByCoordSys = dataByCoordSys;

        return !!contentNotChanged;
    },

    _hide: function (dispatchAction) {
        // Do not directly hideLater here, because this behavior may be prevented
        // in dispatchAction when showTip is dispatched.

        // FIXME
        // duplicated hideTip if manuallyHideTip is called from dispatchAction.
        this._lastDataByCoordSys = null;
        dispatchAction({
            type: 'hideTip',
            from: this.uid
        });
    },

    dispose: function (ecModel, api) {
        if (env$1.node) {
            return;
        }
        this._tooltipContent.dispose();
        unregister('itemTooltip', api);
    }
});


/**
 * @param {Array.<Object|module:echarts/model/Model>} modelCascade
 * From top to bottom. (the last one should be globalTooltipModel);
 */
function buildTooltipModel(modelCascade) {
    var resultModel = modelCascade.pop();
    while (modelCascade.length) {
        var tooltipOpt = modelCascade.pop();
        if (tooltipOpt) {
            if (Model.isInstance(tooltipOpt)) {
                tooltipOpt = tooltipOpt.get('tooltip', true);
            }
            // In each data item tooltip can be simply write:
            // {
            //  value: 10,
            //  tooltip: 'Something you need to know'
            // }
            if (typeof tooltipOpt === 'string') {
                tooltipOpt = {formatter: tooltipOpt};
            }
            resultModel = new Model(tooltipOpt, resultModel, resultModel.ecModel);
        }
    }
    return resultModel;
}

function makeDispatchAction$1(payload, api) {
    return payload.dispatchAction || bind(api.dispatchAction, api);
}

function refixTooltipPosition(x, y, content, viewWidth, viewHeight, gapH, gapV) {
    var size = content.getOuterSize();
    var width = size.width;
    var height = size.height;

    if (gapH != null) {
        if (x + width + gapH > viewWidth) {
            x -= width + gapH;
        }
        else {
            x += gapH;
        }
    }
    if (gapV != null) {
        if (y + height + gapV > viewHeight) {
            y -= height + gapV;
        }
        else {
            y += gapV;
        }
    }
    return [x, y];
}

function confineTooltipPosition(x, y, content, viewWidth, viewHeight) {
    var size = content.getOuterSize();
    var width = size.width;
    var height = size.height;

    x = Math.min(x + width, viewWidth) - width;
    y = Math.min(y + height, viewHeight) - height;
    x = Math.max(x, 0);
    y = Math.max(y, 0);

    return [x, y];
}

function calcTooltipPosition(position, rect, contentSize) {
    var domWidth = contentSize[0];
    var domHeight = contentSize[1];
    var gap = 5;
    var x = 0;
    var y = 0;
    var rectWidth = rect.width;
    var rectHeight = rect.height;
    switch (position) {
        case 'inside':
            x = rect.x + rectWidth / 2 - domWidth / 2;
            y = rect.y + rectHeight / 2 - domHeight / 2;
            break;
        case 'top':
            x = rect.x + rectWidth / 2 - domWidth / 2;
            y = rect.y - domHeight - gap;
            break;
        case 'bottom':
            x = rect.x + rectWidth / 2 - domWidth / 2;
            y = rect.y + rectHeight + gap;
            break;
        case 'left':
            x = rect.x - domWidth - gap;
            y = rect.y + rectHeight / 2 - domHeight / 2;
            break;
        case 'right':
            x = rect.x + rectWidth + gap;
            y = rect.y + rectHeight / 2 - domHeight / 2;
    }
    return [x, y];
}

function isCenterAlign(align) {
    return align === 'center' || align === 'middle';
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

// FIXME Better way to pack data in graphic element

/**
 * @action
 * @property {string} type
 * @property {number} seriesIndex
 * @property {number} dataIndex
 * @property {number} [x]
 * @property {number} [y]
 */
registerAction(
    {
        type: 'showTip',
        event: 'showTip',
        update: 'tooltip:manuallyShowTip'
    },
    // noop
    function () {}
);

registerAction(
    {
        type: 'hideTip',
        event: 'hideTip',
        update: 'tooltip:manuallyHideTip'
    },
    // noop
    function () {}
);

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var langSelector = lang.legend.selector;

var defaultSelectorOption = {
    all: {
        type: 'all',
        title: clone(langSelector.all)
    },
    inverse: {
        type: 'inverse',
        title: clone(langSelector.inverse)
    }
};

var LegendModel = extendComponentModel({

    type: 'legend.plain',

    dependencies: ['series'],

    layoutMode: {
        type: 'box',
        // legend.width/height are maxWidth/maxHeight actually,
        // whereas realy width/height is calculated by its content.
        // (Setting {left: 10, right: 10} does not make sense).
        // So consider the case:
        // `setOption({legend: {left: 10});`
        // then `setOption({legend: {right: 10});`
        // The previous `left` should be cleared by setting `ignoreSize`.
        ignoreSize: true
    },

    init: function (option, parentModel, ecModel) {
        this.mergeDefaultAndTheme(option, ecModel);

        option.selected = option.selected || {};
        this._updateSelector(option);
    },

    mergeOption: function (option) {
        LegendModel.superCall(this, 'mergeOption', option);
        this._updateSelector(option);
    },

    _updateSelector: function (option) {
        var selector = option.selector;
        if (selector === true) {
            selector = option.selector = ['all', 'inverse'];
        }
        if (isArray(selector)) {
            each$1(selector, function (item, index) {
                isString(item) && (item = {type: item});
                selector[index] = merge(item, defaultSelectorOption[item.type]);
            });
        }
    },

    optionUpdated: function () {
        this._updateData(this.ecModel);

        var legendData = this._data;

        // If selectedMode is single, try to select one
        if (legendData[0] && this.get('selectedMode') === 'single') {
            var hasSelected = false;
            // If has any selected in option.selected
            for (var i = 0; i < legendData.length; i++) {
                var name = legendData[i].get('name');
                if (this.isSelected(name)) {
                    // Force to unselect others
                    this.select(name);
                    hasSelected = true;
                    break;
                }
            }
            // Try select the first if selectedMode is single
            !hasSelected && this.select(legendData[0].get('name'));
        }
    },

    _updateData: function (ecModel) {
        var potentialData = [];
        var availableNames = [];

        ecModel.eachRawSeries(function (seriesModel) {
            var seriesName = seriesModel.name;
            availableNames.push(seriesName);
            var isPotential;

            if (seriesModel.legendVisualProvider) {
                var provider = seriesModel.legendVisualProvider;
                var names = provider.getAllNames();

                if (!ecModel.isSeriesFiltered(seriesModel)) {
                    availableNames = availableNames.concat(names);
                }

                if (names.length) {
                    potentialData = potentialData.concat(names);
                }
                else {
                    isPotential = true;
                }
            }
            else {
                isPotential = true;
            }

            if (isPotential && isNameSpecified(seriesModel)) {
                potentialData.push(seriesModel.name);
            }
        });

        /**
         * @type {Array.<string>}
         * @private
         */
        this._availableNames = availableNames;

        // If legend.data not specified in option, use availableNames as data,
        // which is convinient for user preparing option.
        var rawData = this.get('data') || potentialData;

        var legendData = map(rawData, function (dataItem) {
            // Can be string or number
            if (typeof dataItem === 'string' || typeof dataItem === 'number') {
                dataItem = {
                    name: dataItem
                };
            }
            return new Model(dataItem, this, this.ecModel);
        }, this);

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

    /**
     * @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;
            each$1(data, function (dataItem) {
                selected[dataItem.get('name')] = false;
            });
        }
        selected[name] = true;
    },

    /**
     * @param {string} name
     */
    unSelect: function (name) {
        if (this.get('selectedMode') !== 'single') {
            this.option.selected[name] = false;
        }
    },

    /**
     * @param {string} name
     */
    toggleSelected: function (name) {
        var selected = this.option.selected;
        // Default is true
        if (!selected.hasOwnProperty(name)) {
            selected[name] = true;
        }
        this[selected[name] ? 'unSelect' : 'select'](name);
    },

    allSelect: function () {
        var data = this._data;
        var selected = this.option.selected;
        each$1(data, function (dataItem) {
            selected[dataItem.get('name', true)] = true;
        });
    },

    inverseSelect: function () {
        var data = this._data;
        var selected = this.option.selected;
        each$1(data, function (dataItem) {
            var name = dataItem.get('name', true);
            // Initially, default value is true
            if (!selected.hasOwnProperty(name)) {
                selected[name] = true;
            }
            selected[name] = !selected[name];
        });
    },

    /**
     * @param {string} name
     */
    isSelected: function (name) {
        var selected = this.option.selected;
        return !(selected.hasOwnProperty(name) && !selected[name])
            && indexOf(this._availableNames, name) >= 0;
    },

    getOrient: function () {
        return this.get('orient') === 'vertical'
            ? {index: 1, name: 'vertical'}
            : {index: 0, name: 'horizontal'};
    },

    defaultOption: {
        // 一级层叠
        zlevel: 0,
        // 二级层叠
        z: 4,
        show: true,

        // 布局方式，默认为水平布局，可选为：
        // 'horizontal' | 'vertical'
        orient: 'horizontal',

        left: 'center',
        // right: 'center',

        top: 0,
        // bottom: null,

        // 水平对齐
        // 'auto' | 'left' | 'right'
        // 默认为 'auto', 根据 x 的位置判断是左对齐还是右对齐
        align: 'auto',

        backgroundColor: 'rgba(0,0,0,0)',
        // 图例边框颜色
        borderColor: '#ccc',
        borderRadius: 0,
        // 图例边框线宽，单位px，默认为0（无边框）
        borderWidth: 0,
        // 图例内边距，单位px，默认各方向内边距为5，
        // 接受数组分别设定上右下左边距，同css
        padding: 5,
        // 各个item之间的间隔，单位px，默认为10，
        // 横向布局时为水平间隔，纵向布局时为纵向间隔
        itemGap: 10,
        // the width of legend symbol
        itemWidth: 25,
        // the height of legend symbol
        itemHeight: 14,

        // the color of unselected legend symbol
        inactiveColor: '#ccc',

        // the borderColor of unselected legend symbol
        inactiveBorderColor: '#ccc',

        itemStyle: {
            // the default borderWidth of legend symbol
            borderWidth: 0
        },

        textStyle: {
            // 图例文字颜色
            color: '#333'
        },
        // formatter: '',
        // 选择模式，默认开启图例开关
        selectedMode: true,
        // 配置默认选中状态，可配合LEGEND.SELECTED事件做动态数据载入
        // selected: null,
        // 图例内容（详见legend.data，数组中每一项代表一个item
        // data: [],

        // Usage:
        // selector: [{type: 'all or inverse', title: xxx}]
        // or
        // selector: true
        // or
        // selector: ['all', 'inverse']
        selector: false,

        selectorLabel: {
            show: true,
            borderRadius: 10,
            padding: [3, 5, 3, 5],
            fontSize: 12,
            fontFamily: ' sans-serif',
            color: '#666',
            borderWidth: 1,
            borderColor: '#666'
        },

        emphasis: {
            selectorLabel: {
                show: true,
                color: '#eee',
                backgroundColor: '#666'
            }
        },

        // Value can be 'start' or 'end'
        selectorPosition: 'auto',

        selectorItemGap: 7,

        selectorButtonGap: 10,

        // Tooltip 相关配置
        tooltip: {
            show: false
        }
    }
});

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

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 if (methodName === 'allSelect' || methodName === 'inverseSelect') {
            legendModel[methodName]();
        }
        else {
            legendModel[methodName](payload.name);
            isSelected = legendModel.isSelected(payload.name);
        }
        var legendData = legendModel.getData();
        each$1(legendData, function (model) {
            var name = model.get('name');
            // Wrap element
            if (name === '\n' || name === '') {
                return;
            }
            var isItemSelected = legendModel.isSelected(name);
            if (selectedMap.hasOwnProperty(name)) {
                // Unselected if any legend is unselected
                selectedMap[name] = selectedMap[name] && isItemSelected;
            }
            else {
                selectedMap[name] = isItemSelected;
            }
        });
    });
    // Return the event explicitly
    return (methodName === 'allSelect' || methodName === 'inverseSelect')
        ? {
            selected: selectedMap
        }
        : {
            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
 */
registerAction(
    'legendToggleSelect', 'legendselectchanged',
    curry(legendSelectActionHandler, 'toggleSelected')
);

registerAction(
    'legendAllSelect', 'legendselectall',
    curry(legendSelectActionHandler, 'allSelect')
);

registerAction(
    'legendInverseSelect', 'legendinverseselect',
    curry(legendSelectActionHandler, 'inverseSelect')
);

/**
 * @event legendSelect
 * @type {Object}
 * @property {string} type 'legendSelect'
 * @property {string} name Series name or data item name
 */
registerAction(
    'legendSelect', 'legendselected',
    curry(legendSelectActionHandler, 'select')
);

/**
 * @event legendUnSelect
 * @type {Object}
 * @property {string} type 'legendUnSelect'
 * @property {string} name Series name or data item name
 */
registerAction(
    'legendUnSelect', 'legendunselected',
    curry(legendSelectActionHandler, 'unSelect')
);

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * 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}
 */
function layout$2(group, componentModel, api) {
    var boxLayoutParams = componentModel.getBoxLayoutParams();
    var padding = componentModel.get('padding');
    var viewportSize = {width: api.getWidth(), height: api.getHeight()};

    var rect = getLayoutRect(
        boxLayoutParams,
        viewportSize,
        padding
    );

    box(
        componentModel.get('orient'),
        group,
        componentModel.get('itemGap'),
        rect.width,
        rect.height
    );

    positionElement(
        group,
        boxLayoutParams,
        viewportSize,
        padding
    );
}

function makeBackground(rect, componentModel) {
    var padding = normalizeCssArray$1(
        componentModel.get('padding')
    );
    var style = componentModel.getItemStyle(['color', 'opacity']);
    style.fill = componentModel.get('backgroundColor');
    var rect = new Rect({
        shape: {
            x: rect.x - padding[3],
            y: rect.y - padding[0],
            width: rect.width + padding[1] + padding[3],
            height: rect.height + padding[0] + padding[2],
            r: componentModel.get('borderRadius')
        },
        style: style,
        silent: true,
        z2: -1
    });
    // FIXME
    // `subPixelOptimizeRect` may bring some gap between edge of viewpart
    // and background rect when setting like `left: 0`, `top: 0`.
    // graphic.subPixelOptimizeRect(rect);

    return rect;
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var curry$3 = curry;
var each$11 = each$1;
var Group$2 = Group;

var LegendView = extendComponentView({

    type: 'legend.plain',

    newlineDisabled: false,

    /**
     * @override
     */
    init: function () {

        /**
         * @private
         * @type {module:zrender/container/Group}
         */
        this.group.add(this._contentGroup = new Group$2());

        /**
         * @private
         * @type {module:zrender/Element}
         */
        this._backgroundEl;

        /**
         * @private
         * @type {module:zrender/container/Group}
         */
        this.group.add(this._selectorGroup = new Group$2());

        /**
         * If first rendering, `contentGroup.position` is [0, 0], which
         * does not make sense and may cause unexepcted animation if adopted.
         * @private
         * @type {boolean}
         */
        this._isFirstRender = true;
    },

    /**
     * @protected
     */
    getContentGroup: function () {
        return this._contentGroup;
    },

    /**
     * @protected
     */
    getSelectorGroup: function () {
        return this._selectorGroup;
    },

    /**
     * @override
     */
    render: function (legendModel, ecModel, api) {
        var isFirstRender = this._isFirstRender;
        this._isFirstRender = false;

        this.resetInner();

        if (!legendModel.get('show', true)) {
            return;
        }

        var itemAlign = legendModel.get('align');
        var orient = legendModel.get('orient');
        if (!itemAlign || itemAlign === 'auto') {
            itemAlign = (
                legendModel.get('left') === 'right'
                && orient === 'vertical'
            ) ? 'right' : 'left';
        }

        var selector = legendModel.get('selector', true);
        var selectorPosition = legendModel.get('selectorPosition', true);
        if (selector && (!selectorPosition || selectorPosition === 'auto')) {
            selectorPosition = orient === 'horizontal' ? 'end' : 'start';
        }

        this.renderInner(itemAlign, legendModel, ecModel, api, selector, orient, selectorPosition);

        // Perform layout.
        var positionInfo = legendModel.getBoxLayoutParams();
        var viewportSize = {width: api.getWidth(), height: api.getHeight()};
        var padding = legendModel.get('padding');

        var maxSize = getLayoutRect(positionInfo, viewportSize, padding);

        var mainRect = this.layoutInner(legendModel, itemAlign, maxSize, isFirstRender, selector, selectorPosition);

        // Place mainGroup, based on the calculated `mainRect`.
        var layoutRect = getLayoutRect(
            defaults({width: mainRect.width, height: mainRect.height}, positionInfo),
            viewportSize,
            padding
        );
        this.group.attr('position', [layoutRect.x - mainRect.x, layoutRect.y - mainRect.y]);

        // Render background after group is layout.
        this.group.add(
            this._backgroundEl = makeBackground(mainRect, legendModel)
        );
    },

    /**
     * @protected
     */
    resetInner: function () {
        this.getContentGroup().removeAll();
        this._backgroundEl && this.group.remove(this._backgroundEl);
        this.getSelectorGroup().removeAll();
    },

    /**
     * @protected
     */
    renderInner: function (itemAlign, legendModel, ecModel, api, selector, orient, selectorPosition) {
        var contentGroup = this.getContentGroup();
        var legendDrawnMap = createHashMap();
        var selectMode = legendModel.get('selectedMode');

        var excludeSeriesId = [];
        ecModel.eachRawSeries(function (seriesModel) {
            !seriesModel.get('legendHoverLink') && excludeSeriesId.push(seriesModel.id);
        });

        each$11(legendModel.getData(), function (itemModel, dataIndex) {
            var name = itemModel.get('name');

            // Use empty string or \n as a newline string
            if (!this.newlineDisabled && (name === '' || name === '\n')) {
                contentGroup.add(new Group$2({
                    newline: true
                }));
                return;
            }

            // Representitive series.
            var seriesModel = ecModel.getSeriesByName(name)[0];

            if (legendDrawnMap.get(name)) {
                // Have been drawed
                return;
            }

            // Legend to control series.
            if (seriesModel) {
                var data = seriesModel.getData();
                var color = data.getVisual('color');
                var borderColor = data.getVisual('borderColor');

                // If color is a callback function
                if (typeof color === 'function') {
                    // Use the first data
                    color = color(seriesModel.getDataParams(0));
                }

                 // If borderColor is a callback function
                if (typeof borderColor === 'function') {
                    // Use the first data
                    borderColor = borderColor(seriesModel.getDataParams(0));
                }

                // Using rect symbol defaultly
                var legendSymbolType = data.getVisual('legendSymbol') || 'roundRect';
                var symbolType = data.getVisual('symbol');

                var itemGroup = this._createItem(
                    name, dataIndex, itemModel, legendModel,
                    legendSymbolType, symbolType,
                    itemAlign, color, borderColor,
                    selectMode
                );

                itemGroup.on('click', curry$3(dispatchSelectAction, name, null, api, excludeSeriesId))
                    .on('mouseover', curry$3(dispatchHighlightAction, seriesModel.name, null, api, excludeSeriesId))
                    .on('mouseout', curry$3(dispatchDownplayAction, seriesModel.name, null, api, excludeSeriesId));

                legendDrawnMap.set(name, true);
            }
            else {
                // Legend to control data. In pie and funnel.
                ecModel.eachRawSeries(function (seriesModel) {

                    // In case multiple series has same data name
                    if (legendDrawnMap.get(name)) {
                        return;
                    }

                    if (seriesModel.legendVisualProvider) {
                        var provider = seriesModel.legendVisualProvider;
                        if (!provider.containName(name)) {
                            return;
                        }

                        var idx = provider.indexOfName(name);

                        var color = provider.getItemVisual(idx, 'color');
                        var borderColor = provider.getItemVisual(idx, 'borderColor');

                        var legendSymbolType = 'roundRect';

                        var itemGroup = this._createItem(
                            name, dataIndex, itemModel, legendModel,
                            legendSymbolType, null,
                            itemAlign, color, borderColor,
                            selectMode
                        );

                        // FIXME: consider different series has items with the same name.
                        itemGroup.on('click', curry$3(dispatchSelectAction, null, name, api, excludeSeriesId))
                            // Should not specify the series name, consider legend controls
                            // more than one pie series.
                            .on('mouseover', curry$3(dispatchHighlightAction, null, name, api, excludeSeriesId))
                            .on('mouseout', curry$3(dispatchDownplayAction, null, name, api, excludeSeriesId));

                        legendDrawnMap.set(name, true);
                    }

                }, this);
            }

            if (__DEV__) {
                if (!legendDrawnMap.get(name)) {
                    console.warn(
                        name + ' series not exists. Legend data should be same with series name or data name.'
                    );
                }
            }
        }, this);

        if (selector) {
            this._createSelector(selector, legendModel, api, orient, selectorPosition);
        }
    },

    _createSelector: function (selector, legendModel, api, orient, selectorPosition) {
        var selectorGroup = this.getSelectorGroup();

        each$11(selector, function (selectorItem) {
            createSelectorButton(selectorItem);
        });

        function createSelectorButton(selectorItem) {
            var type = selectorItem.type;

            var labelText = new Text({
                style: {
                    x: 0,
                    y: 0,
                    align: 'center',
                    verticalAlign: 'middle'
                },
                onclick: function () {
                    api.dispatchAction({
                        type: type === 'all' ? 'legendAllSelect' : 'legendInverseSelect'
                    });
                }
            });

            selectorGroup.add(labelText);

            var labelModel = legendModel.getModel('selectorLabel');
            var emphasisLabelModel = legendModel.getModel('emphasis.selectorLabel');

            setLabelStyle(
                labelText.style, labelText.hoverStyle = {}, labelModel, emphasisLabelModel,
                {
                    defaultText: selectorItem.title,
                    isRectText: false
                }
            );
            setHoverStyle(labelText);
        }
    },

    _createItem: function (
        name, dataIndex, itemModel, legendModel,
        legendSymbolType, symbolType,
        itemAlign, color, borderColor, selectMode
    ) {
        var itemWidth = legendModel.get('itemWidth');
        var itemHeight = legendModel.get('itemHeight');
        var inactiveColor = legendModel.get('inactiveColor');
        var inactiveBorderColor = legendModel.get('inactiveBorderColor');
        var symbolKeepAspect = legendModel.get('symbolKeepAspect');
        var legendModelItemStyle = legendModel.getModel('itemStyle');

        var isSelected = legendModel.isSelected(name);
        var itemGroup = new Group$2();

        var textStyleModel = itemModel.getModel('textStyle');

        var itemIcon = itemModel.get('icon');

        var tooltipModel = itemModel.getModel('tooltip');
        var legendGlobalTooltipModel = tooltipModel.parentModel;

        // Use user given icon first
        legendSymbolType = itemIcon || legendSymbolType;
        var legendSymbol = createSymbol(
            legendSymbolType,
            0,
            0,
            itemWidth,
            itemHeight,
            isSelected ? color : inactiveColor,
            // symbolKeepAspect default true for legend
            symbolKeepAspect == null ? true : symbolKeepAspect
        );
        itemGroup.add(
            setSymbolStyle(
                legendSymbol, legendSymbolType, legendModelItemStyle,
                borderColor, inactiveBorderColor, isSelected
            )
        );

        // Compose symbols
        // PENDING
        if (!itemIcon && symbolType
            // At least show one symbol, can't be all none
            && ((symbolType !== legendSymbolType) || symbolType === 'none')
        ) {
            var size = itemHeight * 0.8;
            if (symbolType === 'none') {
                symbolType = 'circle';
            }
            var legendSymbolCenter = createSymbol(
                symbolType,
                (itemWidth - size) / 2,
                (itemHeight - size) / 2,
                size,
                size,
                isSelected ? color : inactiveColor,
                // symbolKeepAspect default true for legend
                symbolKeepAspect == null ? true : symbolKeepAspect
            );
            // Put symbol in the center
            itemGroup.add(
                setSymbolStyle(
                    legendSymbolCenter, symbolType, legendModelItemStyle,
                    borderColor, inactiveBorderColor, isSelected
                )
            );
        }

        var textX = itemAlign === 'left' ? itemWidth + 5 : -5;
        var textAlign = itemAlign;

        var formatter = legendModel.get('formatter');
        var content = name;
        if (typeof formatter === 'string' && formatter) {
            content = formatter.replace('{name}', name != null ? name : '');
        }
        else if (typeof formatter === 'function') {
            content = formatter(name);
        }

        itemGroup.add(new Text({
            style: setTextStyle({}, textStyleModel, {
                text: content,
                x: textX,
                y: itemHeight / 2,
                textFill: isSelected ? textStyleModel.getTextColor() : inactiveColor,
                textAlign: textAlign,
                textVerticalAlign: 'middle'
            })
        }));

        // Add a invisible rect to increase the area of mouse hover
        var hitRect = new Rect({
            shape: itemGroup.getBoundingRect(),
            invisible: true,
            tooltip: tooltipModel.get('show') ? extend({
                content: name,
                // Defaul formatter
                formatter: legendGlobalTooltipModel.get('formatter', true) || function () {
                    return name;
                },
                formatterParams: {
                    componentType: 'legend',
                    legendIndex: legendModel.componentIndex,
                    name: name,
                    $vars: ['name']
                }
            }, tooltipModel.option) : null
        });
        itemGroup.add(hitRect);

        itemGroup.eachChild(function (child) {
            child.silent = true;
        });

        hitRect.silent = !selectMode;

        this.getContentGroup().add(itemGroup);

        setHoverStyle(itemGroup);

        itemGroup.__legendDataIndex = dataIndex;

        return itemGroup;
    },

    /**
     * @protected
     */
    layoutInner: function (legendModel, itemAlign, maxSize, isFirstRender, selector, selectorPosition) {
        var contentGroup = this.getContentGroup();
        var selectorGroup = this.getSelectorGroup();

        // Place items in contentGroup.
        box(
            legendModel.get('orient'),
            contentGroup,
            legendModel.get('itemGap'),
            maxSize.width,
            maxSize.height
        );

        var contentRect = contentGroup.getBoundingRect();
        var contentPos = [-contentRect.x, -contentRect.y];

        if (selector) {
            // Place buttons in selectorGroup
            box(
                // Buttons in selectorGroup always layout horizontally
                'horizontal',
                selectorGroup,
                legendModel.get('selectorItemGap', true)
            );

            var selectorRect = selectorGroup.getBoundingRect();
            var selectorPos = [-selectorRect.x, -selectorRect.y];
            var selectorButtonGap = legendModel.get('selectorButtonGap', true);

            var orientIdx = legendModel.getOrient().index;
            var wh = orientIdx === 0 ? 'width' : 'height';
            var hw = orientIdx === 0 ? 'height' : 'width';
            var yx = orientIdx === 0 ? 'y' : 'x';

            if (selectorPosition === 'end') {
                selectorPos[orientIdx] += contentRect[wh] + selectorButtonGap;
            }
            else {
                contentPos[orientIdx] += selectorRect[wh] + selectorButtonGap;
            }

            //Always align selector to content as 'middle'
            selectorPos[1 - orientIdx] += contentRect[hw] / 2 - selectorRect[hw] / 2;
            selectorGroup.attr('position', selectorPos);
            contentGroup.attr('position', contentPos);

            var mainRect = {x: 0, y: 0};
            mainRect[wh] = contentRect[wh] + selectorButtonGap + selectorRect[wh];
            mainRect[hw] = Math.max(contentRect[hw], selectorRect[hw]);
            mainRect[yx] = Math.min(0, selectorRect[yx] + selectorPos[1 - orientIdx]);
            return mainRect;
        }
        else {
            contentGroup.attr('position', contentPos);
            return this.group.getBoundingRect();
        }
    },

    /**
     * @protected
     */
    remove: function () {
        this.getContentGroup().removeAll();
        this._isFirstRender = true;
    }

});

function setSymbolStyle(symbol, symbolType, legendModelItemStyle, borderColor, inactiveBorderColor, isSelected) {
    var itemStyle;
    if (symbolType !== 'line' && symbolType.indexOf('empty') < 0) {
        itemStyle = legendModelItemStyle.getItemStyle();
        symbol.style.stroke = borderColor;
        if (!isSelected) {
            itemStyle.stroke = inactiveBorderColor;
        }
    }
    else {
        itemStyle = legendModelItemStyle.getItemStyle(['borderWidth', 'borderColor']);
    }
    return symbol.setStyle(itemStyle);
}

function dispatchSelectAction(seriesName, dataName, api, excludeSeriesId) {
    // downplay before unselect
    dispatchDownplayAction(seriesName, dataName, api, excludeSeriesId);
    api.dispatchAction({
        type: 'legendToggleSelect',
        name: seriesName != null ? seriesName : dataName
    });
    // highlight after select
    dispatchHighlightAction(seriesName, dataName, api, excludeSeriesId);
}

function dispatchHighlightAction(seriesName, dataName, api, excludeSeriesId) {
    // If element hover will move to a hoverLayer.
    var el = api.getZr().storage.getDisplayList()[0];
    if (!(el && el.useHoverLayer)) {
        api.dispatchAction({
            type: 'highlight',
            seriesName: seriesName,
            name: dataName,
            excludeSeriesId: excludeSeriesId
        });
    }
}

function dispatchDownplayAction(seriesName, dataName, api, excludeSeriesId) {
    // If element hover will move to a hoverLayer.
    var el = api.getZr().storage.getDisplayList()[0];
    if (!(el && el.useHoverLayer)) {
        api.dispatchAction({
            type: 'downplay',
            seriesName: seriesName,
            name: dataName,
            excludeSeriesId: excludeSeriesId
        });
    }
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var legendFilter = function (ecModel) {

    var legendModels = ecModel.findComponents({
        mainType: 'legend'
    });
    if (legendModels && legendModels.length) {
        ecModel.filterSeries(function (series) {
            // If in any legend component the status is not selected.
            // Because in legend series is assumed selected when it is not in the legend data.
            for (var i = 0; i < legendModels.length; i++) {
                if (!legendModels[i].isSelected(series.name)) {
                    return false;
                }
            }
            return true;
        });
    }

};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/


// Do not contain scrollable legend, for sake of file size.

// Series Filter
registerProcessor(PRIORITY.PROCESSOR.SERIES_FILTER, legendFilter);

ComponentModel.registerSubTypeDefaulter('legend', function () {
    // Default 'plain' when no type specified.
    return 'plain';
});

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var ScrollableLegendModel = LegendModel.extend({

    type: 'legend.scroll',

    /**
     * @param {number} scrollDataIndex
     */
    setScrollDataIndex: function (scrollDataIndex) {
        this.option.scrollDataIndex = scrollDataIndex;
    },

    defaultOption: {
        scrollDataIndex: 0,
        pageButtonItemGap: 5,
        pageButtonGap: null,
        pageButtonPosition: 'end', // 'start' or 'end'
        pageFormatter: '{current}/{total}', // If null/undefined, do not show page.
        pageIcons: {
            horizontal: ['M0,0L12,-10L12,10z', 'M0,0L-12,-10L-12,10z'],
            vertical: ['M0,0L20,0L10,-20z', 'M0,0L20,0L10,20z']
        },
        pageIconColor: '#2f4554',
        pageIconInactiveColor: '#aaa',
        pageIconSize: 15, // Can be [10, 3], which represents [width, height]
        pageTextStyle: {
            color: '#333'
        },

        animationDurationUpdate: 800
    },

    /**
     * @override
     */
    init: function (option, parentModel, ecModel, extraOpt) {
        var inputPositionParams = getLayoutParams(option);

        ScrollableLegendModel.superCall(this, 'init', option, parentModel, ecModel, extraOpt);

        mergeAndNormalizeLayoutParams(this, option, inputPositionParams);
    },

    /**
     * @override
     */
    mergeOption: function (option, extraOpt) {
        ScrollableLegendModel.superCall(this, 'mergeOption', option, extraOpt);

        mergeAndNormalizeLayoutParams(this, this.option, option);
    }

});

// Do not `ignoreSize` to enable setting {left: 10, right: 10}.
function mergeAndNormalizeLayoutParams(legendModel, target, raw) {
    var orient = legendModel.getOrient();
    var ignoreSize = [1, 1];
    ignoreSize[orient.index] = 0;
    mergeLayoutParam(target, raw, {
        type: 'box', ignoreSize: ignoreSize
    });
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * Separate legend and scrollable legend to reduce package size.
 */

var Group$3 = Group;

var WH = ['width', 'height'];
var XY = ['x', 'y'];

var ScrollableLegendView = LegendView.extend({

    type: 'legend.scroll',

    newlineDisabled: true,

    init: function () {

        ScrollableLegendView.superCall(this, 'init');

        /**
         * @private
         * @type {number} For `scroll`.
         */
        this._currentIndex = 0;

        /**
         * @private
         * @type {module:zrender/container/Group}
         */
        this.group.add(this._containerGroup = new Group$3());
        this._containerGroup.add(this.getContentGroup());

        /**
         * @private
         * @type {module:zrender/container/Group}
         */
        this.group.add(this._controllerGroup = new Group$3());

        /**
         *
         * @private
         */
        this._showController;
    },

    /**
     * @override
     */
    resetInner: function () {
        ScrollableLegendView.superCall(this, 'resetInner');

        this._controllerGroup.removeAll();
        this._containerGroup.removeClipPath();
        this._containerGroup.__rectSize = null;
    },

    /**
     * @override
     */
    renderInner: function (itemAlign, legendModel, ecModel, api, selector, orient, selectorPosition) {
        var me = this;

        // Render content items.
        ScrollableLegendView.superCall(this, 'renderInner', itemAlign,
            legendModel, ecModel, api, selector, orient, selectorPosition);

        var controllerGroup = this._controllerGroup;

        // FIXME: support be 'auto' adapt to size number text length,
        // e.g., '3/12345' should not overlap with the control arrow button.
        var pageIconSize = legendModel.get('pageIconSize', true);
        if (!isArray(pageIconSize)) {
            pageIconSize = [pageIconSize, pageIconSize];
        }

        createPageButton('pagePrev', 0);

        var pageTextStyleModel = legendModel.getModel('pageTextStyle');
        controllerGroup.add(new Text({
            name: 'pageText',
            style: {
                textFill: pageTextStyleModel.getTextColor(),
                font: pageTextStyleModel.getFont(),
                textVerticalAlign: 'middle',
                textAlign: 'center'
            },
            silent: true
        }));

        createPageButton('pageNext', 1);

        function createPageButton(name, iconIdx) {
            var pageDataIndexName = name + 'DataIndex';
            var icon = createIcon(
                legendModel.get('pageIcons', true)[legendModel.getOrient().name][iconIdx],
                {
                    // Buttons will be created in each render, so we do not need
                    // to worry about avoiding using legendModel kept in scope.
                    onclick: bind(
                        me._pageGo, me, pageDataIndexName, legendModel, api
                    )
                },
                {
                    x: -pageIconSize[0] / 2,
                    y: -pageIconSize[1] / 2,
                    width: pageIconSize[0],
                    height: pageIconSize[1]
                }
            );
            icon.name = name;
            controllerGroup.add(icon);
        }
    },

    /**
     * @override
     */
    layoutInner: function (legendModel, itemAlign, maxSize, isFirstRender, selector, selectorPosition) {
        var selectorGroup = this.getSelectorGroup();

        var orientIdx = legendModel.getOrient().index;
        var wh = WH[orientIdx];
        var xy = XY[orientIdx];
        var hw = WH[1 - orientIdx];
        var yx = XY[1 - orientIdx];

        selector && box(
            // Buttons in selectorGroup always layout horizontally
            'horizontal',
            selectorGroup,
            legendModel.get('selectorItemGap', true)
        );

        var selectorButtonGap = legendModel.get('selectorButtonGap', true);
        var selectorRect = selectorGroup.getBoundingRect();
        var selectorPos = [-selectorRect.x, -selectorRect.y];

        var processMaxSize = clone(maxSize);
        selector && (processMaxSize[wh] = maxSize[wh] - selectorRect[wh] - selectorButtonGap);

        var mainRect = this._layoutContentAndController(legendModel, isFirstRender,
            processMaxSize, orientIdx, wh, hw, yx
        );

        if (selector) {
            if (selectorPosition === 'end') {
                selectorPos[orientIdx] += mainRect[wh] + selectorButtonGap;
            }
            else {
                var offset = selectorRect[wh] + selectorButtonGap;
                selectorPos[orientIdx] -= offset;
                mainRect[xy] -= offset;
            }
            mainRect[wh] += selectorRect[wh] + selectorButtonGap;

            selectorPos[1 - orientIdx] += mainRect[yx] + mainRect[hw] / 2 - selectorRect[hw] / 2;
            mainRect[hw] = Math.max(mainRect[hw], selectorRect[hw]);
            mainRect[yx] = Math.min(mainRect[yx], selectorRect[yx] + selectorPos[1 - orientIdx]);

            selectorGroup.attr('position', selectorPos);
        }

        return mainRect;
    },

    _layoutContentAndController: function (legendModel, isFirstRender, maxSize, orientIdx, wh, hw, yx) {
        var contentGroup = this.getContentGroup();
        var containerGroup = this._containerGroup;
        var controllerGroup = this._controllerGroup;

        // Place items in contentGroup.
        box(
            legendModel.get('orient'),
            contentGroup,
            legendModel.get('itemGap'),
            !orientIdx ? null : maxSize.width,
            orientIdx ? null : maxSize.height
        );

        box(
            // Buttons in controller are layout always horizontally.
            'horizontal',
            controllerGroup,
            legendModel.get('pageButtonItemGap', true)
        );

        var contentRect = contentGroup.getBoundingRect();
        var controllerRect = controllerGroup.getBoundingRect();
        var showController = this._showController = contentRect[wh] > maxSize[wh];

        var contentPos = [-contentRect.x, -contentRect.y];
        // Remain contentPos when scroll animation perfroming.
        // If first rendering, `contentGroup.position` is [0, 0], which
        // does not make sense and may cause unexepcted animation if adopted.
        if (!isFirstRender) {
            contentPos[orientIdx] = contentGroup.position[orientIdx];
        }

        // Layout container group based on 0.
        var containerPos = [0, 0];
        var controllerPos = [-controllerRect.x, -controllerRect.y];
        var pageButtonGap = retrieve2(
            legendModel.get('pageButtonGap', true), legendModel.get('itemGap', true)
        );

        // Place containerGroup and controllerGroup and contentGroup.
        if (showController) {
            var pageButtonPosition = legendModel.get('pageButtonPosition', true);
            // controller is on the right / bottom.
            if (pageButtonPosition === 'end') {
                controllerPos[orientIdx] += maxSize[wh] - controllerRect[wh];
            }
            // controller is on the left / top.
            else {
                containerPos[orientIdx] += controllerRect[wh] + pageButtonGap;
            }
        }

        // Always align controller to content as 'middle'.
        controllerPos[1 - orientIdx] += contentRect[hw] / 2 - controllerRect[hw] / 2;

        contentGroup.attr('position', contentPos);
        containerGroup.attr('position', containerPos);
        controllerGroup.attr('position', controllerPos);

        // Calculate `mainRect` and set `clipPath`.
        // mainRect should not be calculated by `this.group.getBoundingRect()`
        // for sake of the overflow.
        var mainRect = {x: 0, y: 0};

        // Consider content may be overflow (should be clipped).
        mainRect[wh] = showController ? maxSize[wh] : contentRect[wh];
        mainRect[hw] = Math.max(contentRect[hw], controllerRect[hw]);

        // `containerRect[yx] + containerPos[1 - orientIdx]` is 0.
        mainRect[yx] = Math.min(0, controllerRect[yx] + controllerPos[1 - orientIdx]);

        containerGroup.__rectSize = maxSize[wh];
        if (showController) {
            var clipShape = {x: 0, y: 0};
            clipShape[wh] = Math.max(maxSize[wh] - controllerRect[wh] - pageButtonGap, 0);
            clipShape[hw] = mainRect[hw];
            containerGroup.setClipPath(new Rect({shape: clipShape}));
            // Consider content may be larger than container, container rect
            // can not be obtained from `containerGroup.getBoundingRect()`.
            containerGroup.__rectSize = clipShape[wh];
        }
        else {
            // Do not remove or ignore controller. Keep them set as placeholders.
            controllerGroup.eachChild(function (child) {
                child.attr({invisible: true, silent: true});
            });
        }

        // Content translate animation.
        var pageInfo = this._getPageInfo(legendModel);
        pageInfo.pageIndex != null && updateProps(
            contentGroup,
            {position: pageInfo.contentPosition},
            // When switch from "show controller" to "not show controller", view should be
            // updated immediately without animation, otherwise causes weird effect.
            showController ? legendModel : false
        );

        this._updatePageInfoView(legendModel, pageInfo);

        return mainRect;
    },

    _pageGo: function (to, legendModel, api) {
        var scrollDataIndex = this._getPageInfo(legendModel)[to];

        scrollDataIndex != null && api.dispatchAction({
            type: 'legendScroll',
            scrollDataIndex: scrollDataIndex,
            legendId: legendModel.id
        });
    },

    _updatePageInfoView: function (legendModel, pageInfo) {
        var controllerGroup = this._controllerGroup;

        each$1(['pagePrev', 'pageNext'], function (name) {
            var canJump = pageInfo[name + 'DataIndex'] != null;
            var icon = controllerGroup.childOfName(name);
            if (icon) {
                icon.setStyle(
                    'fill',
                    canJump
                        ? legendModel.get('pageIconColor', true)
                        : legendModel.get('pageIconInactiveColor', true)
                );
                icon.cursor = canJump ? 'pointer' : 'default';
            }
        });

        var pageText = controllerGroup.childOfName('pageText');
        var pageFormatter = legendModel.get('pageFormatter');
        var pageIndex = pageInfo.pageIndex;
        var current = pageIndex != null ? pageIndex + 1 : 0;
        var total = pageInfo.pageCount;

        pageText && pageFormatter && pageText.setStyle(
            'text',
            isString(pageFormatter)
                ? pageFormatter.replace('{current}', current).replace('{total}', total)
                : pageFormatter({current: current, total: total})
        );
    },

    /**
     * @param {module:echarts/model/Model} legendModel
     * @return {Object} {
     *  contentPosition: Array.<number>, null when data item not found.
     *  pageIndex: number, null when data item not found.
     *  pageCount: number, always be a number, can be 0.
     *  pagePrevDataIndex: number, null when no previous page.
     *  pageNextDataIndex: number, null when no next page.
     * }
     */
    _getPageInfo: function (legendModel) {
        var scrollDataIndex = legendModel.get('scrollDataIndex', true);
        var contentGroup = this.getContentGroup();
        var containerRectSize = this._containerGroup.__rectSize;
        var orientIdx = legendModel.getOrient().index;
        var wh = WH[orientIdx];
        var xy = XY[orientIdx];

        var targetItemIndex = this._findTargetItemIndex(scrollDataIndex);
        var children = contentGroup.children();
        var targetItem = children[targetItemIndex];
        var itemCount = children.length;
        var pCount = !itemCount ? 0 : 1;

        var result = {
            contentPosition: contentGroup.position.slice(),
            pageCount: pCount,
            pageIndex: pCount - 1,
            pagePrevDataIndex: null,
            pageNextDataIndex: null
        };

        if (!targetItem) {
            return result;
        }

        var targetItemInfo = getItemInfo(targetItem);
        result.contentPosition[orientIdx] = -targetItemInfo.s;

        // Strategy:
        // (1) Always align based on the left/top most item.
        // (2) It is user-friendly that the last item shown in the
        // current window is shown at the begining of next window.
        // Otherwise if half of the last item is cut by the window,
        // it will have no chance to display entirely.
        // (3) Consider that item size probably be different, we
        // have calculate pageIndex by size rather than item index,
        // and we can not get page index directly by division.
        // (4) The window is to narrow to contain more than
        // one item, we should make sure that the page can be fliped.

        for (var i = targetItemIndex + 1,
            winStartItemInfo = targetItemInfo,
            winEndItemInfo = targetItemInfo,
            currItemInfo = null;
            i <= itemCount;
            ++i
        ) {
            currItemInfo = getItemInfo(children[i]);
            if (
                // Half of the last item is out of the window.
                (!currItemInfo && winEndItemInfo.e > winStartItemInfo.s + containerRectSize)
                // If the current item does not intersect with the window, the new page
                // can be started at the current item or the last item.
                || (currItemInfo && !intersect(currItemInfo, winStartItemInfo.s))
            ) {
                if (winEndItemInfo.i > winStartItemInfo.i) {
                    winStartItemInfo = winEndItemInfo;
                }
                else { // e.g., when page size is smaller than item size.
                    winStartItemInfo = currItemInfo;
                }
                if (winStartItemInfo) {
                    if (result.pageNextDataIndex == null) {
                        result.pageNextDataIndex = winStartItemInfo.i;
                    }
                    ++result.pageCount;
                }
            }
            winEndItemInfo = currItemInfo;
        }

        for (var i = targetItemIndex - 1,
            winStartItemInfo = targetItemInfo,
            winEndItemInfo = targetItemInfo,
            currItemInfo = null;
            i >= -1;
            --i
        ) {
            currItemInfo = getItemInfo(children[i]);
            if (
                // If the the end item does not intersect with the window started
                // from the current item, a page can be settled.
                (!currItemInfo || !intersect(winEndItemInfo, currItemInfo.s))
                // e.g., when page size is smaller than item size.
                && winStartItemInfo.i < winEndItemInfo.i
            ) {
                winEndItemInfo = winStartItemInfo;
                if (result.pagePrevDataIndex == null) {
                    result.pagePrevDataIndex = winStartItemInfo.i;
                }
                ++result.pageCount;
                ++result.pageIndex;
            }
            winStartItemInfo = currItemInfo;
        }

        return result;

        function getItemInfo(el) {
            if (el) {
                var itemRect = el.getBoundingRect();
                var start = itemRect[xy] + el.position[orientIdx];
                return {
                    s: start,
                    e: start + itemRect[wh],
                    i: el.__legendDataIndex
                };
            }
        }

        function intersect(itemInfo, winStart) {
            return itemInfo.e >= winStart && itemInfo.s <= winStart + containerRectSize;
        }
    },

    _findTargetItemIndex: function (targetDataIndex) {
        if (!this._showController) {
            return 0;
        }

        var index;
        var contentGroup = this.getContentGroup();
        var defaultIndex;

        contentGroup.eachChild(function (child, idx) {
            var legendDataIdx = child.__legendDataIndex;
            // FIXME
            // If the given targetDataIndex (from model) is illegal,
            // we use defaultIndex. But the index on the legend model and
            // action payload is still illegal. That case will not be
            // changed until some scenario requires.
            if (defaultIndex == null && legendDataIdx != null) {
                defaultIndex = idx;
            }
            if (legendDataIdx === targetDataIndex) {
                index = idx;
            }
        });

        return index != null ? index : defaultIndex;
    }

});

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * @event legendScroll
 * @type {Object}
 * @property {string} type 'legendScroll'
 * @property {string} scrollDataIndex
 */
registerAction(
    'legendScroll', 'legendscroll',
    function (payload, ecModel) {
        var scrollDataIndex = payload.scrollDataIndex;

        scrollDataIndex != null && ecModel.eachComponent(
            {mainType: 'legend', subType: 'scroll', query: payload},
            function (legendModel) {
                legendModel.setScrollDataIndex(scrollDataIndex);
            }
        );
    }
);

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * Legend component entry file8
 */

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

// Model
extendComponentModel({

    type: 'title',

    layoutMode: {type: 'box', ignoreSize: true},

    defaultOption: {
        // 一级层叠
        zlevel: 0,
        // 二级层叠
        z: 6,
        show: true,

        text: '',
        // 超链接跳转
        // link: null,
        // 仅支持self | blank
        target: 'blank',
        subtext: '',

        // 超链接跳转
        // sublink: null,
        // 仅支持self | blank
        subtarget: 'blank',

        // 'center' ¦ 'left' ¦ 'right'
        // ¦ {number}（x坐标，单位px）
        left: 0,
        // 'top' ¦ 'bottom' ¦ 'center'
        // ¦ {number}（y坐标，单位px）
        top: 0,

        // 水平对齐
        // 'auto' | 'left' | 'right' | 'center'
        // 默认根据 left 的位置判断是左对齐还是右对齐
        // textAlign: null
        //
        // 垂直对齐
        // 'auto' | 'top' | 'bottom' | 'middle'
        // 默认根据 top 位置判断是上对齐还是下对齐
        // textVerticalAlign: null
        // textBaseline: null // The same as textVerticalAlign.

        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
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 textVerticalAlign = retrieve2(
            titleModel.get('textBaseline'), titleModel.get('textVerticalAlign')
        );

        var textEl = new Text({
            style: setTextStyle({}, textStyleModel, {
                text: titleModel.get('text'),
                textFill: textStyleModel.getTextColor()
            }, {disableBox: true}),
            z2: 10
        });

        var textRect = textEl.getBoundingRect();

        var subText = titleModel.get('subtext');
        var subTextEl = new Text({
            style: setTextStyle({}, subtextStyleModel, {
                text: subText,
                textFill: subtextStyleModel.getTextColor(),
                y: textRect.height + titleModel.get('itemGap'),
                textVerticalAlign: 'top'
            }, {disableBox: true}),
            z2: 10
        });

        var link = titleModel.get('link');
        var sublink = titleModel.get('sublink');
        var triggerEvent = titleModel.get('triggerEvent', true);

        textEl.silent = !link && !triggerEvent;
        subTextEl.silent = !sublink && !triggerEvent;

        if (link) {
            textEl.on('click', function () {
                windowOpen(link, '_' + titleModel.get('target'));
            });
        }
        if (sublink) {
            subTextEl.on('click', function () {
                windowOpen(sublink, '_' + titleModel.get('subtarget'));
            });
        }

        textEl.eventData = subTextEl.eventData = triggerEvent
            ? {
                componentType: 'title',
                componentIndex: titleModel.componentIndex
            }
            : null;

        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 = getLayoutRect(
            layoutOption, {
                width: api.getWidth(),
                height: api.getHeight()
            }, titleModel.get('padding')
        );
        // Adjust text align based on position
        if (!textAlign) {
            // Align left if title is on the left. center and right is same
            textAlign = titleModel.get('left') || titleModel.get('right');
            if (textAlign === 'middle') {
                textAlign = 'center';
            }
            // Adjust layout by text align
            if (textAlign === 'right') {
                layoutRect.x += layoutRect.width;
            }
            else if (textAlign === 'center') {
                layoutRect.x += layoutRect.width / 2;
            }
        }
        if (!textVerticalAlign) {
            textVerticalAlign = titleModel.get('top') || titleModel.get('bottom');
            if (textVerticalAlign === 'center') {
                textVerticalAlign = 'middle';
            }
            if (textVerticalAlign === 'bottom') {
                layoutRect.y += layoutRect.height;
            }
            else if (textVerticalAlign === 'middle') {
                layoutRect.y += layoutRect.height / 2;
            }

            textVerticalAlign = textVerticalAlign || 'top';
        }

        group.attr('position', [layoutRect.x, layoutRect.y]);
        var alignStyle = {
            textAlign: textAlign,
            textVerticalAlign: textVerticalAlign
        };
        textEl.setStyle(alignStyle);
        subTextEl.setStyle(alignStyle);

        // Render background
        // Get groupRect again because textAlign has been changed
        groupRect = group.getBoundingRect();
        var padding = layoutRect.margin;
        var style = titleModel.getItemStyle(['color', 'opacity']);
        style.fill = titleModel.get('backgroundColor');
        var rect = new 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],
                r: titleModel.get('borderRadius')
            },
            style: style,
            subPixelOptimize: true,
            silent: true
        });

        group.add(rect);
    }
});

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var addCommas$1 = addCommas;
var encodeHTML$1 = encodeHTML;

function fillLabel(opt) {
    defaultEmphasis(opt, 'label', ['show']);
}
var MarkerModel = extendComponentModel({

    type: 'marker',

    dependencies: ['series', 'grid', 'polar', 'geo'],

    /**
     * @overrite
     */
    init: function (option, parentModel, ecModel) {

        if (__DEV__) {
            if (this.type === 'marker') {
                throw new Error('Marker component is abstract component. Use markLine, markPoint, markArea instead.');
            }
        }
        this.mergeDefaultAndTheme(option, ecModel);
        this._mergeOption(option, ecModel, false, true);
    },

    /**
     * @return {boolean}
     */
    isAnimationEnabled: function () {
        if (env$1.node) {
            return false;
        }

        var hostSeries = this.__hostSeries;
        return this.getShallow('animation') && hostSeries && hostSeries.isAnimationEnabled();
    },

    /**
     * @overrite
     */
    mergeOption: function (newOpt, ecModel) {
        this._mergeOption(newOpt, ecModel, false, false);
    },

    _mergeOption: function (newOpt, ecModel, createdBySelf, isInit) {
        var MarkerModel = this.constructor;
        var modelPropName = this.mainType + 'Model';
        if (!createdBySelf) {
            ecModel.eachSeries(function (seriesModel) {

                var markerOpt = seriesModel.get(this.mainType, true);

                var markerModel = seriesModel[modelPropName];
                if (!markerOpt || !markerOpt.data) {
                    seriesModel[modelPropName] = null;
                    return;
                }
                if (!markerModel) {
                    if (isInit) {
                        // Default label emphasis `position` and `show`
                        fillLabel(markerOpt);
                    }
                    each$1(markerOpt.data, function (item) {
                        // FIXME Overwrite fillLabel method ?
                        if (item instanceof Array) {
                            fillLabel(item[0]);
                            fillLabel(item[1]);
                        }
                        else {
                            fillLabel(item);
                        }
                    });

                    markerModel = new MarkerModel(
                        markerOpt, this, ecModel
                    );

                    extend(markerModel, {
                        mainType: this.mainType,
                        // Use the same series index and name
                        seriesIndex: seriesModel.seriesIndex,
                        name: seriesModel.name,
                        createdBySelf: true
                    });

                    markerModel.__hostSeries = seriesModel;
                }
                else {
                    markerModel._mergeOption(markerOpt, ecModel, true);
                }
                seriesModel[modelPropName] = markerModel;
            }, this);
        }
    },

    formatTooltip: function (dataIndex, multipleSeries, dataType, renderMode) {
        var data = this.getData();
        var value = this.getRawValue(dataIndex);
        var formattedValue = isArray(value)
            ? map(value, addCommas$1).join(', ') : addCommas$1(value);
        var name = data.getName(dataIndex);
        var html = encodeHTML$1(this.name);
        var newLine = renderMode === 'html' ? '<br/>' : '\n';
        if (value != null || name) {
            html += newLine;
        }
        if (name) {
            html += encodeHTML$1(name);
            if (value != null) {
                html += ' : ';
            }
        }
        if (value != null) {
            html += encodeHTML$1(formattedValue);
        }
        return html;
    },

    getData: function () {
        return this._data;
    },

    setData: function (data) {
        this._data = data;
    }
});

mixin(MarkerModel, dataFormatMixin);

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

MarkerModel.extend({

    type: 'markPoint',

    defaultOption: {
        zlevel: 0,
        z: 5,
        symbol: 'pin',
        symbolSize: 50,
        //symbolRotate: 0,
        //symbolOffset: [0, 0]
        tooltip: {
            trigger: 'item'
        },
        label: {
            show: true,
            position: 'inside'
        },
        itemStyle: {
            borderWidth: 2
        },
        emphasis: {
            label: {
                show: true
            }
        }
    }
});

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var indexOf$1 = indexOf;

function hasXOrY(item) {
    return !(isNaN(parseFloat(item.x)) && isNaN(parseFloat(item.y)));
}

function hasXAndY(item) {
    return !isNaN(parseFloat(item.x)) && !isNaN(parseFloat(item.y));
}

// Make it simple, do not visit all stacked value to count precision.
// function getPrecision(data, valueAxisDim, dataIndex) {
//     var precision = -1;
//     var stackedDim = data.mapDimension(valueAxisDim);
//     do {
//         precision = Math.max(
//             numberUtil.getPrecision(data.get(stackedDim, dataIndex)),
//             precision
//         );
//         var stackedOnSeries = data.getCalculationInfo('stackedOnSeries');
//         if (stackedOnSeries) {
//             var byValue = data.get(data.getCalculationInfo('stackedByDimension'), dataIndex);
//             data = stackedOnSeries.getData();
//             dataIndex = data.indexOf(data.getCalculationInfo('stackedByDimension'), byValue);
//             stackedDim = data.getCalculationInfo('stackedDimension');
//         }
//         else {
//             data = null;
//         }
//     } while (data);

//     return precision;
// }

function markerTypeCalculatorWithExtent(
    mlType, data, otherDataDim, targetDataDim, otherCoordIndex, targetCoordIndex
) {
    var coordArr = [];

    var stacked = isDimensionStacked(data, targetDataDim /*, otherDataDim*/);
    var calcDataDim = stacked
        ? data.getCalculationInfo('stackResultDimension')
        : targetDataDim;

    var value = numCalculate(data, calcDataDim, mlType);

    var dataIndex = data.indicesOfNearest(calcDataDim, value)[0];
    coordArr[otherCoordIndex] = data.get(otherDataDim, dataIndex);
    coordArr[targetCoordIndex] = data.get(calcDataDim, dataIndex);
    var coordArrValue = data.get(targetDataDim, dataIndex);
    // Make it simple, do not visit all stacked value to count precision.
    var precision = getPrecision(data.get(targetDataDim, dataIndex));
    precision = Math.min(precision, 20);
    if (precision >= 0) {
        coordArr[targetCoordIndex] = +coordArr[targetCoordIndex].toFixed(precision);
    }

    return [coordArr, coordArrValue];
}

var curry$4 = curry;
// TODO Specified percent
var markerTypeCalculator = {
    /**
     * @method
     * @param {module:echarts/data/List} data
     * @param {string} baseAxisDim
     * @param {string} valueAxisDim
     */
    min: curry$4(markerTypeCalculatorWithExtent, 'min'),
    /**
     * @method
     * @param {module:echarts/data/List} data
     * @param {string} baseAxisDim
     * @param {string} valueAxisDim
     */
    max: curry$4(markerTypeCalculatorWithExtent, 'max'),

    /**
     * @method
     * @param {module:echarts/data/List} data
     * @param {string} baseAxisDim
     * @param {string} valueAxisDim
     */
    average: curry$4(markerTypeCalculatorWithExtent, 'average')
};

/**
 * Transform markPoint data item to format used in List by do the following
 * 1. Calculate statistic like `max`, `min`, `average`
 * 2. Convert `item.xAxis`, `item.yAxis` to `item.coord` array
 * @param  {module:echarts/model/Series} seriesModel
 * @param  {module:echarts/coord/*} [coordSys]
 * @param  {Object} item
 * @return {Object}
 */
function dataTransform(seriesModel, item) {
    var data = seriesModel.getData();
    var coordSys = seriesModel.coordinateSystem;

    // 1. If not specify the position with pixel directly
    // 2. If `coord` is not a data array. Which uses `xAxis`,
    // `yAxis` to specify the coord on each dimension

    // parseFloat first because item.x and item.y can be percent string like '20%'
    if (item && !hasXAndY(item) && !isArray(item.coord) && coordSys) {
        var dims = coordSys.dimensions;
        var axisInfo = getAxisInfo$1(item, data, coordSys, seriesModel);

        // Clone the option
        // Transform the properties xAxis, yAxis, radiusAxis, angleAxis, geoCoord to value
        item = clone(item);

        if (item.type
            && markerTypeCalculator[item.type]
            && axisInfo.baseAxis && axisInfo.valueAxis
        ) {
            var otherCoordIndex = indexOf$1(dims, axisInfo.baseAxis.dim);
            var targetCoordIndex = indexOf$1(dims, axisInfo.valueAxis.dim);

            var coordInfo = markerTypeCalculator[item.type](
                data, axisInfo.baseDataDim, axisInfo.valueDataDim,
                otherCoordIndex, targetCoordIndex
            );
            item.coord = coordInfo[0];
            // Force to use the value of calculated value.
            // let item use the value without stack.
            item.value = coordInfo[1];

        }
        else {
            // FIXME Only has one of xAxis and yAxis.
            var coord = [
                item.xAxis != null ? item.xAxis : item.radiusAxis,
                item.yAxis != null ? item.yAxis : item.angleAxis
            ];
            // Each coord support max, min, average
            for (var i = 0; i < 2; i++) {
                if (markerTypeCalculator[coord[i]]) {
                    coord[i] = numCalculate(data, data.mapDimension(dims[i]), coord[i]);
                }
            }
            item.coord = coord;
        }
    }
    return item;
}

function getAxisInfo$1(item, data, coordSys, seriesModel) {
    var ret = {};

    if (item.valueIndex != null || item.valueDim != null) {
        ret.valueDataDim = item.valueIndex != null
            ? data.getDimension(item.valueIndex) : item.valueDim;
        ret.valueAxis = coordSys.getAxis(dataDimToCoordDim(seriesModel, ret.valueDataDim));
        ret.baseAxis = coordSys.getOtherAxis(ret.valueAxis);
        ret.baseDataDim = data.mapDimension(ret.baseAxis.dim);
    }
    else {
        ret.baseAxis = seriesModel.getBaseAxis();
        ret.valueAxis = coordSys.getOtherAxis(ret.baseAxis);
        ret.baseDataDim = data.mapDimension(ret.baseAxis.dim);
        ret.valueDataDim = data.mapDimension(ret.valueAxis.dim);
    }

    return ret;
}

function dataDimToCoordDim(seriesModel, dataDim) {
    var data = seriesModel.getData();
    var dimensions = data.dimensions;
    dataDim = data.getDimension(dataDim);
    for (var i = 0; i < dimensions.length; i++) {
        var dimItem = data.getDimensionInfo(dimensions[i]);
        if (dimItem.name === dataDim) {
            return dimItem.coordDim;
        }
    }
}

/**
 * Filter data which is out of coordinateSystem range
 * [dataFilter description]
 * @param  {module:echarts/coord/*} [coordSys]
 * @param  {Object} item
 * @return {boolean}
 */
function dataFilter$1(coordSys, item) {
    // Alwalys return true if there is no coordSys
    return (coordSys && coordSys.containData && item.coord && !hasXOrY(item))
        ? coordSys.containData(item.coord) : true;
}

function dimValueGetter(item, dimName, dataIndex, dimIndex) {
    // x, y, radius, angle
    if (dimIndex < 2) {
        return item.coord && item.coord[dimIndex];
    }
    return item.value;
}

function numCalculate(data, valueDataDim, type) {
    if (type === 'average') {
        var sum = 0;
        var count = 0;
        data.each(valueDataDim, function (val, idx) {
            if (!isNaN(val)) {
                sum += val;
                count++;
            }
        });
        return sum / count;
    }
    else if (type === 'median') {
        return data.getMedian(valueDataDim);
    }
    else {
        // max & min
        return data.getDataExtent(valueDataDim, true)[type === 'max' ? 1 : 0];
    }
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var MarkerView = extendComponentView({

    type: 'marker',

    init: function () {
        /**
         * Markline grouped by series
         * @private
         * @type {module:zrender/core/util.HashMap}
         */
        this.markerGroupMap = createHashMap();
    },

    render: function (markerModel, ecModel, api) {
        var markerGroupMap = this.markerGroupMap;
        markerGroupMap.each(function (item) {
            item.__keep = false;
        });

        var markerModelKey = this.type + 'Model';
        ecModel.eachSeries(function (seriesModel) {
            var markerModel = seriesModel[markerModelKey];
            markerModel && this.renderSeries(seriesModel, markerModel, ecModel, api);
        }, this);

        markerGroupMap.each(function (item) {
            !item.__keep && this.group.remove(item.group);
        }, this);
    },

    renderSeries: function () {}
});

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

function updateMarkerLayout(mpData, seriesModel, api) {
    var coordSys = seriesModel.coordinateSystem;
    mpData.each(function (idx) {
        var itemModel = mpData.getItemModel(idx);
        var point;
        var xPx = parsePercent$1(itemModel.get('x'), api.getWidth());
        var yPx = parsePercent$1(itemModel.get('y'), api.getHeight());
        if (!isNaN(xPx) && !isNaN(yPx)) {
            point = [xPx, yPx];
        }
        // Chart like bar may have there own marker positioning logic
        else if (seriesModel.getMarkerPosition) {
            // Use the getMarkerPoisition
            point = seriesModel.getMarkerPosition(
                mpData.getValues(mpData.dimensions, idx)
            );
        }
        else if (coordSys) {
            var x = mpData.get(coordSys.dimensions[0], idx);
            var y = mpData.get(coordSys.dimensions[1], idx);
            point = coordSys.dataToPoint([x, y]);

        }

        // Use x, y if has any
        if (!isNaN(xPx)) {
            point[0] = xPx;
        }
        if (!isNaN(yPx)) {
            point[1] = yPx;
        }

        mpData.setItemLayout(idx, point);
    });
}

MarkerView.extend({

    type: 'markPoint',

    // updateLayout: function (markPointModel, ecModel, api) {
    //     ecModel.eachSeries(function (seriesModel) {
    //         var mpModel = seriesModel.markPointModel;
    //         if (mpModel) {
    //             updateMarkerLayout(mpModel.getData(), seriesModel, api);
    //             this.markerGroupMap.get(seriesModel.id).updateLayout(mpModel);
    //         }
    //     }, this);
    // },

    updateTransform: function (markPointModel, ecModel, api) {
        ecModel.eachSeries(function (seriesModel) {
            var mpModel = seriesModel.markPointModel;
            if (mpModel) {
                updateMarkerLayout(mpModel.getData(), seriesModel, api);
                this.markerGroupMap.get(seriesModel.id).updateLayout(mpModel);
            }
        }, this);
    },

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

        var symbolDrawMap = this.markerGroupMap;
        var symbolDraw = symbolDrawMap.get(seriesId)
            || symbolDrawMap.set(seriesId, new SymbolDraw());

        var mpData = createList$1(coordSys, seriesModel, mpModel);

        // FIXME
        mpModel.setData(mpData);

        updateMarkerLayout(mpModel.getData(), seriesModel, api);

        mpData.each(function (idx) {
            var itemModel = mpData.getItemModel(idx);
            var symbol = itemModel.getShallow('symbol');
            var symbolSize = itemModel.getShallow('symbolSize');
            var symbolRotate = itemModel.getShallow('symbolRotate');
            var isFnSymbol = isFunction$1(symbol);
            var isFnSymbolSize = isFunction$1(symbolSize);
            var isFnSymbolRotate = isFunction$1(symbolRotate);

            if (isFnSymbol || isFnSymbolSize || isFnSymbolRotate) {
                var rawIdx = mpModel.getRawValue(idx);
                var dataParams = mpModel.getDataParams(idx);
                if (isFnSymbol) {
                    symbol = symbol(rawIdx, dataParams);
                }
                if (isFnSymbolSize) {
                    // FIXME 这里不兼容 ECharts 2.x，2.x 貌似参数是整个数据？
                    symbolSize = symbolSize(rawIdx, dataParams);
                }
                if (isFnSymbolRotate) {
                    symbolRotate = symbolRotate(rawIdx, dataParams);
                }
            }

            mpData.setItemVisual(idx, {
                symbol: symbol,
                symbolSize: symbolSize,
                symbolRotate: symbolRotate,
                color: itemModel.get('itemStyle.color')
                    || seriesData.getVisual('color')
            });
        });

        // TODO Text are wrong
        symbolDraw.updateData(mpData);
        this.group.add(symbolDraw.group);

        // Set host model for tooltip
        // FIXME
        mpData.eachItemGraphicEl(function (el) {
            el.traverse(function (child) {
                child.dataModel = mpModel;
            });
        });

        symbolDraw.__keep = true;

        symbolDraw.group.silent = mpModel.get('silent') || seriesModel.get('silent');
    }
});

/**
 * @inner
 * @param {module:echarts/coord/*} [coordSys]
 * @param {module:echarts/model/Series} seriesModel
 * @param {module:echarts/model/Model} mpModel
 */
function createList$1(coordSys, seriesModel, mpModel) {
    var coordDimsInfos;
    if (coordSys) {
        coordDimsInfos = map(coordSys && coordSys.dimensions, function (coordDim) {
            var info = seriesModel.getData().getDimensionInfo(
                seriesModel.getData().mapDimension(coordDim)
            ) || {};
            // In map series data don't have lng and lat dimension. Fallback to same with coordSys
            return defaults({name: coordDim}, info);
        });
    }
    else {
        coordDimsInfos = [{
            name: 'value',
            type: 'float'
        }];
    }

    var mpData = new List(coordDimsInfos, mpModel);
    var dataOpt = map(mpModel.get('data'), curry(
            dataTransform, seriesModel
        ));
    if (coordSys) {
        dataOpt = filter(
            dataOpt, curry(dataFilter$1, coordSys)
        );
    }

    mpData.initData(dataOpt, null,
        coordSys ? dimValueGetter : function (item) {
            return item.value;
        }
    );

    return mpData;
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

// HINT Markpoint can't be used too much
registerPreprocessor(function (opt) {
    // Make sure markPoint component is enabled
    opt.markPoint = opt.markPoint || {};
});

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

MarkerModel.extend({

    type: 'markLine',

    defaultOption: {
        zlevel: 0,
        z: 5,

        symbol: ['circle', 'arrow'],
        symbolSize: [8, 16],

        //symbolRotate: 0,

        precision: 2,
        tooltip: {
            trigger: 'item'
        },
        label: {
            show: true,
            position: 'end',
            distance: 5
        },
        lineStyle: {
            type: 'dashed'
        },
        emphasis: {
            label: {
                show: true
            },
            lineStyle: {
                width: 3
            }
        },
        animationEasing: 'linear'
    }
});

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * Line path for bezier and straight line draw
 */

var straightLineProto = Line.prototype;
var bezierCurveProto = BezierCurve.prototype;

function isLine(shape) {
    return isNaN(+shape.cpx1) || isNaN(+shape.cpy1);
}

var LinePath = 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) {
        this[isLine(shape) ? '_buildPathLine' : '_buildPathCurve'](ctx, shape);
    },
    _buildPathLine: straightLineProto.buildPath,
    _buildPathCurve: bezierCurveProto.buildPath,

    pointAt: function (t) {
        return this[isLine(this.shape) ? '_pointAtLine' : '_pointAtCurve'](t);
    },
    _pointAtLine: straightLineProto.pointAt,
    _pointAtCurve: bezierCurveProto.pointAt,

    tangentAt: function (t) {
        var shape = this.shape;
        var p = isLine(shape)
            ? [shape.x2 - shape.x1, shape.y2 - shape.y1]
            : this._tangentAtCurve(t);
        return normalize(p, p);
    },
    _tangentAtCurve: bezierCurveProto.tangentAt

});

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * @module echarts/chart/helper/Line
 */

var SYMBOL_CATEGORIES = ['fromSymbol', 'toSymbol'];

function makeSymbolTypeKey(symbolCategory) {
    return '_' + symbolCategory + 'Type';
}
/**
 * @inner
 */
function createSymbol$1(name, lineData, idx) {
    var symbolType = lineData.getItemVisual(idx, name);

    if (!symbolType || symbolType === 'none') {
        return;
    }

    var color = lineData.getItemVisual(idx, 'color');
    var symbolSize = lineData.getItemVisual(idx, name + 'Size');
    var symbolRotate = lineData.getItemVisual(idx, name + 'Rotate');

    if (!isArray(symbolSize)) {
        symbolSize = [symbolSize, symbolSize];
    }

    var symbolPath = createSymbol(
        symbolType, -symbolSize[0] / 2, -symbolSize[1] / 2,
        symbolSize[0], symbolSize[1], color
    );

    // rotate by default if symbolRotate is not specified or NaN
    symbolPath.__specifiedRotation = symbolRotate == null || isNaN(symbolRotate)
        ? void 0
        : +symbolRotate * Math.PI / 180 || 0;
    symbolPath.name = name;

    return symbolPath;
}

function createLine(points) {
    var line = new LinePath({
        name: 'line',
        subPixelOptimize: true
    });
    setLinePoints(line.shape, points);
    return line;
}

function setLinePoints(targetShape, points) {
    targetShape.x1 = points[0][0];
    targetShape.y1 = points[0][1];
    targetShape.x2 = points[1][0];
    targetShape.y2 = points[1][1];
    targetShape.percent = 1;

    var cp1 = points[2];
    if (cp1) {
        targetShape.cpx1 = cp1[0];
        targetShape.cpy1 = cp1[1];
    }
    else {
        targetShape.cpx1 = NaN;
        targetShape.cpy1 = NaN;
    }
}

function updateSymbolAndLabelBeforeLineUpdate() {
    var lineGroup = this;
    var symbolFrom = lineGroup.childOfName('fromSymbol');
    var symbolTo = lineGroup.childOfName('toSymbol');
    var label = lineGroup.childOfName('label');
    // Quick reject
    if (!symbolFrom && !symbolTo && label.ignore) {
        return;
    }

    var invScale = 1;
    var parentNode = this.parent;
    while (parentNode) {
        if (parentNode.scale) {
            invScale /= parentNode.scale[0];
        }
        parentNode = parentNode.parent;
    }

    var line = lineGroup.childOfName('line');
    // If line not changed
    // FIXME Parent scale changed
    if (!this.__dirty && !line.__dirty) {
        return;
    }

    var percent = line.shape.percent;
    var fromPos = line.pointAt(0);
    var toPos = line.pointAt(percent);

    var d = sub([], toPos, fromPos);
    normalize(d, d);

    if (symbolFrom) {
        symbolFrom.attr('position', fromPos);
        // Fix #12388
        // when symbol is set to be 'arrow' in markLine,
        // symbolRotate value will be ignored, and compulsively use tangent angle.
        // rotate by default if symbol rotation is not specified
        var specifiedRotation = symbolFrom.__specifiedRotation;
        if (specifiedRotation == null) {
            var tangent = line.tangentAt(0);
            symbolFrom.attr('rotation', Math.PI / 2 - Math.atan2(
                tangent[1], tangent[0]
            ));
        }
        else {
            symbolFrom.attr('rotation', specifiedRotation);
        }
        symbolFrom.attr('scale', [invScale * percent, invScale * percent]);
    }
    if (symbolTo) {
        symbolTo.attr('position', toPos);
        // Fix #12388
        // when symbol is set to be 'arrow' in markLine,
        // symbolRotate value will be ignored, and compulsively use tangent angle.
        // rotate by default if symbol rotation is not specified
        var specifiedRotation = symbolTo.__specifiedRotation;
        if (specifiedRotation == null) {
            var tangent = line.tangentAt(1);
            symbolTo.attr('rotation', -Math.PI / 2 - Math.atan2(
                tangent[1], tangent[0]
            ));
        }
        else {
            symbolTo.attr('rotation', specifiedRotation);
        }
        symbolTo.attr('scale', [invScale * percent, invScale * percent]);
    }

    if (!label.ignore) {
        label.attr('position', toPos);

        var textPosition;
        var textAlign;
        var textVerticalAlign;
        var textOrigin;

        var distance$$1 = label.__labelDistance;
        var distanceX = distance$$1[0] * invScale;
        var distanceY = distance$$1[1] * invScale;
        var halfPercent = percent / 2;
        var tangent = line.tangentAt(halfPercent);
        var n = [tangent[1], -tangent[0]];
        var cp = line.pointAt(halfPercent);
        if (n[1] > 0) {
            n[0] = -n[0];
            n[1] = -n[1];
        }
        var dir = tangent[0] < 0 ? -1 : 1;

        if (label.__position !== 'start' && label.__position !== 'end') {
            var rotation = -Math.atan2(tangent[1], tangent[0]);
            if (toPos[0] < fromPos[0]) {
                rotation = Math.PI + rotation;
            }
            label.attr('rotation', rotation);
        }

        var dy;
        switch (label.__position) {
            case 'insideStartTop':
            case 'insideMiddleTop':
            case 'insideEndTop':
            case 'middle':
                dy = -distanceY;
                textVerticalAlign = 'bottom';
                break;

            case 'insideStartBottom':
            case 'insideMiddleBottom':
            case 'insideEndBottom':
                dy = distanceY;
                textVerticalAlign = 'top';
                break;

            default:
                dy = 0;
                textVerticalAlign = 'middle';
        }

        switch (label.__position) {
            case 'end':
                textPosition = [d[0] * distanceX + toPos[0], d[1] * distanceY + toPos[1]];
                textAlign = d[0] > 0.8 ? 'left' : (d[0] < -0.8 ? 'right' : 'center');
                textVerticalAlign = d[1] > 0.8 ? 'top' : (d[1] < -0.8 ? 'bottom' : 'middle');
                break;

            case 'start':
                textPosition = [-d[0] * distanceX + fromPos[0], -d[1] * distanceY + fromPos[1]];
                textAlign = d[0] > 0.8 ? 'right' : (d[0] < -0.8 ? 'left' : 'center');
                textVerticalAlign = d[1] > 0.8 ? 'bottom' : (d[1] < -0.8 ? 'top' : 'middle');
                break;

            case 'insideStartTop':
            case 'insideStart':
            case 'insideStartBottom':
                textPosition = [distanceX * dir + fromPos[0], fromPos[1] + dy];
                textAlign = tangent[0] < 0 ? 'right' : 'left';
                textOrigin = [-distanceX * dir, -dy];
                break;

            case 'insideMiddleTop':
            case 'insideMiddle':
            case 'insideMiddleBottom':
            case 'middle':
                textPosition = [cp[0], cp[1] + dy];
                textAlign = 'center';
                textOrigin = [0, -dy];
                break;

            case 'insideEndTop':
            case 'insideEnd':
            case 'insideEndBottom':
                textPosition = [-distanceX * dir + toPos[0], toPos[1] + dy];
                textAlign = tangent[0] >= 0 ? 'right' : 'left';
                textOrigin = [distanceX * dir, -dy];
                break;
        }

        label.attr({
            style: {
                // Use the user specified text align and baseline first
                textVerticalAlign: label.__verticalAlign || textVerticalAlign,
                textAlign: label.__textAlign || textAlign
            },
            position: textPosition,
            scale: [invScale, invScale],
            origin: textOrigin
        });
    }
}

/**
 * @constructor
 * @extends {module:zrender/graphic/Group}
 * @alias {module:echarts/chart/helper/Line}
 */
function Line$1(lineData, idx, seriesScope) {
    Group.call(this);

    this._createLine(lineData, idx, seriesScope);
}

var lineProto = Line$1.prototype;

// Update symbol position and rotation
lineProto.beforeUpdate = updateSymbolAndLabelBeforeLineUpdate;

lineProto._createLine = function (lineData, idx, seriesScope) {
    var seriesModel = lineData.hostModel;
    var linePoints = lineData.getItemLayout(idx);
    var line = createLine(linePoints);
    line.shape.percent = 0;
    initProps(line, {
        shape: {
            percent: 1
        }
    }, seriesModel, idx);

    this.add(line);

    var label = new Text({
        name: 'label',
        // FIXME
        // Temporary solution for `focusNodeAdjacency`.
        // line label do not use the opacity of lineStyle.
        lineLabelOriginalOpacity: 1
    });
    this.add(label);

    each$1(SYMBOL_CATEGORIES, function (symbolCategory) {
        var symbol = createSymbol$1(symbolCategory, lineData, idx);
        // symbols must added after line to make sure
        // it will be updated after line#update.
        // Or symbol position and rotation update in line#beforeUpdate will be one frame slow
        this.add(symbol);
        this[makeSymbolTypeKey(symbolCategory)] = lineData.getItemVisual(idx, symbolCategory);
    }, this);

    this._updateCommonStl(lineData, idx, seriesScope);
};

lineProto.updateData = function (lineData, idx, seriesScope) {
    var seriesModel = lineData.hostModel;

    var line = this.childOfName('line');
    var linePoints = lineData.getItemLayout(idx);
    var target = {
        shape: {}
    };

    setLinePoints(target.shape, linePoints);
    updateProps(line, target, seriesModel, idx);

    each$1(SYMBOL_CATEGORIES, function (symbolCategory) {
        var symbolType = lineData.getItemVisual(idx, symbolCategory);
        var key = makeSymbolTypeKey(symbolCategory);
        // Symbol changed
        if (this[key] !== symbolType) {
            this.remove(this.childOfName(symbolCategory));
            var symbol = createSymbol$1(symbolCategory, lineData, idx);
            this.add(symbol);
        }
        this[key] = symbolType;
    }, this);

    this._updateCommonStl(lineData, idx, seriesScope);
};

lineProto._updateCommonStl = function (lineData, idx, seriesScope) {
    var seriesModel = lineData.hostModel;

    var line = this.childOfName('line');

    var lineStyle = seriesScope && seriesScope.lineStyle;
    var hoverLineStyle = seriesScope && seriesScope.hoverLineStyle;
    var labelModel = seriesScope && seriesScope.labelModel;
    var hoverLabelModel = seriesScope && seriesScope.hoverLabelModel;

    // Optimization for large dataset
    if (!seriesScope || lineData.hasItemOption) {
        var itemModel = lineData.getItemModel(idx);

        lineStyle = itemModel.getModel('lineStyle').getLineStyle();
        hoverLineStyle = itemModel.getModel('emphasis.lineStyle').getLineStyle();

        labelModel = itemModel.getModel('label');
        hoverLabelModel = itemModel.getModel('emphasis.label');
    }

    var visualColor = lineData.getItemVisual(idx, 'color');
    var visualOpacity = retrieve3(
        lineData.getItemVisual(idx, 'opacity'),
        lineStyle.opacity,
        1
    );

    line.useStyle(defaults(
        {
            strokeNoScale: true,
            fill: 'none',
            stroke: visualColor,
            opacity: visualOpacity
        },
        lineStyle
    ));
    line.hoverStyle = hoverLineStyle;

    // Update symbol
    each$1(SYMBOL_CATEGORIES, function (symbolCategory) {
        var symbol = this.childOfName(symbolCategory);
        if (symbol) {
            symbol.setColor(visualColor);
            symbol.setStyle({
                opacity: visualOpacity
            });
        }
    }, this);

    var showLabel = labelModel.getShallow('show');
    var hoverShowLabel = hoverLabelModel.getShallow('show');

    var label = this.childOfName('label');
    var defaultLabelColor;
    var baseText;

    // FIXME: the logic below probably should be merged to `graphic.setLabelStyle`.
    if (showLabel || hoverShowLabel) {
        defaultLabelColor = visualColor || '#000';

        baseText = seriesModel.getFormattedLabel(idx, 'normal', lineData.dataType);
        if (baseText == null) {
            var rawVal = seriesModel.getRawValue(idx);
            baseText = rawVal == null
                ? lineData.getName(idx)
                : isFinite(rawVal)
                ? round$1(rawVal)
                : rawVal;
        }
    }
    var normalText = showLabel ? baseText : null;
    var emphasisText = hoverShowLabel
        ? retrieve2(
            seriesModel.getFormattedLabel(idx, 'emphasis', lineData.dataType),
            baseText
        )
        : null;

    var labelStyle = label.style;

    // Always set `textStyle` even if `normalStyle.text` is null, because default
    // values have to be set on `normalStyle`.
    if (normalText != null || emphasisText != null) {
        setTextStyle(label.style, labelModel, {
            text: normalText
        }, {
            autoColor: defaultLabelColor
        });

        label.__textAlign = labelStyle.textAlign;
        label.__verticalAlign = labelStyle.textVerticalAlign;
        // 'start', 'middle', 'end'
        label.__position = labelModel.get('position') || 'middle';

        var distance$$1 = labelModel.get('distance');
        if (!isArray(distance$$1)) {
            distance$$1 = [distance$$1, distance$$1];
        }
        label.__labelDistance = distance$$1;
    }

    if (emphasisText != null) {
        // Only these properties supported in this emphasis style here.
        label.hoverStyle = {
            text: emphasisText,
            textFill: hoverLabelModel.getTextColor(true),
            // For merging hover style to normal style, do not use
            // `hoverLabelModel.getFont()` here.
            fontStyle: hoverLabelModel.getShallow('fontStyle'),
            fontWeight: hoverLabelModel.getShallow('fontWeight'),
            fontSize: hoverLabelModel.getShallow('fontSize'),
            fontFamily: hoverLabelModel.getShallow('fontFamily')
        };
    }
    else {
        label.hoverStyle = {
            text: null
        };
    }

    label.ignore = !showLabel && !hoverShowLabel;

    setHoverStyle(this);
};

lineProto.highlight = function () {
    this.trigger('emphasis');
};

lineProto.downplay = function () {
    this.trigger('normal');
};

lineProto.updateLayout = function (lineData, idx) {
    this.setLinePoints(lineData.getItemLayout(idx));
};

lineProto.setLinePoints = function (points) {
    var linePath = this.childOfName('line');
    setLinePoints(linePath.shape, points);
    linePath.dirty();
};

inherits(Line$1, Group);

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

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

// import IncrementalDisplayable from 'zrender/src/graphic/IncrementalDisplayable';

/**
 * @alias module:echarts/component/marker/LineDraw
 * @constructor
 */
function LineDraw(ctor) {
    this._ctor = ctor || Line$1;

    this.group = new Group();
}

var lineDrawProto = LineDraw.prototype;

lineDrawProto.isPersistent = function () {
    return true;
};

/**
 * @param {module:echarts/data/List} lineData
 */
lineDrawProto.updateData = function (lineData) {
    var lineDraw = this;
    var group = lineDraw.group;

    var oldLineData = lineDraw._lineData;
    lineDraw._lineData = lineData;

    // There is no oldLineData only when first rendering or switching from
    // stream mode to normal mode, where previous elements should be removed.
    if (!oldLineData) {
        group.removeAll();
    }

    var seriesScope = makeSeriesScope$1(lineData);

    lineData.diff(oldLineData)
        .add(function (idx) {
            doAdd(lineDraw, lineData, idx, seriesScope);
        })
        .update(function (newIdx, oldIdx) {
            doUpdate(lineDraw, oldLineData, lineData, oldIdx, newIdx, seriesScope);
        })
        .remove(function (idx) {
            group.remove(oldLineData.getItemGraphicEl(idx));
        })
        .execute();
};

function doAdd(lineDraw, lineData, idx, seriesScope) {
    var itemLayout = lineData.getItemLayout(idx);

    if (!lineNeedsDraw(itemLayout)) {
        return;
    }

    var el = new lineDraw._ctor(lineData, idx, seriesScope);
    lineData.setItemGraphicEl(idx, el);
    lineDraw.group.add(el);
}

function doUpdate(lineDraw, oldLineData, newLineData, oldIdx, newIdx, seriesScope) {
    var itemEl = oldLineData.getItemGraphicEl(oldIdx);

    if (!lineNeedsDraw(newLineData.getItemLayout(newIdx))) {
        lineDraw.group.remove(itemEl);
        return;
    }

    if (!itemEl) {
        itemEl = new lineDraw._ctor(newLineData, newIdx, seriesScope);
    }
    else {
        itemEl.updateData(newLineData, newIdx, seriesScope);
    }

    newLineData.setItemGraphicEl(newIdx, itemEl);

    lineDraw.group.add(itemEl);
}

lineDrawProto.updateLayout = function () {
    var lineData = this._lineData;

    // Do not support update layout in incremental mode.
    if (!lineData) {
        return;
    }

    lineData.eachItemGraphicEl(function (el, idx) {
        el.updateLayout(lineData, idx);
    }, this);
};

lineDrawProto.incrementalPrepareUpdate = function (lineData) {
    this._seriesScope = makeSeriesScope$1(lineData);
    this._lineData = null;
    this.group.removeAll();
};

function isEffectObject(el) {
    return el.animators && el.animators.length > 0;
}

lineDrawProto.incrementalUpdate = function (taskParams, lineData) {
    function updateIncrementalAndHover(el) {
        if (!el.isGroup && !isEffectObject(el)) {
            el.incremental = el.useHoverLayer = true;
        }
    }

    for (var idx = taskParams.start; idx < taskParams.end; idx++) {
        var itemLayout = lineData.getItemLayout(idx);

        if (lineNeedsDraw(itemLayout)) {
            var el = new this._ctor(lineData, idx, this._seriesScope);
            el.traverse(updateIncrementalAndHover);

            this.group.add(el);
            lineData.setItemGraphicEl(idx, el);
        }
    }
};

function makeSeriesScope$1(lineData) {
    var hostModel = lineData.hostModel;
    return {
        lineStyle: hostModel.getModel('lineStyle').getLineStyle(),
        hoverLineStyle: hostModel.getModel('emphasis.lineStyle').getLineStyle(),
        labelModel: hostModel.getModel('label'),
        hoverLabelModel: hostModel.getModel('emphasis.label')
    };
}

lineDrawProto.remove = function () {
    this._clearIncremental();
    this._incremental = null;
    this.group.removeAll();
};

lineDrawProto._clearIncremental = function () {
    var incremental = this._incremental;
    if (incremental) {
        incremental.clearDisplaybles();
    }
};

function isPointNaN(pt) {
    return isNaN(pt[0]) || isNaN(pt[1]);
}

function lineNeedsDraw(pts) {
    return !isPointNaN(pts[0]) && !isPointNaN(pts[1]);
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var markLineTransform = function (seriesModel, coordSys, mlModel, item) {
    var data = seriesModel.getData();
    // Special type markLine like 'min', 'max', 'average', 'median'
    var mlType = item.type;

    if (!isArray(item)
        && (
            mlType === 'min' || mlType === 'max' || mlType === 'average' || mlType === 'median'
            // In case
            // data: [{
            //   yAxis: 10
            // }]
            || (item.xAxis != null || item.yAxis != null)
        )
    ) {
        var valueAxis;
        var value;

        if (item.yAxis != null || item.xAxis != null) {
            valueAxis = coordSys.getAxis(item.yAxis != null ? 'y' : 'x');
            value = retrieve(item.yAxis, item.xAxis);
        }
        else {
            var axisInfo = getAxisInfo$1(item, data, coordSys, seriesModel);
            valueAxis = axisInfo.valueAxis;
            var valueDataDim = getStackedDimension(data, axisInfo.valueDataDim);
            value = numCalculate(data, valueDataDim, mlType);
        }
        var valueIndex = valueAxis.dim === 'x' ? 0 : 1;
        var baseIndex = 1 - valueIndex;

        var mlFrom = clone(item);
        var mlTo = {};

        mlFrom.type = null;

        mlFrom.coord = [];
        mlTo.coord = [];
        mlFrom.coord[baseIndex] = -Infinity;
        mlTo.coord[baseIndex] = Infinity;

        var precision = mlModel.get('precision');
        if (precision >= 0 && typeof value === 'number') {
            value = +value.toFixed(Math.min(precision, 20));
        }

        mlFrom.coord[valueIndex] = mlTo.coord[valueIndex] = value;

        item = [mlFrom, mlTo, { // Extra option for tooltip and label
            type: mlType,
            valueIndex: item.valueIndex,
            // Force to use the value of calculated value.
            value: value
        }];
    }

    item = [
        dataTransform(seriesModel, item[0]),
        dataTransform(seriesModel, item[1]),
        extend({}, item[2])
    ];

    // Avoid line data type is extended by from(to) data type
    item[2].type = item[2].type || '';

    // Merge from option and to option into line option
    merge(item[2], item[0]);
    merge(item[2], item[1]);

    return item;
};

function isInifinity(val) {
    return !isNaN(val) && !isFinite(val);
}

// If a markLine has one dim
function ifMarkLineHasOnlyDim(dimIndex, fromCoord, toCoord, coordSys) {
    var otherDimIndex = 1 - dimIndex;
    var dimName = coordSys.dimensions[dimIndex];
    return isInifinity(fromCoord[otherDimIndex]) && isInifinity(toCoord[otherDimIndex])
        && fromCoord[dimIndex] === toCoord[dimIndex] && coordSys.getAxis(dimName).containData(fromCoord[dimIndex]);
}

function markLineFilter(coordSys, item) {
    if (coordSys.type === 'cartesian2d') {
        var fromCoord = item[0].coord;
        var toCoord = item[1].coord;
        // In case
        // {
        //  markLine: {
        //    data: [{ yAxis: 2 }]
        //  }
        // }
        if (
            fromCoord && toCoord
            && (ifMarkLineHasOnlyDim(1, fromCoord, toCoord, coordSys)
            || ifMarkLineHasOnlyDim(0, fromCoord, toCoord, coordSys))
        ) {
            return true;
        }
    }
    return dataFilter$1(coordSys, item[0])
        && dataFilter$1(coordSys, item[1]);
}

function updateSingleMarkerEndLayout(
    data, idx, isFrom, seriesModel, api
) {
    var coordSys = seriesModel.coordinateSystem;
    var itemModel = data.getItemModel(idx);

    var point;
    var xPx = parsePercent$1(itemModel.get('x'), api.getWidth());
    var yPx = parsePercent$1(itemModel.get('y'), api.getHeight());
    if (!isNaN(xPx) && !isNaN(yPx)) {
        point = [xPx, yPx];
    }
    else {
        // Chart like bar may have there own marker positioning logic
        if (seriesModel.getMarkerPosition) {
            // Use the getMarkerPoisition
            point = seriesModel.getMarkerPosition(
                data.getValues(data.dimensions, idx)
            );
        }
        else {
            var dims = coordSys.dimensions;
            var x = data.get(dims[0], idx);
            var y = data.get(dims[1], idx);
            point = coordSys.dataToPoint([x, y]);
        }
        // Expand line to the edge of grid if value on one axis is Inifnity
        // In case
        //  markLine: {
        //    data: [{
        //      yAxis: 2
        //      // or
        //      type: 'average'
        //    }]
        //  }
        if (coordSys.type === 'cartesian2d') {
            var xAxis = coordSys.getAxis('x');
            var yAxis = coordSys.getAxis('y');
            var dims = coordSys.dimensions;
            if (isInifinity(data.get(dims[0], idx))) {
                point[0] = xAxis.toGlobalCoord(xAxis.getExtent()[isFrom ? 0 : 1]);
            }
            else if (isInifinity(data.get(dims[1], idx))) {
                point[1] = yAxis.toGlobalCoord(yAxis.getExtent()[isFrom ? 0 : 1]);
            }
        }

        // Use x, y if has any
        if (!isNaN(xPx)) {
            point[0] = xPx;
        }
        if (!isNaN(yPx)) {
            point[1] = yPx;
        }
    }

    data.setItemLayout(idx, point);
}

MarkerView.extend({

    type: 'markLine',

    // updateLayout: function (markLineModel, ecModel, api) {
    //     ecModel.eachSeries(function (seriesModel) {
    //         var mlModel = seriesModel.markLineModel;
    //         if (mlModel) {
    //             var mlData = mlModel.getData();
    //             var fromData = mlModel.__from;
    //             var toData = mlModel.__to;
    //             // Update visual and layout of from symbol and to symbol
    //             fromData.each(function (idx) {
    //                 updateSingleMarkerEndLayout(fromData, idx, true, seriesModel, api);
    //                 updateSingleMarkerEndLayout(toData, idx, false, seriesModel, api);
    //             });
    //             // Update layout of line
    //             mlData.each(function (idx) {
    //                 mlData.setItemLayout(idx, [
    //                     fromData.getItemLayout(idx),
    //                     toData.getItemLayout(idx)
    //                 ]);
    //             });

    //             this.markerGroupMap.get(seriesModel.id).updateLayout();

    //         }
    //     }, this);
    // },

    updateTransform: function (markLineModel, ecModel, api) {
        ecModel.eachSeries(function (seriesModel) {
            var mlModel = seriesModel.markLineModel;
            if (mlModel) {
                var mlData = mlModel.getData();
                var fromData = mlModel.__from;
                var toData = mlModel.__to;
                // Update visual and layout of from symbol and to symbol
                fromData.each(function (idx) {
                    updateSingleMarkerEndLayout(fromData, idx, true, seriesModel, api);
                    updateSingleMarkerEndLayout(toData, idx, false, seriesModel, api);
                });
                // Update layout of line
                mlData.each(function (idx) {
                    mlData.setItemLayout(idx, [
                        fromData.getItemLayout(idx),
                        toData.getItemLayout(idx)
                    ]);
                });

                this.markerGroupMap.get(seriesModel.id).updateLayout();

            }
        }, this);
    },

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

        var lineDrawMap = this.markerGroupMap;
        var lineDraw = lineDrawMap.get(seriesId)
            || lineDrawMap.set(seriesId, new LineDraw());
        this.group.add(lineDraw.group);

        var mlData = createList$2(coordSys, seriesModel, mlModel);

        var fromData = mlData.from;
        var toData = mlData.to;
        var lineData = mlData.line;

        mlModel.__from = fromData;
        mlModel.__to = toData;
        // Line data for tooltip and formatter
        mlModel.setData(lineData);

        var symbolType = mlModel.get('symbol');
        var symbolSize = mlModel.get('symbolSize');
        if (!isArray(symbolType)) {
            symbolType = [symbolType, symbolType];
        }
        if (typeof symbolSize === 'number') {
            symbolSize = [symbolSize, symbolSize];
        }

        // Update visual and layout of from symbol and to symbol
        mlData.from.each(function (idx) {
            updateDataVisualAndLayout(fromData, idx, true);
            updateDataVisualAndLayout(toData, idx, false);
        });

        // Update visual and layout of line
        lineData.each(function (idx) {
            var lineColor = lineData.getItemModel(idx).get('lineStyle.color');
            lineData.setItemVisual(idx, {
                color: lineColor || fromData.getItemVisual(idx, 'color')
            });
            lineData.setItemLayout(idx, [
                fromData.getItemLayout(idx),
                toData.getItemLayout(idx)
            ]);

            lineData.setItemVisual(idx, {
                'fromSymbolRotate': fromData.getItemVisual(idx, 'symbolRotate'),
                'fromSymbolSize': fromData.getItemVisual(idx, 'symbolSize'),
                'fromSymbol': fromData.getItemVisual(idx, 'symbol'),
                'toSymbolRotate': toData.getItemVisual(idx, 'symbolRotate'),
                'toSymbolSize': toData.getItemVisual(idx, 'symbolSize'),
                'toSymbol': toData.getItemVisual(idx, 'symbol')
            });
        });

        lineDraw.updateData(lineData);

        // Set host model for tooltip
        // FIXME
        mlData.line.eachItemGraphicEl(function (el, idx) {
            el.traverse(function (child) {
                child.dataModel = mlModel;
            });
        });

        function updateDataVisualAndLayout(data, idx, isFrom) {
            var itemModel = data.getItemModel(idx);

            updateSingleMarkerEndLayout(
                data, idx, isFrom, seriesModel, api
            );
            data.setItemVisual(idx, {
                symbolRotate: itemModel.get('symbolRotate'),
                symbolSize: itemModel.get('symbolSize') || symbolSize[isFrom ? 0 : 1],
                symbol: itemModel.get('symbol', true) || symbolType[isFrom ? 0 : 1],
                color: itemModel.get('itemStyle.color') || seriesData.getVisual('color')
            });
        }

        lineDraw.__keep = true;

        lineDraw.group.silent = mlModel.get('silent') || seriesModel.get('silent');
    }
});

/**
 * @inner
 * @param {module:echarts/coord/*} coordSys
 * @param {module:echarts/model/Series} seriesModel
 * @param {module:echarts/model/Model} mpModel
 */
function createList$2(coordSys, seriesModel, mlModel) {

    var coordDimsInfos;
    if (coordSys) {
        coordDimsInfos = map(coordSys && coordSys.dimensions, function (coordDim) {
            var info = seriesModel.getData().getDimensionInfo(
                seriesModel.getData().mapDimension(coordDim)
            ) || {};
            // In map series data don't have lng and lat dimension. Fallback to same with coordSys
            return defaults({name: coordDim}, info);
        });
    }
    else {
        coordDimsInfos = [{
            name: 'value',
            type: 'float'
        }];
    }

    var fromData = new List(coordDimsInfos, mlModel);
    var toData = new List(coordDimsInfos, mlModel);
    // No dimensions
    var lineData = new List([], mlModel);

    var optData = map(mlModel.get('data'), curry(
        markLineTransform, seriesModel, coordSys, mlModel
    ));
    if (coordSys) {
        optData = filter(
            optData, curry(markLineFilter, coordSys)
        );
    }
    var dimValueGetter$$1 = coordSys ? dimValueGetter : function (item) {
        return item.value;
    };
    fromData.initData(
        map(optData, function (item) {
            return item[0];
        }),
        null,
        dimValueGetter$$1
    );
    toData.initData(
        map(optData, function (item) {
            return item[1];
        }),
        null,
        dimValueGetter$$1
    );
    lineData.initData(
        map(optData, function (item) {
            return item[2];
        })
    );
    lineData.hasItemOption = true;

    return {
        from: fromData,
        to: toData,
        line: lineData
    };
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

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

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

MarkerModel.extend({

    type: 'markArea',

    defaultOption: {
        zlevel: 0,
        // PENDING
        z: 1,
        tooltip: {
            trigger: 'item'
        },
        // markArea should fixed on the coordinate system
        animation: false,
        label: {
            show: true,
            position: 'top'
        },
        itemStyle: {
            // color and borderColor default to use color from series
            // color: 'auto'
            // borderColor: 'auto'
            borderWidth: 0
        },

        emphasis: {
            label: {
                show: true,
                position: 'top'
            }
        }
    }
});

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

// TODO Better on polar

var markAreaTransform = function (seriesModel, coordSys, maModel, item) {
    var lt = dataTransform(seriesModel, item[0]);
    var rb = dataTransform(seriesModel, item[1]);
    var retrieve$$1 = retrieve;

    // FIXME make sure lt is less than rb
    var ltCoord = lt.coord;
    var rbCoord = rb.coord;
    ltCoord[0] = retrieve$$1(ltCoord[0], -Infinity);
    ltCoord[1] = retrieve$$1(ltCoord[1], -Infinity);

    rbCoord[0] = retrieve$$1(rbCoord[0], Infinity);
    rbCoord[1] = retrieve$$1(rbCoord[1], Infinity);

    // Merge option into one
    var result = mergeAll([{}, lt, rb]);

    result.coord = [
        lt.coord, rb.coord
    ];
    result.x0 = lt.x;
    result.y0 = lt.y;
    result.x1 = rb.x;
    result.y1 = rb.y;
    return result;
};

function isInifinity$1(val) {
    return !isNaN(val) && !isFinite(val);
}

// If a markArea has one dim
function ifMarkLineHasOnlyDim$1(dimIndex, fromCoord, toCoord, coordSys) {
    var otherDimIndex = 1 - dimIndex;
    return isInifinity$1(fromCoord[otherDimIndex]) && isInifinity$1(toCoord[otherDimIndex]);
}

function markAreaFilter(coordSys, item) {
    var fromCoord = item.coord[0];
    var toCoord = item.coord[1];
    if (coordSys.type === 'cartesian2d') {
        // In case
        // {
        //  markArea: {
        //    data: [{ yAxis: 2 }]
        //  }
        // }
        if (
            fromCoord && toCoord
            && (ifMarkLineHasOnlyDim$1(1, fromCoord, toCoord, coordSys)
            || ifMarkLineHasOnlyDim$1(0, fromCoord, toCoord, coordSys))
        ) {
            return true;
        }
    }
    return dataFilter$1(coordSys, {
            coord: fromCoord,
            x: item.x0,
            y: item.y0
        })
        || dataFilter$1(coordSys, {
            coord: toCoord,
            x: item.x1,
            y: item.y1
        });
}

// dims can be ['x0', 'y0'], ['x1', 'y1'], ['x0', 'y1'], ['x1', 'y0']
function getSingleMarkerEndPoint(data, idx, dims, seriesModel, api) {
    var coordSys = seriesModel.coordinateSystem;
    var itemModel = data.getItemModel(idx);

    var point;
    var xPx = parsePercent$1(itemModel.get(dims[0]), api.getWidth());
    var yPx = parsePercent$1(itemModel.get(dims[1]), api.getHeight());
    if (!isNaN(xPx) && !isNaN(yPx)) {
        point = [xPx, yPx];
    }
    else {
        // Chart like bar may have there own marker positioning logic
        if (seriesModel.getMarkerPosition) {
            // Use the getMarkerPoisition
            point = seriesModel.getMarkerPosition(
                data.getValues(dims, idx)
            );
        }
        else {
            var x = data.get(dims[0], idx);
            var y = data.get(dims[1], idx);
            var pt = [x, y];
            coordSys.clampData && coordSys.clampData(pt, pt);
            point = coordSys.dataToPoint(pt, true);
        }
        if (coordSys.type === 'cartesian2d') {
            var xAxis = coordSys.getAxis('x');
            var yAxis = coordSys.getAxis('y');
            var x = data.get(dims[0], idx);
            var y = data.get(dims[1], idx);
            if (isInifinity$1(x)) {
                point[0] = xAxis.toGlobalCoord(xAxis.getExtent()[dims[0] === 'x0' ? 0 : 1]);
            }
            else if (isInifinity$1(y)) {
                point[1] = yAxis.toGlobalCoord(yAxis.getExtent()[dims[1] === 'y0' ? 0 : 1]);
            }
        }

        // Use x, y if has any
        if (!isNaN(xPx)) {
            point[0] = xPx;
        }
        if (!isNaN(yPx)) {
            point[1] = yPx;
        }
    }

    return point;
}

var dimPermutations = [['x0', 'y0'], ['x1', 'y0'], ['x1', 'y1'], ['x0', 'y1']];

MarkerView.extend({

    type: 'markArea',

    // updateLayout: function (markAreaModel, ecModel, api) {
    //     ecModel.eachSeries(function (seriesModel) {
    //         var maModel = seriesModel.markAreaModel;
    //         if (maModel) {
    //             var areaData = maModel.getData();
    //             areaData.each(function (idx) {
    //                 var points = zrUtil.map(dimPermutations, function (dim) {
    //                     return getSingleMarkerEndPoint(areaData, idx, dim, seriesModel, api);
    //                 });
    //                 // Layout
    //                 areaData.setItemLayout(idx, points);
    //                 var el = areaData.getItemGraphicEl(idx);
    //                 el.setShape('points', points);
    //             });
    //         }
    //     }, this);
    // },

    updateTransform: function (markAreaModel, ecModel, api) {
        ecModel.eachSeries(function (seriesModel) {
            var maModel = seriesModel.markAreaModel;
            if (maModel) {
                var areaData = maModel.getData();
                areaData.each(function (idx) {
                    var points = map(dimPermutations, function (dim) {
                        return getSingleMarkerEndPoint(areaData, idx, dim, seriesModel, api);
                    });
                    // Layout
                    areaData.setItemLayout(idx, points);
                    var el = areaData.getItemGraphicEl(idx);
                    el.setShape('points', points);
                });
            }
        }, this);
    },

    renderSeries: function (seriesModel, maModel, ecModel, api) {
        var coordSys = seriesModel.coordinateSystem;
        var seriesId = seriesModel.id;
        var seriesData = seriesModel.getData();

        var areaGroupMap = this.markerGroupMap;
        var polygonGroup = areaGroupMap.get(seriesId)
            || areaGroupMap.set(seriesId, {group: new Group()});

        this.group.add(polygonGroup.group);
        polygonGroup.__keep = true;

        var areaData = createList$3(coordSys, seriesModel, maModel);

        // Line data for tooltip and formatter
        maModel.setData(areaData);

        // Update visual and layout of line
        areaData.each(function (idx) {
            // Layout
            var points = map(dimPermutations, function (dim) {
                return getSingleMarkerEndPoint(areaData, idx, dim, seriesModel, api);
            });
            // If none of the area is inside coordSys, allClipped is set to be true
            // in layout so that label will not be displayed. See #12591
            var allClipped = true;
            each$1(dimPermutations, function (dim) {
                if (!allClipped) {
                    return;
                }
                var xValue = areaData.get(dim[0], idx);
                var yValue = areaData.get(dim[1], idx);
                // If is infinity, the axis should be considered not clipped
                if ((isInifinity$1(xValue) || coordSys.getAxis('x').containData(xValue))
                    && (isInifinity$1(yValue) || coordSys.getAxis('y').containData(yValue))
                ) {
                    allClipped = false;
                }
            });
            areaData.setItemLayout(idx, {
                points: points,
                allClipped: allClipped
            });

            // Visual
            areaData.setItemVisual(idx, {
                color: seriesData.getVisual('color')
            });
        });


        areaData.diff(polygonGroup.__data)
            .add(function (idx) {
                var layout = areaData.getItemLayout(idx);
                if (!layout.allClipped) {
                    var polygon = new Polygon({
                        shape: {
                            points: layout.points
                        }
                    });
                    areaData.setItemGraphicEl(idx, polygon);
                    polygonGroup.group.add(polygon);
                }
            })
            .update(function (newIdx, oldIdx) {
                var polygon = polygonGroup.__data.getItemGraphicEl(oldIdx);
                var layout = areaData.getItemLayout(newIdx);
                if (!layout.allClipped) {
                    if (polygon) {
                        updateProps(polygon, {
                            shape: {
                                points: layout.points
                            }
                        }, maModel, newIdx);
                    }
                    else {
                        polygon = new Polygon({
                            shape: {
                                points: layout.points
                            }
                        });
                    }
                    areaData.setItemGraphicEl(newIdx, polygon);
                    polygonGroup.group.add(polygon);
                }
                else if (polygon) {
                    polygonGroup.group.remove(polygon);
                }
            })
            .remove(function (idx) {
                var polygon = polygonGroup.__data.getItemGraphicEl(idx);
                polygonGroup.group.remove(polygon);
            })
            .execute();

        areaData.eachItemGraphicEl(function (polygon, idx) {
            var itemModel = areaData.getItemModel(idx);
            var labelModel = itemModel.getModel('label');
            var labelHoverModel = itemModel.getModel('emphasis.label');
            var color = areaData.getItemVisual(idx, 'color');
            polygon.useStyle(
                defaults(
                    itemModel.getModel('itemStyle').getItemStyle(),
                    {
                        fill: modifyAlpha(color, 0.4),
                        stroke: color
                    }
                )
            );

            polygon.hoverStyle = itemModel.getModel('emphasis.itemStyle').getItemStyle();

            setLabelStyle(
                polygon.style, polygon.hoverStyle, labelModel, labelHoverModel,
                {
                    labelFetcher: maModel,
                    labelDataIndex: idx,
                    defaultText: areaData.getName(idx) || '',
                    isRectText: true,
                    autoColor: color
                }
            );

            setHoverStyle(polygon, {});

            polygon.dataModel = maModel;
        });

        polygonGroup.__data = areaData;

        polygonGroup.group.silent = maModel.get('silent') || seriesModel.get('silent');
    }
});

/**
 * @inner
 * @param {module:echarts/coord/*} coordSys
 * @param {module:echarts/model/Series} seriesModel
 * @param {module:echarts/model/Model} mpModel
 */
function createList$3(coordSys, seriesModel, maModel) {

    var coordDimsInfos;
    var areaData;
    var dims = ['x0', 'y0', 'x1', 'y1'];
    if (coordSys) {
        coordDimsInfos = map(coordSys && coordSys.dimensions, function (coordDim) {
            var data = seriesModel.getData();
            var info = data.getDimensionInfo(
                data.mapDimension(coordDim)
            ) || {};
            // In map series data don't have lng and lat dimension. Fallback to same with coordSys
            return defaults({name: coordDim}, info);
        });
        areaData = new List(map(dims, function (dim, idx) {
            return {
                name: dim,
                type: coordDimsInfos[idx % 2].type
            };
        }), maModel);
    }
    else {
        coordDimsInfos = [{
            name: 'value',
            type: 'float'
        }];
        areaData = new List(coordDimsInfos, maModel);
    }

    var optData = map(maModel.get('data'), curry(
        markAreaTransform, seriesModel, coordSys, maModel
    ));
    if (coordSys) {
        optData = filter(
            optData, curry(markAreaFilter, coordSys)
        );
    }

    var dimValueGetter$$1 = coordSys ? function (item, dimName, dataIndex, dimIndex) {
        return item.coord[Math.floor(dimIndex / 2)][dimIndex % 2];
    } : function (item) {
        return item.value;
    };
    areaData.initData(optData, null, dimValueGetter$$1);
    areaData.hasItemOption = true;
    return areaData;
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

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

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

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

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var AXIS_DIMS = ['x', 'y', 'z', 'radius', 'angle', 'single'];
// Supported coords.
var COORDS = ['cartesian2d', 'polar', 'singleAxis'];

/**
 * @param {string} coordType
 * @return {boolean}
 */
function isCoordSupported(coordType) {
    return indexOf(COORDS, coordType) >= 0;
}

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

    return function (callback, context) {
        each$1(names, function (name, index) {
            var nameObj = {name: name, capital: capitalNames[index]};

            for (var j = 0; j < attrs.length; j++) {
                nameObj[attrs[j]] = name + capitalAttrs[j];
            }

            callback.call(context, nameObj);
        });
    };
}

/**
 * Iterate each dimension name.
 *
 * @public
 * @param {Function} callback The parameter is like:
 *                            {
 *                                name: 'angle',
 *                                capital: 'Angle',
 *                                axis: 'angleAxis',
 *                                axisIndex: 'angleAixs',
 *                                index: 'angleIndex'
 *                            }
 * @param {Object} context
 */
var eachAxisDim$1 = createNameEach(AXIS_DIMS, ['axisIndex', 'axis', 'index', 'id']);

/**
 * If tow dataZoomModels has the same axis controlled, we say that they are 'linked'.
 * dataZoomModels and 'links' make up one or more graphics.
 * This function finds the graphic where the source dataZoomModel is in.
 *
 * @public
 * @param {Function} forEachNode Node iterator.
 * @param {Function} forEachEdgeType edgeType iterator
 * @param {Function} edgeIdGetter Giving node and edgeType, return an array of edge id.
 * @return {Function} Input: sourceNode, Output: Like {nodes: [], dims: {}}
 */
function createLinkedNodesFinder(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 indexOf(result.nodes, node) >= 0;
    }

    function isLinked(node, result) {
        var hasLink = false;
        forEachEdgeType(function (edgeType) {
            each$1(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) {
            each$1(edgeIdGetter(node, edgeType) || [], function (edgeId) {
                result.records[edgeType.name][edgeId] = true;
            });
        });
    }
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * Calculate slider move result.
 * Usage:
 * (1) If both handle0 and handle1 are needed to be moved, set minSpan the same as
 * maxSpan and the same as `Math.abs(handleEnd[1] - handleEnds[0])`.
 * (2) If handle0 is forbidden to cross handle1, set minSpan as `0`.
 *
 * @param {number} delta Move length.
 * @param {Array.<number>} handleEnds handleEnds[0] can be bigger then handleEnds[1].
 *              handleEnds will be modified in this method.
 * @param {Array.<number>} extent handleEnds is restricted by extent.
 *              extent[0] should less or equals than extent[1].
 * @param {number|string} handleIndex Can be 'all', means that both move the two handleEnds.
 * @param {number} [minSpan] The range of dataZoom can not be smaller than that.
 *              If not set, handle0 and cross handle1. If set as a non-negative
 *              number (including `0`), handles will push each other when reaching
 *              the minSpan.
 * @param {number} [maxSpan] The range of dataZoom can not be larger than that.
 * @return {Array.<number>} The input handleEnds.
 */
var sliderMove = function (delta, handleEnds, extent, handleIndex, minSpan, maxSpan) {

    delta = delta || 0;

    var extentSpan = extent[1] - extent[0];

    // Notice maxSpan and minSpan can be null/undefined.
    if (minSpan != null) {
        minSpan = restrict(minSpan, [0, extentSpan]);
    }
    if (maxSpan != null) {
        maxSpan = Math.max(maxSpan, minSpan != null ? minSpan : 0);
    }
    if (handleIndex === 'all') {
        var handleSpan = Math.abs(handleEnds[1] - handleEnds[0]);
        handleSpan = restrict(handleSpan, [0, extentSpan]);
        minSpan = maxSpan = restrict(handleSpan, [minSpan, maxSpan]);
        handleIndex = 0;
    }

    handleEnds[0] = restrict(handleEnds[0], extent);
    handleEnds[1] = restrict(handleEnds[1], extent);

    var originalDistSign = getSpanSign(handleEnds, handleIndex);

    handleEnds[handleIndex] += delta;

    // Restrict in extent.
    var extentMinSpan = minSpan || 0;
    var realExtent = extent.slice();
    originalDistSign.sign < 0 ? (realExtent[0] += extentMinSpan) : (realExtent[1] -= extentMinSpan);
    handleEnds[handleIndex] = restrict(handleEnds[handleIndex], realExtent);

    // Expand span.
    var currDistSign = getSpanSign(handleEnds, handleIndex);
    if (minSpan != null && (
        currDistSign.sign !== originalDistSign.sign || currDistSign.span < minSpan
    )) {
        // If minSpan exists, 'cross' is forbidden.
        handleEnds[1 - handleIndex] = handleEnds[handleIndex] + originalDistSign.sign * minSpan;
    }

    // Shrink span.
    var currDistSign = getSpanSign(handleEnds, handleIndex);
    if (maxSpan != null && currDistSign.span > maxSpan) {
        handleEnds[1 - handleIndex] = handleEnds[handleIndex] + currDistSign.sign * maxSpan;
    }

    return handleEnds;
};

function getSpanSign(handleEnds, handleIndex) {
    var dist = handleEnds[handleIndex] - handleEnds[1 - handleIndex];
    // If `handleEnds[0] === handleEnds[1]`, always believe that handleEnd[0]
    // is at left of handleEnds[1] for non-cross case.
    return {span: Math.abs(dist), sign: dist > 0 ? -1 : dist < 0 ? 1 : handleIndex ? -1 : 1};
}

function restrict(value, extend) {
    return Math.min(
        extend[1] != null ? extend[1] : Infinity,
        Math.max(extend[0] != null ? extend[0] : -Infinity, value)
    );
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var each$13 = each$1;
var asc$1 = asc;

/**
 * Operate single axis.
 * One axis can only operated by one axis operator.
 * Different dataZoomModels may be defined to operate the same axis.
 * (i.e. 'inside' data zoom and 'slider' data zoom components)
 * So dataZoomModels share one axisProxy in that case.
 *
 * @class
 */
var AxisProxy = function (dimName, axisIndex, dataZoomModel, ecModel) {

    /**
     * @private
     * @type {string}
     */
    this._dimName = dimName;

    /**
     * @private
     */
    this._axisIndex = axisIndex;

    /**
     * @private
     * @type {Array.<number>}
     */
    this._valueWindow;

    /**
     * @private
     * @type {Array.<number>}
     */
    this._percentWindow;

    /**
     * @private
     * @type {Array.<number>}
     */
    this._dataExtent;

    /**
     * {minSpan, maxSpan, minValueSpan, maxValueSpan}
     * @private
     * @type {Object}
     */
    this._minMaxSpan;

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

    /**
     * @private
     * @type {module: echarts/component/dataZoom/DataZoomModel}
     */
    this._dataZoomModel = dataZoomModel;

    // /**
    //  * @readOnly
    //  * @private
    //  */
    // this.hasSeriesStacked;
};

AxisProxy.prototype = {

    constructor: AxisProxy,

    /**
     * Whether the axisProxy is hosted by dataZoomModel.
     *
     * @public
     * @param {module: echarts/component/dataZoom/DataZoomModel} dataZoomModel
     * @return {boolean}
     */
    hostedBy: function (dataZoomModel) {
        return this._dataZoomModel === dataZoomModel;
    },

    /**
     * @return {Array.<number>} Value can only be NaN or finite value.
     */
    getDataValueWindow: function () {
        return this._valueWindow.slice();
    },

    /**
     * @return {Array.<number>}
     */
    getDataPercentWindow: function () {
        return this._percentWindow.slice();
    },

    /**
     * @public
     * @param {number} axisIndex
     * @return {Array} seriesModels
     */
    getTargetSeriesModels: function () {
        var seriesModels = [];
        var ecModel = this.ecModel;

        ecModel.eachSeries(function (seriesModel) {
            if (isCoordSupported(seriesModel.get('coordinateSystem'))) {
                var dimName = this._dimName;
                var axisModel = ecModel.queryComponents({
                    mainType: dimName + 'Axis',
                    index: seriesModel.get(dimName + 'AxisIndex'),
                    id: seriesModel.get(dimName + 'AxisId')
                })[0];
                if (this._axisIndex === (axisModel && axisModel.componentIndex)) {
                    seriesModels.push(seriesModel);
                }
            }
        }, this);

        return seriesModels;
    },

    getAxisModel: function () {
        return this.ecModel.getComponent(this._dimName + 'Axis', this._axisIndex);
    },

    getOtherAxisModel: function () {
        var axisDim = this._dimName;
        var ecModel = this.ecModel;
        var axisModel = this.getAxisModel();
        var isCartesian = axisDim === 'x' || axisDim === 'y';
        var otherAxisDim;
        var coordSysIndexName;
        if (isCartesian) {
            coordSysIndexName = 'gridIndex';
            otherAxisDim = axisDim === 'x' ? 'y' : 'x';
        }
        else {
            coordSysIndexName = 'polarIndex';
            otherAxisDim = axisDim === 'angle' ? 'radius' : 'angle';
        }
        var foundOtherAxisModel;
        ecModel.eachComponent(otherAxisDim + 'Axis', function (otherAxisModel) {
            if ((otherAxisModel.get(coordSysIndexName) || 0)
                === (axisModel.get(coordSysIndexName) || 0)
            ) {
                foundOtherAxisModel = otherAxisModel;
            }
        });
        return foundOtherAxisModel;
    },

    getMinMaxSpan: function () {
        return clone(this._minMaxSpan);
    },

    /**
     * Only calculate by given range and this._dataExtent, do not change anything.
     *
     * @param {Object} opt
     * @param {number} [opt.start]
     * @param {number} [opt.end]
     * @param {number} [opt.startValue]
     * @param {number} [opt.endValue]
     */
    calculateDataWindow: function (opt) {
        var dataExtent = this._dataExtent;
        var axisModel = this.getAxisModel();
        var scale = axisModel.axis.scale;
        var rangePropMode = this._dataZoomModel.getRangePropMode();
        var percentExtent = [0, 100];
        var percentWindow = [];
        var valueWindow = [];
        var hasPropModeValue;

        each$13(['start', 'end'], function (prop, idx) {
            var boundPercent = opt[prop];
            var boundValue = opt[prop + 'Value'];

            // Notice: dataZoom is based either on `percentProp` ('start', 'end') or
            // on `valueProp` ('startValue', 'endValue'). (They are based on the data extent
            // but not min/max of axis, which will be calculated by data window then).
            // The former one is suitable for cases that a dataZoom component controls multiple
            // axes with different unit or extent, and the latter one is suitable for accurate
            // zoom by pixel (e.g., in dataZoomSelect).
            // we use `getRangePropMode()` to mark which prop is used. `rangePropMode` is updated
            // only when setOption or dispatchAction, otherwise it remains its original value.
            // (Why not only record `percentProp` and always map to `valueProp`? Because
            // the map `valueProp` -> `percentProp` -> `valueProp` probably not the original
            // `valueProp`. consider two axes constrolled by one dataZoom. They have different
            // data extent. All of values that are overflow the `dataExtent` will be calculated
            // to percent '100%').

            if (rangePropMode[idx] === 'percent') {
                boundPercent == null && (boundPercent = percentExtent[idx]);
                // Use scale.parse to math round for category or time axis.
                boundValue = scale.parse(linearMap(
                    boundPercent, percentExtent, dataExtent
                ));
            }
            else {
                hasPropModeValue = true;
                boundValue = boundValue == null ? dataExtent[idx] : scale.parse(boundValue);
                // Calculating `percent` from `value` may be not accurate, because
                // This calculation can not be inversed, because all of values that
                // are overflow the `dataExtent` will be calculated to percent '100%'
                boundPercent = linearMap(
                    boundValue, dataExtent, percentExtent
                );
            }

            // valueWindow[idx] = round(boundValue);
            // percentWindow[idx] = round(boundPercent);
            valueWindow[idx] = boundValue;
            percentWindow[idx] = boundPercent;
        });

        asc$1(valueWindow);
        asc$1(percentWindow);

        // The windows from user calling of `dispatchAction` might be out of the extent,
        // or do not obey the `min/maxSpan`, `min/maxValueSpan`. But we dont restrict window
        // by `zoomLock` here, because we see `zoomLock` just as a interaction constraint,
        // where API is able to initialize/modify the window size even though `zoomLock`
        // specified.
        var spans = this._minMaxSpan;
        hasPropModeValue
            ? restrictSet(valueWindow, percentWindow, dataExtent, percentExtent, false)
            : restrictSet(percentWindow, valueWindow, percentExtent, dataExtent, true);

        function restrictSet(fromWindow, toWindow, fromExtent, toExtent, toValue) {
            var suffix = toValue ? 'Span' : 'ValueSpan';
            sliderMove(0, fromWindow, fromExtent, 'all', spans['min' + suffix], spans['max' + suffix]);
            for (var i = 0; i < 2; i++) {
                toWindow[i] = linearMap(fromWindow[i], fromExtent, toExtent, true);
                toValue && (toWindow[i] = scale.parse(toWindow[i]));
            }
        }

        return {
            valueWindow: valueWindow,
            percentWindow: percentWindow
        };
    },

    /**
     * Notice: reset should not be called before series.restoreData() called,
     * so it is recommanded to be called in "process stage" but not "model init
     * stage".
     *
     * @param {module: echarts/component/dataZoom/DataZoomModel} dataZoomModel
     */
    reset: function (dataZoomModel) {
        if (dataZoomModel !== this._dataZoomModel) {
            return;
        }

        var targetSeries = this.getTargetSeriesModels();
        // Culculate data window and data extent, and record them.
        this._dataExtent = calculateDataExtent(this, this._dimName, targetSeries);

        // this.hasSeriesStacked = false;
        // each(targetSeries, function (series) {
            // var data = series.getData();
            // var dataDim = data.mapDimension(this._dimName);
            // var stackedDimension = data.getCalculationInfo('stackedDimension');
            // if (stackedDimension && stackedDimension === dataDim) {
                // this.hasSeriesStacked = true;
            // }
        // }, this);

        // `calculateDataWindow` uses min/maxSpan.
        setMinMaxSpan(this);

        var dataWindow = this.calculateDataWindow(dataZoomModel.settledOption);

        this._valueWindow = dataWindow.valueWindow;
        this._percentWindow = dataWindow.percentWindow;

        // Update axis setting then.
        setAxisModel(this);
    },

    /**
     * @param {module: echarts/component/dataZoom/DataZoomModel} dataZoomModel
     */
    restore: function (dataZoomModel) {
        if (dataZoomModel !== this._dataZoomModel) {
            return;
        }

        this._valueWindow = this._percentWindow = null;
        setAxisModel(this, true);
    },

    /**
     * @param {module: echarts/component/dataZoom/DataZoomModel} dataZoomModel
     */
    filterData: function (dataZoomModel, api) {
        if (dataZoomModel !== this._dataZoomModel) {
            return;
        }

        var axisDim = this._dimName;
        var seriesModels = this.getTargetSeriesModels();
        var filterMode = dataZoomModel.get('filterMode');
        var valueWindow = this._valueWindow;

        if (filterMode === 'none') {
            return;
        }

        // FIXME
        // Toolbox may has dataZoom injected. And if there are stacked bar chart
        // with NaN data, NaN will be filtered and stack will be wrong.
        // So we need to force the mode to be set empty.
        // In fect, it is not a big deal that do not support filterMode-'filter'
        // when using toolbox#dataZoom, utill tooltip#dataZoom support "single axis
        // selection" some day, which might need "adapt to data extent on the
        // otherAxis", which is disabled by filterMode-'empty'.
        // But currently, stack has been fixed to based on value but not index,
        // so this is not an issue any more.
        // var otherAxisModel = this.getOtherAxisModel();
        // if (dataZoomModel.get('$fromToolbox')
        //     && otherAxisModel
        //     && otherAxisModel.hasSeriesStacked
        // ) {
        //     filterMode = 'empty';
        // }

        // TODO
        // filterMode 'weakFilter' and 'empty' is not optimized for huge data yet.

        each$13(seriesModels, function (seriesModel) {
            var seriesData = seriesModel.getData();
            var dataDims = seriesData.mapDimension(axisDim, true);

            if (!dataDims.length) {
                return;
            }

            if (filterMode === 'weakFilter') {
                seriesData.filterSelf(function (dataIndex) {
                    var leftOut;
                    var rightOut;
                    var hasValue;
                    for (var i = 0; i < dataDims.length; i++) {
                        var value = seriesData.get(dataDims[i], dataIndex);
                        var thisHasValue = !isNaN(value);
                        var thisLeftOut = value < valueWindow[0];
                        var thisRightOut = value > valueWindow[1];
                        if (thisHasValue && !thisLeftOut && !thisRightOut) {
                            return true;
                        }
                        thisHasValue && (hasValue = true);
                        thisLeftOut && (leftOut = true);
                        thisRightOut && (rightOut = true);
                    }
                    // If both left out and right out, do not filter.
                    return hasValue && leftOut && rightOut;
                });
            }
            else {
                each$13(dataDims, function (dim) {
                    if (filterMode === 'empty') {
                        seriesModel.setData(
                            seriesData = seriesData.map(dim, function (value) {
                                return !isInWindow(value) ? NaN : value;
                            })
                        );
                    }
                    else {
                        var range = {};
                        range[dim] = valueWindow;

                        // console.time('select');
                        seriesData.selectRange(range);
                        // console.timeEnd('select');
                    }
                });
            }

            each$13(dataDims, function (dim) {
                seriesData.setApproximateExtent(valueWindow, dim);
            });
        });

        function isInWindow(value) {
            return value >= valueWindow[0] && value <= valueWindow[1];
        }
    }
};

function calculateDataExtent(axisProxy, axisDim, seriesModels) {
    var dataExtent = [Infinity, -Infinity];

    each$13(seriesModels, function (seriesModel) {
        var seriesData = seriesModel.getData();
        if (seriesData) {
            each$13(seriesData.mapDimension(axisDim, true), function (dim) {
                var seriesExtent = seriesData.getApproximateExtent(dim);
                seriesExtent[0] < dataExtent[0] && (dataExtent[0] = seriesExtent[0]);
                seriesExtent[1] > dataExtent[1] && (dataExtent[1] = seriesExtent[1]);
            });
        }
    });

    if (dataExtent[1] < dataExtent[0]) {
        dataExtent = [NaN, NaN];
    }

    // It is important to get "consistent" extent when more then one axes is
    // controlled by a `dataZoom`, otherwise those axes will not be synchronized
    // when zooming. But it is difficult to know what is "consistent", considering
    // axes have different type or even different meanings (For example, two
    // time axes are used to compare data of the same date in different years).
    // So basically dataZoom just obtains extent by series.data (in category axis
    // extent can be obtained from axis.data).
    // Nevertheless, user can set min/max/scale on axes to make extent of axes
    // consistent.
    fixExtentByAxis(axisProxy, dataExtent);

    return dataExtent;
}

function fixExtentByAxis(axisProxy, dataExtent) {
    var axisModel = axisProxy.getAxisModel();
    var min = axisModel.getMin(true);

    // For category axis, if min/max/scale are not set, extent is determined
    // by axis.data by default.
    var isCategoryAxis = axisModel.get('type') === 'category';
    var axisDataLen = isCategoryAxis && axisModel.getCategories().length;

    if (min != null && min !== 'dataMin' && typeof min !== 'function') {
        dataExtent[0] = min;
    }
    else if (isCategoryAxis) {
        dataExtent[0] = axisDataLen > 0 ? 0 : NaN;
    }

    var max = axisModel.getMax(true);
    if (max != null && max !== 'dataMax' && typeof max !== 'function') {
        dataExtent[1] = max;
    }
    else if (isCategoryAxis) {
        dataExtent[1] = axisDataLen > 0 ? axisDataLen - 1 : NaN;
    }

    if (!axisModel.get('scale', true)) {
        dataExtent[0] > 0 && (dataExtent[0] = 0);
        dataExtent[1] < 0 && (dataExtent[1] = 0);
    }

    // For value axis, if min/max/scale are not set, we just use the extent obtained
    // by series data, which may be a little different from the extent calculated by
    // `axisHelper.getScaleExtent`. But the different just affects the experience a
    // little when zooming. So it will not be fixed until some users require it strongly.

    return dataExtent;
}

function setAxisModel(axisProxy, isRestore) {
    var axisModel = axisProxy.getAxisModel();

    var percentWindow = axisProxy._percentWindow;
    var valueWindow = axisProxy._valueWindow;

    if (!percentWindow) {
        return;
    }

    // [0, 500]: arbitrary value, guess axis extent.
    var precision = getPixelPrecision(valueWindow, [0, 500]);
    precision = Math.min(precision, 20);
    // isRestore or isFull
    var useOrigin = isRestore || (percentWindow[0] === 0 && percentWindow[1] === 100);

    axisModel.setRange(
        useOrigin ? null : +valueWindow[0].toFixed(precision),
        useOrigin ? null : +valueWindow[1].toFixed(precision)
    );
}

function setMinMaxSpan(axisProxy) {
    var minMaxSpan = axisProxy._minMaxSpan = {};
    var dataZoomModel = axisProxy._dataZoomModel;
    var dataExtent = axisProxy._dataExtent;

    each$13(['min', 'max'], function (minMax) {
        var percentSpan = dataZoomModel.get(minMax + 'Span');
        var valueSpan = dataZoomModel.get(minMax + 'ValueSpan');
        valueSpan != null && (valueSpan = axisProxy.getAxisModel().axis.scale.parse(valueSpan));

        // minValueSpan and maxValueSpan has higher priority than minSpan and maxSpan
        if (valueSpan != null) {
            percentSpan = linearMap(
                dataExtent[0] + valueSpan, dataExtent, [0, 100], true
            );
        }
        else if (percentSpan != null) {
            valueSpan = linearMap(
                percentSpan, [0, 100], dataExtent, true
            ) - dataExtent[0];
        }

        minMaxSpan[minMax + 'Span'] = percentSpan;
        minMaxSpan[minMax + 'ValueSpan'] = valueSpan;
    });
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var each$12 = each$1;
var eachAxisDim = eachAxisDim$1;

var DataZoomModel = extendComponentModel({

    type: 'dataZoom',

    dependencies: [
        'xAxis', 'yAxis', 'zAxis', 'radiusAxis', 'angleAxis', 'singleAxis', 'series'
    ],

    /**
     * @protected
     */
    defaultOption: {
        zlevel: 0,
        z: 4,                   // Higher than normal component (z: 2).
        orient: null,           // Default auto by axisIndex. Possible value: 'horizontal', 'vertical'.
        xAxisIndex: null,       // Default the first horizontal category axis.
        yAxisIndex: null,       // Default the first vertical category axis.

        filterMode: 'filter',   // Possible values: 'filter' or 'empty' or 'weakFilter'.
                                // 'filter': data items which are out of window will be removed. This option is
                                //          applicable when filtering outliers. For each data item, it will be
                                //          filtered if one of the relevant dimensions is out of the window.
                                // 'weakFilter': data items which are out of window will be removed. This option
                                //          is applicable when filtering outliers. For each data item, it will be
                                //          filtered only if all  of the relevant dimensions are out of the same
                                //          side of the window.
                                // 'empty': data items which are out of window will be set to empty.
                                //          This option is applicable when user should not neglect
                                //          that there are some data items out of window.
                                // 'none': Do not filter.
                                // Taking line chart as an example, line will be broken in
                                // the filtered points when filterModel is set to 'empty', but
                                // be connected when set to 'filter'.

        throttle: null,         // Dispatch action by the fixed rate, avoid frequency.
                                // default 100. Do not throttle when use null/undefined.
                                // If animation === true and animationDurationUpdate > 0,
                                // default value is 100, otherwise 20.
        start: 0,               // Start percent. 0 ~ 100
        end: 100,               // End percent. 0 ~ 100
        startValue: null,       // Start value. If startValue specified, start is ignored.
        endValue: null,         // End value. If endValue specified, end is ignored.
        minSpan: null,          // 0 ~ 100
        maxSpan: null,          // 0 ~ 100
        minValueSpan: null,     // The range of dataZoom can not be smaller than that.
        maxValueSpan: null,     // The range of dataZoom can not be larger than that.
        rangeMode: null         // Array, can be 'value' or 'percent'.
    },

    /**
     * @override
     */
    init: function (option, parentModel, ecModel) {

        /**
         * key like x_0, y_1
         * @private
         * @type {Object}
         */
        this._dataIntervalByAxis = {};

        /**
         * @private
         */
        this._dataInfo = {};

        /**
         * key like x_0, y_1
         * @private
         */
        this._axisProxies = {};

        /**
         * @readOnly
         */
        this.textStyleModel;

        /**
         * @private
         */
        this._autoThrottle = true;

        /**
         * It is `[rangeModeForMin, rangeModeForMax]`.
         * The optional values for `rangeMode`:
         * + `'value'` mode: the axis extent will always be determined by
         *     `dataZoom.startValue` and `dataZoom.endValue`, despite
         *     how data like and how `axis.min` and `axis.max` are.
         * + `'percent'` mode: `100` represents 100% of the `[dMin, dMax]`,
         *     where `dMin` is `axis.min` if `axis.min` specified, otherwise `data.extent[0]`,
         *     and `dMax` is `axis.max` if `axis.max` specified, otherwise `data.extent[1]`.
         *     Axis extent will be determined by the result of the percent of `[dMin, dMax]`.
         *
         * For example, when users are using dynamic data (update data periodically via `setOption`),
         * if in `'value`' mode, the window will be kept in a fixed value range despite how
         * data are appended, while if in `'percent'` mode, whe window range will be changed alone with
         * the appended data (suppose `axis.min` and `axis.max` are not specified).
         *
         * @private
         */
        this._rangePropMode = ['percent', 'percent'];

        var inputRawOption = retrieveRawOption(option);

        /**
         * Suppose a "main process" start at the point that model prepared (that is,
         * model initialized or merged or method called in `action`).
         * We should keep the `main process` idempotent, that is, given a set of values
         * on `option`, we get the same result.
         *
         * But sometimes, values on `option` will be updated for providing users
         * a "final calculated value" (`dataZoomProcessor` will do that). Those value
         * should not be the base/input of the `main process`.
         *
         * So in that case we should save and keep the input of the `main process`
         * separately, called `settledOption`.
         *
         * For example, consider the case:
         * (Step_1) brush zoom the grid by `toolbox.dataZoom`,
         *     where the original input `option.startValue`, `option.endValue` are earsed by
         *     calculated value.
         * (Step)2) click the legend to hide and show a series,
         *     where the new range is calculated by the earsed `startValue` and `endValue`,
         *     which brings incorrect result.
         *
         * @readOnly
         */
        this.settledOption = inputRawOption;

        this.mergeDefaultAndTheme(option, ecModel);

        this.doInit(inputRawOption);
    },

    /**
     * @override
     */
    mergeOption: function (newOption) {
        var inputRawOption = retrieveRawOption(newOption);

        //FIX #2591
        merge(this.option, newOption, true);
        merge(this.settledOption, inputRawOption, true);

        this.doInit(inputRawOption);
    },

    /**
     * @protected
     */
    doInit: function (inputRawOption) {
        var thisOption = this.option;

        // Disable realtime view update if canvas is not supported.
        if (!env$1.canvasSupported) {
            thisOption.realtime = false;
        }

        this._setDefaultThrottle(inputRawOption);

        updateRangeUse(this, inputRawOption);

        var settledOption = this.settledOption;
        each$12([['start', 'startValue'], ['end', 'endValue']], function (names, index) {
            // start/end has higher priority over startValue/endValue if they
            // both set, but we should make chart.setOption({endValue: 1000})
            // effective, rather than chart.setOption({endValue: 1000, end: null}).
            if (this._rangePropMode[index] === 'value') {
                thisOption[names[0]] = settledOption[names[0]] = null;
            }
            // Otherwise do nothing and use the merge result.
        }, this);

        this.textStyleModel = this.getModel('textStyle');

        this._resetTarget();

        this._giveAxisProxies();
    },

    /**
     * @private
     */
    _giveAxisProxies: function () {
        var axisProxies = this._axisProxies;

        this.eachTargetAxis(function (dimNames, axisIndex, dataZoomModel, ecModel) {
            var axisModel = this.dependentModels[dimNames.axis][axisIndex];

            // If exists, share axisProxy with other dataZoomModels.
            var axisProxy = axisModel.__dzAxisProxy || (
                // Use the first dataZoomModel as the main model of axisProxy.
                axisModel.__dzAxisProxy = new AxisProxy(
                    dimNames.name, axisIndex, this, ecModel
                )
            );
            // FIXME
            // dispose __dzAxisProxy

            axisProxies[dimNames.name + '_' + axisIndex] = axisProxy;
        }, this);
    },

    /**
     * @private
     */
    _resetTarget: function () {
        var thisOption = this.option;

        var autoMode = this._judgeAutoMode();

        eachAxisDim(function (dimNames) {
            var axisIndexName = dimNames.axisIndex;
            thisOption[axisIndexName] = normalizeToArray(
                thisOption[axisIndexName]
            );
        }, this);

        if (autoMode === 'axisIndex') {
            this._autoSetAxisIndex();
        }
        else if (autoMode === 'orient') {
            this._autoSetOrient();
        }
    },

    /**
     * @private
     */
    _judgeAutoMode: function () {
        // Auto set only works for setOption at the first time.
        // The following is user's reponsibility. So using merged
        // option is OK.
        var thisOption = this.option;

        var hasIndexSpecified = false;
        eachAxisDim(function (dimNames) {
            // When user set axisIndex as a empty array, we think that user specify axisIndex
            // but do not want use auto mode. Because empty array may be encountered when
            // some error occured.
            if (thisOption[dimNames.axisIndex] != null) {
                hasIndexSpecified = true;
            }
        }, this);

        var orient = thisOption.orient;

        if (orient == null && hasIndexSpecified) {
            return 'orient';
        }
        else if (!hasIndexSpecified) {
            if (orient == null) {
                thisOption.orient = 'horizontal';
            }
            return 'axisIndex';
        }
    },

    /**
     * @private
     */
    _autoSetAxisIndex: function () {
        var autoAxisIndex = true;
        var orient = this.get('orient', true);
        var thisOption = this.option;
        var dependentModels = this.dependentModels;

        if (autoAxisIndex) {
            // Find axis that parallel to dataZoom as default.
            var dimName = orient === 'vertical' ? 'y' : 'x';

            if (dependentModels[dimName + 'Axis'].length) {
                thisOption[dimName + 'AxisIndex'] = [0];
                autoAxisIndex = false;
            }
            else {
                each$12(dependentModels.singleAxis, function (singleAxisModel) {
                    if (autoAxisIndex && singleAxisModel.get('orient', true) === orient) {
                        thisOption.singleAxisIndex = [singleAxisModel.componentIndex];
                        autoAxisIndex = false;
                    }
                });
            }
        }

        if (autoAxisIndex) {
            // Find the first category axis as default. (consider polar)
            eachAxisDim(function (dimNames) {
                if (!autoAxisIndex) {
                    return;
                }
                var axisIndices = [];
                var axisModels = this.dependentModels[dimNames.axis];
                if (axisModels.length && !axisIndices.length) {
                    for (var i = 0, len = axisModels.length; i < len; i++) {
                        if (axisModels[i].get('type') === 'category') {
                            axisIndices.push(i);
                        }
                    }
                }
                thisOption[dimNames.axisIndex] = axisIndices;
                if (axisIndices.length) {
                    autoAxisIndex = false;
                }
            }, this);
        }

        if (autoAxisIndex) {
            // FIXME
            // 这里是兼容ec2的写法（没指定xAxisIndex和yAxisIndex时把scatter和双数值轴折柱纳入dataZoom控制），
            // 但是实际是否需要Grid.js#getScaleByOption来判断（考虑time，log等axis type）？

            // If both dataZoom.xAxisIndex and dataZoom.yAxisIndex is not specified,
            // dataZoom component auto adopts series that reference to
            // both xAxis and yAxis which type is 'value'.
            this.ecModel.eachSeries(function (seriesModel) {
                if (this._isSeriesHasAllAxesTypeOf(seriesModel, 'value')) {
                    eachAxisDim(function (dimNames) {
                        var axisIndices = thisOption[dimNames.axisIndex];

                        var axisIndex = seriesModel.get(dimNames.axisIndex);
                        var axisId = seriesModel.get(dimNames.axisId);

                        var axisModel = seriesModel.ecModel.queryComponents({
                            mainType: dimNames.axis,
                            index: axisIndex,
                            id: axisId
                        })[0];

                        if (__DEV__) {
                            if (!axisModel) {
                                throw new Error(
                                    dimNames.axis + ' "' + retrieve(
                                        axisIndex,
                                        axisId,
                                        0
                                    ) + '" not found'
                                );
                            }
                        }
                        axisIndex = axisModel.componentIndex;

                        if (indexOf(axisIndices, axisIndex) < 0) {
                            axisIndices.push(axisIndex);
                        }
                    });
                }
            }, this);
        }
    },

    /**
     * @private
     */
    _autoSetOrient: function () {
        var dim;

        // Find the first axis
        this.eachTargetAxis(function (dimNames) {
            !dim && (dim = dimNames.name);
        }, this);

        this.option.orient = dim === 'y' ? 'vertical' : 'horizontal';
    },

    /**
     * @private
     */
    _isSeriesHasAllAxesTypeOf: function (seriesModel, axisType) {
        // FIXME
        // 需要series的xAxisIndex和yAxisIndex都首先自动设置上。
        // 例如series.type === scatter时。

        var is = true;
        eachAxisDim(function (dimNames) {
            var seriesAxisIndex = seriesModel.get(dimNames.axisIndex);
            var axisModel = this.dependentModels[dimNames.axis][seriesAxisIndex];

            if (!axisModel || axisModel.get('type') !== axisType) {
                is = false;
            }
        }, this);
        return is;
    },

    /**
     * @private
     */
    _setDefaultThrottle: function (inputRawOption) {
        // When first time user set throttle, auto throttle ends.
        if (inputRawOption.hasOwnProperty('throttle')) {
            this._autoThrottle = false;
        }
        if (this._autoThrottle) {
            var globalOption = this.ecModel.option;
            this.option.throttle = (
                globalOption.animation && globalOption.animationDurationUpdate > 0
            ) ? 100 : 20;
        }
    },

    /**
     * @public
     */
    getFirstTargetAxisModel: function () {
        var firstAxisModel;
        eachAxisDim(function (dimNames) {
            if (firstAxisModel == null) {
                var indices = this.get(dimNames.axisIndex);
                if (indices.length) {
                    firstAxisModel = this.dependentModels[dimNames.axis][indices[0]];
                }
            }
        }, this);

        return firstAxisModel;
    },

    /**
     * @public
     * @param {Function} callback param: axisModel, dimNames, axisIndex, dataZoomModel, ecModel
     */
    eachTargetAxis: function (callback, context) {
        var ecModel = this.ecModel;
        eachAxisDim(function (dimNames) {
            each$12(
                this.get(dimNames.axisIndex),
                function (axisIndex) {
                    callback.call(context, dimNames, axisIndex, this, ecModel);
                },
                this
            );
        }, this);
    },

    /**
     * @param {string} dimName
     * @param {number} axisIndex
     * @return {module:echarts/component/dataZoom/AxisProxy} If not found, return null/undefined.
     */
    getAxisProxy: function (dimName, axisIndex) {
        return this._axisProxies[dimName + '_' + axisIndex];
    },

    /**
     * @param {string} dimName
     * @param {number} axisIndex
     * @return {module:echarts/model/Model} If not found, return null/undefined.
     */
    getAxisModel: function (dimName, axisIndex) {
        var axisProxy = this.getAxisProxy(dimName, axisIndex);
        return axisProxy && axisProxy.getAxisModel();
    },

    /**
     * If not specified, set to undefined.
     *
     * @public
     * @param {Object} opt
     * @param {number} [opt.start]
     * @param {number} [opt.end]
     * @param {number} [opt.startValue]
     * @param {number} [opt.endValue]
     */
    setRawRange: function (opt) {
        var thisOption = this.option;
        var settledOption = this.settledOption;
        each$12([['start', 'startValue'], ['end', 'endValue']], function (names) {
            // Consider the pair <start, startValue>:
            // If one has value and the other one is `null/undefined`, we both set them
            // to `settledOption`. This strategy enables the feature to clear the original
            // value in `settledOption` to `null/undefined`.
            // But if both of them are `null/undefined`, we do not set them to `settledOption`
            // and keep `settledOption` with the original value. This strategy enables users to
            // only set <end or endValue> but not set <start or startValue> when calling
            // `dispatchAction`.
            // The pair <end, endValue> is treated in the same way.
            if (opt[names[0]] != null || opt[names[1]] != null) {
                thisOption[names[0]] = settledOption[names[0]] = opt[names[0]];
                thisOption[names[1]] = settledOption[names[1]] = opt[names[1]];
            }
        }, this);

        updateRangeUse(this, opt);
    },

    /**
     * @public
     * @param {Object} opt
     * @param {number} [opt.start]
     * @param {number} [opt.end]
     * @param {number} [opt.startValue]
     * @param {number} [opt.endValue]
     */
    setCalculatedRange: function (opt) {
        var option = this.option;
        each$12(['start', 'startValue', 'end', 'endValue'], function (name) {
            option[name] = opt[name];
        });
    },

    /**
     * @public
     * @return {Array.<number>} [startPercent, endPercent]
     */
    getPercentRange: function () {
        var axisProxy = this.findRepresentativeAxisProxy();
        if (axisProxy) {
            return axisProxy.getDataPercentWindow();
        }
    },

    /**
     * @public
     * For example, chart.getModel().getComponent('dataZoom').getValueRange('y', 0);
     *
     * @param {string} [axisDimName]
     * @param {number} [axisIndex]
     * @return {Array.<number>} [startValue, endValue] value can only be '-' or finite number.
     */
    getValueRange: function (axisDimName, axisIndex) {
        if (axisDimName == null && axisIndex == null) {
            var axisProxy = this.findRepresentativeAxisProxy();
            if (axisProxy) {
                return axisProxy.getDataValueWindow();
            }
        }
        else {
            return this.getAxisProxy(axisDimName, axisIndex).getDataValueWindow();
        }
    },

    /**
     * @public
     * @param {module:echarts/model/Model} [axisModel] If axisModel given, find axisProxy
     *      corresponding to the axisModel
     * @return {module:echarts/component/dataZoom/AxisProxy}
     */
    findRepresentativeAxisProxy: function (axisModel) {
        if (axisModel) {
            return axisModel.__dzAxisProxy;
        }

        // Find the first hosted axisProxy
        var axisProxies = this._axisProxies;
        for (var key in axisProxies) {
            if (axisProxies.hasOwnProperty(key) && axisProxies[key].hostedBy(this)) {
                return axisProxies[key];
            }
        }

        // If no hosted axis find not hosted axisProxy.
        // Consider this case: dataZoomModel1 and dataZoomModel2 control the same axis,
        // and the option.start or option.end settings are different. The percentRange
        // should follow axisProxy.
        // (We encounter this problem in toolbox data zoom.)
        for (var key in axisProxies) {
            if (axisProxies.hasOwnProperty(key) && !axisProxies[key].hostedBy(this)) {
                return axisProxies[key];
            }
        }
    },

    /**
     * @return {Array.<string>}
     */
    getRangePropMode: function () {
        return this._rangePropMode.slice();
    }

});

/**
 * Retrieve the those raw params from option, which will be cached separately.
 * becasue they will be overwritten by normalized/calculated values in the main
 * process.
 */
function retrieveRawOption(option) {
    var ret = {};
    each$12(
        ['start', 'end', 'startValue', 'endValue', 'throttle'],
        function (name) {
            option.hasOwnProperty(name) && (ret[name] = option[name]);
        }
    );
    return ret;
}

function updateRangeUse(dataZoomModel, inputRawOption) {
    var rangePropMode = dataZoomModel._rangePropMode;
    var rangeModeInOption = dataZoomModel.get('rangeMode');

    each$12([['start', 'startValue'], ['end', 'endValue']], function (names, index) {
        var percentSpecified = inputRawOption[names[0]] != null;
        var valueSpecified = inputRawOption[names[1]] != null;
        if (percentSpecified && !valueSpecified) {
            rangePropMode[index] = 'percent';
        }
        else if (!percentSpecified && valueSpecified) {
            rangePropMode[index] = 'value';
        }
        else if (rangeModeInOption) {
            rangePropMode[index] = rangeModeInOption[index];
        }
        else if (percentSpecified) { // percentSpecified && valueSpecified
            rangePropMode[index] = 'percent';
        }
        // else remain its original setting.
    });
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var DataZoomView = Component$1.extend({

    type: 'dataZoom',

    render: function (dataZoomModel, ecModel, api, payload) {
        this.dataZoomModel = dataZoomModel;
        this.ecModel = ecModel;
        this.api = api;
    },

    /**
     * Find the first target coordinate system.
     *
     * @protected
     * @return {Object} {
     *                   grid: [
     *                       {model: coord0, axisModels: [axis1, axis3], coordIndex: 1},
     *                       {model: coord1, axisModels: [axis0, axis2], coordIndex: 0},
     *                       ...
     *                   ],  // cartesians must not be null/undefined.
     *                   polar: [
     *                       {model: coord0, axisModels: [axis4], coordIndex: 0},
     *                       ...
     *                   ],  // polars must not be null/undefined.
     *                   singleAxis: [
     *                       {model: coord0, axisModels: [], coordIndex: 0}
     *                   ]
     */
    getTargetCoordInfo: function () {
        var dataZoomModel = this.dataZoomModel;
        var ecModel = this.ecModel;
        var coordSysLists = {};

        dataZoomModel.eachTargetAxis(function (dimNames, axisIndex) {
            var axisModel = ecModel.getComponent(dimNames.axis, axisIndex);
            if (axisModel) {
                var coordModel = axisModel.getCoordSysModel();
                coordModel && save(
                    coordModel,
                    axisModel,
                    coordSysLists[coordModel.mainType] || (coordSysLists[coordModel.mainType] = []),
                    coordModel.componentIndex
                );
            }
        }, this);

        function save(coordModel, axisModel, store, coordIndex) {
            var item;
            for (var i = 0; i < store.length; i++) {
                if (store[i].model === coordModel) {
                    item = store[i];
                    break;
                }
            }
            if (!item) {
                store.push(item = {
                    model: coordModel, axisModels: [], coordIndex: coordIndex
                });
            }
            item.axisModels.push(axisModel);
        }

        return coordSysLists;
    }

});

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var SliderZoomModel = DataZoomModel.extend({

    type: 'dataZoom.slider',

    layoutMode: 'box',

    /**
     * @protected
     */
    defaultOption: {
        show: true,

        // ph => placeholder. Using placehoder here because
        // deault value can only be drived in view stage.
        right: 'ph',  // Default align to grid rect.
        top: 'ph',    // Default align to grid rect.
        width: 'ph',  // Default align to grid rect.
        height: 'ph', // Default align to grid rect.
        left: null,   // Default align to grid rect.
        bottom: null, // Default align to grid rect.

        backgroundColor: 'rgba(47,69,84,0)',    // Background of slider zoom component.
        // dataBackgroundColor: '#ddd',         // Background coor of data shadow and border of box,
                                                // highest priority, remain for compatibility of
                                                // previous version, but not recommended any more.
        dataBackground: {
            lineStyle: {
                color: '#2f4554',
                width: 0.5,
                opacity: 0.3
            },
            areaStyle: {
                color: 'rgba(47,69,84,0.3)',
                opacity: 0.3
            }
        },
        borderColor: '#ddd',                    // border color of the box. For compatibility,
                                                // if dataBackgroundColor is set, borderColor
                                                // is ignored.

        fillerColor: 'rgba(167,183,204,0.4)',     // Color of selected area.
        // handleColor: 'rgba(89,170,216,0.95)',     // Color of handle.
        // handleIcon: 'path://M4.9,17.8c0-1.4,4.5-10.5,5.5-12.4c0-0.1,0.6-1.1,0.9-1.1c0.4,0,0.9,1,0.9,1.1c1.1,2.2,5.4,11,5.4,12.4v17.8c0,1.5-0.6,2.1-1.3,2.1H6.1c-0.7,0-1.3-0.6-1.3-2.1V17.8z',
        /* eslint-disable */
        handleIcon: 'M8.2,13.6V3.9H6.3v9.7H3.1v14.9h3.3v9.7h1.8v-9.7h3.3V13.6H8.2z M9.7,24.4H4.8v-1.4h4.9V24.4z M9.7,19.1H4.8v-1.4h4.9V19.1z',
        /* eslint-enable */
        // Percent of the slider height
        handleSize: '100%',

        handleStyle: {
            color: '#a7b7cc'
        },

        labelPrecision: null,
        labelFormatter: null,
        showDetail: true,
        showDataShadow: 'auto',                 // Default auto decision.
        realtime: true,
        zoomLock: false,                        // Whether disable zoom.
        textStyle: {
            color: '#333'
        }
    }

});

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var Rect$1 = Rect;
var linearMap$1 = linearMap;
var asc$2 = asc;
var bind$3 = bind;
var each$14 = each$1;

// Constants
var DEFAULT_LOCATION_EDGE_GAP = 7;
var DEFAULT_FRAME_BORDER_WIDTH = 1;
var DEFAULT_FILLER_SIZE = 30;
var HORIZONTAL = 'horizontal';
var VERTICAL = 'vertical';
var LABEL_GAP = 5;
var SHOW_DATA_SHADOW_SERIES_TYPE = ['line', 'bar', 'candlestick', 'scatter'];

var SliderZoomView = DataZoomView.extend({

    type: 'dataZoom.slider',

    init: function (ecModel, api) {

        /**
         * @private
         * @type {Object}
         */
        this._displayables = {};

        /**
         * @private
         * @type {string}
         */
        this._orient;

        /**
         * [0, 100]
         * @private
         */
        this._range;

        /**
         * [coord of the first handle, coord of the second handle]
         * @private
         */
        this._handleEnds;

        /**
         * [length, thick]
         * @private
         * @type {Array.<number>}
         */
        this._size;

        /**
         * @private
         * @type {number}
         */
        this._handleWidth;

        /**
         * @private
         * @type {number}
         */
        this._handleHeight;

        /**
         * @private
         */
        this._location;

        /**
         * @private
         */
        this._dragging;

        /**
         * @private
         */
        this._dataShadowInfo;

        this.api = api;
    },

    /**
     * @override
     */
    render: function (dataZoomModel, ecModel, api, payload) {
        SliderZoomView.superApply(this, 'render', arguments);

        createOrUpdate(
            this,
            '_dispatchZoomAction',
            this.dataZoomModel.get('throttle'),
            'fixRate'
        );

        this._orient = dataZoomModel.get('orient');

        if (this.dataZoomModel.get('show') === false) {
            this.group.removeAll();
            return;
        }

        // Notice: this._resetInterval() should not be executed when payload.type
        // is 'dataZoom', origin this._range should be maintained, otherwise 'pan'
        // or 'zoom' info will be missed because of 'throttle' of this.dispatchAction,
        if (!payload || payload.type !== 'dataZoom' || payload.from !== this.uid) {
            this._buildView();
        }

        this._updateView();
    },

    /**
     * @override
     */
    remove: function () {
        SliderZoomView.superApply(this, 'remove', arguments);
        clear(this, '_dispatchZoomAction');
    },

    /**
     * @override
     */
    dispose: function () {
        SliderZoomView.superApply(this, 'dispose', arguments);
        clear(this, '_dispatchZoomAction');
    },

    _buildView: function () {
        var thisGroup = this.group;

        thisGroup.removeAll();

        this._resetLocation();
        this._resetInterval();

        var barGroup = this._displayables.barGroup = new Group();

        this._renderBackground();

        this._renderHandle();

        this._renderDataShadow();

        thisGroup.add(barGroup);

        this._positionGroup();
    },

    /**
     * @private
     */
    _resetLocation: function () {
        var dataZoomModel = this.dataZoomModel;
        var api = this.api;

        // If some of x/y/width/height are not specified,
        // auto-adapt according to target grid.
        var coordRect = this._findCoordRect();
        var ecSize = {width: api.getWidth(), height: api.getHeight()};
        // Default align by coordinate system rect.
        var positionInfo = this._orient === HORIZONTAL
            ? {
                // Why using 'right', because right should be used in vertical,
                // and it is better to be consistent for dealing with position param merge.
                right: ecSize.width - coordRect.x - coordRect.width,
                top: (ecSize.height - DEFAULT_FILLER_SIZE - DEFAULT_LOCATION_EDGE_GAP),
                width: coordRect.width,
                height: DEFAULT_FILLER_SIZE
            }
            : { // vertical
                right: DEFAULT_LOCATION_EDGE_GAP,
                top: coordRect.y,
                width: DEFAULT_FILLER_SIZE,
                height: coordRect.height
            };

        // Do not write back to option and replace value 'ph', because
        // the 'ph' value should be recalculated when resize.
        var layoutParams = getLayoutParams(dataZoomModel.option);

        // Replace the placeholder value.
        each$1(['right', 'top', 'width', 'height'], function (name) {
            if (layoutParams[name] === 'ph') {
                layoutParams[name] = positionInfo[name];
            }
        });

        var layoutRect = getLayoutRect(
            layoutParams,
            ecSize,
            dataZoomModel.padding
        );

        this._location = {x: layoutRect.x, y: layoutRect.y};
        this._size = [layoutRect.width, layoutRect.height];
        this._orient === VERTICAL && this._size.reverse();
    },

    /**
     * @private
     */
    _positionGroup: function () {
        var thisGroup = this.group;
        var location = this._location;
        var orient = this._orient;

        // Just use the first axis to determine mapping.
        var targetAxisModel = this.dataZoomModel.getFirstTargetAxisModel();
        var inverse = targetAxisModel && targetAxisModel.get('inverse');

        var barGroup = this._displayables.barGroup;
        var otherAxisInverse = (this._dataShadowInfo || {}).otherAxisInverse;

        // Transform barGroup.
        barGroup.attr(
            (orient === HORIZONTAL && !inverse)
            ? {scale: otherAxisInverse ? [1, 1] : [1, -1]}
            : (orient === HORIZONTAL && inverse)
            ? {scale: otherAxisInverse ? [-1, 1] : [-1, -1]}
            : (orient === VERTICAL && !inverse)
            ? {scale: otherAxisInverse ? [1, -1] : [1, 1], rotation: Math.PI / 2}
            // Dont use Math.PI, considering shadow direction.
            : {scale: otherAxisInverse ? [-1, -1] : [-1, 1], rotation: Math.PI / 2}
        );

        // Position barGroup
        var rect = thisGroup.getBoundingRect([barGroup]);
        thisGroup.attr('position', [location.x - rect.x, location.y - rect.y]);
    },

    /**
     * @private
     */
    _getViewExtent: function () {
        return [0, this._size[0]];
    },

    _renderBackground: function () {
        var dataZoomModel = this.dataZoomModel;
        var size = this._size;
        var barGroup = this._displayables.barGroup;

        barGroup.add(new Rect$1({
            silent: true,
            shape: {
                x: 0, y: 0, width: size[0], height: size[1]
            },
            style: {
                fill: dataZoomModel.get('backgroundColor')
            },
            z2: -40
        }));

        // Click panel, over shadow, below handles.
        barGroup.add(new Rect$1({
            shape: {
                x: 0, y: 0, width: size[0], height: size[1]
            },
            style: {
                fill: 'transparent'
            },
            z2: 0,
            onclick: bind(this._onClickPanelClick, this)
        }));
    },

    _renderDataShadow: function () {
        var info = this._dataShadowInfo = this._prepareDataShadowInfo();

        if (!info) {
            return;
        }

        var size = this._size;
        var seriesModel = info.series;
        var data = seriesModel.getRawData();

        var otherDim = seriesModel.getShadowDim
            ? seriesModel.getShadowDim() // @see candlestick
            : info.otherDim;

        if (otherDim == null) {
            return;
        }

        var otherDataExtent = data.getDataExtent(otherDim);
        // Nice extent.
        var otherOffset = (otherDataExtent[1] - otherDataExtent[0]) * 0.3;
        otherDataExtent = [
            otherDataExtent[0] - otherOffset,
            otherDataExtent[1] + otherOffset
        ];
        var otherShadowExtent = [0, size[1]];

        var thisShadowExtent = [0, size[0]];

        var areaPoints = [[size[0], 0], [0, 0]];
        var linePoints = [];
        var step = thisShadowExtent[1] / (data.count() - 1);
        var thisCoord = 0;

        // Optimize for large data shadow
        var stride = Math.round(data.count() / size[0]);
        var lastIsEmpty;
        data.each([otherDim], function (value, index) {
            if (stride > 0 && (index % stride)) {
                thisCoord += step;
                return;
            }

            // FIXME
            // Should consider axis.min/axis.max when drawing dataShadow.

            // FIXME
            // 应该使用统一的空判断？还是在list里进行空判断？
            var isEmpty = value == null || isNaN(value) || value === '';
            // See #4235.
            var otherCoord = isEmpty
                ? 0 : linearMap$1(value, otherDataExtent, otherShadowExtent, true);

            // Attempt to draw data shadow precisely when there are empty value.
            if (isEmpty && !lastIsEmpty && index) {
                areaPoints.push([areaPoints[areaPoints.length - 1][0], 0]);
                linePoints.push([linePoints[linePoints.length - 1][0], 0]);
            }
            else if (!isEmpty && lastIsEmpty) {
                areaPoints.push([thisCoord, 0]);
                linePoints.push([thisCoord, 0]);
            }

            areaPoints.push([thisCoord, otherCoord]);
            linePoints.push([thisCoord, otherCoord]);

            thisCoord += step;
            lastIsEmpty = isEmpty;
        });

        var dataZoomModel = this.dataZoomModel;
        // var dataBackgroundModel = dataZoomModel.getModel('dataBackground');
        this._displayables.barGroup.add(new Polygon({
            shape: {points: areaPoints},
            style: defaults(
                {fill: dataZoomModel.get('dataBackgroundColor')},
                dataZoomModel.getModel('dataBackground.areaStyle').getAreaStyle()
            ),
            silent: true,
            z2: -20
        }));
        this._displayables.barGroup.add(new Polyline({
            shape: {points: linePoints},
            style: dataZoomModel.getModel('dataBackground.lineStyle').getLineStyle(),
            silent: true,
            z2: -19
        }));
    },

    _prepareDataShadowInfo: function () {
        var dataZoomModel = this.dataZoomModel;
        var showDataShadow = dataZoomModel.get('showDataShadow');

        if (showDataShadow === false) {
            return;
        }

        // Find a representative series.
        var result;
        var ecModel = this.ecModel;

        dataZoomModel.eachTargetAxis(function (dimNames, axisIndex) {
            var seriesModels = dataZoomModel
                .getAxisProxy(dimNames.name, axisIndex)
                .getTargetSeriesModels();

            each$1(seriesModels, function (seriesModel) {
                if (result) {
                    return;
                }

                if (showDataShadow !== true && indexOf(
                        SHOW_DATA_SHADOW_SERIES_TYPE, seriesModel.get('type')
                    ) < 0
                ) {
                    return;
                }

                var thisAxis = ecModel.getComponent(dimNames.axis, axisIndex).axis;
                var otherDim = getOtherDim(dimNames.name);
                var otherAxisInverse;
                var coordSys = seriesModel.coordinateSystem;

                if (otherDim != null && coordSys.getOtherAxis) {
                    otherAxisInverse = coordSys.getOtherAxis(thisAxis).inverse;
                }

                otherDim = seriesModel.getData().mapDimension(otherDim);

                result = {
                    thisAxis: thisAxis,
                    series: seriesModel,
                    thisDim: dimNames.name,
                    otherDim: otherDim,
                    otherAxisInverse: otherAxisInverse
                };

            }, this);

        }, this);

        return result;
    },

    _renderHandle: function () {
        var displaybles = this._displayables;
        var handles = displaybles.handles = [];
        var handleLabels = displaybles.handleLabels = [];
        var barGroup = this._displayables.barGroup;
        var size = this._size;
        var dataZoomModel = this.dataZoomModel;

        barGroup.add(displaybles.filler = new Rect$1({
            draggable: true,
            cursor: getCursor(this._orient),
            drift: bind$3(this._onDragMove, this, 'all'),
            ondragstart: bind$3(this._showDataInfo, this, true),
            ondragend: bind$3(this._onDragEnd, this),
            onmouseover: bind$3(this._showDataInfo, this, true),
            onmouseout: bind$3(this._showDataInfo, this, false),
            style: {
                fill: dataZoomModel.get('fillerColor'),
                textPosition: 'inside'
            }
        }));

        // Frame border.
        barGroup.add(new Rect$1({
            silent: true,
            subPixelOptimize: true,
            shape: {
                x: 0,
                y: 0,
                width: size[0],
                height: size[1]
            },
            style: {
                stroke: dataZoomModel.get('dataBackgroundColor')
                    || dataZoomModel.get('borderColor'),
                lineWidth: DEFAULT_FRAME_BORDER_WIDTH,
                fill: 'rgba(0,0,0,0)'
            }
        }));

        each$14([0, 1], function (handleIndex) {
            var path = createIcon(
                dataZoomModel.get('handleIcon'),
                {
                    cursor: getCursor(this._orient),
                    draggable: true,
                    drift: bind$3(this._onDragMove, this, handleIndex),
                    ondragend: bind$3(this._onDragEnd, this),
                    onmouseover: bind$3(this._showDataInfo, this, true),
                    onmouseout: bind$3(this._showDataInfo, this, false)
                },
                {x: -1, y: 0, width: 2, height: 2}
            );

            var bRect = path.getBoundingRect();
            this._handleHeight = parsePercent$1(dataZoomModel.get('handleSize'), this._size[1]);
            this._handleWidth = bRect.width / bRect.height * this._handleHeight;

            path.setStyle(dataZoomModel.getModel('handleStyle').getItemStyle());
            var handleColor = dataZoomModel.get('handleColor');
            // Compatitable with previous version
            if (handleColor != null) {
                path.style.fill = handleColor;
            }

            barGroup.add(handles[handleIndex] = path);

            var textStyleModel = dataZoomModel.textStyleModel;

            this.group.add(
                handleLabels[handleIndex] = new Text({
                silent: true,
                invisible: true,
                style: {
                    x: 0, y: 0, text: '',
                    textVerticalAlign: 'middle',
                    textAlign: 'center',
                    textFill: textStyleModel.getTextColor(),
                    textFont: textStyleModel.getFont()
                },
                z2: 10
            }));

        }, this);
    },

    /**
     * @private
     */
    _resetInterval: function () {
        var range = this._range = this.dataZoomModel.getPercentRange();
        var viewExtent = this._getViewExtent();

        this._handleEnds = [
            linearMap$1(range[0], [0, 100], viewExtent, true),
            linearMap$1(range[1], [0, 100], viewExtent, true)
        ];
    },

    /**
     * @private
     * @param {(number|string)} handleIndex 0 or 1 or 'all'
     * @param {number} delta
     * @return {boolean} changed
     */
    _updateInterval: function (handleIndex, delta) {
        var dataZoomModel = this.dataZoomModel;
        var handleEnds = this._handleEnds;
        var viewExtend = this._getViewExtent();
        var minMaxSpan = dataZoomModel.findRepresentativeAxisProxy().getMinMaxSpan();
        var percentExtent = [0, 100];

        sliderMove(
            delta,
            handleEnds,
            viewExtend,
            dataZoomModel.get('zoomLock') ? 'all' : handleIndex,
            minMaxSpan.minSpan != null
                ? linearMap$1(minMaxSpan.minSpan, percentExtent, viewExtend, true) : null,
            minMaxSpan.maxSpan != null
                ? linearMap$1(minMaxSpan.maxSpan, percentExtent, viewExtend, true) : null
        );

        var lastRange = this._range;
        var range = this._range = asc$2([
            linearMap$1(handleEnds[0], viewExtend, percentExtent, true),
            linearMap$1(handleEnds[1], viewExtend, percentExtent, true)
        ]);

        return !lastRange || lastRange[0] !== range[0] || lastRange[1] !== range[1];
    },

    /**
     * @private
     */
    _updateView: function (nonRealtime) {
        var displaybles = this._displayables;
        var handleEnds = this._handleEnds;
        var handleInterval = asc$2(handleEnds.slice());
        var size = this._size;

        each$14([0, 1], function (handleIndex) {
            // Handles
            var handle = displaybles.handles[handleIndex];
            var handleHeight = this._handleHeight;
            handle.attr({
                scale: [handleHeight / 2, handleHeight / 2],
                position: [handleEnds[handleIndex], size[1] / 2 - handleHeight / 2]
            });
        }, this);

        // Filler
        displaybles.filler.setShape({
            x: handleInterval[0],
            y: 0,
            width: handleInterval[1] - handleInterval[0],
            height: size[1]
        });

        this._updateDataInfo(nonRealtime);
    },

    /**
     * @private
     */
    _updateDataInfo: function (nonRealtime) {
        var dataZoomModel = this.dataZoomModel;
        var displaybles = this._displayables;
        var handleLabels = displaybles.handleLabels;
        var orient = this._orient;
        var labelTexts = ['', ''];

        // FIXME
        // date型，支持formatter，autoformatter（ec2 date.getAutoFormatter）
        if (dataZoomModel.get('showDetail')) {
            var axisProxy = dataZoomModel.findRepresentativeAxisProxy();

            if (axisProxy) {
                var axis = axisProxy.getAxisModel().axis;
                var range = this._range;

                var dataInterval = nonRealtime
                    // See #4434, data and axis are not processed and reset yet in non-realtime mode.
                    ? axisProxy.calculateDataWindow({
                        start: range[0], end: range[1]
                    }).valueWindow
                    : axisProxy.getDataValueWindow();

                labelTexts = [
                    this._formatLabel(dataInterval[0], axis),
                    this._formatLabel(dataInterval[1], axis)
                ];
            }
        }

        var orderedHandleEnds = asc$2(this._handleEnds.slice());

        setLabel.call(this, 0);
        setLabel.call(this, 1);

        function setLabel(handleIndex) {
            // Label
            // Text should not transform by barGroup.
            // Ignore handlers transform
            var barTransform = getTransform(
                displaybles.handles[handleIndex].parent, this.group
            );
            var direction = transformDirection(
                handleIndex === 0 ? 'right' : 'left', barTransform
            );
            var offset = this._handleWidth / 2 + LABEL_GAP;
            var textPoint = applyTransform$1(
                [
                    orderedHandleEnds[handleIndex] + (handleIndex === 0 ? -offset : offset),
                    this._size[1] / 2
                ],
                barTransform
            );
            handleLabels[handleIndex].setStyle({
                x: textPoint[0],
                y: textPoint[1],
                textVerticalAlign: orient === HORIZONTAL ? 'middle' : direction,
                textAlign: orient === HORIZONTAL ? direction : 'center',
                text: labelTexts[handleIndex]
            });
        }
    },

    /**
     * @private
     */
    _formatLabel: function (value, axis) {
        var dataZoomModel = this.dataZoomModel;
        var labelFormatter = dataZoomModel.get('labelFormatter');

        var labelPrecision = dataZoomModel.get('labelPrecision');
        if (labelPrecision == null || labelPrecision === 'auto') {
            labelPrecision = axis.getPixelPrecision();
        }

        var valueStr = (value == null || isNaN(value))
            ? ''
            // FIXME Glue code
            : (axis.type === 'category' || axis.type === 'time')
                ? axis.scale.getLabel(Math.round(value))
                // param of toFixed should less then 20.
                : value.toFixed(Math.min(labelPrecision, 20));

        return isFunction$1(labelFormatter)
            ? labelFormatter(value, valueStr)
            : isString(labelFormatter)
            ? labelFormatter.replace('{value}', valueStr)
            : valueStr;
    },

    /**
     * @private
     * @param {boolean} showOrHide true: show, false: hide
     */
    _showDataInfo: function (showOrHide) {
        // Always show when drgging.
        showOrHide = this._dragging || showOrHide;

        var handleLabels = this._displayables.handleLabels;
        handleLabels[0].attr('invisible', !showOrHide);
        handleLabels[1].attr('invisible', !showOrHide);
    },

    _onDragMove: function (handleIndex, dx, dy, event) {
        this._dragging = true;

        // For mobile device, prevent screen slider on the button.
        stop(event.event);

        // Transform dx, dy to bar coordination.
        var barTransform = this._displayables.barGroup.getLocalTransform();
        var vertex = applyTransform$1([dx, dy], barTransform, true);

        var changed = this._updateInterval(handleIndex, vertex[0]);

        var realtime = this.dataZoomModel.get('realtime');

        this._updateView(!realtime);

        // Avoid dispatch dataZoom repeatly but range not changed,
        // which cause bad visual effect when progressive enabled.
        changed && realtime && this._dispatchZoomAction();
    },

    _onDragEnd: function () {
        this._dragging = false;
        this._showDataInfo(false);

        // While in realtime mode and stream mode, dispatch action when
        // drag end will cause the whole view rerender, which is unnecessary.
        var realtime = this.dataZoomModel.get('realtime');
        !realtime && this._dispatchZoomAction();
    },

    _onClickPanelClick: function (e) {
        var size = this._size;
        var localPoint = this._displayables.barGroup.transformCoordToLocal(e.offsetX, e.offsetY);

        if (localPoint[0] < 0 || localPoint[0] > size[0]
            || localPoint[1] < 0 || localPoint[1] > size[1]
        ) {
            return;
        }

        var handleEnds = this._handleEnds;
        var center = (handleEnds[0] + handleEnds[1]) / 2;

        var changed = this._updateInterval('all', localPoint[0] - center);
        this._updateView();
        changed && this._dispatchZoomAction();
    },

    /**
     * This action will be throttled.
     * @private
     */
    _dispatchZoomAction: function () {
        var range = this._range;

        this.api.dispatchAction({
            type: 'dataZoom',
            from: this.uid,
            dataZoomId: this.dataZoomModel.id,
            start: range[0],
            end: range[1]
        });
    },

    /**
     * @private
     */
    _findCoordRect: function () {
        // Find the grid coresponding to the first axis referred by dataZoom.
        var rect;
        each$14(this.getTargetCoordInfo(), function (coordInfoList) {
            if (!rect && coordInfoList.length) {
                var coordSys = coordInfoList[0].model.coordinateSystem;
                rect = coordSys.getRect && coordSys.getRect();
            }
        });
        if (!rect) {
            var width = this.api.getWidth();
            var height = this.api.getHeight();
            rect = {
                x: width * 0.2,
                y: height * 0.2,
                width: width * 0.6,
                height: height * 0.6
            };
        }

        return rect;
    }

});

function getOtherDim(thisDim) {
    // FIXME
    // 这个逻辑和getOtherAxis里一致，但是写在这里是否不好
    var map$$1 = {x: 'y', y: 'x', radius: 'angle', angle: 'radius'};
    return map$$1[thisDim];
}

function getCursor(orient) {
    return orient === 'vertical' ? 'ns-resize' : 'ew-resize';
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

registerProcessor({

    // `dataZoomProcessor` will only be performed in needed series. Consider if
    // there is a line series and a pie series, it is better not to update the
    // line series if only pie series is needed to be updated.
    getTargetSeries: function (ecModel) {
        var seriesModelMap = createHashMap();

        ecModel.eachComponent('dataZoom', function (dataZoomModel) {
            dataZoomModel.eachTargetAxis(function (dimNames, axisIndex, dataZoomModel) {
                var axisProxy = dataZoomModel.getAxisProxy(dimNames.name, axisIndex);
                each$1(axisProxy.getTargetSeriesModels(), function (seriesModel) {
                    seriesModelMap.set(seriesModel.uid, seriesModel);
                });
            });
        });

        return seriesModelMap;
    },

    modifyOutputEnd: true,

    // Consider appendData, where filter should be performed. Because data process is
    // in block mode currently, it is not need to worry about that the overallProgress
    // execute every frame.
    overallReset: function (ecModel, api) {

        ecModel.eachComponent('dataZoom', function (dataZoomModel) {
            // We calculate window and reset axis here but not in model
            // init stage and not after action dispatch handler, because
            // reset should be called after seriesData.restoreData.
            dataZoomModel.eachTargetAxis(function (dimNames, axisIndex, dataZoomModel) {
                dataZoomModel.getAxisProxy(dimNames.name, axisIndex).reset(dataZoomModel, api);
            });

            // Caution: data zoom filtering is order sensitive when using
            // percent range and no min/max/scale set on axis.
            // For example, we have dataZoom definition:
            // [
            //      {xAxisIndex: 0, start: 30, end: 70},
            //      {yAxisIndex: 0, start: 20, end: 80}
            // ]
            // In this case, [20, 80] of y-dataZoom should be based on data
            // that have filtered by x-dataZoom using range of [30, 70],
            // but should not be based on full raw data. Thus sliding
            // x-dataZoom will change both ranges of xAxis and yAxis,
            // while sliding y-dataZoom will only change the range of yAxis.
            // So we should filter x-axis after reset x-axis immediately,
            // and then reset y-axis and filter y-axis.
            dataZoomModel.eachTargetAxis(function (dimNames, axisIndex, dataZoomModel) {
                dataZoomModel.getAxisProxy(dimNames.name, axisIndex).filterData(dataZoomModel, api);
            });
        });

        ecModel.eachComponent('dataZoom', function (dataZoomModel) {
            // Fullfill all of the range props so that user
            // is able to get them from chart.getOption().
            var axisProxy = dataZoomModel.findRepresentativeAxisProxy();
            var percentRange = axisProxy.getDataPercentWindow();
            var valueRange = axisProxy.getDataValueWindow();

            dataZoomModel.setCalculatedRange({
                start: percentRange[0],
                end: percentRange[1],
                startValue: valueRange[0],
                endValue: valueRange[1]
            });
        });
    }
});

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

registerAction('dataZoom', function (payload, ecModel) {

    var linkedNodesFinder = createLinkedNodesFinder(
        bind(ecModel.eachComponent, ecModel, 'dataZoom'),
        eachAxisDim$1,
        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
            );
        }
    );

    each$1(effectedModels, function (dataZoomModel, index) {
        dataZoomModel.setRawRange({
            start: payload.start,
            end: payload.end,
            startValue: payload.startValue,
            endValue: payload.endValue
        });
    });

});

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

DataZoomModel.extend({

    type: 'dataZoom.inside',

    /**
     * @protected
     */
    defaultOption: {
        disabled: false,   // Whether disable this inside zoom.
        zoomLock: false,   // Whether disable zoom but only pan.
        zoomOnMouseWheel: true, // Can be: true / false / 'shift' / 'ctrl' / 'alt'.
        moveOnMouseMove: true,   // Can be: true / false / 'shift' / 'ctrl' / 'alt'.
        moveOnMouseWheel: false, // Can be: true / false / 'shift' / 'ctrl' / 'alt'.
        preventDefaultMouseMove: true
    }
});

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var ATTR$1 = '\0_ec_interaction_mutex';

function take(zr, resourceKey, userKey) {
    var store = getStore(zr);
    store[resourceKey] = userKey;
}

function release(zr, resourceKey, userKey) {
    var store = getStore(zr);
    var uKey = store[resourceKey];

    if (uKey === userKey) {
        store[resourceKey] = null;
    }
}

function isTaken(zr, resourceKey) {
    return !!getStore(zr)[resourceKey];
}

function getStore(zr) {
    return zr[ATTR$1] || (zr[ATTR$1] = {});
}

/**
 * payload: {
 *     type: 'takeGlobalCursor',
 *     key: 'dataZoomSelect', or 'brush', or ...,
 *         If no userKey, release global cursor.
 * }
 */
registerAction(
    {type: 'takeGlobalCursor', event: 'globalCursorTaken', update: 'update'},
    function () {}
);

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * @alias module:echarts/component/helper/RoamController
 * @constructor
 * @mixin {module:zrender/mixin/Eventful}
 *
 * @param {module:zrender/zrender~ZRender} zr
 */
function RoamController(zr) {

    /**
     * @type {Function}
     */
    this.pointerChecker;

    /**
     * @type {module:zrender}
     */
    this._zr = zr;

    /**
     * @type {Object}
     */
    this._opt = {};

    // Avoid two roamController bind the same handler
    var bind$$1 = bind;
    var mousedownHandler = bind$$1(mousedown, this);
    var mousemoveHandler = bind$$1(mousemove, this);
    var mouseupHandler = bind$$1(mouseup, this);
    var mousewheelHandler = bind$$1(mousewheel, this);
    var pinchHandler = bind$$1(pinch, this);

    Eventful.call(this);

    /**
     * @param {Function} pointerChecker
     *                   input: x, y
     *                   output: boolean
     */
    this.setPointerChecker = function (pointerChecker) {
        this.pointerChecker = pointerChecker;
    };

    /**
     * Notice: only enable needed types. For example, if 'zoom'
     * is not needed, 'zoom' should not be enabled, otherwise
     * default mousewheel behaviour (scroll page) will be disabled.
     *
     * @param  {boolean|string} [controlType=true] Specify the control type,
     *                          which can be null/undefined or true/false
     *                          or 'pan/move' or 'zoom'/'scale'
     * @param {Object} [opt]
     * @param {Object} [opt.zoomOnMouseWheel=true] The value can be: true / false / 'shift' / 'ctrl' / 'alt'.
     * @param {Object} [opt.moveOnMouseMove=true] The value can be: true / false / 'shift' / 'ctrl' / 'alt'.
     * @param {Object} [opt.moveOnMouseWheel=false] The value can be: true / false / 'shift' / 'ctrl' / 'alt'.
     * @param {Object} [opt.preventDefaultMouseMove=true] When pan.
     */
    this.enable = function (controlType, opt) {

        // Disable previous first
        this.disable();

        this._opt = defaults(clone(opt) || {}, {
            zoomOnMouseWheel: true,
            moveOnMouseMove: true,
            // By default, wheel do not trigger move.
            moveOnMouseWheel: false,
            preventDefaultMouseMove: true
        });

        if (controlType == null) {
            controlType = true;
        }

        if (controlType === true || (controlType === 'move' || controlType === 'pan')) {
            zr.on('mousedown', mousedownHandler);
            zr.on('mousemove', mousemoveHandler);
            zr.on('mouseup', mouseupHandler);
        }
        if (controlType === true || (controlType === 'scale' || controlType === 'zoom')) {
            zr.on('mousewheel', mousewheelHandler);
            zr.on('pinch', pinchHandler);
        }
    };

    this.disable = function () {
        zr.off('mousedown', mousedownHandler);
        zr.off('mousemove', mousemoveHandler);
        zr.off('mouseup', mouseupHandler);
        zr.off('mousewheel', mousewheelHandler);
        zr.off('pinch', pinchHandler);
    };

    this.dispose = this.disable;

    this.isDragging = function () {
        return this._dragging;
    };

    this.isPinching = function () {
        return this._pinching;
    };
}

mixin(RoamController, Eventful);


function mousedown(e) {
    if (isMiddleOrRightButtonOnMouseUpDown(e)
        || (e.target && e.target.draggable)
    ) {
        return;
    }

    var x = e.offsetX;
    var y = e.offsetY;

    // Only check on mosedown, but not mousemove.
    // Mouse can be out of target when mouse moving.
    if (this.pointerChecker && this.pointerChecker(e, x, y)) {
        this._x = x;
        this._y = y;
        this._dragging = true;
    }
}

function mousemove(e) {
    if (!this._dragging
        || !isAvailableBehavior('moveOnMouseMove', e, this._opt)
        || e.gestureEvent === 'pinch'
        || isTaken(this._zr, 'globalPan')
    ) {
        return;
    }

    var x = e.offsetX;
    var y = e.offsetY;

    var oldX = this._x;
    var oldY = this._y;

    var dx = x - oldX;
    var dy = y - oldY;

    this._x = x;
    this._y = y;

    this._opt.preventDefaultMouseMove && stop(e.event);

    trigger(this, 'pan', 'moveOnMouseMove', e, {
        dx: dx, dy: dy, oldX: oldX, oldY: oldY, newX: x, newY: y
    });
}

function mouseup(e) {
    if (!isMiddleOrRightButtonOnMouseUpDown(e)) {
        this._dragging = false;
    }
}

function mousewheel(e) {
    var shouldZoom = isAvailableBehavior('zoomOnMouseWheel', e, this._opt);
    var shouldMove = isAvailableBehavior('moveOnMouseWheel', e, this._opt);
    var wheelDelta = e.wheelDelta;
    var absWheelDeltaDelta = Math.abs(wheelDelta);
    var originX = e.offsetX;
    var originY = e.offsetY;

    // wheelDelta maybe -0 in chrome mac.
    if (wheelDelta === 0 || (!shouldZoom && !shouldMove)) {
        return;
    }

    // If both `shouldZoom` and `shouldMove` is true, trigger
    // their event both, and the final behavior is determined
    // by event listener themselves.

    if (shouldZoom) {
        // Convenience:
        // Mac and VM Windows on Mac: scroll up: zoom out.
        // Windows: scroll up: zoom in.

        // FIXME: Should do more test in different environment.
        // wheelDelta is too complicated in difference nvironment
        // (https://developer.mozilla.org/en-US/docs/Web/Events/mousewheel),
        // although it has been normallized by zrender.
        // wheelDelta of mouse wheel is bigger than touch pad.
        var factor = absWheelDeltaDelta > 3 ? 1.4 : absWheelDeltaDelta > 1 ? 1.2 : 1.1;
        var scale = wheelDelta > 0 ? factor : 1 / factor;
        checkPointerAndTrigger(this, 'zoom', 'zoomOnMouseWheel', e, {
            scale: scale, originX: originX, originY: originY
        });
    }

    if (shouldMove) {
        // FIXME: Should do more test in different environment.
        var absDelta = Math.abs(wheelDelta);
        // wheelDelta of mouse wheel is bigger than touch pad.
        var scrollDelta = (wheelDelta > 0 ? 1 : -1) * (absDelta > 3 ? 0.4 : absDelta > 1 ? 0.15 : 0.05);
        checkPointerAndTrigger(this, 'scrollMove', 'moveOnMouseWheel', e, {
            scrollDelta: scrollDelta, originX: originX, originY: originY
        });
    }
}

function pinch(e) {
    if (isTaken(this._zr, 'globalPan')) {
        return;
    }
    var scale = e.pinchScale > 1 ? 1.1 : 1 / 1.1;
    checkPointerAndTrigger(this, 'zoom', null, e, {
        scale: scale, originX: e.pinchX, originY: e.pinchY
    });
}

function checkPointerAndTrigger(controller, eventName, behaviorToCheck, e, contollerEvent) {
    if (controller.pointerChecker
        && controller.pointerChecker(e, contollerEvent.originX, contollerEvent.originY)
    ) {
        // When mouse is out of roamController rect,
        // default befavoius should not be be disabled, otherwise
        // page sliding is disabled, contrary to expectation.
        stop(e.event);

        trigger(controller, eventName, behaviorToCheck, e, contollerEvent);
    }
}

function trigger(controller, eventName, behaviorToCheck, e, contollerEvent) {
    // Also provide behavior checker for event listener, for some case that
    // multiple components share one listener.
    contollerEvent.isAvailableBehavior = bind(isAvailableBehavior, null, behaviorToCheck, e);
    controller.trigger(eventName, contollerEvent);
}

// settings: {
//     zoomOnMouseWheel
//     moveOnMouseMove
//     moveOnMouseWheel
// }
// The value can be: true / false / 'shift' / 'ctrl' / 'alt'.
function isAvailableBehavior(behaviorToCheck, e, settings) {
    var setting = settings[behaviorToCheck];
    return !behaviorToCheck || (
        setting && (!isString(setting) || e.event[setting + 'Key'])
    );
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

// Only create one roam controller for each coordinate system.
// one roam controller might be refered by two inside data zoom
// components (for example, one for x and one for y). When user
// pan or zoom, only dispatch one action for those data zoom
// components.

var ATTR = '\0_ec_dataZoom_roams';


/**
 * @public
 * @param {module:echarts/ExtensionAPI} api
 * @param {Object} dataZoomInfo
 * @param {string} dataZoomInfo.coordId
 * @param {Function} dataZoomInfo.containsPoint
 * @param {Array.<string>} dataZoomInfo.allCoordIds
 * @param {string} dataZoomInfo.dataZoomId
 * @param {Object} dataZoomInfo.getRange
 * @param {Function} dataZoomInfo.getRange.pan
 * @param {Function} dataZoomInfo.getRange.zoom
 * @param {Function} dataZoomInfo.getRange.scrollMove
 * @param {boolean} dataZoomInfo.dataZoomModel
 */
function register$1(api, dataZoomInfo) {
    var store = giveStore(api);
    var theDataZoomId = dataZoomInfo.dataZoomId;
    var theCoordId = dataZoomInfo.coordId;

    // Do clean when a dataZoom changes its target coordnate system.
    // Avoid memory leak, dispose all not-used-registered.
    each$1(store, function (record, coordId) {
        var dataZoomInfos = record.dataZoomInfos;
        if (dataZoomInfos[theDataZoomId]
            && indexOf(dataZoomInfo.allCoordIds, theCoordId) < 0
        ) {
            delete dataZoomInfos[theDataZoomId];
            record.count--;
        }
    });

    cleanStore(store);

    var record = store[theCoordId];
    // Create if needed.
    if (!record) {
        record = store[theCoordId] = {
            coordId: theCoordId,
            dataZoomInfos: {},
            count: 0
        };
        record.controller = createController(api, record);
        record.dispatchAction = curry(dispatchAction, api);
    }

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

    var controllerParams = mergeControllerParams(record.dataZoomInfos);
    record.controller.enable(controllerParams.controlType, controllerParams.opt);

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

    // Update throttle.
    createOrUpdate(
        record,
        'dispatchAction',
        dataZoomInfo.dataZoomModel.get('throttle', true),
        'fixRate'
    );
}

/**
 * @public
 * @param {module:echarts/ExtensionAPI} api
 * @param {string} dataZoomId
 */
function unregister$1(api, dataZoomId) {
    var store = giveStore(api);

    each$1(store, function (record) {
        record.controller.dispose();
        var dataZoomInfos = record.dataZoomInfos;
        if (dataZoomInfos[dataZoomId]) {
            delete dataZoomInfos[dataZoomId];
            record.count--;
        }
    });

    cleanStore(store);
}

/**
 * @public
 */
function generateCoordId(coordModel) {
    return coordModel.type + '\0_' + coordModel.id;
}

/**
 * Key: coordId, value: {dataZoomInfos: [], count, controller}
 * @type {Array.<Object>}
 */
function giveStore(api) {
    // Mount store on zrender instance, so that we do not
    // need to worry about dispose.
    var zr = api.getZr();
    return zr[ATTR] || (zr[ATTR] = {});
}

function createController(api, newRecord) {
    var controller = new RoamController(api.getZr());

    each$1(['pan', 'zoom', 'scrollMove'], function (eventName) {
        controller.on(eventName, function (event) {
            var batch = [];

            each$1(newRecord.dataZoomInfos, function (info) {
                // Check whether the behaviors (zoomOnMouseWheel, moveOnMouseMove,
                // moveOnMouseWheel, ...) enabled.
                if (!event.isAvailableBehavior(info.dataZoomModel.option)) {
                    return;
                }

                var method = (info.getRange || {})[eventName];
                var range = method && method(newRecord.controller, event);

                !info.dataZoomModel.get('disabled', true) && range && batch.push({
                    dataZoomId: info.dataZoomId,
                    start: range[0],
                    end: range[1]
                });
            });

            batch.length && newRecord.dispatchAction(batch);
        });
    });

    return controller;
}

function cleanStore(store) {
    each$1(store, function (record, coordId) {
        if (!record.count) {
            record.controller.dispose();
            delete store[coordId];
        }
    });
}

/**
 * This action will be throttled.
 */
function dispatchAction(api, batch) {
    api.dispatchAction({
        type: 'dataZoom',
        batch: batch
    });
}

/**
 * Merge roamController settings when multiple dataZooms share one roamController.
 */
function mergeControllerParams(dataZoomInfos) {
    var controlType;
    // DO NOT use reserved word (true, false, undefined) as key literally. Even if encapsulated
    // as string, it is probably revert to reserved word by compress tool. See #7411.
    var prefix = 'type_';
    var typePriority = {
        'type_true': 2,
        'type_move': 1,
        'type_false': 0,
        'type_undefined': -1
    };
    var preventDefaultMouseMove = true;

    each$1(dataZoomInfos, function (dataZoomInfo) {
        var dataZoomModel = dataZoomInfo.dataZoomModel;
        var oneType = dataZoomModel.get('disabled', true)
            ? false
            : dataZoomModel.get('zoomLock', true)
            ? 'move'
            : true;
        if (typePriority[prefix + oneType] > typePriority[prefix + controlType]) {
            controlType = oneType;
        }

        // Prevent default move event by default. If one false, do not prevent. Otherwise
        // users may be confused why it does not work when multiple insideZooms exist.
        preventDefaultMouseMove &= dataZoomModel.get('preventDefaultMouseMove', true);
    });

    return {
        controlType: controlType,
        opt: {
            // RoamController will enable all of these functionalities,
            // and the final behavior is determined by its event listener
            // provided by each inside zoom.
            zoomOnMouseWheel: true,
            moveOnMouseMove: true,
            moveOnMouseWheel: true,
            preventDefaultMouseMove: !!preventDefaultMouseMove
        }
    };
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var bind$4 = bind;

var InsideZoomView = DataZoomView.extend({

    type: 'dataZoom.inside',

    /**
     * @override
     */
    init: function (ecModel, api) {
        /**
         * 'throttle' is used in this.dispatchAction, so we save range
         * to avoid missing some 'pan' info.
         * @private
         * @type {Array.<number>}
         */
        this._range;
    },

    /**
     * @override
     */
    render: function (dataZoomModel, ecModel, api, payload) {
        InsideZoomView.superApply(this, 'render', arguments);

        // Hence the `throttle` util ensures to preserve command order,
        // here simply updating range all the time will not cause missing
        // any of the the roam change.
        this._range = dataZoomModel.getPercentRange();

        // Reset controllers.
        each$1(this.getTargetCoordInfo(), function (coordInfoList, coordSysName) {

            var allCoordIds = map(coordInfoList, function (coordInfo) {
                return generateCoordId(coordInfo.model);
            });

            each$1(coordInfoList, function (coordInfo) {
                var coordModel = coordInfo.model;

                var getRange = {};
                each$1(['pan', 'zoom', 'scrollMove'], function (eventName) {
                    getRange[eventName] = bind$4(roamHandlers[eventName], this, coordInfo, coordSysName);
                }, this);

                register$1(
                    api,
                    {
                        coordId: generateCoordId(coordModel),
                        allCoordIds: allCoordIds,
                        containsPoint: function (e, x, y) {
                            return coordModel.coordinateSystem.containPoint([x, y]);
                        },
                        dataZoomId: dataZoomModel.id,
                        dataZoomModel: dataZoomModel,
                        getRange: getRange
                    }
                );
            }, this);

        }, this);
    },

    /**
     * @override
     */
    dispose: function () {
        unregister$1(this.api, this.dataZoomModel.id);
        InsideZoomView.superApply(this, 'dispose', arguments);
        this._range = null;
    }

});

var roamHandlers = {

    /**
     * @this {module:echarts/component/dataZoom/InsideZoomView}
     */
    zoom: function (coordInfo, coordSysName, controller, e) {
        var lastRange = this._range;
        var range = lastRange.slice();

        // Calculate transform by the first axis.
        var axisModel = coordInfo.axisModels[0];
        if (!axisModel) {
            return;
        }

        var directionInfo = getDirectionInfo[coordSysName](
            null, [e.originX, e.originY], axisModel, controller, coordInfo
        );
        var percentPoint = (
            directionInfo.signal > 0
                ? (directionInfo.pixelStart + directionInfo.pixelLength - directionInfo.pixel)
                : (directionInfo.pixel - directionInfo.pixelStart)
            ) / directionInfo.pixelLength * (range[1] - range[0]) + range[0];

        var scale = Math.max(1 / e.scale, 0);
        range[0] = (range[0] - percentPoint) * scale + percentPoint;
        range[1] = (range[1] - percentPoint) * scale + percentPoint;

        // Restrict range.
        var minMaxSpan = this.dataZoomModel.findRepresentativeAxisProxy().getMinMaxSpan();

        sliderMove(0, range, [0, 100], 0, minMaxSpan.minSpan, minMaxSpan.maxSpan);

        this._range = range;

        if (lastRange[0] !== range[0] || lastRange[1] !== range[1]) {
            return range;
        }
    },

    /**
     * @this {module:echarts/component/dataZoom/InsideZoomView}
     */
    pan: makeMover(function (range, axisModel, coordInfo, coordSysName, controller, e) {
        var directionInfo = getDirectionInfo[coordSysName](
            [e.oldX, e.oldY], [e.newX, e.newY], axisModel, controller, coordInfo
        );

        return directionInfo.signal
            * (range[1] - range[0])
            * directionInfo.pixel / directionInfo.pixelLength;
    }),

    /**
     * @this {module:echarts/component/dataZoom/InsideZoomView}
     */
    scrollMove: makeMover(function (range, axisModel, coordInfo, coordSysName, controller, e) {
        var directionInfo = getDirectionInfo[coordSysName](
            [0, 0], [e.scrollDelta, e.scrollDelta], axisModel, controller, coordInfo
        );
        return directionInfo.signal * (range[1] - range[0]) * e.scrollDelta;
    })
};

function makeMover(getPercentDelta) {
    return function (coordInfo, coordSysName, controller, e) {
        var lastRange = this._range;
        var range = lastRange.slice();

        // Calculate transform by the first axis.
        var axisModel = coordInfo.axisModels[0];
        if (!axisModel) {
            return;
        }

        var percentDelta = getPercentDelta(
            range, axisModel, coordInfo, coordSysName, controller, e
        );

        sliderMove(percentDelta, range, [0, 100], 'all');

        this._range = range;

        if (lastRange[0] !== range[0] || lastRange[1] !== range[1]) {
            return range;
        }
    };
}

var getDirectionInfo = {

    grid: function (oldPoint, newPoint, axisModel, controller, coordInfo) {
        var axis = axisModel.axis;
        var ret = {};
        var rect = coordInfo.model.coordinateSystem.getRect();
        oldPoint = oldPoint || [0, 0];

        if (axis.dim === 'x') {
            ret.pixel = newPoint[0] - oldPoint[0];
            ret.pixelLength = rect.width;
            ret.pixelStart = rect.x;
            ret.signal = axis.inverse ? 1 : -1;
        }
        else { // axis.dim === 'y'
            ret.pixel = newPoint[1] - oldPoint[1];
            ret.pixelLength = rect.height;
            ret.pixelStart = rect.y;
            ret.signal = axis.inverse ? -1 : 1;
        }

        return ret;
    },

    polar: function (oldPoint, newPoint, axisModel, controller, coordInfo) {
        var axis = axisModel.axis;
        var ret = {};
        var polar = coordInfo.model.coordinateSystem;
        var radiusExtent = polar.getRadiusAxis().getExtent();
        var angleExtent = polar.getAngleAxis().getExtent();

        oldPoint = oldPoint ? polar.pointToCoord(oldPoint) : [0, 0];
        newPoint = polar.pointToCoord(newPoint);

        if (axisModel.mainType === 'radiusAxis') {
            ret.pixel = newPoint[0] - oldPoint[0];
            // ret.pixelLength = Math.abs(radiusExtent[1] - radiusExtent[0]);
            // ret.pixelStart = Math.min(radiusExtent[0], radiusExtent[1]);
            ret.pixelLength = radiusExtent[1] - radiusExtent[0];
            ret.pixelStart = radiusExtent[0];
            ret.signal = axis.inverse ? 1 : -1;
        }
        else { // 'angleAxis'
            ret.pixel = newPoint[1] - oldPoint[1];
            // ret.pixelLength = Math.abs(angleExtent[1] - angleExtent[0]);
            // ret.pixelStart = Math.min(angleExtent[0], angleExtent[1]);
            ret.pixelLength = angleExtent[1] - angleExtent[0];
            ret.pixelStart = angleExtent[0];
            ret.signal = axis.inverse ? -1 : 1;
        }

        return ret;
    },

    singleAxis: function (oldPoint, newPoint, axisModel, controller, coordInfo) {
        var axis = axisModel.axis;
        var rect = coordInfo.model.coordinateSystem.getRect();
        var ret = {};

        oldPoint = oldPoint || [0, 0];

        if (axis.orient === 'horizontal') {
            ret.pixel = newPoint[0] - oldPoint[0];
            ret.pixelLength = rect.width;
            ret.pixelStart = rect.x;
            ret.signal = axis.inverse ? 1 : -1;
        }
        else { // 'vertical'
            ret.pixel = newPoint[1] - oldPoint[1];
            ret.pixelLength = rect.height;
            ret.pixelStart = rect.y;
            ret.signal = axis.inverse ? -1 : 1;
        }

        return ret;
    }
};

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/



// Do not include './dataZoomSelect',
// since it only work for toolbox dataZoom.

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/


var features = {};

function register$2(name, ctor) {
    features[name] = ctor;
}

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

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var ToolboxModel = extendComponentModel({

    type: 'toolbox',

    layoutMode: {
        type: 'box',
        ignoreSize: true
    },

    optionUpdated: function () {
        ToolboxModel.superApply(this, 'optionUpdated', arguments);

        each$1(this.option.feature, function (featureOpt, featureName) {
            var Feature = get$1(featureName);
            Feature && merge(featureOpt, Feature.defaultOption);
        });
    },

    defaultOption: {

        show: true,

        z: 6,

        zlevel: 0,

        orient: 'horizontal',

        left: 'right',

        top: 'top',

        // right
        // bottom

        backgroundColor: 'transparent',

        borderColor: '#ccc',

        borderRadius: 0,

        borderWidth: 0,

        padding: 5,

        itemSize: 15,

        itemGap: 8,

        showTitle: true,

        iconStyle: {
            borderColor: '#666',
            color: 'none'
        },
        emphasis: {
            iconStyle: {
                borderColor: '#3E98C5'
            }
        },
        // textStyle: {},

        // feature

        tooltip: {
            show: false
        }
    }
});

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

extendComponentView({

    type: 'toolbox',

    render: function (toolboxModel, ecModel, api, payload) {
        var group = this.group;
        group.removeAll();

        if (!toolboxModel.get('show')) {
            return;
        }

        var itemSize = +toolboxModel.get('itemSize');
        var featureOpts = toolboxModel.get('feature') || {};
        var features = this._features || (this._features = {});

        var featureNames = [];
        each$1(featureOpts, function (opt, name) {
            featureNames.push(name);
        });

        (new DataDiffer(this._featureNames || [], featureNames))
            .add(processFeature)
            .update(processFeature)
            .remove(curry(processFeature, null))
            .execute();

        // Keep for diff.
        this._featureNames = featureNames;

        function processFeature(newIndex, oldIndex) {
            var featureName = featureNames[newIndex];
            var oldName = featureNames[oldIndex];
            var featureOpt = featureOpts[featureName];
            var featureModel = new Model(featureOpt, toolboxModel, toolboxModel.ecModel);
            var feature;

            // FIX#11236, merge feature title from MagicType newOption. TODO: consider seriesIndex ?
            if (payload && payload.newTitle != null && payload.featureName === featureName) {
                featureOpt.title = payload.newTitle;
            }

            if (featureName && !oldName) { // Create
                if (isUserFeatureName(featureName)) {
                    feature = {
                        model: featureModel,
                        onclick: featureModel.option.onclick,
                        featureName: featureName
                    };
                }
                else {
                    var Feature = get$1(featureName);
                    if (!Feature) {
                        return;
                    }
                    feature = new Feature(featureModel, ecModel, api);
                }
                features[featureName] = feature;
            }
            else {
                feature = features[oldName];
                // If feature does not exsit.
                if (!feature) {
                    return;
                }
                feature.model = featureModel;
                feature.ecModel = ecModel;
                feature.api = api;
            }

            if (!featureName && oldName) {
                feature.dispose && feature.dispose(ecModel, api);
                return;
            }

            if (!featureModel.get('show') || feature.unusable) {
                feature.remove && feature.remove(ecModel, api);
                return;
            }

            createIconPaths(featureModel, feature, featureName);

            featureModel.setIconStatus = function (iconName, status) {
                var option = this.option;
                var iconPaths = this.iconPaths;
                option.iconStatus = option.iconStatus || {};
                option.iconStatus[iconName] = status;
                // FIXME
                iconPaths[iconName] && iconPaths[iconName].trigger(status);
            };

            if (feature.render) {
                feature.render(featureModel, ecModel, api, payload);
            }
        }

        function createIconPaths(featureModel, feature, featureName) {
            var iconStyleModel = featureModel.getModel('iconStyle');
            var iconStyleEmphasisModel = featureModel.getModel('emphasis.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 = {};
            each$1(icons, function (iconStr, iconName) {
                var path = createIcon(
                    iconStr,
                    {},
                    {
                        x: -itemSize / 2,
                        y: -itemSize / 2,
                        width: itemSize,
                        height: itemSize
                    }
                );
                path.setStyle(iconStyleModel.getItemStyle());
                path.hoverStyle = iconStyleEmphasisModel.getItemStyle();

                // Text position calculation
                path.setStyle({
                    text: titles[iconName],
                    textAlign: iconStyleEmphasisModel.get('textAlign'),
                    textBorderRadius: iconStyleEmphasisModel.get('textBorderRadius'),
                    textPadding: iconStyleEmphasisModel.get('textPadding'),
                    textFill: null
                });

                var tooltipModel = toolboxModel.getModel('tooltip');
                if (tooltipModel && tooltipModel.get('show')) {
                    path.attr('tooltip', extend({
                        content: titles[iconName],
                        formatter: tooltipModel.get('formatter', true)
                            || function () {
                                return titles[iconName];
                            },
                        formatterParams: {
                            componentType: 'toolbox',
                            name: iconName,
                            title: titles[iconName],
                            $vars: ['name', 'title']
                        },
                        position: tooltipModel.get('position', true) || 'bottom'
                    }, tooltipModel.option));
                }

                setHoverStyle(path);

                if (toolboxModel.get('showTitle')) {
                    path.__title = titles[iconName];
                    path.on('mouseover', function () {
                            // Should not reuse above hoverStyle, which might be modified.
                            var hoverStyle = iconStyleEmphasisModel.getItemStyle();
                            var defaultTextPosition = toolboxModel.get('orient') === 'vertical'
                                ? (toolboxModel.get('right') == null ? 'right' : 'left')
                                : (toolboxModel.get('bottom') == null ? 'bottom' : 'top');
                            path.setStyle({
                                textFill: iconStyleEmphasisModel.get('textFill')
                                    || hoverStyle.fill || hoverStyle.stroke || '#000',
                                textBackgroundColor: iconStyleEmphasisModel.get('textBackgroundColor'),
                                textPosition: iconStyleEmphasisModel.get('textPosition') || defaultTextPosition
                            });
                        })
                        .on('mouseout', function () {
                            path.setStyle({
                                textFill: null,
                                textBackgroundColor: null
                            });
                        });
                }
                path.trigger(featureModel.get('iconStatus.' + iconName) || 'normal');

                group.add(path);
                path.on('click', bind(
                    feature.onclick, feature, ecModel, api, iconName
                ));

                iconPaths[iconName] = path;
            });
        }

        layout$2(group, toolboxModel, api);
        // Render background after group is layout
        // FIXME
        group.add(makeBackground(group.getBoundingRect(), 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 = getBoundingRect(
                    titleText, makeFont(hoverStyle)
                );
                var offsetX = icon.position[0] + group.position[0];
                var offsetY = icon.position[1] + group.position[1] + itemSize;

                var needPutOnTop = false;
                if (offsetY + rect.height > api.getHeight()) {
                    hoverStyle.textPosition = 'top';
                    needPutOnTop = true;
                }
                var topOffset = needPutOnTop ? (-5 - rect.height) : (itemSize + 8);
                if (offsetX + rect.width / 2 > api.getWidth()) {
                    hoverStyle.textPosition = ['100%', topOffset];
                    hoverStyle.textAlign = 'right';
                }
                else if (offsetX - rect.width / 2 < 0) {
                    hoverStyle.textPosition = [0, topOffset];
                    hoverStyle.textAlign = 'left';
                }
            }
        });
    },

    updateView: function (toolboxModel, ecModel, api, payload) {
        each$1(this._features, function (feature) {
            feature.updateView && feature.updateView(feature.model, ecModel, api, payload);
        });
    },

    // updateLayout: function (toolboxModel, ecModel, api, payload) {
    //     zrUtil.each(this._features, function (feature) {
    //         feature.updateLayout && feature.updateLayout(feature.model, ecModel, api, payload);
    //     });
    // },

    remove: function (ecModel, api) {
        each$1(this._features, function (feature) {
            feature.remove && feature.remove(ecModel, api);
        });
        this.group.removeAll();
    },

    dispose: function (ecModel, api) {
        each$1(this._features, function (feature) {
            feature.dispose && feature.dispose(ecModel, api);
        });
    }
});

function isUserFeatureName(featureName) {
    return featureName.indexOf('my') === 0;
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/* global Uint8Array */

var saveAsImageLang = lang.toolbox.saveAsImage;

function SaveAsImage(model) {
    this.model = model;
}

SaveAsImage.defaultOption = {
    show: true,
    icon: 'M4.7,22.9L29.3,45.5L54.7,23.4M4.6,43.6L4.6,58L53.8,58L53.8,43.6M29.2,45.1L29.2,0',
    title: saveAsImageLang.title,
    type: 'png',
    // Default use option.backgroundColor
    // backgroundColor: '#fff',
    connectedBackgroundColor: '#fff',
    name: '',
    excludeComponents: ['toolbox'],
    pixelRatio: 1,
    lang: saveAsImageLang.lang.slice()
};

SaveAsImage.prototype.unusable = !env$1.canvasSupported;

var proto$2 = SaveAsImage.prototype;

proto$2.onclick = function (ecModel, api) {
    var model = this.model;
    var title = model.get('name') || ecModel.get('title.0.text') || 'echarts';
    var isSvg = api.getZr().painter.getType() === 'svg';
    var type = isSvg ? 'svg' : model.get('type', true) || 'png';
    var url = api.getConnectedDataURL({
        type: type,
        backgroundColor: model.get('backgroundColor', true)
            || ecModel.get('backgroundColor') || '#fff',
        connectedBackgroundColor: model.get('connectedBackgroundColor'),
        excludeComponents: model.get('excludeComponents'),
        pixelRatio: model.get('pixelRatio')
    });
    // Chrome and Firefox
    if (typeof MouseEvent === 'function' && !env$1.browser.ie && !env$1.browser.edge) {
        var $a = document.createElement('a');
        $a.download = title + '.' + type;
        $a.target = '_blank';
        $a.href = url;
        var evt = new MouseEvent('click', {
            // some micro front-end framework， window maybe is a Proxy
            view: document.defaultView,
            bubbles: true,
            cancelable: false
        });
        $a.dispatchEvent(evt);
    }
    // IE
    else {
        if (window.navigator.msSaveOrOpenBlob) {
            var bstr = atob(url.split(',')[1]);
            var n = bstr.length;
            var u8arr = new Uint8Array(n);
            while (n--) {
                u8arr[n] = bstr.charCodeAt(n);
            }
            var blob = new Blob([u8arr]);
            window.navigator.msSaveOrOpenBlob(blob, title + '.' + type);
        }
        else {
            var lang$$1 = model.get('lang');
            var html = ''
                + '<body style="margin:0;">'
                + '<img src="' + url + '" style="max-width:100%;" title="' + ((lang$$1 && lang$$1[0]) || '') + '" />'
                + '</body>';
            var tab = window.open();
            tab.document.write(html);
        }
    }
};

register$2(
    'saveAsImage', SaveAsImage
);

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var magicTypeLang = lang.toolbox.magicType;
var INNER_STACK_KEYWORD = '__ec_magicType_stack__';

function MagicType(model) {
    this.model = model;
}

MagicType.defaultOption = {
    show: true,
    type: [],
    // Icon group
    icon: {
        /* eslint-disable */
        line: 'M4.1,28.9h7.1l9.3-22l7.4,38l9.7-19.7l3,12.8h14.9M4.1,58h51.4',
        bar: 'M6.7,22.9h10V48h-10V22.9zM24.9,13h10v35h-10V13zM43.2,2h10v46h-10V2zM3.1,58h53.7',
        stack: 'M8.2,38.4l-8.4,4.1l30.6,15.3L60,42.5l-8.1-4.1l-21.5,11L8.2,38.4z M51.9,30l-8.1,4.2l-13.4,6.9l-13.9-6.9L8.2,30l-8.4,4.2l8.4,4.2l22.2,11l21.5-11l8.1-4.2L51.9,30z M51.9,21.7l-8.1,4.2L35.7,30l-5.3,2.8L24.9,30l-8.4-4.1l-8.3-4.2l-8.4,4.2L8.2,30l8.3,4.2l13.9,6.9l13.4-6.9l8.1-4.2l8.1-4.1L51.9,21.7zM30.4,2.2L-0.2,17.5l8.4,4.1l8.3,4.2l8.4,4.2l5.5,2.7l5.3-2.7l8.1-4.2l8.1-4.2l8.1-4.1L30.4,2.2z' // jshint ignore:line
        /* eslint-enable */
    },
    // `line`, `bar`, `stack`, `tiled`
    title: clone(magicTypeLang.title),
    option: {},
    seriesIndex: {}
};

var proto$3 = MagicType.prototype;

proto$3.getIcons = function () {
    var model = this.model;
    var availableIcons = model.get('icon');
    var icons = {};
    each$1(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 merge({
                id: seriesId,
                type: 'line',
                // Preserve data related option
                data: seriesModel.get('data'),
                stack: seriesModel.get('stack'),
                markPoint: seriesModel.get('markPoint'),
                markLine: seriesModel.get('markLine')
            }, model.get('option.line') || {}, true);
        }
    },
    'bar': function (seriesType, seriesId, seriesModel, model) {
        if (seriesType === 'line') {
            return merge({
                id: seriesId,
                type: 'bar',
                // Preserve data related option
                data: seriesModel.get('data'),
                stack: seriesModel.get('stack'),
                markPoint: seriesModel.get('markPoint'),
                markLine: seriesModel.get('markLine')
            }, model.get('option.bar') || {}, true);
        }
    },
    'stack': function (seriesType, seriesId, seriesModel, model) {
        var isStack = seriesModel.get('stack') === INNER_STACK_KEYWORD;
        if (seriesType === 'line' || seriesType === 'bar') {
            model.setIconStatus('stack', isStack ? 'normal' : 'emphasis');
            return merge({
                id: seriesId,
                stack: isStack ? '' : INNER_STACK_KEYWORD
            }, model.get('option.stack') || {}, true);
        }
    }
};

var radioTypes = [
    ['line', 'bar'],
    ['stack']
];

proto$3.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?
            defaults(newSeriesOpt, seriesModel.option);
            newOption.series.push(newSeriesOpt);
        }
        // Modify boundaryGap
        var coordSys = seriesModel.coordinateSystem;
        if (coordSys && coordSys.type === 'cartesian2d' && (type === 'line' || type === 'bar')) {
            var categoryAxis = coordSys.getAxesByScale('ordinal')[0];
            if (categoryAxis) {
                var axisDim = categoryAxis.dim;
                var axisType = axisDim + 'Axis';
                var axisModel = ecModel.queryComponents({
                    mainType: axisType,
                    index: seriesModel.get(name + 'Index'),
                    id: seriesModel.get(name + 'Id')
                })[0];
                var axisIndex = axisModel.componentIndex;

                newOption[axisType] = newOption[axisType] || [];
                for (var i = 0; i <= axisIndex; i++) {
                    newOption[axisType][axisIndex] = newOption[axisType][axisIndex] || {};
                }
                newOption[axisType][axisIndex].boundaryGap = type === 'bar';
            }
        }
    };

    each$1(radioTypes, function (radio) {
        if (indexOf(radio, type) >= 0) {
            each$1(radio, function (item) {
                model.setIconStatus(item, 'normal');
            });
        }
    });

    model.setIconStatus(type, 'emphasis');

    ecModel.eachComponent(
        {
            mainType: 'series',
            query: seriesIndex == null ? null : {
                seriesIndex: seriesIndex
            }
        }, generateNewSeriesTypes
    );

    var newTitle;
    // Change title of stack
    if (type === 'stack') {
        var isStack = newOption.series && newOption.series[0] && newOption.series[0].stack === INNER_STACK_KEYWORD;
        newTitle = isStack
            ? merge({ stack: magicTypeLang.title.tiled }, magicTypeLang.title)
            : clone(magicTypeLang.title);
    }

    api.dispatchAction({
        type: 'changeMagicType',
        currentType: type,
        newOption: newOption,
        newTitle: newTitle,
        featureName: 'magicType'
    });
};

registerAction({
    type: 'changeMagicType',
    event: 'magicTypeChanged',
    update: 'prepareAndUpdate'
}, function (payload, ecModel) {
    ecModel.mergeOption(payload.newOption);
});

register$2('magicType', MagicType);

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var dataViewLang = lang.toolbox.dataView;

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 = [];
    each$1(series, function (group, key) {
        var categoryAxis = group.categoryAxis;
        var valueAxis = group.valueAxis;
        var valueAxisDim = valueAxis.dim;

        var headers = [' '].concat(map(group.series, function (series) {
            return series.name;
        }));
        var columns = [categoryAxis.model.getCategories()];
        each$1(group.series, function (series) {
            var rawData = series.getRawData();
            columns.push(series.getRawData().mapArray(rawData.mapDimension(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 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 {Object}
 * @inner
 */
function getContentFromModel(ecModel) {

    var result = groupSeries(ecModel);

    return {
        value: 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$1(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 {Object}
 */
function parseTSVContents(tsv) {
    var tsvLines = tsv.split(/\n+/g);
    var headers = trim$1(tsvLines.shift()).split(itemSplitRegex);

    var categories = [];
    var series = map(headers, function (header) {
        return {
            name: header,
            data: []
        };
    });
    for (var i = 0; i < tsvLines.length; i++) {
        var items = trim$1(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$1(lines.shift());

    var data = [];
    for (var i = 0; i < lines.length; i++) {
        // if line is empty, ignore it.
        // there is a case that a user forgot to delete `\n`.
        var line = trim$1(lines[i]);
        if (!line) {
            continue;
        }
        var items = line.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: []
    };
    each$1(blocks, function (block, idx) {
        if (isTSVFormat(block)) {
            var result = parseTSVContents(block);
            var blockMeta = blockMetaList[idx];
            var axisKey = blockMeta.axisDim + 'Axis';

            if (blockMeta) {
                newOption[axisKey] = newOption[axisKey] || [];
                newOption[axisKey][blockMeta.axisIndex] = {
                    data: result.categories
                };
                newOption.series = newOption.series.concat(result.series);
            }
        }
        else {
            var result = parseListContents(block);
            newOption.series.push(result);
        }
    });
    return newOption;
}

/**
 * @alias {module:echarts/component/toolbox/feature/DataView}
 * @constructor
 * @param {module:echarts/model/Model} model
 */
function DataView(model) {

    this._dom = null;

    this.model = model;
}

DataView.defaultOption = {
    show: true,
    readOnly: false,
    optionToContent: null,
    contentToOption: null,

    icon: 'M17.5,17.3H33 M17.5,17.3H33 M45.4,29.5h-28 M11.5,2v56H51V14.8L38.4,2H11.5z M38.4,2.2v12.7H51 M45.4,41.7h-28',
    title: clone(dataViewLang.title),
    lang: clone(dataViewLang.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$$1 = model.get('lang') || [];
    header.innerHTML = lang$$1[0] || model.get('title');
    header.style.cssText = 'margin: 10px 20px;';
    header.style.color = model.get('textColor');

    var viewMain = document.createElement('div');
    var textarea = document.createElement('textarea');
    viewMain.style.cssText = 'display:block;width:100%;overflow:auto;';

    var optionToContent = model.get('optionToContent');
    var contentToOption = model.get('contentToOption');
    var result = getContentFromModel(ecModel);
    if (typeof optionToContent === 'function') {
        var htmlOrDom = optionToContent(api.getOption());
        if (typeof htmlOrDom === 'string') {
            viewMain.innerHTML = htmlOrDom;
        }
        else if (isDom(htmlOrDom)) {
            viewMain.appendChild(htmlOrDom);
        }
    }
    else {
        // Use default textarea
        viewMain.appendChild(textarea);
        textarea.readOnly = model.get('readOnly');
        textarea.style.cssText = 'width:100%;height:100%;font-family:monospace;font-size:14px;line-height:1.6rem;';
        textarea.style.color = model.get('textColor');
        textarea.style.borderColor = model.get('textareaBorderColor');
        textarea.style.backgroundColor = model.get('textareaColor');
        textarea.value = result.value;
    }

    var blockMetaList = result.meta;

    var buttonContainer = document.createElement('div');
    buttonContainer.style.cssText = 'position:absolute;bottom:0;left:0;right:0;';

    var buttonStyle = 'float:right;margin-right:20px;border:none;'
        + 'cursor:pointer;padding:2px 5px;font-size:12px;border-radius:3px';
    var closeButton = document.createElement('div');
    var refreshButton = document.createElement('div');

    buttonStyle += ';background-color:' + model.get('buttonColor');
    buttonStyle += ';color:' + model.get('buttonTextColor');

    var self = this;

    function close() {
        container.removeChild(root);
        self._dom = null;
    }
    addEventListener(closeButton, 'click', close);

    addEventListener(refreshButton, 'click', function () {
        var newOption;
        try {
            if (typeof contentToOption === 'function') {
                newOption = contentToOption(viewMain, api.getOption());
            }
            else {
                newOption = parseContents(textarea.value, blockMetaList);
            }
        }
        catch (e) {
            close();
            throw new Error('Data view format error ' + e);
        }
        if (newOption) {
            api.dispatchAction({
                type: 'changeDataView',
                newOption: newOption
            });
        }

        close();
    });

    closeButton.innerHTML = lang$$1[1];
    refreshButton.innerHTML = lang$$1[2];
    refreshButton.style.cssText = buttonStyle;
    closeButton.style.cssText = buttonStyle;

    !model.get('readOnly') && buttonContainer.appendChild(refreshButton);
    buttonContainer.appendChild(closeButton);

    root.appendChild(header);
    root.appendChild(viewMain);
    root.appendChild(buttonContainer);

    viewMain.style.height = (container.clientHeight - 80) + 'px';

    container.appendChild(root);
    this._dom = root;
};

DataView.prototype.remove = function (ecModel, api) {
    this._dom && api.getDom().removeChild(this._dom);
};

DataView.prototype.dispose = function (ecModel, api) {
    this.remove(ecModel, api);
};

/**
 * @inner
 */
function tryMergeDataOption(newData, originalData) {
    return map(newData, function (newVal, idx) {
        var original = originalData && originalData[idx];
        if (isObject$1(original) && !isArray(original)) {
            var newValIsObject = isObject$1(newVal) && !isArray(newVal);
            if (!newValIsObject) {
                newVal = {
                    value: newVal
                };
            }
            // original data has name but new data has no name
            var shouldDeleteName = original.name != null && newVal.name == null;
            // Original data has option
            newVal = defaults(newVal, original);
            shouldDeleteName && (delete newVal.name);
            return newVal;
        }
        else {
            return newVal;
        }
    });
}

register$2('dataView', DataView);

registerAction({
    type: 'changeDataView',
    event: 'dataViewChanged',
    update: 'prepareAndUpdate'
}, function (payload, ecModel) {
    var newSeriesOptList = [];
    each$1(payload.newOption.series, function (seriesOpt) {
        var seriesModel = ecModel.getSeriesByName(seriesOpt.name)[0];
        if (!seriesModel) {
            // New created series
            // Geuss the series type
            newSeriesOptList.push(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(defaults({
        series: newSeriesOptList
    }, payload.newOption));
});

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var curry$5 = curry;
var each$16 = each$1;
var map$2 = map;
var mathMin$5 = Math.min;
var mathMax$5 = Math.max;
var mathPow$2 = Math.pow;

var COVER_Z = 10000;
var UNSELECT_THRESHOLD = 6;
var MIN_RESIZE_LINE_WIDTH = 6;
var MUTEX_RESOURCE_KEY = 'globalPan';

var DIRECTION_MAP = {
    w: [0, 0],
    e: [0, 1],
    n: [1, 0],
    s: [1, 1]
};
var CURSOR_MAP = {
    w: 'ew',
    e: 'ew',
    n: 'ns',
    s: 'ns',
    ne: 'nesw',
    sw: 'nesw',
    nw: 'nwse',
    se: 'nwse'
};
var DEFAULT_BRUSH_OPT = {
    brushStyle: {
        lineWidth: 2,
        stroke: 'rgba(0,0,0,0.3)',
        fill: 'rgba(0,0,0,0.1)'
    },
    transformable: true,
    brushMode: 'single',
    removeOnClick: false
};

var baseUID = 0;

/**
 * @alias module:echarts/component/helper/BrushController
 * @constructor
 * @mixin {module:zrender/mixin/Eventful}
 * @event module:echarts/component/helper/BrushController#brush
 *        params:
 *            areas: Array.<Array>, coord relates to container group,
 *                                    If no container specified, to global.
 *            opt {
 *                isEnd: boolean,
 *                removeOnClick: boolean
 *            }
 *
 * @param {module:zrender/zrender~ZRender} zr
 */
function BrushController(zr) {

    if (__DEV__) {
        assert$1(zr);
    }

    Eventful.call(this);

    /**
     * @type {module:zrender/zrender~ZRender}
     * @private
     */
    this._zr = zr;

    /**
     * @type {module:zrender/container/Group}
     * @readOnly
     */
    this.group = new Group();

    /**
     * Only for drawing (after enabledBrush).
     *     'line', 'rect', 'polygon' or false
     *     If passing false/null/undefined, disable brush.
     *     If passing 'auto', determined by panel.defaultBrushType
     * @private
     * @type {string}
     */
    this._brushType;

    /**
     * Only for drawing (after enabledBrush).
     *
     * @private
     * @type {Object}
     */
    this._brushOption;

    /**
     * @private
     * @type {Object}
     */
    this._panels;

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

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

    /**
     * @private
     * @type {Array}
     */
    this._covers = [];

    /**
     * @private
     * @type {moudule:zrender/container/Group}
     */
    this._creatingCover;

    /**
     * `true` means global panel
     * @private
     * @type {module:zrender/container/Group|boolean}
     */
    this._creatingPanel;

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

    /**
     * @private
     * @type {boolean}
     */
    if (__DEV__) {
        this._mounted;
    }

    /**
     * @private
     * @type {string}
     */
    this._uid = 'brushController_' + baseUID++;

    /**
     * @private
     * @type {Object}
     */
    this._handlers = {};

    each$16(pointerHandlers, function (handler, eventName) {
        this._handlers[eventName] = bind(handler, this);
    }, this);
}

BrushController.prototype = {

    constructor: BrushController,

    /**
     * If set to null/undefined/false, select disabled.
     * @param {Object} brushOption
     * @param {string|boolean} brushOption.brushType 'line', 'rect', 'polygon' or false
     *                          If passing false/null/undefined, disable brush.
     *                          If passing 'auto', determined by panel.defaultBrushType.
     *                              ('auto' can not be used in global panel)
     * @param {number} [brushOption.brushMode='single'] 'single' or 'multiple'
     * @param {boolean} [brushOption.transformable=true]
     * @param {boolean} [brushOption.removeOnClick=false]
     * @param {Object} [brushOption.brushStyle]
     * @param {number} [brushOption.brushStyle.width]
     * @param {number} [brushOption.brushStyle.lineWidth]
     * @param {string} [brushOption.brushStyle.stroke]
     * @param {string} [brushOption.brushStyle.fill]
     * @param {number} [brushOption.z]
     */
    enableBrush: function (brushOption) {
        if (__DEV__) {
            assert$1(this._mounted);
        }

        this._brushType && doDisableBrush(this);
        brushOption.brushType && doEnableBrush(this, brushOption);

        return this;
    },

    /**
     * @param {Array.<Object>} panelOpts If not pass, it is global brush.
     *        Each items: {
     *            panelId, // mandatory.
     *            clipPath, // mandatory. function.
     *            isTargetByCursor, // mandatory. function.
     *            defaultBrushType, // optional, only used when brushType is 'auto'.
     *            getLinearBrushOtherExtent, // optional. function.
     *        }
     */
    setPanels: function (panelOpts) {
        if (panelOpts && panelOpts.length) {
            var panels = this._panels = {};
            each$1(panelOpts, function (panelOpts) {
                panels[panelOpts.panelId] = clone(panelOpts);
            });
        }
        else {
            this._panels = null;
        }
        return this;
    },

    /**
     * @param {Object} [opt]
     * @return {boolean} [opt.enableGlobalPan=false]
     */
    mount: function (opt) {
        opt = opt || {};

        if (__DEV__) {
            this._mounted = true; // should be at first.
        }

        this._enableGlobalPan = opt.enableGlobalPan;

        var thisGroup = this.group;
        this._zr.add(thisGroup);

        thisGroup.attr({
            position: opt.position || [0, 0],
            rotation: opt.rotation || 0,
            scale: opt.scale || [1, 1]
        });
        this._transform = thisGroup.getLocalTransform();

        return this;
    },

    eachCover: function (cb, context) {
        each$16(this._covers, cb, context);
    },

    /**
     * Update covers.
     * @param {Array.<Object>} brushOptionList Like:
     *        [
     *            {id: 'xx', brushType: 'line', range: [23, 44], brushStyle, transformable},
     *            {id: 'yy', brushType: 'rect', range: [[23, 44], [23, 54]]},
     *            ...
     *        ]
     *        `brushType` is required in each cover info. (can not be 'auto')
     *        `id` is not mandatory.
     *        `brushStyle`, `transformable` is not mandatory, use DEFAULT_BRUSH_OPT by default.
     *        If brushOptionList is null/undefined, all covers removed.
     */
    updateCovers: function (brushOptionList) {
        if (__DEV__) {
            assert$1(this._mounted);
        }

        brushOptionList = map(brushOptionList, function (brushOption) {
            return merge(clone(DEFAULT_BRUSH_OPT), brushOption, true);
        });

        var tmpIdPrefix = '\0-brush-index-';
        var oldCovers = this._covers;
        var newCovers = this._covers = [];
        var controller = this;
        var creatingCover = this._creatingCover;

        (new DataDiffer(oldCovers, brushOptionList, oldGetKey, getKey))
            .add(addOrUpdate)
            .update(addOrUpdate)
            .remove(remove)
            .execute();

        return this;

        function getKey(brushOption, index) {
            return (brushOption.id != null ? brushOption.id : tmpIdPrefix + index)
                + '-' + brushOption.brushType;
        }

        function oldGetKey(cover, index) {
            return getKey(cover.__brushOption, index);
        }

        function addOrUpdate(newIndex, oldIndex) {
            var newBrushOption = brushOptionList[newIndex];
            // Consider setOption in event listener of brushSelect,
            // where updating cover when creating should be forbiden.
            if (oldIndex != null && oldCovers[oldIndex] === creatingCover) {
                newCovers[newIndex] = oldCovers[oldIndex];
            }
            else {
                var cover = newCovers[newIndex] = oldIndex != null
                    ? (
                        oldCovers[oldIndex].__brushOption = newBrushOption,
                        oldCovers[oldIndex]
                    )
                    : endCreating(controller, createCover(controller, newBrushOption));
                updateCoverAfterCreation(controller, cover);
            }
        }

        function remove(oldIndex) {
            if (oldCovers[oldIndex] !== creatingCover) {
                controller.group.remove(oldCovers[oldIndex]);
            }
        }
    },

    unmount: function () {
        if (__DEV__) {
            if (!this._mounted) {
                return;
            }
        }

        this.enableBrush(false);

        // container may 'removeAll' outside.
        clearCovers(this);
        this._zr.remove(this.group);

        if (__DEV__) {
            this._mounted = false; // should be at last.
        }

        return this;
    },

    dispose: function () {
        this.unmount();
        this.off();
    }
};

mixin(BrushController, Eventful);

function doEnableBrush(controller, brushOption) {
    var zr = controller._zr;

    // Consider roam, which takes globalPan too.
    if (!controller._enableGlobalPan) {
        take(zr, MUTEX_RESOURCE_KEY, controller._uid);
    }

    mountHandlers(zr, controller._handlers);

    controller._brushType = brushOption.brushType;
    controller._brushOption = merge(clone(DEFAULT_BRUSH_OPT), brushOption, true);
}

function doDisableBrush(controller) {
    var zr = controller._zr;

    release(zr, MUTEX_RESOURCE_KEY, controller._uid);

    unmountHandlers(zr, controller._handlers);

    controller._brushType = controller._brushOption = null;
}

function mountHandlers(zr, handlers) {
    each$16(handlers, function (handler, eventName) {
        zr.on(eventName, handler);
    });
}

function unmountHandlers(zr, handlers) {
    each$16(handlers, function (handler, eventName) {
        zr.off(eventName, handler);
    });
}

function createCover(controller, brushOption) {
    var cover = coverRenderers[brushOption.brushType].createCover(controller, brushOption);
    cover.__brushOption = brushOption;
    updateZ$1(cover, brushOption);
    controller.group.add(cover);
    return cover;
}

function endCreating(controller, creatingCover) {
    var coverRenderer = getCoverRenderer(creatingCover);
    if (coverRenderer.endCreating) {
        coverRenderer.endCreating(controller, creatingCover);
        updateZ$1(creatingCover, creatingCover.__brushOption);
    }
    return creatingCover;
}

function updateCoverShape(controller, cover) {
    var brushOption = cover.__brushOption;
    getCoverRenderer(cover).updateCoverShape(
        controller, cover, brushOption.range, brushOption
    );
}

function updateZ$1(cover, brushOption) {
    var z = brushOption.z;
    z == null && (z = COVER_Z);
    cover.traverse(function (el) {
        el.z = z;
        el.z2 = z; // Consider in given container.
    });
}

function updateCoverAfterCreation(controller, cover) {
    getCoverRenderer(cover).updateCommon(controller, cover);
    updateCoverShape(controller, cover);
}

function getCoverRenderer(cover) {
    return coverRenderers[cover.__brushOption.brushType];
}

// return target panel or `true` (means global panel)
function getPanelByPoint(controller, e, localCursorPoint) {
    var panels = controller._panels;
    if (!panels) {
        return true; // Global panel
    }
    var panel;
    var transform = controller._transform;
    each$16(panels, function (pn) {
        pn.isTargetByCursor(e, localCursorPoint, transform) && (panel = pn);
    });
    return panel;
}

// Return a panel or true
function getPanelByCover(controller, cover) {
    var panels = controller._panels;
    if (!panels) {
        return true; // Global panel
    }
    var panelId = cover.__brushOption.panelId;
    // User may give cover without coord sys info,
    // which is then treated as global panel.
    return panelId != null ? panels[panelId] : true;
}

function clearCovers(controller) {
    var covers = controller._covers;
    var originalLength = covers.length;
    each$16(covers, function (cover) {
        controller.group.remove(cover);
    }, controller);
    covers.length = 0;

    return !!originalLength;
}

function trigger$1(controller, opt) {
    var areas = map$2(controller._covers, function (cover) {
        var brushOption = cover.__brushOption;
        var range = clone(brushOption.range);
        return {
            brushType: brushOption.brushType,
            panelId: brushOption.panelId,
            range: range
        };
    });

    controller.trigger('brush', areas, {
        isEnd: !!opt.isEnd,
        removeOnClick: !!opt.removeOnClick
    });
}

function shouldShowCover(controller) {
    var track = controller._track;

    if (!track.length) {
        return false;
    }

    var p2 = track[track.length - 1];
    var p1 = track[0];
    var dx = p2[0] - p1[0];
    var dy = p2[1] - p1[1];
    var dist = mathPow$2(dx * dx + dy * dy, 0.5);

    return dist > UNSELECT_THRESHOLD;
}

function getTrackEnds(track) {
    var tail = track.length - 1;
    tail < 0 && (tail = 0);
    return [track[0], track[tail]];
}

function createBaseRectCover(doDrift, controller, brushOption, edgeNames) {
    var cover = new Group();

    cover.add(new Rect({
        name: 'main',
        style: makeStyle(brushOption),
        silent: true,
        draggable: true,
        cursor: 'move',
        drift: curry$5(doDrift, controller, cover, 'nswe'),
        ondragend: curry$5(trigger$1, controller, {isEnd: true})
    }));

    each$16(
        edgeNames,
        function (name) {
            cover.add(new Rect({
                name: name,
                style: {opacity: 0},
                draggable: true,
                silent: true,
                invisible: true,
                drift: curry$5(doDrift, controller, cover, name),
                ondragend: curry$5(trigger$1, controller, {isEnd: true})
            }));
        }
    );

    return cover;
}

function updateBaseRect(controller, cover, localRange, brushOption) {
    var lineWidth = brushOption.brushStyle.lineWidth || 0;
    var handleSize = mathMax$5(lineWidth, MIN_RESIZE_LINE_WIDTH);
    var x = localRange[0][0];
    var y = localRange[1][0];
    var xa = x - lineWidth / 2;
    var ya = y - lineWidth / 2;
    var x2 = localRange[0][1];
    var y2 = localRange[1][1];
    var x2a = x2 - handleSize + lineWidth / 2;
    var y2a = y2 - handleSize + lineWidth / 2;
    var width = x2 - x;
    var height = y2 - y;
    var widtha = width + lineWidth;
    var heighta = height + lineWidth;

    updateRectShape(controller, cover, 'main', x, y, width, height);

    if (brushOption.transformable) {
        updateRectShape(controller, cover, 'w', xa, ya, handleSize, heighta);
        updateRectShape(controller, cover, 'e', x2a, ya, handleSize, heighta);
        updateRectShape(controller, cover, 'n', xa, ya, widtha, handleSize);
        updateRectShape(controller, cover, 's', xa, y2a, widtha, handleSize);

        updateRectShape(controller, cover, 'nw', xa, ya, handleSize, handleSize);
        updateRectShape(controller, cover, 'ne', x2a, ya, handleSize, handleSize);
        updateRectShape(controller, cover, 'sw', xa, y2a, handleSize, handleSize);
        updateRectShape(controller, cover, 'se', x2a, y2a, handleSize, handleSize);
    }
}

function updateCommon(controller, cover) {
    var brushOption = cover.__brushOption;
    var transformable = brushOption.transformable;

    var mainEl = cover.childAt(0);
    mainEl.useStyle(makeStyle(brushOption));
    mainEl.attr({
        silent: !transformable,
        cursor: transformable ? 'move' : 'default'
    });

    each$16(
        ['w', 'e', 'n', 's', 'se', 'sw', 'ne', 'nw'],
        function (name) {
            var el = cover.childOfName(name);
            var globalDir = getGlobalDirection(controller, name);

            el && el.attr({
                silent: !transformable,
                invisible: !transformable,
                cursor: transformable ? CURSOR_MAP[globalDir] + '-resize' : null
            });
        }
    );
}

function updateRectShape(controller, cover, name, x, y, w, h) {
    var el = cover.childOfName(name);
    el && el.setShape(pointsToRect(
        clipByPanel(controller, cover, [[x, y], [x + w, y + h]])
    ));
}

function makeStyle(brushOption) {
    return defaults({strokeNoScale: true}, brushOption.brushStyle);
}

function formatRectRange(x, y, x2, y2) {
    var min = [mathMin$5(x, x2), mathMin$5(y, y2)];
    var max = [mathMax$5(x, x2), mathMax$5(y, y2)];

    return [
        [min[0], max[0]], // x range
        [min[1], max[1]] // y range
    ];
}

function getTransform$1(controller) {
    return getTransform(controller.group);
}

function getGlobalDirection(controller, localDirection) {
    if (localDirection.length > 1) {
        localDirection = localDirection.split('');
        var globalDir = [
            getGlobalDirection(controller, localDirection[0]),
            getGlobalDirection(controller, localDirection[1])
        ];
        (globalDir[0] === 'e' || globalDir[0] === 'w') && globalDir.reverse();
        return globalDir.join('');
    }
    else {
        var map$$1 = {w: 'left', e: 'right', n: 'top', s: 'bottom'};
        var inverseMap = {left: 'w', right: 'e', top: 'n', bottom: 's'};
        var globalDir = transformDirection(
            map$$1[localDirection], getTransform$1(controller)
        );
        return inverseMap[globalDir];
    }
}

function driftRect(toRectRange, fromRectRange, controller, cover, name, dx, dy, e) {
    var brushOption = cover.__brushOption;
    var rectRange = toRectRange(brushOption.range);
    var localDelta = toLocalDelta(controller, dx, dy);

    each$16(name.split(''), function (namePart) {
        var ind = DIRECTION_MAP[namePart];
        rectRange[ind[0]][ind[1]] += localDelta[ind[0]];
    });

    brushOption.range = fromRectRange(formatRectRange(
        rectRange[0][0], rectRange[1][0], rectRange[0][1], rectRange[1][1]
    ));

    updateCoverAfterCreation(controller, cover);
    trigger$1(controller, {isEnd: false});
}

function driftPolygon(controller, cover, dx, dy, e) {
    var range = cover.__brushOption.range;
    var localDelta = toLocalDelta(controller, dx, dy);

    each$16(range, function (point) {
        point[0] += localDelta[0];
        point[1] += localDelta[1];
    });

    updateCoverAfterCreation(controller, cover);
    trigger$1(controller, {isEnd: false});
}

function toLocalDelta(controller, dx, dy) {
    var thisGroup = controller.group;
    var localD = thisGroup.transformCoordToLocal(dx, dy);
    var localZero = thisGroup.transformCoordToLocal(0, 0);

    return [localD[0] - localZero[0], localD[1] - localZero[1]];
}

function clipByPanel(controller, cover, data) {
    var panel = getPanelByCover(controller, cover);

    return (panel && panel !== true)
        ? panel.clipPath(data, controller._transform)
        : clone(data);
}

function pointsToRect(points) {
    var xmin = mathMin$5(points[0][0], points[1][0]);
    var ymin = mathMin$5(points[0][1], points[1][1]);
    var xmax = mathMax$5(points[0][0], points[1][0]);
    var ymax = mathMax$5(points[0][1], points[1][1]);

    return {
        x: xmin,
        y: ymin,
        width: xmax - xmin,
        height: ymax - ymin
    };
}

function resetCursor(controller, e, localCursorPoint) {
    if (
        // Check active
        !controller._brushType
        // resetCursor should be always called when mouse is in zr area,
        // but not called when mouse is out of zr area to avoid bad influence
        // if `mousemove`, `mouseup` are triggered from `document` event.
        || isOutsideZrArea(controller, e)
    ) {
        return;
    }

    var zr = controller._zr;
    var covers = controller._covers;
    var currPanel = getPanelByPoint(controller, e, localCursorPoint);

    // Check whether in covers.
    if (!controller._dragging) {
        for (var i = 0; i < covers.length; i++) {
            var brushOption = covers[i].__brushOption;
            if (currPanel
                && (currPanel === true || brushOption.panelId === currPanel.panelId)
                && coverRenderers[brushOption.brushType].contain(
                    covers[i], localCursorPoint[0], localCursorPoint[1]
                )
            ) {
                // Use cursor style set on cover.
                return;
            }
        }
    }

    currPanel && zr.setCursorStyle('crosshair');
}

function preventDefault(e) {
    var rawE = e.event;
    rawE.preventDefault && rawE.preventDefault();
}

function mainShapeContain(cover, x, y) {
    return cover.childOfName('main').contain(x, y);
}

function updateCoverByMouse(controller, e, localCursorPoint, isEnd) {
    var creatingCover = controller._creatingCover;
    var panel = controller._creatingPanel;
    var thisBrushOption = controller._brushOption;
    var eventParams;

    controller._track.push(localCursorPoint.slice());

    if (shouldShowCover(controller) || creatingCover) {

        if (panel && !creatingCover) {
            thisBrushOption.brushMode === 'single' && clearCovers(controller);
            var brushOption = clone(thisBrushOption);
            brushOption.brushType = determineBrushType(brushOption.brushType, panel);
            brushOption.panelId = panel === true ? null : panel.panelId;
            creatingCover = controller._creatingCover = createCover(controller, brushOption);
            controller._covers.push(creatingCover);
        }

        if (creatingCover) {
            var coverRenderer = coverRenderers[determineBrushType(controller._brushType, panel)];
            var coverBrushOption = creatingCover.__brushOption;

            coverBrushOption.range = coverRenderer.getCreatingRange(
                clipByPanel(controller, creatingCover, controller._track)
            );

            if (isEnd) {
                endCreating(controller, creatingCover);
                coverRenderer.updateCommon(controller, creatingCover);
            }

            updateCoverShape(controller, creatingCover);

            eventParams = {isEnd: isEnd};
        }
    }
    else if (
        isEnd
        && thisBrushOption.brushMode === 'single'
        && thisBrushOption.removeOnClick
    ) {
        // Help user to remove covers easily, only by a tiny drag, in 'single' mode.
        // But a single click do not clear covers, because user may have casual
        // clicks (for example, click on other component and do not expect covers
        // disappear).
        // Only some cover removed, trigger action, but not every click trigger action.
        if (getPanelByPoint(controller, e, localCursorPoint) && clearCovers(controller)) {
            eventParams = {isEnd: isEnd, removeOnClick: true};
        }
    }

    return eventParams;
}

function determineBrushType(brushType, panel) {
    if (brushType === 'auto') {
        if (__DEV__) {
            assert$1(
                panel && panel.defaultBrushType,
                'MUST have defaultBrushType when brushType is "atuo"'
            );
        }
        return panel.defaultBrushType;
    }
    return brushType;
}

var pointerHandlers = {

    mousedown: function (e) {
        if (this._dragging) {
            // In case some browser do not support globalOut,
            // and release mose out side the browser.
            handleDragEnd(this, e);
        }
        else if (!e.target || !e.target.draggable) {

            preventDefault(e);

            var localCursorPoint = this.group.transformCoordToLocal(e.offsetX, e.offsetY);

            this._creatingCover = null;
            var panel = this._creatingPanel = getPanelByPoint(this, e, localCursorPoint);

            if (panel) {
                this._dragging = true;
                this._track = [localCursorPoint.slice()];
            }
        }
    },

    mousemove: function (e) {
        var x = e.offsetX;
        var y = e.offsetY;

        var localCursorPoint = this.group.transformCoordToLocal(x, y);

        resetCursor(this, e, localCursorPoint);

        if (this._dragging) {
            preventDefault(e);
            var eventParams = updateCoverByMouse(this, e, localCursorPoint, false);
            eventParams && trigger$1(this, eventParams);
        }
    },

    mouseup: function (e) {
        handleDragEnd(this, e);
    }
};


function handleDragEnd(controller, e) {
    if (controller._dragging) {
        preventDefault(e);

        var x = e.offsetX;
        var y = e.offsetY;

        var localCursorPoint = controller.group.transformCoordToLocal(x, y);
        var eventParams = updateCoverByMouse(controller, e, localCursorPoint, true);

        controller._dragging = false;
        controller._track = [];
        controller._creatingCover = null;

        // trigger event shoule be at final, after procedure will be nested.
        eventParams && trigger$1(controller, eventParams);
    }
}

function isOutsideZrArea(controller, x, y) {
    var zr = controller._zr;
    return x < 0 || x > zr.getWidth() || y < 0 || y > zr.getHeight();
}


/**
 * key: brushType
 * @type {Object}
 */
var coverRenderers = {

    lineX: getLineRenderer(0),

    lineY: getLineRenderer(1),

    rect: {
        createCover: function (controller, brushOption) {
            return createBaseRectCover(
                curry$5(
                    driftRect,
                    function (range) {
                        return range;
                    },
                    function (range) {
                        return range;
                    }
                ),
                controller,
                brushOption,
                ['w', 'e', 'n', 's', 'se', 'sw', 'ne', 'nw']
            );
        },
        getCreatingRange: function (localTrack) {
            var ends = getTrackEnds(localTrack);
            return formatRectRange(ends[1][0], ends[1][1], ends[0][0], ends[0][1]);
        },
        updateCoverShape: function (controller, cover, localRange, brushOption) {
            updateBaseRect(controller, cover, localRange, brushOption);
        },
        updateCommon: updateCommon,
        contain: mainShapeContain
    },

    polygon: {
        createCover: function (controller, brushOption) {
            var cover = new Group();

            // Do not use graphic.Polygon because graphic.Polyline do not close the
            // border of the shape when drawing, which is a better experience for user.
            cover.add(new Polyline({
                name: 'main',
                style: makeStyle(brushOption),
                silent: true
            }));

            return cover;
        },
        getCreatingRange: function (localTrack) {
            return localTrack;
        },
        endCreating: function (controller, cover) {
            cover.remove(cover.childAt(0));
            // Use graphic.Polygon close the shape.
            cover.add(new Polygon({
                name: 'main',
                draggable: true,
                drift: curry$5(driftPolygon, controller, cover),
                ondragend: curry$5(trigger$1, controller, {isEnd: true})
            }));
        },
        updateCoverShape: function (controller, cover, localRange, brushOption) {
            cover.childAt(0).setShape({
                points: clipByPanel(controller, cover, localRange)
            });
        },
        updateCommon: updateCommon,
        contain: mainShapeContain
    }
};

function getLineRenderer(xyIndex) {
    return {
        createCover: function (controller, brushOption) {
            return createBaseRectCover(
                curry$5(
                    driftRect,
                    function (range) {
                        var rectRange = [range, [0, 100]];
                        xyIndex && rectRange.reverse();
                        return rectRange;
                    },
                    function (rectRange) {
                        return rectRange[xyIndex];
                    }
                ),
                controller,
                brushOption,
                [['w', 'e'], ['n', 's']][xyIndex]
            );
        },
        getCreatingRange: function (localTrack) {
            var ends = getTrackEnds(localTrack);
            var min = mathMin$5(ends[0][xyIndex], ends[1][xyIndex]);
            var max = mathMax$5(ends[0][xyIndex], ends[1][xyIndex]);

            return [min, max];
        },
        updateCoverShape: function (controller, cover, localRange, brushOption) {
            var otherExtent;
            // If brushWidth not specified, fit the panel.
            var panel = getPanelByCover(controller, cover);
            if (panel !== true && panel.getLinearBrushOtherExtent) {
                otherExtent = panel.getLinearBrushOtherExtent(
                    xyIndex, controller._transform
                );
            }
            else {
                var zr = controller._zr;
                otherExtent = [0, [zr.getWidth(), zr.getHeight()][1 - xyIndex]];
            }
            var rectRange = [localRange, otherExtent];
            xyIndex && rectRange.reverse();

            updateBaseRect(controller, cover, rectRange, brushOption);
        },
        updateCommon: updateCommon,
        contain: mainShapeContain
    };
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/


var IRRELEVANT_EXCLUDES = {'axisPointer': 1, 'tooltip': 1, 'brush': 1};

/**
 * Avoid that: mouse click on a elements that is over geo or graph,
 * but roam is triggered.
 */
function onIrrelevantElement(e, api, targetCoordSysModel) {
    var model = api.getComponentByElement(e.topTarget);
    // If model is axisModel, it works only if it is injected with coordinateSystem.
    var coordSys = model && model.coordinateSystem;
    return model
        && model !== targetCoordSysModel
        && !IRRELEVANT_EXCLUDES[model.mainType]
        && (coordSys && coordSys.model !== targetCoordSysModel);
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

function makeRectPanelClipPath(rect) {
    rect = normalizeRect(rect);
    return function (localPoints, transform) {
        return clipPointsByRect(localPoints, rect);
    };
}

function makeLinearBrushOtherExtent(rect, specifiedXYIndex) {
    rect = normalizeRect(rect);
    return function (xyIndex) {
        var idx = specifiedXYIndex != null ? specifiedXYIndex : xyIndex;
        var brushWidth = idx ? rect.width : rect.height;
        var base = idx ? rect.x : rect.y;
        return [base, base + (brushWidth || 0)];
    };
}

function makeRectIsTargetByCursor(rect, api, targetModel) {
    rect = normalizeRect(rect);
    return function (e, localCursorPoint, transform) {
        return rect.contain(localCursorPoint[0], localCursorPoint[1])
            && !onIrrelevantElement(e, api, targetModel);
    };
}

// Consider width/height is negative.
function normalizeRect(rect) {
    return BoundingRect.create(rect);
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var each$17 = each$1;
var indexOf$2 = indexOf;
var curry$6 = curry;

var COORD_CONVERTS = ['dataToPoint', 'pointToData'];

// FIXME
// how to genarialize to more coordinate systems.
var INCLUDE_FINDER_MAIN_TYPES = [
    'grid', 'xAxis', 'yAxis', 'geo', 'graph',
    'polar', 'radiusAxis', 'angleAxis', 'bmap'
];

/**
 * [option in constructor]:
 * {
 *     Index/Id/Name of geo, xAxis, yAxis, grid: See util/model#parseFinder.
 * }
 *
 *
 * [targetInfo]:
 *
 * There can be multiple axes in a single targetInfo. Consider the case
 * of `grid` component, a targetInfo represents a grid which contains one or more
 * cartesian and one or more axes. And consider the case of parallel system,
 * which has multiple axes in a coordinate system.
 * Can be {
 *     panelId: ...,
 *     coordSys: <a representitive cartesian in grid (first cartesian by default)>,
 *     coordSyses: all cartesians.
 *     gridModel: <grid component>
 *     xAxes: correspond to coordSyses on index
 *     yAxes: correspond to coordSyses on index
 * }
 * or {
 *     panelId: ...,
 *     coordSys: <geo coord sys>
 *     coordSyses: [<geo coord sys>]
 *     geoModel: <geo component>
 * }
 *
 *
 * [panelOpt]:
 *
 * Make from targetInfo. Input to BrushController.
 * {
 *     panelId: ...,
 *     rect: ...
 * }
 *
 *
 * [area]:
 *
 * Generated by BrushController or user input.
 * {
 *     panelId: Used to locate coordInfo directly. If user inpput, no panelId.
 *     brushType: determine how to convert to/from coord('rect' or 'polygon' or 'lineX/Y').
 *     Index/Id/Name of geo, xAxis, yAxis, grid: See util/model#parseFinder.
 *     range: pixel range.
 *     coordRange: representitive coord range (the first one of coordRanges).
 *     coordRanges: <Array> coord ranges, used in multiple cartesian in one grid.
 * }
 */

/**
 * @param {Object} option contains Index/Id/Name of xAxis/yAxis/geo/grid
 *        Each can be {number|Array.<number>}. like: {xAxisIndex: [3, 4]}
 * @param {module:echarts/model/Global} ecModel
 * @param {Object} [opt]
 * @param {Array.<string>} [opt.include] include coordinate system types.
 */
function BrushTargetManager(option, ecModel, opt) {
    /**
     * @private
     * @type {Array.<Object>}
     */
    var targetInfoList = this._targetInfoList = [];
    var info = {};
    var foundCpts = parseFinder$1(ecModel, option);

    each$17(targetInfoBuilders, function (builder, type) {
        if (!opt || !opt.include || indexOf$2(opt.include, type) >= 0) {
            builder(foundCpts, targetInfoList, info);
        }
    });
}

var proto$5 = BrushTargetManager.prototype;

proto$5.setOutputRanges = function (areas, ecModel) {
    this.matchOutputRanges(areas, ecModel, function (area, coordRange, coordSys) {
        (area.coordRanges || (area.coordRanges = [])).push(coordRange);
        // area.coordRange is the first of area.coordRanges
        if (!area.coordRange) {
            area.coordRange = coordRange;
            // In 'category' axis, coord to pixel is not reversible, so we can not
            // rebuild range by coordRange accrately, which may bring trouble when
            // brushing only one item. So we use __rangeOffset to rebuilding range
            // by coordRange. And this it only used in brush component so it is no
            // need to be adapted to coordRanges.
            var result = coordConvert[area.brushType](0, coordSys, coordRange);
            area.__rangeOffset = {
                offset: diffProcessor[area.brushType](result.values, area.range, [1, 1]),
                xyMinMax: result.xyMinMax
            };
        }
    });
};

proto$5.matchOutputRanges = function (areas, ecModel, cb) {
    each$17(areas, function (area) {
        var targetInfo = this.findTargetInfo(area, ecModel);

        if (targetInfo && targetInfo !== true) {
            each$1(
                targetInfo.coordSyses,
                function (coordSys) {
                    var result = coordConvert[area.brushType](1, coordSys, area.range);
                    cb(area, result.values, coordSys, ecModel);
                }
            );
        }
    }, this);
};

proto$5.setInputRanges = function (areas, ecModel) {
    each$17(areas, function (area) {
        var targetInfo = this.findTargetInfo(area, ecModel);

        if (__DEV__) {
            assert$1(
                !targetInfo || targetInfo === true || area.coordRange,
                'coordRange must be specified when coord index specified.'
            );
            assert$1(
                !targetInfo || targetInfo !== true || area.range,
                'range must be specified in global brush.'
            );
        }

        area.range = area.range || [];

        // convert coordRange to global range and set panelId.
        if (targetInfo && targetInfo !== true) {
            area.panelId = targetInfo.panelId;
            // (1) area.range shoule always be calculate from coordRange but does
            // not keep its original value, for the sake of the dataZoom scenario,
            // where area.coordRange remains unchanged but area.range may be changed.
            // (2) Only support converting one coordRange to pixel range in brush
            // component. So do not consider `coordRanges`.
            // (3) About __rangeOffset, see comment above.
            var result = coordConvert[area.brushType](0, targetInfo.coordSys, area.coordRange);
            var rangeOffset = area.__rangeOffset;
            area.range = rangeOffset
                ? diffProcessor[area.brushType](
                    result.values,
                    rangeOffset.offset,
                    getScales(result.xyMinMax, rangeOffset.xyMinMax)
                )
                : result.values;
        }
    }, this);
};

proto$5.makePanelOpts = function (api, getDefaultBrushType) {
    return map(this._targetInfoList, function (targetInfo) {
        var rect = targetInfo.getPanelRect();
        return {
            panelId: targetInfo.panelId,
            defaultBrushType: getDefaultBrushType && getDefaultBrushType(targetInfo),
            clipPath: makeRectPanelClipPath(rect),
            isTargetByCursor: makeRectIsTargetByCursor(
                rect, api, targetInfo.coordSysModel
            ),
            getLinearBrushOtherExtent: makeLinearBrushOtherExtent(rect)
        };
    });
};

proto$5.controlSeries = function (area, seriesModel, ecModel) {
    // Check whether area is bound in coord, and series do not belong to that coord.
    // If do not do this check, some brush (like lineX) will controll all axes.
    var targetInfo = this.findTargetInfo(area, ecModel);
    return targetInfo === true || (
        targetInfo && indexOf$2(targetInfo.coordSyses, seriesModel.coordinateSystem) >= 0
    );
};

/**
 * If return Object, a coord found.
 * If reutrn true, global found.
 * Otherwise nothing found.
 *
 * @param {Object} area
 * @param {Array} targetInfoList
 * @return {Object|boolean}
 */
proto$5.findTargetInfo = function (area, ecModel) {
    var targetInfoList = this._targetInfoList;
    var foundCpts = parseFinder$1(ecModel, area);

    for (var i = 0; i < targetInfoList.length; i++) {
        var targetInfo = targetInfoList[i];
        var areaPanelId = area.panelId;
        if (areaPanelId) {
            if (targetInfo.panelId === areaPanelId) {
                return targetInfo;
            }
        }
        else {
            for (var i = 0; i < targetInfoMatchers.length; i++) {
                if (targetInfoMatchers[i](foundCpts, targetInfo)) {
                    return targetInfo;
                }
            }
        }
    }

    return true;
};

function formatMinMax(minMax) {
    minMax[0] > minMax[1] && minMax.reverse();
    return minMax;
}

function parseFinder$1(ecModel, option) {
    return parseFinder(
        ecModel, option, {includeMainTypes: INCLUDE_FINDER_MAIN_TYPES}
    );
}

var targetInfoBuilders = {

    grid: function (foundCpts, targetInfoList) {
        var xAxisModels = foundCpts.xAxisModels;
        var yAxisModels = foundCpts.yAxisModels;
        var gridModels = foundCpts.gridModels;
        // Remove duplicated.
        var gridModelMap = createHashMap();
        var xAxesHas = {};
        var yAxesHas = {};

        if (!xAxisModels && !yAxisModels && !gridModels) {
            return;
        }

        each$17(xAxisModels, function (axisModel) {
            var gridModel = axisModel.axis.grid.model;
            gridModelMap.set(gridModel.id, gridModel);
            xAxesHas[gridModel.id] = true;
        });
        each$17(yAxisModels, function (axisModel) {
            var gridModel = axisModel.axis.grid.model;
            gridModelMap.set(gridModel.id, gridModel);
            yAxesHas[gridModel.id] = true;
        });
        each$17(gridModels, function (gridModel) {
            gridModelMap.set(gridModel.id, gridModel);
            xAxesHas[gridModel.id] = true;
            yAxesHas[gridModel.id] = true;
        });

        gridModelMap.each(function (gridModel) {
            var grid = gridModel.coordinateSystem;
            var cartesians = [];

            each$17(grid.getCartesians(), function (cartesian, index) {
                if (indexOf$2(xAxisModels, cartesian.getAxis('x').model) >= 0
                    || indexOf$2(yAxisModels, cartesian.getAxis('y').model) >= 0
                ) {
                    cartesians.push(cartesian);
                }
            });
            targetInfoList.push({
                panelId: 'grid--' + gridModel.id,
                gridModel: gridModel,
                coordSysModel: gridModel,
                // Use the first one as the representitive coordSys.
                coordSys: cartesians[0],
                coordSyses: cartesians,
                getPanelRect: panelRectBuilder.grid,
                xAxisDeclared: xAxesHas[gridModel.id],
                yAxisDeclared: yAxesHas[gridModel.id]
            });
        });
    },

    geo: function (foundCpts, targetInfoList) {
        each$17(foundCpts.geoModels, function (geoModel) {
            var coordSys = geoModel.coordinateSystem;
            targetInfoList.push({
                panelId: 'geo--' + geoModel.id,
                geoModel: geoModel,
                coordSysModel: geoModel,
                coordSys: coordSys,
                coordSyses: [coordSys],
                getPanelRect: panelRectBuilder.geo
            });
        });
    }
};

var targetInfoMatchers = [

    // grid
    function (foundCpts, targetInfo) {
        var xAxisModel = foundCpts.xAxisModel;
        var yAxisModel = foundCpts.yAxisModel;
        var gridModel = foundCpts.gridModel;

        !gridModel && xAxisModel && (gridModel = xAxisModel.axis.grid.model);
        !gridModel && yAxisModel && (gridModel = yAxisModel.axis.grid.model);

        return gridModel && gridModel === targetInfo.gridModel;
    },

    // geo
    function (foundCpts, targetInfo) {
        var geoModel = foundCpts.geoModel;
        return geoModel && geoModel === targetInfo.geoModel;
    }
];

var panelRectBuilder = {

    grid: function () {
        // grid is not Transformable.
        return this.coordSys.grid.getRect().clone();
    },

    geo: function () {
        var coordSys = this.coordSys;
        var rect = coordSys.getBoundingRect().clone();
        // geo roam and zoom transform
        rect.applyTransform(getTransform(coordSys));
        return rect;
    }
};

var coordConvert = {

    lineX: curry$6(axisConvert, 0),

    lineY: curry$6(axisConvert, 1),

    rect: function (to, coordSys, rangeOrCoordRange) {
        var xminymin = coordSys[COORD_CONVERTS[to]]([rangeOrCoordRange[0][0], rangeOrCoordRange[1][0]]);
        var xmaxymax = coordSys[COORD_CONVERTS[to]]([rangeOrCoordRange[0][1], rangeOrCoordRange[1][1]]);
        var values = [
            formatMinMax([xminymin[0], xmaxymax[0]]),
            formatMinMax([xminymin[1], xmaxymax[1]])
        ];
        return {values: values, xyMinMax: values};
    },

    polygon: function (to, coordSys, rangeOrCoordRange) {
        var xyMinMax = [[Infinity, -Infinity], [Infinity, -Infinity]];
        var values = map(rangeOrCoordRange, function (item) {
            var p = coordSys[COORD_CONVERTS[to]](item);
            xyMinMax[0][0] = Math.min(xyMinMax[0][0], p[0]);
            xyMinMax[1][0] = Math.min(xyMinMax[1][0], p[1]);
            xyMinMax[0][1] = Math.max(xyMinMax[0][1], p[0]);
            xyMinMax[1][1] = Math.max(xyMinMax[1][1], p[1]);
            return p;
        });
        return {values: values, xyMinMax: xyMinMax};
    }
};

function axisConvert(axisNameIndex, to, coordSys, rangeOrCoordRange) {
    if (__DEV__) {
        assert$1(
            coordSys.type === 'cartesian2d',
            'lineX/lineY brush is available only in cartesian2d.'
        );
    }

    var axis = coordSys.getAxis(['x', 'y'][axisNameIndex]);
    var values = formatMinMax(map([0, 1], function (i) {
        return to
            ? axis.coordToData(axis.toLocalCoord(rangeOrCoordRange[i]))
            : axis.toGlobalCoord(axis.dataToCoord(rangeOrCoordRange[i]));
    }));
    var xyMinMax = [];
    xyMinMax[axisNameIndex] = values;
    xyMinMax[1 - axisNameIndex] = [NaN, NaN];

    return {values: values, xyMinMax: xyMinMax};
}

var diffProcessor = {
    lineX: curry$6(axisDiffProcessor, 0),

    lineY: curry$6(axisDiffProcessor, 1),

    rect: function (values, refer, scales) {
        return [
            [values[0][0] - scales[0] * refer[0][0], values[0][1] - scales[0] * refer[0][1]],
            [values[1][0] - scales[1] * refer[1][0], values[1][1] - scales[1] * refer[1][1]]
        ];
    },

    polygon: function (values, refer, scales) {
        return map(values, function (item, idx) {
            return [item[0] - scales[0] * refer[idx][0], item[1] - scales[1] * refer[idx][1]];
        });
    }
};

function axisDiffProcessor(axisNameIndex, values, refer, scales) {
    return [
        values[0] - scales[axisNameIndex] * refer[0],
        values[1] - scales[axisNameIndex] * refer[1]
    ];
}

// We have to process scale caused by dataZoom manually,
// although it might be not accurate.
function getScales(xyMinMaxCurr, xyMinMaxOrigin) {
    var sizeCurr = getSize(xyMinMaxCurr);
    var sizeOrigin = getSize(xyMinMaxOrigin);
    var scales = [sizeCurr[0] / sizeOrigin[0], sizeCurr[1] / sizeOrigin[1]];
    isNaN(scales[0]) && (scales[0] = 1);
    isNaN(scales[1]) && (scales[1] = 1);
    return scales;
}

function getSize(xyMinMax) {
    return xyMinMax
        ? [xyMinMax[0][1] - xyMinMax[0][0], xyMinMax[1][1] - xyMinMax[1][0]]
        : [NaN, NaN];
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var each$18 = each$1;

var ATTR$2 = '\0_ec_hist_store';

/**
 * @param {module:echarts/model/Global} ecModel
 * @param {Object} newSnapshot {dataZoomId, batch: [payloadInfo, ...]}
 */
function push(ecModel, newSnapshot) {
    var store = giveStore$1(ecModel);

    // If previous dataZoom can not be found,
    // complete an range with current range.
    each$18(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);
}

/**
 * @param {module:echarts/model/Global} ecModel
 * @return {Object} snapshot
 */
function pop(ecModel) {
    var store = giveStore$1(ecModel);
    var head = store[store.length - 1];
    store.length > 1 && store.pop();

    // Find top for all dataZoom.
    var snapshot = {};
    each$18(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;
}

/**
 * @param {module:echarts/model/Global} ecModel
 */
function clear$1(ecModel) {
    ecModel[ATTR$2] = null;
}

/**
 * @param {module:echarts/model/Global} ecModel
 * @return {number} records. always >= 1.
 */
function count(ecModel) {
    return giveStore$1(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$1(ecModel) {
    var store = ecModel[ATTR$2];
    if (!store) {
        store = ecModel[ATTR$2] = [{}];
    }
    return store;
}

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

DataZoomModel.extend({
    type: 'dataZoom.select'
});

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

DataZoomView.extend({
    type: 'dataZoom.select'
});

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/**
 * Only work for toolbox dataZoom. User
 * MUST NOT import this module directly.
 */

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

// Use dataZoomSelect
var dataZoomLang = lang.toolbox.dataZoom;
var each$15 = each$1;

// Spectial component id start with \0ec\0, see echarts/model/Global.js~hasInnerId
var DATA_ZOOM_ID_BASE = '\0_ec_\0toolbox-dataZoom_';

function DataZoom(model, ecModel, api) {

    /**
     * @private
     * @type {module:echarts/component/helper/BrushController}
     */
    (this._brushController = new BrushController(api.getZr()))
        .on('brush', bind(this._onBrush, this))
        .mount();

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

DataZoom.defaultOption = {
    show: true,
    filterMode: 'filter',
    // 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'
    },
    // `zoom`, `back`
    title: clone(dataZoomLang.title),
    brushStyle: {
        borderWidth: 0,
        color: 'rgba(0,0,0,0.2)'
    }
};

var proto$4 = DataZoom.prototype;

proto$4.render = function (featureModel, ecModel, api, payload) {
    this.model = featureModel;
    this.ecModel = ecModel;
    this.api = api;

    updateZoomBtnStatus(featureModel, ecModel, this, payload, api);
    updateBackBtnStatus(featureModel, ecModel);
};

proto$4.onclick = function (ecModel, api, type) {
    handlers[type].call(this);
};

proto$4.remove = function (ecModel, api) {
    this._brushController.unmount();
};

proto$4.dispose = function (ecModel, api) {
    this._brushController.dispose();
};

/**
 * @private
 */
var handlers = {

    zoom: function () {
        var nextActive = !this._isZoomActive;

        this.api.dispatchAction({
            type: 'takeGlobalCursor',
            key: 'dataZoomSelect',
            dataZoomSelectActive: nextActive
        });
    },

    back: function () {
        this._dispatchZoomAction(pop(this.ecModel));
    }
};

/**
 * @private
 */
proto$4._onBrush = function (areas, opt) {
    if (!opt.isEnd || !areas.length) {
        return;
    }
    var snapshot = {};
    var ecModel = this.ecModel;

    this._brushController.updateCovers([]); // remove cover

    var brushTargetManager = new BrushTargetManager(
        retrieveAxisSetting(this.model.option), ecModel, {include: ['grid']}
    );
    brushTargetManager.matchOutputRanges(areas, ecModel, function (area, coordRange, coordSys) {
        if (coordSys.type !== 'cartesian2d') {
            return;
        }

        var brushType = area.brushType;
        if (brushType === 'rect') {
            setBatch('x', coordSys, coordRange[0]);
            setBatch('y', coordSys, coordRange[1]);
        }
        else {
            setBatch(({lineX: 'x', lineY: 'y'})[brushType], coordSys, coordRange);
        }
    });

    push(ecModel, snapshot);

    this._dispatchZoomAction(snapshot);

    function setBatch(dimName, coordSys, minMax) {
        var axis = coordSys.getAxis(dimName);
        var axisModel = axis.model;
        var dataZoomModel = findDataZoom(dimName, axisModel, ecModel);

        // Restrict range.
        var minMaxSpan = dataZoomModel.findRepresentativeAxisProxy(axisModel).getMinMaxSpan();
        if (minMaxSpan.minValueSpan != null || minMaxSpan.maxValueSpan != null) {
            minMax = sliderMove(
                0, minMax.slice(), axis.scale.getExtent(), 0,
                minMaxSpan.minValueSpan, minMaxSpan.maxValueSpan
            );
        }

        dataZoomModel && (snapshot[dataZoomModel.id] = {
            dataZoomId: dataZoomModel.id,
            startValue: minMax[0],
            endValue: minMax[1]
        });
    }

    function findDataZoom(dimName, axisModel, ecModel) {
        var found;
        ecModel.eachComponent({mainType: 'dataZoom', subType: 'select'}, function (dzModel) {
            var has = dzModel.getAxisModel(dimName, axisModel.componentIndex);
            has && (found = dzModel);
        });
        return found;
    }
};

/**
 * @private
 */
proto$4._dispatchZoomAction = function (snapshot) {
    var batch = [];

    // Convert from hash map to array.
    each$15(snapshot, function (batchItem, dataZoomId) {
        batch.push(clone(batchItem));
    });

    batch.length && this.api.dispatchAction({
        type: 'dataZoom',
        from: this.uid,
        batch: batch
    });
};

function retrieveAxisSetting(option) {
    var setting = {};
    // Compatible with previous setting: null => all axis, false => no axis.
    each$1(['xAxisIndex', 'yAxisIndex'], function (name) {
        setting[name] = option[name];
        setting[name] == null && (setting[name] = 'all');
        (setting[name] === false || setting[name] === 'none') && (setting[name] = []);
    });
    return setting;
}

function updateBackBtnStatus(featureModel, ecModel) {
    featureModel.setIconStatus(
        'back',
        count(ecModel) > 1 ? 'emphasis' : 'normal'
    );
}

function updateZoomBtnStatus(featureModel, ecModel, view, payload, api) {
    var zoomActive = view._isZoomActive;

    if (payload && payload.type === 'takeGlobalCursor') {
        zoomActive = payload.key === 'dataZoomSelect'
            ? payload.dataZoomSelectActive : false;
    }

    view._isZoomActive = zoomActive;

    featureModel.setIconStatus('zoom', zoomActive ? 'emphasis' : 'normal');

    var brushTargetManager = new BrushTargetManager(
        retrieveAxisSetting(featureModel.option), ecModel, {include: ['grid']}
    );

    view._brushController
        .setPanels(brushTargetManager.makePanelOpts(api, function (targetInfo) {
            return (targetInfo.xAxisDeclared && !targetInfo.yAxisDeclared)
                ? 'lineX'
                : (!targetInfo.xAxisDeclared && targetInfo.yAxisDeclared)
                ? 'lineY'
                : 'rect';
        }))
        .enableBrush(
            zoomActive
            ? {
                brushType: 'auto',
                brushStyle: featureModel.getModel('brushStyle').getItemStyle()
            }
            : false
        );
}


register$2('dataZoom', DataZoom);


// Create special dataZoom option for select
// FIXME consider the case of merge option, where axes options are not exists.
registerPreprocessor(function (option) {
    if (!option) {
        return;
    }

    var dataZoomOpts = option.dataZoom || (option.dataZoom = []);
    if (!isArray(dataZoomOpts)) {
        option.dataZoom = dataZoomOpts = [dataZoomOpts];
    }

    var toolboxOpt = option.toolbox;
    if (toolboxOpt) {
        // Assume there is only one toolbox
        if (isArray(toolboxOpt)) {
            toolboxOpt = toolboxOpt[0];
        }

        if (toolboxOpt && toolboxOpt.feature) {
            var dataZoomOpt = toolboxOpt.feature.dataZoom;
            // FIXME: If add dataZoom when setOption in merge mode,
            // no axis info to be added. See `test/dataZoom-extreme.html`
            addForAxis('xAxis', dataZoomOpt);
            addForAxis('yAxis', dataZoomOpt);
        }
    }

    function addForAxis(axisName, dataZoomOpt) {
        if (!dataZoomOpt) {
            return;
        }

        // Try not to modify model, because it is not merged yet.
        var axisIndicesName = axisName + 'Index';
        var givenAxisIndices = dataZoomOpt[axisIndicesName];
        if (givenAxisIndices != null
            && givenAxisIndices !== 'all'
            && !isArray(givenAxisIndices)
        ) {
            givenAxisIndices = (givenAxisIndices === false || givenAxisIndices === 'none') ? [] : [givenAxisIndices];
        }

        forEachComponent(axisName, function (axisOpt, axisIndex) {
            if (givenAxisIndices != null
                && givenAxisIndices !== 'all'
                && indexOf(givenAxisIndices, axisIndex) === -1
            ) {
                return;
            }
            var newOpt = {
                type: 'select',
                $fromToolbox: true,
                // Default to be filter
                filterMode: dataZoomOpt.filterMode || 'filter',
                // Id for merge mapping.
                id: DATA_ZOOM_ID_BASE + axisName + axisIndex
            };
            // FIXME
            // Only support one axis now.
            newOpt[axisIndicesName] = axisIndex;
            dataZoomOpts.push(newOpt);
        });
    }

    function forEachComponent(mainType, cb) {
        var opts = option[mainType];
        if (!isArray(opts)) {
            opts = opts ? [opts] : [];
        }
        each$15(opts, cb);
    }
});

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var restoreLang = lang.toolbox.restore;

function Restore(model) {
    this.model = model;
}

Restore.defaultOption = {
    show: true,
    /* eslint-disable */
    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',
    /* eslint-enable */
    title: restoreLang.title
};

var proto$6 = Restore.prototype;

proto$6.onclick = function (ecModel, api, type) {
    clear$1(ecModel);

    api.dispatchAction({
        type: 'restore',
        from: this.uid
    });
};

register$2('restore', Restore);

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

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

var urn = 'urn:schemas-microsoft-com:vml';
var win = typeof window === 'undefined' ? null : window;

var vmlInited = false;

var doc = win && win.document;

function createNode(tagName) {
    return doCreateNode(tagName);
}

// Avoid assign to an exported variable, for transforming to cjs.
var doCreateNode;

if (doc && !env$1.canvasSupported) {
    try {
        !doc.namespaces.zrvml && doc.namespaces.add('zrvml', urn);
        doCreateNode = function (tagName) {
            return doc.createElement('<zrvml:' + tagName + ' class="zrvml">');
        };
    }
    catch (e) {
        doCreateNode = function (tagName) {
            return doc.createElement('<' + tagName + ' xmlns="' + urn + '" class="zrvml">');
        };
    }
}

// From raphael
function initVML() {
    if (vmlInited || !doc) {
        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)');
    }
}

// http://www.w3.org/TR/NOTE-VML
// TODO Use proxy like svg instead of overwrite brush methods

var CMD$3 = PathProxy.CMD;
var round$2 = Math.round;
var sqrt = Math.sqrt;
var abs$1 = Math.abs;
var cos = Math.cos;
var sin = Math.sin;
var mathMax$6 = Math.max;

if (!env$1.canvasSupported) {

    var comma = ',';
    var imageTransformPrefix = 'progid:DXImageTransform.Microsoft';

    var Z = 21600;
    var Z2 = Z / 2;

    var ZLEVEL_BASE = 100000;
    var Z_BASE = 1000;

    var initRootElStyle = function (el) {
        el.style.cssText = 'position:absolute;left:0;top:0;width:1px;height:1px;';
        el.coordsize = Z + ',' + Z;
        el.coordorigin = '0,0';
    };

    var encodeHtmlAttribute = function (s) {
        return String(s).replace(/&/g, '&amp;').replace(/"/g, '&quot;');
    };

    var rgb2Str = function (r, g, b) {
        return 'rgb(' + [r, g, b].join(',') + ')';
    };

    var append = function (parent, child) {
        if (child && parent && child.parentNode !== parent) {
            parent.appendChild(child);
        }
    };

    var remove = function (parent, child) {
        if (child && parent && child.parentNode === parent) {
            parent.removeChild(child);
        }
    };

    var getZIndex = function (zlevel, z, z2) {
        // z 的取值范围为 [0, 1000]
        return (parseFloat(zlevel) || 0) * ZLEVEL_BASE + (parseFloat(z) || 0) * Z_BASE + z2;
    };

    var parsePercent$3 = parsePercent;

    /***************************************************
     * PATH
     **************************************************/

    var setColorAndOpacity = function (el, color, opacity) {
        var colorArr = parse(color);
        opacity = +opacity;
        if (isNaN(opacity)) {
            opacity = 1;
        }
        if (colorArr) {
            el.color = rgb2Str(colorArr[0], colorArr[1], colorArr[2]);
            el.opacity = opacity * colorArr[3];
        }
    };

    var getColorAndAlpha = function (color) {
        var colorArr = parse(color);
        return [
            rgb2Str(colorArr[0], colorArr[1], colorArr[2]),
            colorArr[3]
        ];
    };

    var updateFillNode = function (el, style, zrEl) {
        // TODO pattern
        var fill = style.fill;
        if (fill != null) {
            // Modified from excanvas
            if (fill instanceof Gradient) {
                var gradientType;
                var angle = 0;
                var focus = [0, 0];
                // additional offset
                var shift = 0;
                // scale factor for offset
                var expansion = 1;
                var rect = zrEl.getBoundingRect();
                var rectWidth = rect.width;
                var rectHeight = rect.height;
                if (fill.type === 'linear') {
                    gradientType = 'gradient';
                    var transform = zrEl.transform;
                    var p0 = [fill.x * rectWidth, fill.y * rectHeight];
                    var p1 = [fill.x2 * rectWidth, fill.y2 * rectHeight];
                    if (transform) {
                        applyTransform(p0, p0, transform);
                        applyTransform(p1, p1, transform);
                    }
                    var dx = p1[0] - p0[0];
                    var dy = p1[1] - p0[1];
                    angle = Math.atan2(dx, dy) * 180 / Math.PI;
                    // The angle should be a non-negative number.
                    if (angle < 0) {
                        angle += 360;
                    }

                    // Very small angles produce an unexpected result because they are
                    // converted to a scientific notation string.
                    if (angle < 1e-6) {
                        angle = 0;
                    }
                }
                else {
                    gradientType = 'gradientradial';
                    var p0 = [fill.x * rectWidth, fill.y * rectHeight];
                    var transform = zrEl.transform;
                    var scale$$1 = 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$$1[0] * Z;
                    height /= scale$$1[1] * Z;
                    var dimension = mathMax$6(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$$1 = stops.length;
                // Color and alpha list of first and last stop
                var colorAndAlphaList = [];
                var colors = [];
                for (var i = 0; i < length$$1; i++) {
                    var stop = stops[i];
                    var colorAndAlpha = getColorAndAlpha(stop.color);
                    colors.push(stop.offset * expansion + shift + ' ' + colorAndAlpha[0]);
                    if (i === 0 || i === length$$1 - 1) {
                        colorAndAlphaList.push(colorAndAlpha);
                    }
                }

                if (length$$1 >= 2) {
                    var color1 = colorAndAlphaList[0][0];
                    var color2 = colorAndAlphaList[1][0];
                    var opacity1 = colorAndAlphaList[0][1] * style.opacity;
                    var opacity2 = colorAndAlphaList[1][1] * style.opacity;

                    el.type = gradientType;
                    el.method = 'none';
                    el.focus = '100%';
                    el.angle = angle;
                    el.color = color1;
                    el.color2 = color2;
                    el.colors = colors.join(',');
                    // When colors attribute is used, the meanings of opacity and o:opacity2
                    // are reversed.
                    el.opacity = opacity2;
                    // FIXME g_o_:opacity ?
                    el.opacity2 = opacity1;
                }
                if (gradientType === 'radial') {
                    el.focusposition = focus.join(',');
                }
            }
            else {
                // FIXME Change from Gradient fill to color fill
                setColorAndOpacity(el, fill, style.opacity);
            }
        }
    };

    var updateStrokeNode = function (el, style) {
        // if (style.lineJoin != null) {
        //     el.joinstyle = style.lineJoin;
        // }
        // if (style.miterLimit != null) {
        //     el.miterlimit = style.miterLimit * Z;
        // }
        // if (style.lineCap != null) {
        //     el.endcap = style.lineCap;
        // }
        if (style.lineDash) {
            el.dashstyle = style.lineDash.join(' ');
        }
        if (style.stroke != null && !(style.stroke instanceof Gradient)) {
            setColorAndOpacity(el, style.stroke, style.opacity);
        }
    };

    var updateFillAndStroke = function (vmlEl, type, style, zrEl) {
        var isFill = type === 'fill';
        var el = vmlEl.getElementsByTagName(type)[0];
        // Stroke must have lineWidth
        if (style[type] != null && style[type] !== 'none' && (isFill || (!isFill && style.lineWidth))) {
            vmlEl[isFill ? 'filled' : 'stroked'] = 'true';
            // FIXME Remove before updating, or set `colors` will throw error
            if (style[type] instanceof Gradient) {
                remove(vmlEl, el);
            }
            if (!el) {
                el = createNode(type);
            }

            isFill ? updateFillNode(el, style, zrEl) : updateStrokeNode(el, style);
            append(vmlEl, el);
        }
        else {
            vmlEl[isFill ? 'filled' : 'stroked'] = 'false';
            remove(vmlEl, el);
        }
    };

    var points$1 = [[], [], []];
    var pathDataToString = function (path, m) {
        var M = CMD$3.M;
        var C = CMD$3.C;
        var L = CMD$3.L;
        var A = CMD$3.A;
        var Q = CMD$3.Q;

        var str = [];
        var nPoint;
        var cmdStr;
        var cmd;
        var i;
        var xi;
        var yi;
        var data = path.data;
        var dataLength = path.len();
        for (i = 0; i < dataLength;) {
            cmd = data[i++];
            cmdStr = '';
            nPoint = 0;
            switch (cmd) {
                case M:
                    cmdStr = ' m ';
                    nPoint = 1;
                    xi = data[i++];
                    yi = data[i++];
                    points$1[0][0] = xi;
                    points$1[0][1] = yi;
                    break;
                case L:
                    cmdStr = ' l ';
                    nPoint = 1;
                    xi = data[i++];
                    yi = data[i++];
                    points$1[0][0] = xi;
                    points$1[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$1[0][0] = x1;
                    points$1[0][1] = y1;
                    points$1[1][0] = x2;
                    points$1[1][1] = y2;
                    points$1[2][0] = x3;
                    points$1[2][1] = y3;

                    xi = x3;
                    yi = y3;
                    break;
                case A:
                    var x = 0;
                    var y = 0;
                    var sx = 1;
                    var sy = 1;
                    var angle = 0;
                    if (m) {
                        // Extract SRT from matrix
                        x = m[4];
                        y = m[5];
                        sx = sqrt(m[0] * m[0] + m[1] * m[1]);
                        sy = sqrt(m[2] * m[2] + m[3] * m[3]);
                        angle = Math.atan2(-m[1] / sy, m[0] / sx);
                    }

                    var cx = data[i++];
                    var cy = data[i++];
                    var rx = data[i++];
                    var ry = data[i++];
                    var startAngle = data[i++] + angle;
                    var endAngle = data[i++] + startAngle + angle;
                    // FIXME
                    // var psi = data[i++];
                    i++;
                    var clockwise = data[i++];

                    var x0 = cx + cos(startAngle) * rx;
                    var y0 = cy + sin(startAngle) * ry;

                    var x1 = cx + cos(endAngle) * rx;
                    var y1 = cy + sin(endAngle) * ry;

                    var type = clockwise ? ' wa ' : ' at ';
                    if (Math.abs(x0 - x1) < 1e-4) {
                        // IE won't render arches drawn counter clockwise if x0 == x1.
                        if (Math.abs(endAngle - startAngle) > 1e-2) {
                            // Offset x0 by 1/80 of a pixel. Use something
                            // that can be represented in binary
                            if (clockwise) {
                                x0 += 270 / Z;
                            }
                        }
                        else {
                            // Avoid case draw full circle
                            if (Math.abs(y0 - cy) < 1e-4) {
                                if ((clockwise && x0 < cx) || (!clockwise && x0 > cx)) {
                                    y1 -= 270 / Z;
                                }
                                else {
                                    y1 += 270 / Z;
                                }
                            }
                            else if ((clockwise && y0 < cy) || (!clockwise && y0 > cy)) {
                                x1 += 270 / Z;
                            }
                            else {
                                x1 -= 270 / Z;
                            }
                        }
                    }
                    str.push(
                        type,
                        round$2(((cx - rx) * sx + x) * Z - Z2), comma,
                        round$2(((cy - ry) * sy + y) * Z - Z2), comma,
                        round$2(((cx + rx) * sx + x) * Z - Z2), comma,
                        round$2(((cy + ry) * sy + y) * Z - Z2), comma,
                        round$2((x0 * sx + x) * Z - Z2), comma,
                        round$2((y0 * sy + y) * Z - Z2), comma,
                        round$2((x1 * sx + x) * Z - Z2), comma,
                        round$2((y1 * sy + y) * Z - Z2)
                    );

                    xi = x1;
                    yi = y1;
                    break;
                case CMD$3.R:
                    var p0 = points$1[0];
                    var p1 = points$1[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$2(p0[0] * Z - Z2);
                    p1[0] = round$2(p1[0] * Z - Z2);
                    p0[1] = round$2(p0[1] * Z - Z2);
                    p1[1] = round$2(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$3.Z:
                    // FIXME Update xi, yi
                    str.push(' x ');
            }

            if (nPoint > 0) {
                str.push(cmdStr);
                for (var k = 0; k < nPoint; k++) {
                    var p = points$1[k];

                    m && applyTransform(p, p, m);
                    // 不 round 会非常慢
                    str.push(
                        round$2(p[0] * Z - Z2), comma, round$2(p[1] * Z - Z2),
                        k < nPoint - 1 ? comma : ''
                    );
                }
            }
        }

        return str.join('');
    };

    // Rewrite the original path method
    Path.prototype.brushVML = function (vmlRoot) {
        var style = this.style;

        var vmlEl = this._vmlEl;
        if (!vmlEl) {
            vmlEl = 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$1(det));
            }
            strokeEl.weight = lineWidth + 'px';
        }

        var path = this.path || (this.path = new PathProxy());
        if (this.__dirtyPath) {
            path.beginPath();
            path.subPixelOptimize = false;
            this.buildPath(path, this.shape);
            path.toStatic();
            this.__dirtyPath = false;
        }

        vmlEl.path = pathDataToString(path, this.transform);

        vmlEl.style.zIndex = getZIndex(this.zlevel, this.z, this.z2);

        // Append to root
        append(vmlRoot, vmlEl);

        // Text
        if (style.text != null) {
            this.drawRectText(vmlRoot, this.getBoundingRect());
        }
        else {
            this.removeRectText(vmlRoot);
        }
    };

    Path.prototype.onRemove = function (vmlRoot) {
        remove(vmlRoot, this._vmlEl);
        this.removeRectText(vmlRoot);
    };

    Path.prototype.onAdd = function (vmlRoot) {
        append(vmlRoot, this._vmlEl);
        this.appendRectText(vmlRoot);
    };

    /***************************************************
     * IMAGE
     **************************************************/
    var isImage = function (img) {
        // FIXME img instanceof Image 如果 img 是一个字符串的时候，IE8 下会报错
        return (typeof img === 'object') && img.tagName && img.tagName.toUpperCase() === 'IMG';
        // return img instanceof Image;
    };

    // Rewrite the original path method
    ZImage.prototype.brushVML = function (vmlRoot) {
        var style = this.style;
        var image = style.image;

        // Image original width, height
        var ow;
        var oh;

        if (isImage(image)) {
            var src = image.src;
            if (src === this._imageSrc) {
                ow = this._imageWidth;
                oh = this._imageHeight;
            }
            else {
                var imageRuntimeStyle = image.runtimeStyle;
                var oldRuntimeWidth = imageRuntimeStyle.width;
                var oldRuntimeHeight = imageRuntimeStyle.height;
                imageRuntimeStyle.width = 'auto';
                imageRuntimeStyle.height = 'auto';

                // get the original size
                ow = image.width;
                oh = image.height;

                // and remove overides
                imageRuntimeStyle.width = oldRuntimeWidth;
                imageRuntimeStyle.height = oldRuntimeHeight;

                // Caching image original width, height and src
                this._imageSrc = src;
                this._imageWidth = ow;
                this._imageHeight = oh;
            }
            image = src;
        }
        else {
            if (image === this._imageSrc) {
                ow = this._imageWidth;
                oh = this._imageHeight;
            }
        }
        if (!image) {
            return;
        }

        var x = style.x || 0;
        var y = style.y || 0;

        var dw = style.width;
        var dh = style.height;

        var sw = style.sWidth;
        var sh = style.sHeight;
        var sx = style.sx || 0;
        var sy = style.sy || 0;

        var hasCrop = sw && sh;

        var vmlEl = this._vmlEl;
        if (!vmlEl) {
            // FIXME 使用 group 在 left, top 都不是 0 的时候就无法显示了。
            // vmlEl = vmlCore.createNode('group');
            vmlEl = 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$6(p0[0], p1[0], p2[0], p3[0]);
            var maxY = mathMax$6(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$2(x * scaleX + m[4]), comma,
                        'Dy=', round$2(y * scaleY + m[5]));

            vmlElStyle.padding = '0 ' + round$2(maxX) + 'px ' + round$2(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$2(x) + 'px';
            vmlElStyle.top = round$2(y) + 'px';
        }

        var imageEl = this._imageEl;
        var cropEl = this._cropEl;

        if (!imageEl) {
            imageEl = 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$2(scaleX * ow * dw / sw) + 'px';
                    imageELStyle.height = round$2(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$2(scaleX * ow * dw / sw) + 'px';
                imageELStyle.height = round$2(scaleY * oh * dh / sh) + 'px';
            }

            if (!cropEl) {
                cropEl = doc.createElement('div');
                cropEl.style.overflow = 'hidden';
                this._cropEl = cropEl;
            }
            var cropElStyle = cropEl.style;
            cropElStyle.width = round$2((dw + sx * dw / sw) * scaleX);
            cropElStyle.height = round$2((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$2(scaleX * dw) + 'px';
            imageELStyle.height = round$2(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$2(alpha * 100) + ') ';
        }
        filterStr += imageTransformPrefix + '.AlphaImageLoader(src=' + image + ', SizingMethod=scale)';

        imageELStyle.filter = filterStr;

        vmlEl.style.zIndex = getZIndex(this.zlevel, this.z, this.z2);

        // Append to root
        append(vmlRoot, vmlEl);

        // Text
        if (style.text != null) {
            this.drawRectText(vmlRoot, this.getBoundingRect());
        }
    };

    ZImage.prototype.onRemove = function (vmlRoot) {
        remove(vmlRoot, this._vmlEl);

        this._vmlEl = null;
        this._cropEl = null;
        this._imageEl = null;

        this.removeRectText(vmlRoot);
    };

    ZImage.prototype.onAdd = function (vmlRoot) {
        append(vmlRoot, this._vmlEl);
        this.appendRectText(vmlRoot);
    };


    /***************************************************
     * TEXT
     **************************************************/

    var DEFAULT_STYLE_NORMAL = 'normal';

    var fontStyleCache = {};
    var fontStyleCacheCount = 0;
    var MAX_FONT_CACHE_SIZE = 100;
    var fontEl = document.createElement('div');

    var getFontStyle = function (fontString) {
        var fontStyle = fontStyleCache[fontString];
        if (!fontStyle) {
            // Clear cache
            if (fontStyleCacheCount > MAX_FONT_CACHE_SIZE) {
                fontStyleCacheCount = 0;
                fontStyleCache = {};
            }

            var style = fontEl.style;
            var fontFamily;
            try {
                style.font = fontString;
                fontFamily = style.fontFamily.split(',')[0];
            }
            catch (e) {
            }

            fontStyle = {
                style: style.fontStyle || DEFAULT_STYLE_NORMAL,
                variant: style.fontVariant || DEFAULT_STYLE_NORMAL,
                weight: style.fontWeight || DEFAULT_STYLE_NORMAL,
                size: parseFloat(style.fontSize || 12) | 0,
                family: fontFamily || 'Microsoft YaHei'
            };

            fontStyleCache[fontString] = fontStyle;
            fontStyleCacheCount++;
        }
        return fontStyle;
    };

    var textMeasureEl;
    // Overwrite measure text method
    $override$1('measureText', function (text, textFont) {
        var doc$$1 = doc;
        if (!textMeasureEl) {
            textMeasureEl = doc$$1.createElement('div');
            textMeasureEl.style.cssText = 'position:absolute;top:-20000px;left:0;'
                + 'padding:0;margin:0;border:none;white-space:pre;';
            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$$1.createTextNode(text));
        return {
            width: textMeasureEl.offsetWidth
        };
    });

    var tmpRect$2 = new BoundingRect();

    var drawRectText = function (vmlRoot, rect, textRect, fromTextEl) {

        var style = this.style;

        // Optimize, avoid normalize every time.
        this.__dirty && normalizeTextStyle(style, true);

        var text = style.text;
        // Convert to string
        text != null && (text += '');
        if (!text) {
            return;
        }

        // Convert rich text to plain text. Rich text is not supported in
        // IE8-, but tags in rich text template will be removed.
        if (style.rich) {
            var contentBlock = parseRichText(text, style);
            text = [];
            for (var i = 0; i < contentBlock.lines.length; i++) {
                var tokens = contentBlock.lines[i].tokens;
                var textLine = [];
                for (var j = 0; j < tokens.length; j++) {
                    textLine.push(tokens[j].text);
                }
                text.push(textLine.join(''));
            }
            text = text.join('\n');
        }

        var x;
        var y;
        var align = style.textAlign;
        var verticalAlign = style.textVerticalAlign;

        var fontStyle = getFontStyle(style.font);
        // FIXME encodeHtmlAttribute ?
        var font = fontStyle.style + ' ' + fontStyle.variant + ' ' + fontStyle.weight + ' '
            + fontStyle.size + 'px "' + fontStyle.family + '"';

        textRect = textRect || getBoundingRect(
            text, font, align, verticalAlign, style.textPadding, style.textLineHeight
        );

        // Transform rect to view space
        var m = this.transform;
        // Ignore transform for text in other element
        if (m && !fromTextEl) {
            tmpRect$2.copy(rect);
            tmpRect$2.applyTransform(m);
            rect = tmpRect$2;
        }

        if (!fromTextEl) {
            var textPosition = style.textPosition;
            // Text position represented by coord
            if (textPosition instanceof Array) {
                x = rect.x + parsePercent$3(textPosition[0], rect.width);
                y = rect.y + parsePercent$3(textPosition[1], rect.height);

                align = align || 'left';
            }
            else {
                var res = this.calculateTextPosition
                    ? this.calculateTextPosition({}, style, rect)
                    : calculateTextPosition({}, style, rect);
                x = res.x;
                y = res.y;

                // Default align and baseline when has textPosition
                align = align || res.textAlign;
                verticalAlign = verticalAlign || res.textVerticalAlign;
            }
        }
        else {
            x = rect.x;
            y = rect.y;
        }

        x = adjustTextX(x, textRect.width, align);
        y = adjustTextY(y, textRect.height, verticalAlign);

        // Force baseline 'middle'
        y += textRect.height / 2;

        // 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$$1 = createNode;

        var textVmlEl = this._textVmlEl;
        var pathEl;
        var textPathEl;
        var skewEl;
        if (!textVmlEl) {
            textVmlEl = createNode$$1('line');
            pathEl = createNode$$1('path');
            textPathEl = createNode$$1('textpath');
            skewEl = createNode$$1('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$2(coords[0]) || 0) + ',' + (round$2(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$2(x) + 'px';
            textVmlElStyle.top = round$2(y) + 'px';
        }

        textPathEl.string = encodeHtmlAttribute(text);
        // TODO
        try {
            textPathEl.style.font = font;
        }
        // Error font format
        catch (e) {}

        updateFillAndStroke(textVmlEl, 'fill', {
            fill: style.textFill,
            opacity: style.opacity
        }, this);
        updateFillAndStroke(textVmlEl, 'stroke', {
            stroke: style.textStroke,
            opacity: style.opacity,
            lineDash: style.lineDash || null // style.lineDash can be `false`.
        }, this);

        textVmlEl.style.zIndex = getZIndex(this.zlevel, this.z, this.z2);

        // Attached to root
        append(vmlRoot, textVmlEl);
    };

    var removeRectText = function (vmlRoot) {
        remove(vmlRoot, this._textVmlEl);
        this._textVmlEl = null;
    };

    var appendRectText = function (vmlRoot) {
        append(vmlRoot, this._textVmlEl);
    };

    var list = [RectText, Displayable, ZImage, Path, Text];

    // In case Displayable has been mixed in RectText
    for (var i$1 = 0; i$1 < list.length; i$1++) {
        var proto$7 = list[i$1].prototype;
        proto$7.drawRectText = drawRectText;
        proto$7.removeRectText = removeRectText;
        proto$7.appendRectText = appendRectText;
    }

    Text.prototype.brushVML = function (vmlRoot) {
        var style = this.style;
        if (style.text != null) {
            this.drawRectText(vmlRoot, {
                x: style.x || 0, y: style.y || 0,
                width: 0, height: 0
            }, this.getBoundingRect(), true);
        }
        else {
            this.removeRectText(vmlRoot);
        }
    };

    Text.prototype.onRemove = function (vmlRoot) {
        this.removeRectText(vmlRoot);
    };

    Text.prototype.onAdd = function (vmlRoot) {
        this.appendRectText(vmlRoot);
    };
}

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

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

/**
 * @alias module:zrender/vml/Painter
 */
function VMLPainter(root, storage) {

    initVML();

    this.root = root;

    this.storage = storage;

    var vmlViewport = document.createElement('div');

    var vmlRoot = document.createElement('div');

    vmlViewport.style.cssText = 'display:inline-block;overflow:hidden;position:relative;width:300px;height:150px;';

    vmlRoot.style.cssText = 'position:absolute;left:0;top:0;';

    root.appendChild(vmlViewport);

    this._vmlRoot = vmlRoot;
    this._vmlViewport = vmlViewport;

    this.resize();

    // Modify storage
    var oldDelFromStorage = storage.delFromStorage;
    var oldAddToStorage = storage.addToStorage;
    storage.delFromStorage = function (el) {
        oldDelFromStorage.call(storage, el);

        if (el) {
            el.onRemove && el.onRemove(vmlRoot);
        }
    };

    storage.addToStorage = function (el) {
        // Displayable already has a vml node
        el.onAdd && el.onAdd(vmlRoot);

        oldAddToStorage.call(storage, el);
    };

    this._firstPaint = true;
}

VMLPainter.prototype = {

    constructor: VMLPainter,

    getType: function () {
        return 'vml';
    },

    /**
     * @return {HTMLDivElement}
     */
    getViewportRoot: function () {
        return this._vmlViewport;
    },

    getViewportRootOffset: function () {
        var viewportRoot = this.getViewportRoot();
        if (viewportRoot) {
            return {
                offsetLeft: viewportRoot.offsetLeft || 0,
                offsetTop: viewportRoot.offsetTop || 0
            };
        }
    },

    /**
     * 刷新
     */
    refresh: function () {

        var list = this.storage.getDisplayList(true, true);

        this._paintList(list);
    },

    _paintList: function (list) {
        var vmlRoot = this._vmlRoot;
        for (var i = 0; i < list.length; i++) {
            var el = list[i];
            if (el.invisible || el.ignore) {
                if (!el.__alreadyNotVisible) {
                    el.onRemove(vmlRoot);
                }
                // Set as already invisible
                el.__alreadyNotVisible = true;
            }
            else {
                if (el.__alreadyNotVisible) {
                    el.onAdd(vmlRoot);
                }
                el.__alreadyNotVisible = false;
                if (el.__dirty) {
                    el.beforeBrush && el.beforeBrush();
                    (el.brushVML || el.brush).call(el, vmlRoot);
                    el.afterBrush && el.afterBrush();
                }
            }
            el.__dirty = false;
        }

        if (this._firstPaint) {
            // Detached from document at first time
            // to avoid page refreshing too many times

            // FIXME 如果每次都先 removeChild 可能会导致一些填充和描边的效果改变
            this._vmlViewport.appendChild(vmlRoot);
            this._firstPaint = false;
        }
    },

    resize: function (width, height) {
        var width = width == null ? this._getWidth() : width;
        var height = height == null ? this._getHeight() : height;

        if (this._width !== width || this._height !== height) {
            this._width = width;
            this._height = height;

            var vmlViewportStyle = this._vmlViewport.style;
            vmlViewportStyle.width = width + 'px';
            vmlViewportStyle.height = height + 'px';
        }
    },

    dispose: function () {
        this.root.innerHTML = '';

        this._vmlRoot =
        this._vmlViewport =
        this.storage = null;
    },

    getWidth: function () {
        return this._width;
    },

    getHeight: function () {
        return this._height;
    },

    clear: function () {
        if (this._vmlViewport) {
            this.root.removeChild(this._vmlViewport);
        }
    },

    _getWidth: function () {
        var root = this.root;
        var stl = root.currentStyle;

        return ((root.clientWidth || parseInt10$1(stl.width))
                - parseInt10$1(stl.paddingLeft)
                - parseInt10$1(stl.paddingRight)) | 0;
    },

    _getHeight: function () {
        var root = this.root;
        var stl = root.currentStyle;

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

// Not supported methods
function createMethodNotSupport(method) {
    return function () {
        logError$1('In IE8.0 VML mode painter not support method "' + method + '"');
    };
}

// Unsupported methods
each$1([
    'getLayer', 'insertLayer', 'eachLayer', 'eachBuiltinLayer', 'eachOtherLayer', 'getLayers',
    'modLayer', 'delLayer', 'clearLayer', 'toDataURL', 'pathToImage'
], function (name) {
    VMLPainter.prototype[name] = createMethodNotSupport(name);
});

registerPainter('vml', VMLPainter);

var svgURI = 'http://www.w3.org/2000/svg';

function createElement(name) {
    return document.createElementNS(svgURI, name);
}

// TODO
// 1. shadow
// 2. Image: sx, sy, sw, sh

var CMD$4 = PathProxy.CMD;
var arrayJoin = Array.prototype.join;

var NONE = 'none';
var mathRound = Math.round;
var mathSin$3 = Math.sin;
var mathCos$3 = Math.cos;
var PI$3 = Math.PI;
var PI2$5 = Math.PI * 2;
var degree = 180 / PI$3;

var EPSILON$4 = 1e-4;

function round4(val) {
    return mathRound(val * 1e4) / 1e4;
}

function isAroundZero$1(val) {
    return val < EPSILON$4 && val > -EPSILON$4;
}

function pathHasFill(style, isText) {
    var fill = isText ? style.textFill : style.fill;
    return fill != null && fill !== NONE;
}

function pathHasStroke(style, isText) {
    var stroke = isText ? style.textStroke : style.stroke;
    return stroke != null && stroke !== NONE;
}

function setTransform(svgEl, m) {
    if (m) {
        attr(svgEl, 'transform', 'matrix(' + arrayJoin.call(m, ',') + ')');
    }
}

function attr(el, key, val) {
    if (!val || val.type !== 'linear' && val.type !== 'radial') {
        // Don't set attribute for gradient, since it need new dom nodes
        el.setAttribute(key, val);
    }
}

function attrXLink(el, key, val) {
    el.setAttributeNS('http://www.w3.org/1999/xlink', key, val);
}

function bindStyle(svgEl, style, isText, el) {
    if (pathHasFill(style, isText)) {
        var fill = isText ? style.textFill : style.fill;
        fill = fill === 'transparent' ? NONE : fill;
        attr(svgEl, 'fill', fill);
        attr(svgEl, 'fill-opacity', style.fillOpacity != null ? style.fillOpacity * style.opacity : style.opacity);
    }
    else {
        attr(svgEl, 'fill', NONE);
    }

    if (pathHasStroke(style, isText)) {
        var stroke = isText ? style.textStroke : style.stroke;
        stroke = stroke === 'transparent' ? NONE : stroke;
        attr(svgEl, 'stroke', stroke);
        var strokeWidth = isText
            ? style.textStrokeWidth
            : style.lineWidth;
        var strokeScale = !isText && style.strokeNoScale
            ? el.getLineScale()
            : 1;
        attr(svgEl, 'stroke-width', strokeWidth / strokeScale);
        // stroke then fill for text; fill then stroke for others
        attr(svgEl, 'paint-order', isText ? 'stroke' : 'fill');
        attr(svgEl, 'stroke-opacity', style.strokeOpacity != null ? style.strokeOpacity : style.opacity);
        var lineDash = style.lineDash;
        if (lineDash) {
            attr(svgEl, 'stroke-dasharray', style.lineDash.join(','));
            attr(svgEl, 'stroke-dashoffset', mathRound(style.lineDashOffset || 0));
        }
        else {
            attr(svgEl, 'stroke-dasharray', '');
        }

        // PENDING
        style.lineCap && attr(svgEl, 'stroke-linecap', style.lineCap);
        style.lineJoin && attr(svgEl, 'stroke-linejoin', style.lineJoin);
        style.miterLimit && attr(svgEl, 'stroke-miterlimit', style.miterLimit);
    }
    else {
        attr(svgEl, 'stroke', NONE);
    }
}

/***************************************************
 * PATH
 **************************************************/
function pathDataToString$1(path) {
    var str = [];
    var data = path.data;
    var dataLength = path.len();
    for (var i = 0; i < dataLength;) {
        var cmd = data[i++];
        var cmdStr = '';
        var nData = 0;
        switch (cmd) {
            case CMD$4.M:
                cmdStr = 'M';
                nData = 2;
                break;
            case CMD$4.L:
                cmdStr = 'L';
                nData = 2;
                break;
            case CMD$4.Q:
                cmdStr = 'Q';
                nData = 4;
                break;
            case CMD$4.C:
                cmdStr = 'C';
                nData = 6;
                break;
            case CMD$4.A:
                var cx = data[i++];
                var cy = data[i++];
                var rx = data[i++];
                var ry = data[i++];
                var theta = data[i++];
                var dTheta = data[i++];
                var psi = data[i++];
                var clockwise = data[i++];

                var dThetaPositive = Math.abs(dTheta);
                var isCircle = isAroundZero$1(dThetaPositive - PI2$5)
                    || (clockwise ? dTheta >= PI2$5 : -dTheta >= PI2$5);

                // Mapping to 0~2PI
                var unifiedTheta = dTheta > 0 ? dTheta % PI2$5 : (dTheta % PI2$5 + PI2$5);

                var large = false;
                if (isCircle) {
                    large = true;
                }
                else if (isAroundZero$1(dThetaPositive)) {
                    large = false;
                }
                else {
                    large = (unifiedTheta >= PI$3) === !!clockwise;
                }

                var x0 = round4(cx + rx * mathCos$3(theta));
                var y0 = round4(cy + ry * mathSin$3(theta));

                // It will not draw if start point and end point are exactly the same
                // We need to shift the end point with a small value
                // FIXME A better way to draw circle ?
                if (isCircle) {
                    if (clockwise) {
                        dTheta = PI2$5 - 1e-4;
                    }
                    else {
                        dTheta = -PI2$5 + 1e-4;
                    }

                    large = true;

                    if (i === 9) {
                        // Move to (x0, y0) only when CMD.A comes at the
                        // first position of a shape.
                        // For instance, when drawing a ring, CMD.A comes
                        // after CMD.M, so it's unnecessary to move to
                        // (x0, y0).
                        str.push('M', x0, y0);
                    }
                }

                var x = round4(cx + rx * mathCos$3(theta + dTheta));
                var y = round4(cy + ry * mathSin$3(theta + dTheta));

                // FIXME Ellipse
                str.push('A', round4(rx), round4(ry),
                    mathRound(psi * degree), +large, +clockwise, x, y);
                break;
            case CMD$4.Z:
                cmdStr = 'Z';
                break;
            case CMD$4.R:
                var x = round4(data[i++]);
                var y = round4(data[i++]);
                var w = round4(data[i++]);
                var h = round4(data[i++]);
                str.push(
                    'M', x, y,
                    'L', x + w, y,
                    'L', x + w, y + h,
                    'L', x, y + h,
                    'L', x, y
                );
                break;
        }
        cmdStr && str.push(cmdStr);
        for (var j = 0; j < nData; j++) {
            // PENDING With scale
            str.push(round4(data[i++]));
        }
    }
    return str.join(' ');
}

var svgPath = {};
svgPath.brush = function (el) {
    var style = el.style;

    var svgEl = el.__svgEl;
    if (!svgEl) {
        svgEl = createElement('path');
        el.__svgEl = svgEl;
    }

    if (!el.path) {
        el.createPathProxy();
    }
    var path = el.path;

    if (el.__dirtyPath) {
        path.beginPath();
        path.subPixelOptimize = false;
        el.buildPath(path, el.shape);
        el.__dirtyPath = false;

        var pathStr = pathDataToString$1(path);
        if (pathStr.indexOf('NaN') < 0) {
            // Ignore illegal path, which may happen such in out-of-range
            // data in Calendar series.
            attr(svgEl, 'd', pathStr);
        }
    }

    bindStyle(svgEl, style, false, el);
    setTransform(svgEl, el.transform);

    if (style.text != null) {
        svgTextDrawRectText(el, el.getBoundingRect());
    }
    else {
        removeOldTextNode(el);
    }
};

/***************************************************
 * IMAGE
 **************************************************/
var svgImage = {};
svgImage.brush = function (el) {
    var style = el.style;
    var image = style.image;

    if (image instanceof HTMLImageElement) {
        var src = image.src;
        image = src;
    }
    if (!image) {
        return;
    }

    var x = style.x || 0;
    var y = style.y || 0;

    var dw = style.width;
    var dh = style.height;

    var svgEl = el.__svgEl;
    if (!svgEl) {
        svgEl = createElement('image');
        el.__svgEl = svgEl;
    }

    if (image !== el.__imageSrc) {
        attrXLink(svgEl, 'href', image);
        // Caching image src
        el.__imageSrc = image;
    }

    attr(svgEl, 'width', dw);
    attr(svgEl, 'height', dh);

    attr(svgEl, 'x', x);
    attr(svgEl, 'y', y);

    setTransform(svgEl, el.transform);

    if (style.text != null) {
        svgTextDrawRectText(el, el.getBoundingRect());
    }
    else {
        removeOldTextNode(el);
    }
};

/***************************************************
 * TEXT
 **************************************************/
var svgText = {};
var _tmpTextHostRect = new BoundingRect();
var _tmpTextBoxPos = {};
var _tmpTextTransform = [];
var TEXT_ALIGN_TO_ANCHRO = {
    left: 'start',
    right: 'end',
    center: 'middle',
    middle: 'middle'
};

/**
 * @param {module:zrender/Element} el
 * @param {Object|boolean} [hostRect] {x, y, width, height}
 *        If set false, rect text is not used.
 */
var svgTextDrawRectText = function (el, hostRect) {
    var style = el.style;
    var elTransform = el.transform;
    var needTransformTextByHostEl = el instanceof Text || style.transformText;

    el.__dirty && normalizeTextStyle(style, true);

    var text = style.text;
    // Convert to string
    text != null && (text += '');
    if (!needDrawText(text, style)) {
        return;
    }
    // render empty text for svg if no text but need draw text.
    text == null && (text = '');

    // Follow the setting in the canvas renderer, if not transform the
    // text, transform the hostRect, by which the text is located.
    if (!needTransformTextByHostEl && elTransform) {
        _tmpTextHostRect.copy(hostRect);
        _tmpTextHostRect.applyTransform(elTransform);
        hostRect = _tmpTextHostRect;
    }

    var textSvgEl = el.__textSvgEl;
    if (!textSvgEl) {
        textSvgEl = createElement('text');
        el.__textSvgEl = textSvgEl;
    }

    // style.font has been normalized by `normalizeTextStyle`.
    var textSvgElStyle = textSvgEl.style;
    var font = style.font || DEFAULT_FONT$1;
    var computedFont = textSvgEl.__computedFont;
    if (font !== textSvgEl.__styleFont) {
        textSvgElStyle.font = textSvgEl.__styleFont = font;
        // The computedFont might not be the orginal font if it is illegal font.
        computedFont = textSvgEl.__computedFont = textSvgElStyle.font;
    }

    var textPadding = style.textPadding;
    var textLineHeight = style.textLineHeight;

    var contentBlock = el.__textCotentBlock;
    if (!contentBlock || el.__dirtyText) {
        contentBlock = el.__textCotentBlock = parsePlainText(
            text, computedFont, textPadding, textLineHeight, style.truncate
        );
    }

    var outerHeight = contentBlock.outerHeight;
    var lineHeight = contentBlock.lineHeight;

    getBoxPosition(_tmpTextBoxPos, el, style, hostRect);
    var baseX = _tmpTextBoxPos.baseX;
    var baseY = _tmpTextBoxPos.baseY;
    var textAlign = _tmpTextBoxPos.textAlign || 'left';
    var textVerticalAlign = _tmpTextBoxPos.textVerticalAlign;

    setTextTransform(
        textSvgEl, needTransformTextByHostEl, elTransform, style, hostRect, baseX, baseY
    );

    var boxY = adjustTextY(baseY, outerHeight, textVerticalAlign);
    var textX = baseX;
    var textY = boxY;

    // TODO needDrawBg
    if (textPadding) {
        textX = getTextXForPadding$1(baseX, textAlign, textPadding);
        textY += textPadding[0];
    }

    // `textBaseline` is set as 'middle'.
    textY += lineHeight / 2;

    bindStyle(textSvgEl, style, true, el);

    // FIXME
    // Add a <style> to reset all of the text font as inherit?
    // otherwise the outer <style> may set the unexpected style.

    // Font may affect position of each tspan elements
    var canCacheByTextString = contentBlock.canCacheByTextString;
    var tspanList = el.__tspanList || (el.__tspanList = []);
    var tspanOriginLen = tspanList.length;

    // Optimize for most cases, just compare text string to determine change.
    if (canCacheByTextString && el.__canCacheByTextString && el.__text === text) {
        if (el.__dirtyText && tspanOriginLen) {
            for (var idx = 0; idx < tspanOriginLen; ++idx) {
                updateTextLocation(tspanList[idx], textAlign, textX, textY + idx * lineHeight);
            }
        }
    }
    else {
        el.__text = text;
        el.__canCacheByTextString = canCacheByTextString;
        var textLines = contentBlock.lines;
        var nTextLines = textLines.length;

        var idx = 0;
        for (; idx < nTextLines; idx++) {
            // Using cached tspan elements
            var tspan = tspanList[idx];
            var singleLineText = textLines[idx];

            if (!tspan) {
                tspan = tspanList[idx] = createElement('tspan');
                textSvgEl.appendChild(tspan);
                tspan.appendChild(document.createTextNode(singleLineText));
            }
            else if (tspan.__zrText !== singleLineText) {
                tspan.innerHTML = '';
                tspan.appendChild(document.createTextNode(singleLineText));
            }
            updateTextLocation(tspan, textAlign, textX, textY + idx * lineHeight);
        }
        // Remove unused tspan elements
        if (tspanOriginLen > nTextLines) {
            for (; idx < tspanOriginLen; idx++) {
                textSvgEl.removeChild(tspanList[idx]);
            }
            tspanList.length = nTextLines;
        }
    }
};

function setTextTransform(textSvgEl, needTransformTextByHostEl, elTransform, style, hostRect, baseX, baseY) {
    identity(_tmpTextTransform);

    if (needTransformTextByHostEl && elTransform) {
        copy$1(_tmpTextTransform, elTransform);
    }

    // textRotation only apply in RectText.
    var textRotation = style.textRotation;
    if (hostRect && textRotation) {
        var origin = style.textOrigin;
        if (origin === 'center') {
            baseX = hostRect.width / 2 + hostRect.x;
            baseY = hostRect.height / 2 + hostRect.y;
        }
        else if (origin) {
            baseX = origin[0] + hostRect.x;
            baseY = origin[1] + hostRect.y;
        }

        _tmpTextTransform[4] -= baseX;
        _tmpTextTransform[5] -= baseY;
        // Positive: anticlockwise
        rotate(_tmpTextTransform, _tmpTextTransform, textRotation);
        _tmpTextTransform[4] += baseX;
        _tmpTextTransform[5] += baseY;
    }
    // See the definition in `Style.js#textOrigin`, the default
    // origin is from the result of `getBoxPosition`.

    setTransform(textSvgEl, _tmpTextTransform);
}

// FIXME merge the same code with `helper/text.js#getTextXForPadding`;
function getTextXForPadding$1(x, textAlign, textPadding) {
    return textAlign === 'right'
        ? (x - textPadding[1])
        : textAlign === 'center'
        ? (x + textPadding[3] / 2 - textPadding[1] / 2)
        : (x + textPadding[3]);
}

function updateTextLocation(tspan, textAlign, x, y) {
    // Consider different font display differently in vertial align, we always
    // set vertialAlign as 'middle', and use 'y' to locate text vertically.
    attr(tspan, 'dominant-baseline', 'middle');
    attr(tspan, 'text-anchor', TEXT_ALIGN_TO_ANCHRO[textAlign]);
    attr(tspan, 'x', x);
    attr(tspan, 'y', y);
}

function removeOldTextNode(el) {
    if (el && el.__textSvgEl) {
        // textSvgEl may has no parentNode if el has been removed temporary.
        if (el.__textSvgEl.parentNode) {
            el.__textSvgEl.parentNode.removeChild(el.__textSvgEl);
        }
        el.__textSvgEl = null;
        el.__tspanList = [];
        el.__text = null;
    }
}

svgText.drawRectText = svgTextDrawRectText;

svgText.brush = function (el) {
    var style = el.style;
    if (style.text != null) {
        svgTextDrawRectText(el, false);
    }
    else {
        removeOldTextNode(el);
    }
};

// Myers' Diff Algorithm
// Modified from https://github.com/kpdecker/jsdiff/blob/master/src/diff/base.js

function Diff() {}

Diff.prototype = {
    diff: function (oldArr, newArr, equals) {
        if (!equals) {
            equals = function (a, b) {
                return a === b;
            };
        }
        this.equals = equals;

        var self = this;

        oldArr = oldArr.slice();
        newArr = newArr.slice();
        // Allow subclasses to massage the input prior to running
        var newLen = newArr.length;
        var oldLen = oldArr.length;
        var editLength = 1;
        var maxEditLength = newLen + oldLen;
        var bestPath = [{ newPos: -1, components: [] }];

        // Seed editLength = 0, i.e. the content starts with the same values
        var oldPos = this.extractCommon(bestPath[0], newArr, oldArr, 0);
        if (bestPath[0].newPos + 1 >= newLen && oldPos + 1 >= oldLen) {
            var indices = [];
            for (var i = 0; i < newArr.length; i++) {
                indices.push(i);
            }
            // Identity per the equality and tokenizer
            return [{
                indices: indices, count: newArr.length
            }];
        }

        // Main worker method. checks all permutations of a given edit length for acceptance.
        function execEditLength() {
            for (var diagonalPath = -1 * editLength; diagonalPath <= editLength; diagonalPath += 2) {
                var basePath;
                var addPath = bestPath[diagonalPath - 1];
                var removePath = bestPath[diagonalPath + 1];
                var oldPos = (removePath ? removePath.newPos : 0) - diagonalPath;
                if (addPath) {
                    // No one else is going to attempt to use this value, clear it
                    bestPath[diagonalPath - 1] = undefined;
                }

                var canAdd = addPath && addPath.newPos + 1 < newLen;
                var canRemove = removePath && 0 <= oldPos && oldPos < oldLen;
                if (!canAdd && !canRemove) {
                    // If this path is a terminal then prune
                    bestPath[diagonalPath] = undefined;
                    continue;
                }

                // Select the diagonal that we want to branch from. We select the prior
                // path whose position in the new string is the farthest from the origin
                // and does not pass the bounds of the diff graph
                if (!canAdd || (canRemove && addPath.newPos < removePath.newPos)) {
                    basePath = clonePath(removePath);
                    self.pushComponent(basePath.components, undefined, true);
                }
                else {
                    basePath = addPath;   // No need to clone, we've pulled it from the list
                    basePath.newPos++;
                    self.pushComponent(basePath.components, true, undefined);
                }

                oldPos = self.extractCommon(basePath, newArr, oldArr, diagonalPath);

                // If we have hit the end of both strings, then we are done
                if (basePath.newPos + 1 >= newLen && oldPos + 1 >= oldLen) {
                    return buildValues(self, basePath.components, newArr, oldArr);
                }
                else {
                    // Otherwise track this path as a potential candidate and continue.
                    bestPath[diagonalPath] = basePath;
                }
            }

            editLength++;
        }

        while (editLength <= maxEditLength) {
            var ret = execEditLength();
            if (ret) {
                return ret;
            }
        }
    },

    pushComponent: function (components, added, removed) {
        var last = components[components.length - 1];
        if (last && last.added === added && last.removed === removed) {
            // We need to clone here as the component clone operation is just
            // as shallow array clone
            components[components.length - 1] = {count: last.count + 1, added: added, removed: removed };
        }
        else {
            components.push({count: 1, added: added, removed: removed });
        }
    },
    extractCommon: function (basePath, newArr, oldArr, diagonalPath) {
        var newLen = newArr.length;
        var oldLen = oldArr.length;
        var newPos = basePath.newPos;
        var oldPos = newPos - diagonalPath;
        var commonCount = 0;

        while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(newArr[newPos + 1], oldArr[oldPos + 1])) {
            newPos++;
            oldPos++;
            commonCount++;
        }

        if (commonCount) {
            basePath.components.push({count: commonCount});
        }

        basePath.newPos = newPos;
        return oldPos;
    },
    tokenize: function (value) {
        return value.slice();
    },
    join: function (value) {
        return value.slice();
    }
};

function buildValues(diff, components, newArr, oldArr) {
    var componentPos = 0;
    var componentLen = components.length;
    var newPos = 0;
    var oldPos = 0;

    for (; componentPos < componentLen; componentPos++) {
        var component = components[componentPos];
        if (!component.removed) {
            var indices = [];
            for (var i = newPos; i < newPos + component.count; i++) {
                indices.push(i);
            }
            component.indices = indices;
            newPos += component.count;
            // Common case
            if (!component.added) {
                oldPos += component.count;
            }
        }
        else {
            var indices = [];
            for (var i = oldPos; i < oldPos + component.count; i++) {
                indices.push(i);
            }
            component.indices = indices;
            oldPos += component.count;
        }
    }

    return components;
}

function clonePath(path) {
    return { newPos: path.newPos, components: path.components.slice(0) };
}

var arrayDiff = new Diff();

var arrayDiff$1 = function (oldArr, newArr, callback) {
    return arrayDiff.diff(oldArr, newArr, callback);
};

/**
 * @file Manages elements that can be defined in <defs> in SVG,
 *       e.g., gradients, clip path, etc.
 * @author Zhang Wenli
 */

var MARK_UNUSED = '0';
var MARK_USED = '1';

/**
 * Manages elements that can be defined in <defs> in SVG,
 * e.g., gradients, clip path, etc.
 *
 * @class
 * @param {number}          zrId      zrender instance id
 * @param {SVGElement}      svgRoot   root of SVG document
 * @param {string|string[]} tagNames  possible tag names
 * @param {string}          markLabel label name to make if the element
 *                                    is used
 */
function Definable(
    zrId,
    svgRoot,
    tagNames,
    markLabel,
    domName
) {
    this._zrId = zrId;
    this._svgRoot = svgRoot;
    this._tagNames = typeof tagNames === 'string' ? [tagNames] : tagNames;
    this._markLabel = markLabel;
    this._domName = domName || '_dom';

    this.nextId = 0;
}


Definable.prototype.createElement = createElement;


/**
 * Get the <defs> tag for svgRoot; optionally creates one if not exists.
 *
 * @param {boolean} isForceCreating if need to create when not exists
 * @return {SVGDefsElement} SVG <defs> element, null if it doesn't
 * exist and isForceCreating is false
 */
Definable.prototype.getDefs = function (isForceCreating) {
    var svgRoot = this._svgRoot;
    var defs = this._svgRoot.getElementsByTagName('defs');
    if (defs.length === 0) {
        // Not exist
        if (isForceCreating) {
            defs = svgRoot.insertBefore(
                this.createElement('defs'), // Create new tag
                svgRoot.firstChild // Insert in the front of svg
            );
            if (!defs.contains) {
                // IE doesn't support contains method
                defs.contains = function (el) {
                    var children = defs.children;
                    if (!children) {
                        return false;
                    }
                    for (var i = children.length - 1; i >= 0; --i) {
                        if (children[i] === el) {
                            return true;
                        }
                    }
                    return false;
                };
            }
            return defs;
        }
        else {
            return null;
        }
    }
    else {
        return defs[0];
    }
};


/**
 * Update DOM element if necessary.
 *
 * @param {Object|string} element style element. e.g., for gradient,
 *                                it may be '#ccc' or {type: 'linear', ...}
 * @param {Function|undefined} onUpdate update callback
 */
Definable.prototype.update = function (element, onUpdate) {
    if (!element) {
        return;
    }

    var defs = this.getDefs(false);
    if (element[this._domName] && defs.contains(element[this._domName])) {
        // Update DOM
        if (typeof onUpdate === 'function') {
            onUpdate(element);
        }
    }
    else {
        // No previous dom, create new
        var dom = this.add(element);
        if (dom) {
            element[this._domName] = dom;
        }
    }
};


/**
 * Add gradient dom to defs
 *
 * @param {SVGElement} dom DOM to be added to <defs>
 */
Definable.prototype.addDom = function (dom) {
    var defs = this.getDefs(true);
    defs.appendChild(dom);
};


/**
 * Remove DOM of a given element.
 *
 * @param {SVGElement} element element to remove dom
 */
Definable.prototype.removeDom = function (element) {
    var defs = this.getDefs(false);
    if (defs && element[this._domName]) {
        defs.removeChild(element[this._domName]);
        element[this._domName] = null;
    }
};


/**
 * Get DOMs of this element.
 *
 * @return {HTMLDomElement} doms of this defineable elements in <defs>
 */
Definable.prototype.getDoms = function () {
    var defs = this.getDefs(false);
    if (!defs) {
        // No dom when defs is not defined
        return [];
    }

    var doms = [];
    each$1(this._tagNames, function (tagName) {
        var tags = defs.getElementsByTagName(tagName);
        // Note that tags is HTMLCollection, which is array-like
        // rather than real array.
        // So `doms.concat(tags)` add tags as one object.
        doms = doms.concat([].slice.call(tags));
    });

    return doms;
};


/**
 * Mark DOMs to be unused before painting, and clear unused ones at the end
 * of the painting.
 */
Definable.prototype.markAllUnused = function () {
    var doms = this.getDoms();
    var that = this;
    each$1(doms, function (dom) {
        dom[that._markLabel] = MARK_UNUSED;
    });
};


/**
 * Mark a single DOM to be used.
 *
 * @param {SVGElement} dom DOM to mark
 */
Definable.prototype.markUsed = function (dom) {
    if (dom) {
        dom[this._markLabel] = MARK_USED;
    }
};


/**
 * Remove unused DOMs defined in <defs>
 */
Definable.prototype.removeUnused = function () {
    var defs = this.getDefs(false);
    if (!defs) {
        // Nothing to remove
        return;
    }

    var doms = this.getDoms();
    var that = this;
    each$1(doms, function (dom) {
        if (dom[that._markLabel] !== MARK_USED) {
            // Remove gradient
            defs.removeChild(dom);
        }
    });
};


/**
 * Get SVG proxy.
 *
 * @param {Displayable} displayable displayable element
 * @return {Path|Image|Text} svg proxy of given element
 */
Definable.prototype.getSvgProxy = function (displayable) {
    if (displayable instanceof Path) {
        return svgPath;
    }
    else if (displayable instanceof ZImage) {
        return svgImage;
    }
    else if (displayable instanceof Text) {
        return svgText;
    }
    else {
        return svgPath;
    }
};


/**
 * Get text SVG element.
 *
 * @param {Displayable} displayable displayable element
 * @return {SVGElement} SVG element of text
 */
Definable.prototype.getTextSvgElement = function (displayable) {
    return displayable.__textSvgEl;
};


/**
 * Get SVG element.
 *
 * @param {Displayable} displayable displayable element
 * @return {SVGElement} SVG element
 */
Definable.prototype.getSvgElement = function (displayable) {
    return displayable.__svgEl;
};

/**
 * @file Manages SVG gradient elements.
 * @author Zhang Wenli
 */

/**
 * Manages SVG gradient elements.
 *
 * @class
 * @extends Definable
 * @param   {number}     zrId    zrender instance id
 * @param   {SVGElement} svgRoot root of SVG document
 */
function GradientManager(zrId, svgRoot) {
    Definable.call(
        this,
        zrId,
        svgRoot,
        ['linearGradient', 'radialGradient'],
        '__gradient_in_use__'
    );
}


inherits(GradientManager, Definable);


/**
 * Create new gradient DOM for fill or stroke if not exist,
 * but will not update gradient if exists.
 *
 * @param {SvgElement}  svgElement   SVG element to paint
 * @param {Displayable} displayable  zrender displayable element
 */
GradientManager.prototype.addWithoutUpdate = function (
    svgElement,
    displayable
) {
    if (displayable && displayable.style) {
        var that = this;
        each$1(['fill', 'stroke'], function (fillOrStroke) {
            if (displayable.style[fillOrStroke]
                && (displayable.style[fillOrStroke].type === 'linear'
                || displayable.style[fillOrStroke].type === 'radial')
            ) {
                var gradient = displayable.style[fillOrStroke];
                var defs = that.getDefs(true);

                // Create dom in <defs> if not exists
                var dom;
                if (gradient._dom) {
                    // Gradient exists
                    dom = gradient._dom;
                    if (!defs.contains(gradient._dom)) {
                        // _dom is no longer in defs, recreate
                        that.addDom(dom);
                    }
                }
                else {
                    // New dom
                    dom = that.add(gradient);
                }

                that.markUsed(displayable);

                var id = dom.getAttribute('id');
                svgElement.setAttribute(fillOrStroke, 'url(#' + id + ')');
            }
        });
    }
};


/**
 * Add a new gradient tag in <defs>
 *
 * @param   {Gradient} gradient zr gradient instance
 * @return {SVGLinearGradientElement | SVGRadialGradientElement}
 *                            created DOM
 */
GradientManager.prototype.add = function (gradient) {
    var dom;
    if (gradient.type === 'linear') {
        dom = this.createElement('linearGradient');
    }
    else if (gradient.type === 'radial') {
        dom = this.createElement('radialGradient');
    }
    else {
        logError$1('Illegal gradient type.');
        return null;
    }

    // Set dom id with gradient id, since each gradient instance
    // will have no more than one dom element.
    // id may exists before for those dirty elements, in which case
    // id should remain the same, and other attributes should be
    // updated.
    gradient.id = gradient.id || this.nextId++;
    dom.setAttribute('id', 'zr' + this._zrId
        + '-gradient-' + gradient.id);

    this.updateDom(gradient, dom);
    this.addDom(dom);

    return dom;
};


/**
 * Update gradient.
 *
 * @param {Gradient} gradient zr gradient instance
 */
GradientManager.prototype.update = function (gradient) {
    var that = this;
    Definable.prototype.update.call(this, gradient, function () {
        var type = gradient.type;
        var tagName = gradient._dom.tagName;
        if (type === 'linear' && tagName === 'linearGradient'
            || type === 'radial' && tagName === 'radialGradient'
        ) {
            // Gradient type is not changed, update gradient
            that.updateDom(gradient, gradient._dom);
        }
        else {
            // Remove and re-create if type is changed
            that.removeDom(gradient);
            that.add(gradient);
        }
    });
};


/**
 * Update gradient dom
 *
 * @param {Gradient} gradient zr gradient instance
 * @param {SVGLinearGradientElement | SVGRadialGradientElement} dom
 *                            DOM to update
 */
GradientManager.prototype.updateDom = function (gradient, dom) {
    if (gradient.type === 'linear') {
        dom.setAttribute('x1', gradient.x);
        dom.setAttribute('y1', gradient.y);
        dom.setAttribute('x2', gradient.x2);
        dom.setAttribute('y2', gradient.y2);
    }
    else if (gradient.type === 'radial') {
        dom.setAttribute('cx', gradient.x);
        dom.setAttribute('cy', gradient.y);
        dom.setAttribute('r', gradient.r);
    }
    else {
        logError$1('Illegal gradient type.');
        return;
    }

    if (gradient.global) {
        // x1, x2, y1, y2 in range of 0 to canvas width or height
        dom.setAttribute('gradientUnits', 'userSpaceOnUse');
    }
    else {
        // x1, x2, y1, y2 in range of 0 to 1
        dom.setAttribute('gradientUnits', 'objectBoundingBox');
    }

    // Remove color stops if exists
    dom.innerHTML = '';

    // Add color stops
    var colors = gradient.colorStops;
    for (var i = 0, len = colors.length; i < len; ++i) {
        var stop = this.createElement('stop');
        stop.setAttribute('offset', colors[i].offset * 100 + '%');

        var color = colors[i].color;
        if (color.indexOf('rgba') > -1) {
            // Fix Safari bug that stop-color not recognizing alpha #9014
            var opacity = parse(color)[3];
            var hex = toHex(color);

            // stop-color cannot be color, since:
            // The opacity value used for the gradient calculation is the
            // *product* of the value of stop-opacity and the opacity of the
            // value of stop-color.
            // See https://www.w3.org/TR/SVG2/pservers.html#StopOpacityProperty
            stop.setAttribute('stop-color', '#' + hex);
            stop.setAttribute('stop-opacity', opacity);
        }
        else {
            stop.setAttribute('stop-color', colors[i].color);
        }

        dom.appendChild(stop);
    }

    // Store dom element in gradient, to avoid creating multiple
    // dom instances for the same gradient element
    gradient._dom = dom;
};

/**
 * Mark a single gradient to be used
 *
 * @param {Displayable} displayable displayable element
 */
GradientManager.prototype.markUsed = function (displayable) {
    if (displayable.style) {
        var gradient = displayable.style.fill;
        if (gradient && gradient._dom) {
            Definable.prototype.markUsed.call(this, gradient._dom);
        }

        gradient = displayable.style.stroke;
        if (gradient && gradient._dom) {
            Definable.prototype.markUsed.call(this, gradient._dom);
        }
    }
};

/**
 * @file Manages SVG clipPath elements.
 * @author Zhang Wenli
 */

/**
 * Manages SVG clipPath elements.
 *
 * @class
 * @extends Definable
 * @param   {number}     zrId    zrender instance id
 * @param   {SVGElement} svgRoot root of SVG document
 */
function ClippathManager(zrId, svgRoot) {
    Definable.call(this, zrId, svgRoot, 'clipPath', '__clippath_in_use__');
}


inherits(ClippathManager, Definable);


/**
 * Update clipPath.
 *
 * @param {Displayable} displayable displayable element
 */
ClippathManager.prototype.update = function (displayable) {
    var svgEl = this.getSvgElement(displayable);
    if (svgEl) {
        this.updateDom(svgEl, displayable.__clipPaths, false);
    }

    var textEl = this.getTextSvgElement(displayable);
    if (textEl) {
        // Make another clipPath for text, since it's transform
        // matrix is not the same with svgElement
        this.updateDom(textEl, displayable.__clipPaths, true);
    }

    this.markUsed(displayable);
};


/**
 * Create an SVGElement of displayable and create a <clipPath> of its
 * clipPath
 *
 * @param {Displayable} parentEl  parent element
 * @param {ClipPath[]}  clipPaths clipPaths of parent element
 * @param {boolean}     isText    if parent element is Text
 */
ClippathManager.prototype.updateDom = function (
    parentEl,
    clipPaths,
    isText
) {
    if (clipPaths && clipPaths.length > 0) {
        // Has clipPath, create <clipPath> with the first clipPath
        var defs = this.getDefs(true);
        var clipPath = clipPaths[0];
        var clipPathEl;
        var id;

        var dom = isText ? '_textDom' : '_dom';

        if (clipPath[dom]) {
            // Use a dom that is already in <defs>
            id = clipPath[dom].getAttribute('id');
            clipPathEl = clipPath[dom];

            // Use a dom that is already in <defs>
            if (!defs.contains(clipPathEl)) {
                // This happens when set old clipPath that has
                // been previously removed
                defs.appendChild(clipPathEl);
            }
        }
        else {
            // New <clipPath>
            id = 'zr' + this._zrId + '-clip-' + this.nextId;
            ++this.nextId;
            clipPathEl = this.createElement('clipPath');
            clipPathEl.setAttribute('id', id);
            defs.appendChild(clipPathEl);

            clipPath[dom] = clipPathEl;
        }

        // Build path and add to <clipPath>
        var svgProxy = this.getSvgProxy(clipPath);
        if (clipPath.transform
            && clipPath.parent.invTransform
            && !isText
        ) {
            /**
             * If a clipPath has a parent with transform, the transform
             * of parent should not be considered when setting transform
             * of clipPath. So we need to transform back from parent's
             * transform, which is done by multiplying parent's inverse
             * transform.
             */
            // Store old transform
            var transform = Array.prototype.slice.call(
                clipPath.transform
            );

            // Transform back from parent, and brush path
            mul$1(
                clipPath.transform,
                clipPath.parent.invTransform,
                clipPath.transform
            );
            svgProxy.brush(clipPath);

            // Set back transform of clipPath
            clipPath.transform = transform;
        }
        else {
            svgProxy.brush(clipPath);
        }

        var pathEl = this.getSvgElement(clipPath);

        clipPathEl.innerHTML = '';
        /**
         * Use `cloneNode()` here to appendChild to multiple parents,
         * which may happend when Text and other shapes are using the same
         * clipPath. Since Text will create an extra clipPath DOM due to
         * different transform rules.
         */
        clipPathEl.appendChild(pathEl.cloneNode());

        parentEl.setAttribute('clip-path', 'url(#' + id + ')');

        if (clipPaths.length > 1) {
            // Make the other clipPaths recursively
            this.updateDom(clipPathEl, clipPaths.slice(1), isText);
        }
    }
    else {
        // No clipPath
        if (parentEl) {
            parentEl.setAttribute('clip-path', 'none');
        }
    }
};

/**
 * Mark a single clipPath to be used
 *
 * @param {Displayable} displayable displayable element
 */
ClippathManager.prototype.markUsed = function (displayable) {
    var that = this;
    // displayable.__clipPaths can only be `null`/`undefined` or an non-empty array.
    if (displayable.__clipPaths) {
        each$1(displayable.__clipPaths, function (clipPath) {
            if (clipPath._dom) {
                Definable.prototype.markUsed.call(that, clipPath._dom);
            }
            if (clipPath._textDom) {
                Definable.prototype.markUsed.call(that, clipPath._textDom);
            }
        });
    }
};

/**
 * @file Manages SVG shadow elements.
 * @author Zhang Wenli
 */

/**
 * Manages SVG shadow elements.
 *
 * @class
 * @extends Definable
 * @param   {number}     zrId    zrender instance id
 * @param   {SVGElement} svgRoot root of SVG document
 */
function ShadowManager(zrId, svgRoot) {
    Definable.call(
        this,
        zrId,
        svgRoot,
        ['filter'],
        '__filter_in_use__',
        '_shadowDom'
    );
}


inherits(ShadowManager, Definable);


/**
 * Create new shadow DOM for fill or stroke if not exist,
 * but will not update shadow if exists.
 *
 * @param {SvgElement}  svgElement   SVG element to paint
 * @param {Displayable} displayable  zrender displayable element
 */
ShadowManager.prototype.addWithoutUpdate = function (
    svgElement,
    displayable
) {
    if (displayable && hasShadow(displayable.style)) {

        // Create dom in <defs> if not exists
        var dom;
        if (displayable._shadowDom) {
            // Gradient exists
            dom = displayable._shadowDom;

            var defs = this.getDefs(true);
            if (!defs.contains(displayable._shadowDom)) {
                // _shadowDom is no longer in defs, recreate
                this.addDom(dom);
            }
        }
        else {
            // New dom
            dom = this.add(displayable);
        }

        this.markUsed(displayable);

        var id = dom.getAttribute('id');
        svgElement.style.filter = 'url(#' + id + ')';
    }
};


/**
 * Add a new shadow tag in <defs>
 *
 * @param {Displayable} displayable  zrender displayable element
 * @return {SVGFilterElement} created DOM
 */
ShadowManager.prototype.add = function (displayable) {
    var dom = this.createElement('filter');

    // Set dom id with shadow id, since each shadow instance
    // will have no more than one dom element.
    // id may exists before for those dirty elements, in which case
    // id should remain the same, and other attributes should be
    // updated.
    displayable._shadowDomId = displayable._shadowDomId || this.nextId++;
    dom.setAttribute('id', 'zr' + this._zrId
        + '-shadow-' + displayable._shadowDomId);

    this.updateDom(displayable, dom);
    this.addDom(dom);

    return dom;
};


/**
 * Update shadow.
 *
 * @param {Displayable} displayable  zrender displayable element
 */
ShadowManager.prototype.update = function (svgElement, displayable) {
    var style = displayable.style;
    if (hasShadow(style)) {
        var that = this;
        Definable.prototype.update.call(this, displayable, function () {
            that.updateDom(displayable, displayable._shadowDom);
        });
    }
    else {
        // Remove shadow
        this.remove(svgElement, displayable);
    }
};


/**
 * Remove DOM and clear parent filter
 */
ShadowManager.prototype.remove = function (svgElement, displayable) {
    if (displayable._shadowDomId != null) {
        this.removeDom(svgElement);
        svgElement.style.filter = '';
    }
};


/**
 * Update shadow dom
 *
 * @param {Displayable} displayable  zrender displayable element
 * @param {SVGFilterElement} dom DOM to update
 */
ShadowManager.prototype.updateDom = function (displayable, dom) {
    var domChild = dom.getElementsByTagName('feDropShadow');
    if (domChild.length === 0) {
        domChild = this.createElement('feDropShadow');
    }
    else {
        domChild = domChild[0];
    }

    var style = displayable.style;
    var scaleX = displayable.scale ? (displayable.scale[0] || 1) : 1;
    var scaleY = displayable.scale ? (displayable.scale[1] || 1) : 1;

    // TODO: textBoxShadowBlur is not supported yet
    var offsetX;
    var offsetY;
    var blur;
    var color;
    if (style.shadowBlur || style.shadowOffsetX || style.shadowOffsetY) {
        offsetX = style.shadowOffsetX || 0;
        offsetY = style.shadowOffsetY || 0;
        blur = style.shadowBlur;
        color = style.shadowColor;
    }
    else if (style.textShadowBlur) {
        offsetX = style.textShadowOffsetX || 0;
        offsetY = style.textShadowOffsetY || 0;
        blur = style.textShadowBlur;
        color = style.textShadowColor;
    }
    else {
        // Remove shadow
        this.removeDom(dom, style);
        return;
    }

    domChild.setAttribute('dx', offsetX / scaleX);
    domChild.setAttribute('dy', offsetY / scaleY);
    domChild.setAttribute('flood-color', color);

    // Divide by two here so that it looks the same as in canvas
    // See: https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-shadowblur
    var stdDx = blur / 2 / scaleX;
    var stdDy = blur / 2 / scaleY;
    var stdDeviation = stdDx + ' ' + stdDy;
    domChild.setAttribute('stdDeviation', stdDeviation);

    // Fix filter clipping problem
    dom.setAttribute('x', '-100%');
    dom.setAttribute('y', '-100%');
    dom.setAttribute('width', Math.ceil(blur / 2 * 200) + '%');
    dom.setAttribute('height', Math.ceil(blur / 2 * 200) + '%');

    dom.appendChild(domChild);

    // Store dom element in shadow, to avoid creating multiple
    // dom instances for the same shadow element
    displayable._shadowDom = dom;
};

/**
 * Mark a single shadow to be used
 *
 * @param {Displayable} displayable displayable element
 */
ShadowManager.prototype.markUsed = function (displayable) {
    if (displayable._shadowDom) {
        Definable.prototype.markUsed.call(this, displayable._shadowDom);
    }
};

function hasShadow(style) {
    // TODO: textBoxShadowBlur is not supported yet
    return style
        && (style.shadowBlur || style.shadowOffsetX || style.shadowOffsetY
            || style.textShadowBlur || style.textShadowOffsetX
            || style.textShadowOffsetY);
}

/**
 * SVG Painter
 * @module zrender/svg/Painter
 */

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

function getSvgProxy(el) {
    if (el instanceof Path) {
        return svgPath;
    }
    else if (el instanceof ZImage) {
        return svgImage;
    }
    else if (el instanceof Text) {
        return svgText;
    }
    else {
        return svgPath;
    }
}

function checkParentAvailable(parent, child) {
    return child && parent && child.parentNode !== parent;
}

function insertAfter(parent, child, prevSibling) {
    if (checkParentAvailable(parent, child) && prevSibling) {
        var nextSibling = prevSibling.nextSibling;
        nextSibling ? parent.insertBefore(child, nextSibling)
            : parent.appendChild(child);
    }
}

function prepend(parent, child) {
    if (checkParentAvailable(parent, child)) {
        var firstChild = parent.firstChild;
        firstChild ? parent.insertBefore(child, firstChild)
            : parent.appendChild(child);
    }
}

// function append(parent, child) {
//     if (checkParentAvailable(parent, child)) {
//         parent.appendChild(child);
//     }
// }

function remove$1(parent, child) {
    if (child && parent && child.parentNode === parent) {
        parent.removeChild(child);
    }
}

function getTextSvgElement(displayable) {
    return displayable.__textSvgEl;
}

function getSvgElement(displayable) {
    return displayable.__svgEl;
}

/**
 * @alias module:zrender/svg/Painter
 * @constructor
 * @param {HTMLElement} root 绘图容器
 * @param {module:zrender/Storage} storage
 * @param {Object} opts
 */
var SVGPainter = function (root, storage, opts, zrId) {

    this.root = root;
    this.storage = storage;
    this._opts = opts = extend({}, opts || {});

    var svgDom = createElement('svg');
    svgDom.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
    svgDom.setAttribute('version', '1.1');
    svgDom.setAttribute('baseProfile', 'full');
    svgDom.style.cssText = 'user-select:none;position:absolute;left:0;top:0;';

    var bgRoot = createElement('g');
    svgDom.appendChild(bgRoot);
    var svgRoot = createElement('g');
    svgDom.appendChild(svgRoot);

    this.gradientManager = new GradientManager(zrId, svgRoot);
    this.clipPathManager = new ClippathManager(zrId, svgRoot);
    this.shadowManager = new ShadowManager(zrId, svgRoot);

    var viewport = document.createElement('div');
    viewport.style.cssText = 'overflow:hidden;position:relative';

    this._svgDom = svgDom;
    this._svgRoot = svgRoot;
    this._backgroundRoot = bgRoot;
    this._viewport = viewport;

    root.appendChild(viewport);
    viewport.appendChild(svgDom);

    this.resize(opts.width, opts.height);

    this._visibleList = [];
};

SVGPainter.prototype = {

    constructor: SVGPainter,

    getType: function () {
        return 'svg';
    },

    getViewportRoot: function () {
        return this._viewport;
    },

    getSvgDom: function () {
        return this._svgDom;
    },

    getSvgRoot: function () {
        return this._svgRoot;
    },

    getViewportRootOffset: function () {
        var viewportRoot = this.getViewportRoot();
        if (viewportRoot) {
            return {
                offsetLeft: viewportRoot.offsetLeft || 0,
                offsetTop: viewportRoot.offsetTop || 0
            };
        }
    },

    refresh: function () {

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

        this._paintList(list);
    },

    setBackgroundColor: function (backgroundColor) {
        // TODO gradient
        // Insert a bg rect instead of setting background to viewport.
        // Otherwise, the exported SVG don't have background.
        if (this._backgroundRoot && this._backgroundNode) {
            this._backgroundRoot.removeChild(this._backgroundNode);
        }

        var bgNode = createElement('rect');
        bgNode.setAttribute('width', this.getWidth());
        bgNode.setAttribute('height', this.getHeight());
        bgNode.setAttribute('x', 0);
        bgNode.setAttribute('y', 0);
        bgNode.setAttribute('id', 0);
        bgNode.style.fill = backgroundColor;
        this._backgroundRoot.appendChild(bgNode);
        this._backgroundNode = bgNode;
    },

    _paintList: function (list) {
        this.gradientManager.markAllUnused();
        this.clipPathManager.markAllUnused();
        this.shadowManager.markAllUnused();

        var svgRoot = this._svgRoot;
        var visibleList = this._visibleList;
        var listLen = list.length;

        var newVisibleList = [];
        var i;
        for (i = 0; i < listLen; i++) {
            var displayable = list[i];
            var svgProxy = getSvgProxy(displayable);
            var svgElement = getSvgElement(displayable)
                || getTextSvgElement(displayable);
            if (!displayable.invisible) {
                if (displayable.__dirty) {
                    svgProxy && svgProxy.brush(displayable);

                    // Update clipPath
                    this.clipPathManager.update(displayable);

                    // Update gradient and shadow
                    if (displayable.style) {
                        this.gradientManager
                            .update(displayable.style.fill);
                        this.gradientManager
                            .update(displayable.style.stroke);

                        this.shadowManager
                            .update(svgElement, displayable);
                    }

                    displayable.__dirty = false;
                }
                newVisibleList.push(displayable);
            }
        }

        var diff = arrayDiff$1(visibleList, newVisibleList);
        var prevSvgElement;

        // First do remove, in case element moved to the head and do remove
        // after add
        for (i = 0; i < diff.length; i++) {
            var item = diff[i];
            if (item.removed) {
                for (var k = 0; k < item.count; k++) {
                    var displayable = visibleList[item.indices[k]];
                    var svgElement = getSvgElement(displayable);
                    var textSvgElement = getTextSvgElement(displayable);
                    remove$1(svgRoot, svgElement);
                    remove$1(svgRoot, textSvgElement);
                }
            }
        }
        for (i = 0; i < diff.length; i++) {
            var item = diff[i];
            if (item.added) {
                for (var k = 0; k < item.count; k++) {
                    var displayable = newVisibleList[item.indices[k]];
                    var svgElement = getSvgElement(displayable);
                    var textSvgElement = getTextSvgElement(displayable);
                    prevSvgElement
                        ? insertAfter(svgRoot, svgElement, prevSvgElement)
                        : prepend(svgRoot, svgElement);
                    if (svgElement) {
                        insertAfter(svgRoot, textSvgElement, svgElement);
                    }
                    else if (prevSvgElement) {
                        insertAfter(
                            svgRoot, textSvgElement, prevSvgElement
                        );
                    }
                    else {
                        prepend(svgRoot, textSvgElement);
                    }
                    // Insert text
                    insertAfter(svgRoot, textSvgElement, svgElement);
                    prevSvgElement = textSvgElement || svgElement
                        || prevSvgElement;

                    // zrender.Text only create textSvgElement.
                    this.gradientManager
                        .addWithoutUpdate(svgElement || textSvgElement, displayable);
                    this.shadowManager
                        .addWithoutUpdate(svgElement || textSvgElement, displayable);
                    this.clipPathManager.markUsed(displayable);
                }
            }
            else if (!item.removed) {
                for (var k = 0; k < item.count; k++) {
                    var displayable = newVisibleList[item.indices[k]];
                    var svgElement = getSvgElement(displayable);
                    var textSvgElement = getTextSvgElement(displayable);

                    var svgElement = getSvgElement(displayable);
                    var textSvgElement = getTextSvgElement(displayable);

                    this.gradientManager.markUsed(displayable);
                    this.gradientManager
                        .addWithoutUpdate(svgElement || textSvgElement, displayable);

                    this.shadowManager.markUsed(displayable);
                    this.shadowManager
                        .addWithoutUpdate(svgElement || textSvgElement, displayable);

                    this.clipPathManager.markUsed(displayable);

                    if (textSvgElement) { // Insert text.
                        insertAfter(svgRoot, textSvgElement, svgElement);
                    }
                    prevSvgElement = svgElement
                        || textSvgElement || prevSvgElement;
                }
            }
        }

        this.gradientManager.removeUnused();
        this.clipPathManager.removeUnused();
        this.shadowManager.removeUnused();

        this._visibleList = newVisibleList;
    },

    _getDefs: function (isForceCreating) {
        var svgRoot = this._svgDom;
        var defs = svgRoot.getElementsByTagName('defs');
        if (defs.length === 0) {
            // Not exist
            if (isForceCreating) {
                var defs = svgRoot.insertBefore(
                    createElement('defs'), // Create new tag
                    svgRoot.firstChild // Insert in the front of svg
                );
                if (!defs.contains) {
                    // IE doesn't support contains method
                    defs.contains = function (el) {
                        var children = defs.children;
                        if (!children) {
                            return false;
                        }
                        for (var i = children.length - 1; i >= 0; --i) {
                            if (children[i] === el) {
                                return true;
                            }
                        }
                        return false;
                    };
                }
                return defs;
            }
            else {
                return null;
            }
        }
        else {
            return defs[0];
        }
    },

    resize: function (width, height) {
        var viewport = this._viewport;
        // FIXME Why ?
        viewport.style.display = 'none';

        // Save input w/h
        var opts = this._opts;
        width != null && (opts.width = width);
        height != null && (opts.height = height);

        width = this._getSize(0);
        height = this._getSize(1);

        viewport.style.display = '';

        if (this._width !== width || this._height !== height) {
            this._width = width;
            this._height = height;

            var viewportStyle = viewport.style;
            viewportStyle.width = width + 'px';
            viewportStyle.height = height + 'px';

            var svgRoot = this._svgDom;
            // Set width by 'svgRoot.width = width' is invalid
            svgRoot.setAttribute('width', width);
            svgRoot.setAttribute('height', height);
        }

        if (this._backgroundNode) {
            this._backgroundNode.setAttribute('width', width);
            this._backgroundNode.setAttribute('height', height);
        }
    },

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

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

    _getSize: function (whIdx) {
        var opts = this._opts;
        var wh = ['width', 'height'][whIdx];
        var cwh = ['clientWidth', 'clientHeight'][whIdx];
        var plt = ['paddingLeft', 'paddingTop'][whIdx];
        var prb = ['paddingRight', 'paddingBottom'][whIdx];

        if (opts[wh] != null && opts[wh] !== 'auto') {
            return parseFloat(opts[wh]);
        }

        var root = this.root;
        // IE8 does not support getComputedStyle, but it use VML.
        var stl = document.defaultView.getComputedStyle(root);

        return (
            (root[cwh] || parseInt10$2(stl[wh]) || parseInt10$2(root.style[wh]))
            - (parseInt10$2(stl[plt]) || 0)
            - (parseInt10$2(stl[prb]) || 0)
        ) | 0;
    },

    dispose: function () {
        this.root.innerHTML = '';

        this._svgRoot
            = this._backgroundRoot
            = this._svgDom
            = this._backgroundNode
            = this._viewport
            = this.storage
            = null;
    },

    clear: function () {
        if (this._viewport) {
            this.root.removeChild(this._viewport);
        }
    },

    toDataURL: function () {
        this.refresh();
        var html = encodeURIComponent(this._svgDom.outerHTML.replace(/></g, '>\n\r<'));
        return 'data:image/svg+xml;charset=UTF-8,' + html;
    }
};

// Not supported methods
function createMethodNotSupport$1(method) {
    return function () {
        logError$1('In SVG mode painter not support method "' + method + '"');
    };
}

// Unsuppoted methods
each$1([
    'getLayer', 'insertLayer', 'eachLayer', 'eachBuiltinLayer',
    'eachOtherLayer', 'getLayers', 'modLayer', 'delLayer', 'clearLayer',
    'pathToImage'
], function (name) {
    SVGPainter.prototype[name] = createMethodNotSupport$1(name);
});

registerPainter('svg', SVGPainter);

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

exports.version = version;
exports.dependencies = dependencies;
exports.PRIORITY = PRIORITY;
exports.init = init;
exports.connect = connect;
exports.disConnect = disConnect;
exports.disconnect = disconnect;
exports.dispose = dispose;
exports.getInstanceByDom = getInstanceByDom;
exports.getInstanceById = getInstanceById;
exports.registerTheme = registerTheme;
exports.registerPreprocessor = registerPreprocessor;
exports.registerProcessor = registerProcessor;
exports.registerPostUpdate = registerPostUpdate;
exports.registerAction = registerAction;
exports.registerCoordinateSystem = registerCoordinateSystem;
exports.getCoordinateSystemDimensions = getCoordinateSystemDimensions;
exports.registerLayout = registerLayout;
exports.registerVisual = registerVisual;
exports.registerLoading = registerLoading;
exports.extendComponentModel = extendComponentModel;
exports.extendComponentView = extendComponentView;
exports.extendSeriesModel = extendSeriesModel;
exports.extendChartView = extendChartView;
exports.setCanvasCreator = setCanvasCreator;
exports.registerMap = registerMap;
exports.getMap = getMap;
exports.dataTool = dataTool;
exports.zrender = zrender;
exports.number = number;
exports.format = format;
exports.throttle = throttle;
exports.helper = helper;
exports.matrix = matrix;
exports.vector = vector;
exports.color = color;
exports.parseGeoJSON = parseGeoJSON;
exports.parseGeoJson = parseGeoJson;
exports.util = ecUtil;
exports.graphic = graphic$1;
exports.List = List;
exports.Model = Model;
exports.Axis = Axis;
exports.env = env$1;

})));
