
/*
* 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 (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
    typeof define === 'function' && define.amd ? define(['exports'], factory) :
    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.echarts = {}));
}(this, (function (exports) { 'use strict';

    /*! *****************************************************************************
    Copyright (c) Microsoft Corporation.

    Permission to use, copy, modify, and/or distribute this software for any
    purpose with or without fee is hereby granted.

    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
    REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
    AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
    INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
    LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
    OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
    PERFORMANCE OF THIS SOFTWARE.
    ***************************************************************************** */
    /* global Reflect, Promise */

    var extendStatics = function(d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };

    function __extends(d, b) {
        if (typeof b !== "function" && b !== null)
            throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    }

    var Browser = (function () {
        function Browser() {
            this.firefox = false;
            this.ie = false;
            this.edge = false;
            this.newEdge = false;
            this.weChat = false;
        }
        return Browser;
    }());
    var Env = (function () {
        function Env() {
            this.browser = new Browser();
            this.node = false;
            this.wxa = false;
            this.worker = false;
            this.svgSupported = false;
            this.touchEventsSupported = false;
            this.pointerEventsSupported = false;
            this.domSupported = false;
            this.transformSupported = false;
            this.transform3dSupported = false;
            this.hasGlobalWindow = typeof window !== 'undefined';
        }
        return Env;
    }());
    var env = new Env();
    if (typeof wx === 'object' && typeof wx.getSystemInfoSync === 'function') {
        env.wxa = true;
        env.touchEventsSupported = true;
    }
    else if (typeof document === 'undefined' && typeof self !== 'undefined') {
        env.worker = true;
    }
    else if (typeof navigator === 'undefined') {
        env.node = true;
        env.svgSupported = true;
    }
    else {
        detect(navigator.userAgent, env);
    }
    function detect(ua, env) {
        var browser = env.browser;
        var firefox = ua.match(/Firefox\/([\d.]+)/);
        var ie = ua.match(/MSIE\s([\d.]+)/)
            || ua.match(/Trident\/.+?rv:(([\d.]+))/);
        var edge = ua.match(/Edge?\/([\d.]+)/);
        var weChat = (/micromessenger/i).test(ua);
        if (firefox) {
            browser.firefox = true;
            browser.version = firefox[1];
        }
        if (ie) {
            browser.ie = true;
            browser.version = ie[1];
        }
        if (edge) {
            browser.edge = true;
            browser.version = edge[1];
            browser.newEdge = +edge[1].split('.')[0] > 18;
        }
        if (weChat) {
            browser.weChat = true;
        }
        env.svgSupported = typeof SVGRect !== 'undefined';
        env.touchEventsSupported = 'ontouchstart' in window && !browser.ie && !browser.edge;
        env.pointerEventsSupported = 'onpointerdown' in window
            && (browser.edge || (browser.ie && +browser.version >= 11));
        env.domSupported = typeof document !== 'undefined';
        var style = document.documentElement.style;
        env.transform3dSupported = ((browser.ie && 'transition' in style)
            || browser.edge
            || (('WebKitCSSMatrix' in window) && ('m11' in new WebKitCSSMatrix()))
            || 'MozPerspective' in style)
            && !('OTransition' in style);
        env.transformSupported = env.transform3dSupported
            || (browser.ie && +browser.version >= 9);
    }

    var DEFAULT_FONT_SIZE = 12;
    var DEFAULT_FONT_FAMILY = 'sans-serif';
    var DEFAULT_FONT = DEFAULT_FONT_SIZE + "px " + DEFAULT_FONT_FAMILY;
    var OFFSET = 20;
    var SCALE = 100;
    var defaultWidthMapStr = "007LLmW'55;N0500LLLLLLLLLL00NNNLzWW\\\\WQb\\0FWLg\\bWb\\WQ\\WrWWQ000CL5LLFLL0LL**F*gLLLL5F0LF\\FFF5.5N";
    function getTextWidthMap(mapStr) {
        var map = {};
        if (typeof JSON === 'undefined') {
            return map;
        }
        for (var i = 0; i < mapStr.length; i++) {
            var char = String.fromCharCode(i + 32);
            var size = (mapStr.charCodeAt(i) - OFFSET) / SCALE;
            map[char] = size;
        }
        return map;
    }
    var DEFAULT_TEXT_WIDTH_MAP = getTextWidthMap(defaultWidthMapStr);
    var platformApi = {
        createCanvas: function () {
            return typeof document !== 'undefined'
                && document.createElement('canvas');
        },
        measureText: (function () {
            var _ctx;
            var _cachedFont;
            return function (text, font) {
                if (!_ctx) {
                    var canvas = platformApi.createCanvas();
                    _ctx = canvas && canvas.getContext('2d');
                }
                if (_ctx) {
                    if (_cachedFont !== font) {
                        _cachedFont = _ctx.font = font || DEFAULT_FONT;
                    }
                    return _ctx.measureText(text);
                }
                else {
                    text = text || '';
                    font = font || DEFAULT_FONT;
                    var res = /(\d+)px/.exec(font);
                    var fontSize = res && +res[1] || DEFAULT_FONT_SIZE;
                    var width = 0;
                    if (font.indexOf('mono') >= 0) {
                        width = fontSize * text.length;
                    }
                    else {
                        for (var i = 0; i < text.length; i++) {
                            var preCalcWidth = DEFAULT_TEXT_WIDTH_MAP[text[i]];
                            width += preCalcWidth == null ? fontSize : (preCalcWidth * fontSize);
                        }
                    }
                    return { width: width };
                }
            };
        })(),
        loadImage: function (src, onload, onerror) {
            var image = new Image();
            image.onload = onload;
            image.onerror = onerror;
            image.src = src;
            return image;
        }
    };
    function setPlatformAPI(newPlatformApis) {
        for (var key in platformApi) {
            if (newPlatformApis[key]) {
                platformApi[key] = newPlatformApis[key];
            }
        }
    }

    var BUILTIN_OBJECT = reduce([
        'Function',
        'RegExp',
        'Date',
        'Error',
        'CanvasGradient',
        'CanvasPattern',
        'Image',
        'Canvas'
    ], function (obj, val) {
        obj['[object ' + val + ']'] = true;
        return obj;
    }, {});
    var TYPED_ARRAY = reduce([
        'Int8',
        'Uint8',
        'Uint8Clamped',
        'Int16',
        'Uint16',
        'Int32',
        'Uint32',
        'Float32',
        'Float64'
    ], function (obj, val) {
        obj['[object ' + val + 'Array]'] = true;
        return obj;
    }, {});
    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 ctorFunction = function () { }.constructor;
    var protoFunction = ctorFunction ? ctorFunction.prototype : null;
    var protoKey = '__proto__';
    var idStart = 0x0907;
    function guid() {
        return idStart++;
    }
    function logError() {
        var args = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            args[_i] = arguments[_i];
        }
        if (typeof console !== 'undefined') {
            console.error.apply(console, args);
        }
    }
    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 (Ctor.from) {
                    result = Ctor.from(source);
                }
                else {
                    result = new Ctor(source.length);
                    for (var i = 0, len = source.length; i < len; i++) {
                        result[i] = source[i];
                    }
                }
            }
        }
        else if (!BUILTIN_OBJECT[typeStr] && !isPrimitive(source) && !isDom(source)) {
            result = {};
            for (var key in source) {
                if (source.hasOwnProperty(key) && key !== protoKey) {
                    result[key] = clone(source[key]);
                }
            }
        }
        return result;
    }
    function merge(target, source, overwrite) {
        if (!isObject(source) || !isObject(target)) {
            return overwrite ? clone(source) : target;
        }
        for (var key in source) {
            if (source.hasOwnProperty(key) && key !== protoKey) {
                var targetProp = target[key];
                var sourceProp = source[key];
                if (isObject(sourceProp)
                    && isObject(targetProp)
                    && !isArray(sourceProp)
                    && !isArray(targetProp)
                    && !isDom(sourceProp)
                    && !isDom(targetProp)
                    && !isBuiltInObject(sourceProp)
                    && !isBuiltInObject(targetProp)
                    && !isPrimitive(sourceProp)
                    && !isPrimitive(targetProp)) {
                    merge(targetProp, sourceProp, overwrite);
                }
                else if (overwrite || !(key in target)) {
                    target[key] = clone(source[key]);
                }
            }
        }
        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;
    }
    function extend(target, source) {
        if (Object.assign) {
            Object.assign(target, source);
        }
        else {
            for (var key in source) {
                if (source.hasOwnProperty(key) && key !== protoKey) {
                    target[key] = source[key];
                }
            }
        }
        return target;
    }
    function defaults(target, source, overlay) {
        var keysArr = keys(source);
        for (var i = 0; i < keysArr.length; i++) {
            var key = keysArr[i];
            if ((overlay ? source[key] != null : target[key] == null)) {
                target[key] = source[key];
            }
        }
        return target;
    }
    var createCanvas = platformApi.createCanvas;
    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;
    }
    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;
    }
    function mixin(target, source, override) {
        target = 'prototype' in target ? target.prototype : target;
        source = 'prototype' in source ? source.prototype : source;
        if (Object.getOwnPropertyNames) {
            var keyList = Object.getOwnPropertyNames(source);
            for (var i = 0; i < keyList.length; i++) {
                var key = keyList[i];
                if (key !== 'constructor') {
                    if ((override ? source[key] != null : target[key] == null)) {
                        target[key] = source[key];
                    }
                }
            }
        }
        else {
            defaults(target, source, override);
        }
    }
    function isArrayLike(data) {
        if (!data) {
            return false;
        }
        if (typeof data === 'string') {
            return false;
        }
        return typeof data.length === 'number';
    }
    function each(arr, cb, context) {
        if (!(arr && cb)) {
            return;
        }
        if (arr.forEach && arr.forEach === nativeForEach) {
            arr.forEach(cb, context);
        }
        else if (arr.length === +arr.length) {
            for (var i = 0, len = arr.length; i < len; i++) {
                cb.call(context, arr[i], i, arr);
            }
        }
        else {
            for (var key in arr) {
                if (arr.hasOwnProperty(key)) {
                    cb.call(context, arr[key], key, arr);
                }
            }
        }
    }
    function map(arr, cb, context) {
        if (!arr) {
            return [];
        }
        if (!cb) {
            return slice(arr);
        }
        if (arr.map && arr.map === nativeMap) {
            return arr.map(cb, context);
        }
        else {
            var result = [];
            for (var i = 0, len = arr.length; i < len; i++) {
                result.push(cb.call(context, arr[i], i, arr));
            }
            return result;
        }
    }
    function reduce(arr, cb, memo, context) {
        if (!(arr && cb)) {
            return;
        }
        for (var i = 0, len = arr.length; i < len; i++) {
            memo = cb.call(context, memo, arr[i], i, arr);
        }
        return memo;
    }
    function filter(arr, cb, context) {
        if (!arr) {
            return [];
        }
        if (!cb) {
            return slice(arr);
        }
        if (arr.filter && arr.filter === nativeFilter) {
            return arr.filter(cb, context);
        }
        else {
            var result = [];
            for (var i = 0, len = arr.length; i < len; i++) {
                if (cb.call(context, arr[i], i, arr)) {
                    result.push(arr[i]);
                }
            }
            return result;
        }
    }
    function find(arr, cb, context) {
        if (!(arr && cb)) {
            return;
        }
        for (var i = 0, len = arr.length; i < len; i++) {
            if (cb.call(context, arr[i], i, arr)) {
                return arr[i];
            }
        }
    }
    function keys(obj) {
        if (!obj) {
            return [];
        }
        if (Object.keys) {
            return Object.keys(obj);
        }
        var keyList = [];
        for (var key in obj) {
            if (obj.hasOwnProperty(key)) {
                keyList.push(key);
            }
        }
        return keyList;
    }
    function bindPolyfill(func, context) {
        var args = [];
        for (var _i = 2; _i < arguments.length; _i++) {
            args[_i - 2] = arguments[_i];
        }
        return function () {
            return func.apply(context, args.concat(nativeSlice.call(arguments)));
        };
    }
    var bind = (protoFunction && isFunction(protoFunction.bind))
        ? protoFunction.call.bind(protoFunction.bind)
        : bindPolyfill;
    function curry(func) {
        var args = [];
        for (var _i = 1; _i < arguments.length; _i++) {
            args[_i - 1] = arguments[_i];
        }
        return function () {
            return func.apply(this, args.concat(nativeSlice.call(arguments)));
        };
    }
    function isArray(value) {
        if (Array.isArray) {
            return Array.isArray(value);
        }
        return objToString.call(value) === '[object Array]';
    }
    function isFunction(value) {
        return typeof value === 'function';
    }
    function isString(value) {
        return typeof value === 'string';
    }
    function isStringSafe(value) {
        return objToString.call(value) === '[object String]';
    }
    function isNumber(value) {
        return typeof value === 'number';
    }
    function isObject(value) {
        var type = typeof value;
        return type === 'function' || (!!value && type === 'object');
    }
    function isBuiltInObject(value) {
        return !!BUILTIN_OBJECT[objToString.call(value)];
    }
    function isTypedArray(value) {
        return !!TYPED_ARRAY[objToString.call(value)];
    }
    function isDom(value) {
        return typeof value === 'object'
            && typeof value.nodeType === 'number'
            && typeof value.ownerDocument === 'object';
    }
    function isGradientObject(value) {
        return value.colorStops != null;
    }
    function isImagePatternObject(value) {
        return value.image != null;
    }
    function isRegExp(value) {
        return objToString.call(value) === '[object RegExp]';
    }
    function eqNaN(value) {
        return value !== value;
    }
    function retrieve() {
        var args = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            args[_i] = arguments[_i];
        }
        for (var i = 0, len = args.length; i < len; i++) {
            if (args[i] != null) {
                return args[i];
            }
        }
    }
    function retrieve2(value0, value1) {
        return value0 != null
            ? value0
            : value1;
    }
    function retrieve3(value0, value1, value2) {
        return value0 != null
            ? value0
            : value1 != null
                ? value1
                : value2;
    }
    function slice(arr) {
        var args = [];
        for (var _i = 1; _i < arguments.length; _i++) {
            args[_i - 1] = arguments[_i];
        }
        return nativeSlice.apply(arr, args);
    }
    function normalizeCssArray(val) {
        if (typeof (val) === 'number') {
            return [val, val, val, val];
        }
        var len = val.length;
        if (len === 2) {
            return [val[0], val[1], val[0], val[1]];
        }
        else if (len === 3) {
            return [val[0], val[1], val[2], val[1]];
        }
        return val;
    }
    function assert(condition, message) {
        if (!condition) {
            throw new Error(message);
        }
    }
    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__';
    function setAsPrimitive(obj) {
        obj[primitiveKey] = true;
    }
    function isPrimitive(obj) {
        return obj[primitiveKey];
    }
    var MapPolyfill = (function () {
        function MapPolyfill() {
            this.data = {};
        }
        MapPolyfill.prototype["delete"] = function (key) {
            var existed = this.has(key);
            if (existed) {
                delete this.data[key];
            }
            return existed;
        };
        MapPolyfill.prototype.has = function (key) {
            return this.data.hasOwnProperty(key);
        };
        MapPolyfill.prototype.get = function (key) {
            return this.data[key];
        };
        MapPolyfill.prototype.set = function (key, value) {
            this.data[key] = value;
            return this;
        };
        MapPolyfill.prototype.keys = function () {
            return keys(this.data);
        };
        MapPolyfill.prototype.forEach = function (callback) {
            var data = this.data;
            for (var key in data) {
                if (data.hasOwnProperty(key)) {
                    callback(data[key], key);
                }
            }
        };
        return MapPolyfill;
    }());
    var isNativeMapSupported = typeof Map === 'function';
    function maybeNativeMap() {
        return (isNativeMapSupported ? new Map() : new MapPolyfill());
    }
    var HashMap = (function () {
        function HashMap(obj) {
            var isArr = isArray(obj);
            this.data = maybeNativeMap();
            var thisMap = this;
            (obj instanceof HashMap)
                ? obj.each(visit)
                : (obj && each(obj, visit));
            function visit(value, key) {
                isArr ? thisMap.set(value, key) : thisMap.set(key, value);
            }
        }
        HashMap.prototype.hasKey = function (key) {
            return this.data.has(key);
        };
        HashMap.prototype.get = function (key) {
            return this.data.get(key);
        };
        HashMap.prototype.set = function (key, value) {
            this.data.set(key, value);
            return value;
        };
        HashMap.prototype.each = function (cb, context) {
            this.data.forEach(function (value, key) {
                cb.call(context, value, key);
            });
        };
        HashMap.prototype.keys = function () {
            var keys = this.data.keys();
            return isNativeMapSupported
                ? Array.from(keys)
                : keys;
        };
        HashMap.prototype.removeKey = function (key) {
            this.data["delete"](key);
        };
        return HashMap;
    }());
    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 (var i = 0; i < b.length; i++) {
            newArray[i + offset] = b[i];
        }
        return newArray;
    }
    function createObject(proto, properties) {
        var obj;
        if (Object.create) {
            obj = Object.create(proto);
        }
        else {
            var StyleCtor = function () { };
            StyleCtor.prototype = proto;
            obj = new StyleCtor();
        }
        if (properties) {
            extend(obj, properties);
        }
        return obj;
    }
    function disableUserSelect(dom) {
        var domStyle = dom.style;
        domStyle.webkitUserSelect = 'none';
        domStyle.userSelect = 'none';
        domStyle.webkitTapHighlightColor = 'rgba(0,0,0,0)';
        domStyle['-webkit-touch-callout'] = 'none';
    }
    function hasOwn(own, prop) {
        return own.hasOwnProperty(prop);
    }
    function noop() { }
    var RADIAN_TO_DEGREE = 180 / Math.PI;

    var util = /*#__PURE__*/Object.freeze({
        __proto__: null,
        guid: guid,
        logError: logError,
        clone: clone,
        merge: merge,
        mergeAll: mergeAll,
        extend: extend,
        defaults: defaults,
        createCanvas: createCanvas,
        indexOf: indexOf,
        inherits: inherits,
        mixin: mixin,
        isArrayLike: isArrayLike,
        each: each,
        map: map,
        reduce: reduce,
        filter: filter,
        find: find,
        keys: keys,
        bind: bind,
        curry: curry,
        isArray: isArray,
        isFunction: isFunction,
        isString: isString,
        isStringSafe: isStringSafe,
        isNumber: isNumber,
        isObject: isObject,
        isBuiltInObject: isBuiltInObject,
        isTypedArray: isTypedArray,
        isDom: isDom,
        isGradientObject: isGradientObject,
        isImagePatternObject: isImagePatternObject,
        isRegExp: isRegExp,
        eqNaN: eqNaN,
        retrieve: retrieve,
        retrieve2: retrieve2,
        retrieve3: retrieve3,
        slice: slice,
        normalizeCssArray: normalizeCssArray,
        assert: assert,
        trim: trim,
        setAsPrimitive: setAsPrimitive,
        isPrimitive: isPrimitive,
        HashMap: HashMap,
        createHashMap: createHashMap,
        concatArray: concatArray,
        createObject: createObject,
        disableUserSelect: disableUserSelect,
        hasOwn: hasOwn,
        noop: noop,
        RADIAN_TO_DEGREE: RADIAN_TO_DEGREE
    });

    function create(x, y) {
        if (x == null) {
            x = 0;
        }
        if (y == null) {
            y = 0;
        }
        return [x, y];
    }
    function copy(out, v) {
        out[0] = v[0];
        out[1] = v[1];
        return out;
    }
    function clone$1(v) {
        return [v[0], v[1]];
    }
    function set(out, a, b) {
        out[0] = a;
        out[1] = b;
        return out;
    }
    function add(out, v1, v2) {
        out[0] = v1[0] + v2[0];
        out[1] = v1[1] + v2[1];
        return out;
    }
    function scaleAndAdd(out, v1, v2, a) {
        out[0] = v1[0] + v2[0] * a;
        out[1] = v1[1] + v2[1] * a;
        return out;
    }
    function sub(out, v1, v2) {
        out[0] = v1[0] - v2[0];
        out[1] = v1[1] - v2[1];
        return out;
    }
    function len(v) {
        return Math.sqrt(lenSquare(v));
    }
    var length = len;
    function lenSquare(v) {
        return v[0] * v[0] + v[1] * v[1];
    }
    var lengthSquare = lenSquare;
    function mul(out, v1, v2) {
        out[0] = v1[0] * v2[0];
        out[1] = v1[1] * v2[1];
        return out;
    }
    function div(out, v1, v2) {
        out[0] = v1[0] / v2[0];
        out[1] = v1[1] / v2[1];
        return out;
    }
    function dot(v1, v2) {
        return v1[0] * v2[0] + v1[1] * v2[1];
    }
    function scale(out, v, s) {
        out[0] = v[0] * s;
        out[1] = v[1] * s;
        return out;
    }
    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;
    }
    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;
    function distanceSquare(v1, v2) {
        return (v1[0] - v2[0]) * (v1[0] - v2[0])
            + (v1[1] - v2[1]) * (v1[1] - v2[1]);
    }
    var distSquare = distanceSquare;
    function negate(out, v) {
        out[0] = -v[0];
        out[1] = -v[1];
        return out;
    }
    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;
    }
    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;
    }
    function min(out, v1, v2) {
        out[0] = Math.min(v1[0], v2[0]);
        out[1] = Math.min(v1[1], v2[1]);
        return out;
    }
    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 = /*#__PURE__*/Object.freeze({
        __proto__: null,
        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
    });

    var Param = (function () {
        function Param(target, e) {
            this.target = target;
            this.topTarget = e && e.topTarget;
        }
        return Param;
    }());
    var Draggable = (function () {
        function Draggable(handler) {
            this.handler = handler;
            handler.on('mousedown', this._dragStart, this);
            handler.on('mousemove', this._drag, this);
            handler.on('mouseup', this._dragEnd, this);
        }
        Draggable.prototype._dragStart = function (e) {
            var draggingTarget = e.target;
            while (draggingTarget && !draggingTarget.draggable) {
                draggingTarget = draggingTarget.parent || draggingTarget.__hostTarget;
            }
            if (draggingTarget) {
                this._draggingTarget = draggingTarget;
                draggingTarget.dragging = true;
                this._x = e.offsetX;
                this._y = e.offsetY;
                this.handler.dispatchToElement(new Param(draggingTarget, e), 'dragstart', e.event);
            }
        };
        Draggable.prototype._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.handler.dispatchToElement(new Param(draggingTarget, e), 'drag', e.event);
                var dropTarget = this.handler.findHover(x, y, draggingTarget).target;
                var lastDropTarget = this._dropTarget;
                this._dropTarget = dropTarget;
                if (draggingTarget !== dropTarget) {
                    if (lastDropTarget && dropTarget !== lastDropTarget) {
                        this.handler.dispatchToElement(new Param(lastDropTarget, e), 'dragleave', e.event);
                    }
                    if (dropTarget && dropTarget !== lastDropTarget) {
                        this.handler.dispatchToElement(new Param(dropTarget, e), 'dragenter', e.event);
                    }
                }
            }
        };
        Draggable.prototype._dragEnd = function (e) {
            var draggingTarget = this._draggingTarget;
            if (draggingTarget) {
                draggingTarget.dragging = false;
            }
            this.handler.dispatchToElement(new Param(draggingTarget, e), 'dragend', e.event);
            if (this._dropTarget) {
                this.handler.dispatchToElement(new Param(this._dropTarget, e), 'drop', e.event);
            }
            this._draggingTarget = null;
            this._dropTarget = null;
        };
        return Draggable;
    }());

    var Eventful = (function () {
        function Eventful(eventProcessors) {
            if (eventProcessors) {
                this._$eventProcessor = eventProcessors;
            }
        }
        Eventful.prototype.on = function (event, query, handler, context) {
            if (!this._$handlers) {
                this._$handlers = {};
            }
            var _h = this._$handlers;
            if (typeof query === 'function') {
                context = handler;
                handler = query;
                query = null;
            }
            if (!handler || !event) {
                return this;
            }
            var eventProcessor = this._$eventProcessor;
            if (query != null && eventProcessor && eventProcessor.normalizeQuery) {
                query = eventProcessor.normalizeQuery(query);
            }
            if (!_h[event]) {
                _h[event] = [];
            }
            for (var i = 0; i < _h[event].length; i++) {
                if (_h[event][i].h === handler) {
                    return this;
                }
            }
            var wrap = {
                h: handler,
                query: query,
                ctx: (context || this),
                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 this;
        };
        Eventful.prototype.isSilent = function (eventName) {
            var _h = this._$handlers;
            return !_h || !_h[eventName] || !_h[eventName].length;
        };
        Eventful.prototype.off = function (eventType, handler) {
            var _h = this._$handlers;
            if (!_h) {
                return this;
            }
            if (!eventType) {
                this._$handlers = {};
                return this;
            }
            if (handler) {
                if (_h[eventType]) {
                    var newList = [];
                    for (var i = 0, l = _h[eventType].length; i < l; i++) {
                        if (_h[eventType][i].h !== handler) {
                            newList.push(_h[eventType][i]);
                        }
                    }
                    _h[eventType] = newList;
                }
                if (_h[eventType] && _h[eventType].length === 0) {
                    delete _h[eventType];
                }
            }
            else {
                delete _h[eventType];
            }
            return this;
        };
        Eventful.prototype.trigger = function (eventType) {
            var args = [];
            for (var _i = 1; _i < arguments.length; _i++) {
                args[_i - 1] = arguments[_i];
            }
            if (!this._$handlers) {
                return this;
            }
            var _h = this._$handlers[eventType];
            var eventProcessor = this._$eventProcessor;
            if (_h) {
                var argLen = args.length;
                var len = _h.length;
                for (var i = 0; i < len; i++) {
                    var hItem = _h[i];
                    if (eventProcessor
                        && eventProcessor.filter
                        && hItem.query != null
                        && !eventProcessor.filter(eventType, hItem.query)) {
                        continue;
                    }
                    switch (argLen) {
                        case 0:
                            hItem.h.call(hItem.ctx);
                            break;
                        case 1:
                            hItem.h.call(hItem.ctx, args[0]);
                            break;
                        case 2:
                            hItem.h.call(hItem.ctx, args[0], args[1]);
                            break;
                        default:
                            hItem.h.apply(hItem.ctx, args);
                            break;
                    }
                }
            }
            eventProcessor && eventProcessor.afterTrigger
                && eventProcessor.afterTrigger(eventType);
            return this;
        };
        Eventful.prototype.triggerWithContext = function (type) {
            var args = [];
            for (var _i = 1; _i < arguments.length; _i++) {
                args[_i - 1] = arguments[_i];
            }
            if (!this._$handlers) {
                return this;
            }
            var _h = this._$handlers[type];
            var eventProcessor = this._$eventProcessor;
            if (_h) {
                var argLen = args.length;
                var ctx = args[argLen - 1];
                var len = _h.length;
                for (var i = 0; i < len; i++) {
                    var hItem = _h[i];
                    if (eventProcessor
                        && eventProcessor.filter
                        && hItem.query != null
                        && !eventProcessor.filter(type, hItem.query)) {
                        continue;
                    }
                    switch (argLen) {
                        case 0:
                            hItem.h.call(ctx);
                            break;
                        case 1:
                            hItem.h.call(ctx, args[0]);
                            break;
                        case 2:
                            hItem.h.call(ctx, args[0], args[1]);
                            break;
                        default:
                            hItem.h.apply(ctx, args.slice(1, argLen - 1));
                            break;
                    }
                }
            }
            eventProcessor && eventProcessor.afterTrigger
                && eventProcessor.afterTrigger(type);
            return this;
        };
        return Eventful;
    }());

    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) {
            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]
                    * determinant(rows, rank - 1, subRowStart, subRowMask, colMask | colTag, detCache);
                colLocalIdx++;
            }
        }
        detCache[cacheKey] = sum;
        return sum;
    }
    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) {
            return;
        }
        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)
                    * 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 = [];
    function transformLocalCoord(out, elFrom, elTarget, inX, inY) {
        return transformCoordWithViewport(_calcOut, elFrom, inX, inY, true)
            && transformCoordWithViewport(out, elTarget, _calcOut[0], _calcOut[1]);
    }
    function transformCoordWithViewport(out, el, inX, inY, inverse) {
        if (el.getBoundingClientRect && env.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',
                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 srcCoords = [];
        var destCoords = [];
        var oldCoordTheSame = true;
        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);
        }
        return (oldCoordTheSame && transformer)
            ? transformer
            : (saved.srcCoords = srcCoords,
                saved[transformerName] = inverse
                    ? buildTransformer(destCoords, srcCoords)
                    : buildTransformer(srcCoords, destCoords));
    }
    function isCanvasEl(el) {
        return el.nodeName.toUpperCase() === 'CANVAS';
    }
    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 MOUSE_EVENT_REG = /^(?:mouse|pointer|contextmenu|drag|drop)|click/;
    var _calcOut$1 = [];
    var firefoxNotSupportOffsetXY = env.browser.firefox
        && +env.browser.version.split('.')[0] < 39;
    function clientToLocal(el, e, out, calculate) {
        out = out || {};
        if (calculate) {
            calculateZrXY(el, e, out);
        }
        else if (firefoxNotSupportOffsetXY
            && e.layerX != null
            && e.layerX !== e.offsetX) {
            out.zrX = e.layerX;
            out.zrY = e.layerY;
        }
        else if (e.offsetX != null) {
            out.zrX = e.offsetX;
            out.zrY = e.offsetY;
        }
        else {
            calculateZrXY(el, e, out);
        }
        return out;
    }
    function calculateZrXY(el, e, out) {
        if (env.domSupported && el.getBoundingClientRect) {
            var ex = e.clientX;
            var ey = e.clientY;
            if (isCanvasEl(el)) {
                var box = el.getBoundingClientRect();
                out.zrX = ex - box.left;
                out.zrY = ey - box.top;
                return;
            }
            else {
                if (transformCoordWithViewport(_calcOut$1, el, ex, ey)) {
                    out.zrX = _calcOut$1[0];
                    out.zrY = _calcOut$1[1];
                    return;
                }
            }
        }
        out.zrX = out.zrY = 0;
    }
    function getNativeEvent(e) {
        return e
            || window.event;
    }
    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);
            var wheelDelta = getWheelDeltaMayPolyfill(e);
            e.zrDelta = wheelDelta ? wheelDelta / 120 : -(e.detail || 0) / 3;
        }
        else {
            var touch = eventType !== 'touchend'
                ? e.targetTouches[0]
                : e.changedTouches[0];
            touch && clientToLocal(el, touch, e, calculate);
        }
        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)));
        }
        return e;
    }
    function getWheelDeltaMayPolyfill(e) {
        var rawWheelDelta = e.wheelDelta;
        if (rawWheelDelta) {
            return rawWheelDelta;
        }
        var deltaX = e.deltaX;
        var deltaY = e.deltaY;
        if (deltaX == null || deltaY == null) {
            return rawWheelDelta;
        }
        var delta = deltaY !== 0 ? Math.abs(deltaY) : Math.abs(deltaX);
        var sign = deltaY > 0 ? -1
            : deltaY < 0 ? 1
                : deltaX > 0 ? -1
                    : 1;
        return 3 * delta * sign;
    }
    function addEventListener(el, name, handler, opt) {
        el.addEventListener(name, handler, opt);
    }
    function removeEventListener(el, name, handler, opt) {
        el.removeEventListener(name, handler, opt);
    }
    var stop = function (e) {
        e.preventDefault();
        e.stopPropagation();
        e.cancelBubble = true;
    };
    function isMiddleOrRightButtonOnMouseUpDown(e) {
        return e.which === 2 || e.which === 3;
    }

    var GestureMgr = (function () {
        function GestureMgr() {
            this._track = [];
        }
        GestureMgr.prototype.recognize = function (event, target, root) {
            this._doTrack(event, target, root);
            return this._recognize(event);
        };
        GestureMgr.prototype.clear = function () {
            this._track.length = 0;
            return this;
        };
        GestureMgr.prototype._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);
        };
        GestureMgr.prototype._recognize = function (event) {
            for (var eventName in recognizers) {
                if (recognizers.hasOwnProperty(eventName)) {
                    var gestureInfo = recognizers[eventName](this._track, event);
                    if (gestureInfo) {
                        return gestureInfo;
                    }
                }
            }
        };
        return GestureMgr;
    }());
    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 (tracks, event) {
            var trackLen = tracks.length;
            if (!trackLen) {
                return;
            }
            var pinchEnd = (tracks[trackLen - 1] || {}).points;
            var pinchPre = (tracks[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: tracks[0].target,
                    event: event
                };
            }
        }
    };

    function create$1() {
        return [1, 0, 0, 1, 0, 0];
    }
    function identity(out) {
        out[0] = 1;
        out[1] = 0;
        out[2] = 0;
        out[3] = 1;
        out[4] = 0;
        out[5] = 0;
        return out;
    }
    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;
    }
    function mul$1(out, m1, m2) {
        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;
    }
    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;
    }
    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;
    }
    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;
    }
    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;
    }
    function clone$2(a) {
        var b = create$1();
        copy$1(b, a);
        return b;
    }

    var matrix = /*#__PURE__*/Object.freeze({
        __proto__: null,
        create: create$1,
        identity: identity,
        copy: copy$1,
        mul: mul$1,
        translate: translate,
        rotate: rotate,
        scale: scale$1,
        invert: invert,
        clone: clone$2
    });

    var Point = (function () {
        function Point(x, y) {
            this.x = x || 0;
            this.y = y || 0;
        }
        Point.prototype.copy = function (other) {
            this.x = other.x;
            this.y = other.y;
            return this;
        };
        Point.prototype.clone = function () {
            return new Point(this.x, this.y);
        };
        Point.prototype.set = function (x, y) {
            this.x = x;
            this.y = y;
            return this;
        };
        Point.prototype.equal = function (other) {
            return other.x === this.x && other.y === this.y;
        };
        Point.prototype.add = function (other) {
            this.x += other.x;
            this.y += other.y;
            return this;
        };
        Point.prototype.scale = function (scalar) {
            this.x *= scalar;
            this.y *= scalar;
        };
        Point.prototype.scaleAndAdd = function (other, scalar) {
            this.x += other.x * scalar;
            this.y += other.y * scalar;
        };
        Point.prototype.sub = function (other) {
            this.x -= other.x;
            this.y -= other.y;
            return this;
        };
        Point.prototype.dot = function (other) {
            return this.x * other.x + this.y * other.y;
        };
        Point.prototype.len = function () {
            return Math.sqrt(this.x * this.x + this.y * this.y);
        };
        Point.prototype.lenSquare = function () {
            return this.x * this.x + this.y * this.y;
        };
        Point.prototype.normalize = function () {
            var len = this.len();
            this.x /= len;
            this.y /= len;
            return this;
        };
        Point.prototype.distance = function (other) {
            var dx = this.x - other.x;
            var dy = this.y - other.y;
            return Math.sqrt(dx * dx + dy * dy);
        };
        Point.prototype.distanceSquare = function (other) {
            var dx = this.x - other.x;
            var dy = this.y - other.y;
            return dx * dx + dy * dy;
        };
        Point.prototype.negate = function () {
            this.x = -this.x;
            this.y = -this.y;
            return this;
        };
        Point.prototype.transform = function (m) {
            if (!m) {
                return;
            }
            var x = this.x;
            var y = this.y;
            this.x = m[0] * x + m[2] * y + m[4];
            this.y = m[1] * x + m[3] * y + m[5];
            return this;
        };
        Point.prototype.toArray = function (out) {
            out[0] = this.x;
            out[1] = this.y;
            return out;
        };
        Point.prototype.fromArray = function (input) {
            this.x = input[0];
            this.y = input[1];
        };
        Point.set = function (p, x, y) {
            p.x = x;
            p.y = y;
        };
        Point.copy = function (p, p2) {
            p.x = p2.x;
            p.y = p2.y;
        };
        Point.len = function (p) {
            return Math.sqrt(p.x * p.x + p.y * p.y);
        };
        Point.lenSquare = function (p) {
            return p.x * p.x + p.y * p.y;
        };
        Point.dot = function (p0, p1) {
            return p0.x * p1.x + p0.y * p1.y;
        };
        Point.add = function (out, p0, p1) {
            out.x = p0.x + p1.x;
            out.y = p0.y + p1.y;
        };
        Point.sub = function (out, p0, p1) {
            out.x = p0.x - p1.x;
            out.y = p0.y - p1.y;
        };
        Point.scale = function (out, p0, scalar) {
            out.x = p0.x * scalar;
            out.y = p0.y * scalar;
        };
        Point.scaleAndAdd = function (out, p0, p1, scalar) {
            out.x = p0.x + p1.x * scalar;
            out.y = p0.y + p1.y * scalar;
        };
        Point.lerp = function (out, p0, p1, t) {
            var onet = 1 - t;
            out.x = onet * p0.x + t * p1.x;
            out.y = onet * p0.y + t * p1.y;
        };
        return Point;
    }());

    var mathMin = Math.min;
    var mathMax = Math.max;
    var lt = new Point();
    var rb = new Point();
    var lb = new Point();
    var rt = new Point();
    var minTv = new Point();
    var maxTv = new Point();
    var BoundingRect = (function () {
        function BoundingRect(x, y, width, height) {
            if (width < 0) {
                x = x + width;
                width = -width;
            }
            if (height < 0) {
                y = y + height;
                height = -height;
            }
            this.x = x;
            this.y = y;
            this.width = width;
            this.height = height;
        }
        BoundingRect.prototype.union = function (other) {
            var x = mathMin(other.x, this.x);
            var y = mathMin(other.y, this.y);
            if (isFinite(this.x) && isFinite(this.width)) {
                this.width = mathMax(other.x + other.width, this.x + this.width) - x;
            }
            else {
                this.width = other.width;
            }
            if (isFinite(this.y) && isFinite(this.height)) {
                this.height = mathMax(other.y + other.height, this.y + this.height) - y;
            }
            else {
                this.height = other.height;
            }
            this.x = x;
            this.y = y;
        };
        BoundingRect.prototype.applyTransform = function (m) {
            BoundingRect.applyTransform(this, this, m);
        };
        BoundingRect.prototype.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;
        };
        BoundingRect.prototype.intersect = function (b, mtv) {
            if (!b) {
                return false;
            }
            if (!(b instanceof BoundingRect)) {
                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;
            var overlap = !(ax1 < bx0 || bx1 < ax0 || ay1 < by0 || by1 < ay0);
            if (mtv) {
                var dMin = Infinity;
                var dMax = 0;
                var d0 = Math.abs(ax1 - bx0);
                var d1 = Math.abs(bx1 - ax0);
                var d2 = Math.abs(ay1 - by0);
                var d3 = Math.abs(by1 - ay0);
                var dx = Math.min(d0, d1);
                var dy = Math.min(d2, d3);
                if (ax1 < bx0 || bx1 < ax0) {
                    if (dx > dMax) {
                        dMax = dx;
                        if (d0 < d1) {
                            Point.set(maxTv, -d0, 0);
                        }
                        else {
                            Point.set(maxTv, d1, 0);
                        }
                    }
                }
                else {
                    if (dx < dMin) {
                        dMin = dx;
                        if (d0 < d1) {
                            Point.set(minTv, d0, 0);
                        }
                        else {
                            Point.set(minTv, -d1, 0);
                        }
                    }
                }
                if (ay1 < by0 || by1 < ay0) {
                    if (dy > dMax) {
                        dMax = dy;
                        if (d2 < d3) {
                            Point.set(maxTv, 0, -d2);
                        }
                        else {
                            Point.set(maxTv, 0, d3);
                        }
                    }
                }
                else {
                    if (dx < dMin) {
                        dMin = dx;
                        if (d2 < d3) {
                            Point.set(minTv, 0, d2);
                        }
                        else {
                            Point.set(minTv, 0, -d3);
                        }
                    }
                }
            }
            if (mtv) {
                Point.copy(mtv, overlap ? minTv : maxTv);
            }
            return overlap;
        };
        BoundingRect.prototype.contain = function (x, y) {
            var rect = this;
            return x >= rect.x
                && x <= (rect.x + rect.width)
                && y >= rect.y
                && y <= (rect.y + rect.height);
        };
        BoundingRect.prototype.clone = function () {
            return new BoundingRect(this.x, this.y, this.width, this.height);
        };
        BoundingRect.prototype.copy = function (other) {
            BoundingRect.copy(this, other);
        };
        BoundingRect.prototype.plain = function () {
            return {
                x: this.x,
                y: this.y,
                width: this.width,
                height: this.height
            };
        };
        BoundingRect.prototype.isFinite = function () {
            return isFinite(this.x)
                && isFinite(this.y)
                && isFinite(this.width)
                && isFinite(this.height);
        };
        BoundingRect.prototype.isZero = function () {
            return this.width === 0 || this.height === 0;
        };
        BoundingRect.create = function (rect) {
            return new BoundingRect(rect.x, rect.y, rect.width, rect.height);
        };
        BoundingRect.copy = function (target, source) {
            target.x = source.x;
            target.y = source.y;
            target.width = source.width;
            target.height = source.height;
        };
        BoundingRect.applyTransform = function (target, source, m) {
            if (!m) {
                if (target !== source) {
                    BoundingRect.copy(target, source);
                }
                return;
            }
            if (m[1] < 1e-5 && m[1] > -1e-5 && m[2] < 1e-5 && m[2] > -1e-5) {
                var sx = m[0];
                var sy = m[3];
                var tx = m[4];
                var ty = m[5];
                target.x = source.x * sx + tx;
                target.y = source.y * sy + ty;
                target.width = source.width * sx;
                target.height = source.height * sy;
                if (target.width < 0) {
                    target.x += target.width;
                    target.width = -target.width;
                }
                if (target.height < 0) {
                    target.y += target.height;
                    target.height = -target.height;
                }
                return;
            }
            lt.x = lb.x = source.x;
            lt.y = rt.y = source.y;
            rb.x = rt.x = source.x + source.width;
            rb.y = lb.y = source.y + source.height;
            lt.transform(m);
            rt.transform(m);
            rb.transform(m);
            lb.transform(m);
            target.x = mathMin(lt.x, rb.x, lb.x, rt.x);
            target.y = mathMin(lt.y, rb.y, lb.y, rt.y);
            var maxX = mathMax(lt.x, rb.x, lb.x, rt.x);
            var maxY = mathMax(lt.y, rb.y, lb.y, rt.y);
            target.width = maxX - target.x;
            target.height = maxY - target.y;
        };
        return BoundingRect;
    }());

    var SILENT = 'silent';
    function makeEventPacket(eveType, targetInfo, event) {
        return {
            type: eveType,
            event: event,
            target: targetInfo.target,
            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);
    }
    var EmptyProxy = (function (_super) {
        __extends(EmptyProxy, _super);
        function EmptyProxy() {
            var _this = _super !== null && _super.apply(this, arguments) || this;
            _this.handler = null;
            return _this;
        }
        EmptyProxy.prototype.dispose = function () { };
        EmptyProxy.prototype.setCursor = function () { };
        return EmptyProxy;
    }(Eventful));
    var HoveredResult = (function () {
        function HoveredResult(x, y) {
            this.x = x;
            this.y = y;
        }
        return HoveredResult;
    }());
    var handlerNames = [
        'click', 'dblclick', 'mousewheel', 'mouseout',
        'mouseup', 'mousedown', 'mousemove', 'contextmenu'
    ];
    var tmpRect = new BoundingRect(0, 0, 0, 0);
    var Handler = (function (_super) {
        __extends(Handler, _super);
        function Handler(storage, painter, proxy, painterRoot, pointerSize) {
            var _this = _super.call(this) || this;
            _this._hovered = new HoveredResult(0, 0);
            _this.storage = storage;
            _this.painter = painter;
            _this.painterRoot = painterRoot;
            _this._pointerSize = pointerSize;
            proxy = proxy || new EmptyProxy();
            _this.proxy = null;
            _this.setHandlerProxy(proxy);
            _this._draggingMgr = new Draggable(_this);
            return _this;
        }
        Handler.prototype.setHandlerProxy = function (proxy) {
            if (this.proxy) {
                this.proxy.dispose();
            }
            if (proxy) {
                each(handlerNames, function (name) {
                    proxy.on && proxy.on(name, this[name], this);
                }, this);
                proxy.handler = this;
            }
            this.proxy = proxy;
        };
        Handler.prototype.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 && !lastHoveredTarget.__zr) {
                lastHovered = this.findHover(lastHovered.x, lastHovered.y);
                lastHoveredTarget = lastHovered.target;
            }
            var hovered = this._hovered = isOutside ? new HoveredResult(x, y) : this.findHover(x, y);
            var hoveredTarget = hovered.target;
            var proxy = this.proxy;
            proxy.setCursor && proxy.setCursor(hoveredTarget ? hoveredTarget.cursor : 'default');
            if (lastHoveredTarget && hoveredTarget !== lastHoveredTarget) {
                this.dispatchToElement(lastHovered, 'mouseout', event);
            }
            this.dispatchToElement(hovered, 'mousemove', event);
            if (hoveredTarget && hoveredTarget !== lastHoveredTarget) {
                this.dispatchToElement(hovered, 'mouseover', event);
            }
        };
        Handler.prototype.mouseout = function (event) {
            var eventControl = event.zrEventControl;
            if (eventControl !== 'only_globalout') {
                this.dispatchToElement(this._hovered, 'mouseout', event);
            }
            if (eventControl !== 'no_globalout') {
                this.trigger('globalout', { type: 'globalout', event: event });
            }
        };
        Handler.prototype.resize = function () {
            this._hovered = new HoveredResult(0, 0);
        };
        Handler.prototype.dispatch = function (eventName, eventArgs) {
            var handler = this[eventName];
            handler && handler.call(this, eventArgs);
        };
        Handler.prototype.dispose = function () {
            this.proxy.dispose();
            this.storage = null;
            this.proxy = null;
            this.painter = null;
        };
        Handler.prototype.setCursorStyle = function (cursorStyle) {
            var proxy = this.proxy;
            proxy.setCursor && proxy.setCursor(cursorStyle);
        };
        Handler.prototype.dispatchToElement = function (targetInfo, eventName, event) {
            targetInfo = targetInfo || {};
            var el = targetInfo.target;
            if (el && el.silent) {
                return;
            }
            var eventKey = ('on' + eventName);
            var eventPacket = makeEventPacket(eventName, targetInfo, event);
            while (el) {
                el[eventKey]
                    && (eventPacket.cancelBubble = !!el[eventKey].call(el, eventPacket));
                el.trigger(eventName, eventPacket);
                el = el.__hostTarget ? el.__hostTarget : el.parent;
                if (eventPacket.cancelBubble) {
                    break;
                }
            }
            if (!eventPacket.cancelBubble) {
                this.trigger(eventName, eventPacket);
                if (this.painter && this.painter.eachOtherLayer) {
                    this.painter.eachOtherLayer(function (layer) {
                        if (typeof (layer[eventKey]) === 'function') {
                            layer[eventKey].call(layer, eventPacket);
                        }
                        if (layer.trigger) {
                            layer.trigger(eventName, eventPacket);
                        }
                    });
                }
            }
        };
        Handler.prototype.findHover = function (x, y, exclude) {
            var list = this.storage.getDisplayList();
            var out = new HoveredResult(x, y);
            setHoverTarget(list, out, x, y, exclude);
            if (this._pointerSize && !out.target) {
                var candidates = [];
                var pointerSize = this._pointerSize;
                var targetSizeHalf = pointerSize / 2;
                var pointerRect = new BoundingRect(x - targetSizeHalf, y - targetSizeHalf, pointerSize, pointerSize);
                for (var i = list.length - 1; i >= 0; i--) {
                    var el = list[i];
                    if (el !== exclude
                        && !el.ignore
                        && !el.ignoreCoarsePointer
                        && (!el.parent || !el.parent.ignoreCoarsePointer)) {
                        tmpRect.copy(el.getBoundingRect());
                        if (el.transform) {
                            tmpRect.applyTransform(el.transform);
                        }
                        if (tmpRect.intersect(pointerRect)) {
                            candidates.push(el);
                        }
                    }
                }
                if (candidates.length) {
                    var rStep = 4;
                    var thetaStep = Math.PI / 12;
                    var PI2 = Math.PI * 2;
                    for (var r = 0; r < targetSizeHalf; r += rStep) {
                        for (var theta = 0; theta < PI2; theta += thetaStep) {
                            var x1 = x + r * Math.cos(theta);
                            var y1 = y + r * Math.sin(theta);
                            setHoverTarget(candidates, out, x1, y1, exclude);
                            if (out.target) {
                                return out;
                            }
                        }
                    }
                }
            }
            return out;
        };
        Handler.prototype.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();
            if (gestureInfo) {
                var type = gestureInfo.type;
                event.gestureEvent = type;
                var res = new HoveredResult();
                res.target = gestureInfo.target;
                this.dispatchToElement(res, type, gestureInfo.event);
            }
        };
        return Handler;
    }(Eventful));
    each(['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) {
                hovered = this.findHover(x, y);
                hoveredTarget = hovered.target;
            }
            if (name === 'mousedown') {
                this._downEl = hoveredTarget;
                this._downPoint = [event.zrX, event.zrY];
                this._upEl = hoveredTarget;
            }
            else if (name === 'mouseup') {
                this._upEl = hoveredTarget;
            }
            else if (name === 'click') {
                if (this._downEl !== this._upEl
                    || !this._downPoint
                    || 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 = void 0;
            var ignoreClip = false;
            while (el) {
                if (el.ignoreClip) {
                    ignoreClip = true;
                }
                if (!ignoreClip) {
                    var clipPath = el.getClipPath();
                    if (clipPath && !clipPath.contain(x, y)) {
                        return false;
                    }
                    if (el.silent) {
                        isSilent = true;
                    }
                }
                var hostEl = el.__hostTarget;
                el = hostEl ? hostEl : el.parent;
            }
            return isSilent ? SILENT : true;
        }
        return false;
    }
    function setHoverTarget(list, out, x, y, exclude) {
        for (var i = list.length - 1; i >= 0; i--) {
            var el = list[i];
            var hoverCheckResult = void 0;
            if (el !== exclude
                && !el.ignore
                && (hoverCheckResult = isHover(el, x, y))) {
                !out.topTarget && (out.topTarget = el);
                if (hoverCheckResult !== SILENT) {
                    out.target = el;
                    break;
                }
            }
        }
    }
    function isOutsideBoundary(handlerInstance, x, y) {
        var painter = handlerInstance.painter;
        return x < 0 || x > painter.getWidth() || y < 0 || y > painter.getHeight();
    }

    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 length = 0;
        var runStart;
        var runLength;
        var stackSize = 0;
        length = array.length;
        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();
            }
            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();
            }
            else {
                customCursor = dest - (length2 - 1);
                for (i = 0; i < length2; i++) {
                    array[customCursor + i] = tmp[i];
                }
            }
        }
        return {
            mergeRuns: mergeRuns,
            forceMergeRuns: forceMergeRuns,
            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 = 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();
    }

    var REDRAW_BIT = 1;
    var STYLE_CHANGED_BIT = 2;
    var SHAPE_CHANGED_BIT = 4;

    var invalidZErrorLogged = false;
    function logInvalidZError() {
        if (invalidZErrorLogged) {
            return;
        }
        invalidZErrorLogged = true;
        console.warn('z / z2 / zlevel of displayable is invalid, which may cause unexpected errors');
    }
    function shapeCompareFunc(a, b) {
        if (a.zlevel === b.zlevel) {
            if (a.z === b.z) {
                return a.z2 - b.z2;
            }
            return a.z - b.z;
        }
        return a.zlevel - b.zlevel;
    }
    var Storage = (function () {
        function Storage() {
            this._roots = [];
            this._displayList = [];
            this._displayListLen = 0;
            this.displayableSortFunc = shapeCompareFunc;
        }
        Storage.prototype.traverse = function (cb, context) {
            for (var i = 0; i < this._roots.length; i++) {
                this._roots[i].traverse(cb, context);
            }
        };
        Storage.prototype.getDisplayList = function (update, includeIgnore) {
            includeIgnore = includeIgnore || false;
            var displayList = this._displayList;
            if (update || !displayList.length) {
                this.updateDisplayList(includeIgnore);
            }
            return displayList;
        };
        Storage.prototype.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;
            sort(displayList, shapeCompareFunc);
        };
        Storage.prototype._updateAndAddDisplayable = function (el, clipPaths, includeIgnore) {
            if (el.ignore && !includeIgnore) {
                return;
            }
            el.beforeUpdate();
            el.update();
            el.afterUpdate();
            var userSetClipPath = el.getClipPath();
            if (el.ignoreClip) {
                clipPaths = null;
            }
            else if (userSetClipPath) {
                if (clipPaths) {
                    clipPaths = clipPaths.slice();
                }
                else {
                    clipPaths = [];
                }
                var currentClipPath = userSetClipPath;
                var parentClipPath = el;
                while (currentClipPath) {
                    currentClipPath.parent = parentClipPath;
                    currentClipPath.updateTransform();
                    clipPaths.push(currentClipPath);
                    parentClipPath = currentClipPath;
                    currentClipPath = currentClipPath.getClipPath();
                }
            }
            if (el.childrenRef) {
                var children = el.childrenRef();
                for (var i = 0; i < children.length; i++) {
                    var child = children[i];
                    if (el.__dirty) {
                        child.__dirty |= REDRAW_BIT;
                    }
                    this._updateAndAddDisplayable(child, clipPaths, includeIgnore);
                }
                el.__dirty = 0;
            }
            else {
                var disp = el;
                if (clipPaths && clipPaths.length) {
                    disp.__clipPaths = clipPaths;
                }
                else if (disp.__clipPaths && disp.__clipPaths.length > 0) {
                    disp.__clipPaths = [];
                }
                if (isNaN(disp.z)) {
                    logInvalidZError();
                    disp.z = 0;
                }
                if (isNaN(disp.z2)) {
                    logInvalidZError();
                    disp.z2 = 0;
                }
                if (isNaN(disp.zlevel)) {
                    logInvalidZError();
                    disp.zlevel = 0;
                }
                this._displayList[this._displayListLen++] = disp;
            }
            var decalEl = el.getDecalElement && el.getDecalElement();
            if (decalEl) {
                this._updateAndAddDisplayable(decalEl, clipPaths, includeIgnore);
            }
            var textGuide = el.getTextGuideLine();
            if (textGuide) {
                this._updateAndAddDisplayable(textGuide, clipPaths, includeIgnore);
            }
            var textEl = el.getTextContent();
            if (textEl) {
                this._updateAndAddDisplayable(textEl, clipPaths, includeIgnore);
            }
        };
        Storage.prototype.addRoot = function (el) {
            if (el.__zr && el.__zr.storage === this) {
                return;
            }
            this._roots.push(el);
        };
        Storage.prototype.delRoot = function (el) {
            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._roots.splice(idx, 1);
            }
        };
        Storage.prototype.delAllRoots = function () {
            this._roots = [];
            this._displayList = [];
            this._displayListLen = 0;
            return;
        };
        Storage.prototype.getRoots = function () {
            return this._roots;
        };
        Storage.prototype.dispose = function () {
            this._displayList = null;
            this._roots = null;
        };
        return Storage;
    }());

    var requestAnimationFrame;
    requestAnimationFrame = (env.hasGlobalWindow
        && ((window.requestAnimationFrame && window.requestAnimationFrame.bind(window))
            || (window.msRequestAnimationFrame && window.msRequestAnimationFrame.bind(window))
            || window.mozRequestAnimationFrame
            || window.webkitRequestAnimationFrame)) || function (func) {
        return setTimeout(func, 16);
    };
    var requestAnimationFrame$1 = requestAnimationFrame;

    var easingFuncs = {
        linear: function (k) {
            return k;
        },
        quadraticIn: function (k) {
            return k * k;
        },
        quadraticOut: function (k) {
            return k * (2 - k);
        },
        quadraticInOut: function (k) {
            if ((k *= 2) < 1) {
                return 0.5 * k * k;
            }
            return -0.5 * (--k * (k - 2) - 1);
        },
        cubicIn: function (k) {
            return k * k * k;
        },
        cubicOut: function (k) {
            return --k * k * k + 1;
        },
        cubicInOut: function (k) {
            if ((k *= 2) < 1) {
                return 0.5 * k * k * k;
            }
            return 0.5 * ((k -= 2) * k * k + 2);
        },
        quarticIn: function (k) {
            return k * k * k * k;
        },
        quarticOut: function (k) {
            return 1 - (--k * k * k * k);
        },
        quarticInOut: function (k) {
            if ((k *= 2) < 1) {
                return 0.5 * k * k * k * k;
            }
            return -0.5 * ((k -= 2) * k * k * k - 2);
        },
        quinticIn: function (k) {
            return k * k * k * k * k;
        },
        quinticOut: function (k) {
            return --k * k * k * k * k + 1;
        },
        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);
        },
        sinusoidalIn: function (k) {
            return 1 - Math.cos(k * Math.PI / 2);
        },
        sinusoidalOut: function (k) {
            return Math.sin(k * Math.PI / 2);
        },
        sinusoidalInOut: function (k) {
            return 0.5 * (1 - Math.cos(Math.PI * k));
        },
        exponentialIn: function (k) {
            return k === 0 ? 0 : Math.pow(1024, k - 1);
        },
        exponentialOut: function (k) {
            return k === 1 ? 1 : 1 - Math.pow(2, -10 * k);
        },
        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);
        },
        circularIn: function (k) {
            return 1 - Math.sqrt(1 - k * k);
        },
        circularOut: function (k) {
            return Math.sqrt(1 - (--k * k));
        },
        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);
        },
        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));
        },
        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);
        },
        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;
        },
        backIn: function (k) {
            var s = 1.70158;
            return k * k * ((s + 1) * k - s);
        },
        backOut: function (k) {
            var s = 1.70158;
            return --k * k * ((s + 1) * k + s) + 1;
        },
        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);
        },
        bounceIn: function (k) {
            return 1 - easingFuncs.bounceOut(1 - k);
        },
        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;
            }
        },
        bounceInOut: function (k) {
            if (k < 0.5) {
                return easingFuncs.bounceIn(k * 2) * 0.5;
            }
            return easingFuncs.bounceOut(k * 2 - 1) * 0.5 + 0.5;
        }
    };

    var mathPow = Math.pow;
    var mathSqrt = Math.sqrt;
    var EPSILON = 1e-8;
    var EPSILON_NUMERIC = 1e-4;
    var THREE_SQRT = mathSqrt(3);
    var ONE_THIRD = 1 / 3;
    var _v0 = create();
    var _v1 = create();
    var _v2 = create();
    function isAroundZero(val) {
        return val > -EPSILON && val < EPSILON;
    }
    function isNotAroundZero(val) {
        return val > EPSILON || val < -EPSILON;
    }
    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);
    }
    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);
    }
    function cubicRootAt(p0, p1, p2, p3, val, roots) {
        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;
                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;
                var t2 = -K / 2;
                if (t1 >= 0 && t1 <= 1) {
                    roots[n++] = t1;
                }
                if (t2 >= 0 && t2 <= 1) {
                    roots[n++] = t2;
                }
            }
            else if (disc > 0) {
                var discSqrt = mathSqrt(disc);
                var Y1 = A * b + 1.5 * a * (-B + discSqrt);
                var Y2 = A * b + 1.5 * a * (-B - discSqrt);
                if (Y1 < 0) {
                    Y1 = -mathPow(-Y1, ONE_THIRD);
                }
                else {
                    Y1 = mathPow(Y1, ONE_THIRD);
                }
                if (Y2 < 0) {
                    Y2 = -mathPow(-Y2, ONE_THIRD);
                }
                else {
                    Y2 = mathPow(Y2, ONE_THIRD);
                }
                var t1 = (-b - (Y1 + Y2)) / (3 * a);
                if (t1 >= 0 && t1 <= 1) {
                    roots[n++] = t1;
                }
            }
            else {
                var T = (2 * A * b - 3 * a * B) / (2 * mathSqrt(A * A * A));
                var theta = Math.acos(T) / 3;
                var ASqrt = mathSqrt(A);
                var tmp = Math.cos(theta);
                var t1 = (-b - 2 * ASqrt * tmp) / (3 * a);
                var t2 = (-b + ASqrt * (tmp + THREE_SQRT * Math.sin(theta))) / (3 * a);
                var t3 = (-b + ASqrt * (tmp - THREE_SQRT * Math.sin(theta))) / (3 * a);
                if (t1 >= 0 && t1 <= 1) {
                    roots[n++] = t1;
                }
                if (t2 >= 0 && t2 <= 1) {
                    roots[n++] = t2;
                }
                if (t3 >= 0 && t3 <= 1) {
                    roots[n++] = t3;
                }
            }
        }
        return n;
    }
    function cubicExtrema(p0, p1, p2, p3, extrema) {
        var b = 6 * p2 - 12 * p1 + 6 * p0;
        var a = 9 * p1 + 3 * p3 - 3 * p0 - 9 * p2;
        var c = 3 * p1 - 3 * p0;
        var n = 0;
        if (isAroundZero(a)) {
            if (isNotAroundZero(b)) {
                var t1 = -c / b;
                if (t1 >= 0 && t1 <= 1) {
                    extrema[n++] = t1;
                }
            }
        }
        else {
            var disc = b * b - 4 * a * c;
            if (isAroundZero(disc)) {
                extrema[0] = -b / (2 * a);
            }
            else if (disc > 0) {
                var discSqrt = mathSqrt(disc);
                var t1 = (-b + discSqrt) / (2 * a);
                var t2 = (-b - discSqrt) / (2 * a);
                if (t1 >= 0 && t1 <= 1) {
                    extrema[n++] = t1;
                }
                if (t2 >= 0 && t2 <= 1) {
                    extrema[n++] = t2;
                }
            }
        }
        return n;
    }
    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;
        out[0] = p0;
        out[1] = p01;
        out[2] = p012;
        out[3] = p0123;
        out[4] = p0123;
        out[5] = p123;
        out[6] = p23;
        out[7] = p3;
    }
    function cubicProjectPoint(x0, y0, x1, y1, x2, y2, x3, y3, x, y, out) {
        var t;
        var interval = 0.005;
        var d = Infinity;
        var prev;
        var next;
        var d1;
        var d2;
        _v0[0] = x;
        _v0[1] = y;
        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;
        for (var i = 0; i < 32; i++) {
            if (interval < EPSILON_NUMERIC) {
                break;
            }
            prev = t - interval;
            next = 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 {
                _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;
                }
            }
        }
        if (out) {
            out[0] = cubicAt(x0, x1, x2, x3, t);
            out[1] = cubicAt(y0, y1, y2, y3, t);
        }
        return mathSqrt(d);
    }
    function cubicLength(x0, y0, x1, y1, x2, y2, x3, y3, iteration) {
        var px = x0;
        var py = y0;
        var d = 0;
        var step = 1 / iteration;
        for (var i = 1; i <= iteration; i++) {
            var t = i * step;
            var x = cubicAt(x0, x1, x2, x3, t);
            var y = cubicAt(y0, y1, y2, y3, t);
            var dx = x - px;
            var dy = y - py;
            d += Math.sqrt(dx * dx + dy * dy);
            px = x;
            py = y;
        }
        return d;
    }
    function quadraticAt(p0, p1, p2, t) {
        var onet = 1 - t;
        return onet * (onet * p0 + 2 * t * p1) + t * t * p2;
    }
    function quadraticDerivativeAt(p0, p1, p2, t) {
        return 2 * ((1 - t) * (p1 - p0) + t * (p2 - p1));
    }
    function quadraticRootAt(p0, p1, p2, val, roots) {
        var a = p0 - 2 * p1 + p2;
        var b = 2 * (p1 - p0);
        var c = p0 - val;
        var n = 0;
        if (isAroundZero(a)) {
            if (isNotAroundZero(b)) {
                var t1 = -c / b;
                if (t1 >= 0 && t1 <= 1) {
                    roots[n++] = t1;
                }
            }
        }
        else {
            var disc = b * b - 4 * a * c;
            if (isAroundZero(disc)) {
                var t1 = -b / (2 * a);
                if (t1 >= 0 && t1 <= 1) {
                    roots[n++] = t1;
                }
            }
            else if (disc > 0) {
                var discSqrt = mathSqrt(disc);
                var t1 = (-b + discSqrt) / (2 * a);
                var t2 = (-b - discSqrt) / (2 * a);
                if (t1 >= 0 && t1 <= 1) {
                    roots[n++] = t1;
                }
                if (t2 >= 0 && t2 <= 1) {
                    roots[n++] = t2;
                }
            }
        }
        return n;
    }
    function quadraticExtremum(p0, p1, p2) {
        var divider = p0 + p2 - 2 * p1;
        if (divider === 0) {
            return 0.5;
        }
        else {
            return (p0 - p1) / divider;
        }
    }
    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;
        out[0] = p0;
        out[1] = p01;
        out[2] = p012;
        out[3] = p012;
        out[4] = p12;
        out[5] = p2;
    }
    function quadraticProjectPoint(x0, y0, x1, y1, x2, y2, x, y, out) {
        var t;
        var interval = 0.005;
        var d = Infinity;
        _v0[0] = x;
        _v0[1] = y;
        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;
        for (var i = 0; i < 32; i++) {
            if (interval < EPSILON_NUMERIC) {
                break;
            }
            var prev = t - interval;
            var next = 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 {
                _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;
                }
            }
        }
        if (out) {
            out[0] = quadraticAt(x0, x1, x2, t);
            out[1] = quadraticAt(y0, y1, y2, t);
        }
        return mathSqrt(d);
    }
    function quadraticLength(x0, y0, x1, y1, x2, y2, iteration) {
        var px = x0;
        var py = y0;
        var d = 0;
        var step = 1 / iteration;
        for (var i = 1; i <= iteration; i++) {
            var t = i * step;
            var x = quadraticAt(x0, x1, x2, t);
            var y = quadraticAt(y0, y1, y2, t);
            var dx = x - px;
            var dy = y - py;
            d += Math.sqrt(dx * dx + dy * dy);
            px = x;
            py = y;
        }
        return d;
    }

    var regexp = /cubic-bezier\(([0-9,\.e ]+)\)/;
    function createCubicEasingFunc(cubicEasingStr) {
        var cubic = cubicEasingStr && regexp.exec(cubicEasingStr);
        if (cubic) {
            var points = cubic[1].split(',');
            var a_1 = +trim(points[0]);
            var b_1 = +trim(points[1]);
            var c_1 = +trim(points[2]);
            var d_1 = +trim(points[3]);
            if (isNaN(a_1 + b_1 + c_1 + d_1)) {
                return;
            }
            var roots_1 = [];
            return function (p) {
                return p <= 0
                    ? 0 : p >= 1
                    ? 1
                    : cubicRootAt(0, a_1, c_1, 1, p, roots_1) && cubicAt(0, b_1, d_1, 1, roots_1[0]);
            };
        }
    }

    var Clip = (function () {
        function Clip(opts) {
            this._inited = false;
            this._startTime = 0;
            this._pausedTime = 0;
            this._paused = false;
            this._life = opts.life || 1000;
            this._delay = opts.delay || 0;
            this.loop = opts.loop || false;
            this.onframe = opts.onframe || noop;
            this.ondestroy = opts.ondestroy || noop;
            this.onrestart = opts.onrestart || noop;
            opts.easing && this.setEasing(opts.easing);
        }
        Clip.prototype.step = function (globalTime, deltaTime) {
            if (!this._inited) {
                this._startTime = globalTime + this._delay;
                this._inited = true;
            }
            if (this._paused) {
                this._pausedTime += deltaTime;
                return;
            }
            var life = this._life;
            var elapsedTime = globalTime - this._startTime - this._pausedTime;
            var percent = elapsedTime / life;
            if (percent < 0) {
                percent = 0;
            }
            percent = Math.min(percent, 1);
            var easingFunc = this.easingFunc;
            var schedule = easingFunc ? easingFunc(percent) : percent;
            this.onframe(schedule);
            if (percent === 1) {
                if (this.loop) {
                    var remainder = elapsedTime % life;
                    this._startTime = globalTime - remainder;
                    this._pausedTime = 0;
                    this.onrestart();
                }
                else {
                    return true;
                }
            }
            return false;
        };
        Clip.prototype.pause = function () {
            this._paused = true;
        };
        Clip.prototype.resume = function () {
            this._paused = false;
        };
        Clip.prototype.setEasing = function (easing) {
            this.easing = easing;
            this.easingFunc = isFunction(easing)
                ? easing
                : easingFuncs[easing] || createCubicEasingFunc(easing);
        };
        return Clip;
    }());

    var Entry = (function () {
        function Entry(val) {
            this.value = val;
        }
        return Entry;
    }());
    var LinkedList = (function () {
        function LinkedList() {
            this._len = 0;
        }
        LinkedList.prototype.insert = function (val) {
            var entry = new Entry(val);
            this.insertEntry(entry);
            return entry;
        };
        LinkedList.prototype.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++;
        };
        LinkedList.prototype.remove = function (entry) {
            var prev = entry.prev;
            var next = entry.next;
            if (prev) {
                prev.next = next;
            }
            else {
                this.head = next;
            }
            if (next) {
                next.prev = prev;
            }
            else {
                this.tail = prev;
            }
            entry.next = entry.prev = null;
            this._len--;
        };
        LinkedList.prototype.len = function () {
            return this._len;
        };
        LinkedList.prototype.clear = function () {
            this.head = this.tail = null;
            this._len = 0;
        };
        return LinkedList;
    }());
    var LRU = (function () {
        function LRU(maxSize) {
            this._list = new LinkedList();
            this._maxSize = 10;
            this._map = {};
            this._maxSize = maxSize;
        }
        LRU.prototype.put = function (key, value) {
            var list = this._list;
            var map = this._map;
            var removed = null;
            if (map[key] == null) {
                var len = list.len();
                var entry = this._lastRemovedEntry;
                if (len >= this._maxSize && len > 0) {
                    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;
        };
        LRU.prototype.get = function (key) {
            var entry = this._map[key];
            var list = this._list;
            if (entry != null) {
                if (entry !== list.tail) {
                    list.remove(entry);
                    list.insertEntry(entry);
                }
                return entry.value;
            }
        };
        LRU.prototype.clear = function () {
            this._list.clear();
            this._map = {};
        };
        LRU.prototype.len = function () {
            return this._list.len();
        };
        return LRU;
    }());

    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) {
        i = Math.round(i);
        return i < 0 ? 0 : i > 255 ? 255 : i;
    }
    function clampCssAngle(i) {
        i = Math.round(i);
        return i < 0 ? 0 : i > 360 ? 360 : i;
    }
    function clampCssFloat(f) {
        return f < 0 ? 0 : f > 1 ? 1 : f;
    }
    function parseCssInt(val) {
        var str = val;
        if (str.length && str.charAt(str.length - 1) === '%') {
            return clampCssByte(parseFloat(str) / 100 * 255);
        }
        return clampCssByte(parseInt(str, 10));
    }
    function parseCssFloat(val) {
        var str = val;
        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) {
        if (lastRemovedArr) {
            copyRgba(lastRemovedArr, rgbaArr);
        }
        lastRemovedArr = colorCache.put(colorStr, lastRemovedArr || (rgbaArr.slice()));
    }
    function parse(colorStr, rgbaArr) {
        if (!colorStr) {
            return;
        }
        rgbaArr = rgbaArr || [];
        var cached = colorCache.get(colorStr);
        if (cached) {
            return copyRgba(rgbaArr, cached);
        }
        colorStr = colorStr + '';
        var str = colorStr.replace(/ /g, '').toLowerCase();
        if (str in kCSSColorTable) {
            copyRgba(rgbaArr, kCSSColorTable[str]);
            putToCache(colorStr, rgbaArr);
            return rgbaArr;
        }
        var strLen = str.length;
        if (str.charAt(0) === '#') {
            if (strLen === 4 || strLen === 5) {
                var iv = parseInt(str.slice(1, 4), 16);
                if (!(iv >= 0 && iv <= 0xfff)) {
                    setRgba(rgbaArr, 0, 0, 0, 1);
                    return;
                }
                setRgba(rgbaArr, ((iv & 0xf00) >> 4) | ((iv & 0xf00) >> 8), (iv & 0xf0) | ((iv & 0xf0) >> 4), (iv & 0xf) | ((iv & 0xf) << 4), strLen === 5 ? parseInt(str.slice(4), 16) / 0xf : 1);
                putToCache(colorStr, rgbaArr);
                return rgbaArr;
            }
            else if (strLen === 7 || strLen === 9) {
                var iv = parseInt(str.slice(1, 7), 16);
                if (!(iv >= 0 && iv <= 0xffffff)) {
                    setRgba(rgbaArr, 0, 0, 0, 1);
                    return;
                }
                setRgba(rgbaArr, (iv & 0xff0000) >> 16, (iv & 0xff00) >> 8, iv & 0xff, strLen === 9 ? parseInt(str.slice(7), 16) / 0xff : 1);
                putToCache(colorStr, rgbaArr);
                return rgbaArr;
            }
            return;
        }
        var op = str.indexOf('(');
        var ep = str.indexOf(')');
        if (op !== -1 && ep + 1 === strLen) {
            var fname = str.substr(0, op);
            var params = str.substr(op + 1, ep - (op + 1)).split(',');
            var alpha = 1;
            switch (fname) {
                case 'rgba':
                    if (params.length !== 4) {
                        return params.length === 3
                            ? setRgba(rgbaArr, +params[0], +params[1], +params[2], 1)
                            : setRgba(rgbaArr, 0, 0, 0, 1);
                    }
                    alpha = parseCssFloat(params.pop());
                case 'rgb':
                    if (params.length >= 3) {
                        setRgba(rgbaArr, parseCssInt(params[0]), parseCssInt(params[1]), parseCssInt(params[2]), params.length === 3 ? alpha : parseCssFloat(params[3]));
                        putToCache(colorStr, rgbaArr);
                        return rgbaArr;
                    }
                    else {
                        setRgba(rgbaArr, 0, 0, 0, 1);
                        return;
                    }
                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;
    }
    function hsla2rgba(hsla, rgba) {
        var h = (((parseFloat(hsla[0]) % 360) + 360) % 360) / 360;
        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;
    }
    function rgba2hsla(rgba) {
        if (!rgba) {
            return;
        }
        var R = rgba[0] / 255;
        var G = rgba[1] / 255;
        var B = rgba[2] / 255;
        var vMin = Math.min(R, G, B);
        var vMax = Math.max(R, G, B);
        var delta = vMax - vMin;
        var L = (vMax + vMin) / 2;
        var H;
        var S;
        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;
    }
    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 (colorArr[i] < 0) {
                    colorArr[i] = 0;
                }
            }
            return stringify(colorArr, colorArr.length === 4 ? 'rgba' : 'rgb');
        }
    }
    function toHex(color) {
        var colorArr = parse(color);
        if (colorArr) {
            return ((1 << 24) + (colorArr[0] << 16) + (colorArr[1] << 8) + (+colorArr[2])).toString(16).slice(1);
        }
    }
    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;
    }
    var fastMapToColor = fastLerp;
    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;
    }
    var mapToColor = lerp$1;
    function modifyHSL(color, h, s, l) {
        var colorArr = parse(color);
        if (color) {
            colorArr = rgba2hsla(colorArr);
            h != null && (colorArr[0] = clampCssAngle(h));
            s != null && (colorArr[1] = parseCssFloat(s));
            l != null && (colorArr[2] = parseCssFloat(l));
            return stringify(hsla2rgba(colorArr), 'rgba');
        }
    }
    function modifyAlpha(color, alpha) {
        var colorArr = parse(color);
        if (colorArr && alpha != null) {
            colorArr[3] = clampCssFloat(alpha);
            return stringify(colorArr, 'rgba');
        }
    }
    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 + ')';
    }
    function lum(color, backgroundLum) {
        var arr = parse(color);
        return arr
            ? (0.299 * arr[0] + 0.587 * arr[1] + 0.114 * arr[2]) * arr[3] / 255
                + (1 - arr[3]) * backgroundLum
            : 0;
    }
    function random() {
        return stringify([
            Math.round(Math.random() * 255),
            Math.round(Math.random() * 255),
            Math.round(Math.random() * 255)
        ], 'rgb');
    }

    var color = /*#__PURE__*/Object.freeze({
        __proto__: null,
        parse: parse,
        lift: lift,
        toHex: toHex,
        fastLerp: fastLerp,
        fastMapToColor: fastMapToColor,
        lerp: lerp$1,
        mapToColor: mapToColor,
        modifyHSL: modifyHSL,
        modifyAlpha: modifyAlpha,
        stringify: stringify,
        lum: lum,
        random: random
    });

    var mathRound = Math.round;
    function normalizeColor(color) {
        var opacity;
        if (!color || color === 'transparent') {
            color = 'none';
        }
        else if (typeof color === 'string' && color.indexOf('rgba') > -1) {
            var arr = parse(color);
            if (arr) {
                color = 'rgb(' + arr[0] + ',' + arr[1] + ',' + arr[2] + ')';
                opacity = arr[3];
            }
        }
        return {
            color: color,
            opacity: opacity == null ? 1 : opacity
        };
    }
    var EPSILON$1 = 1e-4;
    function isAroundZero$1(transform) {
        return transform < EPSILON$1 && transform > -EPSILON$1;
    }
    function round3(transform) {
        return mathRound(transform * 1e3) / 1e3;
    }
    function round4(transform) {
        return mathRound(transform * 1e4) / 1e4;
    }
    function getMatrixStr(m) {
        return 'matrix('
            + round3(m[0]) + ','
            + round3(m[1]) + ','
            + round3(m[2]) + ','
            + round3(m[3]) + ','
            + round4(m[4]) + ','
            + round4(m[5])
            + ')';
    }
    var TEXT_ALIGN_TO_ANCHOR = {
        left: 'start',
        right: 'end',
        center: 'middle',
        middle: 'middle'
    };
    function adjustTextY(y, lineHeight, textBaseline) {
        if (textBaseline === 'top') {
            y += lineHeight / 2;
        }
        else if (textBaseline === 'bottom') {
            y -= lineHeight / 2;
        }
        return y;
    }
    function hasShadow(style) {
        return style
            && (style.shadowBlur || style.shadowOffsetX || style.shadowOffsetY);
    }
    function getShadowKey(displayable) {
        var style = displayable.style;
        var globalScale = displayable.getGlobalScale();
        return [
            style.shadowColor,
            (style.shadowBlur || 0).toFixed(2),
            (style.shadowOffsetX || 0).toFixed(2),
            (style.shadowOffsetY || 0).toFixed(2),
            globalScale[0],
            globalScale[1]
        ].join(',');
    }
    function isImagePattern(val) {
        return val && (!!val.image);
    }
    function isSVGPattern(val) {
        return val && (!!val.svgElement);
    }
    function isPattern(val) {
        return isImagePattern(val) || isSVGPattern(val);
    }
    function isLinearGradient(val) {
        return val.type === 'linear';
    }
    function isRadialGradient(val) {
        return val.type === 'radial';
    }
    function isGradient(val) {
        return val && (val.type === 'linear'
            || val.type === 'radial');
    }
    function getIdURL(id) {
        return "url(#" + id + ")";
    }
    function getPathPrecision(el) {
        var scale = el.getGlobalScale();
        var size = Math.max(scale[0], scale[1]);
        return Math.max(Math.ceil(Math.log(size) / Math.log(10)), 1);
    }
    function getSRTTransformString(transform) {
        var x = transform.x || 0;
        var y = transform.y || 0;
        var rotation = (transform.rotation || 0) * RADIAN_TO_DEGREE;
        var scaleX = retrieve2(transform.scaleX, 1);
        var scaleY = retrieve2(transform.scaleY, 1);
        var skewX = transform.skewX || 0;
        var skewY = transform.skewY || 0;
        var res = [];
        if (x || y) {
            res.push("translate(" + x + "px," + y + "px)");
        }
        if (rotation) {
            res.push("rotate(" + rotation + ")");
        }
        if (scaleX !== 1 || scaleY !== 1) {
            res.push("scale(" + scaleX + "," + scaleY + ")");
        }
        if (skewX || skewY) {
            res.push("skew(" + mathRound(skewX * RADIAN_TO_DEGREE) + "deg, " + mathRound(skewY * RADIAN_TO_DEGREE) + "deg)");
        }
        return res.join(' ');
    }
    var encodeBase64 = (function () {
        if (env.hasGlobalWindow && isFunction(window.btoa)) {
            return function (str) {
                return window.btoa(unescape(encodeURIComponent(str)));
            };
        }
        if (typeof Buffer !== 'undefined') {
            return function (str) {
                return Buffer.from(str).toString('base64');
            };
        }
        return function (str) {
            if ("development" !== 'production') {
                logError('Base64 isn\'t natively supported in the current environment.');
            }
            return null;
        };
    })();

    var arraySlice = Array.prototype.slice;
    function interpolateNumber(p0, p1, percent) {
        return (p1 - p0) * percent + p0;
    }
    function interpolate1DArray(out, p0, p1, percent) {
        var len = p0.length;
        for (var i = 0; i < len; i++) {
            out[i] = interpolateNumber(p0[i], p1[i], percent);
        }
        return out;
    }
    function interpolate2DArray(out, p0, p1, percent) {
        var len = p0.length;
        var len2 = len && p0[0].length;
        for (var i = 0; i < len; i++) {
            if (!out[i]) {
                out[i] = [];
            }
            for (var j = 0; j < len2; j++) {
                out[i][j] = interpolateNumber(p0[i][j], p1[i][j], percent);
            }
        }
        return out;
    }
    function add1DArray(out, p0, p1, sign) {
        var len = p0.length;
        for (var i = 0; i < len; i++) {
            out[i] = p0[i] + p1[i] * sign;
        }
        return out;
    }
    function add2DArray(out, p0, p1, sign) {
        var len = p0.length;
        var len2 = len && p0[0].length;
        for (var i = 0; i < len; i++) {
            if (!out[i]) {
                out[i] = [];
            }
            for (var j = 0; j < len2; j++) {
                out[i][j] = p0[i][j] + p1[i][j] * sign;
            }
        }
        return out;
    }
    function fillColorStops(val0, val1) {
        var len0 = val0.length;
        var len1 = val1.length;
        var shorterArr = len0 > len1 ? val1 : val0;
        var shorterLen = Math.min(len0, len1);
        var last = shorterArr[shorterLen - 1] || { color: [0, 0, 0, 0], offset: 0 };
        for (var i = shorterLen; i < Math.max(len0, len1); i++) {
            shorterArr.push({
                offset: last.offset,
                color: last.color.slice()
            });
        }
    }
    function fillArray(val0, val1, arrDim) {
        var arr0 = val0;
        var arr1 = val1;
        if (!arr0.push || !arr1.push) {
            return;
        }
        var arr0Len = arr0.length;
        var arr1Len = arr1.length;
        if (arr0Len !== arr1Len) {
            var isPreviousLarger = arr0Len > arr1Len;
            if (isPreviousLarger) {
                arr0.length = arr1Len;
            }
            else {
                for (var i = arr0Len; i < arr1Len; i++) {
                    arr0.push(arrDim === 1 ? arr1[i] : arraySlice.call(arr1[i]));
                }
            }
        }
        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];
                    }
                }
            }
        }
    }
    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]) || 0;
        rgba[1] = Math.floor(rgba[1]) || 0;
        rgba[2] = Math.floor(rgba[2]) || 0;
        rgba[3] = rgba[3] == null ? 1 : rgba[3];
        return 'rgba(' + rgba.join(',') + ')';
    }
    function guessArrayDim(value) {
        return isArrayLike(value && value[0]) ? 2 : 1;
    }
    var VALUE_TYPE_NUMBER = 0;
    var VALUE_TYPE_1D_ARRAY = 1;
    var VALUE_TYPE_2D_ARRAY = 2;
    var VALUE_TYPE_COLOR = 3;
    var VALUE_TYPE_LINEAR_GRADIENT = 4;
    var VALUE_TYPE_RADIAL_GRADIENT = 5;
    var VALUE_TYPE_UNKOWN = 6;
    function isGradientValueType(valType) {
        return valType === VALUE_TYPE_LINEAR_GRADIENT || valType === VALUE_TYPE_RADIAL_GRADIENT;
    }
    function isArrayValueType(valType) {
        return valType === VALUE_TYPE_1D_ARRAY || valType === VALUE_TYPE_2D_ARRAY;
    }
    var tmpRgba = [0, 0, 0, 0];
    var Track = (function () {
        function Track(propName) {
            this.keyframes = [];
            this.discrete = false;
            this._invalid = false;
            this._needsSort = false;
            this._lastFr = 0;
            this._lastFrP = 0;
            this.propName = propName;
        }
        Track.prototype.isFinished = function () {
            return this._finished;
        };
        Track.prototype.setFinished = function () {
            this._finished = true;
            if (this._additiveTrack) {
                this._additiveTrack.setFinished();
            }
        };
        Track.prototype.needsAnimate = function () {
            return this.keyframes.length >= 1;
        };
        Track.prototype.getAdditiveTrack = function () {
            return this._additiveTrack;
        };
        Track.prototype.addKeyframe = function (time, rawValue, easing) {
            this._needsSort = true;
            var keyframes = this.keyframes;
            var len = keyframes.length;
            var discrete = false;
            var valType = VALUE_TYPE_UNKOWN;
            var value = rawValue;
            if (isArrayLike(rawValue)) {
                var arrayDim = guessArrayDim(rawValue);
                valType = arrayDim;
                if (arrayDim === 1 && !isNumber(rawValue[0])
                    || arrayDim === 2 && !isNumber(rawValue[0][0])) {
                    discrete = true;
                }
            }
            else {
                if (isNumber(rawValue) && !eqNaN(rawValue)) {
                    valType = VALUE_TYPE_NUMBER;
                }
                else if (isString(rawValue)) {
                    if (!isNaN(+rawValue)) {
                        valType = VALUE_TYPE_NUMBER;
                    }
                    else {
                        var colorArray = parse(rawValue);
                        if (colorArray) {
                            value = colorArray;
                            valType = VALUE_TYPE_COLOR;
                        }
                    }
                }
                else if (isGradientObject(rawValue)) {
                    var parsedGradient = extend({}, value);
                    parsedGradient.colorStops = map(rawValue.colorStops, function (colorStop) { return ({
                        offset: colorStop.offset,
                        color: parse(colorStop.color)
                    }); });
                    if (isLinearGradient(rawValue)) {
                        valType = VALUE_TYPE_LINEAR_GRADIENT;
                    }
                    else if (isRadialGradient(rawValue)) {
                        valType = VALUE_TYPE_RADIAL_GRADIENT;
                    }
                    value = parsedGradient;
                }
            }
            if (len === 0) {
                this.valType = valType;
            }
            else if (valType !== this.valType || valType === VALUE_TYPE_UNKOWN) {
                discrete = true;
            }
            this.discrete = this.discrete || discrete;
            var kf = {
                time: time,
                value: value,
                rawValue: rawValue,
                percent: 0
            };
            if (easing) {
                kf.easing = easing;
                kf.easingFunc = isFunction(easing)
                    ? easing
                    : easingFuncs[easing] || createCubicEasingFunc(easing);
            }
            keyframes.push(kf);
            return kf;
        };
        Track.prototype.prepare = function (maxTime, additiveTrack) {
            var kfs = this.keyframes;
            if (this._needsSort) {
                kfs.sort(function (a, b) {
                    return a.time - b.time;
                });
            }
            var valType = this.valType;
            var kfsLen = kfs.length;
            var lastKf = kfs[kfsLen - 1];
            var isDiscrete = this.discrete;
            var isArr = isArrayValueType(valType);
            var isGradient = isGradientValueType(valType);
            for (var i = 0; i < kfsLen; i++) {
                var kf = kfs[i];
                var value = kf.value;
                var lastValue = lastKf.value;
                kf.percent = kf.time / maxTime;
                if (!isDiscrete) {
                    if (isArr && i !== kfsLen - 1) {
                        fillArray(value, lastValue, valType);
                    }
                    else if (isGradient) {
                        fillColorStops(value.colorStops, lastValue.colorStops);
                    }
                }
            }
            if (!isDiscrete
                && valType !== VALUE_TYPE_RADIAL_GRADIENT
                && additiveTrack
                && this.needsAnimate()
                && additiveTrack.needsAnimate()
                && valType === additiveTrack.valType
                && !additiveTrack._finished) {
                this._additiveTrack = additiveTrack;
                var startValue = kfs[0].value;
                for (var i = 0; i < kfsLen; i++) {
                    if (valType === VALUE_TYPE_NUMBER) {
                        kfs[i].additiveValue = kfs[i].value - startValue;
                    }
                    else if (valType === VALUE_TYPE_COLOR) {
                        kfs[i].additiveValue =
                            add1DArray([], kfs[i].value, startValue, -1);
                    }
                    else if (isArrayValueType(valType)) {
                        kfs[i].additiveValue = valType === VALUE_TYPE_1D_ARRAY
                            ? add1DArray([], kfs[i].value, startValue, -1)
                            : add2DArray([], kfs[i].value, startValue, -1);
                    }
                }
            }
        };
        Track.prototype.step = function (target, percent) {
            if (this._finished) {
                return;
            }
            if (this._additiveTrack && this._additiveTrack._finished) {
                this._additiveTrack = null;
            }
            var isAdditive = this._additiveTrack != null;
            var valueKey = isAdditive ? 'additiveValue' : 'value';
            var valType = this.valType;
            var keyframes = this.keyframes;
            var kfsNum = keyframes.length;
            var propName = this.propName;
            var isValueColor = valType === VALUE_TYPE_COLOR;
            var frameIdx;
            var lastFrame = this._lastFr;
            var mathMin = Math.min;
            var frame;
            var nextFrame;
            if (kfsNum === 1) {
                frame = nextFrame = keyframes[0];
            }
            else {
                if (percent < 0) {
                    frameIdx = 0;
                }
                else if (percent < this._lastFrP) {
                    var start = mathMin(lastFrame + 1, kfsNum - 1);
                    for (frameIdx = start; frameIdx >= 0; frameIdx--) {
                        if (keyframes[frameIdx].percent <= percent) {
                            break;
                        }
                    }
                    frameIdx = mathMin(frameIdx, kfsNum - 2);
                }
                else {
                    for (frameIdx = lastFrame; frameIdx < kfsNum; frameIdx++) {
                        if (keyframes[frameIdx].percent > percent) {
                            break;
                        }
                    }
                    frameIdx = mathMin(frameIdx - 1, kfsNum - 2);
                }
                nextFrame = keyframes[frameIdx + 1];
                frame = keyframes[frameIdx];
            }
            if (!(frame && nextFrame)) {
                return;
            }
            this._lastFr = frameIdx;
            this._lastFrP = percent;
            var interval = (nextFrame.percent - frame.percent);
            var w = interval === 0 ? 1 : mathMin((percent - frame.percent) / interval, 1);
            if (nextFrame.easingFunc) {
                w = nextFrame.easingFunc(w);
            }
            var targetArr = isAdditive ? this._additiveValue
                : (isValueColor ? tmpRgba : target[propName]);
            if ((isArrayValueType(valType) || isValueColor) && !targetArr) {
                targetArr = this._additiveValue = [];
            }
            if (this.discrete) {
                target[propName] = w < 1 ? frame.rawValue : nextFrame.rawValue;
            }
            else if (isArrayValueType(valType)) {
                valType === VALUE_TYPE_1D_ARRAY
                    ? interpolate1DArray(targetArr, frame[valueKey], nextFrame[valueKey], w)
                    : interpolate2DArray(targetArr, frame[valueKey], nextFrame[valueKey], w);
            }
            else if (isGradientValueType(valType)) {
                var val = frame[valueKey];
                var nextVal_1 = nextFrame[valueKey];
                var isLinearGradient_1 = valType === VALUE_TYPE_LINEAR_GRADIENT;
                target[propName] = {
                    type: isLinearGradient_1 ? 'linear' : 'radial',
                    x: interpolateNumber(val.x, nextVal_1.x, w),
                    y: interpolateNumber(val.y, nextVal_1.y, w),
                    colorStops: map(val.colorStops, function (colorStop, idx) {
                        var nextColorStop = nextVal_1.colorStops[idx];
                        return {
                            offset: interpolateNumber(colorStop.offset, nextColorStop.offset, w),
                            color: rgba2String(interpolate1DArray([], colorStop.color, nextColorStop.color, w))
                        };
                    }),
                    global: nextVal_1.global
                };
                if (isLinearGradient_1) {
                    target[propName].x2 = interpolateNumber(val.x2, nextVal_1.x2, w);
                    target[propName].y2 = interpolateNumber(val.y2, nextVal_1.y2, w);
                }
                else {
                    target[propName].r = interpolateNumber(val.r, nextVal_1.r, w);
                }
            }
            else if (isValueColor) {
                interpolate1DArray(targetArr, frame[valueKey], nextFrame[valueKey], w);
                if (!isAdditive) {
                    target[propName] = rgba2String(targetArr);
                }
            }
            else {
                var value = interpolateNumber(frame[valueKey], nextFrame[valueKey], w);
                if (isAdditive) {
                    this._additiveValue = value;
                }
                else {
                    target[propName] = value;
                }
            }
            if (isAdditive) {
                this._addToTarget(target);
            }
        };
        Track.prototype._addToTarget = function (target) {
            var valType = this.valType;
            var propName = this.propName;
            var additiveValue = this._additiveValue;
            if (valType === VALUE_TYPE_NUMBER) {
                target[propName] = target[propName] + additiveValue;
            }
            else if (valType === VALUE_TYPE_COLOR) {
                parse(target[propName], tmpRgba);
                add1DArray(tmpRgba, tmpRgba, additiveValue, 1);
                target[propName] = rgba2String(tmpRgba);
            }
            else if (valType === VALUE_TYPE_1D_ARRAY) {
                add1DArray(target[propName], target[propName], additiveValue, 1);
            }
            else if (valType === VALUE_TYPE_2D_ARRAY) {
                add2DArray(target[propName], target[propName], additiveValue, 1);
            }
        };
        return Track;
    }());
    var Animator = (function () {
        function Animator(target, loop, allowDiscreteAnimation, additiveTo) {
            this._tracks = {};
            this._trackKeys = [];
            this._maxTime = 0;
            this._started = 0;
            this._clip = null;
            this._target = target;
            this._loop = loop;
            if (loop && additiveTo) {
                logError('Can\' use additive animation on looped animation.');
                return;
            }
            this._additiveAnimators = additiveTo;
            this._allowDiscrete = allowDiscreteAnimation;
        }
        Animator.prototype.getMaxTime = function () {
            return this._maxTime;
        };
        Animator.prototype.getDelay = function () {
            return this._delay;
        };
        Animator.prototype.getLoop = function () {
            return this._loop;
        };
        Animator.prototype.getTarget = function () {
            return this._target;
        };
        Animator.prototype.changeTarget = function (target) {
            this._target = target;
        };
        Animator.prototype.when = function (time, props, easing) {
            return this.whenWithKeys(time, props, keys(props), easing);
        };
        Animator.prototype.whenWithKeys = function (time, props, propNames, easing) {
            var tracks = this._tracks;
            for (var i = 0; i < propNames.length; i++) {
                var propName = propNames[i];
                var track = tracks[propName];
                if (!track) {
                    track = tracks[propName] = new Track(propName);
                    var initialValue = void 0;
                    var additiveTrack = this._getAdditiveTrack(propName);
                    if (additiveTrack) {
                        var addtiveTrackKfs = additiveTrack.keyframes;
                        var lastFinalKf = addtiveTrackKfs[addtiveTrackKfs.length - 1];
                        initialValue = lastFinalKf && lastFinalKf.value;
                        if (additiveTrack.valType === VALUE_TYPE_COLOR && initialValue) {
                            initialValue = rgba2String(initialValue);
                        }
                    }
                    else {
                        initialValue = this._target[propName];
                    }
                    if (initialValue == null) {
                        continue;
                    }
                    if (time > 0) {
                        track.addKeyframe(0, cloneValue(initialValue), easing);
                    }
                    this._trackKeys.push(propName);
                }
                track.addKeyframe(time, cloneValue(props[propName]), easing);
            }
            this._maxTime = Math.max(this._maxTime, time);
            return this;
        };
        Animator.prototype.pause = function () {
            this._clip.pause();
            this._paused = true;
        };
        Animator.prototype.resume = function () {
            this._clip.resume();
            this._paused = false;
        };
        Animator.prototype.isPaused = function () {
            return !!this._paused;
        };
        Animator.prototype.duration = function (duration) {
            this._maxTime = duration;
            this._force = true;
            return this;
        };
        Animator.prototype._doneCallback = function () {
            this._setTracksFinished();
            this._clip = null;
            var doneList = this._doneCbs;
            if (doneList) {
                var len = doneList.length;
                for (var i = 0; i < len; i++) {
                    doneList[i].call(this);
                }
            }
        };
        Animator.prototype._abortedCallback = function () {
            this._setTracksFinished();
            var animation = this.animation;
            var abortedList = this._abortedCbs;
            if (animation) {
                animation.removeClip(this._clip);
            }
            this._clip = null;
            if (abortedList) {
                for (var i = 0; i < abortedList.length; i++) {
                    abortedList[i].call(this);
                }
            }
        };
        Animator.prototype._setTracksFinished = function () {
            var tracks = this._tracks;
            var tracksKeys = this._trackKeys;
            for (var i = 0; i < tracksKeys.length; i++) {
                tracks[tracksKeys[i]].setFinished();
            }
        };
        Animator.prototype._getAdditiveTrack = function (trackName) {
            var additiveTrack;
            var additiveAnimators = this._additiveAnimators;
            if (additiveAnimators) {
                for (var i = 0; i < additiveAnimators.length; i++) {
                    var track = additiveAnimators[i].getTrack(trackName);
                    if (track) {
                        additiveTrack = track;
                    }
                }
            }
            return additiveTrack;
        };
        Animator.prototype.start = function (easing) {
            if (this._started > 0) {
                return;
            }
            this._started = 1;
            var self = this;
            var tracks = [];
            var maxTime = this._maxTime || 0;
            for (var i = 0; i < this._trackKeys.length; i++) {
                var propName = this._trackKeys[i];
                var track = this._tracks[propName];
                var additiveTrack = this._getAdditiveTrack(propName);
                var kfs = track.keyframes;
                var kfsNum = kfs.length;
                track.prepare(maxTime, additiveTrack);
                if (track.needsAnimate()) {
                    if (!this._allowDiscrete && track.discrete) {
                        var lastKf = kfs[kfsNum - 1];
                        if (lastKf) {
                            self._target[track.propName] = lastKf.rawValue;
                        }
                        track.setFinished();
                    }
                    else {
                        tracks.push(track);
                    }
                }
            }
            if (tracks.length || this._force) {
                var clip = new Clip({
                    life: maxTime,
                    loop: this._loop,
                    delay: this._delay || 0,
                    onframe: function (percent) {
                        self._started = 2;
                        var additiveAnimators = self._additiveAnimators;
                        if (additiveAnimators) {
                            var stillHasAdditiveAnimator = false;
                            for (var i = 0; i < additiveAnimators.length; i++) {
                                if (additiveAnimators[i]._clip) {
                                    stillHasAdditiveAnimator = true;
                                    break;
                                }
                            }
                            if (!stillHasAdditiveAnimator) {
                                self._additiveAnimators = null;
                            }
                        }
                        for (var i = 0; i < tracks.length; i++) {
                            tracks[i].step(self._target, percent);
                        }
                        var onframeList = self._onframeCbs;
                        if (onframeList) {
                            for (var i = 0; i < onframeList.length; i++) {
                                onframeList[i](self._target, percent);
                            }
                        }
                    },
                    ondestroy: function () {
                        self._doneCallback();
                    }
                });
                this._clip = clip;
                if (this.animation) {
                    this.animation.addClip(clip);
                }
                if (easing) {
                    clip.setEasing(easing);
                }
            }
            else {
                this._doneCallback();
            }
            return this;
        };
        Animator.prototype.stop = function (forwardToLast) {
            if (!this._clip) {
                return;
            }
            var clip = this._clip;
            if (forwardToLast) {
                clip.onframe(1);
            }
            this._abortedCallback();
        };
        Animator.prototype.delay = function (time) {
            this._delay = time;
            return this;
        };
        Animator.prototype.during = function (cb) {
            if (cb) {
                if (!this._onframeCbs) {
                    this._onframeCbs = [];
                }
                this._onframeCbs.push(cb);
            }
            return this;
        };
        Animator.prototype.done = function (cb) {
            if (cb) {
                if (!this._doneCbs) {
                    this._doneCbs = [];
                }
                this._doneCbs.push(cb);
            }
            return this;
        };
        Animator.prototype.aborted = function (cb) {
            if (cb) {
                if (!this._abortedCbs) {
                    this._abortedCbs = [];
                }
                this._abortedCbs.push(cb);
            }
            return this;
        };
        Animator.prototype.getClip = function () {
            return this._clip;
        };
        Animator.prototype.getTrack = function (propName) {
            return this._tracks[propName];
        };
        Animator.prototype.getTracks = function () {
            var _this = this;
            return map(this._trackKeys, function (key) { return _this._tracks[key]; });
        };
        Animator.prototype.stopTracks = function (propNames, forwardToLast) {
            if (!propNames.length || !this._clip) {
                return true;
            }
            var tracks = this._tracks;
            var tracksKeys = this._trackKeys;
            for (var i = 0; i < propNames.length; i++) {
                var track = tracks[propNames[i]];
                if (track && !track.isFinished()) {
                    if (forwardToLast) {
                        track.step(this._target, 1);
                    }
                    else if (this._started === 1) {
                        track.step(this._target, 0);
                    }
                    track.setFinished();
                }
            }
            var allAborted = true;
            for (var i = 0; i < tracksKeys.length; i++) {
                if (!tracks[tracksKeys[i]].isFinished()) {
                    allAborted = false;
                    break;
                }
            }
            if (allAborted) {
                this._abortedCallback();
            }
            return allAborted;
        };
        Animator.prototype.saveTo = function (target, trackKeys, firstOrLast) {
            if (!target) {
                return;
            }
            trackKeys = trackKeys || this._trackKeys;
            for (var i = 0; i < trackKeys.length; i++) {
                var propName = trackKeys[i];
                var track = this._tracks[propName];
                if (!track || track.isFinished()) {
                    continue;
                }
                var kfs = track.keyframes;
                var kf = kfs[firstOrLast ? 0 : kfs.length - 1];
                if (kf) {
                    target[propName] = cloneValue(kf.rawValue);
                }
            }
        };
        Animator.prototype.__changeFinalValue = function (finalProps, trackKeys) {
            trackKeys = trackKeys || keys(finalProps);
            for (var i = 0; i < trackKeys.length; i++) {
                var propName = trackKeys[i];
                var track = this._tracks[propName];
                if (!track) {
                    continue;
                }
                var kfs = track.keyframes;
                if (kfs.length > 1) {
                    var lastKf = kfs.pop();
                    track.addKeyframe(lastKf.time, finalProps[propName]);
                    track.prepare(this._maxTime, track.getAdditiveTrack());
                }
            }
        };
        return Animator;
    }());

    function getTime() {
        return new Date().getTime();
    }
    var Animation = (function (_super) {
        __extends(Animation, _super);
        function Animation(opts) {
            var _this = _super.call(this) || this;
            _this._running = false;
            _this._time = 0;
            _this._pausedTime = 0;
            _this._pauseStart = 0;
            _this._paused = false;
            opts = opts || {};
            _this.stage = opts.stage || {};
            return _this;
        }
        Animation.prototype.addClip = function (clip) {
            if (clip.animation) {
                this.removeClip(clip);
            }
            if (!this._head) {
                this._head = this._tail = clip;
            }
            else {
                this._tail.next = clip;
                clip.prev = this._tail;
                clip.next = null;
                this._tail = clip;
            }
            clip.animation = this;
        };
        Animation.prototype.addAnimator = function (animator) {
            animator.animation = this;
            var clip = animator.getClip();
            if (clip) {
                this.addClip(clip);
            }
        };
        Animation.prototype.removeClip = function (clip) {
            if (!clip.animation) {
                return;
            }
            var prev = clip.prev;
            var next = clip.next;
            if (prev) {
                prev.next = next;
            }
            else {
                this._head = next;
            }
            if (next) {
                next.prev = prev;
            }
            else {
                this._tail = prev;
            }
            clip.next = clip.prev = clip.animation = null;
        };
        Animation.prototype.removeAnimator = function (animator) {
            var clip = animator.getClip();
            if (clip) {
                this.removeClip(clip);
            }
            animator.animation = null;
        };
        Animation.prototype.update = function (notTriggerFrameAndStageUpdate) {
            var time = getTime() - this._pausedTime;
            var delta = time - this._time;
            var clip = this._head;
            while (clip) {
                var nextClip = clip.next;
                var finished = clip.step(time, delta);
                if (finished) {
                    clip.ondestroy();
                    this.removeClip(clip);
                    clip = nextClip;
                }
                else {
                    clip = nextClip;
                }
            }
            this._time = time;
            if (!notTriggerFrameAndStageUpdate) {
                this.trigger('frame', delta);
                this.stage.update && this.stage.update();
            }
        };
        Animation.prototype._startLoop = function () {
            var self = this;
            this._running = true;
            function step() {
                if (self._running) {
                    requestAnimationFrame$1(step);
                    !self._paused && self.update();
                }
            }
            requestAnimationFrame$1(step);
        };
        Animation.prototype.start = function () {
            if (this._running) {
                return;
            }
            this._time = getTime();
            this._pausedTime = 0;
            this._startLoop();
        };
        Animation.prototype.stop = function () {
            this._running = false;
        };
        Animation.prototype.pause = function () {
            if (!this._paused) {
                this._pauseStart = getTime();
                this._paused = true;
            }
        };
        Animation.prototype.resume = function () {
            if (this._paused) {
                this._pausedTime += getTime() - this._pauseStart;
                this._paused = false;
            }
        };
        Animation.prototype.clear = function () {
            var clip = this._head;
            while (clip) {
                var nextClip = clip.next;
                clip.prev = clip.next = clip.animation = null;
                clip = nextClip;
            }
            this._head = this._tail = null;
        };
        Animation.prototype.isFinished = function () {
            return this._head == null;
        };
        Animation.prototype.animate = function (target, options) {
            options = options || {};
            this.start();
            var animator = new Animator(target, options.loop);
            this.addAnimator(animator);
            return animator;
        };
        return Animation;
    }(Eventful));

    var TOUCH_CLICK_DELAY = 300;
    var globalEventSupported = env.domSupported;
    var localNativeListenerNames = (function () {
        var mouseHandlerNames = [
            'click', 'dblclick', 'mousewheel', 'wheel', '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']
    };
    var wheelEventSupported = false;
    function isPointerFromTouch(event) {
        var pointerType = event.pointerType;
        return pointerType === 'pen' || pointerType === 'touch';
    }
    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);
    }
    function markTouch(event) {
        event && (event.zrByTouch = true);
    }
    function normalizeGlobalEvent(instance, event) {
        return normalizeEvent(instance.dom, new FakeGlobalEvent(instance, event), true);
    }
    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;
    }
    var FakeGlobalEvent = (function () {
        function FakeGlobalEvent(instance, event) {
            this.stopPropagation = noop;
            this.stopImmediatePropagation = noop;
            this.preventDefault = noop;
            this.type = event.type;
            this.target = this.currentTarget = instance.dom;
            this.pointerType = event.pointerType;
            this.clientX = event.clientX;
            this.clientY = event.clientY;
        }
        return FakeGlobalEvent;
    }());
    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])) {
                this.__togglePointerCapture(true);
            }
            this.trigger('mousemove', event);
        },
        mouseup: function (event) {
            event = normalizeEvent(this.dom, event);
            this.__togglePointerCapture(false);
            this.trigger('mouseup', event);
        },
        mouseout: function (event) {
            event = normalizeEvent(this.dom, event);
            var element = event.toElement || event.relatedTarget;
            if (!isLocalEl(this, element)) {
                if (this.__pointerCapturing) {
                    event.zrEventControl = 'no_globalout';
                }
                this.trigger('mouseout', event);
            }
        },
        wheel: function (event) {
            wheelEventSupported = true;
            event = normalizeEvent(this.dom, event);
            this.trigger('mousewheel', event);
        },
        mousewheel: function (event) {
            if (wheelEventSupported) {
                return;
            }
            event = normalizeEvent(this.dom, event);
            this.trigger('mousewheel', event);
        },
        touchstart: function (event) {
            event = normalizeEvent(this.dom, event);
            markTouch(event);
            this.__lastTouchMoment = new Date();
            this.handler.processGesture(event, 'start');
            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');
            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);
            if (+new Date() - (+this.__lastTouchMoment) < TOUCH_CLICK_DELAY) {
                localDOMHandlers.click.call(this, event);
            }
        },
        pointerdown: function (event) {
            localDOMHandlers.mousedown.call(this, event);
        },
        pointermove: function (event) {
            if (!isPointerFromTouch(event)) {
                localDOMHandlers.mousemove.call(this, event);
            }
        },
        pointerup: function (event) {
            localDOMHandlers.mouseup.call(this, event);
        },
        pointerout: function (event) {
            if (!isPointerFromTouch(event)) {
                localDOMHandlers.mouseout.call(this, event);
            }
        }
    };
    each(['click', 'dblclick', 'contextmenu'], function (name) {
        localDOMHandlers[name] = function (event) {
            event = normalizeEvent(this.dom, event);
            this.trigger(name, event);
        };
    });
    var globalDOMHandlers = {
        pointermove: function (event) {
            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;
            this.__togglePointerCapture(false);
            this.trigger('mouseup', event);
            if (pointerCaptureReleasing) {
                event.zrEventControl = 'only_globalout';
                this.trigger('mouseout', event);
            }
        }
    };
    function mountLocalDOMEventListeners(instance, scope) {
        var domHandlers = scope.domHandlers;
        if (env.pointerEventsSupported) {
            each(localNativeListenerNames.pointer, function (nativeEventName) {
                mountSingleDOMEventListener(scope, nativeEventName, function (event) {
                    domHandlers[nativeEventName].call(instance, event);
                });
            });
        }
        else {
            if (env.touchEventsSupported) {
                each(localNativeListenerNames.touch, function (nativeEventName) {
                    mountSingleDOMEventListener(scope, nativeEventName, function (event) {
                        domHandlers[nativeEventName].call(instance, event);
                        setTouchTimer(scope);
                    });
                });
            }
            each(localNativeListenerNames.mouse, function (nativeEventName) {
                mountSingleDOMEventListener(scope, nativeEventName, function (event) {
                    event = getNativeEvent(event);
                    if (!scope.touching) {
                        domHandlers[nativeEventName].call(instance, event);
                    }
                });
            });
        }
    }
    function mountGlobalDOMEventListeners(instance, scope) {
        if (env.pointerEventsSupported) {
            each(globalNativeListenerNames.pointer, mount);
        }
        else if (!env.touchEventsSupported) {
            each(globalNativeListenerNames.mouse, mount);
        }
        function mount(nativeEventName) {
            function nativeEventListener(event) {
                event = getNativeEvent(event);
                if (!isLocalEl(instance, event.target)) {
                    event = normalizeGlobalEvent(instance, event);
                    scope.domHandlers[nativeEventName].call(instance, event);
                }
            }
            mountSingleDOMEventListener(scope, nativeEventName, nativeEventListener, { capture: true });
        }
    }
    function mountSingleDOMEventListener(scope, nativeEventName, listener, opt) {
        scope.mounted[nativeEventName] = listener;
        scope.listenerOpts[nativeEventName] = opt;
        addEventListener(scope.domTarget, nativeEventName, listener, opt);
    }
    function unmountDOMEventListeners(scope) {
        var mounted = scope.mounted;
        for (var nativeEventName in mounted) {
            if (mounted.hasOwnProperty(nativeEventName)) {
                removeEventListener(scope.domTarget, nativeEventName, mounted[nativeEventName], scope.listenerOpts[nativeEventName]);
            }
        }
        scope.mounted = {};
    }
    var DOMHandlerScope = (function () {
        function DOMHandlerScope(domTarget, domHandlers) {
            this.mounted = {};
            this.listenerOpts = {};
            this.touching = false;
            this.domTarget = domTarget;
            this.domHandlers = domHandlers;
        }
        return DOMHandlerScope;
    }());
    var HandlerDomProxy = (function (_super) {
        __extends(HandlerDomProxy, _super);
        function HandlerDomProxy(dom, painterRoot) {
            var _this = _super.call(this) || this;
            _this.__pointerCapturing = false;
            _this.dom = dom;
            _this.painterRoot = painterRoot;
            _this._localHandlerScope = new DOMHandlerScope(dom, localDOMHandlers);
            if (globalEventSupported) {
                _this._globalHandlerScope = new DOMHandlerScope(document, globalDOMHandlers);
            }
            mountLocalDOMEventListeners(_this, _this._localHandlerScope);
            return _this;
        }
        HandlerDomProxy.prototype.dispose = function () {
            unmountDOMEventListeners(this._localHandlerScope);
            if (globalEventSupported) {
                unmountDOMEventListeners(this._globalHandlerScope);
            }
        };
        HandlerDomProxy.prototype.setCursor = function (cursorStyle) {
            this.dom.style && (this.dom.style.cursor = cursorStyle || 'default');
        };
        HandlerDomProxy.prototype.__togglePointerCapture = function (isPointerCapturing) {
            this.__mayPointerCapture = null;
            if (globalEventSupported
                && ((+this.__pointerCapturing) ^ (+isPointerCapturing))) {
                this.__pointerCapturing = isPointerCapturing;
                var globalHandlerScope = this._globalHandlerScope;
                isPointerCapturing
                    ? mountGlobalDOMEventListeners(this, globalHandlerScope)
                    : unmountDOMEventListeners(globalHandlerScope);
            }
        };
        return HandlerDomProxy;
    }(Eventful));

    var dpr = 1;
    if (env.hasGlobalWindow) {
        dpr = Math.max(window.devicePixelRatio
            || (window.screen && window.screen.deviceXDPI / window.screen.logicalXDPI)
            || 1, 1);
    }
    var devicePixelRatio = dpr;
    var DARK_MODE_THRESHOLD = 0.4;
    var DARK_LABEL_COLOR = '#333';
    var LIGHT_LABEL_COLOR = '#ccc';
    var LIGHTER_LABEL_COLOR = '#eee';

    var mIdentity = identity;
    var EPSILON$2 = 5e-5;
    function isNotAroundZero$1(val) {
        return val > EPSILON$2 || val < -EPSILON$2;
    }
    var scaleTmp = [];
    var tmpTransform = [];
    var originTransform = create$1();
    var abs = Math.abs;
    var Transformable = (function () {
        function Transformable() {
        }
        Transformable.prototype.getLocalTransform = function (m) {
            return Transformable.getLocalTransform(this, m);
        };
        Transformable.prototype.setPosition = function (arr) {
            this.x = arr[0];
            this.y = arr[1];
        };
        Transformable.prototype.setScale = function (arr) {
            this.scaleX = arr[0];
            this.scaleY = arr[1];
        };
        Transformable.prototype.setSkew = function (arr) {
            this.skewX = arr[0];
            this.skewY = arr[1];
        };
        Transformable.prototype.setOrigin = function (arr) {
            this.originX = arr[0];
            this.originY = arr[1];
        };
        Transformable.prototype.needLocalTransform = function () {
            return isNotAroundZero$1(this.rotation)
                || isNotAroundZero$1(this.x)
                || isNotAroundZero$1(this.y)
                || isNotAroundZero$1(this.scaleX - 1)
                || isNotAroundZero$1(this.scaleY - 1)
                || isNotAroundZero$1(this.skewX)
                || isNotAroundZero$1(this.skewY);
        };
        Transformable.prototype.updateTransform = function () {
            var parentTransform = this.parent && this.parent.transform;
            var needLocalTransform = this.needLocalTransform();
            var m = this.transform;
            if (!(needLocalTransform || parentTransform)) {
                m && mIdentity(m);
                return;
            }
            m = m || create$1();
            if (needLocalTransform) {
                this.getLocalTransform(m);
            }
            else {
                mIdentity(m);
            }
            if (parentTransform) {
                if (needLocalTransform) {
                    mul$1(m, parentTransform, m);
                }
                else {
                    copy$1(m, parentTransform);
                }
            }
            this.transform = m;
            this._resolveGlobalScaleRatio(m);
        };
        Transformable.prototype._resolveGlobalScaleRatio = function (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);
        };
        Transformable.prototype.getComputedTransform = function () {
            var transformNode = this;
            var ancestors = [];
            while (transformNode) {
                ancestors.push(transformNode);
                transformNode = transformNode.parent;
            }
            while (transformNode = ancestors.pop()) {
                transformNode.updateTransform();
            }
            return this.transform;
        };
        Transformable.prototype.setLocalTransform = function (m) {
            if (!m) {
                return;
            }
            var sx = m[0] * m[0] + m[1] * m[1];
            var sy = m[2] * m[2] + m[3] * m[3];
            var rotation = Math.atan2(m[1], m[0]);
            var shearX = Math.PI / 2 + rotation - Math.atan2(m[3], m[2]);
            sy = Math.sqrt(sy) * Math.cos(shearX);
            sx = Math.sqrt(sx);
            this.skewX = shearX;
            this.skewY = 0;
            this.rotation = -rotation;
            this.x = +m[4];
            this.y = +m[5];
            this.scaleX = sx;
            this.scaleY = sy;
            this.originX = 0;
            this.originY = 0;
        };
        Transformable.prototype.decomposeTransform = function () {
            if (!this.transform) {
                return;
            }
            var parent = this.parent;
            var m = this.transform;
            if (parent && parent.transform) {
                mul$1(tmpTransform, parent.invTransform, m);
                m = tmpTransform;
            }
            var ox = this.originX;
            var oy = this.originY;
            if (ox || oy) {
                originTransform[4] = ox;
                originTransform[5] = oy;
                mul$1(tmpTransform, m, originTransform);
                tmpTransform[4] -= ox;
                tmpTransform[5] -= oy;
                m = tmpTransform;
            }
            this.setLocalTransform(m);
        };
        Transformable.prototype.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;
        };
        Transformable.prototype.transformCoordToLocal = function (x, y) {
            var v2 = [x, y];
            var invTransform = this.invTransform;
            if (invTransform) {
                applyTransform(v2, v2, invTransform);
            }
            return v2;
        };
        Transformable.prototype.transformCoordToGlobal = function (x, y) {
            var v2 = [x, y];
            var transform = this.transform;
            if (transform) {
                applyTransform(v2, v2, transform);
            }
            return v2;
        };
        Transformable.prototype.getLineScale = function () {
            var m = this.transform;
            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;
        };
        Transformable.prototype.copyTransform = function (source) {
            copyTransform(this, source);
        };
        Transformable.getLocalTransform = function (target, m) {
            m = m || [];
            var ox = target.originX || 0;
            var oy = target.originY || 0;
            var sx = target.scaleX;
            var sy = target.scaleY;
            var ax = target.anchorX;
            var ay = target.anchorY;
            var rotation = target.rotation || 0;
            var x = target.x;
            var y = target.y;
            var skewX = target.skewX ? Math.tan(target.skewX) : 0;
            var skewY = target.skewY ? Math.tan(-target.skewY) : 0;
            if (ox || oy || ax || ay) {
                var dx = ox + ax;
                var dy = oy + ay;
                m[4] = -dx * sx - skewX * dy * sy;
                m[5] = -dy * sy - skewY * dx * sx;
            }
            else {
                m[4] = m[5] = 0;
            }
            m[0] = sx;
            m[3] = sy;
            m[1] = skewY * sx;
            m[2] = skewX * sy;
            rotation && rotate(m, m, rotation);
            m[4] += ox + x;
            m[5] += oy + y;
            return m;
        };
        Transformable.initDefaultProps = (function () {
            var proto = Transformable.prototype;
            proto.scaleX =
                proto.scaleY =
                    proto.globalScaleRatio = 1;
            proto.x =
                proto.y =
                    proto.originX =
                        proto.originY =
                            proto.skewX =
                                proto.skewY =
                                    proto.rotation =
                                        proto.anchorX =
                                            proto.anchorY = 0;
        })();
        return Transformable;
    }());
    var TRANSFORMABLE_PROPS = [
        'x', 'y', 'originX', 'originY', 'anchorX', 'anchorY', 'rotation', 'scaleX', 'scaleY', 'skewX', 'skewY'
    ];
    function copyTransform(target, source) {
        for (var i = 0; i < TRANSFORMABLE_PROPS.length; i++) {
            var propName = TRANSFORMABLE_PROPS[i];
            target[propName] = source[propName];
        }
    }

    var textWidthCache = {};
    function getWidth(text, font) {
        font = font || DEFAULT_FONT;
        var cacheOfFont = textWidthCache[font];
        if (!cacheOfFont) {
            cacheOfFont = textWidthCache[font] = new LRU(500);
        }
        var width = cacheOfFont.get(text);
        if (width == null) {
            width = platformApi.measureText(text, font).width;
            cacheOfFont.put(text, width);
        }
        return width;
    }
    function innerGetBoundingRect(text, font, textAlign, textBaseline) {
        var width = getWidth(text, font);
        var height = getLineHeight(font);
        var x = adjustTextX(0, width, textAlign);
        var y = adjustTextY$1(0, height, textBaseline);
        var rect = new BoundingRect(x, y, width, height);
        return rect;
    }
    function getBoundingRect(text, font, textAlign, textBaseline) {
        var textLines = ((text || '') + '').split('\n');
        var len = textLines.length;
        if (len === 1) {
            return innerGetBoundingRect(textLines[0], font, textAlign, textBaseline);
        }
        else {
            var uniondRect = new BoundingRect(0, 0, 0, 0);
            for (var i = 0; i < textLines.length; i++) {
                var rect = innerGetBoundingRect(textLines[i], font, textAlign, textBaseline);
                i === 0 ? uniondRect.copy(rect) : uniondRect.union(rect);
            }
            return uniondRect;
        }
    }
    function adjustTextX(x, width, textAlign) {
        if (textAlign === 'right') {
            x -= width;
        }
        else if (textAlign === 'center') {
            x -= width / 2;
        }
        return x;
    }
    function adjustTextY$1(y, height, verticalAlign) {
        if (verticalAlign === 'middle') {
            y -= height / 2;
        }
        else if (verticalAlign === 'bottom') {
            y -= height;
        }
        return y;
    }
    function getLineHeight(font) {
        return getWidth('国', font);
    }
    function parsePercent(value, maxValue) {
        if (typeof value === 'string') {
            if (value.lastIndexOf('%') >= 0) {
                return parseFloat(value) / 100 * maxValue;
            }
            return parseFloat(value);
        }
        return value;
    }
    function calculateTextPosition(out, opts, rect) {
        var textPosition = opts.position || 'inside';
        var distance = opts.distance != null ? opts.distance : 5;
        var height = rect.height;
        var width = rect.width;
        var halfHeight = height / 2;
        var x = rect.x;
        var y = rect.y;
        var textAlign = 'left';
        var textVerticalAlign = 'top';
        if (textPosition instanceof Array) {
            x += parsePercent(textPosition[0], rect.width);
            y += parsePercent(textPosition[1], rect.height);
            textAlign = null;
            textVerticalAlign = null;
        }
        else {
            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.align = textAlign;
        out.verticalAlign = textVerticalAlign;
        return out;
    }

    var PRESERVED_NORMAL_STATE = '__zr_normal__';
    var PRIMARY_STATES_KEYS = TRANSFORMABLE_PROPS.concat(['ignore']);
    var DEFAULT_ANIMATABLE_MAP = reduce(TRANSFORMABLE_PROPS, function (obj, key) {
        obj[key] = true;
        return obj;
    }, { ignore: false });
    var tmpTextPosCalcRes = {};
    var tmpBoundingRect = new BoundingRect(0, 0, 0, 0);
    var Element = (function () {
        function Element(props) {
            this.id = guid();
            this.animators = [];
            this.currentStates = [];
            this.states = {};
            this._init(props);
        }
        Element.prototype._init = function (props) {
            this.attr(props);
        };
        Element.prototype.drift = function (dx, dy, e) {
            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.markRedraw();
        };
        Element.prototype.beforeUpdate = function () { };
        Element.prototype.afterUpdate = function () { };
        Element.prototype.update = function () {
            this.updateTransform();
            if (this.__dirty) {
                this.updateInnerText();
            }
        };
        Element.prototype.updateInnerText = function (forceUpdate) {
            var textEl = this._textContent;
            if (textEl && (!textEl.ignore || forceUpdate)) {
                if (!this.textConfig) {
                    this.textConfig = {};
                }
                var textConfig = this.textConfig;
                var isLocal = textConfig.local;
                var innerTransformable = textEl.innerTransformable;
                var textAlign = void 0;
                var textVerticalAlign = void 0;
                var textStyleChanged = false;
                innerTransformable.parent = isLocal ? this : null;
                var innerOrigin = false;
                innerTransformable.copyTransform(textEl);
                if (textConfig.position != null) {
                    var layoutRect = tmpBoundingRect;
                    if (textConfig.layoutRect) {
                        layoutRect.copy(textConfig.layoutRect);
                    }
                    else {
                        layoutRect.copy(this.getBoundingRect());
                    }
                    if (!isLocal) {
                        layoutRect.applyTransform(this.transform);
                    }
                    if (this.calculateTextPosition) {
                        this.calculateTextPosition(tmpTextPosCalcRes, textConfig, layoutRect);
                    }
                    else {
                        calculateTextPosition(tmpTextPosCalcRes, textConfig, layoutRect);
                    }
                    innerTransformable.x = tmpTextPosCalcRes.x;
                    innerTransformable.y = tmpTextPosCalcRes.y;
                    textAlign = tmpTextPosCalcRes.align;
                    textVerticalAlign = tmpTextPosCalcRes.verticalAlign;
                    var textOrigin = textConfig.origin;
                    if (textOrigin && textConfig.rotation != null) {
                        var relOriginX = void 0;
                        var relOriginY = void 0;
                        if (textOrigin === 'center') {
                            relOriginX = layoutRect.width * 0.5;
                            relOriginY = layoutRect.height * 0.5;
                        }
                        else {
                            relOriginX = parsePercent(textOrigin[0], layoutRect.width);
                            relOriginY = parsePercent(textOrigin[1], layoutRect.height);
                        }
                        innerOrigin = true;
                        innerTransformable.originX = -innerTransformable.x + relOriginX + (isLocal ? 0 : layoutRect.x);
                        innerTransformable.originY = -innerTransformable.y + relOriginY + (isLocal ? 0 : layoutRect.y);
                    }
                }
                if (textConfig.rotation != null) {
                    innerTransformable.rotation = textConfig.rotation;
                }
                var textOffset = textConfig.offset;
                if (textOffset) {
                    innerTransformable.x += textOffset[0];
                    innerTransformable.y += textOffset[1];
                    if (!innerOrigin) {
                        innerTransformable.originX = -textOffset[0];
                        innerTransformable.originY = -textOffset[1];
                    }
                }
                var isInside = textConfig.inside == null
                    ? (typeof textConfig.position === 'string' && textConfig.position.indexOf('inside') >= 0)
                    : textConfig.inside;
                var innerTextDefaultStyle = this._innerTextDefaultStyle || (this._innerTextDefaultStyle = {});
                var textFill = void 0;
                var textStroke = void 0;
                var autoStroke = void 0;
                if (isInside && this.canBeInsideText()) {
                    textFill = textConfig.insideFill;
                    textStroke = textConfig.insideStroke;
                    if (textFill == null || textFill === 'auto') {
                        textFill = this.getInsideTextFill();
                    }
                    if (textStroke == null || textStroke === 'auto') {
                        textStroke = this.getInsideTextStroke(textFill);
                        autoStroke = true;
                    }
                }
                else {
                    textFill = textConfig.outsideFill;
                    textStroke = textConfig.outsideStroke;
                    if (textFill == null || textFill === 'auto') {
                        textFill = this.getOutsideFill();
                    }
                    if (textStroke == null || textStroke === 'auto') {
                        textStroke = this.getOutsideStroke(textFill);
                        autoStroke = true;
                    }
                }
                textFill = textFill || '#000';
                if (textFill !== innerTextDefaultStyle.fill
                    || textStroke !== innerTextDefaultStyle.stroke
                    || autoStroke !== innerTextDefaultStyle.autoStroke
                    || textAlign !== innerTextDefaultStyle.align
                    || textVerticalAlign !== innerTextDefaultStyle.verticalAlign) {
                    textStyleChanged = true;
                    innerTextDefaultStyle.fill = textFill;
                    innerTextDefaultStyle.stroke = textStroke;
                    innerTextDefaultStyle.autoStroke = autoStroke;
                    innerTextDefaultStyle.align = textAlign;
                    innerTextDefaultStyle.verticalAlign = textVerticalAlign;
                    textEl.setDefaultTextStyle(innerTextDefaultStyle);
                }
                textEl.__dirty |= REDRAW_BIT;
                if (textStyleChanged) {
                    textEl.dirtyStyle(true);
                }
            }
        };
        Element.prototype.canBeInsideText = function () {
            return true;
        };
        Element.prototype.getInsideTextFill = function () {
            return '#fff';
        };
        Element.prototype.getInsideTextStroke = function (textFill) {
            return '#000';
        };
        Element.prototype.getOutsideFill = function () {
            return this.__zr && this.__zr.isDarkMode() ? LIGHT_LABEL_COLOR : DARK_LABEL_COLOR;
        };
        Element.prototype.getOutsideStroke = function (textFill) {
            var backgroundColor = this.__zr && this.__zr.getBackgroundColor();
            var colorArr = typeof backgroundColor === 'string' && parse(backgroundColor);
            if (!colorArr) {
                colorArr = [255, 255, 255, 1];
            }
            var alpha = colorArr[3];
            var isDark = this.__zr.isDarkMode();
            for (var i = 0; i < 3; i++) {
                colorArr[i] = colorArr[i] * alpha + (isDark ? 0 : 255) * (1 - alpha);
            }
            colorArr[3] = 1;
            return stringify(colorArr, 'rgba');
        };
        Element.prototype.traverse = function (cb, context) { };
        Element.prototype.attrKV = function (key, value) {
            if (key === 'textConfig') {
                this.setTextConfig(value);
            }
            else if (key === 'textContent') {
                this.setTextContent(value);
            }
            else if (key === 'clipPath') {
                this.setClipPath(value);
            }
            else if (key === 'extra') {
                this.extra = this.extra || {};
                extend(this.extra, value);
            }
            else {
                this[key] = value;
            }
        };
        Element.prototype.hide = function () {
            this.ignore = true;
            this.markRedraw();
        };
        Element.prototype.show = function () {
            this.ignore = false;
            this.markRedraw();
        };
        Element.prototype.attr = function (keyOrObj, value) {
            if (typeof keyOrObj === 'string') {
                this.attrKV(keyOrObj, value);
            }
            else if (isObject(keyOrObj)) {
                var obj = keyOrObj;
                var keysArr = keys(obj);
                for (var i = 0; i < keysArr.length; i++) {
                    var key = keysArr[i];
                    this.attrKV(key, keyOrObj[key]);
                }
            }
            this.markRedraw();
            return this;
        };
        Element.prototype.saveCurrentToNormalState = function (toState) {
            this._innerSaveToNormal(toState);
            var normalState = this._normalState;
            for (var i = 0; i < this.animators.length; i++) {
                var animator = this.animators[i];
                var fromStateTransition = animator.__fromStateTransition;
                if (animator.getLoop() || fromStateTransition && fromStateTransition !== PRESERVED_NORMAL_STATE) {
                    continue;
                }
                var targetName = animator.targetName;
                var target = targetName
                    ? normalState[targetName] : normalState;
                animator.saveTo(target);
            }
        };
        Element.prototype._innerSaveToNormal = function (toState) {
            var normalState = this._normalState;
            if (!normalState) {
                normalState = this._normalState = {};
            }
            if (toState.textConfig && !normalState.textConfig) {
                normalState.textConfig = this.textConfig;
            }
            this._savePrimaryToNormal(toState, normalState, PRIMARY_STATES_KEYS);
        };
        Element.prototype._savePrimaryToNormal = function (toState, normalState, primaryKeys) {
            for (var i = 0; i < primaryKeys.length; i++) {
                var key = primaryKeys[i];
                if (toState[key] != null && !(key in normalState)) {
                    normalState[key] = this[key];
                }
            }
        };
        Element.prototype.hasState = function () {
            return this.currentStates.length > 0;
        };
        Element.prototype.getState = function (name) {
            return this.states[name];
        };
        Element.prototype.ensureState = function (name) {
            var states = this.states;
            if (!states[name]) {
                states[name] = {};
            }
            return states[name];
        };
        Element.prototype.clearStates = function (noAnimation) {
            this.useState(PRESERVED_NORMAL_STATE, false, noAnimation);
        };
        Element.prototype.useState = function (stateName, keepCurrentStates, noAnimation, forceUseHoverLayer) {
            var toNormalState = stateName === PRESERVED_NORMAL_STATE;
            var hasStates = this.hasState();
            if (!hasStates && toNormalState) {
                return;
            }
            var currentStates = this.currentStates;
            var animationCfg = this.stateTransition;
            if (indexOf(currentStates, stateName) >= 0 && (keepCurrentStates || currentStates.length === 1)) {
                return;
            }
            var state;
            if (this.stateProxy && !toNormalState) {
                state = this.stateProxy(stateName);
            }
            if (!state) {
                state = (this.states && this.states[stateName]);
            }
            if (!state && !toNormalState) {
                logError("State " + stateName + " not exists.");
                return;
            }
            if (!toNormalState) {
                this.saveCurrentToNormalState(state);
            }
            var useHoverLayer = !!((state && state.hoverLayer) || forceUseHoverLayer);
            if (useHoverLayer) {
                this._toggleHoverLayerFlag(true);
            }
            this._applyStateObj(stateName, state, this._normalState, keepCurrentStates, !noAnimation && !this.__inHover && animationCfg && animationCfg.duration > 0, animationCfg);
            var textContent = this._textContent;
            var textGuide = this._textGuide;
            if (textContent) {
                textContent.useState(stateName, keepCurrentStates, noAnimation, useHoverLayer);
            }
            if (textGuide) {
                textGuide.useState(stateName, keepCurrentStates, noAnimation, useHoverLayer);
            }
            if (toNormalState) {
                this.currentStates = [];
                this._normalState = {};
            }
            else {
                if (!keepCurrentStates) {
                    this.currentStates = [stateName];
                }
                else {
                    this.currentStates.push(stateName);
                }
            }
            this._updateAnimationTargets();
            this.markRedraw();
            if (!useHoverLayer && this.__inHover) {
                this._toggleHoverLayerFlag(false);
                this.__dirty &= ~REDRAW_BIT;
            }
            return state;
        };
        Element.prototype.useStates = function (states, noAnimation, forceUseHoverLayer) {
            if (!states.length) {
                this.clearStates();
            }
            else {
                var stateObjects = [];
                var currentStates = this.currentStates;
                var len = states.length;
                var notChange = len === currentStates.length;
                if (notChange) {
                    for (var i = 0; i < len; i++) {
                        if (states[i] !== currentStates[i]) {
                            notChange = false;
                            break;
                        }
                    }
                }
                if (notChange) {
                    return;
                }
                for (var i = 0; i < len; i++) {
                    var stateName = states[i];
                    var stateObj = void 0;
                    if (this.stateProxy) {
                        stateObj = this.stateProxy(stateName, states);
                    }
                    if (!stateObj) {
                        stateObj = this.states[stateName];
                    }
                    if (stateObj) {
                        stateObjects.push(stateObj);
                    }
                }
                var lastStateObj = stateObjects[len - 1];
                var useHoverLayer = !!((lastStateObj && lastStateObj.hoverLayer) || forceUseHoverLayer);
                if (useHoverLayer) {
                    this._toggleHoverLayerFlag(true);
                }
                var mergedState = this._mergeStates(stateObjects);
                var animationCfg = this.stateTransition;
                this.saveCurrentToNormalState(mergedState);
                this._applyStateObj(states.join(','), mergedState, this._normalState, false, !noAnimation && !this.__inHover && animationCfg && animationCfg.duration > 0, animationCfg);
                var textContent = this._textContent;
                var textGuide = this._textGuide;
                if (textContent) {
                    textContent.useStates(states, noAnimation, useHoverLayer);
                }
                if (textGuide) {
                    textGuide.useStates(states, noAnimation, useHoverLayer);
                }
                this._updateAnimationTargets();
                this.currentStates = states.slice();
                this.markRedraw();
                if (!useHoverLayer && this.__inHover) {
                    this._toggleHoverLayerFlag(false);
                    this.__dirty &= ~REDRAW_BIT;
                }
            }
        };
        Element.prototype._updateAnimationTargets = function () {
            for (var i = 0; i < this.animators.length; i++) {
                var animator = this.animators[i];
                if (animator.targetName) {
                    animator.changeTarget(this[animator.targetName]);
                }
            }
        };
        Element.prototype.removeState = function (state) {
            var idx = indexOf(this.currentStates, state);
            if (idx >= 0) {
                var currentStates = this.currentStates.slice();
                currentStates.splice(idx, 1);
                this.useStates(currentStates);
            }
        };
        Element.prototype.replaceState = function (oldState, newState, forceAdd) {
            var currentStates = this.currentStates.slice();
            var idx = indexOf(currentStates, oldState);
            var newStateExists = indexOf(currentStates, newState) >= 0;
            if (idx >= 0) {
                if (!newStateExists) {
                    currentStates[idx] = newState;
                }
                else {
                    currentStates.splice(idx, 1);
                }
            }
            else if (forceAdd && !newStateExists) {
                currentStates.push(newState);
            }
            this.useStates(currentStates);
        };
        Element.prototype.toggleState = function (state, enable) {
            if (enable) {
                this.useState(state, true);
            }
            else {
                this.removeState(state);
            }
        };
        Element.prototype._mergeStates = function (states) {
            var mergedState = {};
            var mergedTextConfig;
            for (var i = 0; i < states.length; i++) {
                var state = states[i];
                extend(mergedState, state);
                if (state.textConfig) {
                    mergedTextConfig = mergedTextConfig || {};
                    extend(mergedTextConfig, state.textConfig);
                }
            }
            if (mergedTextConfig) {
                mergedState.textConfig = mergedTextConfig;
            }
            return mergedState;
        };
        Element.prototype._applyStateObj = function (stateName, state, normalState, keepCurrentStates, transition, animationCfg) {
            var needsRestoreToNormal = !(state && keepCurrentStates);
            if (state && state.textConfig) {
                this.textConfig = extend({}, keepCurrentStates ? this.textConfig : normalState.textConfig);
                extend(this.textConfig, state.textConfig);
            }
            else if (needsRestoreToNormal) {
                if (normalState.textConfig) {
                    this.textConfig = normalState.textConfig;
                }
            }
            var transitionTarget = {};
            var hasTransition = false;
            for (var i = 0; i < PRIMARY_STATES_KEYS.length; i++) {
                var key = PRIMARY_STATES_KEYS[i];
                var propNeedsTransition = transition && DEFAULT_ANIMATABLE_MAP[key];
                if (state && state[key] != null) {
                    if (propNeedsTransition) {
                        hasTransition = true;
                        transitionTarget[key] = state[key];
                    }
                    else {
                        this[key] = state[key];
                    }
                }
                else if (needsRestoreToNormal) {
                    if (normalState[key] != null) {
                        if (propNeedsTransition) {
                            hasTransition = true;
                            transitionTarget[key] = normalState[key];
                        }
                        else {
                            this[key] = normalState[key];
                        }
                    }
                }
            }
            if (!transition) {
                for (var i = 0; i < this.animators.length; i++) {
                    var animator = this.animators[i];
                    var targetName = animator.targetName;
                    if (!animator.getLoop()) {
                        animator.__changeFinalValue(targetName
                            ? (state || normalState)[targetName]
                            : (state || normalState));
                    }
                }
            }
            if (hasTransition) {
                this._transitionState(stateName, transitionTarget, animationCfg);
            }
        };
        Element.prototype._attachComponent = function (componentEl) {
            if (componentEl.__zr && !componentEl.__hostTarget) {
                if ("development" !== 'production') {
                    throw new Error('Text element has been added to zrender.');
                }
                return;
            }
            if (componentEl === this) {
                if ("development" !== 'production') {
                    throw new Error('Recursive component attachment.');
                }
                return;
            }
            var zr = this.__zr;
            if (zr) {
                componentEl.addSelfToZr(zr);
            }
            componentEl.__zr = zr;
            componentEl.__hostTarget = this;
        };
        Element.prototype._detachComponent = function (componentEl) {
            if (componentEl.__zr) {
                componentEl.removeSelfFromZr(componentEl.__zr);
            }
            componentEl.__zr = null;
            componentEl.__hostTarget = null;
        };
        Element.prototype.getClipPath = function () {
            return this._clipPath;
        };
        Element.prototype.setClipPath = function (clipPath) {
            if (this._clipPath && this._clipPath !== clipPath) {
                this.removeClipPath();
            }
            this._attachComponent(clipPath);
            this._clipPath = clipPath;
            this.markRedraw();
        };
        Element.prototype.removeClipPath = function () {
            var clipPath = this._clipPath;
            if (clipPath) {
                this._detachComponent(clipPath);
                this._clipPath = null;
                this.markRedraw();
            }
        };
        Element.prototype.getTextContent = function () {
            return this._textContent;
        };
        Element.prototype.setTextContent = function (textEl) {
            var previousTextContent = this._textContent;
            if (previousTextContent === textEl) {
                return;
            }
            if (previousTextContent && previousTextContent !== textEl) {
                this.removeTextContent();
            }
            if ("development" !== 'production') {
                if (textEl.__zr && !textEl.__hostTarget) {
                    throw new Error('Text element has been added to zrender.');
                }
            }
            textEl.innerTransformable = new Transformable();
            this._attachComponent(textEl);
            this._textContent = textEl;
            this.markRedraw();
        };
        Element.prototype.setTextConfig = function (cfg) {
            if (!this.textConfig) {
                this.textConfig = {};
            }
            extend(this.textConfig, cfg);
            this.markRedraw();
        };
        Element.prototype.removeTextConfig = function () {
            this.textConfig = null;
            this.markRedraw();
        };
        Element.prototype.removeTextContent = function () {
            var textEl = this._textContent;
            if (textEl) {
                textEl.innerTransformable = null;
                this._detachComponent(textEl);
                this._textContent = null;
                this._innerTextDefaultStyle = null;
                this.markRedraw();
            }
        };
        Element.prototype.getTextGuideLine = function () {
            return this._textGuide;
        };
        Element.prototype.setTextGuideLine = function (guideLine) {
            if (this._textGuide && this._textGuide !== guideLine) {
                this.removeTextGuideLine();
            }
            this._attachComponent(guideLine);
            this._textGuide = guideLine;
            this.markRedraw();
        };
        Element.prototype.removeTextGuideLine = function () {
            var textGuide = this._textGuide;
            if (textGuide) {
                this._detachComponent(textGuide);
                this._textGuide = null;
                this.markRedraw();
            }
        };
        Element.prototype.markRedraw = function () {
            this.__dirty |= REDRAW_BIT;
            var zr = this.__zr;
            if (zr) {
                if (this.__inHover) {
                    zr.refreshHover();
                }
                else {
                    zr.refresh();
                }
            }
            if (this.__hostTarget) {
                this.__hostTarget.markRedraw();
            }
        };
        Element.prototype.dirty = function () {
            this.markRedraw();
        };
        Element.prototype._toggleHoverLayerFlag = function (inHover) {
            this.__inHover = inHover;
            var textContent = this._textContent;
            var textGuide = this._textGuide;
            if (textContent) {
                textContent.__inHover = inHover;
            }
            if (textGuide) {
                textGuide.__inHover = inHover;
            }
        };
        Element.prototype.addSelfToZr = function (zr) {
            if (this.__zr === zr) {
                return;
            }
            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);
            }
            if (this._textContent) {
                this._textContent.addSelfToZr(zr);
            }
            if (this._textGuide) {
                this._textGuide.addSelfToZr(zr);
            }
        };
        Element.prototype.removeSelfFromZr = function (zr) {
            if (!this.__zr) {
                return;
            }
            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);
            }
            if (this._textContent) {
                this._textContent.removeSelfFromZr(zr);
            }
            if (this._textGuide) {
                this._textGuide.removeSelfFromZr(zr);
            }
        };
        Element.prototype.animate = function (key, loop, allowDiscreteAnimation) {
            var target = key ? this[key] : this;
            if ("development" !== 'production') {
                if (!target) {
                    logError('Property "'
                        + key
                        + '" is not existed in element '
                        + this.id);
                    return;
                }
            }
            var animator = new Animator(target, loop, allowDiscreteAnimation);
            key && (animator.targetName = key);
            this.addAnimator(animator, key);
            return animator;
        };
        Element.prototype.addAnimator = function (animator, key) {
            var zr = this.__zr;
            var el = this;
            animator.during(function () {
                el.updateDuringAnimation(key);
            }).done(function () {
                var animators = el.animators;
                var idx = indexOf(animators, animator);
                if (idx >= 0) {
                    animators.splice(idx, 1);
                }
            });
            this.animators.push(animator);
            if (zr) {
                zr.animation.addAnimator(animator);
            }
            zr && zr.wakeUp();
        };
        Element.prototype.updateDuringAnimation = function (key) {
            this.markRedraw();
        };
        Element.prototype.stopAnimation = function (scope, forwardToLast) {
            var animators = this.animators;
            var len = animators.length;
            var leftAnimators = [];
            for (var i = 0; i < len; i++) {
                var animator = animators[i];
                if (!scope || scope === animator.scope) {
                    animator.stop(forwardToLast);
                }
                else {
                    leftAnimators.push(animator);
                }
            }
            this.animators = leftAnimators;
            return this;
        };
        Element.prototype.animateTo = function (target, cfg, animationProps) {
            animateTo(this, target, cfg, animationProps);
        };
        Element.prototype.animateFrom = function (target, cfg, animationProps) {
            animateTo(this, target, cfg, animationProps, true);
        };
        Element.prototype._transitionState = function (stateName, target, cfg, animationProps) {
            var animators = animateTo(this, target, cfg, animationProps);
            for (var i = 0; i < animators.length; i++) {
                animators[i].__fromStateTransition = stateName;
            }
        };
        Element.prototype.getBoundingRect = function () {
            return null;
        };
        Element.prototype.getPaintRect = function () {
            return null;
        };
        Element.initDefaultProps = (function () {
            var elProto = Element.prototype;
            elProto.type = 'element';
            elProto.name = '';
            elProto.ignore =
                elProto.silent =
                    elProto.isGroup =
                        elProto.draggable =
                            elProto.dragging =
                                elProto.ignoreClip =
                                    elProto.__inHover = false;
            elProto.__dirty = REDRAW_BIT;
            var logs = {};
            function logDeprecatedError(key, xKey, yKey) {
                if (!logs[key + xKey + yKey]) {
                    console.warn("DEPRECATED: '" + key + "' has been deprecated. use '" + xKey + "', '" + yKey + "' instead");
                    logs[key + xKey + yKey] = true;
                }
            }
            function createLegacyProperty(key, privateKey, xKey, yKey) {
                Object.defineProperty(elProto, key, {
                    get: function () {
                        if ("development" !== 'production') {
                            logDeprecatedError(key, xKey, yKey);
                        }
                        if (!this[privateKey]) {
                            var pos = this[privateKey] = [];
                            enhanceArray(this, pos);
                        }
                        return this[privateKey];
                    },
                    set: function (pos) {
                        if ("development" !== 'production') {
                            logDeprecatedError(key, xKey, yKey);
                        }
                        this[xKey] = pos[0];
                        this[yKey] = pos[1];
                        this[privateKey] = pos;
                        enhanceArray(this, pos);
                    }
                });
                function enhanceArray(self, pos) {
                    Object.defineProperty(pos, 0, {
                        get: function () {
                            return self[xKey];
                        },
                        set: function (val) {
                            self[xKey] = val;
                        }
                    });
                    Object.defineProperty(pos, 1, {
                        get: function () {
                            return self[yKey];
                        },
                        set: function (val) {
                            self[yKey] = val;
                        }
                    });
                }
            }
            if (Object.defineProperty) {
                createLegacyProperty('position', '_legacyPos', 'x', 'y');
                createLegacyProperty('scale', '_legacyScale', 'scaleX', 'scaleY');
                createLegacyProperty('origin', '_legacyOrigin', 'originX', 'originY');
            }
        })();
        return Element;
    }());
    mixin(Element, Eventful);
    mixin(Element, Transformable);
    function animateTo(animatable, target, cfg, animationProps, reverse) {
        cfg = cfg || {};
        var animators = [];
        animateToShallow(animatable, '', animatable, target, cfg, animationProps, animators, reverse);
        var finishCount = animators.length;
        var doneHappened = false;
        var cfgDone = cfg.done;
        var cfgAborted = cfg.aborted;
        var doneCb = function () {
            doneHappened = true;
            finishCount--;
            if (finishCount <= 0) {
                doneHappened
                    ? (cfgDone && cfgDone())
                    : (cfgAborted && cfgAborted());
            }
        };
        var abortedCb = function () {
            finishCount--;
            if (finishCount <= 0) {
                doneHappened
                    ? (cfgDone && cfgDone())
                    : (cfgAborted && cfgAborted());
            }
        };
        if (!finishCount) {
            cfgDone && cfgDone();
        }
        if (animators.length > 0 && cfg.during) {
            animators[0].during(function (target, percent) {
                cfg.during(percent);
            });
        }
        for (var i = 0; i < animators.length; i++) {
            var animator = animators[i];
            if (doneCb) {
                animator.done(doneCb);
            }
            if (abortedCb) {
                animator.aborted(abortedCb);
            }
            if (cfg.force) {
                animator.duration(cfg.duration);
            }
            animator.start(cfg.easing);
        }
        return animators;
    }
    function copyArrShallow(source, target, len) {
        for (var i = 0; i < len; i++) {
            source[i] = target[i];
        }
    }
    function is2DArray(value) {
        return isArrayLike(value[0]);
    }
    function copyValue(target, source, key) {
        if (isArrayLike(source[key])) {
            if (!isArrayLike(target[key])) {
                target[key] = [];
            }
            if (isTypedArray(source[key])) {
                var len = source[key].length;
                if (target[key].length !== len) {
                    target[key] = new (source[key].constructor)(len);
                    copyArrShallow(target[key], source[key], len);
                }
            }
            else {
                var sourceArr = source[key];
                var targetArr = target[key];
                var len0 = sourceArr.length;
                if (is2DArray(sourceArr)) {
                    var len1 = sourceArr[0].length;
                    for (var i = 0; i < len0; i++) {
                        if (!targetArr[i]) {
                            targetArr[i] = Array.prototype.slice.call(sourceArr[i]);
                        }
                        else {
                            copyArrShallow(targetArr[i], sourceArr[i], len1);
                        }
                    }
                }
                else {
                    copyArrShallow(targetArr, sourceArr, len0);
                }
                targetArr.length = sourceArr.length;
            }
        }
        else {
            target[key] = source[key];
        }
    }
    function isValueSame(val1, val2) {
        return val1 === val2
            || isArrayLike(val1) && isArrayLike(val2) && is1DArraySame(val1, val2);
    }
    function is1DArraySame(arr0, arr1) {
        var len = arr0.length;
        if (len !== arr1.length) {
            return false;
        }
        for (var i = 0; i < len; i++) {
            if (arr0[i] !== arr1[i]) {
                return false;
            }
        }
        return true;
    }
    function animateToShallow(animatable, topKey, animateObj, target, cfg, animationProps, animators, reverse) {
        var targetKeys = keys(target);
        var duration = cfg.duration;
        var delay = cfg.delay;
        var additive = cfg.additive;
        var setToFinal = cfg.setToFinal;
        var animateAll = !isObject(animationProps);
        var existsAnimators = animatable.animators;
        var animationKeys = [];
        for (var k = 0; k < targetKeys.length; k++) {
            var innerKey = targetKeys[k];
            var targetVal = target[innerKey];
            if (targetVal != null && animateObj[innerKey] != null
                && (animateAll || animationProps[innerKey])) {
                if (isObject(targetVal)
                    && !isArrayLike(targetVal)
                    && !isGradientObject(targetVal)) {
                    if (topKey) {
                        if (!reverse) {
                            animateObj[innerKey] = targetVal;
                            animatable.updateDuringAnimation(topKey);
                        }
                        continue;
                    }
                    animateToShallow(animatable, innerKey, animateObj[innerKey], targetVal, cfg, animationProps && animationProps[innerKey], animators, reverse);
                }
                else {
                    animationKeys.push(innerKey);
                }
            }
            else if (!reverse) {
                animateObj[innerKey] = targetVal;
                animatable.updateDuringAnimation(topKey);
                animationKeys.push(innerKey);
            }
        }
        var keyLen = animationKeys.length;
        if (!additive && keyLen) {
            for (var i = 0; i < existsAnimators.length; i++) {
                var animator = existsAnimators[i];
                if (animator.targetName === topKey) {
                    var allAborted = animator.stopTracks(animationKeys);
                    if (allAborted) {
                        var idx = indexOf(existsAnimators, animator);
                        existsAnimators.splice(idx, 1);
                    }
                }
            }
        }
        if (!cfg.force) {
            animationKeys = filter(animationKeys, function (key) { return !isValueSame(target[key], animateObj[key]); });
            keyLen = animationKeys.length;
        }
        if (keyLen > 0
            || (cfg.force && !animators.length)) {
            var revertedSource = void 0;
            var reversedTarget = void 0;
            var sourceClone = void 0;
            if (reverse) {
                reversedTarget = {};
                if (setToFinal) {
                    revertedSource = {};
                }
                for (var i = 0; i < keyLen; i++) {
                    var innerKey = animationKeys[i];
                    reversedTarget[innerKey] = animateObj[innerKey];
                    if (setToFinal) {
                        revertedSource[innerKey] = target[innerKey];
                    }
                    else {
                        animateObj[innerKey] = target[innerKey];
                    }
                }
            }
            else if (setToFinal) {
                sourceClone = {};
                for (var i = 0; i < keyLen; i++) {
                    var innerKey = animationKeys[i];
                    sourceClone[innerKey] = cloneValue(animateObj[innerKey]);
                    copyValue(animateObj, target, innerKey);
                }
            }
            var animator = new Animator(animateObj, false, false, additive ? filter(existsAnimators, function (animator) { return animator.targetName === topKey; }) : null);
            animator.targetName = topKey;
            if (cfg.scope) {
                animator.scope = cfg.scope;
            }
            if (setToFinal && revertedSource) {
                animator.whenWithKeys(0, revertedSource, animationKeys);
            }
            if (sourceClone) {
                animator.whenWithKeys(0, sourceClone, animationKeys);
            }
            animator.whenWithKeys(duration == null ? 500 : duration, reverse ? reversedTarget : target, animationKeys).delay(delay || 0);
            animatable.addAnimator(animator, topKey);
            animators.push(animator);
        }
    }

    var Group = (function (_super) {
        __extends(Group, _super);
        function Group(opts) {
            var _this = _super.call(this) || this;
            _this.isGroup = true;
            _this._children = [];
            _this.attr(opts);
            return _this;
        }
        Group.prototype.childrenRef = function () {
            return this._children;
        };
        Group.prototype.children = function () {
            return this._children.slice();
        };
        Group.prototype.childAt = function (idx) {
            return this._children[idx];
        };
        Group.prototype.childOfName = function (name) {
            var children = this._children;
            for (var i = 0; i < children.length; i++) {
                if (children[i].name === name) {
                    return children[i];
                }
            }
        };
        Group.prototype.childCount = function () {
            return this._children.length;
        };
        Group.prototype.add = function (child) {
            if (child) {
                if (child !== this && child.parent !== this) {
                    this._children.push(child);
                    this._doAdd(child);
                }
                if ("development" !== 'production') {
                    if (child.__hostTarget) {
                        throw 'This elemenet has been used as an attachment';
                    }
                }
            }
            return this;
        };
        Group.prototype.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;
        };
        Group.prototype.replace = function (oldChild, newChild) {
            var idx = indexOf(this._children, oldChild);
            if (idx >= 0) {
                this.replaceAt(newChild, idx);
            }
            return this;
        };
        Group.prototype.replaceAt = function (child, index) {
            var children = this._children;
            var old = children[index];
            if (child && child !== this && child.parent !== this && child !== old) {
                children[index] = child;
                old.parent = null;
                var zr = this.__zr;
                if (zr) {
                    old.removeSelfFromZr(zr);
                }
                this._doAdd(child);
            }
            return this;
        };
        Group.prototype._doAdd = function (child) {
            if (child.parent) {
                child.parent.remove(child);
            }
            child.parent = this;
            var zr = this.__zr;
            if (zr && zr !== child.__zr) {
                child.addSelfToZr(zr);
            }
            zr && zr.refresh();
        };
        Group.prototype.remove = function (child) {
            var zr = this.__zr;
            var children = this._children;
            var idx = indexOf(children, child);
            if (idx < 0) {
                return this;
            }
            children.splice(idx, 1);
            child.parent = null;
            if (zr) {
                child.removeSelfFromZr(zr);
            }
            zr && zr.refresh();
            return this;
        };
        Group.prototype.removeAll = function () {
            var children = this._children;
            var zr = this.__zr;
            for (var i = 0; i < children.length; i++) {
                var child = children[i];
                if (zr) {
                    child.removeSelfFromZr(zr);
                }
                child.parent = null;
            }
            children.length = 0;
            return this;
        };
        Group.prototype.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;
        };
        Group.prototype.traverse = function (cb, context) {
            for (var i = 0; i < this._children.length; i++) {
                var child = this._children[i];
                var stopped = cb.call(context, child);
                if (child.isGroup && !stopped) {
                    child.traverse(cb, context);
                }
            }
            return this;
        };
        Group.prototype.addSelfToZr = function (zr) {
            _super.prototype.addSelfToZr.call(this, zr);
            for (var i = 0; i < this._children.length; i++) {
                var child = this._children[i];
                child.addSelfToZr(zr);
            }
        };
        Group.prototype.removeSelfFromZr = function (zr) {
            _super.prototype.removeSelfFromZr.call(this, zr);
            for (var i = 0; i < this._children.length; i++) {
                var child = this._children[i];
                child.removeSelfFromZr(zr);
            }
        };
        Group.prototype.getBoundingRect = function (includeChildren) {
            var tmpRect = new BoundingRect(0, 0, 0, 0);
            var children = includeChildren || this._children;
            var tmpMat = [];
            var rect = null;
            for (var i = 0; i < children.length; i++) {
                var child = children[i];
                if (child.ignore || child.invisible) {
                    continue;
                }
                var childRect = child.getBoundingRect();
                var transform = child.getLocalTransform(tmpMat);
                if (transform) {
                    BoundingRect.applyTransform(tmpRect, childRect, transform);
                    rect = rect || tmpRect.clone();
                    rect.union(tmpRect);
                }
                else {
                    rect = rect || childRect.clone();
                    rect.union(childRect);
                }
            }
            return rect || tmpRect;
        };
        return Group;
    }(Element));
    Group.prototype.type = 'group';

    /*!
    * 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 painterCtors = {};
    var instances = {};
    function delInstance(id) {
        delete instances[id];
    }
    function isDarkMode(backgroundColor) {
        if (!backgroundColor) {
            return false;
        }
        if (typeof backgroundColor === 'string') {
            return lum(backgroundColor, 1) < DARK_MODE_THRESHOLD;
        }
        else if (backgroundColor.colorStops) {
            var colorStops = backgroundColor.colorStops;
            var totalLum = 0;
            var len = colorStops.length;
            for (var i = 0; i < len; i++) {
                totalLum += lum(colorStops[i].color, 1);
            }
            totalLum /= len;
            return totalLum < DARK_MODE_THRESHOLD;
        }
        return false;
    }
    var ZRender = (function () {
        function ZRender(id, dom, opts) {
            var _this = this;
            this._sleepAfterStill = 10;
            this._stillFrameAccum = 0;
            this._needsRefresh = true;
            this._needsRefreshHover = true;
            this._darkMode = false;
            opts = opts || {};
            this.dom = dom;
            this.id = id;
            var storage = new Storage();
            var rendererType = opts.renderer || 'canvas';
            if (!painterCtors[rendererType]) {
                rendererType = keys(painterCtors)[0];
            }
            if ("development" !== 'production') {
                if (!painterCtors[rendererType]) {
                    throw new Error("Renderer '" + rendererType + "' is not imported. Please import it first.");
                }
            }
            opts.useDirtyRect = opts.useDirtyRect == null
                ? false
                : opts.useDirtyRect;
            var painter = new painterCtors[rendererType](dom, storage, opts, id);
            var ssrMode = opts.ssr || painter.ssrOnly;
            this.storage = storage;
            this.painter = painter;
            var handerProxy = (!env.node && !env.worker && !ssrMode)
                ? new HandlerDomProxy(painter.getViewportRoot(), painter.root)
                : null;
            var useCoarsePointer = opts.useCoarsePointer;
            var usePointerSize = (useCoarsePointer == null || useCoarsePointer === 'auto')
                ? env.touchEventsSupported
                : !!useCoarsePointer;
            var defaultPointerSize = 44;
            var pointerSize;
            if (usePointerSize) {
                pointerSize = retrieve2(opts.pointerSize, defaultPointerSize);
            }
            this.handler = new Handler(storage, painter, handerProxy, painter.root, pointerSize);
            this.animation = new Animation({
                stage: {
                    update: ssrMode ? null : function () { return _this._flush(true); }
                }
            });
            if (!ssrMode) {
                this.animation.start();
            }
        }
        ZRender.prototype.add = function (el) {
            if (!el) {
                return;
            }
            this.storage.addRoot(el);
            el.addSelfToZr(this);
            this.refresh();
        };
        ZRender.prototype.remove = function (el) {
            if (!el) {
                return;
            }
            this.storage.delRoot(el);
            el.removeSelfFromZr(this);
            this.refresh();
        };
        ZRender.prototype.configLayer = function (zLevel, config) {
            if (this.painter.configLayer) {
                this.painter.configLayer(zLevel, config);
            }
            this.refresh();
        };
        ZRender.prototype.setBackgroundColor = function (backgroundColor) {
            if (this.painter.setBackgroundColor) {
                this.painter.setBackgroundColor(backgroundColor);
            }
            this.refresh();
            this._backgroundColor = backgroundColor;
            this._darkMode = isDarkMode(backgroundColor);
        };
        ZRender.prototype.getBackgroundColor = function () {
            return this._backgroundColor;
        };
        ZRender.prototype.setDarkMode = function (darkMode) {
            this._darkMode = darkMode;
        };
        ZRender.prototype.isDarkMode = function () {
            return this._darkMode;
        };
        ZRender.prototype.refreshImmediately = function (fromInside) {
            if (!fromInside) {
                this.animation.update(true);
            }
            this._needsRefresh = false;
            this.painter.refresh();
            this._needsRefresh = false;
        };
        ZRender.prototype.refresh = function () {
            this._needsRefresh = true;
            this.animation.start();
        };
        ZRender.prototype.flush = function () {
            this._flush(false);
        };
        ZRender.prototype._flush = function (fromInside) {
            var triggerRendered;
            var start = getTime();
            if (this._needsRefresh) {
                triggerRendered = true;
                this.refreshImmediately(fromInside);
            }
            if (this._needsRefreshHover) {
                triggerRendered = true;
                this.refreshHoverImmediately();
            }
            var end = getTime();
            if (triggerRendered) {
                this._stillFrameAccum = 0;
                this.trigger('rendered', {
                    elapsedTime: end - start
                });
            }
            else if (this._sleepAfterStill > 0) {
                this._stillFrameAccum++;
                if (this._stillFrameAccum > this._sleepAfterStill) {
                    this.animation.stop();
                }
            }
        };
        ZRender.prototype.setSleepAfterStill = function (stillFramesCount) {
            this._sleepAfterStill = stillFramesCount;
        };
        ZRender.prototype.wakeUp = function () {
            this.animation.start();
            this._stillFrameAccum = 0;
        };
        ZRender.prototype.refreshHover = function () {
            this._needsRefreshHover = true;
        };
        ZRender.prototype.refreshHoverImmediately = function () {
            this._needsRefreshHover = false;
            if (this.painter.refreshHover && this.painter.getType() === 'canvas') {
                this.painter.refreshHover();
            }
        };
        ZRender.prototype.resize = function (opts) {
            opts = opts || {};
            this.painter.resize(opts.width, opts.height);
            this.handler.resize();
        };
        ZRender.prototype.clearAnimation = function () {
            this.animation.clear();
        };
        ZRender.prototype.getWidth = function () {
            return this.painter.getWidth();
        };
        ZRender.prototype.getHeight = function () {
            return this.painter.getHeight();
        };
        ZRender.prototype.setCursorStyle = function (cursorStyle) {
            this.handler.setCursorStyle(cursorStyle);
        };
        ZRender.prototype.findHover = function (x, y) {
            return this.handler.findHover(x, y);
        };
        ZRender.prototype.on = function (eventName, eventHandler, context) {
            this.handler.on(eventName, eventHandler, context);
            return this;
        };
        ZRender.prototype.off = function (eventName, eventHandler) {
            this.handler.off(eventName, eventHandler);
        };
        ZRender.prototype.trigger = function (eventName, event) {
            this.handler.trigger(eventName, event);
        };
        ZRender.prototype.clear = function () {
            var roots = this.storage.getRoots();
            for (var i = 0; i < roots.length; i++) {
                if (roots[i] instanceof Group) {
                    roots[i].removeSelfFromZr(this);
                }
            }
            this.storage.delAllRoots();
            this.painter.clear();
        };
        ZRender.prototype.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);
        };
        return ZRender;
    }());
    function init(dom, opts) {
        var zr = new ZRender(guid(), dom, opts);
        instances[zr.id] = zr;
        return zr;
    }
    function dispose(zr) {
        zr.dispose();
    }
    function disposeAll() {
        for (var key in instances) {
            if (instances.hasOwnProperty(key)) {
                instances[key].dispose();
            }
        }
        instances = {};
    }
    function getInstance(id) {
        return instances[id];
    }
    function registerPainter(name, Ctor) {
        painterCtors[name] = Ctor;
    }
    var version = '5.4.1';

    var zrender = /*#__PURE__*/Object.freeze({
        __proto__: null,
        init: init,
        dispose: dispose,
        disposeAll: disposeAll,
        getInstance: getInstance,
        registerPainter: registerPainter,
        version: version
    });

    var RADIAN_EPSILON = 1e-4; // Although chrome already enlarge this number to 100 for `toFixed`, but
    // we sill follow the spec for compatibility.

    var ROUND_SUPPORTED_PRECISION_MAX = 20;

    function _trim(str) {
      return str.replace(/^\s+|\s+$/g, '');
    }
    /**
     * Linear mapping a value from domain to range
     * @param  val
     * @param  domain Domain extent domain[0] can be bigger than domain[1]
     * @param  range  Range extent range[0] can be bigger than range[1]
     * @param  clamp Default to be false
     */


    function linearMap(val, domain, range, clamp) {
      var d0 = domain[0];
      var d1 = domain[1];
      var r0 = range[0];
      var r1 = range[1];
      var subDomain = d1 - d0;
      var subRange = r1 - r0;

      if (subDomain === 0) {
        return subRange === 0 ? r0 : (r0 + r1) / 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 <= d0) {
            return r0;
          } else if (val >= d1) {
            return r1;
          }
        } else {
          if (val >= d0) {
            return r0;
          } else if (val <= d1) {
            return r1;
          }
        }
      } else {
        if (val === d0) {
          return r0;
        }

        if (val === d1) {
          return r1;
        }
      }

      return (val - d0) / subDomain * subRange + r0;
    }
    /**
     * Convert a percent string to absolute number.
     * Returns NaN if percent is not a valid string or 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 (isString(percent)) {
        if (_trim(percent).match(/%$/)) {
          return parseFloat(percent) / 100 * all;
        }

        return parseFloat(percent);
      }

      return percent == null ? NaN : +percent;
    }
    function round(x, precision, returnStr) {
      if (precision == null) {
        precision = 10;
      } // Avoid range error


      precision = Math.min(Math.max(0, precision), ROUND_SUPPORTED_PRECISION_MAX); // PENDING: 1.005.toFixed(2) is '1.00' rather than '1.01'

      x = (+x).toFixed(precision);
      return returnStr ? x : +x;
    }
    /**
     * Inplacd asc sort arr.
     * The input arr will be modified.
     */

    function asc(arr) {
      arr.sort(function (a, b) {
        return a - b;
      });
      return arr;
    }
    /**
     * Get precision.
     */

    function getPrecision(val) {
      val = +val;

      if (isNaN(val)) {
        return 0;
      } // It is much faster than methods converting number to string as follows
      //      let tmp = val.toString();
      //      return tmp.length - 1 - tmp.indexOf('.');
      // especially when precision is low
      // Notice:
      // (1) If the loop count is over about 20, it is slower than `getPrecisionSafe`.
      //     (see https://jsbench.me/2vkpcekkvw/1)
      // (2) If the val is less than for example 1e-15, the result may be incorrect.
      //     (see test/ut/spec/util/number.test.ts `getPrecision_equal_random`)


      if (val > 1e-14) {
        var e = 1;

        for (var i = 0; i < 15; i++, e *= 10) {
          if (Math.round(val * e) / e === val) {
            return i;
          }
        }
      }

      return getPrecisionSafe(val);
    }
    /**
     * Get precision with slow but safe method
     */

    function getPrecisionSafe(val) {
      // toLowerCase for: '3.4E-12'
      var str = val.toString().toLowerCase(); // Consider scientific notation: '3.4e-12' '3.4e+12'

      var eIndex = str.indexOf('e');
      var exp = eIndex > 0 ? +str.slice(eIndex + 1) : 0;
      var significandPartLen = eIndex > 0 ? eIndex : str.length;
      var dotIndex = str.indexOf('.');
      var decimalPartLen = dotIndex < 0 ? 0 : significandPartLen - 1 - dotIndex;
      return Math.max(0, decimalPartLen - exp);
    }
    /**
     * Minimal dicernible data precisioin according to a single pixel.
     */

    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 remainder method is used.
     * https://en.wikipedia.org/wiki/Largest_remainder_method
     *
     * @param valueList a list of all data
     * @param idx index of the data to be processed in valueList
     * @param precision integer number showing digits of precision
     * @return percent ranging from 0 to 100
     */

    function getPercentWithPrecision(valueList, idx, precision) {
      if (!valueList[idx]) {
        return 0;
      }

      var seats = getPercentSeats(valueList, precision);
      return seats[idx] || 0;
    }
    /**
     * Get a data of given precision, assuring the sum of percentages
     * in valueList is 1.
     * The largest remainder method is used.
     * https://en.wikipedia.org/wiki/Largest_remainder_method
     *
     * @param valueList a list of all data
     * @param precision integer number showing digits of precision
     * @return {Array<number>}
     */

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

      if (sum === 0) {
        return [];
      }

      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 map(seats, function (seat) {
        return seat / digits;
      });
    }
    /**
     * Solve the floating point adding problem like 0.1 + 0.2 === 0.30000000000000004
     * See <http://0.30000000000000004.com/>
     */

    function addSafe(val0, val1) {
      var maxPrecision = Math.max(getPrecision(val0), getPrecision(val1)); // const multiplier = Math.pow(10, maxPrecision);
      // return (Math.round(val0 * multiplier) + Math.round(val1 * multiplier)) / multiplier;

      var sum = val0 + val1; // // PENDING: support more?

      return maxPrecision > ROUND_SUPPORTED_PRECISION_MAX ? sum : round(sum, maxPrecision);
    } // Number.MAX_SAFE_INTEGER, ie do not support.

    var MAX_SAFE_INTEGER = 9007199254740991;
    /**
     * To 0 - 2 * PI, considering negative radian.
     */

    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-next-line

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

    /**
     * @param value valid type: number | string | Date, otherwise return `new Date(NaN)`
     *   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 local 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 Never be null/undefined. If invalid, return `new Date(NaN)`.
     */

    function parseDate(value) {
      if (value instanceof Date) {
        return value;
      } else if (isString(value)) {
        // 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 is specified.


        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] ? +match[7].substring(0, 3) : 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] ? +match[7].substring(0, 3) : 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 val
     * @return
     */

    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 val non-negative value
     * @return
     */

    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  val Non-negative value.
     * @param  round
     * @return Niced 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 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 list, where `close` mean open or close
     *        of the interval, and Infinity can be used.
     * @return 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_1 = list[i].close;

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

          curr = interval[lg];
          currClose = close_1[lg];
        }

        if (interval[0] === interval[1] && close_1[0] * close_1[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));
      }
    }
    /**
     * [Numeric is defined as]:
     *     `parseFloat(val) == val`
     * For example:
     * numeric:
     *     typeof number except NaN, '-123', '123', '2e3', '-2e3', '011', 'Infinity', Infinity,
     *     and they rounded by white-spaces or line-terminal like ' -123 \n ' (see es spec)
     * not-numeric:
     *     null, undefined, [], {}, true, false, 'NaN', NaN, '123ab',
     *     empty string, string with only white-spaces or line-terminal (see es spec),
     *     0x12, '0x12', '-0x12', 012, '012', '-012',
     *     non-string, ...
     *
     * @test See full test cases in `test/ut/spec/util/number.js`.
     * @return Must be a typeof number. If not numeric, return NaN.
     */

    function numericToNumber(val) {
      var valFloat = parseFloat(val);
      return valFloat == val // eslint-disable-line eqeqeq
      && (valFloat !== 0 || !isString(val) || val.indexOf('x') <= 0) // For case ' 0x0 '.
      ? valFloat : NaN;
    }
    /**
     * Definition of "numeric": see `numericToNumber`.
     */

    function isNumeric(val) {
      return !isNaN(numericToNumber(val));
    }
    /**
     * Use random base to prevent users hard code depending on
     * this auto generated marker id.
     * @return An positive integer.
     */

    function getRandomIdBase() {
      return Math.round(Math.random() * 9);
    }
    /**
     * Get the greatest common divisor.
     *
     * @param {number} a one number
     * @param {number} b the other number
     */

    function getGreatestCommonDividor(a, b) {
      if (b === 0) {
        return a;
      }

      return getGreatestCommonDividor(b, a % b);
    }
    /**
     * Get the least common multiple.
     *
     * @param {number} a one number
     * @param {number} b the other number
     */

    function getLeastCommonMultiple(a, b) {
      if (a == null) {
        return b;
      }

      if (b == null) {
        return a;
      }

      return a * b / getGreatestCommonDividor(a, b);
    }

    var ECHARTS_PREFIX = '[ECharts] ';
    var storedLogs = {};
    var hasConsole = typeof console !== 'undefined' // eslint-disable-next-line
    && console.warn && console.log;

    function outputLog(type, str, onlyOnce) {
      if (hasConsole) {
        if (onlyOnce) {
          if (storedLogs[str]) {
            return;
          }

          storedLogs[str] = true;
        } // eslint-disable-next-line


        console[type](ECHARTS_PREFIX + str);
      }
    }

    function log(str, onlyOnce) {
      outputLog('log', str, onlyOnce);
    }
    function warn(str, onlyOnce) {
      outputLog('warn', str, onlyOnce);
    }
    function error(str, onlyOnce) {
      outputLog('error', str, onlyOnce);
    }
    function deprecateLog(str) {
      if ("development" !== 'production') {
        // Not display duplicate message.
        outputLog('warn', 'DEPRECATED: ' + str, true);
      }
    }
    function deprecateReplaceLog(oldOpt, newOpt, scope) {
      if ("development" !== 'production') {
        deprecateLog((scope ? "[" + scope + "]" : '') + (oldOpt + " is deprecated, use " + newOpt + " instead."));
      }
    }
    /**
     * If in __DEV__ environment, get console printable message for users hint.
     * Parameters are separated by ' '.
     * @usage
     * makePrintable('This is an error on', someVar, someObj);
     *
     * @param hintInfo anything about the current execution context to hint users.
     * @throws Error
     */

    function makePrintable() {
      var hintInfo = [];

      for (var _i = 0; _i < arguments.length; _i++) {
        hintInfo[_i] = arguments[_i];
      }

      var msg = '';

      if ("development" !== 'production') {
        // Fuzzy stringify for print.
        // This code only exist in dev environment.
        var makePrintableStringIfPossible_1 = function (val) {
          return val === void 0 ? 'undefined' : val === Infinity ? 'Infinity' : val === -Infinity ? '-Infinity' : eqNaN(val) ? 'NaN' : val instanceof Date ? 'Date(' + val.toISOString() + ')' : isFunction(val) ? 'function () { ... }' : isRegExp(val) ? val + '' : null;
        };

        msg = map(hintInfo, function (arg) {
          if (isString(arg)) {
            // Print without quotation mark for some statement.
            return arg;
          } else {
            var printableStr = makePrintableStringIfPossible_1(arg);

            if (printableStr != null) {
              return printableStr;
            } else if (typeof JSON !== 'undefined' && JSON.stringify) {
              try {
                return JSON.stringify(arg, function (n, val) {
                  var printableStr = makePrintableStringIfPossible_1(val);
                  return printableStr == null ? val : printableStr;
                }); // In most cases the info object is small, so do not line break.
              } catch (err) {
                return '?';
              }
            } else {
              return '?';
            }
          }
        }).join(' ');
      }

      return msg;
    }
    /**
     * @throws Error
     */

    function throwError(msg) {
      throw new Error(msg);
    }

    function interpolateNumber$1(p0, p1, percent) {
      return (p1 - p0) * percent + p0;
    }
    /**
     * 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';
    var INTERNAL_COMPONENT_ID_PREFIX = '\0_ec_\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 }
     *     }
     */

    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 does not ensure performance.
     * data could be [12, 2323, {value: 223}, [1221, 23], {value: [2, 23]}]
     * This helper method retrieves value from data.
     */

    function getDataItemValue(dataItem) {
      return isObject(dataItem) && !isArray(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
     */

    function isDataItemOption(dataItem) {
      return isObject(dataItem) && !(dataItem instanceof Array); // // markLine data can be array
      // && !(dataItem[0] && isObject(dataItem[0]) && !(dataItem[0] instanceof Array));
    }
    /**
     * Mapping to existings for merge.
     *
     * Mode "normalMege":
     *     The mapping result (merge result) will keep the order of the existing
     *     component, rather than the order of new option. Because we should ensure
     *     some specified index reference (like xAxisIndex) keep work.
     *     And in most cases, "merge option" is used to update partial option but not
     *     be expected to change the order.
     *
     * Mode "replaceMege":
     *     (1) Only the id mapped components will be merged.
     *     (2) Other existing components (except internal components) will be removed.
     *     (3) Other new options will be used to create new component.
     *     (4) The index of the existing components will not be modified.
     *     That means their might be "hole" after the removal.
     *     The new components are created first at those available index.
     *
     * Mode "replaceAll":
     *     This mode try to support that reproduce an echarts instance from another
     *     echarts instance (via `getOption`) in some simple cases.
     *     In this scenario, the `result` index are exactly the consistent with the `newCmptOptions`,
     *     which ensures the component index referring (like `xAxisIndex: ?`) corrent. That is,
     *     the "hole" in `newCmptOptions` will also be kept.
     *     On the contrary, other modes try best to eliminate holes.
     *     PENDING: This is an experimental mode yet.
     *
     * @return See the comment of <MappingResult>.
     */

    function mappingToExists(existings, newCmptOptions, mode) {
      var isNormalMergeMode = mode === 'normalMerge';
      var isReplaceMergeMode = mode === 'replaceMerge';
      var isReplaceAllMode = mode === 'replaceAll';
      existings = existings || [];
      newCmptOptions = (newCmptOptions || []).slice();
      var existingIdIdxMap = createHashMap(); // Validate id and name on user input option.

      each(newCmptOptions, function (cmptOption, index) {
        if (!isObject(cmptOption)) {
          newCmptOptions[index] = null;
          return;
        }

        if ("development" !== 'production') {
          // There is some legacy case that name is set as `false`.
          // But should work normally rather than throw error.
          if (cmptOption.id != null && !isValidIdOrName(cmptOption.id)) {
            warnInvalidateIdOrName(cmptOption.id);
          }

          if (cmptOption.name != null && !isValidIdOrName(cmptOption.name)) {
            warnInvalidateIdOrName(cmptOption.name);
          }
        }
      });
      var result = prepareResult(existings, existingIdIdxMap, mode);

      if (isNormalMergeMode || isReplaceMergeMode) {
        mappingById(result, existings, existingIdIdxMap, newCmptOptions);
      }

      if (isNormalMergeMode) {
        mappingByName(result, newCmptOptions);
      }

      if (isNormalMergeMode || isReplaceMergeMode) {
        mappingByIndex(result, newCmptOptions, isReplaceMergeMode);
      } else if (isReplaceAllMode) {
        mappingInReplaceAllMode(result, newCmptOptions);
      }

      makeIdAndName(result); // The array `result` MUST NOT contain elided items, otherwise the
      // forEach will omit those items and result in incorrect result.

      return result;
    }

    function prepareResult(existings, existingIdIdxMap, mode) {
      var result = [];

      if (mode === 'replaceAll') {
        return result;
      } // Do not use native `map` to in case that the array `existings`
      // contains elided items, which will be omitted.


      for (var index = 0; index < existings.length; index++) {
        var existing = existings[index]; // Because of replaceMerge, `existing` may be null/undefined.

        if (existing && existing.id != null) {
          existingIdIdxMap.set(existing.id, index);
        } // For non-internal-componnets:
        //     Mode "normalMerge": all existings kept.
        //     Mode "replaceMerge": all existing removed unless mapped by id.
        // For internal-components:
        //     go with "replaceMerge" approach in both mode.


        result.push({
          existing: mode === 'replaceMerge' || isComponentIdInternal(existing) ? null : existing,
          newOption: null,
          keyInfo: null,
          brandNew: null
        });
      }

      return result;
    }

    function mappingById(result, existings, existingIdIdxMap, newCmptOptions) {
      // Mapping by id if specified.
      each(newCmptOptions, function (cmptOption, index) {
        if (!cmptOption || cmptOption.id == null) {
          return;
        }

        var optionId = makeComparableKey(cmptOption.id);
        var existingIdx = existingIdIdxMap.get(optionId);

        if (existingIdx != null) {
          var resultItem = result[existingIdx];
          assert(!resultItem.newOption, 'Duplicated option on id "' + optionId + '".');
          resultItem.newOption = cmptOption; // In both mode, if id matched, new option will be merged to
          // the existings rather than creating new component model.

          resultItem.existing = existings[existingIdx];
          newCmptOptions[index] = null;
        }
      });
    }

    function mappingByName(result, newCmptOptions) {
      // Mapping by name if specified.
      each(newCmptOptions, function (cmptOption, index) {
        if (!cmptOption || cmptOption.name == null) {
          return;
        }

        for (var i = 0; i < result.length; i++) {
          var existing = result[i].existing;

          if (!result[i].newOption // Consider name: two map to one.
          // Can not match when both ids existing but different.
          && existing && (existing.id == null || cmptOption.id == null) && !isComponentIdInternal(cmptOption) && !isComponentIdInternal(existing) && keyExistAndEqual('name', existing, cmptOption)) {
            result[i].newOption = cmptOption;
            newCmptOptions[index] = null;
            return;
          }
        }
      });
    }

    function mappingByIndex(result, newCmptOptions, brandNew) {
      each(newCmptOptions, function (cmptOption) {
        if (!cmptOption) {
          return;
        } // Find the first place that not mapped by id and not internal component (consider the "hole").


        var resultItem;
        var nextIdx = 0;

        while ( // Be `!resultItem` only when `nextIdx >= result.length`.
        (resultItem = result[nextIdx]) && ( // (1) Existing models that already have id should be able to mapped to. Because
        // after mapping performed, model will always be assigned with an id if user not given.
        // After that all models have id.
        // (2) If new option has id, it can only set to a hole or append to the last. It should
        // not be merged to the existings with different id. Because id should not be overwritten.
        // (3) Name can be overwritten, because axis use name as 'show label text'.
        resultItem.newOption || isComponentIdInternal(resultItem.existing) || // In mode "replaceMerge", here no not-mapped-non-internal-existing.
        resultItem.existing && cmptOption.id != null && !keyExistAndEqual('id', cmptOption, resultItem.existing))) {
          nextIdx++;
        }

        if (resultItem) {
          resultItem.newOption = cmptOption;
          resultItem.brandNew = brandNew;
        } else {
          result.push({
            newOption: cmptOption,
            brandNew: brandNew,
            existing: null,
            keyInfo: null
          });
        }

        nextIdx++;
      });
    }

    function mappingInReplaceAllMode(result, newCmptOptions) {
      each(newCmptOptions, function (cmptOption) {
        // The feature "reproduce" requires "hole" will also reproduced
        // in case that component index referring are broken.
        result.push({
          newOption: cmptOption,
          brandNew: true,
          existing: null,
          keyInfo: null
        });
      });
    }
    /**
     * Make id and name for mapping result (result of mappingToExists)
     * into `keyInfo` field.
     */


    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(mapResult, function (item) {
        var existing = item.existing;
        existing && idMap.set(existing.id, item);
      });
      each(mapResult, function (item) {
        var opt = item.newOption; // Force ensure id not duplicated.

        assert(!opt || opt.id == null || !idMap.get(opt.id) || idMap.get(opt.id) === item, 'id duplicates: ' + (opt && opt.id));
        opt && opt.id != null && idMap.set(opt.id, item);
        !item.keyInfo && (item.keyInfo = {});
      }); // Make name and id.

      each(mapResult, function (item, index) {
        var existing = item.existing;
        var opt = item.newOption;
        var keyInfo = item.keyInfo;

        if (!isObject(opt)) {
          return;
        } // Name can be overwritten. 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 ? makeComparableKey(opt.name) : existing ? existing.name // Avoid that different series has the same name,
        // because name may be used like in color pallet.
        : DUMMY_COMPONENT_NAME_PREFIX + index;

        if (existing) {
          keyInfo.id = makeComparableKey(existing.id);
        } else if (opt.id != null) {
          keyInfo.id = makeComparableKey(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 keyExistAndEqual(attr, obj1, obj2) {
      var key1 = convertOptionIdName(obj1[attr], null);
      var key2 = convertOptionIdName(obj2[attr], null); // See `MappingExistingItem`. `id` and `name` trade string equals to number.

      return key1 != null && key2 != null && key1 === key2;
    }
    /**
     * @return return null if not exist.
     */


    function makeComparableKey(val) {
      if ("development" !== 'production') {
        if (val == null) {
          throw new Error();
        }
      }

      return convertOptionIdName(val, '');
    }

    function convertOptionIdName(idOrName, defaultValue) {
      if (idOrName == null) {
        return defaultValue;
      }

      return isString(idOrName) ? idOrName : isNumber(idOrName) || isStringSafe(idOrName) ? idOrName + '' : defaultValue;
    }

    function warnInvalidateIdOrName(idOrName) {
      if ("development" !== 'production') {
        warn('`' + idOrName + '` is invalid id or name. Must be a string or number.');
      }
    }

    function isValidIdOrName(idOrName) {
      return isStringSafe(idOrName) || isNumeric(idOrName);
    }

    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} cmptOption
     * @return {boolean}
     */

    function isComponentIdInternal(cmptOption) {
      return cmptOption && cmptOption.id != null && makeComparableKey(cmptOption.id).indexOf(INTERNAL_COMPONENT_ID_PREFIX) === 0;
    }
    function makeInternalComponentId(idSuffix) {
      return INTERNAL_COMPONENT_ID_PREFIX + idSuffix;
    }
    function setComponentTypeToKeyInfo(mappingResult, mainType, componentModelCtor) {
      // Set mainType and complete subType.
      each(mappingResult, function (item) {
        var newOption = item.newOption;

        if (isObject(newOption)) {
          item.keyInfo.mainType = mainType;
          item.keyInfo.subType = determineSubType(mainType, newOption, item.existing, componentModelCtor);
        }
      });
    }

    function determineSubType(mainType, newCmptOption, existComponent, componentModelCtor) {
      var subType = newCmptOption.type ? newCmptOption.type : existComponent ? existComponent.subType // Use determineSubType only when there is no existComponent.
      : componentModelCtor.determineSubType(mainType, newCmptOption); // tooltip, markline, markpoint may always has no subType

      return subType;
    }
    /**
     * A helper for removing duplicate items between batchA and batchB,
     * and in themselves, and categorize by series.
     *
     * @param batchA Like: [{seriesId: 2, dataIndex: [32, 4, 5]}, ...]
     * @param batchB Like: [{seriesId: 2, dataIndex: [32, 4, 5]}, ...]
     * @return result: [resultBatchA, resultBatchB]
     */


    function compressBatches(batchA, batchB) {
      var mapA = {};
      var mapB = {};
      makeMap(batchA || [], mapA);
      makeMap(batchB || [], mapB, mapA);
      return [mapToArray(mapA), mapToArray(mapB)];

      function makeMap(sourceBatch, map, otherMap) {
        for (var i = 0, len = sourceBatch.length; i < len; i++) {
          var seriesId = convertOptionIdName(sourceBatch[i].seriesId, null);

          if (seriesId == null) {
            return;
          }

          var dataIndices = normalizeToArray(sourceBatch[i].dataIndex);
          var otherDataIndices = otherMap && otherMap[seriesId];

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

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

      function mapToArray(map, isData) {
        var result = [];

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

        return result;
      }
    }
    /**
     * @param payload Contains dataIndex (means rawIndex) / dataIndexInside / name
     *                         each of which can be Array or primary type.
     * @return 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:
     * let inner = zrUitl.makeInner();
     *
     * function some1(hostObj) {
     *      inner(hostObj).someProperty = 1212;
     *      ...
     * }
     * function some2() {
     *      let fields = inner(this);
     *      fields.someProperty1 = 1212;
     *      fields.someProperty2 = 'xx';
     *      ...
     * }
     *
     * @return {Function}
     */

    function makeInner() {
      var key = '__ec_inner_' + innerUniqueIndex++;
      return function (hostObj) {
        return hostObj[key] || (hostObj[key] = {});
      };
    }
    var innerUniqueIndex = getRandomIdBase();
    /**
     * The same behavior as `component.getReferringComponents`.
     */

    function parseFinder(ecModel, finderInput, opt) {
      var _a = preParseFinder(finderInput, opt),
          mainTypeSpecified = _a.mainTypeSpecified,
          queryOptionMap = _a.queryOptionMap,
          others = _a.others;

      var result = others;
      var defaultMainType = opt ? opt.defaultMainType : null;

      if (!mainTypeSpecified && defaultMainType) {
        queryOptionMap.set(defaultMainType, {});
      }

      queryOptionMap.each(function (queryOption, mainType) {
        var queryResult = queryReferringComponents(ecModel, mainType, queryOption, {
          useDefault: defaultMainType === mainType,
          enableAll: opt && opt.enableAll != null ? opt.enableAll : true,
          enableNone: opt && opt.enableNone != null ? opt.enableNone : true
        });
        result[mainType + 'Models'] = queryResult.models;
        result[mainType + 'Model'] = queryResult.models[0];
      });
      return result;
    }
    function preParseFinder(finderInput, opt) {
      var finder;

      if (isString(finderInput)) {
        var obj = {};
        obj[finderInput + 'Index'] = 0;
        finder = obj;
      } else {
        finder = finderInput;
      }

      var queryOptionMap = createHashMap();
      var others = {};
      var mainTypeSpecified = false;
      each(finder, function (value, key) {
        // Exclude 'dataIndex' and other illgal keys.
        if (key === 'dataIndex' || key === 'dataIndexInside') {
          others[key] = value;
          return;
        }

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

        if (!mainType || !queryType || opt && opt.includeMainTypes && indexOf(opt.includeMainTypes, mainType) < 0) {
          return;
        }

        mainTypeSpecified = mainTypeSpecified || !!mainType;
        var queryOption = queryOptionMap.get(mainType) || queryOptionMap.set(mainType, {});
        queryOption[queryType] = value;
      });
      return {
        mainTypeSpecified: mainTypeSpecified,
        queryOptionMap: queryOptionMap,
        others: others
      };
    }
    var SINGLE_REFERRING = {
      useDefault: true,
      enableAll: false,
      enableNone: false
    };
    var MULTIPLE_REFERRING = {
      useDefault: false,
      enableAll: true,
      enableNone: true
    };
    function queryReferringComponents(ecModel, mainType, userOption, opt) {
      opt = opt || SINGLE_REFERRING;
      var indexOption = userOption.index;
      var idOption = userOption.id;
      var nameOption = userOption.name;
      var result = {
        models: null,
        specified: indexOption != null || idOption != null || nameOption != null
      };

      if (!result.specified) {
        // Use the first as default if `useDefault`.
        var firstCmpt = void 0;
        result.models = opt.useDefault && (firstCmpt = ecModel.getComponent(mainType)) ? [firstCmpt] : [];
        return result;
      }

      if (indexOption === 'none' || indexOption === false) {
        assert(opt.enableNone, '`"none"` or `false` is not a valid value on index option.');
        result.models = [];
        return result;
      } // `queryComponents` will return all components if
      // both all of index/id/name are null/undefined.


      if (indexOption === 'all') {
        assert(opt.enableAll, '`"all"` is not a valid value on index option.');
        indexOption = idOption = nameOption = null;
      }

      result.models = ecModel.queryComponents({
        mainType: mainType,
        index: indexOption,
        id: idOption,
        name: nameOption
      });
      return result;
    }
    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.domSupported ? 'html' : 'richText';
      } else {
        return renderModeOption || 'html';
      }
    }
    /**
     * Group a list by key.
     */

    function groupData(array, getKey // return key
    ) {
      var buckets = createHashMap();
      var keys = [];
      each(array, function (item) {
        var key = getKey(item);
        (buckets.get(key) || (keys.push(key), buckets.set(key, []))).push(item);
      });
      return {
        keys: keys,
        buckets: buckets
      };
    }
    /**
     * Interpolate raw values of a series with percent
     *
     * @param data         data
     * @param labelModel   label model of the text element
     * @param sourceValue  start value. May be null/undefined when init.
     * @param targetValue  end value
     * @param percent      0~1 percentage; 0 uses start value while 1 uses end value
     * @return             interpolated values
     *                     If `sourceValue` and `targetValue` are `number`, return `number`.
     *                     If `sourceValue` and `targetValue` are `string`, return `string`.
     *                     If `sourceValue` and `targetValue` are `(string | number)[]`, return `(string | number)[]`.
     *                     Other cases do not supported.
     */

    function interpolateRawValues(data, precision, sourceValue, targetValue, percent) {
      var isAutoPrecision = precision == null || precision === 'auto';

      if (targetValue == null) {
        return targetValue;
      }

      if (isNumber(targetValue)) {
        var value = interpolateNumber$1(sourceValue || 0, targetValue, percent);
        return round(value, isAutoPrecision ? Math.max(getPrecision(sourceValue || 0), getPrecision(targetValue)) : precision);
      } else if (isString(targetValue)) {
        return percent < 1 ? sourceValue : targetValue;
      } else {
        var interpolated = [];
        var leftArr = sourceValue;
        var rightArr = targetValue;
        var length_1 = Math.max(leftArr ? leftArr.length : 0, rightArr.length);

        for (var i = 0; i < length_1; ++i) {
          var info = data.getDimensionInfo(i); // Don't interpolate ordinal dims

          if (info && info.type === 'ordinal') {
            // In init, there is no `sourceValue`, but should better not to get undefined result.
            interpolated[i] = (percent < 1 && leftArr ? leftArr : rightArr)[i];
          } else {
            var leftVal = leftArr && leftArr[i] ? leftArr[i] : 0;
            var rightVal = rightArr[i];
            var value = interpolateNumber$1(leftVal, rightVal, percent);
            interpolated[i] = round(value, isAutoPrecision ? Math.max(getPrecision(leftVal), getPrecision(rightVal)) : precision);
          }
        }

        return interpolated;
      }
    }

    var TYPE_DELIMITER = '.';
    var IS_CONTAINER = '___EC__COMPONENT__CONTAINER___';
    var IS_EXTENDED_CLASS = '___EC__EXTENDED_CLASS___';
    /**
     * Notice, parseClassType('') should returns {main: '', sub: ''}
     * @public
     */

    function parseClassType(componentType) {
      var ret = {
        main: '',
        sub: ''
      };

      if (componentType) {
        var typeArr = componentType.split(TYPE_DELIMITER);
        ret.main = typeArr[0] || '';
        ret.sub = typeArr[1] || '';
      }

      return ret;
    }
    /**
     * @public
     */

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

    function isExtendedClass(clz) {
      return !!(clz && clz[IS_EXTENDED_CLASS]);
    }
    /**
     * Implements `ExtendableConstructor` for `rootClz`.
     *
     * @usage
     * ```ts
     * class Xxx {}
     * type XxxConstructor = typeof Xxx & ExtendableConstructor
     * enableClassExtend(Xxx as XxxConstructor);
     * ```
     */

    function enableClassExtend(rootClz, mandatoryMethods) {
      rootClz.$constructor = rootClz; // FIXME: not necessary?

      rootClz.extend = function (proto) {
        if ("development" !== 'production') {
          each(mandatoryMethods, function (method) {
            if (!proto[method]) {
              console.warn('Method `' + method + '` should be implemented' + (proto.type ? ' in ' + proto.type : '') + '.');
            }
          });
        }

        var superClass = this;
        var ExtendedClass;

        if (isESClass(superClass)) {
          ExtendedClass =
          /** @class */
          function (_super) {
            __extends(class_1, _super);

            function class_1() {
              return _super.apply(this, arguments) || this;
            }

            return class_1;
          }(superClass);
        } else {
          // For backward compat, we both support ts class inheritance and this
          // "extend" approach.
          // The constructor should keep the same behavior as ts class inheritance:
          // If this constructor/$constructor is not declared, auto invoke the super
          // constructor.
          // If this constructor/$constructor is declared, it is responsible for
          // calling the super constructor.
          ExtendedClass = function () {
            (proto.$constructor || superClass).apply(this, arguments);
          };

          inherits(ExtendedClass, this);
        }

        extend(ExtendedClass.prototype, proto);
        ExtendedClass[IS_EXTENDED_CLASS] = true;
        ExtendedClass.extend = this.extend;
        ExtendedClass.superCall = superCall;
        ExtendedClass.superApply = superApply;
        ExtendedClass.superClass = superClass;
        return ExtendedClass;
      };
    }

    function isESClass(fn) {
      return isFunction(fn) && /^class\s/.test(Function.prototype.toString.call(fn));
    }
    /**
     * A work around to both support ts extend and this extend mechanism.
     * on sub-class.
     * @usage
     * ```ts
     * class Component { ... }
     * classUtil.enableClassExtend(Component);
     * classUtil.enableClassManagement(Component, {registerWhenExtend: true});
     *
     * class Series extends Component { ... }
     * // Without calling `markExtend`, `registerWhenExtend` will not work.
     * Component.markExtend(Series);
     * ```
     */


    function mountExtend(SubClz, SupperClz) {
      SubClz.extend = SupperClz.extend;
    } // A random offset.

    var classBase = Math.round(Math.random() * 10);
    /**
     * Implements `CheckableConstructor` for `target`.
     * Can not use instanceof, consider different scope by
     * cross domain or es module import in ec extensions.
     * Mount a method "isInstance()" to Clz.
     *
     * @usage
     * ```ts
     * class Xxx {}
     * type XxxConstructor = typeof Xxx & CheckableConstructor;
     * enableClassCheck(Xxx as XxxConstructor)
     * ```
     */

    function enableClassCheck(target) {
      var classAttr = ['__\0is_clz', classBase++].join('_');
      target.prototype[classAttr] = true;

      if ("development" !== 'production') {
        assert(!target.isInstance, 'The method "is" can not be defined.');
      }

      target.isInstance = function (obj) {
        return !!(obj && obj[classAttr]);
      };
    } // superCall should have class info, which can not be fetched 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, does not override method f,
    // then when method of class C is called, dead loop occurred.

    function superCall(context, methodName) {
      var args = [];

      for (var _i = 2; _i < arguments.length; _i++) {
        args[_i - 2] = arguments[_i];
      }

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

    function superApply(context, methodName, args) {
      return this.superClass.prototype[methodName].apply(context, args);
    }
    /**
     * Implements `ClassManager` for `target`
     *
     * @usage
     * ```ts
     * class Xxx {}
     * type XxxConstructor = typeof Xxx & ClassManager
     * enableClassManagement(Xxx as XxxConstructor);
     * ```
     */


    function enableClassManagement(target) {
      /**
       * Component model classes
       * key: componentType,
       * value:
       *     componentClass, when componentType is 'a'
       *     or Object.<subKey, componentClass>, when componentType is 'a.b'
       */
      var storage = {};

      target.registerClass = function (clz) {
        // `type` should not be a "instance member".
        // If using TS class, should better declared as `static type = 'series.pie'`.
        // otherwise users have to mount `type` on prototype manually.
        // For backward compat and enable instance visit type via `this.type`,
        // we still support fetch `type` from prototype.
        var componentFullType = clz.type || clz.prototype.type;

        if (componentFullType) {
          checkClassType(componentFullType); // If only static type declared, we assign it to prototype mandatorily.

          clz.prototype.type = componentFullType;
          var componentTypeInfo = parseClassType(componentFullType);

          if (!componentTypeInfo.sub) {
            if ("development" !== 'production') {
              if (storage[componentTypeInfo.main]) {
                console.warn(componentTypeInfo.main + ' exists.');
              }
            }

            storage[componentTypeInfo.main] = clz;
          } else if (componentTypeInfo.sub !== IS_CONTAINER) {
            var container = makeContainer(componentTypeInfo);
            container[componentTypeInfo.sub] = clz;
          }
        }

        return clz;
      };

      target.getClass = function (mainType, subType, throwWhenNotFound) {
        var clz = storage[mainType];

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

        if (throwWhenNotFound && !clz) {
          throw new Error(!subType ? mainType + '.' + 'type should be specified.' : 'Component ' + mainType + '.' + (subType || '') + ' is used but not imported.');
        }

        return clz;
      };

      target.getClassesByMainType = function (componentType) {
        var componentTypeInfo = parseClassType(componentType);
        var result = [];
        var obj = storage[componentTypeInfo.main];

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

        return result;
      };

      target.hasClass = function (componentType) {
        // Just consider componentType.main.
        var componentTypeInfo = parseClassType(componentType);
        return !!storage[componentTypeInfo.main];
      };
      /**
       * @return Like ['aa', 'bb'], but can not be ['aa.xx']
       */


      target.getAllClassMainTypes = function () {
        var types = [];
        each(storage, function (obj, type) {
          types.push(type);
        });
        return types;
      };
      /**
       * If a main type is container and has sub types
       */


      target.hasSubTypes = function (componentType) {
        var componentTypeInfo = parseClassType(componentType);
        var obj = storage[componentTypeInfo.main];
        return obj && obj[IS_CONTAINER];
      };

      function makeContainer(componentTypeInfo) {
        var container = storage[componentTypeInfo.main];

        if (!container || !container[IS_CONTAINER]) {
          container = storage[componentTypeInfo.main] = {};
          container[IS_CONTAINER] = true;
        }

        return container;
      }
    } // /**
    //  * @param {string|Array.<string>} properties
    //  */
    // export function setReadOnly(obj, properties) {
    // FIXME It seems broken in IE8 simulation of IE11
    // if (!zrUtil.isArray(properties)) {
    //     properties = properties != null ? [properties] : [];
    // }
    // zrUtil.each(properties, function (prop) {
    //     let value = obj[prop];
    //     Object.defineProperty
    //         && Object.defineProperty(obj, prop, {
    //             value: value, writable: false
    //         });
    //     zrUtil.isArray(obj[prop])
    //         && Object.freeze
    //         && Object.freeze(obj[prop]);
    // });
    // }

    function makeStyleMapper(properties, ignoreParent) {
      // Normalize
      for (var i = 0; i < properties.length; i++) {
        if (!properties[i][1]) {
          properties[i][1] = properties[i][0];
        }
      }

      ignoreParent = ignoreParent || false;
      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, ignoreParent);

          if (val != null) {
            style[properties[i][0]] = val;
          }
        } // TODO Text or image?


        return style;
      };
    }

    var AREA_STYLE_KEY_MAP = [['fill', 'color'], ['shadowBlur'], ['shadowOffsetX'], ['shadowOffsetY'], ['opacity'], ['shadowColor'] // Option decal is in `DecalObject` but style.decal is in `PatternObject`.
    // So do not transfer decal directly.
    ];
    var getAreaStyle = makeStyleMapper(AREA_STYLE_KEY_MAP);

    var AreaStyleMixin =
    /** @class */
    function () {
      function AreaStyleMixin() {}

      AreaStyleMixin.prototype.getAreaStyle = function (excludes, includes) {
        return getAreaStyle(this, excludes, includes);
      };

      return AreaStyleMixin;
    }();

    var globalImageCache = new LRU(50);
    function findExistImage(newImageOrSrc) {
        if (typeof newImageOrSrc === 'string') {
            var cachedImgObj = globalImageCache.get(newImageOrSrc);
            return cachedImgObj && cachedImgObj.image;
        }
        else {
            return newImageOrSrc;
        }
    }
    function createOrUpdateImage(newImageOrSrc, image, hostEl, onload, cbPayload) {
        if (!newImageOrSrc) {
            return image;
        }
        else if (typeof newImageOrSrc === 'string') {
            if ((image && image.__zrImageSrc === newImageOrSrc) || !hostEl) {
                return image;
            }
            var cachedImgObj = globalImageCache.get(newImageOrSrc);
            var pendingWrap = { hostEl: hostEl, cb: onload, cbPayload: cbPayload };
            if (cachedImgObj) {
                image = cachedImgObj.image;
                !isImageReady(image) && cachedImgObj.pending.push(pendingWrap);
            }
            else {
                image = platformApi.loadImage(newImageOrSrc, imageOnLoad, imageOnLoad);
                image.__zrImageSrc = newImageOrSrc;
                globalImageCache.put(newImageOrSrc, image.__cachedImgObj = {
                    image: image,
                    pending: [pendingWrap]
                });
            }
            return image;
        }
        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 STYLE_REG = /\{([a-zA-Z0-9_]+)\|([^}]*)\}/g;
    function truncateText(text, containerWidth, font, ellipsis, options) {
        if (!containerWidth) {
            return '';
        }
        var textLines = (text + '').split('\n');
        options = prepareTruncateOptions(containerWidth, font, ellipsis, options);
        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 = options || {};
        var preparedOpts = extend({}, options);
        preparedOpts.font = font;
        ellipsis = retrieve2(ellipsis, '...');
        preparedOpts.maxIterations = retrieve2(options.maxIterations, 2);
        var minChar = preparedOpts.minChar = retrieve2(options.minChar, 0);
        preparedOpts.cnCharWidth = getWidth('国', font);
        var ascCharWidth = preparedOpts.ascCharWidth = getWidth('a', font);
        preparedOpts.placeholder = retrieve2(options.placeholder, '');
        var contentWidth = containerWidth = Math.max(0, containerWidth - 1);
        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;
        preparedOpts.ellipsis = ellipsis;
        preparedOpts.ellipsisWidth = ellipsisWidth;
        preparedOpts.contentWidth = contentWidth;
        preparedOpts.containerWidth = containerWidth;
        return preparedOpts;
    }
    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;
    }
    function parsePlainText(text, style) {
        text != null && (text += '');
        var overflow = style.overflow;
        var padding = style.padding;
        var font = style.font;
        var truncate = overflow === 'truncate';
        var calculatedLineHeight = getLineHeight(font);
        var lineHeight = retrieve2(style.lineHeight, calculatedLineHeight);
        var bgColorDrawn = !!(style.backgroundColor);
        var truncateLineOverflow = style.lineOverflow === 'truncate';
        var width = style.width;
        var lines;
        if (width != null && (overflow === 'break' || overflow === 'breakAll')) {
            lines = text ? wrapText(text, style.font, width, overflow === 'breakAll', 0).lines : [];
        }
        else {
            lines = text ? text.split('\n') : [];
        }
        var contentHeight = lines.length * lineHeight;
        var height = retrieve2(style.height, contentHeight);
        if (contentHeight > height && truncateLineOverflow) {
            var lineCount = Math.floor(height / lineHeight);
            lines = lines.slice(0, lineCount);
        }
        if (text && truncate && width != null) {
            var options = prepareTruncateOptions(width, font, style.ellipsis, {
                minChar: style.truncateMinChar,
                placeholder: style.placeholder
            });
            for (var i = 0; i < lines.length; i++) {
                lines[i] = truncateSingleLine(lines[i], options);
            }
        }
        var outerHeight = height;
        var contentWidth = 0;
        for (var i = 0; i < lines.length; i++) {
            contentWidth = Math.max(getWidth(lines[i], font), contentWidth);
        }
        if (width == null) {
            width = contentWidth;
        }
        var outerWidth = contentWidth;
        if (padding) {
            outerHeight += padding[0] + padding[2];
            outerWidth += padding[1] + padding[3];
            width += padding[1] + padding[3];
        }
        if (bgColorDrawn) {
            outerWidth = width;
        }
        return {
            lines: lines,
            height: height,
            outerWidth: outerWidth,
            outerHeight: outerHeight,
            lineHeight: lineHeight,
            calculatedLineHeight: calculatedLineHeight,
            contentWidth: contentWidth,
            contentHeight: contentHeight,
            width: width
        };
    }
    var RichTextToken = (function () {
        function RichTextToken() {
        }
        return RichTextToken;
    }());
    var RichTextLine = (function () {
        function RichTextLine(tokens) {
            this.tokens = [];
            if (tokens) {
                this.tokens = tokens;
            }
        }
        return RichTextLine;
    }());
    var RichTextContentBlock = (function () {
        function RichTextContentBlock() {
            this.width = 0;
            this.height = 0;
            this.contentWidth = 0;
            this.contentHeight = 0;
            this.outerWidth = 0;
            this.outerHeight = 0;
            this.lines = [];
        }
        return RichTextContentBlock;
    }());
    function parseRichText(text, style) {
        var contentBlock = new RichTextContentBlock();
        text != null && (text += '');
        if (!text) {
            return contentBlock;
        }
        var topWidth = style.width;
        var topHeight = style.height;
        var overflow = style.overflow;
        var wrapInfo = (overflow === 'break' || overflow === 'breakAll') && topWidth != null
            ? { width: topWidth, accumWidth: 0, breakAll: overflow === 'breakAll' }
            : null;
        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), style, wrapInfo);
            }
            pushTokens(contentBlock, result[2], style, wrapInfo, result[1]);
            lastIndex = STYLE_REG.lastIndex;
        }
        if (lastIndex < text.length) {
            pushTokens(contentBlock, text.substring(lastIndex, text.length), style, wrapInfo);
        }
        var pendingList = [];
        var calculatedHeight = 0;
        var calculatedWidth = 0;
        var stlPadding = style.padding;
        var truncate = overflow === 'truncate';
        var truncateLine = style.lineOverflow === 'truncate';
        function finishLine(line, lineWidth, lineHeight) {
            line.width = lineWidth;
            line.lineHeight = lineHeight;
            calculatedHeight += lineHeight;
            calculatedWidth = Math.max(calculatedWidth, lineWidth);
        }
        outer: for (var i = 0; i < contentBlock.lines.length; i++) {
            var line = contentBlock.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] || {};
                var textPadding = token.textPadding = tokenStyle.padding;
                var paddingH = textPadding ? textPadding[1] + textPadding[3] : 0;
                var font = token.font = tokenStyle.font || style.font;
                token.contentHeight = getLineHeight(font);
                var tokenHeight = retrieve2(tokenStyle.height, token.contentHeight);
                token.innerHeight = tokenHeight;
                textPadding && (tokenHeight += textPadding[0] + textPadding[2]);
                token.height = tokenHeight;
                token.lineHeight = retrieve3(tokenStyle.lineHeight, style.lineHeight, tokenHeight);
                token.align = tokenStyle && tokenStyle.align || style.align;
                token.verticalAlign = tokenStyle && tokenStyle.verticalAlign || 'middle';
                if (truncateLine && topHeight != null && calculatedHeight + token.lineHeight > topHeight) {
                    if (j > 0) {
                        line.tokens = line.tokens.slice(0, j);
                        finishLine(line, lineWidth, lineHeight);
                        contentBlock.lines = contentBlock.lines.slice(0, i + 1);
                    }
                    else {
                        contentBlock.lines = contentBlock.lines.slice(0, i);
                    }
                    break outer;
                }
                var styleTokenWidth = tokenStyle.width;
                var tokenWidthNotSpecified = styleTokenWidth == null || styleTokenWidth === 'auto';
                if (typeof styleTokenWidth === 'string' && styleTokenWidth.charAt(styleTokenWidth.length - 1) === '%') {
                    token.percentWidth = styleTokenWidth;
                    pendingList.push(token);
                    token.contentWidth = getWidth(token.text, font);
                }
                else {
                    if (tokenWidthNotSpecified) {
                        var textBackgroundColor = tokenStyle.backgroundColor;
                        var bgImg = textBackgroundColor && textBackgroundColor.image;
                        if (bgImg) {
                            bgImg = findExistImage(bgImg);
                            if (isImageReady(bgImg)) {
                                token.width = Math.max(token.width, bgImg.width * tokenHeight / bgImg.height);
                            }
                        }
                    }
                    var remainTruncWidth = truncate && topWidth != null
                        ? topWidth - lineWidth : null;
                    if (remainTruncWidth != null && remainTruncWidth < token.width) {
                        if (!tokenWidthNotSpecified || remainTruncWidth < paddingH) {
                            token.text = '';
                            token.width = token.contentWidth = 0;
                        }
                        else {
                            token.text = truncateText(token.text, remainTruncWidth - paddingH, font, style.ellipsis, { minChar: style.truncateMinChar });
                            token.width = token.contentWidth = getWidth(token.text, font);
                        }
                    }
                    else {
                        token.contentWidth = getWidth(token.text, font);
                    }
                }
                token.width += paddingH;
                lineWidth += token.width;
                tokenStyle && (lineHeight = Math.max(lineHeight, token.lineHeight));
            }
            finishLine(line, lineWidth, lineHeight);
        }
        contentBlock.outerWidth = contentBlock.width = retrieve2(topWidth, calculatedWidth);
        contentBlock.outerHeight = contentBlock.height = retrieve2(topHeight, calculatedHeight);
        contentBlock.contentHeight = calculatedHeight;
        contentBlock.contentWidth = calculatedWidth;
        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;
            token.width = parseInt(percentWidth, 10) / 100 * contentBlock.width;
        }
        return contentBlock;
    }
    function pushTokens(block, str, style, wrapInfo, styleName) {
        var isEmptyStr = str === '';
        var tokenStyle = styleName && style.rich[styleName] || {};
        var lines = block.lines;
        var font = tokenStyle.font || style.font;
        var newLine = false;
        var strLines;
        var linesWidths;
        if (wrapInfo) {
            var tokenPadding = tokenStyle.padding;
            var tokenPaddingH = tokenPadding ? tokenPadding[1] + tokenPadding[3] : 0;
            if (tokenStyle.width != null && tokenStyle.width !== 'auto') {
                var outerWidth_1 = parsePercent(tokenStyle.width, wrapInfo.width) + tokenPaddingH;
                if (lines.length > 0) {
                    if (outerWidth_1 + wrapInfo.accumWidth > wrapInfo.width) {
                        strLines = str.split('\n');
                        newLine = true;
                    }
                }
                wrapInfo.accumWidth = outerWidth_1;
            }
            else {
                var res = wrapText(str, font, wrapInfo.width, wrapInfo.breakAll, wrapInfo.accumWidth);
                wrapInfo.accumWidth = res.accumWidth + tokenPaddingH;
                linesWidths = res.linesWidths;
                strLines = res.lines;
            }
        }
        else {
            strLines = str.split('\n');
        }
        for (var i = 0; i < strLines.length; i++) {
            var text = strLines[i];
            var token = new RichTextToken();
            token.styleName = styleName;
            token.text = text;
            token.isLineHolder = !text && !isEmptyStr;
            if (typeof tokenStyle.width === 'number') {
                token.width = tokenStyle.width;
            }
            else {
                token.width = linesWidths
                    ? linesWidths[i]
                    : getWidth(text, font);
            }
            if (!i && !newLine) {
                var tokens = (lines[lines.length - 1] || (lines[0] = new RichTextLine())).tokens;
                var tokensLen = tokens.length;
                (tokensLen === 1 && tokens[0].isLineHolder)
                    ? (tokens[0] = token)
                    : ((text || !tokensLen || isEmptyStr) && tokens.push(token));
            }
            else {
                lines.push(new RichTextLine([token]));
            }
        }
    }
    function isLatin(ch) {
        var code = ch.charCodeAt(0);
        return code >= 0x21 && code <= 0x17F;
    }
    var breakCharMap = reduce(',&?/;] '.split(''), function (obj, ch) {
        obj[ch] = true;
        return obj;
    }, {});
    function isWordBreakChar(ch) {
        if (isLatin(ch)) {
            if (breakCharMap[ch]) {
                return true;
            }
            return false;
        }
        return true;
    }
    function wrapText(text, font, lineWidth, isBreakAll, lastAccumWidth) {
        var lines = [];
        var linesWidths = [];
        var line = '';
        var currentWord = '';
        var currentWordWidth = 0;
        var accumWidth = 0;
        for (var i = 0; i < text.length; i++) {
            var ch = text.charAt(i);
            if (ch === '\n') {
                if (currentWord) {
                    line += currentWord;
                    accumWidth += currentWordWidth;
                }
                lines.push(line);
                linesWidths.push(accumWidth);
                line = '';
                currentWord = '';
                currentWordWidth = 0;
                accumWidth = 0;
                continue;
            }
            var chWidth = getWidth(ch, font);
            var inWord = isBreakAll ? false : !isWordBreakChar(ch);
            if (!lines.length
                ? lastAccumWidth + accumWidth + chWidth > lineWidth
                : accumWidth + chWidth > lineWidth) {
                if (!accumWidth) {
                    if (inWord) {
                        lines.push(currentWord);
                        linesWidths.push(currentWordWidth);
                        currentWord = ch;
                        currentWordWidth = chWidth;
                    }
                    else {
                        lines.push(ch);
                        linesWidths.push(chWidth);
                    }
                }
                else if (line || currentWord) {
                    if (inWord) {
                        if (!line) {
                            line = currentWord;
                            currentWord = '';
                            currentWordWidth = 0;
                            accumWidth = currentWordWidth;
                        }
                        lines.push(line);
                        linesWidths.push(accumWidth - currentWordWidth);
                        currentWord += ch;
                        currentWordWidth += chWidth;
                        line = '';
                        accumWidth = currentWordWidth;
                    }
                    else {
                        if (currentWord) {
                            line += currentWord;
                            currentWord = '';
                            currentWordWidth = 0;
                        }
                        lines.push(line);
                        linesWidths.push(accumWidth);
                        line = ch;
                        accumWidth = chWidth;
                    }
                }
                continue;
            }
            accumWidth += chWidth;
            if (inWord) {
                currentWord += ch;
                currentWordWidth += chWidth;
            }
            else {
                if (currentWord) {
                    line += currentWord;
                    currentWord = '';
                    currentWordWidth = 0;
                }
                line += ch;
            }
        }
        if (!lines.length && !line) {
            line = text;
            currentWord = '';
            currentWordWidth = 0;
        }
        if (currentWord) {
            line += currentWord;
        }
        if (line) {
            lines.push(line);
            linesWidths.push(accumWidth);
        }
        if (lines.length === 1) {
            accumWidth += lastAccumWidth;
        }
        return {
            accumWidth: accumWidth,
            lines: lines,
            linesWidths: linesWidths
        };
    }

    var STYLE_MAGIC_KEY = '__zr_style_' + Math.round((Math.random() * 10));
    var DEFAULT_COMMON_STYLE = {
        shadowBlur: 0,
        shadowOffsetX: 0,
        shadowOffsetY: 0,
        shadowColor: '#000',
        opacity: 1,
        blend: 'source-over'
    };
    var DEFAULT_COMMON_ANIMATION_PROPS = {
        style: {
            shadowBlur: true,
            shadowOffsetX: true,
            shadowOffsetY: true,
            shadowColor: true,
            opacity: true
        }
    };
    DEFAULT_COMMON_STYLE[STYLE_MAGIC_KEY] = true;
    var PRIMARY_STATES_KEYS$1 = ['z', 'z2', 'invisible'];
    var PRIMARY_STATES_KEYS_IN_HOVER_LAYER = ['invisible'];
    var Displayable = (function (_super) {
        __extends(Displayable, _super);
        function Displayable(props) {
            return _super.call(this, props) || this;
        }
        Displayable.prototype._init = function (props) {
            var keysArr = keys(props);
            for (var i = 0; i < keysArr.length; i++) {
                var key = keysArr[i];
                if (key === 'style') {
                    this.useStyle(props[key]);
                }
                else {
                    _super.prototype.attrKV.call(this, key, props[key]);
                }
            }
            if (!this.style) {
                this.useStyle({});
            }
        };
        Displayable.prototype.beforeBrush = function () { };
        Displayable.prototype.afterBrush = function () { };
        Displayable.prototype.innerBeforeBrush = function () { };
        Displayable.prototype.innerAfterBrush = function () { };
        Displayable.prototype.shouldBePainted = function (viewWidth, viewHeight, considerClipPath, considerAncestors) {
            var m = this.transform;
            if (this.ignore
                || this.invisible
                || this.style.opacity === 0
                || (this.culling
                    && isDisplayableCulled(this, viewWidth, viewHeight))
                || (m && !m[0] && !m[3])) {
                return false;
            }
            if (considerClipPath && this.__clipPaths) {
                for (var i = 0; i < this.__clipPaths.length; ++i) {
                    if (this.__clipPaths[i].isZeroArea()) {
                        return false;
                    }
                }
            }
            if (considerAncestors && this.parent) {
                var parent_1 = this.parent;
                while (parent_1) {
                    if (parent_1.ignore) {
                        return false;
                    }
                    parent_1 = parent_1.parent;
                }
            }
            return true;
        };
        Displayable.prototype.contain = function (x, y) {
            return this.rectContain(x, y);
        };
        Displayable.prototype.traverse = function (cb, context) {
            cb.call(context, this);
        };
        Displayable.prototype.rectContain = function (x, y) {
            var coord = this.transformCoordToLocal(x, y);
            var rect = this.getBoundingRect();
            return rect.contain(coord[0], coord[1]);
        };
        Displayable.prototype.getPaintRect = function () {
            var rect = this._paintRect;
            if (!this._paintRect || this.__dirty) {
                var transform = this.transform;
                var elRect = this.getBoundingRect();
                var style = this.style;
                var shadowSize = style.shadowBlur || 0;
                var shadowOffsetX = style.shadowOffsetX || 0;
                var shadowOffsetY = style.shadowOffsetY || 0;
                rect = this._paintRect || (this._paintRect = new BoundingRect(0, 0, 0, 0));
                if (transform) {
                    BoundingRect.applyTransform(rect, elRect, transform);
                }
                else {
                    rect.copy(elRect);
                }
                if (shadowSize || shadowOffsetX || shadowOffsetY) {
                    rect.width += shadowSize * 2 + Math.abs(shadowOffsetX);
                    rect.height += shadowSize * 2 + Math.abs(shadowOffsetY);
                    rect.x = Math.min(rect.x, rect.x + shadowOffsetX - shadowSize);
                    rect.y = Math.min(rect.y, rect.y + shadowOffsetY - shadowSize);
                }
                var tolerance = this.dirtyRectTolerance;
                if (!rect.isZero()) {
                    rect.x = Math.floor(rect.x - tolerance);
                    rect.y = Math.floor(rect.y - tolerance);
                    rect.width = Math.ceil(rect.width + 1 + tolerance * 2);
                    rect.height = Math.ceil(rect.height + 1 + tolerance * 2);
                }
            }
            return rect;
        };
        Displayable.prototype.setPrevPaintRect = function (paintRect) {
            if (paintRect) {
                this._prevPaintRect = this._prevPaintRect || new BoundingRect(0, 0, 0, 0);
                this._prevPaintRect.copy(paintRect);
            }
            else {
                this._prevPaintRect = null;
            }
        };
        Displayable.prototype.getPrevPaintRect = function () {
            return this._prevPaintRect;
        };
        Displayable.prototype.animateStyle = function (loop) {
            return this.animate('style', loop);
        };
        Displayable.prototype.updateDuringAnimation = function (targetKey) {
            if (targetKey === 'style') {
                this.dirtyStyle();
            }
            else {
                this.markRedraw();
            }
        };
        Displayable.prototype.attrKV = function (key, value) {
            if (key !== 'style') {
                _super.prototype.attrKV.call(this, key, value);
            }
            else {
                if (!this.style) {
                    this.useStyle(value);
                }
                else {
                    this.setStyle(value);
                }
            }
        };
        Displayable.prototype.setStyle = function (keyOrObj, value) {
            if (typeof keyOrObj === 'string') {
                this.style[keyOrObj] = value;
            }
            else {
                extend(this.style, keyOrObj);
            }
            this.dirtyStyle();
            return this;
        };
        Displayable.prototype.dirtyStyle = function (notRedraw) {
            if (!notRedraw) {
                this.markRedraw();
            }
            this.__dirty |= STYLE_CHANGED_BIT;
            if (this._rect) {
                this._rect = null;
            }
        };
        Displayable.prototype.dirty = function () {
            this.dirtyStyle();
        };
        Displayable.prototype.styleChanged = function () {
            return !!(this.__dirty & STYLE_CHANGED_BIT);
        };
        Displayable.prototype.styleUpdated = function () {
            this.__dirty &= ~STYLE_CHANGED_BIT;
        };
        Displayable.prototype.createStyle = function (obj) {
            return createObject(DEFAULT_COMMON_STYLE, obj);
        };
        Displayable.prototype.useStyle = function (obj) {
            if (!obj[STYLE_MAGIC_KEY]) {
                obj = this.createStyle(obj);
            }
            if (this.__inHover) {
                this.__hoverStyle = obj;
            }
            else {
                this.style = obj;
            }
            this.dirtyStyle();
        };
        Displayable.prototype.isStyleObject = function (obj) {
            return obj[STYLE_MAGIC_KEY];
        };
        Displayable.prototype._innerSaveToNormal = function (toState) {
            _super.prototype._innerSaveToNormal.call(this, toState);
            var normalState = this._normalState;
            if (toState.style && !normalState.style) {
                normalState.style = this._mergeStyle(this.createStyle(), this.style);
            }
            this._savePrimaryToNormal(toState, normalState, PRIMARY_STATES_KEYS$1);
        };
        Displayable.prototype._applyStateObj = function (stateName, state, normalState, keepCurrentStates, transition, animationCfg) {
            _super.prototype._applyStateObj.call(this, stateName, state, normalState, keepCurrentStates, transition, animationCfg);
            var needsRestoreToNormal = !(state && keepCurrentStates);
            var targetStyle;
            if (state && state.style) {
                if (transition) {
                    if (keepCurrentStates) {
                        targetStyle = state.style;
                    }
                    else {
                        targetStyle = this._mergeStyle(this.createStyle(), normalState.style);
                        this._mergeStyle(targetStyle, state.style);
                    }
                }
                else {
                    targetStyle = this._mergeStyle(this.createStyle(), keepCurrentStates ? this.style : normalState.style);
                    this._mergeStyle(targetStyle, state.style);
                }
            }
            else if (needsRestoreToNormal) {
                targetStyle = normalState.style;
            }
            if (targetStyle) {
                if (transition) {
                    var sourceStyle = this.style;
                    this.style = this.createStyle(needsRestoreToNormal ? {} : sourceStyle);
                    if (needsRestoreToNormal) {
                        var changedKeys = keys(sourceStyle);
                        for (var i = 0; i < changedKeys.length; i++) {
                            var key = changedKeys[i];
                            if (key in targetStyle) {
                                targetStyle[key] = targetStyle[key];
                                this.style[key] = sourceStyle[key];
                            }
                        }
                    }
                    var targetKeys = keys(targetStyle);
                    for (var i = 0; i < targetKeys.length; i++) {
                        var key = targetKeys[i];
                        this.style[key] = this.style[key];
                    }
                    this._transitionState(stateName, {
                        style: targetStyle
                    }, animationCfg, this.getAnimationStyleProps());
                }
                else {
                    this.useStyle(targetStyle);
                }
            }
            var statesKeys = this.__inHover ? PRIMARY_STATES_KEYS_IN_HOVER_LAYER : PRIMARY_STATES_KEYS$1;
            for (var i = 0; i < statesKeys.length; i++) {
                var key = statesKeys[i];
                if (state && state[key] != null) {
                    this[key] = state[key];
                }
                else if (needsRestoreToNormal) {
                    if (normalState[key] != null) {
                        this[key] = normalState[key];
                    }
                }
            }
        };
        Displayable.prototype._mergeStates = function (states) {
            var mergedState = _super.prototype._mergeStates.call(this, states);
            var mergedStyle;
            for (var i = 0; i < states.length; i++) {
                var state = states[i];
                if (state.style) {
                    mergedStyle = mergedStyle || {};
                    this._mergeStyle(mergedStyle, state.style);
                }
            }
            if (mergedStyle) {
                mergedState.style = mergedStyle;
            }
            return mergedState;
        };
        Displayable.prototype._mergeStyle = function (targetStyle, sourceStyle) {
            extend(targetStyle, sourceStyle);
            return targetStyle;
        };
        Displayable.prototype.getAnimationStyleProps = function () {
            return DEFAULT_COMMON_ANIMATION_PROPS;
        };
        Displayable.initDefaultProps = (function () {
            var dispProto = Displayable.prototype;
            dispProto.type = 'displayable';
            dispProto.invisible = false;
            dispProto.z = 0;
            dispProto.z2 = 0;
            dispProto.zlevel = 0;
            dispProto.culling = false;
            dispProto.cursor = 'pointer';
            dispProto.rectHover = false;
            dispProto.incremental = false;
            dispProto._rect = null;
            dispProto.dirtyRectTolerance = 0;
            dispProto.__dirty = REDRAW_BIT | STYLE_CHANGED_BIT;
        })();
        return Displayable;
    }(Element));
    var tmpRect$1 = new BoundingRect(0, 0, 0, 0);
    var viewRect = new BoundingRect(0, 0, 0, 0);
    function isDisplayableCulled(el, width, height) {
        tmpRect$1.copy(el.getBoundingRect());
        if (el.transform) {
            tmpRect$1.applyTransform(el.transform);
        }
        viewRect.width = width;
        viewRect.height = height;
        return !tmpRect$1.intersect(viewRect);
    }

    var mathMin$1 = Math.min;
    var mathMax$1 = Math.max;
    var mathSin = Math.sin;
    var mathCos = Math.cos;
    var PI2 = Math.PI * 2;
    var start = create();
    var end = create();
    var extremity = create();
    function fromPoints(points, min, max) {
        if (points.length === 0) {
            return;
        }
        var p = points[0];
        var left = p[0];
        var right = p[0];
        var top = p[1];
        var bottom = p[1];
        for (var i = 1; i < points.length; i++) {
            p = points[i];
            left = mathMin$1(left, p[0]);
            right = mathMax$1(right, p[0]);
            top = mathMin$1(top, p[1]);
            bottom = mathMax$1(bottom, p[1]);
        }
        min[0] = left;
        min[1] = top;
        max[0] = right;
        max[1] = bottom;
    }
    function fromLine(x0, y0, x1, y1, min, max) {
        min[0] = mathMin$1(x0, x1);
        min[1] = mathMin$1(y0, y1);
        max[0] = mathMax$1(x0, x1);
        max[1] = mathMax$1(y0, y1);
    }
    var xDim = [];
    var yDim = [];
    function fromCubic(x0, y0, x1, y1, x2, y2, x3, y3, min, max) {
        var cubicExtrema$1 = cubicExtrema;
        var cubicAt$1 = cubicAt;
        var n = cubicExtrema$1(x0, x1, x2, x3, xDim);
        min[0] = Infinity;
        min[1] = Infinity;
        max[0] = -Infinity;
        max[1] = -Infinity;
        for (var i = 0; i < n; i++) {
            var x = cubicAt$1(x0, x1, x2, x3, xDim[i]);
            min[0] = mathMin$1(x, min[0]);
            max[0] = mathMax$1(x, max[0]);
        }
        n = cubicExtrema$1(y0, y1, y2, y3, yDim);
        for (var i = 0; i < n; i++) {
            var y = cubicAt$1(y0, y1, y2, y3, yDim[i]);
            min[1] = mathMin$1(y, min[1]);
            max[1] = mathMax$1(y, max[1]);
        }
        min[0] = mathMin$1(x0, min[0]);
        max[0] = mathMax$1(x0, max[0]);
        min[0] = mathMin$1(x3, min[0]);
        max[0] = mathMax$1(x3, max[0]);
        min[1] = mathMin$1(y0, min[1]);
        max[1] = mathMax$1(y0, max[1]);
        min[1] = mathMin$1(y3, min[1]);
        max[1] = mathMax$1(y3, max[1]);
    }
    function fromQuadratic(x0, y0, x1, y1, x2, y2, min, max) {
        var quadraticExtremum$1 = quadraticExtremum;
        var quadraticAt$1 = quadraticAt;
        var tx = mathMax$1(mathMin$1(quadraticExtremum$1(x0, x1, x2), 1), 0);
        var ty = mathMax$1(mathMin$1(quadraticExtremum$1(y0, y1, y2), 1), 0);
        var x = quadraticAt$1(x0, x1, x2, tx);
        var y = quadraticAt$1(y0, y1, y2, ty);
        min[0] = mathMin$1(x0, x2, x);
        min[1] = mathMin$1(y0, y2, y);
        max[0] = mathMax$1(x0, x2, x);
        max[1] = mathMax$1(y0, y2, y);
    }
    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) {
            min$1[0] = x - rx;
            min$1[1] = y - ry;
            max$1[0] = x + rx;
            max$1[1] = y + ry;
            return;
        }
        start[0] = mathCos(startAngle) * rx + x;
        start[1] = mathSin(startAngle) * ry + y;
        end[0] = mathCos(endAngle) * rx + x;
        end[1] = mathSin(endAngle) * ry + y;
        vec2Min(min$1, start, end);
        vec2Max(max$1, start, end);
        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;
        }
        for (var angle = 0; angle < endAngle; angle += Math.PI / 2) {
            if (angle > startAngle) {
                extremity[0] = mathCos(angle) * rx + x;
                extremity[1] = mathSin(angle) * ry + y;
                vec2Min(min$1, extremity, min$1);
                vec2Max(max$1, extremity, max$1);
            }
        }
    }

    var CMD = {
        M: 1,
        L: 2,
        C: 3,
        Q: 4,
        A: 5,
        Z: 6,
        R: 7
    };
    var tmpOutX = [];
    var tmpOutY = [];
    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 mathAbs = Math.abs;
    var PI = Math.PI;
    var PI2$1 = PI * 2;
    var hasTypedArray = typeof Float32Array !== 'undefined';
    var tmpAngles = [];
    function modPI2(radian) {
        var n = Math.round(radian / PI * 1e8) / 1e8;
        return (n % 2) * PI;
    }
    function normalizeArcAngles(angles, anticlockwise) {
        var newStartAngle = modPI2(angles[0]);
        if (newStartAngle < 0) {
            newStartAngle += PI2$1;
        }
        var delta = newStartAngle - angles[0];
        var newEndAngle = angles[1];
        newEndAngle += delta;
        if (!anticlockwise && newEndAngle - newStartAngle >= PI2$1) {
            newEndAngle = newStartAngle + PI2$1;
        }
        else if (anticlockwise && newStartAngle - newEndAngle >= PI2$1) {
            newEndAngle = newStartAngle - PI2$1;
        }
        else if (!anticlockwise && newStartAngle > newEndAngle) {
            newEndAngle = newStartAngle + (PI2$1 - modPI2(newStartAngle - newEndAngle));
        }
        else if (anticlockwise && newStartAngle < newEndAngle) {
            newEndAngle = newStartAngle - (PI2$1 - modPI2(newEndAngle - newStartAngle));
        }
        angles[0] = newStartAngle;
        angles[1] = newEndAngle;
    }
    var PathProxy = (function () {
        function PathProxy(notSaveData) {
            this.dpr = 1;
            this._xi = 0;
            this._yi = 0;
            this._x0 = 0;
            this._y0 = 0;
            this._len = 0;
            if (notSaveData) {
                this._saveData = false;
            }
            if (this._saveData) {
                this.data = [];
            }
        }
        PathProxy.prototype.increaseVersion = function () {
            this._version++;
        };
        PathProxy.prototype.getVersion = function () {
            return this._version;
        };
        PathProxy.prototype.setScale = function (sx, sy, segmentIgnoreThreshold) {
            segmentIgnoreThreshold = segmentIgnoreThreshold || 0;
            if (segmentIgnoreThreshold > 0) {
                this._ux = mathAbs(segmentIgnoreThreshold / devicePixelRatio / sx) || 0;
                this._uy = mathAbs(segmentIgnoreThreshold / devicePixelRatio / sy) || 0;
            }
        };
        PathProxy.prototype.setDPR = function (dpr) {
            this.dpr = dpr;
        };
        PathProxy.prototype.setContext = function (ctx) {
            this._ctx = ctx;
        };
        PathProxy.prototype.getContext = function () {
            return this._ctx;
        };
        PathProxy.prototype.beginPath = function () {
            this._ctx && this._ctx.beginPath();
            this.reset();
            return this;
        };
        PathProxy.prototype.reset = function () {
            if (this._saveData) {
                this._len = 0;
            }
            if (this._pathSegLen) {
                this._pathSegLen = null;
                this._pathLen = 0;
            }
            this._version++;
        };
        PathProxy.prototype.moveTo = function (x, y) {
            this._drawPendingPt();
            this.addData(CMD.M, x, y);
            this._ctx && this._ctx.moveTo(x, y);
            this._x0 = x;
            this._y0 = y;
            this._xi = x;
            this._yi = y;
            return this;
        };
        PathProxy.prototype.lineTo = function (x, y) {
            var dx = mathAbs(x - this._xi);
            var dy = mathAbs(y - this._yi);
            var exceedUnit = dx > this._ux || dy > this._uy;
            this.addData(CMD.L, x, y);
            if (this._ctx && exceedUnit) {
                this._ctx.lineTo(x, y);
            }
            if (exceedUnit) {
                this._xi = x;
                this._yi = y;
                this._pendingPtDist = 0;
            }
            else {
                var d2 = dx * dx + dy * dy;
                if (d2 > this._pendingPtDist) {
                    this._pendingPtX = x;
                    this._pendingPtY = y;
                    this._pendingPtDist = d2;
                }
            }
            return this;
        };
        PathProxy.prototype.bezierCurveTo = function (x1, y1, x2, y2, x3, y3) {
            this._drawPendingPt();
            this.addData(CMD.C, x1, y1, x2, y2, x3, y3);
            if (this._ctx) {
                this._ctx.bezierCurveTo(x1, y1, x2, y2, x3, y3);
            }
            this._xi = x3;
            this._yi = y3;
            return this;
        };
        PathProxy.prototype.quadraticCurveTo = function (x1, y1, x2, y2) {
            this._drawPendingPt();
            this.addData(CMD.Q, x1, y1, x2, y2);
            if (this._ctx) {
                this._ctx.quadraticCurveTo(x1, y1, x2, y2);
            }
            this._xi = x2;
            this._yi = y2;
            return this;
        };
        PathProxy.prototype.arc = function (cx, cy, r, startAngle, endAngle, anticlockwise) {
            this._drawPendingPt();
            tmpAngles[0] = startAngle;
            tmpAngles[1] = endAngle;
            normalizeArcAngles(tmpAngles, anticlockwise);
            startAngle = tmpAngles[0];
            endAngle = tmpAngles[1];
            var delta = endAngle - startAngle;
            this.addData(CMD.A, cx, cy, r, r, startAngle, delta, 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;
        };
        PathProxy.prototype.arcTo = function (x1, y1, x2, y2, radius) {
            this._drawPendingPt();
            if (this._ctx) {
                this._ctx.arcTo(x1, y1, x2, y2, radius);
            }
            return this;
        };
        PathProxy.prototype.rect = function (x, y, w, h) {
            this._drawPendingPt();
            this._ctx && this._ctx.rect(x, y, w, h);
            this.addData(CMD.R, x, y, w, h);
            return this;
        };
        PathProxy.prototype.closePath = function () {
            this._drawPendingPt();
            this.addData(CMD.Z);
            var ctx = this._ctx;
            var x0 = this._x0;
            var y0 = this._y0;
            if (ctx) {
                ctx.closePath();
            }
            this._xi = x0;
            this._yi = y0;
            return this;
        };
        PathProxy.prototype.fill = function (ctx) {
            ctx && ctx.fill();
            this.toStatic();
        };
        PathProxy.prototype.stroke = function (ctx) {
            ctx && ctx.stroke();
            this.toStatic();
        };
        PathProxy.prototype.len = function () {
            return this._len;
        };
        PathProxy.prototype.setData = function (data) {
            var len = data.length;
            if (!(this.data && this.data.length === len) && hasTypedArray) {
                this.data = new Float32Array(len);
            }
            for (var i = 0; i < len; i++) {
                this.data[i] = data[i];
            }
            this._len = len;
        };
        PathProxy.prototype.appendPath = function (path) {
            if (!(path instanceof Array)) {
                path = [path];
            }
            var len = path.length;
            var appendSize = 0;
            var offset = this._len;
            for (var i = 0; i < len; i++) {
                appendSize += path[i].len();
            }
            if (hasTypedArray && (this.data instanceof Float32Array)) {
                this.data = new Float32Array(offset + appendSize);
            }
            for (var i = 0; i < len; i++) {
                var appendPathData = path[i].data;
                for (var k = 0; k < appendPathData.length; k++) {
                    this.data[offset++] = appendPathData[k];
                }
            }
            this._len = offset;
        };
        PathProxy.prototype.addData = function (cmd, a, b, c, d, e, f, g, h) {
            if (!this._saveData) {
                return;
            }
            var data = this.data;
            if (this._len + arguments.length > data.length) {
                this._expandData();
                data = this.data;
            }
            for (var i = 0; i < arguments.length; i++) {
                data[this._len++] = arguments[i];
            }
        };
        PathProxy.prototype._drawPendingPt = function () {
            if (this._pendingPtDist > 0) {
                this._ctx && this._ctx.lineTo(this._pendingPtX, this._pendingPtY);
                this._pendingPtDist = 0;
            }
        };
        PathProxy.prototype._expandData = function () {
            if (!(this.data instanceof Array)) {
                var newData = [];
                for (var i = 0; i < this._len; i++) {
                    newData[i] = this.data[i];
                }
                this.data = newData;
            }
        };
        PathProxy.prototype.toStatic = function () {
            if (!this._saveData) {
                return;
            }
            this._drawPendingPt();
            var data = this.data;
            if (data instanceof Array) {
                data.length = this._len;
                if (hasTypedArray && this._len > 11) {
                    this.data = new Float32Array(data);
                }
            }
        };
        PathProxy.prototype.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;
            var i;
            for (i = 0; i < this._len;) {
                var cmd = data[i++];
                var isFirst = i === 1;
                if (isFirst) {
                    xi = data[i];
                    yi = data[i + 1];
                    x0 = xi;
                    y0 = yi;
                }
                switch (cmd) {
                    case CMD.M:
                        xi = x0 = data[i++];
                        yi = y0 = data[i++];
                        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:
                        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;
                        i += 1;
                        var anticlockwise = !data[i++];
                        if (isFirst) {
                            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++];
                        fromLine(x0, y0, x0 + width, y0 + height, min2, max2);
                        break;
                    case CMD.Z:
                        xi = x0;
                        yi = y0;
                        break;
                }
                min(min$1, min$1, min2);
                max(max$1, max$1, max2);
            }
            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]);
        };
        PathProxy.prototype._calculateLength = function () {
            var data = this.data;
            var len = this._len;
            var ux = this._ux;
            var uy = this._uy;
            var xi = 0;
            var yi = 0;
            var x0 = 0;
            var y0 = 0;
            if (!this._pathSegLen) {
                this._pathSegLen = [];
            }
            var pathSegLen = this._pathSegLen;
            var pathTotalLen = 0;
            var segCount = 0;
            for (var i = 0; i < len;) {
                var cmd = data[i++];
                var isFirst = i === 1;
                if (isFirst) {
                    xi = data[i];
                    yi = data[i + 1];
                    x0 = xi;
                    y0 = yi;
                }
                var l = -1;
                switch (cmd) {
                    case CMD.M:
                        xi = x0 = data[i++];
                        yi = y0 = data[i++];
                        break;
                    case CMD.L: {
                        var x2 = data[i++];
                        var y2 = data[i++];
                        var dx = x2 - xi;
                        var dy = y2 - yi;
                        if (mathAbs(dx) > ux || mathAbs(dy) > uy || i === len - 1) {
                            l = Math.sqrt(dx * dx + dy * dy);
                            xi = x2;
                            yi = y2;
                        }
                        break;
                    }
                    case CMD.C: {
                        var x1 = data[i++];
                        var y1 = data[i++];
                        var x2 = data[i++];
                        var y2 = data[i++];
                        var x3 = data[i++];
                        var y3 = data[i++];
                        l = cubicLength(xi, yi, x1, y1, x2, y2, x3, y3, 10);
                        xi = x3;
                        yi = y3;
                        break;
                    }
                    case CMD.Q: {
                        var x1 = data[i++];
                        var y1 = data[i++];
                        var x2 = data[i++];
                        var y2 = data[i++];
                        l = quadraticLength(xi, yi, x1, y1, x2, y2, 10);
                        xi = x2;
                        yi = y2;
                        break;
                    }
                    case CMD.A:
                        var cx = data[i++];
                        var cy = data[i++];
                        var rx = data[i++];
                        var ry = data[i++];
                        var startAngle = data[i++];
                        var delta = data[i++];
                        var endAngle = delta + startAngle;
                        i += 1;
                        var anticlockwise = !data[i++];
                        if (isFirst) {
                            x0 = mathCos$1(startAngle) * rx + cx;
                            y0 = mathSin$1(startAngle) * ry + cy;
                        }
                        l = mathMax$2(rx, ry) * mathMin$2(PI2$1, Math.abs(delta));
                        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++];
                        l = width * 2 + height * 2;
                        break;
                    }
                    case CMD.Z: {
                        var dx = x0 - xi;
                        var dy = y0 - yi;
                        l = Math.sqrt(dx * dx + dy * dy);
                        xi = x0;
                        yi = y0;
                        break;
                    }
                }
                if (l >= 0) {
                    pathSegLen[segCount++] = l;
                    pathTotalLen += l;
                }
            }
            this._pathLen = pathTotalLen;
            return pathTotalLen;
        };
        PathProxy.prototype.rebuildPath = function (ctx, percent) {
            var d = this.data;
            var ux = this._ux;
            var uy = this._uy;
            var len = this._len;
            var x0;
            var y0;
            var xi;
            var yi;
            var x;
            var y;
            var drawPart = percent < 1;
            var pathSegLen;
            var pathTotalLen;
            var accumLength = 0;
            var segCount = 0;
            var displayedLength;
            var pendingPtDist = 0;
            var pendingPtX;
            var pendingPtY;
            if (drawPart) {
                if (!this._pathSegLen) {
                    this._calculateLength();
                }
                pathSegLen = this._pathSegLen;
                pathTotalLen = this._pathLen;
                displayedLength = percent * pathTotalLen;
                if (!displayedLength) {
                    return;
                }
            }
            lo: for (var i = 0; i < len;) {
                var cmd = d[i++];
                var isFirst = i === 1;
                if (isFirst) {
                    xi = d[i];
                    yi = d[i + 1];
                    x0 = xi;
                    y0 = yi;
                }
                if (cmd !== CMD.L && pendingPtDist > 0) {
                    ctx.lineTo(pendingPtX, pendingPtY);
                    pendingPtDist = 0;
                }
                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++];
                        var dx = mathAbs(x - xi);
                        var dy = mathAbs(y - yi);
                        if (dx > ux || dy > uy) {
                            if (drawPart) {
                                var l = pathSegLen[segCount++];
                                if (accumLength + l > displayedLength) {
                                    var t = (displayedLength - accumLength) / l;
                                    ctx.lineTo(xi * (1 - t) + x * t, yi * (1 - t) + y * t);
                                    break lo;
                                }
                                accumLength += l;
                            }
                            ctx.lineTo(x, y);
                            xi = x;
                            yi = y;
                            pendingPtDist = 0;
                        }
                        else {
                            var d2 = dx * dx + dy * dy;
                            if (d2 > pendingPtDist) {
                                pendingPtX = x;
                                pendingPtY = y;
                                pendingPtDist = d2;
                            }
                        }
                        break;
                    }
                    case CMD.C: {
                        var x1 = d[i++];
                        var y1 = d[i++];
                        var x2 = d[i++];
                        var y2 = d[i++];
                        var x3 = d[i++];
                        var y3 = d[i++];
                        if (drawPart) {
                            var l = pathSegLen[segCount++];
                            if (accumLength + l > displayedLength) {
                                var t = (displayedLength - accumLength) / l;
                                cubicSubdivide(xi, x1, x2, x3, t, tmpOutX);
                                cubicSubdivide(yi, y1, y2, y3, t, tmpOutY);
                                ctx.bezierCurveTo(tmpOutX[1], tmpOutY[1], tmpOutX[2], tmpOutY[2], tmpOutX[3], tmpOutY[3]);
                                break lo;
                            }
                            accumLength += l;
                        }
                        ctx.bezierCurveTo(x1, y1, x2, y2, x3, y3);
                        xi = x3;
                        yi = y3;
                        break;
                    }
                    case CMD.Q: {
                        var x1 = d[i++];
                        var y1 = d[i++];
                        var x2 = d[i++];
                        var y2 = d[i++];
                        if (drawPart) {
                            var l = pathSegLen[segCount++];
                            if (accumLength + l > displayedLength) {
                                var t = (displayedLength - accumLength) / l;
                                quadraticSubdivide(xi, x1, x2, t, tmpOutX);
                                quadraticSubdivide(yi, y1, y2, t, tmpOutY);
                                ctx.quadraticCurveTo(tmpOutX[1], tmpOutY[1], tmpOutX[2], tmpOutY[2]);
                                break lo;
                            }
                            accumLength += l;
                        }
                        ctx.quadraticCurveTo(x1, y1, x2, y2);
                        xi = x2;
                        yi = y2;
                        break;
                    }
                    case CMD.A:
                        var cx = d[i++];
                        var cy = d[i++];
                        var rx = d[i++];
                        var ry = d[i++];
                        var startAngle = d[i++];
                        var delta = d[i++];
                        var psi = d[i++];
                        var anticlockwise = !d[i++];
                        var r = (rx > ry) ? rx : ry;
                        var isEllipse = mathAbs(rx - ry) > 1e-3;
                        var endAngle = startAngle + delta;
                        var breakBuild = false;
                        if (drawPart) {
                            var l = pathSegLen[segCount++];
                            if (accumLength + l > displayedLength) {
                                endAngle = startAngle + delta * (displayedLength - accumLength) / l;
                                breakBuild = true;
                            }
                            accumLength += l;
                        }
                        if (isEllipse && ctx.ellipse) {
                            ctx.ellipse(cx, cy, rx, ry, psi, startAngle, endAngle, anticlockwise);
                        }
                        else {
                            ctx.arc(cx, cy, r, startAngle, endAngle, anticlockwise);
                        }
                        if (breakBuild) {
                            break lo;
                        }
                        if (isFirst) {
                            x0 = mathCos$1(startAngle) * rx + cx;
                            y0 = mathSin$1(startAngle) * 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];
                        x = d[i++];
                        y = d[i++];
                        var width = d[i++];
                        var height = d[i++];
                        if (drawPart) {
                            var l = pathSegLen[segCount++];
                            if (accumLength + l > displayedLength) {
                                var d_1 = displayedLength - accumLength;
                                ctx.moveTo(x, y);
                                ctx.lineTo(x + mathMin$2(d_1, width), y);
                                d_1 -= width;
                                if (d_1 > 0) {
                                    ctx.lineTo(x + width, y + mathMin$2(d_1, height));
                                }
                                d_1 -= height;
                                if (d_1 > 0) {
                                    ctx.lineTo(x + mathMax$2(width - d_1, 0), y + height);
                                }
                                d_1 -= width;
                                if (d_1 > 0) {
                                    ctx.lineTo(x, y + mathMax$2(height - d_1, 0));
                                }
                                break lo;
                            }
                            accumLength += l;
                        }
                        ctx.rect(x, y, width, height);
                        break;
                    case CMD.Z:
                        if (drawPart) {
                            var l = pathSegLen[segCount++];
                            if (accumLength + l > displayedLength) {
                                var t = (displayedLength - accumLength) / l;
                                ctx.lineTo(xi * (1 - t) + x0 * t, yi * (1 - t) + y0 * t);
                                break lo;
                            }
                            accumLength += l;
                        }
                        ctx.closePath();
                        xi = x0;
                        yi = y0;
                }
            }
        };
        PathProxy.prototype.clone = function () {
            var newProxy = new PathProxy();
            var data = this.data;
            newProxy.data = data.slice ? data.slice()
                : Array.prototype.slice.call(data);
            newProxy._len = this._len;
            return newProxy;
        };
        PathProxy.CMD = CMD;
        PathProxy.initDefaultProps = (function () {
            var proto = PathProxy.prototype;
            proto._saveData = true;
            proto._ux = 0;
            proto._uy = 0;
            proto._pendingPtDist = 0;
            proto._version = 0;
        })();
        return PathProxy;
    }());

    function containStroke(x0, y0, x1, y1, lineWidth, x, y) {
        if (lineWidth === 0) {
            return false;
        }
        var _l = lineWidth;
        var _a = 0;
        var _b = x0;
        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;
    }

    function containStroke$1(x0, y0, x1, y1, x2, y2, x3, y3, lineWidth, x, y) {
        if (lineWidth === 0) {
            return false;
        }
        var _l = lineWidth;
        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;
    }

    function containStroke$2(x0, y0, x1, y1, x2, y2, lineWidth, x, y) {
        if (lineWidth === 0) {
            return false;
        }
        var _l = lineWidth;
        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$2 = Math.PI * 2;
    function normalizeRadian(angle) {
        angle %= PI2$2;
        if (angle < 0) {
            angle += PI2$2;
        }
        return angle;
    }

    var PI2$3 = Math.PI * 2;
    function containStroke$3(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$3 < 1e-4) {
            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$3;
        }
        var angle = Math.atan2(y, x);
        if (angle < 0) {
            angle += PI2$3;
        }
        return (angle >= startAngle && angle <= endAngle)
            || (angle + PI2$3 >= startAngle && angle + PI2$3 <= endAngle);
    }

    function windingLine(x0, y0, x1, y1, x, y) {
        if ((y > y0 && y > y1) || (y < y0 && y < y1)) {
            return 0;
        }
        if (y1 === y0) {
            return 0;
        }
        var t = (y - y0) / (y1 - y0);
        var dir = y1 < y0 ? 1 : -1;
        if (t === 1 || t === 0) {
            dir = y1 < y0 ? 0.5 : -0.5;
        }
        var x_ = t * (x1 - x0) + x0;
        return x_ === x ? Infinity : x_ > x ? dir : 0;
    }

    var CMD$1 = PathProxy.CMD;
    var PI2$4 = Math.PI * 2;
    var EPSILON$3 = 1e-4;
    function isAroundEqual(a, b) {
        return Math.abs(a - b) < EPSILON$3;
    }
    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) {
        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_ = void 0;
            var y1_ = void 0;
            for (var i = 0; i < nRoots; i++) {
                var t = roots[i];
                var unit = (t === 0 || t === 1) ? 0.5 : 1;
                var x_ = cubicAt(x0, x1, x2, x3, t);
                if (x_ < x) {
                    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) {
        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++) {
                    var unit = (roots[i] === 0 || roots[i] === 1) ? 0.5 : 1;
                    var x_ = quadraticAt(x0, x1, x2, roots[i]);
                    if (x_ < x) {
                        continue;
                    }
                    if (roots[i] < t) {
                        w += y_ < y0 ? unit : -unit;
                    }
                    else {
                        w += y2 < y_ ? unit : -unit;
                    }
                }
                return w;
            }
            else {
                var unit = (roots[0] === 0 || roots[0] === 1) ? 0.5 : 1;
                var x_ = quadraticAt(x0, x1, x2, roots[0]);
                if (x_ < x) {
                    return 0;
                }
                return y2 < y0 ? unit : -unit;
            }
        }
    }
    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 dTheta = Math.abs(startAngle - endAngle);
        if (dTheta < 1e-4) {
            return 0;
        }
        if (dTheta >= PI2$4 - 1e-4) {
            startAngle = 0;
            endAngle = PI2$4;
            var dir = anticlockwise ? 1 : -1;
            if (x >= roots[0] + cx && x <= roots[1] + cx) {
                return dir;
            }
            else {
                return 0;
            }
        }
        if (startAngle > endAngle) {
            var tmp_1 = startAngle;
            startAngle = endAngle;
            endAngle = tmp_1;
        }
        if (startAngle < 0) {
            startAngle += PI2$4;
            endAngle += PI2$4;
        }
        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$4 + angle;
                }
                if ((angle >= startAngle && angle <= endAngle)
                    || (angle + PI2$4 >= startAngle && angle + PI2$4 <= endAngle)) {
                    if (angle > Math.PI / 2 && angle < Math.PI * 1.5) {
                        dir = -dir;
                    }
                    w += dir;
                }
            }
        }
        return w;
    }
    function containPath(path, lineWidth, isStroke, x, y) {
        var data = path.data;
        var len = path.len();
        var w = 0;
        var xi = 0;
        var yi = 0;
        var x0 = 0;
        var y0 = 0;
        var x1;
        var y1;
        for (var i = 0; i < len;) {
            var cmd = data[i++];
            var isFirst = i === 1;
            if (cmd === CMD$1.M && i > 1) {
                if (!isStroke) {
                    w += windingLine(xi, yi, x0, y0, x, y);
                }
            }
            if (isFirst) {
                xi = data[i];
                yi = data[i + 1];
                x0 = xi;
                y0 = yi;
            }
            switch (cmd) {
                case CMD$1.M:
                    x0 = data[i++];
                    y0 = data[i++];
                    xi = x0;
                    yi = y0;
                    break;
                case CMD$1.L:
                    if (isStroke) {
                        if (containStroke(xi, yi, data[i], data[i + 1], lineWidth, x, y)) {
                            return true;
                        }
                    }
                    else {
                        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$1(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$2(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:
                    var cx = data[i++];
                    var cy = data[i++];
                    var rx = data[i++];
                    var ry = data[i++];
                    var theta = data[i++];
                    var dTheta = data[i++];
                    i += 1;
                    var anticlockwise = !!(1 - data[i++]);
                    x1 = Math.cos(theta) * rx + cx;
                    y1 = Math.sin(theta) * ry + cy;
                    if (!isFirst) {
                        w += windingLine(xi, yi, x1, y1, x, y);
                    }
                    else {
                        x0 = x1;
                        y0 = y1;
                    }
                    var _x = (x - cx) * ry / rx + cx;
                    if (isStroke) {
                        if (containStroke$3(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++];
                    x1 = x0 + width;
                    y1 = y0 + height;
                    if (isStroke) {
                        if (containStroke(x0, y0, x1, y0, lineWidth, x, y)
                            || containStroke(x1, y0, x1, y1, lineWidth, x, y)
                            || containStroke(x1, y1, x0, y1, lineWidth, x, y)
                            || containStroke(x0, y1, x0, y0, lineWidth, x, y)) {
                            return true;
                        }
                    }
                    else {
                        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(xi, yi, x0, y0, lineWidth, x, y)) {
                            return true;
                        }
                    }
                    else {
                        w += windingLine(xi, yi, x0, y0, x, y);
                    }
                    xi = x0;
                    yi = y0;
                    break;
            }
        }
        if (!isStroke && !isAroundEqual(yi, y0)) {
            w += windingLine(xi, yi, x0, y0, x, y) || 0;
        }
        return w !== 0;
    }
    function contain(pathProxy, x, y) {
        return containPath(pathProxy, 0, false, x, y);
    }
    function containStroke$4(pathProxy, lineWidth, x, y) {
        return containPath(pathProxy, lineWidth, true, x, y);
    }

    var DEFAULT_PATH_STYLE = defaults({
        fill: '#000',
        stroke: null,
        strokePercent: 1,
        fillOpacity: 1,
        strokeOpacity: 1,
        lineDashOffset: 0,
        lineWidth: 1,
        lineCap: 'butt',
        miterLimit: 10,
        strokeNoScale: false,
        strokeFirst: false
    }, DEFAULT_COMMON_STYLE);
    var DEFAULT_PATH_ANIMATION_PROPS = {
        style: defaults({
            fill: true,
            stroke: true,
            strokePercent: true,
            fillOpacity: true,
            strokeOpacity: true,
            lineDashOffset: true,
            lineWidth: true,
            miterLimit: true
        }, DEFAULT_COMMON_ANIMATION_PROPS.style)
    };
    var pathCopyParams = TRANSFORMABLE_PROPS.concat(['invisible',
        'culling', 'z', 'z2', 'zlevel', 'parent'
    ]);
    var Path = (function (_super) {
        __extends(Path, _super);
        function Path(opts) {
            return _super.call(this, opts) || this;
        }
        Path.prototype.update = function () {
            var _this = this;
            _super.prototype.update.call(this);
            var style = this.style;
            if (style.decal) {
                var decalEl = this._decalEl = this._decalEl || new Path();
                if (decalEl.buildPath === Path.prototype.buildPath) {
                    decalEl.buildPath = function (ctx) {
                        _this.buildPath(ctx, _this.shape);
                    };
                }
                decalEl.silent = true;
                var decalElStyle = decalEl.style;
                for (var key in style) {
                    if (decalElStyle[key] !== style[key]) {
                        decalElStyle[key] = style[key];
                    }
                }
                decalElStyle.fill = style.fill ? style.decal : null;
                decalElStyle.decal = null;
                decalElStyle.shadowColor = null;
                style.strokeFirst && (decalElStyle.stroke = null);
                for (var i = 0; i < pathCopyParams.length; ++i) {
                    decalEl[pathCopyParams[i]] = this[pathCopyParams[i]];
                }
                decalEl.__dirty |= REDRAW_BIT;
            }
            else if (this._decalEl) {
                this._decalEl = null;
            }
        };
        Path.prototype.getDecalElement = function () {
            return this._decalEl;
        };
        Path.prototype._init = function (props) {
            var keysArr = keys(props);
            this.shape = this.getDefaultShape();
            var defaultStyle = this.getDefaultStyle();
            if (defaultStyle) {
                this.useStyle(defaultStyle);
            }
            for (var i = 0; i < keysArr.length; i++) {
                var key = keysArr[i];
                var value = props[key];
                if (key === 'style') {
                    if (!this.style) {
                        this.useStyle(value);
                    }
                    else {
                        extend(this.style, value);
                    }
                }
                else if (key === 'shape') {
                    extend(this.shape, value);
                }
                else {
                    _super.prototype.attrKV.call(this, key, value);
                }
            }
            if (!this.style) {
                this.useStyle({});
            }
        };
        Path.prototype.getDefaultStyle = function () {
            return null;
        };
        Path.prototype.getDefaultShape = function () {
            return {};
        };
        Path.prototype.canBeInsideText = function () {
            return this.hasFill();
        };
        Path.prototype.getInsideTextFill = function () {
            var pathFill = this.style.fill;
            if (pathFill !== 'none') {
                if (isString(pathFill)) {
                    var fillLum = lum(pathFill, 0);
                    if (fillLum > 0.5) {
                        return DARK_LABEL_COLOR;
                    }
                    else if (fillLum > 0.2) {
                        return LIGHTER_LABEL_COLOR;
                    }
                    return LIGHT_LABEL_COLOR;
                }
                else if (pathFill) {
                    return LIGHT_LABEL_COLOR;
                }
            }
            return DARK_LABEL_COLOR;
        };
        Path.prototype.getInsideTextStroke = function (textFill) {
            var pathFill = this.style.fill;
            if (isString(pathFill)) {
                var zr = this.__zr;
                var isDarkMode = !!(zr && zr.isDarkMode());
                var isDarkLabel = lum(textFill, 0) < DARK_MODE_THRESHOLD;
                if (isDarkMode === isDarkLabel) {
                    return pathFill;
                }
            }
        };
        Path.prototype.buildPath = function (ctx, shapeCfg, inBatch) { };
        Path.prototype.pathUpdated = function () {
            this.__dirty &= ~SHAPE_CHANGED_BIT;
        };
        Path.prototype.getUpdatedPathProxy = function (inBatch) {
            !this.path && this.createPathProxy();
            this.path.beginPath();
            this.buildPath(this.path, this.shape, inBatch);
            return this.path;
        };
        Path.prototype.createPathProxy = function () {
            this.path = new PathProxy(false);
        };
        Path.prototype.hasStroke = function () {
            var style = this.style;
            var stroke = style.stroke;
            return !(stroke == null || stroke === 'none' || !(style.lineWidth > 0));
        };
        Path.prototype.hasFill = function () {
            var style = this.style;
            var fill = style.fill;
            return fill != null && fill !== 'none';
        };
        Path.prototype.getBoundingRect = function () {
            var rect = this._rect;
            var style = this.style;
            var needsUpdateRect = !rect;
            if (needsUpdateRect) {
                var firstInvoke = false;
                if (!this.path) {
                    firstInvoke = true;
                    this.createPathProxy();
                }
                var path = this.path;
                if (firstInvoke || (this.__dirty & SHAPE_CHANGED_BIT)) {
                    path.beginPath();
                    this.buildPath(path, this.shape, false);
                    this.pathUpdated();
                }
                rect = path.getBoundingRect();
            }
            this._rect = rect;
            if (this.hasStroke() && this.path && this.path.len() > 0) {
                var rectStroke = this._rectStroke || (this._rectStroke = rect.clone());
                if (this.__dirty || needsUpdateRect) {
                    rectStroke.copy(rect);
                    var lineScale = style.strokeNoScale ? this.getLineScale() : 1;
                    var w = style.lineWidth;
                    if (!this.hasFill()) {
                        var strokeContainThreshold = this.strokeContainThreshold;
                        w = Math.max(w, strokeContainThreshold == null ? 4 : strokeContainThreshold);
                    }
                    if (lineScale > 1e-10) {
                        rectStroke.width += w / lineScale;
                        rectStroke.height += w / lineScale;
                        rectStroke.x -= w / lineScale / 2;
                        rectStroke.y -= w / lineScale / 2;
                    }
                }
                return rectStroke;
            }
            return rect;
        };
        Path.prototype.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 pathProxy = this.path;
                if (this.hasStroke()) {
                    var lineWidth = style.lineWidth;
                    var lineScale = style.strokeNoScale ? this.getLineScale() : 1;
                    if (lineScale > 1e-10) {
                        if (!this.hasFill()) {
                            lineWidth = Math.max(lineWidth, this.strokeContainThreshold);
                        }
                        if (containStroke$4(pathProxy, lineWidth / lineScale, x, y)) {
                            return true;
                        }
                    }
                }
                if (this.hasFill()) {
                    return contain(pathProxy, x, y);
                }
            }
            return false;
        };
        Path.prototype.dirtyShape = function () {
            this.__dirty |= SHAPE_CHANGED_BIT;
            if (this._rect) {
                this._rect = null;
            }
            if (this._decalEl) {
                this._decalEl.dirtyShape();
            }
            this.markRedraw();
        };
        Path.prototype.dirty = function () {
            this.dirtyStyle();
            this.dirtyShape();
        };
        Path.prototype.animateShape = function (loop) {
            return this.animate('shape', loop);
        };
        Path.prototype.updateDuringAnimation = function (targetKey) {
            if (targetKey === 'style') {
                this.dirtyStyle();
            }
            else if (targetKey === 'shape') {
                this.dirtyShape();
            }
            else {
                this.markRedraw();
            }
        };
        Path.prototype.attrKV = function (key, value) {
            if (key === 'shape') {
                this.setShape(value);
            }
            else {
                _super.prototype.attrKV.call(this, key, value);
            }
        };
        Path.prototype.setShape = function (keyOrObj, value) {
            var shape = this.shape;
            if (!shape) {
                shape = this.shape = {};
            }
            if (typeof keyOrObj === 'string') {
                shape[keyOrObj] = value;
            }
            else {
                extend(shape, keyOrObj);
            }
            this.dirtyShape();
            return this;
        };
        Path.prototype.shapeChanged = function () {
            return !!(this.__dirty & SHAPE_CHANGED_BIT);
        };
        Path.prototype.createStyle = function (obj) {
            return createObject(DEFAULT_PATH_STYLE, obj);
        };
        Path.prototype._innerSaveToNormal = function (toState) {
            _super.prototype._innerSaveToNormal.call(this, toState);
            var normalState = this._normalState;
            if (toState.shape && !normalState.shape) {
                normalState.shape = extend({}, this.shape);
            }
        };
        Path.prototype._applyStateObj = function (stateName, state, normalState, keepCurrentStates, transition, animationCfg) {
            _super.prototype._applyStateObj.call(this, stateName, state, normalState, keepCurrentStates, transition, animationCfg);
            var needsRestoreToNormal = !(state && keepCurrentStates);
            var targetShape;
            if (state && state.shape) {
                if (transition) {
                    if (keepCurrentStates) {
                        targetShape = state.shape;
                    }
                    else {
                        targetShape = extend({}, normalState.shape);
                        extend(targetShape, state.shape);
                    }
                }
                else {
                    targetShape = extend({}, keepCurrentStates ? this.shape : normalState.shape);
                    extend(targetShape, state.shape);
                }
            }
            else if (needsRestoreToNormal) {
                targetShape = normalState.shape;
            }
            if (targetShape) {
                if (transition) {
                    this.shape = extend({}, this.shape);
                    var targetShapePrimaryProps = {};
                    var shapeKeys = keys(targetShape);
                    for (var i = 0; i < shapeKeys.length; i++) {
                        var key = shapeKeys[i];
                        if (typeof targetShape[key] === 'object') {
                            this.shape[key] = targetShape[key];
                        }
                        else {
                            targetShapePrimaryProps[key] = targetShape[key];
                        }
                    }
                    this._transitionState(stateName, {
                        shape: targetShapePrimaryProps
                    }, animationCfg);
                }
                else {
                    this.shape = targetShape;
                    this.dirtyShape();
                }
            }
        };
        Path.prototype._mergeStates = function (states) {
            var mergedState = _super.prototype._mergeStates.call(this, states);
            var mergedShape;
            for (var i = 0; i < states.length; i++) {
                var state = states[i];
                if (state.shape) {
                    mergedShape = mergedShape || {};
                    this._mergeStyle(mergedShape, state.shape);
                }
            }
            if (mergedShape) {
                mergedState.shape = mergedShape;
            }
            return mergedState;
        };
        Path.prototype.getAnimationStyleProps = function () {
            return DEFAULT_PATH_ANIMATION_PROPS;
        };
        Path.prototype.isZeroArea = function () {
            return false;
        };
        Path.extend = function (defaultProps) {
            var Sub = (function (_super) {
                __extends(Sub, _super);
                function Sub(opts) {
                    var _this = _super.call(this, opts) || this;
                    defaultProps.init && defaultProps.init.call(_this, opts);
                    return _this;
                }
                Sub.prototype.getDefaultStyle = function () {
                    return clone(defaultProps.style);
                };
                Sub.prototype.getDefaultShape = function () {
                    return clone(defaultProps.shape);
                };
                return Sub;
            }(Path));
            for (var key in defaultProps) {
                if (typeof defaultProps[key] === 'function') {
                    Sub.prototype[key] = defaultProps[key];
                }
            }
            return Sub;
        };
        Path.initDefaultProps = (function () {
            var pathProto = Path.prototype;
            pathProto.type = 'path';
            pathProto.strokeContainThreshold = 5;
            pathProto.segmentIgnoreThreshold = 0;
            pathProto.subPixelOptimize = false;
            pathProto.autoBatch = false;
            pathProto.__dirty = REDRAW_BIT | STYLE_CHANGED_BIT | SHAPE_CHANGED_BIT;
        })();
        return Path;
    }(Displayable));

    var DEFAULT_TSPAN_STYLE = defaults({
        strokeFirst: true,
        font: DEFAULT_FONT,
        x: 0,
        y: 0,
        textAlign: 'left',
        textBaseline: 'top',
        miterLimit: 2
    }, DEFAULT_PATH_STYLE);
    var TSpan = (function (_super) {
        __extends(TSpan, _super);
        function TSpan() {
            return _super !== null && _super.apply(this, arguments) || this;
        }
        TSpan.prototype.hasStroke = function () {
            var style = this.style;
            var stroke = style.stroke;
            return stroke != null && stroke !== 'none' && style.lineWidth > 0;
        };
        TSpan.prototype.hasFill = function () {
            var style = this.style;
            var fill = style.fill;
            return fill != null && fill !== 'none';
        };
        TSpan.prototype.createStyle = function (obj) {
            return createObject(DEFAULT_TSPAN_STYLE, obj);
        };
        TSpan.prototype.setBoundingRect = function (rect) {
            this._rect = rect;
        };
        TSpan.prototype.getBoundingRect = function () {
            var style = this.style;
            if (!this._rect) {
                var text = style.text;
                text != null ? (text += '') : (text = '');
                var rect = getBoundingRect(text, style.font, style.textAlign, style.textBaseline);
                rect.x += style.x || 0;
                rect.y += style.y || 0;
                if (this.hasStroke()) {
                    var w = style.lineWidth;
                    rect.x -= w / 2;
                    rect.y -= w / 2;
                    rect.width += w;
                    rect.height += w;
                }
                this._rect = rect;
            }
            return this._rect;
        };
        TSpan.initDefaultProps = (function () {
            var tspanProto = TSpan.prototype;
            tspanProto.dirtyRectTolerance = 10;
        })();
        return TSpan;
    }(Displayable));
    TSpan.prototype.type = 'tspan';

    var DEFAULT_IMAGE_STYLE = defaults({
        x: 0,
        y: 0
    }, DEFAULT_COMMON_STYLE);
    var DEFAULT_IMAGE_ANIMATION_PROPS = {
        style: defaults({
            x: true,
            y: true,
            width: true,
            height: true,
            sx: true,
            sy: true,
            sWidth: true,
            sHeight: true
        }, DEFAULT_COMMON_ANIMATION_PROPS.style)
    };
    function isImageLike(source) {
        return !!(source
            && typeof source !== 'string'
            && source.width && source.height);
    }
    var ZRImage = (function (_super) {
        __extends(ZRImage, _super);
        function ZRImage() {
            return _super !== null && _super.apply(this, arguments) || this;
        }
        ZRImage.prototype.createStyle = function (obj) {
            return createObject(DEFAULT_IMAGE_STYLE, obj);
        };
        ZRImage.prototype._getSize = function (dim) {
            var style = this.style;
            var size = style[dim];
            if (size != null) {
                return size;
            }
            var imageSource = isImageLike(style.image)
                ? style.image : this.__image;
            if (!imageSource) {
                return 0;
            }
            var otherDim = dim === 'width' ? 'height' : 'width';
            var otherDimSize = style[otherDim];
            if (otherDimSize == null) {
                return imageSource[dim];
            }
            else {
                return imageSource[dim] / imageSource[otherDim] * otherDimSize;
            }
        };
        ZRImage.prototype.getWidth = function () {
            return this._getSize('width');
        };
        ZRImage.prototype.getHeight = function () {
            return this._getSize('height');
        };
        ZRImage.prototype.getAnimationStyleProps = function () {
            return DEFAULT_IMAGE_ANIMATION_PROPS;
        };
        ZRImage.prototype.getBoundingRect = function () {
            var style = this.style;
            if (!this._rect) {
                this._rect = new BoundingRect(style.x || 0, style.y || 0, this.getWidth(), this.getHeight());
            }
            return this._rect;
        };
        return ZRImage;
    }(Displayable));
    ZRImage.prototype.type = 'image';

    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;
        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 round$1 = Math.round;
    function subPixelOptimizeLine(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 outputShape;
        }
        if (round$1(x1 * 2) === round$1(x2 * 2)) {
            outputShape.x1 = outputShape.x2 = subPixelOptimize(x1, lineWidth, true);
        }
        if (round$1(y1 * 2) === round$1(y2 * 2)) {
            outputShape.y1 = outputShape.y2 = subPixelOptimize(y1, lineWidth, true);
        }
        return outputShape;
    }
    function subPixelOptimizeRect(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;
        }
        outputShape.x = subPixelOptimize(originX, lineWidth, true);
        outputShape.y = subPixelOptimize(originY, lineWidth, true);
        outputShape.width = Math.max(subPixelOptimize(originX + originWidth, lineWidth, false) - outputShape.x, originWidth === 0 ? 0 : 1);
        outputShape.height = Math.max(subPixelOptimize(originY + originHeight, lineWidth, false) - outputShape.y, originHeight === 0 ? 0 : 1);
        return outputShape;
    }
    function subPixelOptimize(position, lineWidth, positiveOrNegative) {
        if (!lineWidth) {
            return position;
        }
        var doubledPosition = round$1(position * 2);
        return (doubledPosition + round$1(lineWidth)) % 2 === 0
            ? doubledPosition / 2
            : (doubledPosition + (positiveOrNegative ? 1 : -1)) / 2;
    }

    var RectShape = (function () {
        function RectShape() {
            this.x = 0;
            this.y = 0;
            this.width = 0;
            this.height = 0;
        }
        return RectShape;
    }());
    var subPixelOptimizeOutputShape = {};
    var Rect = (function (_super) {
        __extends(Rect, _super);
        function Rect(opts) {
            return _super.call(this, opts) || this;
        }
        Rect.prototype.getDefaultShape = function () {
            return new RectShape();
        };
        Rect.prototype.buildPath = function (ctx, shape) {
            var x;
            var y;
            var width;
            var height;
            if (this.subPixelOptimize) {
                var optimizedShape = subPixelOptimizeRect(subPixelOptimizeOutputShape, shape, this.style);
                x = optimizedShape.x;
                y = optimizedShape.y;
                width = optimizedShape.width;
                height = optimizedShape.height;
                optimizedShape.r = shape.r;
                shape = optimizedShape;
            }
            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);
            }
        };
        Rect.prototype.isZeroArea = function () {
            return !this.shape.width || !this.shape.height;
        };
        return Rect;
    }(Path));
    Rect.prototype.type = 'rect';

    var DEFAULT_RICH_TEXT_COLOR = {
        fill: '#000'
    };
    var DEFAULT_STROKE_LINE_WIDTH = 2;
    var DEFAULT_TEXT_ANIMATION_PROPS = {
        style: defaults({
            fill: true,
            stroke: true,
            fillOpacity: true,
            strokeOpacity: true,
            lineWidth: true,
            fontSize: true,
            lineHeight: true,
            width: true,
            height: true,
            textShadowColor: true,
            textShadowBlur: true,
            textShadowOffsetX: true,
            textShadowOffsetY: true,
            backgroundColor: true,
            padding: true,
            borderColor: true,
            borderWidth: true,
            borderRadius: true
        }, DEFAULT_COMMON_ANIMATION_PROPS.style)
    };
    var ZRText = (function (_super) {
        __extends(ZRText, _super);
        function ZRText(opts) {
            var _this = _super.call(this) || this;
            _this.type = 'text';
            _this._children = [];
            _this._defaultStyle = DEFAULT_RICH_TEXT_COLOR;
            _this.attr(opts);
            return _this;
        }
        ZRText.prototype.childrenRef = function () {
            return this._children;
        };
        ZRText.prototype.update = function () {
            _super.prototype.update.call(this);
            if (this.styleChanged()) {
                this._updateSubTexts();
            }
            for (var i = 0; i < this._children.length; i++) {
                var child = this._children[i];
                child.zlevel = this.zlevel;
                child.z = this.z;
                child.z2 = this.z2;
                child.culling = this.culling;
                child.cursor = this.cursor;
                child.invisible = this.invisible;
            }
        };
        ZRText.prototype.updateTransform = function () {
            var innerTransformable = this.innerTransformable;
            if (innerTransformable) {
                innerTransformable.updateTransform();
                if (innerTransformable.transform) {
                    this.transform = innerTransformable.transform;
                }
            }
            else {
                _super.prototype.updateTransform.call(this);
            }
        };
        ZRText.prototype.getLocalTransform = function (m) {
            var innerTransformable = this.innerTransformable;
            return innerTransformable
                ? innerTransformable.getLocalTransform(m)
                : _super.prototype.getLocalTransform.call(this, m);
        };
        ZRText.prototype.getComputedTransform = function () {
            if (this.__hostTarget) {
                this.__hostTarget.getComputedTransform();
                this.__hostTarget.updateInnerText(true);
            }
            return _super.prototype.getComputedTransform.call(this);
        };
        ZRText.prototype._updateSubTexts = function () {
            this._childCursor = 0;
            normalizeTextStyle(this.style);
            this.style.rich
                ? this._updateRichTexts()
                : this._updatePlainTexts();
            this._children.length = this._childCursor;
            this.styleUpdated();
        };
        ZRText.prototype.addSelfToZr = function (zr) {
            _super.prototype.addSelfToZr.call(this, zr);
            for (var i = 0; i < this._children.length; i++) {
                this._children[i].__zr = zr;
            }
        };
        ZRText.prototype.removeSelfFromZr = function (zr) {
            _super.prototype.removeSelfFromZr.call(this, zr);
            for (var i = 0; i < this._children.length; i++) {
                this._children[i].__zr = null;
            }
        };
        ZRText.prototype.getBoundingRect = function () {
            if (this.styleChanged()) {
                this._updateSubTexts();
            }
            if (!this._rect) {
                var tmpRect = new BoundingRect(0, 0, 0, 0);
                var children = this._children;
                var tmpMat = [];
                var rect = null;
                for (var i = 0; i < children.length; i++) {
                    var child = children[i];
                    var childRect = child.getBoundingRect();
                    var transform = child.getLocalTransform(tmpMat);
                    if (transform) {
                        tmpRect.copy(childRect);
                        tmpRect.applyTransform(transform);
                        rect = rect || tmpRect.clone();
                        rect.union(tmpRect);
                    }
                    else {
                        rect = rect || childRect.clone();
                        rect.union(childRect);
                    }
                }
                this._rect = rect || tmpRect;
            }
            return this._rect;
        };
        ZRText.prototype.setDefaultTextStyle = function (defaultTextStyle) {
            this._defaultStyle = defaultTextStyle || DEFAULT_RICH_TEXT_COLOR;
        };
        ZRText.prototype.setTextContent = function (textContent) {
            if ("development" !== 'production') {
                throw new Error('Can\'t attach text on another text');
            }
        };
        ZRText.prototype._mergeStyle = function (targetStyle, sourceStyle) {
            if (!sourceStyle) {
                return targetStyle;
            }
            var sourceRich = sourceStyle.rich;
            var targetRich = targetStyle.rich || (sourceRich && {});
            extend(targetStyle, sourceStyle);
            if (sourceRich && targetRich) {
                this._mergeRich(targetRich, sourceRich);
                targetStyle.rich = targetRich;
            }
            else if (targetRich) {
                targetStyle.rich = targetRich;
            }
            return targetStyle;
        };
        ZRText.prototype._mergeRich = function (targetRich, sourceRich) {
            var richNames = keys(sourceRich);
            for (var i = 0; i < richNames.length; i++) {
                var richName = richNames[i];
                targetRich[richName] = targetRich[richName] || {};
                extend(targetRich[richName], sourceRich[richName]);
            }
        };
        ZRText.prototype.getAnimationStyleProps = function () {
            return DEFAULT_TEXT_ANIMATION_PROPS;
        };
        ZRText.prototype._getOrCreateChild = function (Ctor) {
            var child = this._children[this._childCursor];
            if (!child || !(child instanceof Ctor)) {
                child = new Ctor();
            }
            this._children[this._childCursor++] = child;
            child.__zr = this.__zr;
            child.parent = this;
            return child;
        };
        ZRText.prototype._updatePlainTexts = function () {
            var style = this.style;
            var textFont = style.font || DEFAULT_FONT;
            var textPadding = style.padding;
            var text = getStyleText(style);
            var contentBlock = parsePlainText(text, style);
            var needDrawBg = needDrawBackground(style);
            var bgColorDrawn = !!(style.backgroundColor);
            var outerHeight = contentBlock.outerHeight;
            var outerWidth = contentBlock.outerWidth;
            var contentWidth = contentBlock.contentWidth;
            var textLines = contentBlock.lines;
            var lineHeight = contentBlock.lineHeight;
            var defaultStyle = this._defaultStyle;
            var baseX = style.x || 0;
            var baseY = style.y || 0;
            var textAlign = style.align || defaultStyle.align || 'left';
            var verticalAlign = style.verticalAlign || defaultStyle.verticalAlign || 'top';
            var textX = baseX;
            var textY = adjustTextY$1(baseY, contentBlock.contentHeight, verticalAlign);
            if (needDrawBg || textPadding) {
                var boxX = adjustTextX(baseX, outerWidth, textAlign);
                var boxY = adjustTextY$1(baseY, outerHeight, verticalAlign);
                needDrawBg && this._renderBackground(style, style, boxX, boxY, outerWidth, outerHeight);
            }
            textY += lineHeight / 2;
            if (textPadding) {
                textX = getTextXForPadding(baseX, textAlign, textPadding);
                if (verticalAlign === 'top') {
                    textY += textPadding[0];
                }
                else if (verticalAlign === 'bottom') {
                    textY -= textPadding[2];
                }
            }
            var defaultLineWidth = 0;
            var useDefaultFill = false;
            var textFill = getFill('fill' in style
                ? style.fill
                : (useDefaultFill = true, defaultStyle.fill));
            var textStroke = getStroke('stroke' in style
                ? style.stroke
                : (!bgColorDrawn
                    && (!defaultStyle.autoStroke || useDefaultFill))
                    ? (defaultLineWidth = DEFAULT_STROKE_LINE_WIDTH, defaultStyle.stroke)
                    : null);
            var hasShadow = style.textShadowBlur > 0;
            var fixedBoundingRect = style.width != null
                && (style.overflow === 'truncate' || style.overflow === 'break' || style.overflow === 'breakAll');
            var calculatedLineHeight = contentBlock.calculatedLineHeight;
            for (var i = 0; i < textLines.length; i++) {
                var el = this._getOrCreateChild(TSpan);
                var subElStyle = el.createStyle();
                el.useStyle(subElStyle);
                subElStyle.text = textLines[i];
                subElStyle.x = textX;
                subElStyle.y = textY;
                if (textAlign) {
                    subElStyle.textAlign = textAlign;
                }
                subElStyle.textBaseline = 'middle';
                subElStyle.opacity = style.opacity;
                subElStyle.strokeFirst = true;
                if (hasShadow) {
                    subElStyle.shadowBlur = style.textShadowBlur || 0;
                    subElStyle.shadowColor = style.textShadowColor || 'transparent';
                    subElStyle.shadowOffsetX = style.textShadowOffsetX || 0;
                    subElStyle.shadowOffsetY = style.textShadowOffsetY || 0;
                }
                subElStyle.stroke = textStroke;
                subElStyle.fill = textFill;
                if (textStroke) {
                    subElStyle.lineWidth = style.lineWidth || defaultLineWidth;
                    subElStyle.lineDash = style.lineDash;
                    subElStyle.lineDashOffset = style.lineDashOffset || 0;
                }
                subElStyle.font = textFont;
                setSeparateFont(subElStyle, style);
                textY += lineHeight;
                if (fixedBoundingRect) {
                    el.setBoundingRect(new BoundingRect(adjustTextX(subElStyle.x, style.width, subElStyle.textAlign), adjustTextY$1(subElStyle.y, calculatedLineHeight, subElStyle.textBaseline), contentWidth, calculatedLineHeight));
                }
            }
        };
        ZRText.prototype._updateRichTexts = function () {
            var style = this.style;
            var text = getStyleText(style);
            var contentBlock = parseRichText(text, style);
            var contentWidth = contentBlock.width;
            var outerWidth = contentBlock.outerWidth;
            var outerHeight = contentBlock.outerHeight;
            var textPadding = style.padding;
            var baseX = style.x || 0;
            var baseY = style.y || 0;
            var defaultStyle = this._defaultStyle;
            var textAlign = style.align || defaultStyle.align;
            var verticalAlign = style.verticalAlign || defaultStyle.verticalAlign;
            var boxX = adjustTextX(baseX, outerWidth, textAlign);
            var boxY = adjustTextY$1(baseY, outerHeight, verticalAlign);
            var xLeft = boxX;
            var lineTop = boxY;
            if (textPadding) {
                xLeft += textPadding[3];
                lineTop += textPadding[0];
            }
            var xRight = xLeft + contentWidth;
            if (needDrawBackground(style)) {
                this._renderBackground(style, style, boxX, boxY, outerWidth, outerHeight);
            }
            var bgColorDrawn = !!(style.backgroundColor);
            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 remainedWidth = line.width;
                var leftIndex = 0;
                var lineXLeft = xLeft;
                var lineXRight = xRight;
                var rightIndex = tokenCount - 1;
                var token = void 0;
                while (leftIndex < tokenCount
                    && (token = tokens[leftIndex], !token.align || token.align === 'left')) {
                    this._placeToken(token, style, lineHeight, lineTop, lineXLeft, 'left', bgColorDrawn);
                    remainedWidth -= token.width;
                    lineXLeft += token.width;
                    leftIndex++;
                }
                while (rightIndex >= 0
                    && (token = tokens[rightIndex], token.align === 'right')) {
                    this._placeToken(token, style, lineHeight, lineTop, lineXRight, 'right', bgColorDrawn);
                    remainedWidth -= token.width;
                    lineXRight -= token.width;
                    rightIndex--;
                }
                lineXLeft += (contentWidth - (lineXLeft - xLeft) - (xRight - lineXRight) - remainedWidth) / 2;
                while (leftIndex <= rightIndex) {
                    token = tokens[leftIndex];
                    this._placeToken(token, style, lineHeight, lineTop, lineXLeft + token.width / 2, 'center', bgColorDrawn);
                    lineXLeft += token.width;
                    leftIndex++;
                }
                lineTop += lineHeight;
            }
        };
        ZRText.prototype._placeToken = function (token, style, lineHeight, lineTop, x, textAlign, parentBgColorDrawn) {
            var tokenStyle = style.rich[token.styleName] || {};
            tokenStyle.text = token.text;
            var verticalAlign = token.verticalAlign;
            var y = lineTop + lineHeight / 2;
            if (verticalAlign === 'top') {
                y = lineTop + token.height / 2;
            }
            else if (verticalAlign === 'bottom') {
                y = lineTop + lineHeight - token.height / 2;
            }
            var needDrawBg = !token.isLineHolder && needDrawBackground(tokenStyle);
            needDrawBg && this._renderBackground(tokenStyle, style, textAlign === 'right'
                ? x - token.width
                : textAlign === 'center'
                    ? x - token.width / 2
                    : x, y - token.height / 2, token.width, token.height);
            var bgColorDrawn = !!tokenStyle.backgroundColor;
            var textPadding = token.textPadding;
            if (textPadding) {
                x = getTextXForPadding(x, textAlign, textPadding);
                y -= token.height / 2 - textPadding[0] - token.innerHeight / 2;
            }
            var el = this._getOrCreateChild(TSpan);
            var subElStyle = el.createStyle();
            el.useStyle(subElStyle);
            var defaultStyle = this._defaultStyle;
            var useDefaultFill = false;
            var defaultLineWidth = 0;
            var textFill = getFill('fill' in tokenStyle ? tokenStyle.fill
                : 'fill' in style ? style.fill
                    : (useDefaultFill = true, defaultStyle.fill));
            var textStroke = getStroke('stroke' in tokenStyle ? tokenStyle.stroke
                : 'stroke' in style ? style.stroke
                    : (!bgColorDrawn
                        && !parentBgColorDrawn
                        && (!defaultStyle.autoStroke || useDefaultFill)) ? (defaultLineWidth = DEFAULT_STROKE_LINE_WIDTH, defaultStyle.stroke)
                        : null);
            var hasShadow = tokenStyle.textShadowBlur > 0
                || style.textShadowBlur > 0;
            subElStyle.text = token.text;
            subElStyle.x = x;
            subElStyle.y = y;
            if (hasShadow) {
                subElStyle.shadowBlur = tokenStyle.textShadowBlur || style.textShadowBlur || 0;
                subElStyle.shadowColor = tokenStyle.textShadowColor || style.textShadowColor || 'transparent';
                subElStyle.shadowOffsetX = tokenStyle.textShadowOffsetX || style.textShadowOffsetX || 0;
                subElStyle.shadowOffsetY = tokenStyle.textShadowOffsetY || style.textShadowOffsetY || 0;
            }
            subElStyle.textAlign = textAlign;
            subElStyle.textBaseline = 'middle';
            subElStyle.font = token.font || DEFAULT_FONT;
            subElStyle.opacity = retrieve3(tokenStyle.opacity, style.opacity, 1);
            setSeparateFont(subElStyle, tokenStyle);
            if (textStroke) {
                subElStyle.lineWidth = retrieve3(tokenStyle.lineWidth, style.lineWidth, defaultLineWidth);
                subElStyle.lineDash = retrieve2(tokenStyle.lineDash, style.lineDash);
                subElStyle.lineDashOffset = style.lineDashOffset || 0;
                subElStyle.stroke = textStroke;
            }
            if (textFill) {
                subElStyle.fill = textFill;
            }
            var textWidth = token.contentWidth;
            var textHeight = token.contentHeight;
            el.setBoundingRect(new BoundingRect(adjustTextX(subElStyle.x, textWidth, subElStyle.textAlign), adjustTextY$1(subElStyle.y, textHeight, subElStyle.textBaseline), textWidth, textHeight));
        };
        ZRText.prototype._renderBackground = function (style, topStyle, x, y, width, height) {
            var textBackgroundColor = style.backgroundColor;
            var textBorderWidth = style.borderWidth;
            var textBorderColor = style.borderColor;
            var isImageBg = textBackgroundColor && textBackgroundColor.image;
            var isPlainOrGradientBg = textBackgroundColor && !isImageBg;
            var textBorderRadius = style.borderRadius;
            var self = this;
            var rectEl;
            var imgEl;
            if (isPlainOrGradientBg || style.lineHeight || (textBorderWidth && textBorderColor)) {
                rectEl = this._getOrCreateChild(Rect);
                rectEl.useStyle(rectEl.createStyle());
                rectEl.style.fill = null;
                var rectShape = rectEl.shape;
                rectShape.x = x;
                rectShape.y = y;
                rectShape.width = width;
                rectShape.height = height;
                rectShape.r = textBorderRadius;
                rectEl.dirtyShape();
            }
            if (isPlainOrGradientBg) {
                var rectStyle = rectEl.style;
                rectStyle.fill = textBackgroundColor || null;
                rectStyle.fillOpacity = retrieve2(style.fillOpacity, 1);
            }
            else if (isImageBg) {
                imgEl = this._getOrCreateChild(ZRImage);
                imgEl.onload = function () {
                    self.dirtyStyle();
                };
                var imgStyle = imgEl.style;
                imgStyle.image = textBackgroundColor.image;
                imgStyle.x = x;
                imgStyle.y = y;
                imgStyle.width = width;
                imgStyle.height = height;
            }
            if (textBorderWidth && textBorderColor) {
                var rectStyle = rectEl.style;
                rectStyle.lineWidth = textBorderWidth;
                rectStyle.stroke = textBorderColor;
                rectStyle.strokeOpacity = retrieve2(style.strokeOpacity, 1);
                rectStyle.lineDash = style.borderDash;
                rectStyle.lineDashOffset = style.borderDashOffset || 0;
                rectEl.strokeContainThreshold = 0;
                if (rectEl.hasFill() && rectEl.hasStroke()) {
                    rectStyle.strokeFirst = true;
                    rectStyle.lineWidth *= 2;
                }
            }
            var commonStyle = (rectEl || imgEl).style;
            commonStyle.shadowBlur = style.shadowBlur || 0;
            commonStyle.shadowColor = style.shadowColor || 'transparent';
            commonStyle.shadowOffsetX = style.shadowOffsetX || 0;
            commonStyle.shadowOffsetY = style.shadowOffsetY || 0;
            commonStyle.opacity = retrieve3(style.opacity, topStyle.opacity, 1);
        };
        ZRText.makeFont = function (style) {
            var font = '';
            if (hasSeparateFont(style)) {
                font = [
                    style.fontStyle,
                    style.fontWeight,
                    parseFontSize(style.fontSize),
                    style.fontFamily || 'sans-serif'
                ].join(' ');
            }
            return font && trim(font) || style.textFont || style.font;
        };
        return ZRText;
    }(Displayable));
    var VALID_TEXT_ALIGN = { left: true, right: 1, center: 1 };
    var VALID_TEXT_VERTICAL_ALIGN = { top: 1, bottom: 1, middle: 1 };
    var FONT_PARTS = ['fontStyle', 'fontWeight', 'fontSize', 'fontFamily'];
    function parseFontSize(fontSize) {
        if (typeof fontSize === 'string'
            && (fontSize.indexOf('px') !== -1
                || fontSize.indexOf('rem') !== -1
                || fontSize.indexOf('em') !== -1)) {
            return fontSize;
        }
        else if (!isNaN(+fontSize)) {
            return fontSize + 'px';
        }
        else {
            return DEFAULT_FONT_SIZE + 'px';
        }
    }
    function setSeparateFont(targetStyle, sourceStyle) {
        for (var i = 0; i < FONT_PARTS.length; i++) {
            var fontProp = FONT_PARTS[i];
            var val = sourceStyle[fontProp];
            if (val != null) {
                targetStyle[fontProp] = val;
            }
        }
    }
    function hasSeparateFont(style) {
        return style.fontSize != null || style.fontFamily || style.fontWeight;
    }
    function normalizeTextStyle(style) {
        normalizeStyle(style);
        each(style.rich, normalizeStyle);
        return style;
    }
    function normalizeStyle(style) {
        if (style) {
            style.font = ZRText.makeFont(style);
            var textAlign = style.align;
            textAlign === 'middle' && (textAlign = 'center');
            style.align = (textAlign == null || VALID_TEXT_ALIGN[textAlign]) ? textAlign : 'left';
            var verticalAlign = style.verticalAlign;
            verticalAlign === 'center' && (verticalAlign = 'middle');
            style.verticalAlign = (verticalAlign == null || VALID_TEXT_VERTICAL_ALIGN[verticalAlign]) ? verticalAlign : 'top';
            var textPadding = style.padding;
            if (textPadding) {
                style.padding = normalizeCssArray(style.padding);
            }
        }
    }
    function getStroke(stroke, lineWidth) {
        return (stroke == null || lineWidth <= 0 || stroke === 'transparent' || stroke === 'none')
            ? null
            : (stroke.image || stroke.colorStops)
                ? '#000'
                : stroke;
    }
    function getFill(fill) {
        return (fill == null || fill === 'none')
            ? null
            : (fill.image || fill.colorStops)
                ? '#000'
                : fill;
    }
    function getTextXForPadding(x, textAlign, textPadding) {
        return textAlign === 'right'
            ? (x - textPadding[1])
            : textAlign === 'center'
                ? (x + textPadding[3] / 2 - textPadding[1] / 2)
                : (x + textPadding[3]);
    }
    function getStyleText(style) {
        var text = style.text;
        text != null && (text += '');
        return text;
    }
    function needDrawBackground(style) {
        return !!(style.backgroundColor
            || style.lineHeight
            || (style.borderWidth && style.borderColor));
    }

    var getECData = makeInner();
    var setCommonECData = function (seriesIndex, dataType, dataIdx, el) {
      if (el) {
        var ecData = getECData(el); // Add data index and series index for indexing the data by element
        // Useful in tooltip

        ecData.dataIndex = dataIdx;
        ecData.dataType = dataType;
        ecData.seriesIndex = seriesIndex; // TODO: not store dataIndex on children.

        if (el.type === 'group') {
          el.traverse(function (child) {
            var childECData = getECData(child);
            childECData.seriesIndex = seriesIndex;
            childECData.dataIndex = dataIdx;
            childECData.dataType = dataType;
          });
        }
      }
    };

    var _highlightNextDigit = 1;
    var _highlightKeyMap = {};
    var getSavedStates = makeInner();
    var getComponentStates = makeInner();
    var HOVER_STATE_NORMAL = 0;
    var HOVER_STATE_BLUR = 1;
    var HOVER_STATE_EMPHASIS = 2;
    var SPECIAL_STATES = ['emphasis', 'blur', 'select'];
    var DISPLAY_STATES = ['normal', 'emphasis', 'blur', 'select'];
    var Z2_EMPHASIS_LIFT = 10;
    var Z2_SELECT_LIFT = 9;
    var HIGHLIGHT_ACTION_TYPE = 'highlight';
    var DOWNPLAY_ACTION_TYPE = 'downplay';
    var SELECT_ACTION_TYPE = 'select';
    var UNSELECT_ACTION_TYPE = 'unselect';
    var TOGGLE_SELECT_ACTION_TYPE = 'toggleSelect';

    function hasFillOrStroke(fillOrStroke) {
      return fillOrStroke != null && fillOrStroke !== 'none';
    } // Most lifted color are duplicated.


    var liftedColorCache = new LRU(100);

    function liftColor(color$1) {
      if (isString(color$1)) {
        var liftedColor = liftedColorCache.get(color$1);

        if (!liftedColor) {
          liftedColor = lift(color$1, -0.1);
          liftedColorCache.put(color$1, liftedColor);
        }

        return liftedColor;
      } else if (isGradientObject(color$1)) {
        var ret = extend({}, color$1);
        ret.colorStops = map(color$1.colorStops, function (stop) {
          return {
            offset: stop.offset,
            color: lift(stop.color, -0.1)
          };
        });
        return ret;
      } // Change nothing.


      return color$1;
    }

    function doChangeHoverState(el, stateName, hoverStateEnum) {
      if (el.onHoverStateChange && (el.hoverState || 0) !== hoverStateEnum) {
        el.onHoverStateChange(stateName);
      }

      el.hoverState = hoverStateEnum;
    }

    function singleEnterEmphasis(el) {
      // Only mark the flag.
      // States will be applied in the echarts.ts in next frame.
      doChangeHoverState(el, 'emphasis', HOVER_STATE_EMPHASIS);
    }

    function singleLeaveEmphasis(el) {
      // Only mark the flag.
      // States will be applied in the echarts.ts in next frame.
      if (el.hoverState === HOVER_STATE_EMPHASIS) {
        doChangeHoverState(el, 'normal', HOVER_STATE_NORMAL);
      }
    }

    function singleEnterBlur(el) {
      doChangeHoverState(el, 'blur', HOVER_STATE_BLUR);
    }

    function singleLeaveBlur(el) {
      if (el.hoverState === HOVER_STATE_BLUR) {
        doChangeHoverState(el, 'normal', HOVER_STATE_NORMAL);
      }
    }

    function singleEnterSelect(el) {
      el.selected = true;
    }

    function singleLeaveSelect(el) {
      el.selected = false;
    }

    function updateElementState(el, updater, commonParam) {
      updater(el, commonParam);
    }

    function traverseUpdateState(el, updater, commonParam) {
      updateElementState(el, updater, commonParam);
      el.isGroup && el.traverse(function (child) {
        updateElementState(child, updater, commonParam);
      });
    }

    function setStatesFlag(el, stateName) {
      switch (stateName) {
        case 'emphasis':
          el.hoverState = HOVER_STATE_EMPHASIS;
          break;

        case 'normal':
          el.hoverState = HOVER_STATE_NORMAL;
          break;

        case 'blur':
          el.hoverState = HOVER_STATE_BLUR;
          break;

        case 'select':
          el.selected = true;
      }
    }

    function getFromStateStyle(el, props, toStateName, defaultValue) {
      var style = el.style;
      var fromState = {};

      for (var i = 0; i < props.length; i++) {
        var propName = props[i];
        var val = style[propName];
        fromState[propName] = val == null ? defaultValue && defaultValue[propName] : val;
      }

      for (var i = 0; i < el.animators.length; i++) {
        var animator = el.animators[i];

        if (animator.__fromStateTransition // Don't consider the animation to emphasis state.
        && animator.__fromStateTransition.indexOf(toStateName) < 0 && animator.targetName === 'style') {
          animator.saveTo(fromState, props);
        }
      }

      return fromState;
    }

    function createEmphasisDefaultState(el, stateName, targetStates, state) {
      var hasSelect = targetStates && indexOf(targetStates, 'select') >= 0;
      var cloned = false;

      if (el instanceof Path) {
        var store = getSavedStates(el);
        var fromFill = hasSelect ? store.selectFill || store.normalFill : store.normalFill;
        var fromStroke = hasSelect ? store.selectStroke || store.normalStroke : store.normalStroke;

        if (hasFillOrStroke(fromFill) || hasFillOrStroke(fromStroke)) {
          state = state || {};
          var emphasisStyle = state.style || {}; // inherit case

          if (emphasisStyle.fill === 'inherit') {
            cloned = true;
            state = extend({}, state);
            emphasisStyle = extend({}, emphasisStyle);
            emphasisStyle.fill = fromFill;
          } // Apply default color lift
          else if (!hasFillOrStroke(emphasisStyle.fill) && hasFillOrStroke(fromFill)) {
              cloned = true; // Not modify the original value.

              state = extend({}, state);
              emphasisStyle = extend({}, emphasisStyle); // Already being applied 'emphasis'. DON'T lift color multiple times.

              emphasisStyle.fill = liftColor(fromFill);
            } // Not highlight stroke if fill has been highlighted.
            else if (!hasFillOrStroke(emphasisStyle.stroke) && hasFillOrStroke(fromStroke)) {
                if (!cloned) {
                  state = extend({}, state);
                  emphasisStyle = extend({}, emphasisStyle);
                }

                emphasisStyle.stroke = liftColor(fromStroke);
              }

          state.style = emphasisStyle;
        }
      }

      if (state) {
        // TODO Share with textContent?
        if (state.z2 == null) {
          if (!cloned) {
            state = extend({}, state);
          }

          var z2EmphasisLift = el.z2EmphasisLift;
          state.z2 = el.z2 + (z2EmphasisLift != null ? z2EmphasisLift : Z2_EMPHASIS_LIFT);
        }
      }

      return state;
    }

    function createSelectDefaultState(el, stateName, state) {
      // const hasSelect = indexOf(el.currentStates, stateName) >= 0;
      if (state) {
        // TODO Share with textContent?
        if (state.z2 == null) {
          state = extend({}, state);
          var z2SelectLift = el.z2SelectLift;
          state.z2 = el.z2 + (z2SelectLift != null ? z2SelectLift : Z2_SELECT_LIFT);
        }
      }

      return state;
    }

    function createBlurDefaultState(el, stateName, state) {
      var hasBlur = indexOf(el.currentStates, stateName) >= 0;
      var currentOpacity = el.style.opacity;
      var fromState = !hasBlur ? getFromStateStyle(el, ['opacity'], stateName, {
        opacity: 1
      }) : null;
      state = state || {};
      var blurStyle = state.style || {};

      if (blurStyle.opacity == null) {
        // clone state
        state = extend({}, state);
        blurStyle = extend({
          // Already being applied 'emphasis'. DON'T mul opacity multiple times.
          opacity: hasBlur ? currentOpacity : fromState.opacity * 0.1
        }, blurStyle);
        state.style = blurStyle;
      }

      return state;
    }

    function elementStateProxy(stateName, targetStates) {
      var state = this.states[stateName];

      if (this.style) {
        if (stateName === 'emphasis') {
          return createEmphasisDefaultState(this, stateName, targetStates, state);
        } else if (stateName === 'blur') {
          return createBlurDefaultState(this, stateName, state);
        } else if (stateName === 'select') {
          return createSelectDefaultState(this, stateName, state);
        }
      }

      return state;
    }
    /**
     * Set hover style (namely "emphasis style") of element.
     * @param el Should not be `zrender/graphic/Group`.
     * @param focus 'self' | 'selfInSeries' | 'series'
     */


    function setDefaultStateProxy(el) {
      el.stateProxy = elementStateProxy;
      var textContent = el.getTextContent();
      var textGuide = el.getTextGuideLine();

      if (textContent) {
        textContent.stateProxy = elementStateProxy;
      }

      if (textGuide) {
        textGuide.stateProxy = elementStateProxy;
      }
    }
    function enterEmphasisWhenMouseOver(el, e) {
      !shouldSilent(el, e) // "emphasis" event highlight has higher priority than mouse highlight.
      && !el.__highByOuter && traverseUpdateState(el, singleEnterEmphasis);
    }
    function leaveEmphasisWhenMouseOut(el, e) {
      !shouldSilent(el, e) // "emphasis" event highlight has higher priority than mouse highlight.
      && !el.__highByOuter && traverseUpdateState(el, singleLeaveEmphasis);
    }
    function enterEmphasis(el, highlightDigit) {
      el.__highByOuter |= 1 << (highlightDigit || 0);
      traverseUpdateState(el, singleEnterEmphasis);
    }
    function leaveEmphasis(el, highlightDigit) {
      !(el.__highByOuter &= ~(1 << (highlightDigit || 0))) && traverseUpdateState(el, singleLeaveEmphasis);
    }
    function enterBlur(el) {
      traverseUpdateState(el, singleEnterBlur);
    }
    function leaveBlur(el) {
      traverseUpdateState(el, singleLeaveBlur);
    }
    function enterSelect(el) {
      traverseUpdateState(el, singleEnterSelect);
    }
    function leaveSelect(el) {
      traverseUpdateState(el, singleLeaveSelect);
    }

    function shouldSilent(el, e) {
      return el.__highDownSilentOnTouch && e.zrByTouch;
    }

    function allLeaveBlur(api) {
      var model = api.getModel();
      var leaveBlurredSeries = [];
      var allComponentViews = [];
      model.eachComponent(function (componentType, componentModel) {
        var componentStates = getComponentStates(componentModel);
        var isSeries = componentType === 'series';
        var view = isSeries ? api.getViewOfSeriesModel(componentModel) : api.getViewOfComponentModel(componentModel);
        !isSeries && allComponentViews.push(view);

        if (componentStates.isBlured) {
          // Leave blur anyway
          view.group.traverse(function (child) {
            singleLeaveBlur(child);
          });
          isSeries && leaveBlurredSeries.push(componentModel);
        }

        componentStates.isBlured = false;
      });
      each(allComponentViews, function (view) {
        if (view && view.toggleBlurSeries) {
          view.toggleBlurSeries(leaveBlurredSeries, false, model);
        }
      });
    }
    function blurSeries(targetSeriesIndex, focus, blurScope, api) {
      var ecModel = api.getModel();
      blurScope = blurScope || 'coordinateSystem';

      function leaveBlurOfIndices(data, dataIndices) {
        for (var i = 0; i < dataIndices.length; i++) {
          var itemEl = data.getItemGraphicEl(dataIndices[i]);
          itemEl && leaveBlur(itemEl);
        }
      }

      if (targetSeriesIndex == null) {
        return;
      }

      if (!focus || focus === 'none') {
        return;
      }

      var targetSeriesModel = ecModel.getSeriesByIndex(targetSeriesIndex);
      var targetCoordSys = targetSeriesModel.coordinateSystem;

      if (targetCoordSys && targetCoordSys.master) {
        targetCoordSys = targetCoordSys.master;
      }

      var blurredSeries = [];
      ecModel.eachSeries(function (seriesModel) {
        var sameSeries = targetSeriesModel === seriesModel;
        var coordSys = seriesModel.coordinateSystem;

        if (coordSys && coordSys.master) {
          coordSys = coordSys.master;
        }

        var sameCoordSys = coordSys && targetCoordSys ? coordSys === targetCoordSys : sameSeries; // If there is no coordinate system. use sameSeries instead.

        if (!( // Not blur other series if blurScope series
        blurScope === 'series' && !sameSeries // Not blur other coordinate system if blurScope is coordinateSystem
        || blurScope === 'coordinateSystem' && !sameCoordSys // Not blur self series if focus is series.
        || focus === 'series' && sameSeries // TODO blurScope: coordinate system
        )) {
          var view = api.getViewOfSeriesModel(seriesModel);
          view.group.traverse(function (child) {
            singleEnterBlur(child);
          });

          if (isArrayLike(focus)) {
            leaveBlurOfIndices(seriesModel.getData(), focus);
          } else if (isObject(focus)) {
            var dataTypes = keys(focus);

            for (var d = 0; d < dataTypes.length; d++) {
              leaveBlurOfIndices(seriesModel.getData(dataTypes[d]), focus[dataTypes[d]]);
            }
          }

          blurredSeries.push(seriesModel);
          getComponentStates(seriesModel).isBlured = true;
        }
      });
      ecModel.eachComponent(function (componentType, componentModel) {
        if (componentType === 'series') {
          return;
        }

        var view = api.getViewOfComponentModel(componentModel);

        if (view && view.toggleBlurSeries) {
          view.toggleBlurSeries(blurredSeries, true, ecModel);
        }
      });
    }
    function blurComponent(componentMainType, componentIndex, api) {
      if (componentMainType == null || componentIndex == null) {
        return;
      }

      var componentModel = api.getModel().getComponent(componentMainType, componentIndex);

      if (!componentModel) {
        return;
      }

      getComponentStates(componentModel).isBlured = true;
      var view = api.getViewOfComponentModel(componentModel);

      if (!view || !view.focusBlurEnabled) {
        return;
      }

      view.group.traverse(function (child) {
        singleEnterBlur(child);
      });
    }
    function blurSeriesFromHighlightPayload(seriesModel, payload, api) {
      var seriesIndex = seriesModel.seriesIndex;
      var data = seriesModel.getData(payload.dataType);

      if (!data) {
        if ("development" !== 'production') {
          error("Unknown dataType " + payload.dataType);
        }

        return;
      }

      var dataIndex = queryDataIndex(data, payload); // Pick the first one if there is multiple/none exists.

      dataIndex = (isArray(dataIndex) ? dataIndex[0] : dataIndex) || 0;
      var el = data.getItemGraphicEl(dataIndex);

      if (!el) {
        var count = data.count();
        var current = 0; // If data on dataIndex is NaN.

        while (!el && current < count) {
          el = data.getItemGraphicEl(current++);
        }
      }

      if (el) {
        var ecData = getECData(el);
        blurSeries(seriesIndex, ecData.focus, ecData.blurScope, api);
      } else {
        // If there is no element put on the data. Try getting it from raw option
        // TODO Should put it on seriesModel?
        var focus_1 = seriesModel.get(['emphasis', 'focus']);
        var blurScope = seriesModel.get(['emphasis', 'blurScope']);

        if (focus_1 != null) {
          blurSeries(seriesIndex, focus_1, blurScope, api);
        }
      }
    }
    function findComponentHighDownDispatchers(componentMainType, componentIndex, name, api) {
      var ret = {
        focusSelf: false,
        dispatchers: null
      };

      if (componentMainType == null || componentMainType === 'series' || componentIndex == null || name == null) {
        return ret;
      }

      var componentModel = api.getModel().getComponent(componentMainType, componentIndex);

      if (!componentModel) {
        return ret;
      }

      var view = api.getViewOfComponentModel(componentModel);

      if (!view || !view.findHighDownDispatchers) {
        return ret;
      }

      var dispatchers = view.findHighDownDispatchers(name); // At presnet, the component (like Geo) only blur inside itself.
      // So we do not use `blurScope` in component.

      var focusSelf;

      for (var i = 0; i < dispatchers.length; i++) {
        if ("development" !== 'production' && !isHighDownDispatcher(dispatchers[i])) {
          error('param should be highDownDispatcher');
        }

        if (getECData(dispatchers[i]).focus === 'self') {
          focusSelf = true;
          break;
        }
      }

      return {
        focusSelf: focusSelf,
        dispatchers: dispatchers
      };
    }
    function handleGlobalMouseOverForHighDown(dispatcher, e, api) {
      if ("development" !== 'production' && !isHighDownDispatcher(dispatcher)) {
        error('param should be highDownDispatcher');
      }

      var ecData = getECData(dispatcher);

      var _a = findComponentHighDownDispatchers(ecData.componentMainType, ecData.componentIndex, ecData.componentHighDownName, api),
          dispatchers = _a.dispatchers,
          focusSelf = _a.focusSelf; // If `findHighDownDispatchers` is supported on the component,
      // highlight/downplay elements with the same name.


      if (dispatchers) {
        if (focusSelf) {
          blurComponent(ecData.componentMainType, ecData.componentIndex, api);
        }

        each(dispatchers, function (dispatcher) {
          return enterEmphasisWhenMouseOver(dispatcher, e);
        });
      } else {
        // Try blur all in the related series. Then emphasis the hoverred.
        // TODO. progressive mode.
        blurSeries(ecData.seriesIndex, ecData.focus, ecData.blurScope, api);

        if (ecData.focus === 'self') {
          blurComponent(ecData.componentMainType, ecData.componentIndex, api);
        } // Other than series, component that not support `findHighDownDispatcher` will
        // also use it. But in this case, highlight/downplay are only supported in
        // mouse hover but not in dispatchAction.


        enterEmphasisWhenMouseOver(dispatcher, e);
      }
    }
    function handleGlobalMouseOutForHighDown(dispatcher, e, api) {
      if ("development" !== 'production' && !isHighDownDispatcher(dispatcher)) {
        error('param should be highDownDispatcher');
      }

      allLeaveBlur(api);
      var ecData = getECData(dispatcher);
      var dispatchers = findComponentHighDownDispatchers(ecData.componentMainType, ecData.componentIndex, ecData.componentHighDownName, api).dispatchers;

      if (dispatchers) {
        each(dispatchers, function (dispatcher) {
          return leaveEmphasisWhenMouseOut(dispatcher, e);
        });
      } else {
        leaveEmphasisWhenMouseOut(dispatcher, e);
      }
    }
    function toggleSelectionFromPayload(seriesModel, payload, api) {
      if (!isSelectChangePayload(payload)) {
        return;
      }

      var dataType = payload.dataType;
      var data = seriesModel.getData(dataType);
      var dataIndex = queryDataIndex(data, payload);

      if (!isArray(dataIndex)) {
        dataIndex = [dataIndex];
      }

      seriesModel[payload.type === TOGGLE_SELECT_ACTION_TYPE ? 'toggleSelect' : payload.type === SELECT_ACTION_TYPE ? 'select' : 'unselect'](dataIndex, dataType);
    }
    function updateSeriesElementSelection(seriesModel) {
      var allData = seriesModel.getAllData();
      each(allData, function (_a) {
        var data = _a.data,
            type = _a.type;
        data.eachItemGraphicEl(function (el, idx) {
          seriesModel.isSelected(idx, type) ? enterSelect(el) : leaveSelect(el);
        });
      });
    }
    function getAllSelectedIndices(ecModel) {
      var ret = [];
      ecModel.eachSeries(function (seriesModel) {
        var allData = seriesModel.getAllData();
        each(allData, function (_a) {
          var data = _a.data,
              type = _a.type;
          var dataIndices = seriesModel.getSelectedDataIndices();

          if (dataIndices.length > 0) {
            var item = {
              dataIndex: dataIndices,
              seriesIndex: seriesModel.seriesIndex
            };

            if (type != null) {
              item.dataType = type;
            }

            ret.push(item);
          }
        });
      });
      return ret;
    }
    /**
     * Enable the function that mouseover will trigger the emphasis state.
     *
     * NOTE:
     * This function should be used on the element with dataIndex, seriesIndex.
     *
     */

    function enableHoverEmphasis(el, focus, blurScope) {
      setAsHighDownDispatcher(el, true);
      traverseUpdateState(el, setDefaultStateProxy);
      enableHoverFocus(el, focus, blurScope);
    }
    function disableHoverEmphasis(el) {
      setAsHighDownDispatcher(el, false);
    }
    function toggleHoverEmphasis(el, focus, blurScope, isDisabled) {
      isDisabled ? disableHoverEmphasis(el) : enableHoverEmphasis(el, focus, blurScope);
    }
    function enableHoverFocus(el, focus, blurScope) {
      var ecData = getECData(el);

      if (focus != null) {
        // TODO dataIndex may be set after this function. This check is not useful.
        // if (ecData.dataIndex == null) {
        //     if (__DEV__) {
        //         console.warn('focus can only been set on element with dataIndex');
        //     }
        // }
        // else {
        ecData.focus = focus;
        ecData.blurScope = blurScope; // }
      } else if (ecData.focus) {
        ecData.focus = null;
      }
    }
    var OTHER_STATES = ['emphasis', 'blur', 'select'];
    var defaultStyleGetterMap = {
      itemStyle: 'getItemStyle',
      lineStyle: 'getLineStyle',
      areaStyle: 'getAreaStyle'
    };
    /**
     * Set emphasis/blur/selected states of element.
     */

    function setStatesStylesFromModel(el, itemModel, styleType, // default itemStyle
    getter) {
      styleType = styleType || 'itemStyle';

      for (var i = 0; i < OTHER_STATES.length; i++) {
        var stateName = OTHER_STATES[i];
        var model = itemModel.getModel([stateName, styleType]);
        var state = el.ensureState(stateName); // Let it throw error if getterType is not found.

        state.style = getter ? getter(model) : model[defaultStyleGetterMap[styleType]]();
      }
    }
    /**
     *
     * Set element as highlight / downplay dispatcher.
     * It will be checked when element received mouseover event or from highlight action.
     * It's in change of all highlight/downplay behavior of it's children.
     *
     * @param el
     * @param el.highDownSilentOnTouch
     *        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 asDispatcher If `false`, do not set as "highDownDispatcher".
     */

    function setAsHighDownDispatcher(el, asDispatcher) {
      var disable = asDispatcher === false;
      var extendedEl = el; // Make `highDownSilentOnTouch` and `onStateChange` only work after
      // `setAsHighDownDispatcher` called. Avoid it is modified by user unexpectedly.

      if (el.highDownSilentOnTouch) {
        extendedEl.__highDownSilentOnTouch = el.highDownSilentOnTouch;
      } // Simple optimize, since this method might be
      // called for each elements of a group in some cases.


      if (!disable || extendedEl.__highDownDispatcher) {
        // 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.
        extendedEl.__highByOuter = extendedEl.__highByOuter || 0;
        extendedEl.__highDownDispatcher = !disable;
      }
    }
    function isHighDownDispatcher(el) {
      return !!(el && el.__highDownDispatcher);
    }
    /**
     * Enable component highlight/downplay features:
     * + hover link (within the same name)
     * + focus blur in component
     */

    function enableComponentHighDownFeatures(el, componentModel, componentHighDownName) {
      var ecData = getECData(el);
      ecData.componentMainType = componentModel.mainType;
      ecData.componentIndex = componentModel.componentIndex;
      ecData.componentHighDownName = componentHighDownName;
    }
    /**
     * Support highlight/downplay record on each elements.
     * For the case: hover highlight/downplay (legend, visualMap, ...) and
     * user triggered highlight/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;
    }
    function isSelectChangePayload(payload) {
      var payloadType = payload.type;
      return payloadType === SELECT_ACTION_TYPE || payloadType === UNSELECT_ACTION_TYPE || payloadType === TOGGLE_SELECT_ACTION_TYPE;
    }
    function isHighDownPayload(payload) {
      var payloadType = payload.type;
      return payloadType === HIGHLIGHT_ACTION_TYPE || payloadType === DOWNPLAY_ACTION_TYPE;
    }
    function savePathStates(el) {
      var store = getSavedStates(el);
      store.normalFill = el.style.fill;
      store.normalStroke = el.style.stroke;
      var selectState = el.states.select || {};
      store.selectFill = selectState.style && selectState.style.fill || null;
      store.selectStroke = selectState.style && selectState.style.stroke || null;
    }

    var CMD$2 = PathProxy.CMD;
    var points = [[], [], []];
    var mathSqrt$1 = Math.sqrt;
    var mathAtan2 = Math.atan2;
    function transformPath(path, m) {
        if (!m) {
            return;
        }
        var data = path.data;
        var len = path.len();
        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 < len;) {
            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$1(m[0] * m[0] + m[1] * m[1]);
                    var sy = mathSqrt$1(m[2] * m[2] + m[3] * m[3]);
                    var angle = mathAtan2(-m[1] / sy, m[0] / sx);
                    data[i] *= sx;
                    data[i++] += x;
                    data[i] *= sy;
                    data[i++] += y;
                    data[i++] *= sx;
                    data[i++] *= sy;
                    data[i++] += angle;
                    data[i++] += angle;
                    i += 2;
                    j = i;
                    break;
                case R:
                    p[0] = data[i++];
                    p[1] = data[i++];
                    applyTransform(p, p, m);
                    data[j++] = p[0];
                    data[j++] = p[1];
                    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_1 = points[k];
                p_1[0] = data[i++];
                p_1[1] = data[i++];
                applyTransform(p_1, p_1, m);
                data[j++] = p_1[0];
                data[j++] = p_1[1];
            }
        }
        path.increaseVersion();
    }

    var mathSqrt$2 = Math.sqrt;
    var mathSin$2 = Math.sin;
    var mathCos$2 = Math.cos;
    var PI$1 = Math.PI;
    function vMag(v) {
        return Math.sqrt(v[0] * v[0] + v[1] * v[1]);
    }
    function vRatio(u, v) {
        return (u[0] * v[0] + u[1] * v[1]) / (vMag(u) * vMag(v));
    }
    function vAngle(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$1 / 180.0);
        var xp = mathCos$2(psi) * (x1 - x2) / 2.0
            + mathSin$2(psi) * (y1 - y2) / 2.0;
        var yp = -1 * mathSin$2(psi) * (x1 - x2) / 2.0
            + mathCos$2(psi) * (y1 - y2) / 2.0;
        var lambda = (xp * xp) / (rx * rx) + (yp * yp) / (ry * ry);
        if (lambda > 1) {
            rx *= mathSqrt$2(lambda);
            ry *= mathSqrt$2(lambda);
        }
        var f = (fa === fs ? -1 : 1)
            * mathSqrt$2((((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$2(psi) * cxp
            - mathSin$2(psi) * cyp;
        var cy = (y1 + y2) / 2.0
            + mathSin$2(psi) * cxp
            + mathCos$2(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$1;
        }
        if (vRatio(u, v) >= 1) {
            dTheta = 0;
        }
        if (dTheta < 0) {
            var n = Math.round(dTheta / PI$1 * 1e6) / 1e6;
            dTheta = PI$1 * 2 + (n % 2) * PI$1;
        }
        path.addData(cmd, cx, cy, rx, ry, theta, dTheta, psi, fs);
    }
    var commandReg = /([mlvhzcqtsa])([^mlvhzcqtsa]*)/ig;
    var numberReg = /-?([0-9]*\.)?[0-9]+([eE]-?[0-9]+)?/g;
    function createPathProxyFromString(data) {
        var path = new PathProxy();
        if (!data) {
            return path;
        }
        var cpx = 0;
        var cpy = 0;
        var subpathX = cpx;
        var subpathY = cpy;
        var prevCmd;
        var CMD = PathProxy.CMD;
        var cmdList = data.match(commandReg);
        if (!cmdList) {
            return path;
        }
        for (var l = 0; l < cmdList.length; l++) {
            var cmdText = cmdList[l];
            var cmdStr = cmdText.charAt(0);
            var cmd = void 0;
            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 = void 0;
                var ctlPty = void 0;
                var rx = void 0;
                var ry = void 0;
                var psi = void 0;
                var fa = void 0;
                var fs = void 0;
                var x1 = cpx;
                var y1 = cpy;
                var len = void 0;
                var pathData = void 0;
                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;
                        len = path.len();
                        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;
                        len = path.len();
                        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;
                        len = path.len();
                        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;
                        len = path.len();
                        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);
                cpx = subpathX;
                cpy = subpathY;
            }
            prevCmd = cmd;
        }
        path.toStatic();
        return path;
    }
    var SVGPath = (function (_super) {
        __extends(SVGPath, _super);
        function SVGPath() {
            return _super !== null && _super.apply(this, arguments) || this;
        }
        SVGPath.prototype.applyTransform = function (m) { };
        return SVGPath;
    }(Path));
    function isPathProxy(path) {
        return path.setData != null;
    }
    function createPathOptions(str, opts) {
        var pathProxy = createPathProxyFromString(str);
        var innerOpts = extend({}, opts);
        innerOpts.buildPath = function (path) {
            if (isPathProxy(path)) {
                path.setData(pathProxy.data);
                var ctx = path.getContext();
                if (ctx) {
                    path.rebuildPath(ctx, 1);
                }
            }
            else {
                var ctx = path;
                pathProxy.rebuildPath(ctx, 1);
            }
        };
        innerOpts.applyTransform = function (m) {
            transformPath(pathProxy, m);
            this.dirtyShape();
        };
        return innerOpts;
    }
    function createFromString(str, opts) {
        return new SVGPath(createPathOptions(str, opts));
    }
    function extendFromString(str, defaultOpts) {
        var innerOpts = createPathOptions(str, defaultOpts);
        var Sub = (function (_super) {
            __extends(Sub, _super);
            function Sub(opts) {
                var _this = _super.call(this, opts) || this;
                _this.applyTransform = innerOpts.applyTransform;
                _this.buildPath = innerOpts.buildPath;
                return _this;
            }
            return Sub;
        }(SVGPath));
        return Sub;
    }
    function mergePath(pathEls, opts) {
        var pathList = [];
        var len = pathEls.length;
        for (var i = 0; i < len; i++) {
            var pathEl = pathEls[i];
            pathList.push(pathEl.getUpdatedPathProxy(true));
        }
        var pathBundle = new Path(opts);
        pathBundle.createPathProxy();
        pathBundle.buildPath = function (path) {
            if (isPathProxy(path)) {
                path.appendPath(pathList);
                var ctx = path.getContext();
                if (ctx) {
                    path.rebuildPath(ctx, 1);
                }
            }
        };
        return pathBundle;
    }
    function clonePath(sourcePath, opts) {
        opts = opts || {};
        var path = new Path();
        if (sourcePath.shape) {
            path.setShape(sourcePath.shape);
        }
        path.setStyle(sourcePath.style);
        if (opts.bakeTransform) {
            transformPath(path.path, sourcePath.getComputedTransform());
        }
        else {
            if (opts.toLocal) {
                path.setLocalTransform(sourcePath.getComputedTransform());
            }
            else {
                path.copyTransform(sourcePath);
            }
        }
        path.buildPath = sourcePath.buildPath;
        path.applyTransform = path.applyTransform;
        path.z = sourcePath.z;
        path.z2 = sourcePath.z2;
        path.zlevel = sourcePath.zlevel;
        return path;
    }

    var CircleShape = (function () {
        function CircleShape() {
            this.cx = 0;
            this.cy = 0;
            this.r = 0;
        }
        return CircleShape;
    }());
    var Circle = (function (_super) {
        __extends(Circle, _super);
        function Circle(opts) {
            return _super.call(this, opts) || this;
        }
        Circle.prototype.getDefaultShape = function () {
            return new CircleShape();
        };
        Circle.prototype.buildPath = function (ctx, shape) {
            ctx.moveTo(shape.cx + shape.r, shape.cy);
            ctx.arc(shape.cx, shape.cy, shape.r, 0, Math.PI * 2);
        };
        return Circle;
    }(Path));
    Circle.prototype.type = 'circle';

    var EllipseShape = (function () {
        function EllipseShape() {
            this.cx = 0;
            this.cy = 0;
            this.rx = 0;
            this.ry = 0;
        }
        return EllipseShape;
    }());
    var Ellipse = (function (_super) {
        __extends(Ellipse, _super);
        function Ellipse(opts) {
            return _super.call(this, opts) || this;
        }
        Ellipse.prototype.getDefaultShape = function () {
            return new EllipseShape();
        };
        Ellipse.prototype.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();
        };
        return Ellipse;
    }(Path));
    Ellipse.prototype.type = 'ellipse';

    var PI$2 = Math.PI;
    var PI2$5 = PI$2 * 2;
    var mathSin$3 = Math.sin;
    var mathCos$3 = Math.cos;
    var mathACos = Math.acos;
    var mathATan2 = Math.atan2;
    var mathAbs$1 = Math.abs;
    var mathSqrt$3 = Math.sqrt;
    var mathMax$3 = Math.max;
    var mathMin$3 = Math.min;
    var e = 1e-4;
    function intersect(x0, y0, x1, y1, x2, y2, x3, y3) {
        var dx10 = x1 - x0;
        var dy10 = y1 - y0;
        var dx32 = x3 - x2;
        var dy32 = y3 - y2;
        var t = dy32 * dx10 - dx32 * dy10;
        if (t * t < e) {
            return;
        }
        t = (dx32 * (y0 - y2) - dy32 * (x0 - x2)) / t;
        return [x0 + t * dx10, y0 + t * dy10];
    }
    function computeCornerTangents(x0, y0, x1, y1, radius, cr, clockwise) {
        var x01 = x0 - x1;
        var y01 = y0 - y1;
        var lo = (clockwise ? cr : -cr) / mathSqrt$3(x01 * x01 + y01 * y01);
        var ox = lo * y01;
        var oy = -lo * x01;
        var x11 = x0 + ox;
        var y11 = y0 + oy;
        var x10 = x1 + ox;
        var y10 = y1 + oy;
        var x00 = (x11 + x10) / 2;
        var y00 = (y11 + y10) / 2;
        var dx = x10 - x11;
        var dy = y10 - y11;
        var d2 = dx * dx + dy * dy;
        var r = radius - cr;
        var s = x11 * y10 - x10 * y11;
        var d = (dy < 0 ? -1 : 1) * mathSqrt$3(mathMax$3(0, r * r * d2 - s * s));
        var cx0 = (s * dy - dx * d) / d2;
        var cy0 = (-s * dx - dy * d) / d2;
        var cx1 = (s * dy + dx * d) / d2;
        var cy1 = (-s * dx + dy * d) / d2;
        var dx0 = cx0 - x00;
        var dy0 = cy0 - y00;
        var dx1 = cx1 - x00;
        var dy1 = cy1 - y00;
        if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) {
            cx0 = cx1;
            cy0 = cy1;
        }
        return {
            cx: cx0,
            cy: cy0,
            x0: -ox,
            y0: -oy,
            x1: cx0 * (radius / r - 1),
            y1: cy0 * (radius / r - 1)
        };
    }
    function normalizeCornerRadius(cr) {
        var arr;
        if (isArray(cr)) {
            var len = cr.length;
            if (!len) {
                return cr;
            }
            if (len === 1) {
                arr = [cr[0], cr[0], 0, 0];
            }
            else if (len === 2) {
                arr = [cr[0], cr[0], cr[1], cr[1]];
            }
            else if (len === 3) {
                arr = cr.concat(cr[2]);
            }
            else {
                arr = cr;
            }
        }
        else {
            arr = [cr, cr, cr, cr];
        }
        return arr;
    }
    function buildPath$1(ctx, shape) {
        var _a;
        var radius = mathMax$3(shape.r, 0);
        var innerRadius = mathMax$3(shape.r0 || 0, 0);
        var hasRadius = radius > 0;
        var hasInnerRadius = innerRadius > 0;
        if (!hasRadius && !hasInnerRadius) {
            return;
        }
        if (!hasRadius) {
            radius = innerRadius;
            innerRadius = 0;
        }
        if (innerRadius > radius) {
            var tmp = radius;
            radius = innerRadius;
            innerRadius = tmp;
        }
        var startAngle = shape.startAngle, endAngle = shape.endAngle;
        if (isNaN(startAngle) || isNaN(endAngle)) {
            return;
        }
        var cx = shape.cx, cy = shape.cy;
        var clockwise = !!shape.clockwise;
        var arc = mathAbs$1(endAngle - startAngle);
        var mod = arc > PI2$5 && arc % PI2$5;
        mod > e && (arc = mod);
        if (!(radius > e)) {
            ctx.moveTo(cx, cy);
        }
        else if (arc > PI2$5 - e) {
            ctx.moveTo(cx + radius * mathCos$3(startAngle), cy + radius * mathSin$3(startAngle));
            ctx.arc(cx, cy, radius, startAngle, endAngle, !clockwise);
            if (innerRadius > e) {
                ctx.moveTo(cx + innerRadius * mathCos$3(endAngle), cy + innerRadius * mathSin$3(endAngle));
                ctx.arc(cx, cy, innerRadius, endAngle, startAngle, clockwise);
            }
        }
        else {
            var icrStart = void 0;
            var icrEnd = void 0;
            var ocrStart = void 0;
            var ocrEnd = void 0;
            var ocrs = void 0;
            var ocre = void 0;
            var icrs = void 0;
            var icre = void 0;
            var ocrMax = void 0;
            var icrMax = void 0;
            var limitedOcrMax = void 0;
            var limitedIcrMax = void 0;
            var xre = void 0;
            var yre = void 0;
            var xirs = void 0;
            var yirs = void 0;
            var xrs = radius * mathCos$3(startAngle);
            var yrs = radius * mathSin$3(startAngle);
            var xire = innerRadius * mathCos$3(endAngle);
            var yire = innerRadius * mathSin$3(endAngle);
            var hasArc = arc > e;
            if (hasArc) {
                var cornerRadius = shape.cornerRadius;
                if (cornerRadius) {
                    _a = normalizeCornerRadius(cornerRadius), icrStart = _a[0], icrEnd = _a[1], ocrStart = _a[2], ocrEnd = _a[3];
                }
                var halfRd = mathAbs$1(radius - innerRadius) / 2;
                ocrs = mathMin$3(halfRd, ocrStart);
                ocre = mathMin$3(halfRd, ocrEnd);
                icrs = mathMin$3(halfRd, icrStart);
                icre = mathMin$3(halfRd, icrEnd);
                limitedOcrMax = ocrMax = mathMax$3(ocrs, ocre);
                limitedIcrMax = icrMax = mathMax$3(icrs, icre);
                if (ocrMax > e || icrMax > e) {
                    xre = radius * mathCos$3(endAngle);
                    yre = radius * mathSin$3(endAngle);
                    xirs = innerRadius * mathCos$3(startAngle);
                    yirs = innerRadius * mathSin$3(startAngle);
                    if (arc < PI$2) {
                        var it_1 = intersect(xrs, yrs, xirs, yirs, xre, yre, xire, yire);
                        if (it_1) {
                            var x0 = xrs - it_1[0];
                            var y0 = yrs - it_1[1];
                            var x1 = xre - it_1[0];
                            var y1 = yre - it_1[1];
                            var a = 1 / mathSin$3(mathACos((x0 * x1 + y0 * y1) / (mathSqrt$3(x0 * x0 + y0 * y0) * mathSqrt$3(x1 * x1 + y1 * y1))) / 2);
                            var b = mathSqrt$3(it_1[0] * it_1[0] + it_1[1] * it_1[1]);
                            limitedOcrMax = mathMin$3(ocrMax, (radius - b) / (a + 1));
                            limitedIcrMax = mathMin$3(icrMax, (innerRadius - b) / (a - 1));
                        }
                    }
                }
            }
            if (!hasArc) {
                ctx.moveTo(cx + xrs, cy + yrs);
            }
            else if (limitedOcrMax > e) {
                var crStart = mathMin$3(ocrStart, limitedOcrMax);
                var crEnd = mathMin$3(ocrEnd, limitedOcrMax);
                var ct0 = computeCornerTangents(xirs, yirs, xrs, yrs, radius, crStart, clockwise);
                var ct1 = computeCornerTangents(xre, yre, xire, yire, radius, crEnd, clockwise);
                ctx.moveTo(cx + ct0.cx + ct0.x0, cy + ct0.cy + ct0.y0);
                if (limitedOcrMax < ocrMax && crStart === crEnd) {
                    ctx.arc(cx + ct0.cx, cy + ct0.cy, limitedOcrMax, mathATan2(ct0.y0, ct0.x0), mathATan2(ct1.y0, ct1.x0), !clockwise);
                }
                else {
                    crStart > 0 && ctx.arc(cx + ct0.cx, cy + ct0.cy, crStart, mathATan2(ct0.y0, ct0.x0), mathATan2(ct0.y1, ct0.x1), !clockwise);
                    ctx.arc(cx, cy, radius, mathATan2(ct0.cy + ct0.y1, ct0.cx + ct0.x1), mathATan2(ct1.cy + ct1.y1, ct1.cx + ct1.x1), !clockwise);
                    crEnd > 0 && ctx.arc(cx + ct1.cx, cy + ct1.cy, crEnd, mathATan2(ct1.y1, ct1.x1), mathATan2(ct1.y0, ct1.x0), !clockwise);
                }
            }
            else {
                ctx.moveTo(cx + xrs, cy + yrs);
                ctx.arc(cx, cy, radius, startAngle, endAngle, !clockwise);
            }
            if (!(innerRadius > e) || !hasArc) {
                ctx.lineTo(cx + xire, cy + yire);
            }
            else if (limitedIcrMax > e) {
                var crStart = mathMin$3(icrStart, limitedIcrMax);
                var crEnd = mathMin$3(icrEnd, limitedIcrMax);
                var ct0 = computeCornerTangents(xire, yire, xre, yre, innerRadius, -crEnd, clockwise);
                var ct1 = computeCornerTangents(xrs, yrs, xirs, yirs, innerRadius, -crStart, clockwise);
                ctx.lineTo(cx + ct0.cx + ct0.x0, cy + ct0.cy + ct0.y0);
                if (limitedIcrMax < icrMax && crStart === crEnd) {
                    ctx.arc(cx + ct0.cx, cy + ct0.cy, limitedIcrMax, mathATan2(ct0.y0, ct0.x0), mathATan2(ct1.y0, ct1.x0), !clockwise);
                }
                else {
                    crEnd > 0 && ctx.arc(cx + ct0.cx, cy + ct0.cy, crEnd, mathATan2(ct0.y0, ct0.x0), mathATan2(ct0.y1, ct0.x1), !clockwise);
                    ctx.arc(cx, cy, innerRadius, mathATan2(ct0.cy + ct0.y1, ct0.cx + ct0.x1), mathATan2(ct1.cy + ct1.y1, ct1.cx + ct1.x1), clockwise);
                    crStart > 0 && ctx.arc(cx + ct1.cx, cy + ct1.cy, crStart, mathATan2(ct1.y1, ct1.x1), mathATan2(ct1.y0, ct1.x0), !clockwise);
                }
            }
            else {
                ctx.lineTo(cx + xire, cy + yire);
                ctx.arc(cx, cy, innerRadius, endAngle, startAngle, clockwise);
            }
        }
        ctx.closePath();
    }

    var SectorShape = (function () {
        function SectorShape() {
            this.cx = 0;
            this.cy = 0;
            this.r0 = 0;
            this.r = 0;
            this.startAngle = 0;
            this.endAngle = Math.PI * 2;
            this.clockwise = true;
            this.cornerRadius = 0;
        }
        return SectorShape;
    }());
    var Sector = (function (_super) {
        __extends(Sector, _super);
        function Sector(opts) {
            return _super.call(this, opts) || this;
        }
        Sector.prototype.getDefaultShape = function () {
            return new SectorShape();
        };
        Sector.prototype.buildPath = function (ctx, shape) {
            buildPath$1(ctx, shape);
        };
        Sector.prototype.isZeroArea = function () {
            return this.shape.startAngle === this.shape.endAngle
                || this.shape.r === this.shape.r0;
        };
        return Sector;
    }(Path));
    Sector.prototype.type = 'sector';

    var RingShape = (function () {
        function RingShape() {
            this.cx = 0;
            this.cy = 0;
            this.r = 0;
            this.r0 = 0;
        }
        return RingShape;
    }());
    var Ring = (function (_super) {
        __extends(Ring, _super);
        function Ring(opts) {
            return _super.call(this, opts) || this;
        }
        Ring.prototype.getDefaultShape = function () {
            return new RingShape();
        };
        Ring.prototype.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);
        };
        return Ring;
    }(Path));
    Ring.prototype.type = 'ring';

    function smoothBezier(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 = points.length; i < len; 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 = points.length; i < len; i++) {
            var point = points[i];
            if (isLoop) {
                prevPoint = points[i ? i - 1 : len - 1];
                nextPoint = points[(i + 1) % len];
            }
            else {
                if (i === 0 || i === len - 1) {
                    cps.push(clone$1(points[i]));
                    continue;
                }
                else {
                    prevPoint = points[i - 1];
                    nextPoint = points[i + 1];
                }
            }
            sub(v, nextPoint, prevPoint);
            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$2(ctx, shape, closePath) {
        var smooth = shape.smooth;
        var points = shape.points;
        if (points && points.length >= 2) {
            if (smooth) {
                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 {
                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();
        }
    }

    var PolygonShape = (function () {
        function PolygonShape() {
            this.points = null;
            this.smooth = 0;
            this.smoothConstraint = null;
        }
        return PolygonShape;
    }());
    var Polygon = (function (_super) {
        __extends(Polygon, _super);
        function Polygon(opts) {
            return _super.call(this, opts) || this;
        }
        Polygon.prototype.getDefaultShape = function () {
            return new PolygonShape();
        };
        Polygon.prototype.buildPath = function (ctx, shape) {
            buildPath$2(ctx, shape, true);
        };
        return Polygon;
    }(Path));
    Polygon.prototype.type = 'polygon';

    var PolylineShape = (function () {
        function PolylineShape() {
            this.points = null;
            this.percent = 1;
            this.smooth = 0;
            this.smoothConstraint = null;
        }
        return PolylineShape;
    }());
    var Polyline = (function (_super) {
        __extends(Polyline, _super);
        function Polyline(opts) {
            return _super.call(this, opts) || this;
        }
        Polyline.prototype.getDefaultStyle = function () {
            return {
                stroke: '#000',
                fill: null
            };
        };
        Polyline.prototype.getDefaultShape = function () {
            return new PolylineShape();
        };
        Polyline.prototype.buildPath = function (ctx, shape) {
            buildPath$2(ctx, shape, false);
        };
        return Polyline;
    }(Path));
    Polyline.prototype.type = 'polyline';

    var subPixelOptimizeOutputShape$1 = {};
    var LineShape = (function () {
        function LineShape() {
            this.x1 = 0;
            this.y1 = 0;
            this.x2 = 0;
            this.y2 = 0;
            this.percent = 1;
        }
        return LineShape;
    }());
    var Line = (function (_super) {
        __extends(Line, _super);
        function Line(opts) {
            return _super.call(this, opts) || this;
        }
        Line.prototype.getDefaultStyle = function () {
            return {
                stroke: '#000',
                fill: null
            };
        };
        Line.prototype.getDefaultShape = function () {
            return new LineShape();
        };
        Line.prototype.buildPath = function (ctx, shape) {
            var x1;
            var y1;
            var x2;
            var y2;
            if (this.subPixelOptimize) {
                var optimizedShape = subPixelOptimizeLine(subPixelOptimizeOutputShape$1, shape, this.style);
                x1 = optimizedShape.x1;
                y1 = optimizedShape.y1;
                x2 = optimizedShape.x2;
                y2 = optimizedShape.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);
        };
        Line.prototype.pointAt = function (p) {
            var shape = this.shape;
            return [
                shape.x1 * (1 - p) + shape.x2 * p,
                shape.y1 * (1 - p) + shape.y2 * p
            ];
        };
        return Line;
    }(Path));
    Line.prototype.type = 'line';

    var out = [];
    var BezierCurveShape = (function () {
        function BezierCurveShape() {
            this.x1 = 0;
            this.y1 = 0;
            this.x2 = 0;
            this.y2 = 0;
            this.cpx1 = 0;
            this.cpy1 = 0;
            this.percent = 1;
        }
        return BezierCurveShape;
    }());
    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 = (function (_super) {
        __extends(BezierCurve, _super);
        function BezierCurve(opts) {
            return _super.call(this, opts) || this;
        }
        BezierCurve.prototype.getDefaultStyle = function () {
            return {
                stroke: '#000',
                fill: null
            };
        };
        BezierCurve.prototype.getDefaultShape = function () {
            return new BezierCurveShape();
        };
        BezierCurve.prototype.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);
            }
        };
        BezierCurve.prototype.pointAt = function (t) {
            return someVectorAt(this.shape, t, false);
        };
        BezierCurve.prototype.tangentAt = function (t) {
            var p = someVectorAt(this.shape, t, true);
            return normalize(p, p);
        };
        return BezierCurve;
    }(Path));
    BezierCurve.prototype.type = 'bezier-curve';

    var ArcShape = (function () {
        function ArcShape() {
            this.cx = 0;
            this.cy = 0;
            this.r = 0;
            this.startAngle = 0;
            this.endAngle = Math.PI * 2;
            this.clockwise = true;
        }
        return ArcShape;
    }());
    var Arc = (function (_super) {
        __extends(Arc, _super);
        function Arc(opts) {
            return _super.call(this, opts) || this;
        }
        Arc.prototype.getDefaultStyle = function () {
            return {
                stroke: '#000',
                fill: null
            };
        };
        Arc.prototype.getDefaultShape = function () {
            return new ArcShape();
        };
        Arc.prototype.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);
        };
        return Arc;
    }(Path));
    Arc.prototype.type = 'arc';

    var CompoundPath = (function (_super) {
        __extends(CompoundPath, _super);
        function CompoundPath() {
            var _this = _super !== null && _super.apply(this, arguments) || this;
            _this.type = 'compound';
            return _this;
        }
        CompoundPath.prototype._updatePathDirty = function () {
            var paths = this.shape.paths;
            var dirtyPath = this.shapeChanged();
            for (var i = 0; i < paths.length; i++) {
                dirtyPath = dirtyPath || paths[i].shapeChanged();
            }
            if (dirtyPath) {
                this.dirtyShape();
            }
        };
        CompoundPath.prototype.beforeBrush = function () {
            this._updatePathDirty();
            var paths = this.shape.paths || [];
            var scale = this.getGlobalScale();
            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);
            }
        };
        CompoundPath.prototype.buildPath = function (ctx, shape) {
            var paths = shape.paths || [];
            for (var i = 0; i < paths.length; i++) {
                paths[i].buildPath(ctx, paths[i].shape, true);
            }
        };
        CompoundPath.prototype.afterBrush = function () {
            var paths = this.shape.paths || [];
            for (var i = 0; i < paths.length; i++) {
                paths[i].pathUpdated();
            }
        };
        CompoundPath.prototype.getBoundingRect = function () {
            this._updatePathDirty.call(this);
            return Path.prototype.getBoundingRect.call(this);
        };
        return CompoundPath;
    }(Path));

    var Gradient = (function () {
        function Gradient(colorStops) {
            this.colorStops = colorStops || [];
        }
        Gradient.prototype.addColorStop = function (offset, color) {
            this.colorStops.push({
                offset: offset,
                color: color
            });
        };
        return Gradient;
    }());

    var LinearGradient = (function (_super) {
        __extends(LinearGradient, _super);
        function LinearGradient(x, y, x2, y2, colorStops, globalCoord) {
            var _this = _super.call(this, colorStops) || this;
            _this.x = x == null ? 0 : x;
            _this.y = y == null ? 0 : y;
            _this.x2 = x2 == null ? 1 : x2;
            _this.y2 = y2 == null ? 0 : y2;
            _this.type = 'linear';
            _this.global = globalCoord || false;
            return _this;
        }
        return LinearGradient;
    }(Gradient));

    var RadialGradient = (function (_super) {
        __extends(RadialGradient, _super);
        function RadialGradient(x, y, r, colorStops, globalCoord) {
            var _this = _super.call(this, colorStops) || this;
            _this.x = x == null ? 0.5 : x;
            _this.y = y == null ? 0.5 : y;
            _this.r = r == null ? 0.5 : r;
            _this.type = 'radial';
            _this.global = globalCoord || false;
            return _this;
        }
        return RadialGradient;
    }(Gradient));

    var extent = [0, 0];
    var extent2 = [0, 0];
    var minTv$1 = new Point();
    var maxTv$1 = new Point();
    var OrientedBoundingRect = (function () {
        function OrientedBoundingRect(rect, transform) {
            this._corners = [];
            this._axes = [];
            this._origin = [0, 0];
            for (var i = 0; i < 4; i++) {
                this._corners[i] = new Point();
            }
            for (var i = 0; i < 2; i++) {
                this._axes[i] = new Point();
            }
            if (rect) {
                this.fromBoundingRect(rect, transform);
            }
        }
        OrientedBoundingRect.prototype.fromBoundingRect = function (rect, transform) {
            var corners = this._corners;
            var axes = this._axes;
            var x = rect.x;
            var y = rect.y;
            var x2 = x + rect.width;
            var y2 = y + rect.height;
            corners[0].set(x, y);
            corners[1].set(x2, y);
            corners[2].set(x2, y2);
            corners[3].set(x, y2);
            if (transform) {
                for (var i = 0; i < 4; i++) {
                    corners[i].transform(transform);
                }
            }
            Point.sub(axes[0], corners[1], corners[0]);
            Point.sub(axes[1], corners[3], corners[0]);
            axes[0].normalize();
            axes[1].normalize();
            for (var i = 0; i < 2; i++) {
                this._origin[i] = axes[i].dot(corners[0]);
            }
        };
        OrientedBoundingRect.prototype.intersect = function (other, mtv) {
            var overlapped = true;
            var noMtv = !mtv;
            minTv$1.set(Infinity, Infinity);
            maxTv$1.set(0, 0);
            if (!this._intersectCheckOneSide(this, other, minTv$1, maxTv$1, noMtv, 1)) {
                overlapped = false;
                if (noMtv) {
                    return overlapped;
                }
            }
            if (!this._intersectCheckOneSide(other, this, minTv$1, maxTv$1, noMtv, -1)) {
                overlapped = false;
                if (noMtv) {
                    return overlapped;
                }
            }
            if (!noMtv) {
                Point.copy(mtv, overlapped ? minTv$1 : maxTv$1);
            }
            return overlapped;
        };
        OrientedBoundingRect.prototype._intersectCheckOneSide = function (self, other, minTv, maxTv, noMtv, inverse) {
            var overlapped = true;
            for (var i = 0; i < 2; i++) {
                var axis = this._axes[i];
                this._getProjMinMaxOnAxis(i, self._corners, extent);
                this._getProjMinMaxOnAxis(i, other._corners, extent2);
                if (extent[1] < extent2[0] || extent[0] > extent2[1]) {
                    overlapped = false;
                    if (noMtv) {
                        return overlapped;
                    }
                    var dist0 = Math.abs(extent2[0] - extent[1]);
                    var dist1 = Math.abs(extent[0] - extent2[1]);
                    if (Math.min(dist0, dist1) > maxTv.len()) {
                        if (dist0 < dist1) {
                            Point.scale(maxTv, axis, -dist0 * inverse);
                        }
                        else {
                            Point.scale(maxTv, axis, dist1 * inverse);
                        }
                    }
                }
                else if (minTv) {
                    var dist0 = Math.abs(extent2[0] - extent[1]);
                    var dist1 = Math.abs(extent[0] - extent2[1]);
                    if (Math.min(dist0, dist1) < minTv.len()) {
                        if (dist0 < dist1) {
                            Point.scale(minTv, axis, dist0 * inverse);
                        }
                        else {
                            Point.scale(minTv, axis, -dist1 * inverse);
                        }
                    }
                }
            }
            return overlapped;
        };
        OrientedBoundingRect.prototype._getProjMinMaxOnAxis = function (dim, corners, out) {
            var axis = this._axes[dim];
            var origin = this._origin;
            var proj = corners[0].dot(axis) + origin[dim];
            var min = proj;
            var max = proj;
            for (var i = 1; i < corners.length; i++) {
                var proj_1 = corners[i].dot(axis) + origin[dim];
                min = Math.min(proj_1, min);
                max = Math.max(proj_1, max);
            }
            out[0] = min;
            out[1] = max;
        };
        return OrientedBoundingRect;
    }());

    var m = [];
    var IncrementalDisplayable = (function (_super) {
        __extends(IncrementalDisplayable, _super);
        function IncrementalDisplayable() {
            var _this = _super !== null && _super.apply(this, arguments) || this;
            _this.notClear = true;
            _this.incremental = true;
            _this._displayables = [];
            _this._temporaryDisplayables = [];
            _this._cursor = 0;
            return _this;
        }
        IncrementalDisplayable.prototype.traverse = function (cb, context) {
            cb.call(context, this);
        };
        IncrementalDisplayable.prototype.useStyle = function () {
            this.style = {};
        };
        IncrementalDisplayable.prototype.getCursor = function () {
            return this._cursor;
        };
        IncrementalDisplayable.prototype.innerAfterBrush = function () {
            this._cursor = this._displayables.length;
        };
        IncrementalDisplayable.prototype.clearDisplaybles = function () {
            this._displayables = [];
            this._temporaryDisplayables = [];
            this._cursor = 0;
            this.markRedraw();
            this.notClear = false;
        };
        IncrementalDisplayable.prototype.clearTemporalDisplayables = function () {
            this._temporaryDisplayables = [];
        };
        IncrementalDisplayable.prototype.addDisplayable = function (displayable, notPersistent) {
            if (notPersistent) {
                this._temporaryDisplayables.push(displayable);
            }
            else {
                this._displayables.push(displayable);
            }
            this.markRedraw();
        };
        IncrementalDisplayable.prototype.addDisplayables = function (displayables, notPersistent) {
            notPersistent = notPersistent || false;
            for (var i = 0; i < displayables.length; i++) {
                this.addDisplayable(displayables[i], notPersistent);
            }
        };
        IncrementalDisplayable.prototype.getDisplayables = function () {
            return this._displayables;
        };
        IncrementalDisplayable.prototype.getTemporalDisplayables = function () {
            return this._temporaryDisplayables;
        };
        IncrementalDisplayable.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]);
            }
        };
        IncrementalDisplayable.prototype.update = function () {
            this.updateTransform();
            for (var i = this._cursor; i < this._displayables.length; i++) {
                var displayable = this._displayables[i];
                displayable.parent = this;
                displayable.update();
                displayable.parent = null;
            }
            for (var i = 0; i < this._temporaryDisplayables.length; i++) {
                var displayable = this._temporaryDisplayables[i];
                displayable.parent = this;
                displayable.update();
                displayable.parent = null;
            }
        };
        IncrementalDisplayable.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;
        };
        IncrementalDisplayable.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;
        };
        return IncrementalDisplayable;
    }(Displayable));

    var transitionStore = makeInner();
    /**
     * Return null if animation is disabled.
     */

    function getAnimationConfig(animationType, animatableModel, dataIndex, // Extra opts can override the option in animatable model.
    extraOpts, // TODO It's only for pictorial bar now.
    extraDelayParams) {
      var animationPayload; // Check if there is global animation configuration from dataZoom/resize can override the config in option.
      // If animation is enabled. Will use this animation config in payload.
      // If animation is disabled. Just ignore it.

      if (animatableModel && animatableModel.ecModel) {
        var updatePayload = animatableModel.ecModel.getUpdatePayload();
        animationPayload = updatePayload && updatePayload.animation;
      }

      var animationEnabled = animatableModel && animatableModel.isAnimationEnabled();
      var isUpdate = animationType === 'update';

      if (animationEnabled) {
        var duration = void 0;
        var easing = void 0;
        var delay = void 0;

        if (extraOpts) {
          duration = retrieve2(extraOpts.duration, 200);
          easing = retrieve2(extraOpts.easing, 'cubicOut');
          delay = 0;
        } else {
          duration = animatableModel.getShallow(isUpdate ? 'animationDurationUpdate' : 'animationDuration');
          easing = animatableModel.getShallow(isUpdate ? 'animationEasingUpdate' : 'animationEasing');
          delay = animatableModel.getShallow(isUpdate ? 'animationDelayUpdate' : 'animationDelay');
        } // animation from payload has highest priority.


        if (animationPayload) {
          animationPayload.duration != null && (duration = animationPayload.duration);
          animationPayload.easing != null && (easing = animationPayload.easing);
          animationPayload.delay != null && (delay = animationPayload.delay);
        }

        if (isFunction(delay)) {
          delay = delay(dataIndex, extraDelayParams);
        }

        if (isFunction(duration)) {
          duration = duration(dataIndex);
        }

        var config = {
          duration: duration || 0,
          delay: delay,
          easing: easing
        };
        return config;
      } else {
        return null;
      }
    }

    function animateOrSetProps(animationType, el, props, animatableModel, dataIndex, cb, during) {
      var isFrom = false;
      var removeOpt;

      if (isFunction(dataIndex)) {
        during = cb;
        cb = dataIndex;
        dataIndex = null;
      } else if (isObject(dataIndex)) {
        cb = dataIndex.cb;
        during = dataIndex.during;
        isFrom = dataIndex.isFrom;
        removeOpt = dataIndex.removeOpt;
        dataIndex = dataIndex.dataIndex;
      }

      var isRemove = animationType === 'leave';

      if (!isRemove) {
        // Must stop the remove animation.
        el.stopAnimation('leave');
      }

      var animationConfig = getAnimationConfig(animationType, animatableModel, dataIndex, isRemove ? removeOpt || {} : null, animatableModel && animatableModel.getAnimationDelayParams ? animatableModel.getAnimationDelayParams(el, dataIndex) : null);

      if (animationConfig && animationConfig.duration > 0) {
        var duration = animationConfig.duration;
        var animationDelay = animationConfig.delay;
        var animationEasing = animationConfig.easing;
        var animateConfig = {
          duration: duration,
          delay: animationDelay || 0,
          easing: animationEasing,
          done: cb,
          force: !!cb || !!during,
          // Set to final state in update/init animation.
          // So the post processing based on the path shape can be done correctly.
          setToFinal: !isRemove,
          scope: animationType,
          during: during
        };
        isFrom ? el.animateFrom(props, animateConfig) : el.animateTo(props, animateConfig);
      } else {
        el.stopAnimation(); // If `isFrom`, the props is the "from" props.

        !isFrom && el.attr(props); // Call during at least once.

        during && during(1);
        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.
     * @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, // TODO: TYPE AnimatableModel
    animatableModel, dataIndex, cb, during) {
      animateOrSetProps('update', el, props, animatableModel, dataIndex, cb, during);
    }
    /**
     * 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.
     */

    function initProps(el, props, animatableModel, dataIndex, cb, during) {
      animateOrSetProps('enter', el, props, animatableModel, dataIndex, cb, during);
    }
    /**
     * If element is removed.
     * It can determine if element is having remove animation.
     */

    function isElementRemoved(el) {
      if (!el.__zr) {
        return true;
      }

      for (var i = 0; i < el.animators.length; i++) {
        var animator = el.animators[i];

        if (animator.scope === 'leave') {
          return true;
        }
      }

      return false;
    }
    /**
     * Remove graphic element
     */

    function removeElement(el, props, animatableModel, dataIndex, cb, during) {
      // Don't do remove animation twice.
      if (isElementRemoved(el)) {
        return;
      }

      animateOrSetProps('leave', el, props, animatableModel, dataIndex, cb, during);
    }

    function fadeOutDisplayable(el, animatableModel, dataIndex, done) {
      el.removeTextContent();
      el.removeTextGuideLine();
      removeElement(el, {
        style: {
          opacity: 0
        }
      }, animatableModel, dataIndex, done);
    }

    function removeElementWithFadeOut(el, animatableModel, dataIndex) {
      function doRemove() {
        el.parent && el.parent.remove(el);
      } // Hide label and labelLine first
      // TODO Also use fade out animation?


      if (!el.isGroup) {
        fadeOutDisplayable(el, animatableModel, dataIndex, doRemove);
      } else {
        el.traverse(function (disp) {
          if (!disp.isGroup) {
            // Can invoke doRemove multiple times.
            fadeOutDisplayable(disp, animatableModel, dataIndex, doRemove);
          }
        });
      }
    }
    /**
     * Save old style for style transition in universalTransition module.
     * It's used when element will be reused in each render.
     * For chart like map, heatmap, which will always create new element.
     * We don't need to save this because universalTransition can get old style from the old element
     */

    function saveOldStyle(el) {
      transitionStore(el).oldStyle = el.style;
    }
    function getOldStyle(el) {
      return transitionStore(el).oldStyle;
    }

    var mathMax$4 = Math.max;
    var mathMin$4 = Math.min;
    var _customShapeMap = {};
    /**
     * Extend shape with parameters
     */

    function extendShape(opts) {
      return Path.extend(opts);
    }
    var extendPathFromString = extendFromString;
    /**
     * Extend path
     */

    function extendPath(pathData, opts) {
      return extendPathFromString(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 name
     * @param 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 registers 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 rarely happens. So we don't make more mechanism
     * to resolve this issue here.
     *
     * @param name
     * @return 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 pathData
     * @param opts
     * @param rect
     * @param layout 'center' or 'cover' default to be 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 imageUrl image url
     * @param opts options
     * @param rect constrain rect
     * @param layout 'center' or 'cover'. Default to be 'cover'
     */

    function makeImage(imageUrl, rect, layout) {
      var zrImg = new ZRImage({
        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
            };
            zrImg.setStyle(centerGraphic(rect, boundingRect));
          }
        }
      });
      return zrImg;
    }
    /**
     * Get position of centered element in bounding box.
     *
     * @param  rect         element local bounding box
     * @param  boundingRect constraint bounding box
     * @return 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$1 = mergePath;
    /**
     * Resize a path to fit the rect
     * @param path
     * @param 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
     */

    function subPixelOptimizeLine$1(shape, lineWidth) {
      subPixelOptimizeLine(shape, shape, {
        lineWidth: lineWidth
      });
      return shape;
    }
    /**
     * Sub pixel optimize rect for canvas
     */

    function subPixelOptimizeRect$1(param) {
      subPixelOptimizeRect(param.shape, param.shape, param.style);
      return param;
    }
    /**
     * Sub pixel optimize for canvas
     *
     * @param position Coordinate, such as x, y
     * @param lineWidth Should be nonnegative integer.
     * @param positiveOrNegative Default false (negative).
     * @return Optimized position.
     */

    var subPixelOptimize$1 = subPixelOptimize;
    /**
     * Get transform matrix of target (param target),
     * in coordinate of its ancestor (param ancestor)
     *
     * @param target
     * @param [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 target [x, y]
     * @param transform Can be:
     *      + Transform matrix: like [1, 0, 0, 1, 0, 0]
     *      + {position, rotation, scale}, the same as `zrender/Transformable`.
     * @param invert Whether use invert matrix.
     * @return [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 direction 'left' 'right' 'top' 'bottom'
     * @param transform Transform matrix: like [1, 0, 0, 1, 0, 0]
     * @param invert Whether use invert matrix.
     * @return Transformed direction. 'left' 'right' 'top' 'bottom'
     */

    function transformDirection(direction, transform, invert) {
      // Pick a base, ensure that transform result will not be (0, 0).
      var hBase = transform[4] === 0 || transform[5] === 0 || transform[0] === 0 ? 1 : Math.abs(2 * transform[4] / transform[0]);
      var vBase = transform[4] === 0 || transform[5] === 0 || transform[2] === 0 ? 1 : Math.abs(2 * transform[4] / transform[2]);
      var vertex = [direction === 'left' ? -hBase : direction === 'right' ? hBase : 0, direction === 'top' ? -vBase : direction === 'bottom' ? vBase : 0];
      vertex = applyTransform$1(vertex, transform, invert);
      return Math.abs(vertex[0]) > Math.abs(vertex[1]) ? vertex[0] > 0 ? 'right' : 'left' : vertex[1] > 0 ? 'bottom' : 'top';
    }

    function isNotGroup(el) {
      return !el.isGroup;
    }

    function isPath(el) {
      return el.shape != null;
    }
    /**
     * Apply group transition animation from g1 to g2.
     * If no animatableModel, no animation.
     */


    function groupTransition(g1, g2, animatableModel) {
      if (!g1 || !g2) {
        return;
      }

      function getElMap(g) {
        var elMap = {};
        g.traverse(function (el) {
          if (isNotGroup(el) && el.anid) {
            elMap[el.anid] = el;
          }
        });
        return elMap;
      }

      function getAnimatableProps(el) {
        var obj = {
          x: el.x,
          y: el.y,
          rotation: el.rotation
        };

        if (isPath(el)) {
          obj.shape = extend({}, el.shape);
        }

        return obj;
      }

      var elMap1 = getElMap(g1);
      g2.traverse(function (el) {
        if (isNotGroup(el) && el.anid) {
          var oldEl = elMap1[el.anid];

          if (oldEl) {
            var newProp = getAnimatableProps(el);
            el.attr(getAnimatableProps(oldEl));
            updateProps(el, newProp, animatableModel, getECData(el).dataIndex);
          }
        }
      });
    }
    function clipPointsByRect(points, rect) {
      // FIXME: This way might be incorrect when graphic clipped by a corner
      // and when element has a border.
      return map(points, function (point) {
        var x = point[0];
        x = mathMax$4(x, rect.x);
        x = mathMin$4(x, rect.x + rect.width);
        var y = point[1];
        y = mathMax$4(y, rect.y);
        y = mathMin$4(y, rect.y + rect.height);
        return [x, y];
      });
    }
    /**
     * Return a new clipped rect. If rect size are negative, return undefined.
     */

    function clipRectByRect(targetRect, rect) {
      var x = mathMax$4(targetRect.x, rect.x);
      var x2 = mathMin$4(targetRect.x + targetRect.width, rect.x + rect.width);
      var y = mathMax$4(targetRect.y, rect.y);
      var y2 = mathMin$4(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
        };
      }
    }
    function createIcon(iconStr, // Support 'image://' or 'path://' or direct svg path.
    opt, rect) {
      var innerOpts = extend({
        rectHover: true
      }, opt);
      var style = innerOpts.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 ZRImage(innerOpts)) : makePath(iconStr.replace('path://', ''), innerOpts, 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.
     */

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

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

    function setTooltipConfig(opt) {
      var itemTooltipOption = opt.itemTooltipOption;
      var componentModel = opt.componentModel;
      var itemName = opt.itemName;
      var itemTooltipOptionObj = isString(itemTooltipOption) ? {
        formatter: itemTooltipOption
      } : itemTooltipOption;
      var mainType = componentModel.mainType;
      var componentIndex = componentModel.componentIndex;
      var formatterParams = {
        componentType: mainType,
        name: itemName,
        $vars: ['name']
      };
      formatterParams[mainType + 'Index'] = componentIndex;
      var formatterParamsExtra = opt.formatterParamsExtra;

      if (formatterParamsExtra) {
        each(keys(formatterParamsExtra), function (key) {
          if (!hasOwn(formatterParams, key)) {
            formatterParams[key] = formatterParamsExtra[key];
            formatterParams.$vars.push(key);
          }
        });
      }

      var ecData = getECData(opt.el);
      ecData.componentMainType = mainType;
      ecData.componentIndex = componentIndex;
      ecData.tooltipConfig = {
        name: itemName,
        option: defaults({
          content: itemName,
          formatterParams: formatterParams
        }, itemTooltipOptionObj)
      };
    }

    function traverseElement(el, cb) {
      var stopped; // TODO
      // Polyfill for fixing zrender group traverse don't visit it's root issue.

      if (el.isGroup) {
        stopped = cb(el);
      }

      if (!stopped) {
        el.traverse(cb);
      }
    }

    function traverseElements(els, cb) {
      if (els) {
        if (isArray(els)) {
          for (var i = 0; i < els.length; i++) {
            traverseElement(els[i], cb);
          }
        } else {
          traverseElement(els, cb);
        }
      }
    } // Register built-in shapes. These shapes might be overwritten
    // by users, although we do not recommend that.

    registerShape('circle', Circle);
    registerShape('ellipse', Ellipse);
    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 = /*#__PURE__*/Object.freeze({
        __proto__: null,
        updateProps: updateProps,
        initProps: initProps,
        removeElement: removeElement,
        removeElementWithFadeOut: removeElementWithFadeOut,
        isElementRemoved: isElementRemoved,
        extendShape: extendShape,
        extendPath: extendPath,
        registerShape: registerShape,
        getShapeClass: getShapeClass,
        makePath: makePath,
        makeImage: makeImage,
        mergePath: mergePath$1,
        resizePath: resizePath,
        subPixelOptimizeLine: subPixelOptimizeLine$1,
        subPixelOptimizeRect: subPixelOptimizeRect$1,
        subPixelOptimize: subPixelOptimize$1,
        getTransform: getTransform,
        applyTransform: applyTransform$1,
        transformDirection: transformDirection,
        groupTransition: groupTransition,
        clipPointsByRect: clipPointsByRect,
        clipRectByRect: clipRectByRect,
        createIcon: createIcon,
        linePolygonIntersect: linePolygonIntersect,
        lineLineIntersect: lineLineIntersect,
        setTooltipConfig: setTooltipConfig,
        traverseElements: traverseElements,
        Group: Group,
        Image: ZRImage,
        Text: ZRText,
        Circle: Circle,
        Ellipse: Ellipse,
        Sector: Sector,
        Ring: Ring,
        Polygon: Polygon,
        Polyline: Polyline,
        Rect: Rect,
        Line: Line,
        BezierCurve: BezierCurve,
        Arc: Arc,
        IncrementalDisplayable: IncrementalDisplayable,
        CompoundPath: CompoundPath,
        LinearGradient: LinearGradient,
        RadialGradient: RadialGradient,
        BoundingRect: BoundingRect,
        OrientedBoundingRect: OrientedBoundingRect,
        Point: Point,
        Path: Path
    });

    var EMPTY_OBJ = {};
    function setLabelText(label, labelTexts) {
      for (var i = 0; i < SPECIAL_STATES.length; i++) {
        var stateName = SPECIAL_STATES[i];
        var text = labelTexts[stateName];
        var state = label.ensureState(stateName);
        state.style = state.style || {};
        state.style.text = text;
      }

      var oldStates = label.currentStates.slice();
      label.clearStates(true);
      label.setStyle({
        text: labelTexts.normal
      });
      label.useStates(oldStates, true);
    }

    function getLabelText(opt, stateModels, interpolatedValue) {
      var labelFetcher = opt.labelFetcher;
      var labelDataIndex = opt.labelDataIndex;
      var labelDimIndex = opt.labelDimIndex;
      var normalModel = stateModels.normal;
      var baseText;

      if (labelFetcher) {
        baseText = labelFetcher.getFormattedLabel(labelDataIndex, 'normal', null, labelDimIndex, normalModel && normalModel.get('formatter'), interpolatedValue != null ? {
          interpolatedValue: interpolatedValue
        } : null);
      }

      if (baseText == null) {
        baseText = isFunction(opt.defaultText) ? opt.defaultText(labelDataIndex, opt, interpolatedValue) : opt.defaultText;
      }

      var statesText = {
        normal: baseText
      };

      for (var i = 0; i < SPECIAL_STATES.length; i++) {
        var stateName = SPECIAL_STATES[i];
        var stateModel = stateModels[stateName];
        statesText[stateName] = retrieve2(labelFetcher ? labelFetcher.getFormattedLabel(labelDataIndex, stateName, null, labelDimIndex, stateModel && stateModel.get('formatter')) : null, baseText);
      }

      return statesText;
    }

    function setLabelStyle(targetEl, labelStatesModels, opt, stateSpecified // TODO specified position?
    ) {
      opt = opt || EMPTY_OBJ;
      var isSetOnText = targetEl instanceof ZRText;
      var needsCreateText = false;

      for (var i = 0; i < DISPLAY_STATES.length; i++) {
        var stateModel = labelStatesModels[DISPLAY_STATES[i]];

        if (stateModel && stateModel.getShallow('show')) {
          needsCreateText = true;
          break;
        }
      }

      var textContent = isSetOnText ? targetEl : targetEl.getTextContent();

      if (needsCreateText) {
        if (!isSetOnText) {
          // Reuse the previous
          if (!textContent) {
            textContent = new ZRText();
            targetEl.setTextContent(textContent);
          } // Use same state proxy


          if (targetEl.stateProxy) {
            textContent.stateProxy = targetEl.stateProxy;
          }
        }

        var labelStatesTexts = getLabelText(opt, labelStatesModels);
        var normalModel = labelStatesModels.normal;
        var showNormal = !!normalModel.getShallow('show');
        var normalStyle = createTextStyle(normalModel, stateSpecified && stateSpecified.normal, opt, false, !isSetOnText);
        normalStyle.text = labelStatesTexts.normal;

        if (!isSetOnText) {
          // Always create new
          targetEl.setTextConfig(createTextConfig(normalModel, opt, false));
        }

        for (var i = 0; i < SPECIAL_STATES.length; i++) {
          var stateName = SPECIAL_STATES[i];
          var stateModel = labelStatesModels[stateName];

          if (stateModel) {
            var stateObj = textContent.ensureState(stateName);
            var stateShow = !!retrieve2(stateModel.getShallow('show'), showNormal);

            if (stateShow !== showNormal) {
              stateObj.ignore = !stateShow;
            }

            stateObj.style = createTextStyle(stateModel, stateSpecified && stateSpecified[stateName], opt, true, !isSetOnText);
            stateObj.style.text = labelStatesTexts[stateName];

            if (!isSetOnText) {
              var targetElEmphasisState = targetEl.ensureState(stateName);
              targetElEmphasisState.textConfig = createTextConfig(stateModel, opt, true);
            }
          }
        } // PENDING: if there is many requirements that emphasis position
        // need to be different from normal position, we might consider
        // auto silent is those cases.


        textContent.silent = !!normalModel.getShallow('silent'); // Keep x and y

        if (textContent.style.x != null) {
          normalStyle.x = textContent.style.x;
        }

        if (textContent.style.y != null) {
          normalStyle.y = textContent.style.y;
        }

        textContent.ignore = !showNormal; // Always create new style.

        textContent.useStyle(normalStyle);
        textContent.dirty();

        if (opt.enableTextSetter) {
          labelInner(textContent).setLabelText = function (interpolatedValue) {
            var labelStatesTexts = getLabelText(opt, labelStatesModels, interpolatedValue);
            setLabelText(textContent, labelStatesTexts);
          };
        }
      } else if (textContent) {
        // Not display rich text.
        textContent.ignore = true;
      }

      targetEl.dirty();
    }
    function getLabelStatesModels(itemModel, labelName) {
      labelName = labelName || 'label';
      var statesModels = {
        normal: itemModel.getModel(labelName)
      };

      for (var i = 0; i < SPECIAL_STATES.length; i++) {
        var stateName = SPECIAL_STATES[i];
        statesModels[stateName] = itemModel.getModel([stateName, labelName]);
      }

      return statesModels;
    }
    /**
     * Set basic textStyle properties.
     */

    function createTextStyle(textStyleModel, specifiedTextStyle, // Fixed style in the code. Can't be set by model.
    opt, isNotNormal, isAttached // If text is attached on an element. If so, auto color will handling in zrender.
    ) {
      var textStyle = {};
      setTextStyleCommon(textStyle, textStyleModel, opt, isNotNormal, isAttached);
      specifiedTextStyle && extend(textStyle, specifiedTextStyle); // textStyle.host && textStyle.host.dirty && textStyle.host.dirty(false);

      return textStyle;
    }
    function createTextConfig(textStyleModel, opt, isNotNormal) {
      opt = opt || {};
      var textConfig = {};
      var labelPosition;
      var labelRotate = textStyleModel.getShallow('rotate');
      var labelDistance = retrieve2(textStyleModel.getShallow('distance'), isNotNormal ? null : 5);
      var labelOffset = textStyleModel.getShallow('offset');
      labelPosition = textStyleModel.getShallow('position') || (isNotNormal ? null : 'inside'); // 'outside' is not a valid zr textPostion value, but used
      // in bar series, and magric type should be considered.

      labelPosition === 'outside' && (labelPosition = opt.defaultOutsidePosition || 'top');

      if (labelPosition != null) {
        textConfig.position = labelPosition;
      }

      if (labelOffset != null) {
        textConfig.offset = labelOffset;
      }

      if (labelRotate != null) {
        labelRotate *= Math.PI / 180;
        textConfig.rotation = labelRotate;
      }

      if (labelDistance != null) {
        textConfig.distance = labelDistance;
      } // fill and auto is determined by the color of path fill if it's not specified by developers.


      textConfig.outsideFill = textStyleModel.get('color') === 'inherit' ? opt.inheritColor || null : 'auto';
      return textConfig;
    }
    /**
     * 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.)
     */

    function setTextStyleCommon(textStyle, textStyleModel, opt, isNotNormal, isAttached) {
      // Consider there will be abnormal when merge hover style to normal style if given default value.
      opt = opt || EMPTY_OBJ;
      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_1 in richItemNames) {
          if (richItemNames.hasOwnProperty(name_1)) {
            // Cascade is supported in rich.
            var richTextStyle = textStyleModel.getModel(['rich', name_1]); // 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_1] = {}, richTextStyle, globalTextStyle, opt, isNotNormal, isAttached, false, true);
          }
        }
      }

      if (richResult) {
        textStyle.rich = richResult;
      }

      var overflow = textStyleModel.get('overflow');

      if (overflow) {
        textStyle.overflow = overflow;
      }

      var margin = textStyleModel.get('minMargin');

      if (margin != null) {
        textStyle.margin = margin;
      }

      setTokenTextStyle(textStyle, textStyleModel, globalTextStyle, opt, isNotNormal, isAttached, true, false);
    } // Consider case:
    // {
    //     data: [{
    //         value: 12,
    //         label: {
    //             rich: {
    //                 // no 'a' here but using parent 'a'.
    //             }
    //         }
    //     }],
    //     rich: {
    //         a: { ... }
    //     }
    // }
    // TODO TextStyleModel


    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 || {};
          var richKeys = keys(rich);

          for (var i = 0; i < richKeys.length; i++) {
            var richKey = richKeys[i];
            richItemNameMap[richKey] = 1;
          }
        }

        textStyleModel = textStyleModel.parentModel;
      }

      return richItemNameMap;
    }

    var TEXT_PROPS_WITH_GLOBAL = ['fontStyle', 'fontWeight', 'fontSize', 'fontFamily', 'textShadowColor', 'textShadowBlur', 'textShadowOffsetX', 'textShadowOffsetY'];
    var TEXT_PROPS_SELF = ['align', 'lineHeight', 'width', 'height', 'tag', 'verticalAlign'];
    var TEXT_PROPS_BOX = ['padding', 'borderWidth', 'borderRadius', 'borderDashOffset', 'backgroundColor', 'borderColor', 'shadowColor', 'shadowBlur', 'shadowOffsetX', 'shadowOffsetY'];

    function setTokenTextStyle(textStyle, textStyleModel, globalTextStyle, opt, isNotNormal, isAttached, isBlock, inRich) {
      // In merge mode, default value should not be given.
      globalTextStyle = !isNotNormal && globalTextStyle || EMPTY_OBJ;
      var inheritColor = opt && opt.inheritColor;
      var fillColor = textStyleModel.getShallow('color');
      var strokeColor = textStyleModel.getShallow('textBorderColor');
      var opacity = retrieve2(textStyleModel.getShallow('opacity'), globalTextStyle.opacity);

      if (fillColor === 'inherit' || fillColor === 'auto') {
        if ("development" !== 'production') {
          if (fillColor === 'auto') {
            deprecateReplaceLog('color: \'auto\'', 'color: \'inherit\'');
          }
        }

        if (inheritColor) {
          fillColor = inheritColor;
        } else {
          fillColor = null;
        }
      }

      if (strokeColor === 'inherit' || strokeColor === 'auto') {
        if ("development" !== 'production') {
          if (strokeColor === 'auto') {
            deprecateReplaceLog('color: \'auto\'', 'color: \'inherit\'');
          }
        }

        if (inheritColor) {
          strokeColor = inheritColor;
        } else {
          strokeColor = null;
        }
      }

      if (!isAttached) {
        // Only use default global textStyle.color if text is individual.
        // Otherwise it will use the strategy of attached text color because text may be on a path.
        fillColor = fillColor || globalTextStyle.color;
        strokeColor = strokeColor || globalTextStyle.textBorderColor;
      }

      if (fillColor != null) {
        textStyle.fill = fillColor;
      }

      if (strokeColor != null) {
        textStyle.stroke = strokeColor;
      }

      var textBorderWidth = retrieve2(textStyleModel.getShallow('textBorderWidth'), globalTextStyle.textBorderWidth);

      if (textBorderWidth != null) {
        textStyle.lineWidth = textBorderWidth;
      }

      var textBorderType = retrieve2(textStyleModel.getShallow('textBorderType'), globalTextStyle.textBorderType);

      if (textBorderType != null) {
        textStyle.lineDash = textBorderType;
      }

      var textBorderDashOffset = retrieve2(textStyleModel.getShallow('textBorderDashOffset'), globalTextStyle.textBorderDashOffset);

      if (textBorderDashOffset != null) {
        textStyle.lineDashOffset = textBorderDashOffset;
      }

      if (!isNotNormal && opacity == null && !inRich) {
        opacity = opt && opt.defaultOpacity;
      }

      if (opacity != null) {
        textStyle.opacity = opacity;
      } // TODO


      if (!isNotNormal && !isAttached) {
        // Set default finally.
        if (textStyle.fill == null && opt.inheritColor) {
          textStyle.fill = opt.inheritColor;
        }
      } // 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.


      for (var i = 0; i < TEXT_PROPS_WITH_GLOBAL.length; i++) {
        var key = TEXT_PROPS_WITH_GLOBAL[i];
        var val = retrieve2(textStyleModel.getShallow(key), globalTextStyle[key]);

        if (val != null) {
          textStyle[key] = val;
        }
      }

      for (var i = 0; i < TEXT_PROPS_SELF.length; i++) {
        var key = TEXT_PROPS_SELF[i];
        var val = textStyleModel.getShallow(key);

        if (val != null) {
          textStyle[key] = val;
        }
      }

      if (textStyle.verticalAlign == null) {
        var baseline = textStyleModel.getShallow('baseline');

        if (baseline != null) {
          textStyle.verticalAlign = baseline;
        }
      }

      if (!isBlock || !opt.disableBox) {
        for (var i = 0; i < TEXT_PROPS_BOX.length; i++) {
          var key = TEXT_PROPS_BOX[i];
          var val = textStyleModel.getShallow(key);

          if (val != null) {
            textStyle[key] = val;
          }
        }

        var borderType = textStyleModel.getShallow('borderType');

        if (borderType != null) {
          textStyle.borderDash = borderType;
        }

        if ((textStyle.backgroundColor === 'auto' || textStyle.backgroundColor === 'inherit') && inheritColor) {
          if ("development" !== 'production') {
            if (textStyle.backgroundColor === 'auto') {
              deprecateReplaceLog('backgroundColor: \'auto\'', 'backgroundColor: \'inherit\'');
            }
          }

          textStyle.backgroundColor = inheritColor;
        }

        if ((textStyle.borderColor === 'auto' || textStyle.borderColor === 'inherit') && inheritColor) {
          if ("development" !== 'production') {
            if (textStyle.borderColor === 'auto') {
              deprecateReplaceLog('borderColor: \'auto\'', 'borderColor: \'inherit\'');
            }
          }

          textStyle.borderColor = inheritColor;
        }
      }
    }

    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(' '));
    }
    var labelInner = makeInner();
    function setLabelValueAnimation(label, labelStatesModels, value, getDefaultText) {
      if (!label) {
        return;
      }

      var obj = labelInner(label);
      obj.prevValue = obj.value;
      obj.value = value;
      var normalLabelModel = labelStatesModels.normal;
      obj.valueAnimation = normalLabelModel.get('valueAnimation');

      if (obj.valueAnimation) {
        obj.precision = normalLabelModel.get('precision');
        obj.defaultInterpolatedText = getDefaultText;
        obj.statesModels = labelStatesModels;
      }
    }
    function animateLabelValue(textEl, dataIndex, data, animatableModel, labelFetcher) {
      var labelInnerStore = labelInner(textEl);

      if (!labelInnerStore.valueAnimation || labelInnerStore.prevValue === labelInnerStore.value) {
        // Value not changed, no new label animation
        return;
      }

      var defaultInterpolatedText = labelInnerStore.defaultInterpolatedText; // Consider the case that being animating, do not use the `obj.value`,
      // Otherwise it will jump to the `obj.value` when this new animation started.

      var currValue = retrieve2(labelInnerStore.interpolatedValue, labelInnerStore.prevValue);
      var targetValue = labelInnerStore.value;

      function during(percent) {
        var interpolated = interpolateRawValues(data, labelInnerStore.precision, currValue, targetValue, percent);
        labelInnerStore.interpolatedValue = percent === 1 ? null : interpolated;
        var labelText = getLabelText({
          labelDataIndex: dataIndex,
          labelFetcher: labelFetcher,
          defaultText: defaultInterpolatedText ? defaultInterpolatedText(interpolated) : interpolated + ''
        }, labelInnerStore.statesModels, interpolated);
        setLabelText(textEl, labelText);
      }

      textEl.percent = 0;
      (labelInnerStore.prevValue == null ? initProps : updateProps)(textEl, {
        // percent is used to prevent animation from being aborted #15916
        percent: 1
      }, animatableModel, dataIndex, null, during);
    }

    var PATH_COLOR = ['textStyle', 'color'];
    var textStyleParams = ['fontStyle', 'fontWeight', 'fontSize', 'fontFamily', 'padding', 'lineHeight', 'rich', 'width', 'height', 'overflow']; // TODO Performance improvement?

    var tmpText = new ZRText();

    var TextStyleMixin =
    /** @class */
    function () {
      function TextStyleMixin() {}
      /**
       * Get color property or get color from option.textStyle.color
       */
      // TODO Callback


      TextStyleMixin.prototype.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}
       */


      TextStyleMixin.prototype.getFont = function () {
        return getFont({
          fontStyle: this.getShallow('fontStyle'),
          fontWeight: this.getShallow('fontWeight'),
          fontSize: this.getShallow('fontSize'),
          fontFamily: this.getShallow('fontFamily')
        }, this.ecModel);
      };

      TextStyleMixin.prototype.getTextRect = function (text) {
        var style = {
          text: text,
          verticalAlign: this.getShallow('verticalAlign') || this.getShallow('baseline')
        };

        for (var i = 0; i < textStyleParams.length; i++) {
          style[textStyleParams[i]] = this.getShallow(textStyleParams[i]);
        }

        tmpText.useStyle(style);
        tmpText.update();
        return tmpText.getBoundingRect();
      };

      return TextStyleMixin;
    }();

    var LINE_STYLE_KEY_MAP = [['lineWidth', 'width'], ['stroke', 'color'], ['opacity'], ['shadowBlur'], ['shadowOffsetX'], ['shadowOffsetY'], ['shadowColor'], ['lineDash', 'type'], ['lineDashOffset', 'dashOffset'], ['lineCap', 'cap'], ['lineJoin', 'join'], ['miterLimit'] // Option decal is in `DecalObject` but style.decal is in `PatternObject`.
    // So do not transfer decal directly.
    ];
    var getLineStyle = makeStyleMapper(LINE_STYLE_KEY_MAP);

    var LineStyleMixin =
    /** @class */
    function () {
      function LineStyleMixin() {}

      LineStyleMixin.prototype.getLineStyle = function (excludes) {
        return getLineStyle(this, excludes);
      };

      return LineStyleMixin;
    }();

    var ITEM_STYLE_KEY_MAP = [['fill', 'color'], ['stroke', 'borderColor'], ['lineWidth', 'borderWidth'], ['opacity'], ['shadowBlur'], ['shadowOffsetX'], ['shadowOffsetY'], ['shadowColor'], ['lineDash', 'borderType'], ['lineDashOffset', 'borderDashOffset'], ['lineCap', 'borderCap'], ['lineJoin', 'borderJoin'], ['miterLimit', 'borderMiterLimit'] // Option decal is in `DecalObject` but style.decal is in `PatternObject`.
    // So do not transfer decal directly.
    ];
    var getItemStyle = makeStyleMapper(ITEM_STYLE_KEY_MAP);

    var ItemStyleMixin =
    /** @class */
    function () {
      function ItemStyleMixin() {}

      ItemStyleMixin.prototype.getItemStyle = function (excludes, includes) {
        return getItemStyle(this, excludes, includes);
      };

      return ItemStyleMixin;
    }();

    var Model =
    /** @class */
    function () {
      function Model(option, parentModel, ecModel) {
        this.parentModel = parentModel;
        this.ecModel = ecModel;
        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.init = function (option, parentModel, ecModel) {
        var rest = [];

        for (var _i = 3; _i < arguments.length; _i++) {
          rest[_i - 3] = arguments[_i];
        }
      };
      /**
       * Merge the input option to me.
       */


      Model.prototype.mergeOption = function (option, ecModel) {
        merge(this.option, option, true);
      }; // `path` can be 'a.b.c', so the return value type have to be `ModelOption`
      // TODO: TYPE strict key check?
      // get(path: string | string[], ignoreParent?: boolean): ModelOption;


      Model.prototype.get = function (path, ignoreParent) {
        if (path == null) {
          return this.option;
        }

        return this._doGet(this.parsePath(path), !ignoreParent && this.parentModel);
      };

      Model.prototype.getShallow = function (key, ignoreParent) {
        var option = this.option;
        var val = option == null ? option : option[key];

        if (val == null && !ignoreParent) {
          var parentModel = this.parentModel;

          if (parentModel) {
            // FIXME:TS do not know how to make it works
            val = parentModel.getShallow(key);
          }
        }

        return val;
      }; // `path` can be 'a.b.c', so the return value type have to be `Model<ModelOption>`
      // getModel(path: string | string[], parentModel?: Model): Model;
      // TODO 'a.b.c' is deprecated


      Model.prototype.getModel = function (path, parentModel) {
        var hasPath = path != null;
        var pathFinal = hasPath ? this.parsePath(path) : null;
        var obj = hasPath ? this._doGet(pathFinal) : this.option;
        parentModel = parentModel || this.parentModel && this.parentModel.getModel(this.resolveParentPath(pathFinal));
        return new Model(obj, parentModel, this.ecModel);
      };
      /**
       * If model has option
       */


      Model.prototype.isEmpty = function () {
        return this.option == null;
      };

      Model.prototype.restoreData = function () {}; // Pending


      Model.prototype.clone = function () {
        var Ctor = this.constructor;
        return new Ctor(clone(this.option));
      }; // setReadOnly(properties): void {
      // clazzUtil.setReadOnly(this, properties);
      // }
      // If path is null/undefined, return null/undefined.


      Model.prototype.parsePath = function (path) {
        if (typeof path === 'string') {
          return path.split('.');
        }

        return path;
      }; // Resolve path for parent. Perhaps useful when parent use a different property.
      // Default to be a identity resolver.
      // Can be modified to a different resolver.


      Model.prototype.resolveParentPath = function (path) {
        return path;
      }; // FIXME:TS check whether put this method here


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

      Model.prototype._doGet = function (pathArr, parentModel) {
        var obj = this.option;

        if (!pathArr) {
          return obj;
        }

        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._doGet(this.resolveParentPath(pathArr), parentModel.parentModel);
        }

        return obj;
      };

      return Model;
    }();

    enableClassExtend(Model);
    enableClassCheck(Model);
    mixin(Model, LineStyleMixin);
    mixin(Model, ItemStyleMixin);
    mixin(Model, AreaStyleMixin);
    mixin(Model, TextStyleMixin);

    var base = Math.round(Math.random() * 10);
    /**
     * @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++].join('_');
    }
    /**
     * Implements `SubTypeDefaulterManager` for `target`.
     */

    function enableSubTypeDefaulter(target) {
      var subTypeDefaulters = {};

      target.registerSubTypeDefaulter = function (componentType, defaulter) {
        var componentTypeInfo = parseClassType(componentType);
        subTypeDefaulters[componentTypeInfo.main] = defaulter;
      };

      target.determineSubType = function (componentType, option) {
        var type = option.type;

        if (!type) {
          var componentTypeMain = parseClassType(componentType).main;

          if (target.hasSubTypes(componentType) && subTypeDefaulters[componentTypeMain]) {
            type = subTypeDefaulters[componentTypeMain](option);
          }
        }

        return type;
      };
    }
    /**
     * Implements `TopologicalTravelable<any>` for `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 circular dependencey, Error will be thrown.
     */

    function enableTopologicalTravel(entity, dependencyGetter) {
      /**
       * @param targetNameList Target Component type list.
       *                       Can be ['aa', 'bb', 'aa.xx']
       * @param fullNameList By which we can build dependency graph.
       * @param callback Params: componentType, dependencies.
       * @param context Scope of callback.
       */
      entity.topologicalTravel = function (targetNameList, fullNameList, callback, context) {
        if (!targetNameList.length) {
          return;
        }

        var result = makeDepndencyGraph(fullNameList);
        var graph = result.graph;
        var noEntryList = result.noEntryList;
        var targetNameSet = {};
        each(targetNameList, function (name) {
          targetNameSet[name] = true;
        });

        while (noEntryList.length) {
          var currComponentType = noEntryList.pop();
          var currVertex = graph[currComponentType];
          var isInTargetNameSet = !!targetNameSet[currComponentType];

          if (isInTargetNameSet) {
            callback.call(context, currComponentType, currVertex.originalDeps.slice());
            delete targetNameSet[currComponentType];
          }

          each(currVertex.successor, isInTargetNameSet ? removeEdgeAndAdd : removeEdge);
        }

        each(targetNameSet, function () {
          var errMsg = '';

          if ("development" !== 'production') {
            errMsg = makePrintable('Circular dependency may exists: ', targetNameSet, targetNameList, fullNameList);
          }

          throw new Error(errMsg);
        });

        function removeEdge(succComponentType) {
          graph[succComponentType].entryCount--;

          if (graph[succComponentType].entryCount === 0) {
            noEntryList.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);
        }
      };

      function makeDepndencyGraph(fullNameList) {
        var graph = {};
        var noEntryList = [];
        each(fullNameList, function (name) {
          var thisItem = createDependencyGraphItem(graph, name);
          var originalDeps = thisItem.originalDeps = dependencyGetter(name);
          var availableDeps = getAvailableDependencies(originalDeps, fullNameList);
          thisItem.entryCount = availableDeps.length;

          if (thisItem.entryCount === 0) {
            noEntryList.push(name);
          }

          each(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(originalDeps, function (dep) {
          indexOf(fullNameList, dep) >= 0 && availableDeps.push(dep);
        });
        return availableDeps;
      }
    }
    function inheritDefaultOption(superOption, subOption) {
      // See also `model/Component.ts#getDefaultOption`
      return merge(merge({}, superOption, true), subOption, 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.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * 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: English.
     */
    var langEN = {
      time: {
        month: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
        monthAbbr: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
        dayOfWeek: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
        dayOfWeekAbbr: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
      },
      legend: {
        selector: {
          all: 'All',
          inverse: 'Inv'
        }
      },
      toolbox: {
        brush: {
          title: {
            rect: 'Box Select',
            polygon: 'Lasso Select',
            lineX: 'Horizontally Select',
            lineY: 'Vertically Select',
            keep: 'Keep Selections',
            clear: 'Clear Selections'
          }
        },
        dataView: {
          title: 'Data View',
          lang: ['Data View', 'Close', 'Refresh']
        },
        dataZoom: {
          title: {
            zoom: 'Zoom',
            back: 'Zoom Reset'
          }
        },
        magicType: {
          title: {
            line: 'Switch to Line Chart',
            bar: 'Switch to Bar Chart',
            stack: 'Stack',
            tiled: 'Tile'
          }
        },
        restore: {
          title: 'Restore'
        },
        saveAsImage: {
          title: 'Save as Image',
          lang: ['Right Click to Save Image']
        }
      },
      series: {
        typeNames: {
          pie: 'Pie chart',
          bar: 'Bar chart',
          line: 'Line chart',
          scatter: 'Scatter plot',
          effectScatter: 'Ripple scatter plot',
          radar: 'Radar chart',
          tree: 'Tree',
          treemap: 'Treemap',
          boxplot: 'Boxplot',
          candlestick: 'Candlestick',
          k: 'K line chart',
          heatmap: 'Heat map',
          map: 'Map',
          parallel: 'Parallel coordinate map',
          lines: 'Line graph',
          graph: 'Relationship graph',
          sankey: 'Sankey diagram',
          funnel: 'Funnel chart',
          gauge: 'Gauge',
          pictorialBar: 'Pictorial bar',
          themeRiver: 'Theme River Map',
          sunburst: 'Sunburst'
        }
      },
      aria: {
        general: {
          withTitle: 'This is a chart about "{title}"',
          withoutTitle: 'This is a chart'
        },
        series: {
          single: {
            prefix: '',
            withName: ' with type {seriesType} named {seriesName}.',
            withoutName: ' with type {seriesType}.'
          },
          multiple: {
            prefix: '. It consists of {seriesCount} series count.',
            withName: ' The {seriesId} series is a {seriesType} representing {seriesName}.',
            withoutName: ' The {seriesId} series is a {seriesType}.',
            separator: {
              middle: '',
              end: ''
            }
          }
        },
        data: {
          allData: 'The data is as follows: ',
          partialData: 'The first {displayCnt} items are: ',
          withName: 'the data for {name} is {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.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
     * 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 langZH = {
      time: {
        month: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'],
        monthAbbr: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
        dayOfWeek: ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'],
        dayOfWeekAbbr: ['日', '一', '二', '三', '四', '五', '六']
      },
      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: ''
          }
        }
      }
    };

    var LOCALE_ZH = 'ZH';
    var LOCALE_EN = 'EN';
    var DEFAULT_LOCALE = LOCALE_EN;
    var localeStorage = {};
    var localeModels = {};
    var SYSTEM_LANG = !env.domSupported ? DEFAULT_LOCALE : function () {
      var langStr = (
      /* eslint-disable-next-line */
      document.documentElement.lang || navigator.language || navigator.browserLanguage).toUpperCase();
      return langStr.indexOf(LOCALE_ZH) > -1 ? LOCALE_ZH : DEFAULT_LOCALE;
    }();
    function registerLocale(locale, localeObj) {
      locale = locale.toUpperCase();
      localeModels[locale] = new Model(localeObj);
      localeStorage[locale] = localeObj;
    } // export function getLocale(locale: string) {
    //     return localeStorage[locale];
    // }

    function createLocaleObject(locale) {
      if (isString(locale)) {
        var localeObj = localeStorage[locale.toUpperCase()] || {};

        if (locale === LOCALE_ZH || locale === LOCALE_EN) {
          return clone(localeObj);
        } else {
          return merge(clone(localeObj), clone(localeStorage[DEFAULT_LOCALE]), false);
        }
      } else {
        return merge(clone(locale), clone(localeStorage[DEFAULT_LOCALE]), false);
      }
    }
    function getLocaleModel(lang) {
      return localeModels[lang];
    }
    function getDefaultLocaleModel() {
      return localeModels[DEFAULT_LOCALE];
    } // Default locale

    registerLocale(LOCALE_EN, langEN);
    registerLocale(LOCALE_ZH, langZH);

    var ONE_SECOND = 1000;
    var ONE_MINUTE = ONE_SECOND * 60;
    var ONE_HOUR = ONE_MINUTE * 60;
    var ONE_DAY = ONE_HOUR * 24;
    var ONE_YEAR = ONE_DAY * 365;
    var defaultLeveledFormatter = {
      year: '{yyyy}',
      month: '{MMM}',
      day: '{d}',
      hour: '{HH}:{mm}',
      minute: '{HH}:{mm}',
      second: '{HH}:{mm}:{ss}',
      millisecond: '{HH}:{mm}:{ss} {SSS}',
      none: '{yyyy}-{MM}-{dd} {HH}:{mm}:{ss} {SSS}'
    };
    var fullDayFormatter = '{yyyy}-{MM}-{dd}';
    var fullLeveledFormatter = {
      year: '{yyyy}',
      month: '{yyyy}-{MM}',
      day: fullDayFormatter,
      hour: fullDayFormatter + ' ' + defaultLeveledFormatter.hour,
      minute: fullDayFormatter + ' ' + defaultLeveledFormatter.minute,
      second: fullDayFormatter + ' ' + defaultLeveledFormatter.second,
      millisecond: defaultLeveledFormatter.none
    };
    var primaryTimeUnits = ['year', 'month', 'day', 'hour', 'minute', 'second', 'millisecond'];
    var timeUnits = ['year', 'half-year', 'quarter', 'month', 'week', 'half-week', 'day', 'half-day', 'quarter-day', 'hour', 'minute', 'second', 'millisecond'];
    function pad(str, len) {
      str += '';
      return '0000'.substr(0, len - str.length) + str;
    }
    function getPrimaryTimeUnit(timeUnit) {
      switch (timeUnit) {
        case 'half-year':
        case 'quarter':
          return 'month';

        case 'week':
        case 'half-week':
          return 'day';

        case 'half-day':
        case 'quarter-day':
          return 'hour';

        default:
          // year, minutes, second, milliseconds
          return timeUnit;
      }
    }
    function isPrimaryTimeUnit(timeUnit) {
      return timeUnit === getPrimaryTimeUnit(timeUnit);
    }
    function getDefaultFormatPrecisionOfInterval(timeUnit) {
      switch (timeUnit) {
        case 'year':
        case 'month':
          return 'day';

        case 'millisecond':
          return 'millisecond';

        default:
          // Also for day, hour, minute, second
          return 'second';
      }
    }
    function format( // Note: The result based on `isUTC` are totally different, which can not be just simply
    // substituted by the result without `isUTC`. So we make the param `isUTC` mandatory.
    time, template, isUTC, lang) {
      var date = parseDate(time);
      var y = date[fullYearGetterName(isUTC)]();
      var M = date[monthGetterName(isUTC)]() + 1;
      var q = Math.floor((M - 1) / 3) + 1;
      var d = date[dateGetterName(isUTC)]();
      var e = date['get' + (isUTC ? 'UTC' : '') + 'Day']();
      var H = date[hoursGetterName(isUTC)]();
      var h = (H - 1) % 12 + 1;
      var m = date[minutesGetterName(isUTC)]();
      var s = date[secondsGetterName(isUTC)]();
      var S = date[millisecondsGetterName(isUTC)]();
      var localeModel = lang instanceof Model ? lang : getLocaleModel(lang || SYSTEM_LANG) || getDefaultLocaleModel();
      var timeModel = localeModel.getModel('time');
      var month = timeModel.get('month');
      var monthAbbr = timeModel.get('monthAbbr');
      var dayOfWeek = timeModel.get('dayOfWeek');
      var dayOfWeekAbbr = timeModel.get('dayOfWeekAbbr');
      return (template || '').replace(/{yyyy}/g, y + '').replace(/{yy}/g, y % 100 + '').replace(/{Q}/g, q + '').replace(/{MMMM}/g, month[M - 1]).replace(/{MMM}/g, monthAbbr[M - 1]).replace(/{MM}/g, pad(M, 2)).replace(/{M}/g, M + '').replace(/{dd}/g, pad(d, 2)).replace(/{d}/g, d + '').replace(/{eeee}/g, dayOfWeek[e]).replace(/{ee}/g, dayOfWeekAbbr[e]).replace(/{e}/g, e + '').replace(/{HH}/g, pad(H, 2)).replace(/{H}/g, H + '').replace(/{hh}/g, pad(h + '', 2)).replace(/{h}/g, h + '').replace(/{mm}/g, pad(m, 2)).replace(/{m}/g, m + '').replace(/{ss}/g, pad(s, 2)).replace(/{s}/g, s + '').replace(/{SSS}/g, pad(S, 3)).replace(/{S}/g, S + '');
    }
    function leveledFormat(tick, idx, formatter, lang, isUTC) {
      var template = null;

      if (isString(formatter)) {
        // Single formatter for all units at all levels
        template = formatter;
      } else if (isFunction(formatter)) {
        // Callback formatter
        template = formatter(tick.value, idx, {
          level: tick.level
        });
      } else {
        var defaults$1 = extend({}, defaultLeveledFormatter);

        if (tick.level > 0) {
          for (var i = 0; i < primaryTimeUnits.length; ++i) {
            defaults$1[primaryTimeUnits[i]] = "{primary|" + defaults$1[primaryTimeUnits[i]] + "}";
          }
        }

        var mergedFormatter = formatter ? formatter.inherit === false ? formatter // Use formatter with bigger units
        : defaults(formatter, defaults$1) : defaults$1;
        var unit = getUnitFromValue(tick.value, isUTC);

        if (mergedFormatter[unit]) {
          template = mergedFormatter[unit];
        } else if (mergedFormatter.inherit) {
          // Unit formatter is not defined and should inherit from bigger units
          var targetId = timeUnits.indexOf(unit);

          for (var i = targetId - 1; i >= 0; --i) {
            if (mergedFormatter[unit]) {
              template = mergedFormatter[unit];
              break;
            }
          }

          template = template || defaults$1.none;
        }

        if (isArray(template)) {
          var levelId = tick.level == null ? 0 : tick.level >= 0 ? tick.level : template.length + tick.level;
          levelId = Math.min(levelId, template.length - 1);
          template = template[levelId];
        }
      }

      return format(new Date(tick.value), template, isUTC, lang);
    }
    function getUnitFromValue(value, isUTC) {
      var date = parseDate(value);
      var M = date[monthGetterName(isUTC)]() + 1;
      var d = date[dateGetterName(isUTC)]();
      var h = date[hoursGetterName(isUTC)]();
      var m = date[minutesGetterName(isUTC)]();
      var s = date[secondsGetterName(isUTC)]();
      var S = date[millisecondsGetterName(isUTC)]();
      var isSecond = S === 0;
      var isMinute = isSecond && s === 0;
      var isHour = isMinute && m === 0;
      var isDay = isHour && h === 0;
      var isMonth = isDay && d === 1;
      var isYear = isMonth && M === 1;

      if (isYear) {
        return 'year';
      } else if (isMonth) {
        return 'month';
      } else if (isDay) {
        return 'day';
      } else if (isHour) {
        return 'hour';
      } else if (isMinute) {
        return 'minute';
      } else if (isSecond) {
        return 'second';
      } else {
        return 'millisecond';
      }
    }
    function getUnitValue(value, unit, isUTC) {
      var date = isNumber(value) ? parseDate(value) : value;
      unit = unit || getUnitFromValue(value, isUTC);

      switch (unit) {
        case 'year':
          return date[fullYearGetterName(isUTC)]();

        case 'half-year':
          return date[monthGetterName(isUTC)]() >= 6 ? 1 : 0;

        case 'quarter':
          return Math.floor((date[monthGetterName(isUTC)]() + 1) / 4);

        case 'month':
          return date[monthGetterName(isUTC)]();

        case 'day':
          return date[dateGetterName(isUTC)]();

        case 'half-day':
          return date[hoursGetterName(isUTC)]() / 24;

        case 'hour':
          return date[hoursGetterName(isUTC)]();

        case 'minute':
          return date[minutesGetterName(isUTC)]();

        case 'second':
          return date[secondsGetterName(isUTC)]();

        case 'millisecond':
          return date[millisecondsGetterName(isUTC)]();
      }
    }
    function fullYearGetterName(isUTC) {
      return isUTC ? 'getUTCFullYear' : 'getFullYear';
    }
    function monthGetterName(isUTC) {
      return isUTC ? 'getUTCMonth' : 'getMonth';
    }
    function dateGetterName(isUTC) {
      return isUTC ? 'getUTCDate' : 'getDate';
    }
    function hoursGetterName(isUTC) {
      return isUTC ? 'getUTCHours' : 'getHours';
    }
    function minutesGetterName(isUTC) {
      return isUTC ? 'getUTCMinutes' : 'getMinutes';
    }
    function secondsGetterName(isUTC) {
      return isUTC ? 'getUTCSeconds' : 'getSeconds';
    }
    function millisecondsGetterName(isUTC) {
      return isUTC ? 'getUTCMilliseconds' : 'getMilliseconds';
    }
    function fullYearSetterName(isUTC) {
      return isUTC ? 'setUTCFullYear' : 'setFullYear';
    }
    function monthSetterName(isUTC) {
      return isUTC ? 'setUTCMonth' : 'setMonth';
    }
    function dateSetterName(isUTC) {
      return isUTC ? 'setUTCDate' : 'setDate';
    }
    function hoursSetterName(isUTC) {
      return isUTC ? 'setUTCHours' : 'setHours';
    }
    function minutesSetterName(isUTC) {
      return isUTC ? 'setUTCMinutes' : 'setMinutes';
    }
    function secondsSetterName(isUTC) {
      return isUTC ? 'setUTCSeconds' : 'setSeconds';
    }
    function millisecondsSetterName(isUTC) {
      return isUTC ? 'setUTCMilliseconds' : 'setMilliseconds';
    }

    function getTextRect(text, font, align, verticalAlign, padding, rich, truncate, lineHeight) {
      var textEl = new ZRText({
        style: {
          text: text,
          font: font,
          align: align,
          verticalAlign: verticalAlign,
          padding: padding,
          rich: rich,
          overflow: truncate ? 'truncate' : null,
          lineHeight: lineHeight
        }
      });
      return textEl.getBoundingRect();
    }

    /**
     * Add a comma each three digit.
     */

    function addCommas(x) {
      if (!isNumeric(x)) {
        return isString(x) ? x : '-';
      }

      var parts = (x + '').split('.');
      return parts[0].replace(/(\d{1,3})(?=(?:\d{3})+(?!\d))/g, '$1,') + (parts.length > 1 ? '.' + parts[1] : '');
    }
    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;
    /**
     * Make value user readable for tooltip and label.
     * "User readable":
     *     Try to not print programmer-specific text like NaN, Infinity, null, undefined.
     *     Avoid to display an empty string, which users can not recognize there is
     *     a value and it might look like a bug.
     */

    function makeValueReadable(value, valueType, useUTC) {
      var USER_READABLE_DEFUALT_TIME_PATTERN = '{yyyy}-{MM}-{dd} {HH}:{mm}:{ss}';

      function stringToUserReadable(str) {
        return str && trim(str) ? str : '-';
      }

      function isNumberUserReadable(num) {
        return !!(num != null && !isNaN(num) && isFinite(num));
      }

      var isTypeTime = valueType === 'time';
      var isValueDate = value instanceof Date;

      if (isTypeTime || isValueDate) {
        var date = isTypeTime ? parseDate(value) : value;

        if (!isNaN(+date)) {
          return format(date, USER_READABLE_DEFUALT_TIME_PATTERN, useUTC);
        } else if (isValueDate) {
          return '-';
        } // In other cases, continue to try to display the value in the following code.

      }

      if (valueType === 'ordinal') {
        return isStringSafe(value) ? stringToUserReadable(value) : isNumber(value) ? isNumberUserReadable(value) ? value + '' : '-' : '-';
      } // By default.


      var numericResult = numericToNumber(value);
      return isNumberUserReadable(numericResult) ? addCommas(numericResult) : isStringSafe(value) ? stringToUserReadable(value) : typeof value === 'boolean' ? value + '' : '-';
    }
    var TPL_VAR_ALIAS = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];

    var wrapVar = function (varName, seriesIdx) {
      return '{' + varName + (seriesIdx == null ? '' : seriesIdx) + '}';
    };
    /**
     * Template formatter
     * @param {Array.<Object>|Object} paramsList
     */


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

    function formatTplSimple(tpl, param, encode) {
      each(param, function (value, key) {
        tpl = tpl.replace('{' + key + '}', encode ? encodeHTML(value) : value);
      });
      return tpl;
    }
    function getTooltipMarker(inOpt, extraCssText) {
      var opt = isString(inOpt) ? {
        color: inOpt,
        extraCssText: extraCssText
      } : inOpt || {};
      var color = opt.color;
      var type = opt.type;
      extraCssText = opt.extraCssText;
      var renderMode = opt.renderMode || 'html';

      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:' // Only support string
        + encodeHTML(color) + ';' + (extraCssText || '') + '"></span>' : '<span style="display:inline-block;margin-right:4px;' + 'border-radius:10px;width:10px;height:10px;background-color:' + encodeHTML(color) + ';' + (extraCssText || '') + '"></span>';
      } else {
        // Should better not to auto generate style name by auto-increment number here.
        // Because this util is usually called in tooltip formatter, which is probably
        // called repeatedly when mouse move and the auto-increment number increases fast.
        // Users can make their own style name by theirselves, make it unique and readable.
        var markerId = opt.markerId || 'markerX';
        return {
          renderMode: renderMode,
          content: '{' + markerId + '|}  ',
          style: type === 'subItem' ? {
            width: 4,
            height: 4,
            borderRadius: 2,
            backgroundColor: color
          } : {
            width: 10,
            height: 10,
            borderRadius: 5,
            backgroundColor: color
          }
        };
      }
    }
    /**
     * @deprecated Use `time/format` instead.
     * 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 ("development" !== 'production') {
        deprecateReplaceLog('echarts.format.formatTime', 'echarts.time.format');
      }

      if (tpl === 'week' || tpl === 'month' || tpl === 'quarter' || tpl === 'half-year' || tpl === 'year') {
        tpl = 'MM-dd\nyyyy';
      }

      var date = parseDate(value);
      var getUTC = isUTC ? 'getUTC' : 'get';
      var y = date[getUTC + 'FullYear']();
      var M = date[getUTC + 'Month']() + 1;
      var d = date[getUTC + 'Date']();
      var h = date[getUTC + 'Hours']();
      var m = date[getUTC + 'Minutes']();
      var s = date[getUTC + 'Seconds']();
      var S = date[getUTC + 'Milliseconds']();
      tpl = tpl.replace('MM', pad(M, 2)).replace('M', M).replace('yyyy', y).replace('yy', pad(y % 100 + '', 2)).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;
    }
    /**
     * @return Never be null/undefined.
     */

    function convertToColorString(color, defaultColor) {
      defaultColor = defaultColor || 'transparent';
      return isString(color) ? color : isObject(color) ? color.colorStops && (color.colorStops[0] || {}).color || defaultColor : defaultColor;
    }
    /**
     * open new tab
     * @param link url
     * @param target blank or self
     */

    function windowOpen(link, target) {
      /* global window */
      if (target === '_blank' || target === 'blank') {
        var blank = window.open();
        blank.opener = null;
        blank.location.href = link;
      } else {
        window.open(link, target);
      }
    }

    var each$1 = each;
    /**
     * @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 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;
        }

        child.x = x;
        child.y = y;
        child.markRedraw();
        orient === 'horizontal' ? x = nextX + gap : y = nextY + gap;
      });
    }
    /**
     * VBox or HBox layouting
     * @param {string} orient
     * @param {module:zrender/graphic/Group} group
     * @param {number} gap
     * @param {number} [width=Infinity]
     * @param {number} [height=Infinity]
     */


    var box = boxLayout;
    /**
     * VBox layouting
     * @param {module:zrender/graphic/Group} group
     * @param {number} gap
     * @param {number} [width=Infinity]
     * @param {number} [height=Infinity]
     */

    var vbox = curry(boxLayout, 'vertical');
    /**
     * HBox layouting
     * @param {module:zrender/graphic/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.
     */

    function getAvailableSize(positionInfo, containerRect, margin) {
      var containerWidth = containerRect.width;
      var containerHeight = containerRect.height;
      var x = parsePercent$1(positionInfo.left, containerWidth);
      var y = parsePercent$1(positionInfo.top, containerHeight);
      var x2 = parsePercent$1(positionInfo.right, containerWidth);
      var y2 = parsePercent$1(positionInfo.bottom, containerHeight);
      (isNaN(x) || isNaN(parseFloat(positionInfo.left))) && (x = 0);
      (isNaN(x2) || isNaN(parseFloat(positionInfo.right))) && (x2 = containerWidth);
      (isNaN(y) || isNaN(parseFloat(positionInfo.top))) && (y = 0);
      (isNaN(y2) || isNaN(parseFloat(positionInfo.bottom))) && (y2 = containerHeight);
      margin = normalizeCssArray$1(margin || 0);
      return {
        width: Math.max(x2 - x - margin[1] - margin[3], 0),
        height: Math.max(y2 - y - margin[0] - margin[2], 0)
      };
    }
    /**
     * Parse position info.
     */

    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. Translate (with el.position by this method)
     * So this method only fixes the last step 'Translate', which does not affect
     * scaling and rotating.
     *
     * If be called repeatedly with the same input el, the same result will be gotten.
     *
     * Return true if the layout happened.
     *
     * @param el Should have `getBoundingRect` method.
     * @param positionInfo
     * @param positionInfo.left
     * @param positionInfo.top
     * @param positionInfo.right
     * @param positionInfo.bottom
     * @param positionInfo.width Only for opt.boundingModel: 'raw'
     * @param positionInfo.height Only for opt.boundingModel: 'raw'
     * @param containerRect
     * @param margin
     * @param opt
     * @param opt.hv Only horizontal or only vertical. Default to be [1, 1]
     * @param opt.boundingMode
     *        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, out) {
      var h = !opt || !opt.hv || opt.hv[0];
      var v = !opt || !opt.hv || opt.hv[1];
      var boundingMode = opt && opt.boundingMode || 'all';
      out = out || el;
      out.x = el.x;
      out.y = el.y;

      if (!h && !v) {
        return false;
      }

      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.


      var layoutRect = 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 dx = h ? layoutRect.x - rect.x : 0;
      var dy = v ? layoutRect.y - rect.y : 0;

      if (boundingMode === 'raw') {
        out.x = dx;
        out.y = dy;
      } else {
        out.x += dx;
        out.y += dy;
      }

      if (out === el) {
        el.markRedraw();
      }

      return true;
    }
    /**
     * @param option Contains some of the properties in HV_NAMES.
     * @param hvIdx 0: horizontal; 1: vertical.
     */

    function sizeCalculable(option, hvIdx) {
      return option[HV_NAMES[hvIdx][0]] != null || option[HV_NAMES[hvIdx][1]] != null && option[HV_NAMES[hvIdx][2]] != null;
    }
    function fetchLayoutMode(ins) {
      var layoutMode = ins.layoutMode || ins.constructor.layoutMode;
      return isObject(layoutMode) ? layoutMode : layoutMode ? {
        type: layoutMode
      } : null;
    }
    /**
     * Consider Case:
     * When default 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 () {
     *         ...
     *         let inputPositionParams = layout.getLayoutParams(option);
     *         this.mergeOption(inputPositionParams);
     *     },
     *     mergeOption: function (newOption) {
     *         newOption && zrUtil.merge(thisOption, newOption, true);
     *         layout.mergeLayoutParam(thisOption, newOption);
     *     }
     * });
     *
     * @param targetOption
     * @param newOption
     * @param opt
     */

    function mergeLayoutParam(targetOption, newOption, opt) {
      var ignoreSize = opt && opt.ignoreSize;
      !isArray(ignoreSize) && (ignoreSize = [ignoreSize, ignoreSize]);
      var hResult = merge(HV_NAMES[0], 0);
      var vResult = merge(HV_NAMES[1], 1);
      copy(HV_NAMES[0], targetOption, hResult);
      copy(HV_NAMES[1], targetOption, vResult);

      function merge(names, hvIdx) {
        var newParams = {};
        var newValueCount = 0;
        var merged = {};
        var mergedValueCount = 0;
        var enoughParamNumber = 2;
        each$1(names, function (name) {
          merged[name] = targetOption[name];
        });
        each$1(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_1 = names[i];

              if (!hasProp(newParams, name_1) && hasProp(targetOption, name_1)) {
                newParams[name_1] = targetOption[name_1];
                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$1(names, function (name) {
          target[name] = source[name];
        });
      }
    }
    /**
     * Retrieve 'left', 'right', 'top', 'bottom', 'width', 'height' from object.
     */

    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$1(LOCATION_PARAMS, function (name) {
        source.hasOwnProperty(name) && (target[name] = source[name]);
      });
      return target;
    }

    var inner = makeInner();

    var ComponentModel =
    /** @class */
    function (_super) {
      __extends(ComponentModel, _super);

      function ComponentModel(option, parentModel, ecModel) {
        var _this = _super.call(this, option, parentModel, ecModel) || this;

        _this.uid = getUID('ec_cpt_model');
        return _this;
      }

      ComponentModel.prototype.init = function (option, parentModel, ecModel) {
        this.mergeDefaultAndTheme(option, ecModel);
      };

      ComponentModel.prototype.mergeDefaultAndTheme = function (option, ecModel) {
        var layoutMode = fetchLayoutMode(this);
        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);
        }
      };

      ComponentModel.prototype.mergeOption = function (option, ecModel) {
        merge(this.option, option, true);
        var layoutMode = fetchLayoutMode(this);

        if (layoutMode) {
          mergeLayoutParam(this.option, option, layoutMode);
        }
      };
      /**
       * Called immediately after `init` or `mergeOption` of this instance called.
       */


      ComponentModel.prototype.optionUpdated = function (newCptOption, isInit) {};
      /**
       * [How to declare defaultOption]:
       *
       * (A) If using class declaration in typescript (since echarts 5):
       * ```ts
       * import {ComponentOption} from '../model/option.js';
       * export interface XxxOption extends ComponentOption {
       *     aaa: number
       * }
       * export class XxxModel extends Component {
       *     static type = 'xxx';
       *     static defaultOption: XxxOption = {
       *         aaa: 123
       *     }
       * }
       * Component.registerClass(XxxModel);
       * ```
       * ```ts
       * import {inheritDefaultOption} from '../util/component.js';
       * import {XxxModel, XxxOption} from './XxxModel.js';
       * export interface XxxSubOption extends XxxOption {
       *     bbb: number
       * }
       * class XxxSubModel extends XxxModel {
       *     static defaultOption: XxxSubOption = inheritDefaultOption(XxxModel.defaultOption, {
       *         bbb: 456
       *     })
       *     fn() {
       *         let opt = this.getDefaultOption();
       *         // opt is {aaa: 123, bbb: 456}
       *     }
       * }
       * ```
       *
       * (B) If using class extend (previous approach in echarts 3 & 4):
       * ```js
       * let XxxComponent = Component.extend({
       *     defaultOption: {
       *         xx: 123
       *     }
       * })
       * ```
       * ```js
       * let XxxSubComponent = XxxComponent.extend({
       *     defaultOption: {
       *         yy: 456
       *     },
       *     fn: function () {
       *         let opt = this.getDefaultOption();
       *         // opt is {xx: 123, yy: 456}
       *     }
       * })
       * ```
       */


      ComponentModel.prototype.getDefaultOption = function () {
        var ctor = this.constructor; // If using class declaration, it is different to travel super class
        // in legacy env and auto merge defaultOption. So if using class
        // declaration, defaultOption should be merged manually.

        if (!isExtendedClass(ctor)) {
          // When using ts class, defaultOption must be declared as static.
          return ctor.defaultOption;
        } // FIXME: remove this approach?


        var fields = inner(this);

        if (!fields.defaultOption) {
          var optList = [];
          var clz = ctor;

          while (clz) {
            var opt = clz.prototype.defaultOption;
            opt && optList.push(opt);
            clz = clz.superClass;
          }

          var defaultOption = {};

          for (var i = optList.length - 1; i >= 0; i--) {
            defaultOption = merge(defaultOption, optList[i], true);
          }

          fields.defaultOption = defaultOption;
        }

        return fields.defaultOption;
      };
      /**
       * Notice: always force to input param `useDefault` in case that forget to consider it.
       * The same behavior as `modelUtil.parseFinder`.
       *
       * @param useDefault In many cases like series refer axis and axis refer grid,
       *        If axis index / axis id not specified, use the first target as default.
       *        In other cases like dataZoom refer axis, if not specified, measn no refer.
       */


      ComponentModel.prototype.getReferringComponents = function (mainType, opt) {
        var indexKey = mainType + 'Index';
        var idKey = mainType + 'Id';
        return queryReferringComponents(this.ecModel, mainType, {
          index: this.get(indexKey, true),
          id: this.get(idKey, true)
        }, opt);
      };

      ComponentModel.prototype.getBoxLayoutParams = function () {
        // Consider itself having box layout configs.
        var boxLayoutModel = this;
        return {
          left: boxLayoutModel.get('left'),
          top: boxLayoutModel.get('top'),
          right: boxLayoutModel.get('right'),
          bottom: boxLayoutModel.get('bottom'),
          width: boxLayoutModel.get('width'),
          height: boxLayoutModel.get('height')
        };
      };
      /**
       * Get key for zlevel.
       * If developers don't configure zlevel. We will assign zlevel to series based on the key.
       * For example, lines with trail effect and progressive series will in an individual zlevel.
       */


      ComponentModel.prototype.getZLevelKey = function () {
        return '';
      };

      ComponentModel.prototype.setZLevel = function (zlevel) {
        this.option.zlevel = zlevel;
      };

      ComponentModel.protoInitialize = function () {
        var proto = ComponentModel.prototype;
        proto.type = 'component';
        proto.id = '';
        proto.name = '';
        proto.mainType = '';
        proto.subType = '';
        proto.componentIndex = 0;
      }();

      return ComponentModel;
    }(Model);

    mountExtend(ComponentModel, Model);
    enableClassManagement(ComponentModel);
    enableSubTypeDefaulter(ComponentModel);
    enableTopologicalTravel(ComponentModel, getDependencies);

    function getDependencies(componentType) {
      var deps = [];
      each(ComponentModel.getClassesByMainType(componentType), function (clz) {
        deps = deps.concat(clz.dependencies || clz.prototype.dependencies || []);
      }); // Ensure main type.

      deps = map(deps, function (type) {
        return parseClassType(type).main;
      }); // Hack dataset for convenience.

      if (componentType !== 'dataset' && indexOf(deps, 'dataset') <= 0) {
        deps.unshift('dataset');
      }

      return deps;
    }

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


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * 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') {
      /* global navigator */
      platform = navigator.platform || '';
    }

    var decalColor = 'rgba(0, 0, 0, 0.2)';
    var globalDefault = {
      darkMode: 'auto',
      // backgroundColor: 'rgba(0,0,0,0)',
      colorBy: 'series',
      color: ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc'],
      gradientColor: ['#f6efa6', '#d88273', '#bf444c'],
      aria: {
        decal: {
          decals: [{
            color: decalColor,
            dashArrayX: [1, 0],
            dashArrayY: [2, 5],
            symbolSize: 1,
            rotation: Math.PI / 6
          }, {
            color: decalColor,
            symbol: 'circle',
            dashArrayX: [[8, 8], [0, 8, 8, 0]],
            dashArrayY: [6, 0],
            symbolSize: 0.8
          }, {
            color: decalColor,
            dashArrayX: [1, 0],
            dashArrayY: [4, 3],
            rotation: -Math.PI / 4
          }, {
            color: decalColor,
            dashArrayX: [[6, 6], [0, 6, 6, 0]],
            dashArrayY: [6, 0]
          }, {
            color: decalColor,
            dashArrayX: [[1, 0], [1, 6]],
            dashArrayY: [1, 0, 6, 0],
            rotation: Math.PI / 4
          }, {
            color: decalColor,
            symbol: 'triangle',
            dashArrayX: [[9, 9], [0, 9, 9, 0]],
            dashArrayY: [7, 2],
            symbolSize: 0.75
          }]
        }
      },
      // 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,
      stateAnimation: {
        duration: 300,
        easing: 'cubicOut'
      },
      animation: 'auto',
      animationDuration: 1000,
      animationDurationUpdate: 500,
      animationEasing: 'cubicInOut',
      animationEasingUpdate: 'cubicInOut',
      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
    };

    var VISUAL_DIMENSIONS = createHashMap(['tooltip', 'label', 'itemName', 'itemId', 'itemGroupId', 'seriesName']);
    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_TYPED_ARRAY = 'typedArray';
    var SOURCE_FORMAT_UNKNOWN = 'unknown';
    var SERIES_LAYOUT_BY_COLUMN = 'column';
    var SERIES_LAYOUT_BY_ROW = 'row';

    var BE_ORDINAL = {
      Must: 1,
      Might: 2,
      Not: 3 // Other cases

    };
    var innerGlobalModel = makeInner();
    /**
     * MUST be called before mergeOption of all series.
     */

    function resetSourceDefaulter(ecModel) {
      // `datasetMap` is used to make default encode.
      innerGlobalModel(ecModel).datasetMap = createHashMap();
    }
    /**
     * [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 |
     *
     * @return encode Never be `null/undefined`.
     */

    function makeSeriesEncodeForAxisCoordSys(coordDimensions, seriesModel, source) {
      var encode = {};
      var datasetModel = querySeriesUpstreamDatasetModel(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 = innerGlobalModel(ecModel).datasetMap;
      var key = datasetModel.uid + '_' + source.seriesLayoutBy;
      var baseCategoryDimIndex;
      var categoryWayValueDimStart;
      coordDimensions = coordDimensions.slice();
      each(coordDimensions, function (coordDimInfoLoose, coordDimIdx) {
        var coordDimInfo = isObject(coordDimInfoLoose) ? coordDimInfoLoose : coordDimensions[coordDimIdx] = {
          name: coordDimInfoLoose
        };

        if (coordDimInfo.type === 'ordinal' && baseCategoryDimIndex == null) {
          baseCategoryDimIndex = coordDimIdx;
          categoryWayValueDimStart = getDataDimCountOnCoordDim(coordDimInfo);
        }

        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(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 multiple series share one dimension
          // category axis, series name should better use
          // the other dimension 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: ...}, ...].
     *
     * @return encode Never be `null/undefined`.
     */

    function makeSeriesEncodeForNameBased(seriesModel, source, dimCount) {
      var encode = {};
      var datasetModel = querySeriesUpstreamDatasetModel(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(dimensionsDefine, function (dim, idx) {
          if ((isObject(dim) ? dim.name : dim) === 'name') {
            potentialNameDimIndex = idx;
          }
        });
      }

      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 uses itemName in charts.
        // So we don't set encodeLabel here.

        encode.itemName = [nameDimIndex];
        encode.seriesName = [nameDimIndex];
      }

      return encode;
    }
    /**
     * @return If return null/undefined, indicate that should not use datasetModel.
     */

    function querySeriesUpstreamDatasetModel(seriesModel) {
      // 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 = seriesModel.get('data', true);

      if (!thisData) {
        return queryReferringComponents(seriesModel.ecModel, 'dataset', {
          index: seriesModel.get('datasetIndex', true),
          id: seriesModel.get('datasetId', true)
        }, SINGLE_REFERRING).models[0];
      }
    }
    /**
     * @return Always return an array event empty.
     */

    function queryDatasetUpstreamDatasetModels(datasetModel) {
      // Only these attributes declared, we by defualt reference to `datasetIndex: 0`.
      // Otherwise, no reference.
      if (!datasetModel.get('transform', true) && !datasetModel.get('fromTransformResult', true)) {
        return [];
      }

      return queryReferringComponents(datasetModel.ecModel, 'dataset', {
        index: datasetModel.get('fromDatasetIndex', true),
        id: datasetModel.get('fromDatasetId', true)
      }, SINGLE_REFERRING).models;
    }
    /**
     * 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?
     */

    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(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) {
        var dataArrayRows = data;

        if (seriesLayoutBy === SERIES_LAYOUT_BY_ROW) {
          var sample = dataArrayRows[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 < dataArrayRows.length && i < maxLoop; i++) {
            var row = dataArrayRows[startIndex + i];

            if (row && (result = detectValue(row[dimIndex])) != null) {
              return result;
            }
          }
        }
      } else if (sourceFormat === SOURCE_FORMAT_OBJECT_ROWS) {
        var dataObjectRows = data;

        if (!dimName) {
          return BE_ORDINAL.Not;
        }

        for (var i = 0; i < dataObjectRows.length && i < maxLoop; i++) {
          var item = dataObjectRows[i];

          if (item && (result = detectValue(item[dimName])) != null) {
            return result;
          }
        }
      } else if (sourceFormat === SOURCE_FORMAT_KEYED_COLUMNS) {
        var dataKeyedColumns = data;

        if (!dimName) {
          return BE_ORDINAL.Not;
        }

        var sample = dataKeyedColumns[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) {
        var dataOriginal = data;

        for (var i = 0; i < dataOriginal.length && i < maxLoop; i++) {
          var item = dataOriginal[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;
    }

    var internalOptionCreatorMap = createHashMap();
    function registerInternalOptionCreator(mainType, creator) {
      assert(internalOptionCreatorMap.get(mainType) == null && creator);
      internalOptionCreatorMap.set(mainType, creator);
    }
    function concatInternalOptions(ecModel, mainType, newCmptOptionList) {
      var internalOptionCreator = internalOptionCreatorMap.get(mainType);

      if (!internalOptionCreator) {
        return newCmptOptionList;
      }

      var internalOptions = internalOptionCreator(ecModel);

      if (!internalOptions) {
        return newCmptOptionList;
      }

      if ("development" !== 'production') {
        for (var i = 0; i < internalOptions.length; i++) {
          assert(isComponentIdInternal(internalOptions[i]));
        }
      }

      return newCmptOptionList.concat(internalOptions);
    }

    var innerColor = makeInner();
    var innerDecal = makeInner();

    var PaletteMixin =
    /** @class */
    function () {
      function PaletteMixin() {}

      PaletteMixin.prototype.getColorFromPalette = function (name, scope, requestNum) {
        var defaultPalette = normalizeToArray(this.get('color', true));
        var layeredPalette = this.get('colorLayer', true);
        return getFromPalette(this, innerColor, defaultPalette, layeredPalette, name, scope, requestNum);
      };

      PaletteMixin.prototype.clearColorPalette = function () {
        clearPalette(this, innerColor);
      };

      return PaletteMixin;
    }();

    function getDecalFromPalette(ecModel, name, scope, requestNum) {
      var defaultDecals = normalizeToArray(ecModel.get(['aria', 'decal', 'decals']));
      return getFromPalette(ecModel, innerDecal, defaultDecals, null, name, scope, requestNum);
    }

    function getNearestPalette(palettes, requestColorNum) {
      var paletteNum = palettes.length; // TODO palettes must be in order

      for (var i = 0; i < paletteNum; i++) {
        if (palettes[i].length > requestColorNum) {
          return palettes[i];
        }
      }

      return palettes[paletteNum - 1];
    }
    /**
     * @param name MUST NOT be null/undefined. Otherwise call this function
     *             twise with the same parameters will get different result.
     * @param scope default this.
     * @return Can be null/undefined
     */


    function getFromPalette(that, inner, defaultPalette, layeredPalette, name, scope, requestNum) {
      scope = scope || that;
      var scopeFields = inner(scope);
      var paletteIdx = scopeFields.paletteIdx || 0;
      var paletteNameMap = scopeFields.paletteNameMap = scopeFields.paletteNameMap || {}; // Use `hasOwnProperty` to avoid conflict with Object.prototype.

      if (paletteNameMap.hasOwnProperty(name)) {
        return paletteNameMap[name];
      }

      var palette = requestNum == null || !layeredPalette ? defaultPalette : getNearestPalette(layeredPalette, requestNum); // In case can't find in layered color palette.

      palette = palette || defaultPalette;

      if (!palette || !palette.length) {
        return;
      }

      var pickedPaletteItem = palette[paletteIdx];

      if (name) {
        paletteNameMap[name] = pickedPaletteItem;
      }

      scopeFields.paletteIdx = (paletteIdx + 1) % palette.length;
      return pickedPaletteItem;
    }

    function clearPalette(that, inner) {
      inner(that).paletteIdx = 0;
      inner(that).paletteNameMap = {};
    }

    // Internal method names:
    // -----------------------

    var reCreateSeriesIndices;
    var assertSeriesInitialized;
    var initBase;
    var OPTION_INNER_KEY = '\0_ec_inner';
    var OPTION_INNER_VALUE = 1;
    var BUITIN_COMPONENTS_MAP = {
      grid: 'GridComponent',
      polar: 'PolarComponent',
      geo: 'GeoComponent',
      singleAxis: 'SingleAxisComponent',
      parallel: 'ParallelComponent',
      calendar: 'CalendarComponent',
      graphic: 'GraphicComponent',
      toolbox: 'ToolboxComponent',
      tooltip: 'TooltipComponent',
      axisPointer: 'AxisPointerComponent',
      brush: 'BrushComponent',
      title: 'TitleComponent',
      timeline: 'TimelineComponent',
      markPoint: 'MarkPointComponent',
      markLine: 'MarkLineComponent',
      markArea: 'MarkAreaComponent',
      legend: 'LegendComponent',
      dataZoom: 'DataZoomComponent',
      visualMap: 'VisualMapComponent',
      // aria: 'AriaComponent',
      // dataset: 'DatasetComponent',
      // Dependencies
      xAxis: 'GridComponent',
      yAxis: 'GridComponent',
      angleAxis: 'PolarComponent',
      radiusAxis: 'PolarComponent'
    };
    var BUILTIN_CHARTS_MAP = {
      line: 'LineChart',
      bar: 'BarChart',
      pie: 'PieChart',
      scatter: 'ScatterChart',
      radar: 'RadarChart',
      map: 'MapChart',
      tree: 'TreeChart',
      treemap: 'TreemapChart',
      graph: 'GraphChart',
      gauge: 'GaugeChart',
      funnel: 'FunnelChart',
      parallel: 'ParallelChart',
      sankey: 'SankeyChart',
      boxplot: 'BoxplotChart',
      candlestick: 'CandlestickChart',
      effectScatter: 'EffectScatterChart',
      lines: 'LinesChart',
      heatmap: 'HeatmapChart',
      pictorialBar: 'PictorialBarChart',
      themeRiver: 'ThemeRiverChart',
      sunburst: 'SunburstChart',
      custom: 'CustomChart'
    };
    var componetsMissingLogPrinted = {};

    function checkMissingComponents(option) {
      each(option, function (componentOption, mainType) {
        if (!ComponentModel.hasClass(mainType)) {
          var componentImportName = BUITIN_COMPONENTS_MAP[mainType];

          if (componentImportName && !componetsMissingLogPrinted[componentImportName]) {
            error("Component " + mainType + " is used but not imported.\nimport { " + componentImportName + " } from 'echarts/components';\necharts.use([" + componentImportName + "]);");
            componetsMissingLogPrinted[componentImportName] = true;
          }
        }
      });
    }

    var GlobalModel =
    /** @class */
    function (_super) {
      __extends(GlobalModel, _super);

      function GlobalModel() {
        return _super !== null && _super.apply(this, arguments) || this;
      }

      GlobalModel.prototype.init = function (option, parentModel, ecModel, theme, locale, optionManager) {
        theme = theme || {};
        this.option = null; // Mark as not initialized.

        this._theme = new Model(theme);
        this._locale = new Model(locale);
        this._optionManager = optionManager;
      };

      GlobalModel.prototype.setOption = function (option, opts, optionPreprocessorFuncs) {
        if ("development" !== 'production') {
          assert(option != null, 'option is null/undefined');
          assert(option[OPTION_INNER_KEY] !== OPTION_INNER_VALUE, 'please use chart.getOption()');
        }

        var innerOpt = normalizeSetOptionInput(opts);

        this._optionManager.setOption(option, optionPreprocessorFuncs, innerOpt);

        this._resetOption(null, innerOpt);
      };
      /**
       * @param type null/undefined: reset all.
       *        'recreate': force recreate all.
       *        'timeline': only reset timeline option
       *        'media': only reset media query option
       * @return Whether option changed.
       */


      GlobalModel.prototype.resetOption = function (type, opt) {
        return this._resetOption(type, normalizeSetOptionInput(opt));
      };

      GlobalModel.prototype._resetOption = function (type, opt) {
        var optionChanged = false;
        var optionManager = this._optionManager;

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

          if ("development" !== 'production') {
            checkMissingComponents(baseOption);
          }

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

            this._mergeOption(baseOption, opt);
          }

          optionChanged = true;
        }

        if (type === 'timeline' || type === 'media') {
          this.restoreData();
        } // By design, if `setOption(option2)` at the second time, and `option2` is a `ECUnitOption`,
        // it should better not have the same props with `MediaUnit['option']`.
        // Because either `option2` or `MediaUnit['option']` will be always merged to "current option"
        // rather than original "baseOption". If they both override a prop, the result might be
        // unexpected when media state changed after `setOption` called.
        // If we really need to modify a props in each `MediaUnit['option']`, use the full version
        // (`{baseOption, media}`) in `setOption`.
        // For `timeline`, the case is the same.


        if (!type || type === 'recreate' || type === 'timeline') {
          var timelineOption = optionManager.getTimelineOption(this);

          if (timelineOption) {
            optionChanged = true;

            this._mergeOption(timelineOption, opt);
          }
        }

        if (!type || type === 'recreate' || type === 'media') {
          var mediaOptions = optionManager.getMediaOption(this);

          if (mediaOptions.length) {
            each(mediaOptions, function (mediaOption) {
              optionChanged = true;

              this._mergeOption(mediaOption, opt);
            }, this);
          }
        }

        return optionChanged;
      };

      GlobalModel.prototype.mergeOption = function (option) {
        this._mergeOption(option, null);
      };

      GlobalModel.prototype._mergeOption = function (newOption, opt) {
        var option = this.option;
        var componentsMap = this._componentsMap;
        var componentsCount = this._componentsCount;
        var newCmptTypes = [];
        var newCmptTypeMap = createHashMap();
        var replaceMergeMainTypeMap = opt && opt.replaceMergeMainTypeMap;
        resetSourceDefaulter(this); // If no component class, merge directly.
        // For example: color, animaiton options, etc.

        each(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) {
            newCmptTypes.push(mainType);
            newCmptTypeMap.set(mainType, true);
          }
        });

        if (replaceMergeMainTypeMap) {
          // If there is a mainType `xxx` in `replaceMerge` but not declared in option,
          // we trade it as it is declared in option as `{xxx: []}`. Because:
          // (1) for normal merge, `{xxx: null/undefined}` are the same meaning as `{xxx: []}`.
          // (2) some preprocessor may convert some of `{xxx: null/undefined}` to `{xxx: []}`.
          replaceMergeMainTypeMap.each(function (val, mainTypeInReplaceMerge) {
            if (ComponentModel.hasClass(mainTypeInReplaceMerge) && !newCmptTypeMap.get(mainTypeInReplaceMerge)) {
              newCmptTypes.push(mainTypeInReplaceMerge);
              newCmptTypeMap.set(mainTypeInReplaceMerge, true);
            }
          });
        }

        ComponentModel.topologicalTravel(newCmptTypes, ComponentModel.getAllClassMainTypes(), visitComponent, this);

        function visitComponent(mainType) {
          var newCmptOptionList = concatInternalOptions(this, mainType, normalizeToArray(newOption[mainType]));
          var oldCmptList = componentsMap.get(mainType);
          var mergeMode = // `!oldCmptList` means init. See the comment in `mappingToExists`
          !oldCmptList ? 'replaceAll' : replaceMergeMainTypeMap && replaceMergeMainTypeMap.get(mainType) ? 'replaceMerge' : 'normalMerge';
          var mappingResult = mappingToExists(oldCmptList, newCmptOptionList, mergeMode); // Set mainType and complete subType.

          setComponentTypeToKeyInfo(mappingResult, mainType, ComponentModel); // Empty it before the travel, in order to prevent `this._componentsMap`
          // from being used in the `init`/`mergeOption`/`optionUpdated` of some
          // components, which is probably incorrect logic.

          option[mainType] = null;
          componentsMap.set(mainType, null);
          componentsCount.set(mainType, 0);
          var optionsByMainType = [];
          var cmptsByMainType = [];
          var cmptsCountByMainType = 0;
          var tooltipExists;
          var tooltipWarningLogged;
          each(mappingResult, function (resultItem, index) {
            var componentModel = resultItem.existing;
            var newCmptOption = resultItem.newOption;

            if (!newCmptOption) {
              if (componentModel) {
                // Consider where is no new option and should be merged using {},
                // see removeEdgeAndAdd in topologicalTravel and
                // ComponentModel.getAllClassMainTypes.
                componentModel.mergeOption({}, this);
                componentModel.optionUpdated({}, false);
              } // If no both `resultItem.exist` and `resultItem.option`,
              // either it is in `replaceMerge` and not matched by any id,
              // or it has been removed in previous `replaceMerge` and left a "hole" in this component index.

            } else {
              var isSeriesType = mainType === 'series';
              var ComponentModelClass = ComponentModel.getClass(mainType, resultItem.keyInfo.subType, !isSeriesType // Give a more detailed warn later if series don't exists
              );

              if (!ComponentModelClass) {
                if ("development" !== 'production') {
                  var subType = resultItem.keyInfo.subType;
                  var seriesImportName = BUILTIN_CHARTS_MAP[subType];

                  if (!componetsMissingLogPrinted[subType]) {
                    componetsMissingLogPrinted[subType] = true;

                    if (seriesImportName) {
                      error("Series " + subType + " is used but not imported.\nimport { " + seriesImportName + " } from 'echarts/charts';\necharts.use([" + seriesImportName + "]);");
                    } else {
                      error("Unknown series " + subType);
                    }
                  }
                }

                return;
              } // TODO Before multiple tooltips get supported, we do this check to avoid unexpected exception.


              if (mainType === 'tooltip') {
                if (tooltipExists) {
                  if ("development" !== 'production') {
                    if (!tooltipWarningLogged) {
                      warn('Currently only one tooltip component is allowed.');
                      tooltipWarningLogged = true;
                    }
                  }

                  return;
                }

                tooltipExists = true;
              }

              if (componentModel && componentModel.constructor === ComponentModelClass) {
                componentModel.name = resultItem.keyInfo.name; // componentModel.settingTask && componentModel.settingTask.dirty();

                componentModel.mergeOption(newCmptOption, this);
                componentModel.optionUpdated(newCmptOption, false);
              } else {
                // PENDING Global as parent ?
                var extraOpt = extend({
                  componentIndex: index
                }, resultItem.keyInfo);
                componentModel = new ComponentModelClass(newCmptOption, this, this, extraOpt); // Assign `keyInfo`

                extend(componentModel, extraOpt);

                if (resultItem.brandNew) {
                  componentModel.__requireNewView = true;
                }

                componentModel.init(newCmptOption, this, this); // Call optionUpdated after init.
                // newCmptOption has been used as componentModel.option
                // and may be merged with theme and default, so pass null
                // to avoid confusion.

                componentModel.optionUpdated(null, true);
              }
            }

            if (componentModel) {
              optionsByMainType.push(componentModel.option);
              cmptsByMainType.push(componentModel);
              cmptsCountByMainType++;
            } else {
              // Always do assign to avoid elided item in array.
              optionsByMainType.push(void 0);
              cmptsByMainType.push(void 0);
            }
          }, this);
          option[mainType] = optionsByMainType;
          componentsMap.set(mainType, cmptsByMainType);
          componentsCount.set(mainType, cmptsCountByMainType); // Backup series for filtering.

          if (mainType === 'series') {
            reCreateSeriesIndices(this);
          }
        } // If no series declared, ensure `_seriesIndices` initialized.


        if (!this._seriesIndices) {
          reCreateSeriesIndices(this);
        }
      };
      /**
       * Get option for output (cloned option and inner info removed)
       */


      GlobalModel.prototype.getOption = function () {
        var option = clone(this.option);
        each(option, function (optInMainType, mainType) {
          if (ComponentModel.hasClass(mainType)) {
            var opts = normalizeToArray(optInMainType); // Inner cmpts need to be removed.
            // Inner cmpts might not be at last since ec5.0, but still
            // compatible for users: if inner cmpt at last, splice the returned array.

            var realLen = opts.length;
            var metNonInner = false;

            for (var i = realLen - 1; i >= 0; i--) {
              // Remove options with inner id.
              if (opts[i] && !isComponentIdInternal(opts[i])) {
                metNonInner = true;
              } else {
                opts[i] = null;
                !metNonInner && realLen--;
              }
            }

            opts.length = realLen;
            option[mainType] = opts;
          }
        });
        delete option[OPTION_INNER_KEY];
        return option;
      };

      GlobalModel.prototype.getTheme = function () {
        return this._theme;
      };

      GlobalModel.prototype.getLocaleModel = function () {
        return this._locale;
      };

      GlobalModel.prototype.setUpdatePayload = function (payload) {
        this._payload = payload;
      };

      GlobalModel.prototype.getUpdatePayload = function () {
        return this._payload;
      };
      /**
       * @param idx If not specified, return the first one.
       */


      GlobalModel.prototype.getComponent = function (mainType, idx) {
        var list = this._componentsMap.get(mainType);

        if (list) {
          var cmpt = list[idx || 0];

          if (cmpt) {
            return cmpt;
          } else if (idx == null) {
            for (var i = 0; i < list.length; i++) {
              if (list[i]) {
                return list[i];
              }
            }
          }
        }
      };
      /**
       * @return Never be null/undefined.
       */


      GlobalModel.prototype.queryComponents = function (condition) {
        var mainType = condition.mainType;

        if (!mainType) {
          return [];
        }

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

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

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

        var result;

        if (index != null) {
          result = [];
          each(normalizeToArray(index), function (idx) {
            cmpts[idx] && result.push(cmpts[idx]);
          });
        } else if (id != null) {
          result = queryByIdOrName('id', id, cmpts);
        } else if (name != null) {
          result = queryByIdOrName('name', name, cmpts);
        } else {
          // Return all non-empty components in that mainType
          result = filter(cmpts, function (cmpt) {
            return !!cmpt;
          });
        }

        return filterBySubType(result, condition);
      };
      /**
       * The interface is different from queryComponents,
       * which is convenient for inner usage.
       *
       * @usage
       * let result = findComponents(
       *     {mainType: 'dataZoom', query: {dataZoomId: 'abc'}}
       * );
       * let result = findComponents(
       *     {mainType: 'series', subType: 'pie', query: {seriesName: 'uio'}}
       * );
       * let result = findComponents(
       *     {mainType: 'series',
       *     filter: function (model, index) {...}}
       * );
       * // result like [component0, componnet1, ...]
       */


      GlobalModel.prototype.findComponents = function (condition) {
        var query = condition.query;
        var mainType = condition.mainType;
        var queryCond = getQueryCond(query);
        var result = queryCond ? this.queryComponents(queryCond) // Retrieve all non-empty components.
        : filter(this._componentsMap.get(mainType), function (cmpt) {
          return !!cmpt;
        });
        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;
        }
      };

      GlobalModel.prototype.eachComponent = function (mainType, cb, context) {
        var componentsMap = this._componentsMap;

        if (isFunction(mainType)) {
          var ctxForAll_1 = cb;
          var cbForAll_1 = mainType;
          componentsMap.each(function (cmpts, componentType) {
            for (var i = 0; cmpts && i < cmpts.length; i++) {
              var cmpt = cmpts[i];
              cmpt && cbForAll_1.call(ctxForAll_1, componentType, cmpt, cmpt.componentIndex);
            }
          });
        } else {
          var cmpts = isString(mainType) ? componentsMap.get(mainType) : isObject(mainType) ? this.findComponents(mainType) : null;

          for (var i = 0; cmpts && i < cmpts.length; i++) {
            var cmpt = cmpts[i];
            cmpt && cb.call(context, cmpt, cmpt.componentIndex);
          }
        }
      };
      /**
       * Get series list before filtered by name.
       */


      GlobalModel.prototype.getSeriesByName = function (name) {
        var nameStr = convertOptionIdName(name, null);
        return filter(this._componentsMap.get('series'), function (oneSeries) {
          return !!oneSeries && nameStr != null && oneSeries.name === nameStr;
        });
      };
      /**
       * Get series list before filtered by index.
       */


      GlobalModel.prototype.getSeriesByIndex = function (seriesIndex) {
        return this._componentsMap.get('series')[seriesIndex];
      };
      /**
       * Get series list before filtered by type.
       * FIXME: rename to getRawSeriesByType?
       */


      GlobalModel.prototype.getSeriesByType = function (subType) {
        return filter(this._componentsMap.get('series'), function (oneSeries) {
          return !!oneSeries && oneSeries.subType === subType;
        });
      };
      /**
       * Get all series before filtered.
       */


      GlobalModel.prototype.getSeries = function () {
        return filter(this._componentsMap.get('series'), function (oneSeries) {
          return !!oneSeries;
        });
      };
      /**
       * Count series before filtered.
       */


      GlobalModel.prototype.getSeriesCount = function () {
        return this._componentsCount.get('series');
      };
      /**
       * After filtering, series may be different
       * from raw series.
       */


      GlobalModel.prototype.eachSeries = function (cb, context) {
        assertSeriesInitialized(this);
        each(this._seriesIndices, function (rawSeriesIndex) {
          var series = this._componentsMap.get('series')[rawSeriesIndex];

          cb.call(context, series, rawSeriesIndex);
        }, this);
      };
      /**
       * Iterate raw series before filtered.
       *
       * @param {Function} cb
       * @param {*} context
       */


      GlobalModel.prototype.eachRawSeries = function (cb, context) {
        each(this._componentsMap.get('series'), function (series) {
          series && cb.call(context, series, series.componentIndex);
        });
      };
      /**
       * After filtering, series may be different.
       * from raw series.
       */


      GlobalModel.prototype.eachSeriesByType = function (subType, cb, context) {
        assertSeriesInitialized(this);
        each(this._seriesIndices, function (rawSeriesIndex) {
          var series = this._componentsMap.get('series')[rawSeriesIndex];

          if (series.subType === subType) {
            cb.call(context, series, rawSeriesIndex);
          }
        }, this);
      };
      /**
       * Iterate raw series before filtered of given type.
       */


      GlobalModel.prototype.eachRawSeriesByType = function (subType, cb, context) {
        return each(this.getSeriesByType(subType), cb, context);
      };

      GlobalModel.prototype.isSeriesFiltered = function (seriesModel) {
        assertSeriesInitialized(this);
        return this._seriesIndicesMap.get(seriesModel.componentIndex) == null;
      };

      GlobalModel.prototype.getCurrentSeriesIndices = function () {
        return (this._seriesIndices || []).slice();
      };

      GlobalModel.prototype.filterSeries = function (cb, context) {
        assertSeriesInitialized(this);
        var newSeriesIndices = [];
        each(this._seriesIndices, function (seriesRawIdx) {
          var series = this._componentsMap.get('series')[seriesRawIdx];

          cb.call(context, series, seriesRawIdx) && newSeriesIndices.push(seriesRawIdx);
        }, this);
        this._seriesIndices = newSeriesIndices;
        this._seriesIndicesMap = createHashMap(newSeriesIndices);
      };

      GlobalModel.prototype.restoreData = function (payload) {
        reCreateSeriesIndices(this);
        var componentsMap = this._componentsMap;
        var componentTypes = [];
        componentsMap.each(function (components, componentType) {
          if (ComponentModel.hasClass(componentType)) {
            componentTypes.push(componentType);
          }
        });
        ComponentModel.topologicalTravel(componentTypes, ComponentModel.getAllClassMainTypes(), function (componentType) {
          each(componentsMap.get(componentType), function (component) {
            if (component && (componentType !== 'series' || !isNotTargetSeries(component, payload))) {
              component.restoreData();
            }
          });
        });
      };

      GlobalModel.internalField = function () {
        reCreateSeriesIndices = function (ecModel) {
          var seriesIndices = ecModel._seriesIndices = [];
          each(ecModel._componentsMap.get('series'), function (series) {
            // series may have been removed by `replaceMerge`.
            series && seriesIndices.push(series.componentIndex);
          });
          ecModel._seriesIndicesMap = createHashMap(seriesIndices);
        };

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

        initBase = function (ecModel, baseOption) {
          // Using OPTION_INNER_KEY to mark that this option cannot be used outside,
          // i.e. `chart.setOption(chart.getModel().option);` is forbidden.
          ecModel.option = {};
          ecModel.option[OPTION_INNER_KEY] = OPTION_INNER_VALUE; // Init with series: [], in case of calling findSeries method
          // before series initialized.

          ecModel._componentsMap = createHashMap({
            series: []
          });
          ecModel._componentsCount = createHashMap(); // If user spefied `option.aria`, aria will be enable. This detection should be
          // performed before theme and globalDefault merge.

          var airaOption = baseOption.aria;

          if (isObject(airaOption) && airaOption.enabled == null) {
            airaOption.enabled = true;
          }

          mergeTheme(baseOption, ecModel._theme.option); // TODO Needs clone when merging to the unexisted property

          merge(baseOption, globalDefault, false);

          ecModel._mergeOption(baseOption, null);
        };
      }();

      return GlobalModel;
    }(Model);

    function isNotTargetSeries(seriesModel, payload) {
      if (payload) {
        var index = payload.seriesIndex;
        var id = payload.seriesId;
        var name_1 = payload.seriesName;
        return index != null && seriesModel.componentIndex !== index || id != null && seriesModel.id !== id || name_1 != null && seriesModel.name !== name_1;
      }
    }

    function mergeTheme(option, theme) {
      // PENDING
      // NOT use `colorLayer` in theme if option has `color`
      var notMergeColorLayer = option.color && !option.colorLayer;
      each(theme, function (themeItem, name) {
        if (name === 'colorLayer' && notMergeColorLayer) {
          return;
        } // If it is component model mainType, the model handles that merge later.
        // otherwise, merge them here.


        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 queryByIdOrName(attr, idOrName, cmpts) {
      // Here is a break from echarts4: string and number are
      // treated as equal.
      if (isArray(idOrName)) {
        var keyMap_1 = createHashMap();
        each(idOrName, function (idOrNameItem) {
          if (idOrNameItem != null) {
            var idName = convertOptionIdName(idOrNameItem, null);
            idName != null && keyMap_1.set(idOrNameItem, true);
          }
        });
        return filter(cmpts, function (cmpt) {
          return cmpt && keyMap_1.get(cmpt[attr]);
        });
      } else {
        var idName_1 = convertOptionIdName(idOrName, null);
        return filter(cmpts, function (cmpt) {
          return cmpt && idName_1 != null && cmpt[attr] === idName_1;
        });
      }
    }

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

    function normalizeSetOptionInput(opts) {
      var replaceMergeMainTypeMap = createHashMap();
      opts && each(normalizeToArray(opts.replaceMerge), function (mainType) {
        if ("development" !== 'production') {
          assert(ComponentModel.hasClass(mainType), '"' + mainType + '" is not valid component main type in "replaceMerge"');
        }

        replaceMergeMainTypeMap.set(mainType, true);
      });
      return {
        replaceMergeMainTypeMap: replaceMergeMainTypeMap
      };
    }

    mixin(GlobalModel, PaletteMixin);

    var availableMethods = ['getDom', 'getZr', 'getWidth', 'getHeight', 'getDevicePixelRatio', 'dispatchAction', 'isSSR', 'isDisposed', 'on', 'off', 'getDataURL', 'getConnectedDataURL', // 'getModel',
    'getOption', // 'getViewOfComponentModel',
    // 'getViewOfSeriesModel',
    'getId', 'updateLabelLayout'];

    var ExtensionAPI =
    /** @class */
    function () {
      function ExtensionAPI(ecInstance) {
        each(availableMethods, function (methodName) {
          this[methodName] = bind(ecInstance[methodName], ecInstance);
        }, this);
      }

      return ExtensionAPI;
    }();

    var coordinateSystemCreators = {};

    var CoordinateSystemManager =
    /** @class */
    function () {
      function CoordinateSystemManager() {
        this._coordinateSystems = [];
      }

      CoordinateSystemManager.prototype.create = function (ecModel, api) {
        var coordinateSystems = [];
        each(coordinateSystemCreators, function (creator, type) {
          var list = creator.create(ecModel, api);
          coordinateSystems = coordinateSystems.concat(list || []);
        });
        this._coordinateSystems = coordinateSystems;
      };

      CoordinateSystemManager.prototype.update = function (ecModel, api) {
        each(this._coordinateSystems, function (coordSys) {
          coordSys.update && coordSys.update(ecModel, api);
        });
      };

      CoordinateSystemManager.prototype.getCoordinateSystems = function () {
        return this._coordinateSystems.slice();
      };

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

      CoordinateSystemManager.get = function (type) {
        return coordinateSystemCreators[type];
      };

      return CoordinateSystemManager;
    }();

    var QUERY_REG = /^(min|max)?(.+)$/; // Key: mainType
    // type FakeComponentsMap = HashMap<(MappingExistingItem & { subType: string })[]>;

    /**
     * TERM EXPLANATIONS:
     * See `ECOption` and `ECUnitOption` in `src/util/types.ts`.
     */

    var OptionManager =
    /** @class */
    function () {
      // 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);
      function OptionManager(api) {
        this._timelineOptions = [];
        this._mediaList = [];
        /**
         * -1, means default.
         * empty means no media.
         */

        this._currentMediaIndices = [];
        this._api = api;
      }

      OptionManager.prototype.setOption = function (rawOption, optionPreprocessorFuncs, opt) {
        if (rawOption) {
          // That set dat primitive is dangerous if user reuse the data when setOption again.
          each(normalizeToArray(rawOption.series), function (series) {
            series && series.data && isTypedArray(series.data) && setAsPrimitive(series.data);
          });
          each(normalizeToArray(rawOption.dataset), function (dataset) {
            dataset && dataset.source && isTypedArray(dataset.source) && setAsPrimitive(dataset.source);
          });
        } // 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(rawOption); // FIXME
        // If some property is set in timeline options or media option but
        // not set in baseOption, a warning should be given.

        var optionBackup = this._optionBackup;
        var newParsedOption = parseRawOption(rawOption, optionPreprocessorFuncs, !optionBackup);
        this._newBaseOption = newParsedOption.baseOption; // For setOption at second time (using merge mode);

        if (optionBackup) {
          // FIXME
          // the restore merge solution is essentially incorrect.
          // the mapping can not be 100% consistent with ecModel, which probably brings
          // potential bug!
          // The first merge is delayed, because in most cases, users do not call `setOption` twice.
          // let fakeCmptsMap = this._fakeCmptsMap;
          // if (!fakeCmptsMap) {
          //     fakeCmptsMap = this._fakeCmptsMap = createHashMap();
          //     mergeToBackupOption(fakeCmptsMap, null, optionBackup.baseOption, null);
          // }
          // mergeToBackupOption(
          //     fakeCmptsMap, optionBackup.baseOption, newParsedOption.baseOption, opt
          // );
          // 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 options will not be merged to the former, but just substitute them.
          if (newParsedOption.timelineOptions.length) {
            optionBackup.timelineOptions = newParsedOption.timelineOptions;
          }

          if (newParsedOption.mediaList.length) {
            optionBackup.mediaList = newParsedOption.mediaList;
          }

          if (newParsedOption.mediaDefault) {
            optionBackup.mediaDefault = newParsedOption.mediaDefault;
          }
        } else {
          this._optionBackup = newParsedOption;
        }
      };

      OptionManager.prototype.mountOption = function (isRecreate) {
        var optionBackup = this._optionBackup;
        this._timelineOptions = optionBackup.timelineOptions;
        this._mediaList = optionBackup.mediaList;
        this._mediaDefault = optionBackup.mediaDefault;
        this._currentMediaIndices = [];
        return clone(isRecreate // this._optionBackup.baseOption, which is created at the first `setOption`
        // called, and is merged into every new option by inner method `mergeToBackupOption`
        // 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);
      };

      OptionManager.prototype.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( // FIXME:TS as TimelineModel or quivlant interface
            timelineOptions[timelineModel.getCurrentIndex()]);
          }
        }

        return option;
      };

      OptionManager.prototype.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
        // Whether mediaDefault should force users to provide? Otherwise
        // the change by media query can not be recorvered.


        if (!indices.length && mediaDefault) {
          indices = [-1];
        }

        if (indices.length && !indicesEquals(indices, this._currentMediaIndices)) {
          result = map(indices, function (index) {
            return clone(index === -1 ? mediaDefault.option : mediaList[index].option);
          });
        } // Otherwise return nothing.


        this._currentMediaIndices = indices;
        return result;
      };

      return OptionManager;
    }();
    /**
     * [RAW_OPTION_PATTERNS]
     * (Note: "series: []" represents all other props in `ECUnitOption`)
     *
     * (1) No prop "baseOption" declared:
     * Root option is used as "baseOption" (except prop "options" and "media").
     * ```js
     * option = {
     *     series: [],
     *     timeline: {},
     *     options: [],
     * };
     * option = {
     *     series: [],
     *     media: {},
     * };
     * option = {
     *     series: [],
     *     timeline: {},
     *     options: [],
     *     media: {},
     * }
     * ```
     *
     * (2) Prop "baseOption" declared:
     * If "baseOption" declared, `ECUnitOption` props can only be declared
     * inside "baseOption" except prop "timeline" (compat ec2).
     * ```js
     * option = {
     *     baseOption: {
     *         timeline: {},
     *         series: [],
     *     },
     *     options: []
     * };
     * option = {
     *     baseOption: {
     *         series: [],
     *     },
     *     media: []
     * };
     * option = {
     *     baseOption: {
     *         timeline: {},
     *         series: [],
     *     },
     *     options: []
     *     media: []
     * };
     * option = {
     *     // ec3 compat ec2: allow (only) `timeline` declared
     *     // outside baseOption. Keep this setting for compat.
     *     timeline: {},
     *     baseOption: {
     *         series: [],
     *     },
     *     options: [],
     *     media: []
     * };
     * ```
     */


    function parseRawOption( // `rawOption` May be modified
    rawOption, optionPreprocessorFuncs, isNew) {
      var mediaList = [];
      var mediaDefault;
      var baseOption;
      var declaredBaseOption = rawOption.baseOption; // Compatible with ec2, [RAW_OPTION_PATTERNS] above.

      var timelineOnRoot = rawOption.timeline;
      var timelineOptionsOnRoot = rawOption.options;
      var mediaOnRoot = rawOption.media;
      var hasMedia = !!rawOption.media;
      var hasTimeline = !!(timelineOptionsOnRoot || timelineOnRoot || declaredBaseOption && declaredBaseOption.timeline);

      if (declaredBaseOption) {
        baseOption = declaredBaseOption; // For merge option.

        if (!baseOption.timeline) {
          baseOption.timeline = timelineOnRoot;
        }
      } // For convenience, enable to use the root option as the `baseOption`:
      // `{ ...normalOptionProps, media: [{ ... }, { ... }] }`
      else {
          if (hasTimeline || hasMedia) {
            rawOption.options = rawOption.media = null;
          }

          baseOption = rawOption;
        }

      if (hasMedia) {
        if (isArray(mediaOnRoot)) {
          each(mediaOnRoot, function (singleMedia) {
            if ("development" !== 'production') {
              // Real case of wrong config.
              if (singleMedia && !singleMedia.option && isObject(singleMedia.query) && isObject(singleMedia.query.option)) {
                error('Illegal media option. Must be like { media: [ { query: {}, option: {} } ] }');
              }
            }

            if (singleMedia && singleMedia.option) {
              if (singleMedia.query) {
                mediaList.push(singleMedia);
              } else if (!mediaDefault) {
                // Use the first media default.
                mediaDefault = singleMedia;
              }
            }
          });
        } else {
          if ("development" !== 'production') {
            // Real case of wrong config.
            error('Illegal media option. Must be an array. Like { media: [ {...}, {...} ] }');
          }
        }
      }

      doPreprocess(baseOption);
      each(timelineOptionsOnRoot, function (option) {
        return doPreprocess(option);
      });
      each(mediaList, function (media) {
        return doPreprocess(media.option);
      });

      function doPreprocess(option) {
        each(optionPreprocessorFuncs, function (preProcess) {
          preProcess(option, isNew);
        });
      }

      return {
        baseOption: baseOption,
        timelineOptions: timelineOptionsOnRoot || [],
        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 // lower case for convenience.

      };
      var applicable = true;
      each(query, function (value, attr) {
        var matched = attr.match(QUERY_REG);

        if (!matched || !matched[1] || !matched[2]) {
          return;
        }

        var operator = matched[1];
        var realAttr = matched[2].toLowerCase();

        if (!compare(realMap[realAttr], value, operator)) {
          applicable = false;
        }
      });
      return applicable;
    }

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

    var each$2 = each;
    var isObject$1 = isObject;
    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]) {
          if ("development" !== 'production') {
            deprecateReplaceLog("itemStyle.normal." + styleName, 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]) {
          if ("development" !== 'production') {
            deprecateReplaceLog("itemStyle.emphasis." + styleName, "emphasis." + 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) {
          if ("development" !== 'production') {
            // eslint-disable-next-line max-len
            deprecateLog("'normal' hierarchy in " + optType + " has been removed since 4.0. All style properties are configured in " + optType + " directly now.");
          } // 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) {
          if ("development" !== 'production') {
            deprecateLog(optType + ".emphasis has been changed to emphasis." + optType + " since 4.0");
          }

          opt.emphasis = opt.emphasis || {};
          opt.emphasis[optType] = emphasisOpt; // Also compat the case user mix the style and focus together in ec3 style
          // for example: { itemStyle: { normal: {}, emphasis: {focus, shadowBlur} } }

          if (emphasisOpt.focus) {
            opt.emphasis.focus = emphasisOpt.focus;
          }

          if (emphasisOpt.blurScope) {
            opt.emphasis.blurScope = emphasisOpt.blurScope;
          }
        }
      }
    }

    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$1(opt) && opt[propName];
      var textStyle = isObject$1(labelOptSingle) && labelOptSingle.textStyle;

      if (textStyle) {
        if ("development" !== 'production') {
          // eslint-disable-next-line max-len
          deprecateLog("textStyle hierarchy in " + propName + " has been removed since 4.0. All textStyle properties are configured in " + propName + " directly now.");
        }

        for (var i = 0, len = TEXT_STYLE_OPTIONS.length; i < len; i++) {
          var textPropName = TEXT_STYLE_OPTIONS[i];

          if (textStyle.hasOwnProperty(textPropName)) {
            labelOptSingle[textPropName] = textStyle[textPropName];
          }
        }
      }
    }

    function compatEC3CommonStyles(opt) {
      if (opt) {
        removeEC3NormalStatus(opt);
        compatTextStyle(opt, 'label');
        opt.emphasis && compatTextStyle(opt.emphasis, 'label');
      }
    }

    function processSeries(seriesOpt) {
      if (!isObject$1(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(seriesOpt.categories, function (opt) {
          removeEC3NormalStatus(opt);
        });
      }

      if (data && !isTypedArray(data)) {
        for (var i = 0; i < data.length; i++) {
          compatEC3CommonStyles(data[i]);
        }
      } // mark point data


      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


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

    function globalCompatStyle(option, isTheme) {
      each$2(toArr(option.series), function (seriesOpt) {
        isObject$1(seriesOpt) && processSeries(seriesOpt);
      });
      var axes = ['xAxis', 'yAxis', 'radiusAxis', 'angleAxis', 'singleAxis', 'parallelAxis', 'radar'];
      isTheme && axes.push('valueAxis', 'categoryAxis', 'logAxis', 'timeAxis');
      each$2(axes, function (axisName) {
        each$2(toArr(option[axisName]), function (axisOpt) {
          if (axisOpt) {
            compatTextStyle(axisOpt, 'axisLabel');
            compatTextStyle(axisOpt.axisPointer, 'label');
          }
        });
      });
      each$2(toArr(option.parallel), function (parallelOpt) {
        var parallelAxisDefault = parallelOpt && parallelOpt.parallelAxisDefault;
        compatTextStyle(parallelAxisDefault, 'axisLabel');
        compatTextStyle(parallelAxisDefault && parallelAxisDefault.axisPointer, 'label');
      });
      each$2(toArr(option.calendar), function (calendarOpt) {
        convertNormalEmphasis(calendarOpt, 'itemStyle');
        compatTextStyle(calendarOpt, 'dayLabel');
        compatTextStyle(calendarOpt, 'monthLabel');
        compatTextStyle(calendarOpt, 'yearLabel');
      }); // radar.name.textStyle

      each$2(toArr(option.radar), function (radarOpt) {
        compatTextStyle(radarOpt, 'name'); // Use axisName instead of name because component has name property

        if (radarOpt.name && radarOpt.axisName == null) {
          radarOpt.axisName = radarOpt.name;
          delete radarOpt.name;

          if ("development" !== 'production') {
            deprecateLog('name property in radar component has been changed to axisName');
          }
        }

        if (radarOpt.nameGap != null && radarOpt.axisNameGap == null) {
          radarOpt.axisNameGap = radarOpt.nameGap;
          delete radarOpt.nameGap;

          if ("development" !== 'production') {
            deprecateLog('nameGap property in radar component has been changed to axisNameGap');
          }
        }

        if ("development" !== 'production') {
          each$2(radarOpt.indicator, function (indicatorOpt) {
            if (indicatorOpt.text) {
              deprecateReplaceLog('text', 'name', 'radar.indicator');
            }
          });
        }
      });
      each$2(toArr(option.geo), function (geoOpt) {
        if (isObject$1(geoOpt)) {
          compatEC3CommonStyles(geoOpt);
          each$2(toArr(geoOpt.regions), function (regionObj) {
            compatEC3CommonStyles(regionObj);
          });
        }
      });
      each$2(toArr(option.timeline), function (timelineOpt) {
        compatEC3CommonStyles(timelineOpt);
        convertNormalEmphasis(timelineOpt, 'label');
        convertNormalEmphasis(timelineOpt, 'itemStyle');
        convertNormalEmphasis(timelineOpt, 'controlStyle', true);
        var data = timelineOpt.data;
        isArray(data) && each(data, function (item) {
          if (isObject(item)) {
            convertNormalEmphasis(item, 'label');
            convertNormalEmphasis(item, 'itemStyle');
          }
        });
      });
      each$2(toArr(option.toolbox), function (toolboxOpt) {
        convertNormalEmphasis(toolboxOpt, 'iconStyle');
        each$2(toolboxOpt.feature, function (featureOpt) {
          convertNormalEmphasis(featureOpt, 'iconStyle');
        });
      });
      compatTextStyle(toObj(option.axisPointer), 'label');
      compatTextStyle(toObj(option.tooltip).axisPointer, 'label'); // Clean logs
      // storedLogs = {};
    }

    function get(opt, path) {
      var pathArr = path.split(',');
      var obj = opt;

      for (var i = 0; i < pathArr.length; i++) {
        obj = obj && obj[pathArr[i]];

        if (obj == null) {
          break;
        }
      }

      return obj;
    }

    function set$1(opt, path, val, overwrite) {
      var pathArr = path.split(',');
      var obj = opt;
      var key;
      var i = 0;

      for (; i < pathArr.length - 1; i++) {
        key = pathArr[i];

        if (obj[key] == null) {
          obj[key] = {};
        }

        obj = obj[key];
      }

      if (overwrite || obj[pathArr[i]] == null) {
        obj[pathArr[i]] = val;
      }
    }

    function compatLayoutProperties(option) {
      option && each(LAYOUT_PROPERTIES, function (prop) {
        if (prop[0] in option && !(prop[1] in option)) {
          option[prop[1]] = option[prop[0]];
        }
      });
    }

    var LAYOUT_PROPERTIES = [['x', 'left'], ['y', 'top'], ['x2', 'right'], ['y2', 'bottom']];
    var COMPATITABLE_COMPONENTS = ['grid', 'geo', 'parallel', 'legend', 'toolbox', 'title', 'visualMap', 'dataZoom', 'timeline'];
    var BAR_ITEM_STYLE_MAP = [['borderRadius', 'barBorderRadius'], ['borderColor', 'barBorderColor'], ['borderWidth', 'barBorderWidth']];

    function compatBarItemStyle(option) {
      var itemStyle = option && option.itemStyle;

      if (itemStyle) {
        for (var i = 0; i < BAR_ITEM_STYLE_MAP.length; i++) {
          var oldName = BAR_ITEM_STYLE_MAP[i][1];
          var newName = BAR_ITEM_STYLE_MAP[i][0];

          if (itemStyle[oldName] != null) {
            itemStyle[newName] = itemStyle[oldName];

            if ("development" !== 'production') {
              deprecateReplaceLog(oldName, newName);
            }
          }
        }
      }
    }

    function compatPieLabel(option) {
      if (!option) {
        return;
      }

      if (option.alignTo === 'edge' && option.margin != null && option.edgeDistance == null) {
        if ("development" !== 'production') {
          deprecateReplaceLog('label.margin', 'label.edgeDistance', 'pie');
        }

        option.edgeDistance = option.margin;
      }
    }

    function compatSunburstState(option) {
      if (!option) {
        return;
      }

      if (option.downplay && !option.blur) {
        option.blur = option.downplay;

        if ("development" !== 'production') {
          deprecateReplaceLog('downplay', 'blur', 'sunburst');
        }
      }
    }

    function compatGraphFocus(option) {
      if (!option) {
        return;
      }

      if (option.focusNodeAdjacency != null) {
        option.emphasis = option.emphasis || {};

        if (option.emphasis.focus == null) {
          if ("development" !== 'production') {
            deprecateReplaceLog('focusNodeAdjacency', 'emphasis: { focus: \'adjacency\'}', 'graph/sankey');
          }

          option.emphasis.focus = 'adjacency';
        }
      }
    }

    function traverseTree(data, cb) {
      if (data) {
        for (var i = 0; i < data.length; i++) {
          cb(data[i]);
          data[i] && traverseTree(data[i].children, cb);
        }
      }
    }

    function globalBackwardCompat(option, isTheme) {
      globalCompatStyle(option, isTheme); // Make sure series array for model initialization.

      option.series = normalizeToArray(option.series);
      each(option.series, function (seriesOpt) {
        if (!isObject(seriesOpt)) {
          return;
        }

        var seriesType = seriesOpt.type;

        if (seriesType === 'line') {
          if (seriesOpt.clipOverflow != null) {
            seriesOpt.clip = seriesOpt.clipOverflow;

            if ("development" !== 'production') {
              deprecateReplaceLog('clipOverflow', 'clip', 'line');
            }
          }
        } else if (seriesType === 'pie' || seriesType === 'gauge') {
          if (seriesOpt.clockWise != null) {
            seriesOpt.clockwise = seriesOpt.clockWise;

            if ("development" !== 'production') {
              deprecateReplaceLog('clockWise', 'clockwise');
            }
          }

          compatPieLabel(seriesOpt.label);
          var data = seriesOpt.data;

          if (data && !isTypedArray(data)) {
            for (var i = 0; i < data.length; i++) {
              compatPieLabel(data[i]);
            }
          }

          if (seriesOpt.hoverOffset != null) {
            seriesOpt.emphasis = seriesOpt.emphasis || {};

            if (seriesOpt.emphasis.scaleSize = null) {
              if ("development" !== 'production') {
                deprecateReplaceLog('hoverOffset', 'emphasis.scaleSize');
              }

              seriesOpt.emphasis.scaleSize = seriesOpt.hoverOffset;
            }
          }
        } else if (seriesType === 'gauge') {
          var pointerColor = get(seriesOpt, 'pointer.color');
          pointerColor != null && set$1(seriesOpt, 'itemStyle.color', pointerColor);
        } else if (seriesType === 'bar') {
          compatBarItemStyle(seriesOpt);
          compatBarItemStyle(seriesOpt.backgroundStyle);
          compatBarItemStyle(seriesOpt.emphasis);
          var data = seriesOpt.data;

          if (data && !isTypedArray(data)) {
            for (var i = 0; i < data.length; i++) {
              if (typeof data[i] === 'object') {
                compatBarItemStyle(data[i]);
                compatBarItemStyle(data[i] && data[i].emphasis);
              }
            }
          }
        } else if (seriesType === 'sunburst') {
          var highlightPolicy = seriesOpt.highlightPolicy;

          if (highlightPolicy) {
            seriesOpt.emphasis = seriesOpt.emphasis || {};

            if (!seriesOpt.emphasis.focus) {
              seriesOpt.emphasis.focus = highlightPolicy;

              if ("development" !== 'production') {
                deprecateReplaceLog('highlightPolicy', 'emphasis.focus', 'sunburst');
              }
            }
          }

          compatSunburstState(seriesOpt);
          traverseTree(seriesOpt.data, compatSunburstState);
        } else if (seriesType === 'graph' || seriesType === 'sankey') {
          compatGraphFocus(seriesOpt); // TODO nodes, edges?
        } else if (seriesType === 'map') {
          if (seriesOpt.mapType && !seriesOpt.map) {
            if ("development" !== 'production') {
              deprecateReplaceLog('mapType', 'map', 'map');
            }

            seriesOpt.map = seriesOpt.mapType;
          }

          if (seriesOpt.mapLocation) {
            if ("development" !== 'production') {
              deprecateLog('`mapLocation` is not used anymore.');
            }

            defaults(seriesOpt, seriesOpt.mapLocation);
          }
        }

        if (seriesOpt.hoverAnimation != null) {
          seriesOpt.emphasis = seriesOpt.emphasis || {};

          if (seriesOpt.emphasis && seriesOpt.emphasis.scale == null) {
            if ("development" !== 'production') {
              deprecateReplaceLog('hoverAnimation', 'emphasis.scale');
            }

            seriesOpt.emphasis.scale = seriesOpt.hoverAnimation;
          }
        }

        compatLayoutProperties(seriesOpt);
      }); // dataRange has changed to visualMap

      if (option.dataRange) {
        option.visualMap = option.dataRange;
      }

      each(COMPATITABLE_COMPONENTS, function (componentName) {
        var options = option[componentName];

        if (options) {
          if (!isArray(options)) {
            options = [options];
          }

          each(options, function (option) {
            compatLayoutProperties(option);
          });
        }
      });
    }

    //     data processing stage is blocked in stream.
    //     See <module:echarts/stream/Scheduler#performDataProcessorTasks>
    // (2) Only register once when import repeatedly.
    //     Should be executed after series is filtered and before stack calculation.

    function dataStack(ecModel) {
      var stackInfoMap = createHashMap();
      ecModel.eachSeries(function (seriesModel) {
        var stack = seriesModel.get('stack'); // Compatible: 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.
            // TODO: Type getCalculationInfo return more specific type?
            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(stackInfoList, function (targetStackInfo, idxInStack) {
        var resultVal = [];
        var resultNaN = [NaN, NaN];
        var dims = [targetStackInfo.stackResultDimension, targetStackInfo.stackedOverDimension];
        var targetData = targetStackInfo.data;
        var isStackedByIndex = targetStackInfo.isStackedByIndex;
        var stackStrategy = targetStackInfo.seriesModel.get('stackStrategy') || 'samesign'; // Should not write on raw data, because stack series model list changes
        // depending on legend selection.

        targetData.modify(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 (stackStrategy === 'all' // single stack group
              || stackStrategy === 'positive' && val > 0 || stackStrategy === 'negative' && val < 0 || stackStrategy === 'samesign' && sum >= 0 && val > 0 // All positive stack
              || stackStrategy === 'samesign' && sum <= 0 && val < 0 // All negative stack
              ) {
                  // The sum has to be very small to be affected by the
                  // floating arithmetic problem. An incorrect result will probably
                  // cause axis min/max to be filtered incorrectly.
                  sum = addSafe(sum, val);
                  stackedOver = val;
                  break;
                }
            }
          }

          resultVal[0] = sum;
          resultVal[1] = stackedOver;
          return resultVal;
        });
      });
    }

    var SourceImpl =
    /** @class */
    function () {
      function SourceImpl(fields) {
        this.data = fields.data || (fields.sourceFormat === SOURCE_FORMAT_KEYED_COLUMNS ? {} : []);
        this.sourceFormat = fields.sourceFormat || SOURCE_FORMAT_UNKNOWN; // Visit config

        this.seriesLayoutBy = fields.seriesLayoutBy || SERIES_LAYOUT_BY_COLUMN;
        this.startIndex = fields.startIndex || 0;
        this.dimensionsDetectedCount = fields.dimensionsDetectedCount;
        this.metaRawOption = fields.metaRawOption;
        var dimensionsDefine = this.dimensionsDefine = fields.dimensionsDefine;

        if (dimensionsDefine) {
          for (var i = 0; i < dimensionsDefine.length; i++) {
            var dim = dimensionsDefine[i];

            if (dim.type == null) {
              if (guessOrdinal(this, i) === BE_ORDINAL.Must) {
                dim.type = 'ordinal';
              }
            }
          }
        }
      }

      return SourceImpl;
    }();

    function isSourceInstance(val) {
      return val instanceof SourceImpl;
    }
    /**
     * Create a source from option.
     * NOTE: Created source is immutable. Don't change any properties in it.
     */

    function createSource(sourceData, thisMetaRawOption, // can be null. If not provided, auto detect it from `sourceData`.
    sourceFormat) {
      sourceFormat = sourceFormat || detectSourceFormat(sourceData);
      var seriesLayoutBy = thisMetaRawOption.seriesLayoutBy;
      var determined = determineSourceDimensions(sourceData, sourceFormat, seriesLayoutBy, thisMetaRawOption.sourceHeader, thisMetaRawOption.dimensions);
      var source = new SourceImpl({
        data: sourceData,
        sourceFormat: sourceFormat,
        seriesLayoutBy: seriesLayoutBy,
        dimensionsDefine: determined.dimensionsDefine,
        startIndex: determined.startIndex,
        dimensionsDetectedCount: determined.dimensionsDetectedCount,
        metaRawOption: clone(thisMetaRawOption)
      });
      return source;
    }
    /**
     * Wrap original series data for some compatibility cases.
     */

    function createSourceFromSeriesDataOption(data) {
      return new SourceImpl({
        data: data,
        sourceFormat: isTypedArray(data) ? SOURCE_FORMAT_TYPED_ARRAY : SOURCE_FORMAT_ORIGINAL
      });
    }
    /**
     * Clone source but excludes source data.
     */

    function cloneSourceShallow(source) {
      return new SourceImpl({
        data: source.data,
        sourceFormat: source.sourceFormat,
        seriesLayoutBy: source.seriesLayoutBy,
        dimensionsDefine: clone(source.dimensionsDefine),
        startIndex: source.startIndex,
        dimensionsDetectedCount: source.dimensionsDetectedCount
      });
    }
    /**
     * Note: An empty array will be detected as `SOURCE_FORMAT_ARRAY_ROWS`.
     */

    function detectSourceFormat(data) {
      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(item)) {
            sourceFormat = SOURCE_FORMAT_OBJECT_ROWS;
            break;
          }
        }
      } else if (isObject(data)) {
        for (var key in data) {
          if (hasOwn(data, key) && isArrayLike(data[key])) {
            sourceFormat = SOURCE_FORMAT_KEYED_COLUMNS;
            break;
          }
        }
      }

      return sourceFormat;
    }
    /**
     * Determine the source definitions from data standalone dimensions definitions
     * are not specified.
     */

    function determineSourceDimensions(data, sourceFormat, seriesLayoutBy, sourceHeader, // standalone raw dimensions definition, like:
    // {
    //     dimensions: ['aa', 'bb', { name: 'cc', type: 'time' }]
    // }
    // in `dataset` or `series`
    dimensionsDefine) {
      var dimensionsDetectedCount;
      var startIndex; // PENDING: Could data be null/undefined here?
      // currently, if `dataset.source` not specified, error thrown.
      // if `series.data` not specified, nothing rendered without error thrown.
      // Should test these cases.

      if (!data) {
        return {
          dimensionsDefine: normalizeDimensionsOption(dimensionsDefine),
          startIndex: startIndex,
          dimensionsDetectedCount: dimensionsDetectedCount
        };
      }

      if (sourceFormat === SOURCE_FORMAT_ARRAY_ROWS) {
        var dataArrayRows = data; // 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, dataArrayRows, 10);
        } else {
          startIndex = isNumber(sourceHeader) ? sourceHeader : sourceHeader ? 1 : 0;
        }

        if (!dimensionsDefine && startIndex === 1) {
          dimensionsDefine = [];
          arrayRowsTravelFirst(function (val, index) {
            dimensionsDefine[index] = val != null ? val + '' : '';
          }, seriesLayoutBy, dataArrayRows, Infinity);
        }

        dimensionsDetectedCount = dimensionsDefine ? dimensionsDefine.length : seriesLayoutBy === SERIES_LAYOUT_BY_ROW ? dataArrayRows.length : dataArrayRows[0] ? dataArrayRows[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(data, function (colArr, key) {
            dimensionsDefine.push(key);
          });
        }
      } else if (sourceFormat === SOURCE_FORMAT_ORIGINAL) {
        var value0 = getDataItemValue(data[0]);
        dimensionsDetectedCount = isArray(value0) && value0.length || 1;
      } else if (sourceFormat === SOURCE_FORMAT_TYPED_ARRAY) {
        if ("development" !== 'production') {
          assert(!!dimensionsDefine, 'dimensions must be given if data is TypedArray.');
        }
      }

      return {
        startIndex: startIndex,
        dimensionsDefine: normalizeDimensionsOption(dimensionsDefine),
        dimensionsDetectedCount: dimensionsDetectedCount
      };
    }

    function objectRowsCollectDimensions(data) {
      var firstIndex = 0;
      var obj;

      while (firstIndex < data.length && !(obj = data[firstIndex++])) {} // jshint ignore: line


      if (obj) {
        var dimensions_1 = [];
        each(obj, function (value, key) {
          dimensions_1.push(key);
        });
        return dimensions_1;
      }
    } // 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/undefined or string.


    function normalizeDimensionsOption(dimensionsDefine) {
      if (!dimensionsDefine) {
        // The meaning of null/undefined is different from empty array.
        return;
      }

      var nameMap = createHashMap();
      return map(dimensionsDefine, function (rawItem, index) {
        rawItem = isObject(rawItem) ? rawItem : {
          name: rawItem
        }; // Other fields will be discarded.

        var item = {
          name: rawItem.name,
          displayName: rawItem.displayName,
          type: rawItem.type
        }; // User can set null in dimensions.
        // We don't auto specify name, otherwise a given name may
        // cause it to be referred 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) {
      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 shouldRetrieveDataByName(source) {
      var sourceFormat = source.sourceFormat;
      return sourceFormat === SOURCE_FORMAT_OBJECT_ROWS || sourceFormat === SOURCE_FORMAT_KEYED_COLUMNS;
    }

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


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * 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 _a, _b, _c; // TODO
    var providerMethods;
    var mountMethods;
    /**
     * If normal array used, mutable chunk size is supported.
     * If typed array used, chunk size must be fixed.
     */

    var DefaultDataProvider =
    /** @class */
    function () {
      function DefaultDataProvider(sourceParam, dimSize) {
        // let source: Source;
        var source = !isSourceInstance(sourceParam) ? createSourceFromSeriesDataOption(sourceParam) : sourceParam; // declare source is Source;

        this._source = source;
        var data = this._data = source.data; // Typed array. TODO IE10+?

        if (source.sourceFormat === SOURCE_FORMAT_TYPED_ARRAY) {
          if ("development" !== 'production') {
            if (dimSize == null) {
              throw new Error('Typed array data must specify dimension size');
            }
          }

          this._offset = 0;
          this._dimSize = dimSize;
          this._data = data;
        }

        mountMethods(this, data, source);
      }

      DefaultDataProvider.prototype.getSource = function () {
        return this._source;
      };

      DefaultDataProvider.prototype.count = function () {
        return 0;
      };

      DefaultDataProvider.prototype.getItem = function (idx, out) {
        return;
      };

      DefaultDataProvider.prototype.appendData = function (newData) {};

      DefaultDataProvider.prototype.clean = function () {};

      DefaultDataProvider.protoInitialize = function () {
        // PENDING: To avoid potential incompat (e.g., prototype
        // is visited somewhere), still init them on prototype.
        var proto = DefaultDataProvider.prototype;
        proto.pure = false;
        proto.persistent = true;
      }();

      DefaultDataProvider.internalField = function () {
        var _a;

        mountMethods = function (provider, data, source) {
          var sourceFormat = source.sourceFormat;
          var seriesLayoutBy = source.seriesLayoutBy;
          var startIndex = source.startIndex;
          var dimsDef = source.dimensionsDefine;
          var methods = providerMethods[getMethodMapKey(sourceFormat, seriesLayoutBy)];

          if ("development" !== 'production') {
            assert(methods, 'Invalide sourceFormat: ' + sourceFormat);
          }

          extend(provider, methods);

          if (sourceFormat === SOURCE_FORMAT_TYPED_ARRAY) {
            provider.getItem = getItemForTypedArray;
            provider.count = countForTypedArray;
            provider.fillStorage = fillStorageForTypedArray;
          } else {
            var rawItemGetter = getRawSourceItemGetter(sourceFormat, seriesLayoutBy);
            provider.getItem = bind(rawItemGetter, null, data, startIndex, dimsDef);
            var rawCounter = getRawSourceDataCounter(sourceFormat, seriesLayoutBy);
            provider.count = bind(rawCounter, null, data, startIndex, dimsDef);
          }
        };

        var getItemForTypedArray = function (idx, out) {
          idx = idx - this._offset;
          out = out || [];
          var data = this._data;
          var dimSize = this._dimSize;
          var offset = dimSize * idx;

          for (var i = 0; i < dimSize; i++) {
            out[i] = data[offset + i];
          }

          return out;
        };

        var fillStorageForTypedArray = function (start, end, storage, extent) {
          var data = this._data;
          var dimSize = this._dimSize;

          for (var dim = 0; dim < dimSize; dim++) {
            var dimExtent = extent[dim];
            var min = dimExtent[0] == null ? Infinity : dimExtent[0];
            var max = dimExtent[1] == null ? -Infinity : dimExtent[1];
            var count = end - start;
            var arr = storage[dim];

            for (var i = 0; i < count; i++) {
              // appendData with TypedArray will always do replace in provider.
              var val = data[i * dimSize + dim];
              arr[start + i] = val;
              val < min && (min = val);
              val > max && (max = val);
            }

            dimExtent[0] = min;
            dimExtent[1] = max;
          }
        };

        var countForTypedArray = function () {
          return this._data ? this._data.length / this._dimSize : 0;
        };

        providerMethods = (_a = {}, _a[SOURCE_FORMAT_ARRAY_ROWS + '_' + SERIES_LAYOUT_BY_COLUMN] = {
          pure: true,
          appendData: appendDataSimply
        }, _a[SOURCE_FORMAT_ARRAY_ROWS + '_' + SERIES_LAYOUT_BY_ROW] = {
          pure: true,
          appendData: function () {
            throw new Error('Do not support appendData when set seriesLayoutBy: "row".');
          }
        }, _a[SOURCE_FORMAT_OBJECT_ROWS] = {
          pure: true,
          appendData: appendDataSimply
        }, _a[SOURCE_FORMAT_KEYED_COLUMNS] = {
          pure: true,
          appendData: function (newData) {
            var data = this._data;
            each(newData, function (newCol, key) {
              var oldCol = data[key] || (data[key] = []);

              for (var i = 0; i < (newCol || []).length; i++) {
                oldCol.push(newCol[i]);
              }
            });
          }
        }, _a[SOURCE_FORMAT_ORIGINAL] = {
          appendData: appendDataSimply
        }, _a[SOURCE_FORMAT_TYPED_ARRAY] = {
          persistent: false,
          pure: true,
          appendData: function (newData) {
            if ("development" !== 'production') {
              assert(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;
          }
        }, _a);

        function appendDataSimply(newData) {
          for (var i = 0; i < newData.length; i++) {
            this._data.push(newData[i]);
          }
        }
      }();

      return DefaultDataProvider;
    }();

    var getItemSimply = function (rawData, startIndex, dimsDef, idx) {
      return rawData[idx];
    };

    var rawSourceItemGetterMap = (_a = {}, _a[SOURCE_FORMAT_ARRAY_ROWS + '_' + SERIES_LAYOUT_BY_COLUMN] = function (rawData, startIndex, dimsDef, idx) {
      return rawData[idx + startIndex];
    }, _a[SOURCE_FORMAT_ARRAY_ROWS + '_' + SERIES_LAYOUT_BY_ROW] = function (rawData, startIndex, dimsDef, idx, out) {
      idx += startIndex;
      var item = out || [];
      var data = rawData;

      for (var i = 0; i < data.length; i++) {
        var row = data[i];
        item[i] = row ? row[idx] : null;
      }

      return item;
    }, _a[SOURCE_FORMAT_OBJECT_ROWS] = getItemSimply, _a[SOURCE_FORMAT_KEYED_COLUMNS] = function (rawData, startIndex, dimsDef, idx, out) {
      var item = out || [];

      for (var i = 0; i < dimsDef.length; i++) {
        var dimName = dimsDef[i].name;

        if ("development" !== 'production') {
          if (dimName == null) {
            throw new Error();
          }
        }

        var col = rawData[dimName];
        item[i] = col ? col[idx] : null;
      }

      return item;
    }, _a[SOURCE_FORMAT_ORIGINAL] = getItemSimply, _a);
    function getRawSourceItemGetter(sourceFormat, seriesLayoutBy) {
      var method = rawSourceItemGetterMap[getMethodMapKey(sourceFormat, seriesLayoutBy)];

      if ("development" !== 'production') {
        assert(method, 'Do not support get item on "' + sourceFormat + '", "' + seriesLayoutBy + '".');
      }

      return method;
    }

    var countSimply = function (rawData, startIndex, dimsDef) {
      return rawData.length;
    };

    var rawSourceDataCounterMap = (_b = {}, _b[SOURCE_FORMAT_ARRAY_ROWS + '_' + SERIES_LAYOUT_BY_COLUMN] = function (rawData, startIndex, dimsDef) {
      return Math.max(0, rawData.length - startIndex);
    }, _b[SOURCE_FORMAT_ARRAY_ROWS + '_' + SERIES_LAYOUT_BY_ROW] = function (rawData, startIndex, dimsDef) {
      var row = rawData[0];
      return row ? Math.max(0, row.length - startIndex) : 0;
    }, _b[SOURCE_FORMAT_OBJECT_ROWS] = countSimply, _b[SOURCE_FORMAT_KEYED_COLUMNS] = function (rawData, startIndex, dimsDef) {
      var dimName = dimsDef[0].name;

      if ("development" !== 'production') {
        if (dimName == null) {
          throw new Error();
        }
      }

      var col = rawData[dimName];
      return col ? col.length : 0;
    }, _b[SOURCE_FORMAT_ORIGINAL] = countSimply, _b);
    function getRawSourceDataCounter(sourceFormat, seriesLayoutBy) {
      var method = rawSourceDataCounterMap[getMethodMapKey(sourceFormat, seriesLayoutBy)];

      if ("development" !== 'production') {
        assert(method, 'Do not support count on "' + sourceFormat + '", "' + seriesLayoutBy + '".');
      }

      return method;
    }

    var getRawValueSimply = function (dataItem, dimIndex, property) {
      return dataItem[dimIndex];
    };

    var rawSourceValueGetterMap = (_c = {}, _c[SOURCE_FORMAT_ARRAY_ROWS] = getRawValueSimply, _c[SOURCE_FORMAT_OBJECT_ROWS] = function (dataItem, dimIndex, property) {
      return dataItem[property];
    }, _c[SOURCE_FORMAT_KEYED_COLUMNS] = getRawValueSimply, _c[SOURCE_FORMAT_ORIGINAL] = function (dataItem, dimIndex, property) {
      // FIXME: In some case (markpoint in geo (geo-map.html)),
      // dataItem is {coord: [...]}
      var value = getDataItemValue(dataItem);
      return !(value instanceof Array) ? value : value[dimIndex];
    }, _c[SOURCE_FORMAT_TYPED_ARRAY] = getRawValueSimply, _c);
    function getRawSourceValueGetter(sourceFormat) {
      var method = rawSourceValueGetterMap[sourceFormat];

      if ("development" !== 'production') {
        assert(method, 'Do not support get value on "' + sourceFormat + '".');
      }

      return method;
    }

    function getMethodMapKey(sourceFormat, seriesLayoutBy) {
      return sourceFormat === SOURCE_FORMAT_ARRAY_ROWS ? sourceFormat + '_' + seriesLayoutBy : sourceFormat;
    } // ??? 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?


    function retrieveRawValue(data, dataIndex, // If dimIndex is null/undefined, return OptionDataItem.
    // Otherwise, return OptionDataValue.
    dim) {
      if (!data) {
        return;
      } // Consider data may be not persistent.


      var dataItem = data.getRawDataItem(dataIndex);

      if (dataItem == null) {
        return;
      }

      var store = data.getStore();
      var sourceFormat = store.getSource().sourceFormat;

      if (dim != null) {
        var dimIndex = data.getDimensionIndex(dim);
        var property = store.getDimensionProperty(dimIndex);
        return getRawSourceValueGetter(sourceFormat)(dataItem, dimIndex, property);
      } else {
        var result = dataItem;

        if (sourceFormat === SOURCE_FORMAT_ORIGINAL) {
          result = getDataItemValue(dataItem);
        }

        return result;
      }
    }

    var DIMENSION_LABEL_REG = /\{@(.+?)\}/g;

    var DataFormatMixin =
    /** @class */
    function () {
      function DataFormatMixin() {}
      /**
       * Get params for formatter
       */


      DataFormatMixin.prototype.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 style = data.getItemVisual(dataIndex, 'style');
        var color = style && style[data.getItemVisual(dataIndex, 'drawType') || 'fill'];
        var borderColor = style && style.stroke;
        var mainType = this.mainType;
        var isSeries = mainType === 'series';
        var userOutput = data.userOutput && data.userOutput.get();
        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.fullDimensions : null,
          encode: userOutput ? userOutput.encode : null,
          // Param name list for mapping `a`, `b`, `c`, `d`, `e`
          $vars: ['seriesName', 'name', 'value']
        };
      };
      /**
       * Format label
       * @param dataIndex
       * @param status 'normal' by default
       * @param dataType
       * @param labelDimIndex Only used in some chart that
       *        use formatter in different dimensions, like radar.
       * @param formatter Formatter given outside.
       * @return return null/undefined if no formatter
       */


      DataFormatMixin.prototype.getFormattedLabel = function (dataIndex, status, dataType, labelDimIndex, formatter, extendParams) {
        status = status || 'normal';
        var data = this.getData(dataType);
        var params = this.getDataParams(dataIndex, dataType);

        if (extendParams) {
          params.value = extendParams.interpolatedValue;
        }

        if (labelDimIndex != null && isArray(params.value)) {
          params.value = params.value[labelDimIndex];
        }

        if (!formatter) {
          var itemModel = data.getItemModel(dataIndex); // @ts-ignore

          formatter = itemModel.get(status === 'normal' ? ['label', 'formatter'] : [status, 'label', 'formatter']);
        }

        if (isFunction(formatter)) {
          params.status = status;
          params.dimensionIndex = labelDimIndex;
          return formatter(params);
        } else if (isString(formatter)) {
          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, dimStr) {
            var len = dimStr.length;
            var dimLoose = dimStr;

            if (dimLoose.charAt(0) === '[' && dimLoose.charAt(len - 1) === ']') {
              dimLoose = +dimLoose.slice(1, len - 1); // Also support: '[]' => 0

              if ("development" !== 'production') {
                if (isNaN(dimLoose)) {
                  error("Invalide label formatter: @" + dimStr + ", only support @[0], @[1], @[2], ...");
                }
              }
            }

            var val = retrieveRawValue(data, dataIndex, dimLoose);

            if (extendParams && isArray(extendParams.interpolatedValue)) {
              var dimIndex = data.getDimensionIndex(dimLoose);

              if (dimIndex >= 0) {
                val = extendParams.interpolatedValue[dimIndex];
              }
            }

            return val != null ? val + '' : '';
          });
        }
      };
      /**
       * Get raw value in option
       */


      DataFormatMixin.prototype.getRawValue = function (idx, dataType) {
        return retrieveRawValue(this.getData(dataType), idx);
      };
      /**
       * Should be implemented.
       * @param {number} dataIndex
       * @param {boolean} [multipleSeries=false]
       * @param {string} [dataType]
       */


      DataFormatMixin.prototype.formatTooltip = function (dataIndex, multipleSeries, dataType) {
        // Empty function
        return;
      };

      return DataFormatMixin;
    }();
    // but guess little chance has been used outside. Do we need to backward
    // compat it?
    // type TooltipFormatResultLegacyObject = {
    //     // `html` means the markup language text, either in 'html' or 'richText'.
    //     // The name `html` is not appropriate because in 'richText' it is not a HTML
    //     // string. But still support it for backward compatibility.
    //     html: string;
    //     markers: Dictionary<ColorString>;
    // };

    /**
     * For backward compat, normalize the return from `formatTooltip`.
     */

    function normalizeTooltipFormatResult(result) {
      var markupText; // let markers: Dictionary<ColorString>;

      var markupFragment;

      if (isObject(result)) {
        if (result.type) {
          markupFragment = result;
        } else {
          if ("development" !== 'production') {
            console.warn('The return type of `formatTooltip` is not supported: ' + makePrintable(result));
          }
        } // else {
        //     markupText = (result as TooltipFormatResultLegacyObject).html;
        //     markers = (result as TooltipFormatResultLegacyObject).markers;
        //     if (markersExisting) {
        //         markers = zrUtil.merge(markersExisting, markers);
        //     }
        // }

      } else {
        markupText = result;
      }

      return {
        text: markupText,
        // markers: markers || markersExisting,
        frag: markupFragment
      };
    }

    /**
     * @param {Object} define
     * @return See the return of `createTask`.
     */

    function createTask(define) {
      return new Task(define);
    }

    var Task =
    /** @class */
    function () {
      function Task(define) {
        define = define || {};
        this._reset = define.reset;
        this._plan = define.plan;
        this._count = define.count;
        this._onDirty = define.onDirty;
        this._dirty = true;
      }
      /**
       * @param step Specified step.
       * @param skip Skip customer perform call.
       * @param modBy Sampling window size.
       * @param modDataCount Sampling count.
       * @return whether unfinished.
       */


      Task.prototype.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 = this._doReset(skip);
        }

        this._modBy = modBy;
        this._modDataCount = modDataCount;
        var step = performArgs && performArgs.step;

        if (upTask) {
          if ("development" !== 'production') {
            assert(upTask._outputDueEnd != null);
          }

          this._dueEnd = upTask._outputDueEnd;
        } // DataTask or overallTask
        else {
            if ("development" !== 'production') {
              assert(!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++) {
                this._doProgress(progress[i], start, end, modBy, modDataCount);
              }
            } else {
              this._doProgress(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 ("development" !== 'production') {
            // ??? Can not rollback.
            assert(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();
      };

      Task.prototype.dirty = function () {
        this._dirty = true;
        this._onDirty && this._onDirty(this.context);
      };

      Task.prototype._doProgress = function (progress, start, end, modBy, modDataCount) {
        iterator.reset(start, end, modBy, modDataCount);
        this._callingProgress = progress;

        this._callingProgress({
          start: start,
          end: end,
          count: end - start,
          next: iterator.next
        }, this.context);
      };

      Task.prototype._doReset = function (skip) {
        this._dueIndex = this._outputDueEnd = this._dueEnd = 0;
        this._settedOutputEnd = null;
        var progress;
        var forceFirstProgress;

        if (!skip && this._reset) {
          progress = this._reset(this.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;
          }
        }

        this._progress = progress;
        this._modBy = this._modDataCount = null;
        var downstream = this._downstream;
        downstream && downstream.dirty();
        return forceFirstProgress;
      };

      Task.prototype.unfinished = function () {
        return this._progress && this._dueIndex < this._dueEnd;
      };
      /**
       * @param downTask The downstream task.
       * @return The downstream task.
       */


      Task.prototype.pipe = function (downTask) {
        if ("development" !== 'production') {
          assert(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();
        }
      };

      Task.prototype.dispose = function () {
        if (this._disposed) {
          return;
        }

        this._upstream && (this._upstream._downstream = null);
        this._downstream && (this._downstream._upstream = null);
        this._dirty = false;
        this._disposed = true;
      };

      Task.prototype.getUpstream = function () {
        return this._upstream;
      };

      Task.prototype.getDownstream = function () {
        return this._downstream;
      };

      Task.prototype.setOutputEnd = function (end) {
        // This only happens in dataTask, dataZoom, map, currently.
        // where dataZoom do not set end each time, but only set
        // when reset. So we should record the set end, in case
        // that the stub of dataZoom perform again and earse the
        // set end by upstream.
        this._outputDueEnd = this._settedOutputEnd = end;
      };

      return Task;
    }();

    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;
      }
    }(); // -----------------------------------------------------------------------------
    // For stream debug (Should be commented out after used!)
    // @usage: printTask(this, 'begin');
    // @usage: printTask(this, null, {someExtraProp});
    // @usage: Use `__idxInPipeline` as conditional breakpiont.
    //
    // window.printTask = function (task: any, prefix: string, extra: { [key: string]: unknown }): void {
    //     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++}`);
    //     let props = [];
    //     if (task.__pipeline) {
    //         let val = `${task.__idxInPipeline}/${task.__pipeline.tail.__idxInPipeline} ${task.agent ? '(stub)' : ''}`;
    //         props.push({text: '__idxInPipeline/total', value: val});
    //     } else {
    //         let 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: 'pipelineId', 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]});
    //         });
    //     }
    //     let args = ['color: blue'];
    //     let msg = `%c[${prefix || 'T'}] %c` + props.map(item => (
    //         args.push('color: green', 'color: red'),
    //         `${item.text}: %c${item.value}`
    //     )).join('%c, ');
    //     console.log.apply(console, [msg].concat(args));
    //     // console.log(this);
    // };
    // window.printPipeline = function (task: any, prefix: string) {
    //     const pipeline = task.__pipeline;
    //     let currTask = pipeline.head;
    //     while (currTask) {
    //         window.printTask(currTask, prefix);
    //         currTask = currTask._downstream;
    //     }
    // };
    // window.showChain = function (chainHeadTask) {
    //     var chain = [];
    //     var task = chainHeadTask;
    //     while (task) {
    //         chain.push({
    //             task: task,
    //             up: task._upstream,
    //             down: task._downstream,
    //             idxInPipeline: task.__idxInPipeline
    //         });
    //         task = task._downstream;
    //     }
    //     return chain;
    // };
    // window.findTaskInChain = function (task, chainHeadTask) {
    //     let chain = window.showChain(chainHeadTask);
    //     let result = [];
    //     for (let i = 0; i < chain.length; i++) {
    //         let chainItem = chain[i];
    //         if (chainItem.task === task) {
    //             result.push(i);
    //         }
    //     }
    //     return result;
    // };
    // window.printChainAEachInChainB = function (chainHeadTaskA, chainHeadTaskB) {
    //     let chainA = window.showChain(chainHeadTaskA);
    //     for (let i = 0; i < chainA.length; i++) {
    //         console.log('chainAIdx:', i, 'inChainB:', window.findTaskInChain(chainA[i].task, chainHeadTaskB));
    //     }
    // };

    /**
     * Convert raw the value in to inner value in List.
     *
     * [Performance sensitive]
     *
     * [Caution]: this is the key logic of user value parser.
     * For backward compatibility, do not modify it until you have to!
     */

    function parseDataValue(value, // For high performance, do not omit the second param.
    opt) {
      // Performance sensitive.
      var dimType = opt && opt.type;

      if (dimType === 'ordinal') {
        // If given value is a category string
        return value;
      }

      if (dimType === 'time' // spead up when using timestamp
      && !isNumber(value) && 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.
      // number-like string (like ' 123 ') can be converted to a number.
      // where null/undefined or other string will be converted to NaN.


      return value == null || value === '' ? NaN // If string (like '-'), using '+' parse to NaN
      // If object, also parse to NaN
      : +value;
    }
    var valueParserMap = createHashMap({
      'number': function (val) {
        // Do not use `numericToNumber` here. We have `numericToNumber` by default.
        // Here the number parser can have loose rule:
        // enable to cut suffix: "120px" => 120, "14%" => 14.
        return parseFloat(val);
      },
      'time': function (val) {
        // return timestamp.
        return +parseDate(val);
      },
      'trim': function (val) {
        return isString(val) ? trim(val) : val;
      }
    });
    function getRawValueParser(type) {
      return valueParserMap.get(type);
    }
    var ORDER_COMPARISON_OP_MAP = {
      lt: function (lval, rval) {
        return lval < rval;
      },
      lte: function (lval, rval) {
        return lval <= rval;
      },
      gt: function (lval, rval) {
        return lval > rval;
      },
      gte: function (lval, rval) {
        return lval >= rval;
      }
    };

    var FilterOrderComparator =
    /** @class */
    function () {
      function FilterOrderComparator(op, rval) {
        if (!isNumber(rval)) {
          var errMsg = '';

          if ("development" !== 'production') {
            errMsg = 'rvalue of "<", ">", "<=", ">=" can only be number in filter.';
          }

          throwError(errMsg);
        }

        this._opFn = ORDER_COMPARISON_OP_MAP[op];
        this._rvalFloat = numericToNumber(rval);
      } // Performance sensitive.


      FilterOrderComparator.prototype.evaluate = function (lval) {
        // Most cases is 'number', and typeof maybe 10 times faseter than parseFloat.
        return isNumber(lval) ? this._opFn(lval, this._rvalFloat) : this._opFn(numericToNumber(lval), this._rvalFloat);
      };

      return FilterOrderComparator;
    }();

    var SortOrderComparator =
    /** @class */
    function () {
      /**
       * @param order by default: 'asc'
       * @param incomparable by default: Always on the tail.
       *        That is, if 'asc' => 'max', if 'desc' => 'min'
       *        See the definition of "incomparable" in [SORT_COMPARISON_RULE].
       */
      function SortOrderComparator(order, incomparable) {
        var isDesc = order === 'desc';
        this._resultLT = isDesc ? 1 : -1;

        if (incomparable == null) {
          incomparable = isDesc ? 'min' : 'max';
        }

        this._incomparable = incomparable === 'min' ? -Infinity : Infinity;
      } // See [SORT_COMPARISON_RULE].
      // Performance sensitive.


      SortOrderComparator.prototype.evaluate = function (lval, rval) {
        // Most cases is 'number', and typeof maybe 10 times faseter than parseFloat.
        var lvalFloat = isNumber(lval) ? lval : numericToNumber(lval);
        var rvalFloat = isNumber(rval) ? rval : numericToNumber(rval);
        var lvalNotNumeric = isNaN(lvalFloat);
        var rvalNotNumeric = isNaN(rvalFloat);

        if (lvalNotNumeric) {
          lvalFloat = this._incomparable;
        }

        if (rvalNotNumeric) {
          rvalFloat = this._incomparable;
        }

        if (lvalNotNumeric && rvalNotNumeric) {
          var lvalIsStr = isString(lval);
          var rvalIsStr = isString(rval);

          if (lvalIsStr) {
            lvalFloat = rvalIsStr ? lval : 0;
          }

          if (rvalIsStr) {
            rvalFloat = lvalIsStr ? rval : 0;
          }
        }

        return lvalFloat < rvalFloat ? this._resultLT : lvalFloat > rvalFloat ? -this._resultLT : 0;
      };

      return SortOrderComparator;
    }();

    var FilterEqualityComparator =
    /** @class */
    function () {
      function FilterEqualityComparator(isEq, rval) {
        this._rval = rval;
        this._isEQ = isEq;
        this._rvalTypeof = typeof rval;
        this._rvalFloat = numericToNumber(rval);
      } // Performance sensitive.


      FilterEqualityComparator.prototype.evaluate = function (lval) {
        var eqResult = lval === this._rval;

        if (!eqResult) {
          var lvalTypeof = typeof lval;

          if (lvalTypeof !== this._rvalTypeof && (lvalTypeof === 'number' || this._rvalTypeof === 'number')) {
            eqResult = numericToNumber(lval) === this._rvalFloat;
          }
        }

        return this._isEQ ? eqResult : !eqResult;
      };

      return FilterEqualityComparator;
    }();
    /**
     * [FILTER_COMPARISON_RULE]
     * `lt`|`lte`|`gt`|`gte`:
     * + rval must be a number. And lval will be converted to number (`numericToNumber`) to compare.
     * `eq`:
     * + If same type, compare with `===`.
     * + If there is one number, convert to number (`numericToNumber`) to compare.
     * + Else return `false`.
     * `ne`:
     * + Not `eq`.
     *
     *
     * [SORT_COMPARISON_RULE]
     * All the values are grouped into three categories:
     * + "numeric" (number and numeric string)
     * + "non-numeric-string" (string that excluding numeric string)
     * + "others"
     * "numeric" vs "numeric": values are ordered by number order.
     * "non-numeric-string" vs "non-numeric-string": values are ordered by ES spec (#sec-abstract-relational-comparison).
     * "others" vs "others": do not change order (always return 0).
     * "numeric" vs "non-numeric-string": "non-numeric-string" is treated as "incomparable".
     * "number" vs "others": "others" is treated as "incomparable".
     * "non-numeric-string" vs "others": "others" is treated as "incomparable".
     * "incomparable" will be seen as -Infinity or Infinity (depends on the settings).
     * MEMO:
     *   Non-numeric string sort makes sense when we need to put the items with the same tag together.
     *   But if we support string sort, we still need to avoid the misleading like `'2' > '12'`,
     *   So we treat "numeric-string" sorted by number order rather than string comparison.
     *
     *
     * [CHECK_LIST_OF_THE_RULE_DESIGN]
     * + Do not support string comparison until required. And also need to
     *   avoid the misleading of "2" > "12".
     * + Should avoid the misleading case:
     *   `" 22 " gte "22"` is `true` but `" 22 " eq "22"` is `false`.
     * + JS bad case should be avoided: null <= 0, [] <= 0, ' ' <= 0, ...
     * + Only "numeric" can be converted to comparable number, otherwise converted to NaN.
     *   See `util/number.ts#numericToNumber`.
     *
     * @return If `op` is not `RelationalOperator`, return null;
     */


    function createFilterComparator(op, rval) {
      return op === 'eq' || op === 'ne' ? new FilterEqualityComparator(op === 'eq', rval) : hasOwn(ORDER_COMPARISON_OP_MAP, op) ? new FilterOrderComparator(op, rval) : null;
    }

    /**
     * TODO: disable writable.
     * This structure will be exposed to users.
     */

    var ExternalSource =
    /** @class */
    function () {
      function ExternalSource() {}

      ExternalSource.prototype.getRawData = function () {
        // Only built-in transform available.
        throw new Error('not supported');
      };

      ExternalSource.prototype.getRawDataItem = function (dataIndex) {
        // Only built-in transform available.
        throw new Error('not supported');
      };

      ExternalSource.prototype.cloneRawData = function () {
        return;
      };
      /**
       * @return If dimension not found, return null/undefined.
       */


      ExternalSource.prototype.getDimensionInfo = function (dim) {
        return;
      };
      /**
       * dimensions defined if and only if either:
       * (a) dataset.dimensions are declared.
       * (b) dataset data include dimensions definitions in data (detected or via specified `sourceHeader`).
       * If dimensions are defined, `dimensionInfoAll` is corresponding to
       * the defined dimensions.
       * Otherwise, `dimensionInfoAll` is determined by data columns.
       * @return Always return an array (even empty array).
       */


      ExternalSource.prototype.cloneAllDimensionInfo = function () {
        return;
      };

      ExternalSource.prototype.count = function () {
        return;
      };
      /**
       * Only support by dimension index.
       * No need to support by dimension name in transform function,
       * because transform function is not case-specific, no need to use name literally.
       */


      ExternalSource.prototype.retrieveValue = function (dataIndex, dimIndex) {
        return;
      };

      ExternalSource.prototype.retrieveValueFromItem = function (dataItem, dimIndex) {
        return;
      };

      ExternalSource.prototype.convertValue = function (rawVal, dimInfo) {
        return parseDataValue(rawVal, dimInfo);
      };

      return ExternalSource;
    }();

    function createExternalSource(internalSource, externalTransform) {
      var extSource = new ExternalSource();
      var data = internalSource.data;
      var sourceFormat = extSource.sourceFormat = internalSource.sourceFormat;
      var sourceHeaderCount = internalSource.startIndex;
      var errMsg = '';

      if (internalSource.seriesLayoutBy !== SERIES_LAYOUT_BY_COLUMN) {
        // For the logic simplicity in transformer, only 'culumn' is
        // supported in data transform. Otherwise, the `dimensionsDefine`
        // might be detected by 'row', which probably confuses users.
        if ("development" !== 'production') {
          errMsg = '`seriesLayoutBy` of upstream dataset can only be "column" in data transform.';
        }

        throwError(errMsg);
      } // [MEMO]
      // Create a new dimensions structure for exposing.
      // Do not expose all dimension info to users directly.
      // Because the dimension is probably auto detected from data and not might reliable.
      // Should not lead the transformers to think that is reliable and return it.
      // See [DIMENSION_INHERIT_RULE] in `sourceManager.ts`.


      var dimensions = [];
      var dimsByName = {};
      var dimsDef = internalSource.dimensionsDefine;

      if (dimsDef) {
        each(dimsDef, function (dimDef, idx) {
          var name = dimDef.name;
          var dimDefExt = {
            index: idx,
            name: name,
            displayName: dimDef.displayName
          };
          dimensions.push(dimDefExt); // Users probably do not specify dimension name. For simplicity, data transform
          // does not generate dimension name.

          if (name != null) {
            // Dimension name should not be duplicated.
            // For simplicity, data transform forbids name duplication, do not generate
            // new name like module `completeDimensions.ts` did, but just tell users.
            var errMsg_1 = '';

            if (hasOwn(dimsByName, name)) {
              if ("development" !== 'production') {
                errMsg_1 = 'dimension name "' + name + '" duplicated.';
              }

              throwError(errMsg_1);
            }

            dimsByName[name] = dimDefExt;
          }
        });
      } // If dimension definitions are not defined and can not be detected.
      // e.g., pure data `[[11, 22], ...]`.
      else {
          for (var i = 0; i < internalSource.dimensionsDetectedCount || 0; i++) {
            // Do not generete name or anything others. The consequence process in
            // `transform` or `series` probably have there own name generation strategry.
            dimensions.push({
              index: i
            });
          }
        } // Implement public methods:


      var rawItemGetter = getRawSourceItemGetter(sourceFormat, SERIES_LAYOUT_BY_COLUMN);

      if (externalTransform.__isBuiltIn) {
        extSource.getRawDataItem = function (dataIndex) {
          return rawItemGetter(data, sourceHeaderCount, dimensions, dataIndex);
        };

        extSource.getRawData = bind(getRawData, null, internalSource);
      }

      extSource.cloneRawData = bind(cloneRawData, null, internalSource);
      var rawCounter = getRawSourceDataCounter(sourceFormat, SERIES_LAYOUT_BY_COLUMN);
      extSource.count = bind(rawCounter, null, data, sourceHeaderCount, dimensions);
      var rawValueGetter = getRawSourceValueGetter(sourceFormat);

      extSource.retrieveValue = function (dataIndex, dimIndex) {
        var rawItem = rawItemGetter(data, sourceHeaderCount, dimensions, dataIndex);
        return retrieveValueFromItem(rawItem, dimIndex);
      };

      var retrieveValueFromItem = extSource.retrieveValueFromItem = function (dataItem, dimIndex) {
        if (dataItem == null) {
          return;
        }

        var dimDef = dimensions[dimIndex]; // When `dimIndex` is `null`, `rawValueGetter` return the whole item.

        if (dimDef) {
          return rawValueGetter(dataItem, dimIndex, dimDef.name);
        }
      };

      extSource.getDimensionInfo = bind(getDimensionInfo, null, dimensions, dimsByName);
      extSource.cloneAllDimensionInfo = bind(cloneAllDimensionInfo, null, dimensions);
      return extSource;
    }

    function getRawData(upstream) {
      var sourceFormat = upstream.sourceFormat;

      if (!isSupportedSourceFormat(sourceFormat)) {
        var errMsg = '';

        if ("development" !== 'production') {
          errMsg = '`getRawData` is not supported in source format ' + sourceFormat;
        }

        throwError(errMsg);
      }

      return upstream.data;
    }

    function cloneRawData(upstream) {
      var sourceFormat = upstream.sourceFormat;
      var data = upstream.data;

      if (!isSupportedSourceFormat(sourceFormat)) {
        var errMsg = '';

        if ("development" !== 'production') {
          errMsg = '`cloneRawData` is not supported in source format ' + sourceFormat;
        }

        throwError(errMsg);
      }

      if (sourceFormat === SOURCE_FORMAT_ARRAY_ROWS) {
        var result = [];

        for (var i = 0, len = data.length; i < len; i++) {
          // Not strictly clone for performance
          result.push(data[i].slice());
        }

        return result;
      } else if (sourceFormat === SOURCE_FORMAT_OBJECT_ROWS) {
        var result = [];

        for (var i = 0, len = data.length; i < len; i++) {
          // Not strictly clone for performance
          result.push(extend({}, data[i]));
        }

        return result;
      }
    }

    function getDimensionInfo(dimensions, dimsByName, dim) {
      if (dim == null) {
        return;
      } // Keep the same logic as `List::getDimension` did.


      if (isNumber(dim) // If being a number-like string but not being defined a dimension name.
      || !isNaN(dim) && !hasOwn(dimsByName, dim)) {
        return dimensions[dim];
      } else if (hasOwn(dimsByName, dim)) {
        return dimsByName[dim];
      }
    }

    function cloneAllDimensionInfo(dimensions) {
      return clone(dimensions);
    }

    var externalTransformMap = createHashMap();
    function registerExternalTransform(externalTransform) {
      externalTransform = clone(externalTransform);
      var type = externalTransform.type;
      var errMsg = '';

      if (!type) {
        if ("development" !== 'production') {
          errMsg = 'Must have a `type` when `registerTransform`.';
        }

        throwError(errMsg);
      }

      var typeParsed = type.split(':');

      if (typeParsed.length !== 2) {
        if ("development" !== 'production') {
          errMsg = 'Name must include namespace like "ns:regression".';
        }

        throwError(errMsg);
      } // Namespace 'echarts:xxx' is official namespace, where the transforms should
      // be called directly via 'xxx' rather than 'echarts:xxx'.


      var isBuiltIn = false;

      if (typeParsed[0] === 'echarts') {
        type = typeParsed[1];
        isBuiltIn = true;
      }

      externalTransform.__isBuiltIn = isBuiltIn;
      externalTransformMap.set(type, externalTransform);
    }
    function applyDataTransform(rawTransOption, sourceList, infoForPrint) {
      var pipedTransOption = normalizeToArray(rawTransOption);
      var pipeLen = pipedTransOption.length;
      var errMsg = '';

      if (!pipeLen) {
        if ("development" !== 'production') {
          errMsg = 'If `transform` declared, it should at least contain one transform.';
        }

        throwError(errMsg);
      }

      for (var i = 0, len = pipeLen; i < len; i++) {
        var transOption = pipedTransOption[i];
        sourceList = applySingleDataTransform(transOption, sourceList, infoForPrint, pipeLen === 1 ? null : i); // piped transform only support single input, except the fist one.
        // piped transform only support single output, except the last one.

        if (i !== len - 1) {
          sourceList.length = Math.max(sourceList.length, 1);
        }
      }

      return sourceList;
    }

    function applySingleDataTransform(transOption, upSourceList, infoForPrint, // If `pipeIndex` is null/undefined, no piped transform.
    pipeIndex) {
      var errMsg = '';

      if (!upSourceList.length) {
        if ("development" !== 'production') {
          errMsg = 'Must have at least one upstream dataset.';
        }

        throwError(errMsg);
      }

      if (!isObject(transOption)) {
        if ("development" !== 'production') {
          errMsg = 'transform declaration must be an object rather than ' + typeof transOption + '.';
        }

        throwError(errMsg);
      }

      var transType = transOption.type;
      var externalTransform = externalTransformMap.get(transType);

      if (!externalTransform) {
        if ("development" !== 'production') {
          errMsg = 'Can not find transform on type "' + transType + '".';
        }

        throwError(errMsg);
      } // Prepare source


      var extUpSourceList = map(upSourceList, function (upSource) {
        return createExternalSource(upSource, externalTransform);
      });
      var resultList = normalizeToArray(externalTransform.transform({
        upstream: extUpSourceList[0],
        upstreamList: extUpSourceList,
        config: clone(transOption.config)
      }));

      if ("development" !== 'production') {
        if (transOption.print) {
          var printStrArr = map(resultList, function (extSource) {
            var pipeIndexStr = pipeIndex != null ? ' === pipe index: ' + pipeIndex : '';
            return ['=== dataset index: ' + infoForPrint.datasetIndex + pipeIndexStr + ' ===', '- transform result data:', makePrintable(extSource.data), '- transform result dimensions:', makePrintable(extSource.dimensions)].join('\n');
          }).join('\n');
          log(printStrArr);
        }
      }

      return map(resultList, function (result, resultIndex) {
        var errMsg = '';

        if (!isObject(result)) {
          if ("development" !== 'production') {
            errMsg = 'A transform should not return some empty results.';
          }

          throwError(errMsg);
        }

        if (!result.data) {
          if ("development" !== 'production') {
            errMsg = 'Transform result data should be not be null or undefined';
          }

          throwError(errMsg);
        }

        var sourceFormat = detectSourceFormat(result.data);

        if (!isSupportedSourceFormat(sourceFormat)) {
          if ("development" !== 'production') {
            errMsg = 'Transform result data should be array rows or object rows.';
          }

          throwError(errMsg);
        }

        var resultMetaRawOption;
        var firstUpSource = upSourceList[0];
        /**
         * Intuitively, the end users known the content of the original `dataset.source`,
         * calucating the transform result in mind.
         * Suppose the original `dataset.source` is:
         * ```js
         * [
         *     ['product', '2012', '2013', '2014', '2015'],
         *     ['AAA', 41.1, 30.4, 65.1, 53.3],
         *     ['BBB', 86.5, 92.1, 85.7, 83.1],
         *     ['CCC', 24.1, 67.2, 79.5, 86.4]
         * ]
         * ```
         * The dimension info have to be detected from the source data.
         * Some of the transformers (like filter, sort) will follow the dimension info
         * of upstream, while others use new dimensions (like aggregate).
         * Transformer can output a field `dimensions` to define the its own output dimensions.
         * We also allow transformers to ignore the output `dimensions` field, and
         * inherit the upstream dimensions definition. It can reduce the burden of handling
         * dimensions in transformers.
         *
         * See also [DIMENSION_INHERIT_RULE] in `sourceManager.ts`.
         */

        if (firstUpSource && resultIndex === 0 // If transformer returns `dimensions`, it means that the transformer has different
        // dimensions definitions. We do not inherit anything from upstream.
        && !result.dimensions) {
          var startIndex = firstUpSource.startIndex; // We copy the header of upstream to the result, because:
          // (1) The returned data always does not contain header line and can not be used
          // as dimension-detection. In this case we can not use "detected dimensions" of
          // upstream directly, because it might be detected based on different `seriesLayoutBy`.
          // (2) We should support that the series read the upstream source in `seriesLayoutBy: 'row'`.
          // So the original detected header should be add to the result, otherwise they can not be read.

          if (startIndex) {
            result.data = firstUpSource.data.slice(0, startIndex).concat(result.data);
          }

          resultMetaRawOption = {
            seriesLayoutBy: SERIES_LAYOUT_BY_COLUMN,
            sourceHeader: startIndex,
            dimensions: firstUpSource.metaRawOption.dimensions
          };
        } else {
          resultMetaRawOption = {
            seriesLayoutBy: SERIES_LAYOUT_BY_COLUMN,
            sourceHeader: 0,
            dimensions: result.dimensions
          };
        }

        return createSource(result.data, resultMetaRawOption, null);
      });
    }

    function isSupportedSourceFormat(sourceFormat) {
      return sourceFormat === SOURCE_FORMAT_ARRAY_ROWS || sourceFormat === SOURCE_FORMAT_OBJECT_ROWS;
    }

    var UNDEFINED = 'undefined';
    /* global Float64Array, Int32Array, Uint32Array, Uint16Array */
    // 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 CtorUint16Array = typeof Uint16Array === UNDEFINED ? Array : Uint16Array;
    var CtorInt32Array = typeof Int32Array === UNDEFINED ? Array : Int32Array;
    var CtorFloat64Array = typeof Float64Array === UNDEFINED ? Array : Float64Array;
    /**
     * Multi dimensional data store
     */

    var dataCtors = {
      'float': CtorFloat64Array,
      'int': CtorInt32Array,
      // Ordinal data type can be string or int
      'ordinal': Array,
      'number': Array,
      'time': CtorFloat64Array
    };
    var defaultDimValueGetters;

    function getIndicesCtor(rawCount) {
      // The possible max value in this._indicies is always this._rawCount despite of filtering.
      return rawCount > 65535 ? CtorUint32Array : CtorUint16Array;
    }

    function getInitialExtent() {
      return [Infinity, -Infinity];
    }

    function cloneChunk(originalChunk) {
      var Ctor = originalChunk.constructor; // Only shallow clone is enough when Array.

      return Ctor === Array ? originalChunk.slice() : new Ctor(originalChunk);
    }

    function prepareStore(store, dimIdx, dimType, end, append) {
      var DataCtor = dataCtors[dimType || 'float'];

      if (append) {
        var oldStore = store[dimIdx];
        var oldLen = oldStore && oldStore.length;

        if (!(oldLen === end)) {
          var newStore = new DataCtor(end); // The cost of the copy is probably inconsiderable
          // within the initial chunkSize.

          for (var j = 0; j < oldLen; j++) {
            newStore[j] = oldStore[j];
          }

          store[dimIdx] = newStore;
        }
      } else {
        store[dimIdx] = new DataCtor(end);
      }
    }
    /**
     * Basically, DataStore API keep immutable.
     */

    var DataStore =
    /** @class */
    function () {
      function DataStore() {
        this._chunks = []; // It will not be calculated util needed.

        this._rawExtent = [];
        this._extent = [];
        this._count = 0;
        this._rawCount = 0;
        this._calcDimNameToIdx = createHashMap();
      }
      /**
       * Initialize from data
       */


      DataStore.prototype.initData = function (provider, inputDimensions, dimValueGetter) {
        if ("development" !== 'production') {
          assert(isFunction(provider.getItem) && isFunction(provider.count), 'Invalid data provider.');
        }

        this._provider = provider; // Clear

        this._chunks = [];
        this._indices = null;
        this.getRawIndex = this._getRawIdxIdentity;
        var source = provider.getSource();
        var defaultGetter = this.defaultDimValueGetter = defaultDimValueGetters[source.sourceFormat]; // Default dim value getter

        this._dimValueGetter = dimValueGetter || defaultGetter; // Reset raw extent.

        this._rawExtent = [];
        var willRetrieveDataByName = shouldRetrieveDataByName(source);
        this._dimensions = map(inputDimensions, function (dim) {
          if ("development" !== 'production') {
            if (willRetrieveDataByName) {
              assert(dim.property != null);
            }
          }

          return {
            // Only pick these two props. Not leak other properties like orderMeta.
            type: dim.type,
            property: dim.property
          };
        });

        this._initDataFromProvider(0, provider.count());
      };

      DataStore.prototype.getProvider = function () {
        return this._provider;
      };
      /**
       * Caution: even when a `source` instance owned by a series, the created data store
       * may still be shared by different sereis (the source hash does not use all `source`
       * props, see `sourceManager`). In this case, the `source` props that are not used in
       * hash (like `source.dimensionDefine`) probably only belongs to a certain series and
       * thus should not be fetch here.
       */


      DataStore.prototype.getSource = function () {
        return this._provider.getSource();
      };
      /**
       * @caution Only used in dataStack.
       */


      DataStore.prototype.ensureCalculationDimension = function (dimName, type) {
        var calcDimNameToIdx = this._calcDimNameToIdx;
        var dimensions = this._dimensions;
        var calcDimIdx = calcDimNameToIdx.get(dimName);

        if (calcDimIdx != null) {
          if (dimensions[calcDimIdx].type === type) {
            return calcDimIdx;
          }
        } else {
          calcDimIdx = dimensions.length;
        }

        dimensions[calcDimIdx] = {
          type: type
        };
        calcDimNameToIdx.set(dimName, calcDimIdx);
        this._chunks[calcDimIdx] = new dataCtors[type || 'float'](this._rawCount);
        this._rawExtent[calcDimIdx] = getInitialExtent();
        return calcDimIdx;
      };

      DataStore.prototype.collectOrdinalMeta = function (dimIdx, ordinalMeta) {
        var chunk = this._chunks[dimIdx];
        var dim = this._dimensions[dimIdx];
        var rawExtents = this._rawExtent;
        var offset = dim.ordinalOffset || 0;
        var len = chunk.length;

        if (offset === 0) {
          // We need to reset the rawExtent if collect is from start.
          // Because this dimension may be guessed as number and calcuating a wrong extent.
          rawExtents[dimIdx] = getInitialExtent();
        }

        var dimRawExtent = rawExtents[dimIdx]; // Parse from previous data offset. len may be changed after appendData

        for (var i = offset; i < len; i++) {
          var val = chunk[i] = ordinalMeta.parseAndCollect(chunk[i]);

          if (!isNaN(val)) {
            dimRawExtent[0] = Math.min(val, dimRawExtent[0]);
            dimRawExtent[1] = Math.max(val, dimRawExtent[1]);
          }
        }

        dim.ordinalMeta = ordinalMeta;
        dim.ordinalOffset = len;
        dim.type = 'ordinal'; // Force to be ordinal
      };

      DataStore.prototype.getOrdinalMeta = function (dimIdx) {
        var dimInfo = this._dimensions[dimIdx];
        var ordinalMeta = dimInfo.ordinalMeta;
        return ordinalMeta;
      };

      DataStore.prototype.getDimensionProperty = function (dimIndex) {
        var item = this._dimensions[dimIndex];
        return item && item.property;
      };
      /**
       * Caution: Can be only called on raw data (before `this._indices` created).
       */


      DataStore.prototype.appendData = function (data) {
        if ("development" !== 'production') {
          assert(!this._indices, 'appendData can only be called on raw data.');
        }

        var provider = this._provider;
        var start = this.count();
        provider.appendData(data);
        var end = provider.count();

        if (!provider.persistent) {
          end += start;
        }

        if (start < end) {
          this._initDataFromProvider(start, end, true);
        }

        return [start, end];
      };

      DataStore.prototype.appendValues = function (values, minFillLen) {
        var chunks = this._chunks;
        var dimensions = this._dimensions;
        var dimLen = dimensions.length;
        var rawExtent = this._rawExtent;
        var start = this.count();
        var end = start + Math.max(values.length, minFillLen || 0);

        for (var i = 0; i < dimLen; i++) {
          var dim = dimensions[i];
          prepareStore(chunks, i, dim.type, end, true);
        }

        var emptyDataItem = [];

        for (var idx = start; idx < end; idx++) {
          var sourceIdx = idx - start; // Store the data by dimensions

          for (var dimIdx = 0; dimIdx < dimLen; dimIdx++) {
            var dim = dimensions[dimIdx];
            var val = defaultDimValueGetters.arrayRows.call(this, values[sourceIdx] || emptyDataItem, dim.property, sourceIdx, dimIdx);
            chunks[dimIdx][idx] = val;
            var dimRawExtent = rawExtent[dimIdx];
            val < dimRawExtent[0] && (dimRawExtent[0] = val);
            val > dimRawExtent[1] && (dimRawExtent[1] = val);
          }
        }

        this._rawCount = this._count = end;
        return {
          start: start,
          end: end
        };
      };

      DataStore.prototype._initDataFromProvider = function (start, end, append) {
        var provider = this._provider;
        var chunks = this._chunks;
        var dimensions = this._dimensions;
        var dimLen = dimensions.length;
        var rawExtent = this._rawExtent;
        var dimNames = map(dimensions, function (dim) {
          return dim.property;
        });

        for (var i = 0; i < dimLen; i++) {
          var dim = dimensions[i];

          if (!rawExtent[i]) {
            rawExtent[i] = getInitialExtent();
          }

          prepareStore(chunks, i, dim.type, end, append);
        }

        if (provider.fillStorage) {
          provider.fillStorage(start, end, chunks, rawExtent);
        } else {
          var dataItem = [];

          for (var idx = start; idx < end; idx++) {
            // NOTICE: Try not to write things into dataItem
            dataItem = provider.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
            // Store the data by dimensions

            for (var dimIdx = 0; dimIdx < dimLen; dimIdx++) {
              var dimStorage = chunks[dimIdx]; // PENDING NULL is empty or zero

              var val = this._dimValueGetter(dataItem, dimNames[dimIdx], idx, dimIdx);

              dimStorage[idx] = val;
              var dimRawExtent = rawExtent[dimIdx];
              val < dimRawExtent[0] && (dimRawExtent[0] = val);
              val > dimRawExtent[1] && (dimRawExtent[1] = val);
            }
          }
        }

        if (!provider.persistent && provider.clean) {
          // Clean unused data if data source is typed array.
          provider.clean();
        }

        this._rawCount = this._count = end; // Reset data extent

        this._extent = [];
      };

      DataStore.prototype.count = function () {
        return this._count;
      };
      /**
       * Get value. Return NaN if idx is out of range.
       */


      DataStore.prototype.get = function (dim, idx) {
        if (!(idx >= 0 && idx < this._count)) {
          return NaN;
        }

        var dimStore = this._chunks[dim];
        return dimStore ? dimStore[this.getRawIndex(idx)] : NaN;
      };

      DataStore.prototype.getValues = function (dimensions, idx) {
        var values = [];
        var dimArr = [];

        if (idx == null) {
          idx = dimensions; // TODO get all from store?

          dimensions = []; // All dimensions

          for (var i = 0; i < this._dimensions.length; i++) {
            dimArr.push(i);
          }
        } else {
          dimArr = dimensions;
        }

        for (var i = 0, len = dimArr.length; i < len; i++) {
          values.push(this.get(dimArr[i], idx));
        }

        return values;
      };
      /**
       * @param dim concrete dim
       */


      DataStore.prototype.getByRawIndex = function (dim, rawIdx) {
        if (!(rawIdx >= 0 && rawIdx < this._rawCount)) {
          return NaN;
        }

        var dimStore = this._chunks[dim];
        return dimStore ? dimStore[rawIdx] : NaN;
      };
      /**
       * Get sum of data in one dimension
       */


      DataStore.prototype.getSum = function (dim) {
        var dimData = this._chunks[dim];
        var sum = 0;

        if (dimData) {
          for (var i = 0, len = this.count(); i < len; i++) {
            var value = this.get(dim, i);

            if (!isNaN(value)) {
              sum += value;
            }
          }
        }

        return sum;
      };
      /**
       * Get median of data in one dimension
       */


      DataStore.prototype.getMedian = function (dim) {
        var dimDataArray = []; // map all data of one dimension

        this.each([dim], function (val) {
          if (!isNaN(val)) {
            dimDataArray.push(val);
          }
        }); // TODO
        // Use quick select?

        var sortedDimDataArray = 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;
      };
      /**
       * Retrieve the index with given raw data index.
       */


      DataStore.prototype.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;
      };
      /**
       * Retrieve the index of nearest value.
       * @param dim
       * @param value
       * @param [maxDistance=Infinity]
       * @return If and only if multiple indices have
       *         the same value, they are put to the result.
       */


      DataStore.prototype.indicesOfNearest = function (dim, value, maxDistance) {
        var chunks = this._chunks;
        var dimData = chunks[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/SeriesData.js`.

        for (var i = 0, len = this.count(); i < len; i++) {
          var dataIndex = this.getRawIndex(i);
          var diff = value - dimData[dataIndex];
          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;
      };

      DataStore.prototype.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._rawCount);
          newIndices = new Ctor(this.count());

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

        return newIndices;
      };
      /**
       * Data filter.
       */


      DataStore.prototype.filter = function (dims, cb) {
        if (!this._count) {
          return this;
        }

        var newStore = this.clone();
        var count = newStore.count();
        var Ctor = getIndicesCtor(newStore._rawCount);
        var newIndices = new Ctor(count);
        var value = [];
        var dimSize = dims.length;
        var offset = 0;
        var dim0 = dims[0];
        var chunks = newStore._chunks;

        for (var i = 0; i < count; i++) {
          var keep = void 0;
          var rawIdx = newStore.getRawIndex(i); // Simple optimization

          if (dimSize === 0) {
            keep = cb(i);
          } else if (dimSize === 1) {
            var val = chunks[dim0][rawIdx];
            keep = cb(val, i);
          } else {
            var k = 0;

            for (; k < dimSize; k++) {
              value[k] = chunks[dims[k]][rawIdx];
            }

            value[k] = i;
            keep = cb.apply(null, value);
          }

          if (keep) {
            newIndices[offset++] = rawIdx;
          }
        } // Set indices after filtered.


        if (offset < count) {
          newStore._indices = newIndices;
        }

        newStore._count = offset; // Reset data extent

        newStore._extent = [];

        newStore._updateGetRawIdx();

        return newStore;
      };
      /**
       * Select data in range. (For optimization of filter)
       * (Manually inline code, support 5 million data filtering in data zoom.)
       */


      DataStore.prototype.selectRange = function (range) {
        var newStore = this.clone();
        var len = newStore._count;

        if (!len) {
          return this;
        }

        var dims = keys(range);
        var dimSize = dims.length;

        if (!dimSize) {
          return this;
        }

        var originalCount = newStore.count();
        var Ctor = getIndicesCtor(newStore._rawCount);
        var newIndices = new Ctor(originalCount);
        var offset = 0;
        var dim0 = dims[0];
        var min = range[dim0][0];
        var max = range[dim0][1];
        var storeArr = newStore._chunks;
        var quickFinished = false;

        if (!newStore._indices) {
          // Extreme optimization for common case. About 2x faster in chrome.
          var idx = 0;

          if (dimSize === 1) {
            var dimStorage = storeArr[dims[0]];

            for (var i = 0; i < len; i++) {
              var val = dimStorage[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 = storeArr[dims[0]];
            var dimStorage2 = storeArr[dims[1]];
            var min2 = range[dims[1]][0];
            var max2 = range[dims[1]][1];

            for (var i = 0; i < len; i++) {
              var val = dimStorage[i];
              var val2 = dimStorage2[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 = newStore.getRawIndex(i);
              var val = storeArr[dims[0]][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 = newStore.getRawIndex(i);

              for (var k = 0; k < dimSize; k++) {
                var dimk = dims[k];
                var val = storeArr[dimk][rawIndex]; // Do not filter NaN, see comment above.

                if (val < range[dimk][0] || val > range[dimk][1]) {
                  keep = false;
                }
              }

              if (keep) {
                newIndices[offset++] = newStore.getRawIndex(i);
              }
            }
          }
        } // Set indices after filtered.


        if (offset < originalCount) {
          newStore._indices = newIndices;
        }

        newStore._count = offset; // Reset data extent

        newStore._extent = [];

        newStore._updateGetRawIdx();

        return newStore;
      }; // /**
      //  * Data mapping to a plain array
      //  */
      // mapArray(dims: DimensionIndex[], cb: MapArrayCb): any[] {
      //     const result: any[] = [];
      //     this.each(dims, function () {
      //         result.push(cb && (cb as MapArrayCb).apply(null, arguments));
      //     });
      //     return result;
      // }

      /**
       * Data mapping to a new List with given dimensions
       */


      DataStore.prototype.map = function (dims, cb) {
        // TODO only clone picked chunks.
        var target = this.clone(dims);

        this._updateDims(target, dims, cb);

        return target;
      };
      /**
       * @caution Danger!! Only used in dataStack.
       */


      DataStore.prototype.modify = function (dims, cb) {
        this._updateDims(this, dims, cb);
      };

      DataStore.prototype._updateDims = function (target, dims, cb) {
        var targetChunks = target._chunks;
        var tmpRetValue = [];
        var dimSize = dims.length;
        var dataCount = target.count();
        var values = [];
        var rawExtent = target._rawExtent;

        for (var i = 0; i < dims.length; i++) {
          rawExtent[dims[i]] = getInitialExtent();
        }

        for (var dataIndex = 0; dataIndex < dataCount; dataIndex++) {
          var rawIndex = target.getRawIndex(dataIndex);

          for (var k = 0; k < dimSize; k++) {
            values[k] = targetChunks[dims[k]][rawIndex];
          }

          values[dimSize] = dataIndex;
          var retValue = cb && cb.apply(null, values);

          if (retValue != null) {
            // a number or string (in oridinal dimension)?
            if (typeof retValue !== 'object') {
              tmpRetValue[0] = retValue;
              retValue = tmpRetValue;
            }

            for (var i = 0; i < retValue.length; i++) {
              var dim = dims[i];
              var val = retValue[i];
              var rawExtentOnDim = rawExtent[dim];
              var dimStore = targetChunks[dim];

              if (dimStore) {
                dimStore[rawIndex] = val;
              }

              if (val < rawExtentOnDim[0]) {
                rawExtentOnDim[0] = val;
              }

              if (val > rawExtentOnDim[1]) {
                rawExtentOnDim[1] = val;
              }
            }
          }
        }
      };
      /**
       * Large data down sampling using largest-triangle-three-buckets
       * @param {string} valueDimension
       * @param {number} targetCount
       */


      DataStore.prototype.lttbDownSample = function (valueDimension, rate) {
        var target = this.clone([valueDimension], true);
        var targetStorage = target._chunks;
        var dimStore = targetStorage[valueDimension];
        var len = this.count();
        var sampledIndex = 0;
        var frameSize = Math.floor(1 / rate);
        var currentRawIndex = this.getRawIndex(0);
        var maxArea;
        var area;
        var nextRawIndex;
        var newIndices = new (getIndicesCtor(this._rawCount))(Math.min((Math.ceil(len / frameSize) + 2) * 2, len)); // First frame use the first data.

        newIndices[sampledIndex++] = currentRawIndex;

        for (var i = 1; i < len - 1; i += frameSize) {
          var nextFrameStart = Math.min(i + frameSize, len - 1);
          var nextFrameEnd = Math.min(i + frameSize * 2, len);
          var avgX = (nextFrameEnd + nextFrameStart) / 2;
          var avgY = 0;

          for (var idx = nextFrameStart; idx < nextFrameEnd; idx++) {
            var rawIndex = this.getRawIndex(idx);
            var y = dimStore[rawIndex];

            if (isNaN(y)) {
              continue;
            }

            avgY += y;
          }

          avgY /= nextFrameEnd - nextFrameStart;
          var frameStart = i;
          var frameEnd = Math.min(i + frameSize, len);
          var pointAX = i - 1;
          var pointAY = dimStore[currentRawIndex];
          maxArea = -1;
          nextRawIndex = frameStart;
          var firstNaNIndex = -1;
          var countNaN = 0; // Find a point from current frame that construct a triangel with largest area with previous selected point
          // And the average of next frame.

          for (var idx = frameStart; idx < frameEnd; idx++) {
            var rawIndex = this.getRawIndex(idx);
            var y = dimStore[rawIndex];

            if (isNaN(y)) {
              countNaN++;

              if (firstNaNIndex < 0) {
                firstNaNIndex = rawIndex;
              }

              continue;
            } // Calculate triangle area over three buckets


            area = Math.abs((pointAX - avgX) * (y - pointAY) - (pointAX - idx) * (avgY - pointAY));

            if (area > maxArea) {
              maxArea = area;
              nextRawIndex = rawIndex; // Next a is this b
            }
          }

          if (countNaN > 0 && countNaN < frameEnd - frameStart) {
            // Append first NaN point in every bucket.
            // It is necessary to ensure the correct order of indices.
            newIndices[sampledIndex++] = Math.min(firstNaNIndex, nextRawIndex);
            nextRawIndex = Math.max(firstNaNIndex, nextRawIndex);
          }

          newIndices[sampledIndex++] = nextRawIndex;
          currentRawIndex = nextRawIndex; // This a is the next a (chosen b)
        } // First frame use the last data.


        newIndices[sampledIndex++] = this.getRawIndex(len - 1);
        target._count = sampledIndex;
        target._indices = newIndices;
        target.getRawIndex = this._getRawIdx;
        return target;
      };
      /**
       * Large data down sampling on given dimension
       * @param sampleIndex Sample index for name and id
       */


      DataStore.prototype.downSample = function (dimension, rate, sampleValue, sampleIndex) {
        var target = this.clone([dimension], true);
        var targetStorage = target._chunks;
        var frameValues = [];
        var frameSize = Math.floor(1 / rate);
        var dimStore = targetStorage[dimension];
        var len = this.count();
        var rawExtentOnDim = target._rawExtent[dimension] = getInitialExtent();
        var newIndices = new (getIndicesCtor(this._rawCount))(Math.ceil(len / frameSize));
        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);
            frameValues[k] = dimStore[dataIdx];
          }

          var value = sampleValue(frameValues);
          var sampleFrameIdx = this.getRawIndex(Math.min(i + sampleIndex(frameValues, value) || 0, len - 1)); // Only write value on the filtered data

          dimStore[sampleFrameIdx] = value;

          if (value < rawExtentOnDim[0]) {
            rawExtentOnDim[0] = value;
          }

          if (value > rawExtentOnDim[1]) {
            rawExtentOnDim[1] = value;
          }

          newIndices[offset++] = sampleFrameIdx;
        }

        target._count = offset;
        target._indices = newIndices;

        target._updateGetRawIdx();

        return target;
      };
      /**
       * Data iteration
       * @param ctx default this
       * @example
       *  list.each('x', function (x, idx) {});
       *  list.each(['x', 'y'], function (x, y, idx) {});
       *  list.each(function (idx) {})
       */


      DataStore.prototype.each = function (dims, cb) {
        if (!this._count) {
          return;
        }

        var dimSize = dims.length;
        var chunks = this._chunks;

        for (var i = 0, len = this.count(); i < len; i++) {
          var rawIdx = this.getRawIndex(i); // Simple optimization

          switch (dimSize) {
            case 0:
              cb(i);
              break;

            case 1:
              cb(chunks[dims[0]][rawIdx], i);
              break;

            case 2:
              cb(chunks[dims[0]][rawIdx], chunks[dims[1]][rawIdx], i);
              break;

            default:
              var k = 0;
              var value = [];

              for (; k < dimSize; k++) {
                value[k] = chunks[dims[k]][rawIdx];
              } // Index


              value[k] = i;
              cb.apply(null, value);
          }
        }
      };
      /**
       * Get extent of data in one dimension
       */


      DataStore.prototype.getDataExtent = function (dim) {
        // Make sure use concrete dim as cache name.
        var dimData = this._chunks[dim];
        var initialExtent = getInitialExtent();

        if (!dimData) {
          return initialExtent;
        } // Make more strict checkings to ensure hitting cache.


        var currEnd = this.count(); // 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;
        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 rawIdx = this.getRawIndex(i);
          var value = dimData[rawIdx];
          value < min && (min = value);
          value > max && (max = value);
        }

        dimExtent = [min, max];
        this._extent[dim] = dimExtent;
        return dimExtent;
      };
      /**
       * Get raw data item
       */


      DataStore.prototype.getRawDataItem = function (idx) {
        var rawIdx = this.getRawIndex(idx);

        if (!this._provider.persistent) {
          var val = [];
          var chunks = this._chunks;

          for (var i = 0; i < chunks.length; i++) {
            val.push(chunks[i][rawIdx]);
          }

          return val;
        } else {
          return this._provider.getItem(rawIdx);
        }
      };
      /**
       * Clone shallow.
       *
       * @param clonedDims Determine which dims to clone. Will share the data if not specified.
       */


      DataStore.prototype.clone = function (clonedDims, ignoreIndices) {
        var target = new DataStore();
        var chunks = this._chunks;
        var clonedDimsMap = clonedDims && reduce(clonedDims, function (obj, dimIdx) {
          obj[dimIdx] = true;
          return obj;
        }, {});

        if (clonedDimsMap) {
          for (var i = 0; i < chunks.length; i++) {
            // Not clone if dim is not picked.
            target._chunks[i] = !clonedDimsMap[i] ? chunks[i] : cloneChunk(chunks[i]);
          }
        } else {
          target._chunks = chunks;
        }

        this._copyCommonProps(target);

        if (!ignoreIndices) {
          target._indices = this._cloneIndices();
        }

        target._updateGetRawIdx();

        return target;
      };

      DataStore.prototype._copyCommonProps = function (target) {
        target._count = this._count;
        target._rawCount = this._rawCount;
        target._provider = this._provider;
        target._dimensions = this._dimensions;
        target._extent = clone(this._extent);
        target._rawExtent = clone(this._rawExtent);
      };

      DataStore.prototype._cloneIndices = function () {
        if (this._indices) {
          var Ctor = this._indices.constructor;
          var indices = void 0;

          if (Ctor === Array) {
            var thisCount = this._indices.length;
            indices = new Ctor(thisCount);

            for (var i = 0; i < thisCount; i++) {
              indices[i] = this._indices[i];
            }
          } else {
            indices = new Ctor(this._indices);
          }

          return indices;
        }

        return null;
      };

      DataStore.prototype._getRawIdxIdentity = function (idx) {
        return idx;
      };

      DataStore.prototype._getRawIdx = function (idx) {
        if (idx < this._count && idx >= 0) {
          return this._indices[idx];
        }

        return -1;
      };

      DataStore.prototype._updateGetRawIdx = function () {
        this.getRawIndex = this._indices ? this._getRawIdx : this._getRawIdxIdentity;
      };

      DataStore.internalField = function () {
        function getDimValueSimply(dataItem, property, dataIndex, dimIndex) {
          return parseDataValue(dataItem[dimIndex], this._dimensions[dimIndex]);
        }

        defaultDimValueGetters = {
          arrayRows: getDimValueSimply,
          objectRows: function (dataItem, property, dataIndex, dimIndex) {
            return parseDataValue(dataItem[property], this._dimensions[dimIndex]);
          },
          keyedColumns: getDimValueSimply,
          original: function (dataItem, property, dataIndex, dimIndex) {
            // Performance sensitive, do not use modelUtil.getDataItemValue.
            // If dataItem is an plain object with no value field, the let `value`
            // will be assigned with the object, but it will be tread correctly
            // in the `convertValue`.
            var value = dataItem && (dataItem.value == null ? dataItem : dataItem.value);
            return parseDataValue(value instanceof Array ? value[dimIndex] // If value is a single number or something else not array.
            : value, this._dimensions[dimIndex]);
          },
          typedArray: function (dataItem, property, dataIndex, dimIndex) {
            return dataItem[dimIndex];
          }
        };
      }();

      return DataStore;
    }();

    /**
     * [REQUIREMENT_MEMO]:
     * (0) `metaRawOption` means `dimensions`/`sourceHeader`/`seriesLayoutBy` in raw option.
     * (1) Keep support the feature: `metaRawOption` can be specified both on `series` and
     * `root-dataset`. Them on `series` has higher priority.
     * (2) Do not support to set `metaRawOption` on a `non-root-dataset`, because it might
     * confuse users: whether those props indicate how to visit the upstream source or visit
     * the transform result source, and some transforms has nothing to do with these props,
     * and some transforms might have multiple upstream.
     * (3) Transforms should specify `metaRawOption` in each output, just like they can be
     * declared in `root-dataset`.
     * (4) At present only support visit source in `SERIES_LAYOUT_BY_COLUMN` in transforms.
     * That is for reducing complexity in transforms.
     * PENDING: Whether to provide transposition transform?
     *
     * [IMPLEMENTAION_MEMO]:
     * "sourceVisitConfig" are calculated from `metaRawOption` and `data`.
     * They will not be calculated until `source` is about to be visited (to prevent from
     * duplicate calcuation). `source` is visited only in series and input to transforms.
     *
     * [DIMENSION_INHERIT_RULE]:
     * By default the dimensions are inherited from ancestors, unless a transform return
     * a new dimensions definition.
     * Consider the case:
     * ```js
     * dataset: [{
     *     source: [ ['Product', 'Sales', 'Prise'], ['Cookies', 321, 44.21], ...]
     * }, {
     *     transform: { type: 'filter', ... }
     * }]
     * dataset: [{
     *     dimension: ['Product', 'Sales', 'Prise'],
     *     source: [ ['Cookies', 321, 44.21], ...]
     * }, {
     *     transform: { type: 'filter', ... }
     * }]
     * ```
     * The two types of option should have the same behavior after transform.
     *
     *
     * [SCENARIO]:
     * (1) Provide source data directly:
     * ```js
     * series: {
     *     encode: {...},
     *     dimensions: [...]
     *     seriesLayoutBy: 'row',
     *     data: [[...]]
     * }
     * ```
     * (2) Series refer to dataset.
     * ```js
     * series: [{
     *     encode: {...}
     *     // Ignore datasetIndex means `datasetIndex: 0`
     *     // and the dimensions defination in dataset is used
     * }, {
     *     encode: {...},
     *     seriesLayoutBy: 'column',
     *     datasetIndex: 1
     * }]
     * ```
     * (3) dataset transform
     * ```js
     * dataset: [{
     *     source: [...]
     * }, {
     *     source: [...]
     * }, {
     *     // By default from 0.
     *     transform: { type: 'filter', config: {...} }
     * }, {
     *     // Piped.
     *     transform: [
     *         { type: 'filter', config: {...} },
     *         { type: 'sort', config: {...} }
     *     ]
     * }, {
     *     id: 'regressionData',
     *     fromDatasetIndex: 1,
     *     // Third-party transform
     *     transform: { type: 'ecStat:regression', config: {...} }
     * }, {
     *     // retrieve the extra result.
     *     id: 'regressionFormula',
     *     fromDatasetId: 'regressionData',
     *     fromTransformResult: 1
     * }]
     * ```
     */

    var SourceManager =
    /** @class */
    function () {
      function SourceManager(sourceHost) {
        // Cached source. Do not repeat calculating if not dirty.
        this._sourceList = [];
        this._storeList = []; // version sign of each upstream source manager.

        this._upstreamSignList = [];
        this._versionSignBase = 0;
        this._dirty = true;
        this._sourceHost = sourceHost;
      }
      /**
       * Mark dirty.
       */


      SourceManager.prototype.dirty = function () {
        this._setLocalSource([], []);

        this._storeList = [];
        this._dirty = true;
      };

      SourceManager.prototype._setLocalSource = function (sourceList, upstreamSignList) {
        this._sourceList = sourceList;
        this._upstreamSignList = upstreamSignList;
        this._versionSignBase++;

        if (this._versionSignBase > 9e10) {
          this._versionSignBase = 0;
        }
      };
      /**
       * For detecting whether the upstream source is dirty, so that
       * the local cached source (in `_sourceList`) should be discarded.
       */


      SourceManager.prototype._getVersionSign = function () {
        return this._sourceHost.uid + '_' + this._versionSignBase;
      };
      /**
       * Always return a source instance. Otherwise throw error.
       */


      SourceManager.prototype.prepareSource = function () {
        // For the case that call `setOption` multiple time but no data changed,
        // cache the result source to prevent from repeating transform.
        if (this._isDirty()) {
          this._createSource();

          this._dirty = false;
        }
      };

      SourceManager.prototype._createSource = function () {
        this._setLocalSource([], []);

        var sourceHost = this._sourceHost;

        var upSourceMgrList = this._getUpstreamSourceManagers();

        var hasUpstream = !!upSourceMgrList.length;
        var resultSourceList;
        var upstreamSignList;

        if (isSeries(sourceHost)) {
          var seriesModel = sourceHost;
          var data = void 0;
          var sourceFormat = void 0;
          var upSource = void 0; // Has upstream dataset

          if (hasUpstream) {
            var upSourceMgr = upSourceMgrList[0];
            upSourceMgr.prepareSource();
            upSource = upSourceMgr.getSource();
            data = upSource.data;
            sourceFormat = upSource.sourceFormat;
            upstreamSignList = [upSourceMgr._getVersionSign()];
          } // Series data is from own.
          else {
              data = seriesModel.get('data', true);
              sourceFormat = isTypedArray(data) ? SOURCE_FORMAT_TYPED_ARRAY : SOURCE_FORMAT_ORIGINAL;
              upstreamSignList = [];
            } // See [REQUIREMENT_MEMO], merge settings on series and parent dataset if it is root.


          var newMetaRawOption = this._getSourceMetaRawOption() || {};
          var upMetaRawOption = upSource && upSource.metaRawOption || {};
          var seriesLayoutBy = retrieve2(newMetaRawOption.seriesLayoutBy, upMetaRawOption.seriesLayoutBy) || null;
          var sourceHeader = retrieve2(newMetaRawOption.sourceHeader, upMetaRawOption.sourceHeader); // Note here we should not use `upSource.dimensionsDefine`. Consider the case:
          // `upSource.dimensionsDefine` is detected by `seriesLayoutBy: 'column'`,
          // but series need `seriesLayoutBy: 'row'`.

          var dimensions = retrieve2(newMetaRawOption.dimensions, upMetaRawOption.dimensions); // We share source with dataset as much as possible
          // to avoid extra memory cost of high dimensional data.

          var needsCreateSource = seriesLayoutBy !== upMetaRawOption.seriesLayoutBy || !!sourceHeader !== !!upMetaRawOption.sourceHeader || dimensions;
          resultSourceList = needsCreateSource ? [createSource(data, {
            seriesLayoutBy: seriesLayoutBy,
            sourceHeader: sourceHeader,
            dimensions: dimensions
          }, sourceFormat)] : [];
        } else {
          var datasetModel = sourceHost; // Has upstream dataset.

          if (hasUpstream) {
            var result = this._applyTransform(upSourceMgrList);

            resultSourceList = result.sourceList;
            upstreamSignList = result.upstreamSignList;
          } // Is root dataset.
          else {
              var sourceData = datasetModel.get('source', true);
              resultSourceList = [createSource(sourceData, this._getSourceMetaRawOption(), null)];
              upstreamSignList = [];
            }
        }

        if ("development" !== 'production') {
          assert(resultSourceList && upstreamSignList);
        }

        this._setLocalSource(resultSourceList, upstreamSignList);
      };

      SourceManager.prototype._applyTransform = function (upMgrList) {
        var datasetModel = this._sourceHost;
        var transformOption = datasetModel.get('transform', true);
        var fromTransformResult = datasetModel.get('fromTransformResult', true);

        if ("development" !== 'production') {
          assert(fromTransformResult != null || transformOption != null);
        }

        if (fromTransformResult != null) {
          var errMsg = '';

          if (upMgrList.length !== 1) {
            if ("development" !== 'production') {
              errMsg = 'When using `fromTransformResult`, there should be only one upstream dataset';
            }

            doThrow(errMsg);
          }
        }

        var sourceList;
        var upSourceList = [];
        var upstreamSignList = [];
        each(upMgrList, function (upMgr) {
          upMgr.prepareSource();
          var upSource = upMgr.getSource(fromTransformResult || 0);
          var errMsg = '';

          if (fromTransformResult != null && !upSource) {
            if ("development" !== 'production') {
              errMsg = 'Can not retrieve result by `fromTransformResult`: ' + fromTransformResult;
            }

            doThrow(errMsg);
          }

          upSourceList.push(upSource);
          upstreamSignList.push(upMgr._getVersionSign());
        });

        if (transformOption) {
          sourceList = applyDataTransform(transformOption, upSourceList, {
            datasetIndex: datasetModel.componentIndex
          });
        } else if (fromTransformResult != null) {
          sourceList = [cloneSourceShallow(upSourceList[0])];
        }

        return {
          sourceList: sourceList,
          upstreamSignList: upstreamSignList
        };
      };

      SourceManager.prototype._isDirty = function () {
        if (this._dirty) {
          return true;
        } // All sourceList is from the some upstream.


        var upSourceMgrList = this._getUpstreamSourceManagers();

        for (var i = 0; i < upSourceMgrList.length; i++) {
          var upSrcMgr = upSourceMgrList[i];

          if ( // Consider the case that there is ancestor diry, call it recursively.
          // The performance is probably not an issue because usually the chain is not long.
          upSrcMgr._isDirty() || this._upstreamSignList[i] !== upSrcMgr._getVersionSign()) {
            return true;
          }
        }
      };
      /**
       * @param sourceIndex By default 0, means "main source".
       *                    In most cases there is only one source.
       */


      SourceManager.prototype.getSource = function (sourceIndex) {
        sourceIndex = sourceIndex || 0;
        var source = this._sourceList[sourceIndex];

        if (!source) {
          // Series may share source instance with dataset.
          var upSourceMgrList = this._getUpstreamSourceManagers();

          return upSourceMgrList[0] && upSourceMgrList[0].getSource(sourceIndex);
        }

        return source;
      };
      /**
       *
       * Get a data store which can be shared across series.
       * Only available for series.
       *
       * @param seriesDimRequest Dimensions that are generated in series.
       *        Should have been sorted by `storeDimIndex` asc.
       */


      SourceManager.prototype.getSharedDataStore = function (seriesDimRequest) {
        if ("development" !== 'production') {
          assert(isSeries(this._sourceHost), 'Can only call getDataStore on series source manager.');
        }

        var schema = seriesDimRequest.makeStoreSchema();
        return this._innerGetDataStore(schema.dimensions, seriesDimRequest.source, schema.hash);
      };

      SourceManager.prototype._innerGetDataStore = function (storeDims, seriesSource, sourceReadKey) {
        // TODO Can use other sourceIndex?
        var sourceIndex = 0;
        var storeList = this._storeList;
        var cachedStoreMap = storeList[sourceIndex];

        if (!cachedStoreMap) {
          cachedStoreMap = storeList[sourceIndex] = {};
        }

        var cachedStore = cachedStoreMap[sourceReadKey];

        if (!cachedStore) {
          var upSourceMgr = this._getUpstreamSourceManagers()[0];

          if (isSeries(this._sourceHost) && upSourceMgr) {
            cachedStore = upSourceMgr._innerGetDataStore(storeDims, seriesSource, sourceReadKey);
          } else {
            cachedStore = new DataStore(); // Always create store from source of series.

            cachedStore.initData(new DefaultDataProvider(seriesSource, storeDims.length), storeDims);
          }

          cachedStoreMap[sourceReadKey] = cachedStore;
        }

        return cachedStore;
      };
      /**
       * PENDING: Is it fast enough?
       * If no upstream, return empty array.
       */


      SourceManager.prototype._getUpstreamSourceManagers = function () {
        // Always get the relationship from the raw option.
        // Do not cache the link of the dependency graph, so that
        // there is no need to update them when change happens.
        var sourceHost = this._sourceHost;

        if (isSeries(sourceHost)) {
          var datasetModel = querySeriesUpstreamDatasetModel(sourceHost);
          return !datasetModel ? [] : [datasetModel.getSourceManager()];
        } else {
          return map(queryDatasetUpstreamDatasetModels(sourceHost), function (datasetModel) {
            return datasetModel.getSourceManager();
          });
        }
      };

      SourceManager.prototype._getSourceMetaRawOption = function () {
        var sourceHost = this._sourceHost;
        var seriesLayoutBy;
        var sourceHeader;
        var dimensions;

        if (isSeries(sourceHost)) {
          seriesLayoutBy = sourceHost.get('seriesLayoutBy', true);
          sourceHeader = sourceHost.get('sourceHeader', true);
          dimensions = sourceHost.get('dimensions', true);
        } // See [REQUIREMENT_MEMO], `non-root-dataset` do not support them.
        else if (!this._getUpstreamSourceManagers().length) {
            var model = sourceHost;
            seriesLayoutBy = model.get('seriesLayoutBy', true);
            sourceHeader = model.get('sourceHeader', true);
            dimensions = model.get('dimensions', true);
          }

        return {
          seriesLayoutBy: seriesLayoutBy,
          sourceHeader: sourceHeader,
          dimensions: dimensions
        };
      };

      return SourceManager;
    }();
    // disable the transform merge, but do not disable transform clone from rawOption.

    function disableTransformOptionMerge(datasetModel) {
      var transformOption = datasetModel.option.transform;
      transformOption && setAsPrimitive(datasetModel.option.transform);
    }

    function isSeries(sourceHost) {
      // Avoid circular dependency with Series.ts
      return sourceHost.mainType === 'series';
    }

    function doThrow(errMsg) {
      throw new Error(errMsg);
    }

    var TOOLTIP_LINE_HEIGHT_CSS = 'line-height:1'; // TODO: more textStyle option

    function getTooltipTextStyle(textStyle, renderMode) {
      var nameFontColor = textStyle.color || '#6e7079';
      var nameFontSize = textStyle.fontSize || 12;
      var nameFontWeight = textStyle.fontWeight || '400';
      var valueFontColor = textStyle.color || '#464646';
      var valueFontSize = textStyle.fontSize || 14;
      var valueFontWeight = textStyle.fontWeight || '900';

      if (renderMode === 'html') {
        // `textStyle` is probably from user input, should be encoded to reduce security risk.
        return {
          // eslint-disable-next-line max-len
          nameStyle: "font-size:" + encodeHTML(nameFontSize + '') + "px;color:" + encodeHTML(nameFontColor) + ";font-weight:" + encodeHTML(nameFontWeight + ''),
          // eslint-disable-next-line max-len
          valueStyle: "font-size:" + encodeHTML(valueFontSize + '') + "px;color:" + encodeHTML(valueFontColor) + ";font-weight:" + encodeHTML(valueFontWeight + '')
        };
      } else {
        return {
          nameStyle: {
            fontSize: nameFontSize,
            fill: nameFontColor,
            fontWeight: nameFontWeight
          },
          valueStyle: {
            fontSize: valueFontSize,
            fill: valueFontColor,
            fontWeight: valueFontWeight
          }
        };
      }
    } // See `TooltipMarkupLayoutIntent['innerGapLevel']`.
    // (value from UI design)


    var HTML_GAPS = [0, 10, 20, 30];
    var RICH_TEXT_GAPS = ['', '\n', '\n\n', '\n\n\n']; // eslint-disable-next-line max-len

    function createTooltipMarkup(type, option) {
      option.type = type;
      return option;
    }

    function isSectionFragment(frag) {
      return frag.type === 'section';
    }

    function getBuilder(frag) {
      return isSectionFragment(frag) ? buildSection : buildNameValue;
    }

    function getBlockGapLevel(frag) {
      if (isSectionFragment(frag)) {
        var gapLevel_1 = 0;
        var subBlockLen = frag.blocks.length;
        var hasInnerGap_1 = subBlockLen > 1 || subBlockLen > 0 && !frag.noHeader;
        each(frag.blocks, function (subBlock) {
          var subGapLevel = getBlockGapLevel(subBlock); // If the some of the sub-blocks have some gaps (like 10px) inside, this block
          // should use a larger gap (like 20px) to distinguish those sub-blocks.

          if (subGapLevel >= gapLevel_1) {
            gapLevel_1 = subGapLevel + +(hasInnerGap_1 && ( // 0 always can not be readable gap level.
            !subGapLevel // If no header, always keep the sub gap level. Otherwise
            // look weird in case `multipleSeries`.
            || isSectionFragment(subBlock) && !subBlock.noHeader));
          }
        });
        return gapLevel_1;
      }

      return 0;
    }

    function buildSection(ctx, fragment, topMarginForOuterGap, toolTipTextStyle) {
      var noHeader = fragment.noHeader;
      var gaps = getGap(getBlockGapLevel(fragment));
      var subMarkupTextList = [];
      var subBlocks = fragment.blocks || [];
      assert(!subBlocks || isArray(subBlocks));
      subBlocks = subBlocks || [];
      var orderMode = ctx.orderMode;

      if (fragment.sortBlocks && orderMode) {
        subBlocks = subBlocks.slice();
        var orderMap = {
          valueAsc: 'asc',
          valueDesc: 'desc'
        };

        if (hasOwn(orderMap, orderMode)) {
          var comparator_1 = new SortOrderComparator(orderMap[orderMode], null);
          subBlocks.sort(function (a, b) {
            return comparator_1.evaluate(a.sortParam, b.sortParam);
          });
        } // FIXME 'seriesDesc' necessary?
        else if (orderMode === 'seriesDesc') {
            subBlocks.reverse();
          }
      }

      each(subBlocks, function (subBlock, idx) {
        var valueFormatter = fragment.valueFormatter;
        var subMarkupText = getBuilder(subBlock)( // Inherit valueFormatter
        valueFormatter ? extend(extend({}, ctx), {
          valueFormatter: valueFormatter
        }) : ctx, subBlock, idx > 0 ? gaps.html : 0, toolTipTextStyle);
        subMarkupText != null && subMarkupTextList.push(subMarkupText);
      });
      var subMarkupText = ctx.renderMode === 'richText' ? subMarkupTextList.join(gaps.richText) : wrapBlockHTML(subMarkupTextList.join(''), noHeader ? topMarginForOuterGap : gaps.html);

      if (noHeader) {
        return subMarkupText;
      }

      var displayableHeader = makeValueReadable(fragment.header, 'ordinal', ctx.useUTC);
      var nameStyle = getTooltipTextStyle(toolTipTextStyle, ctx.renderMode).nameStyle;

      if (ctx.renderMode === 'richText') {
        return wrapInlineNameRichText(ctx, displayableHeader, nameStyle) + gaps.richText + subMarkupText;
      } else {
        return wrapBlockHTML("<div style=\"" + nameStyle + ";" + TOOLTIP_LINE_HEIGHT_CSS + ";\">" + encodeHTML(displayableHeader) + '</div>' + subMarkupText, topMarginForOuterGap);
      }
    }

    function buildNameValue(ctx, fragment, topMarginForOuterGap, toolTipTextStyle) {
      var renderMode = ctx.renderMode;
      var noName = fragment.noName;
      var noValue = fragment.noValue;
      var noMarker = !fragment.markerType;
      var name = fragment.name;
      var useUTC = ctx.useUTC;

      var valueFormatter = fragment.valueFormatter || ctx.valueFormatter || function (value) {
        value = isArray(value) ? value : [value];
        return map(value, function (val, idx) {
          return makeValueReadable(val, isArray(valueTypeOption) ? valueTypeOption[idx] : valueTypeOption, useUTC);
        });
      };

      if (noName && noValue) {
        return;
      }

      var markerStr = noMarker ? '' : ctx.markupStyleCreator.makeTooltipMarker(fragment.markerType, fragment.markerColor || '#333', renderMode);
      var readableName = noName ? '' : makeValueReadable(name, 'ordinal', useUTC);
      var valueTypeOption = fragment.valueType;
      var readableValueList = noValue ? [] : valueFormatter(fragment.value);
      var valueAlignRight = !noMarker || !noName; // It little weird if only value next to marker but far from marker.

      var valueCloseToMarker = !noMarker && noName;

      var _a = getTooltipTextStyle(toolTipTextStyle, renderMode),
          nameStyle = _a.nameStyle,
          valueStyle = _a.valueStyle;

      return renderMode === 'richText' ? (noMarker ? '' : markerStr) + (noName ? '' : wrapInlineNameRichText(ctx, readableName, nameStyle)) // Value has commas inside, so use ' ' as delimiter for multiple values.
      + (noValue ? '' : wrapInlineValueRichText(ctx, readableValueList, valueAlignRight, valueCloseToMarker, valueStyle)) : wrapBlockHTML((noMarker ? '' : markerStr) + (noName ? '' : wrapInlineNameHTML(readableName, !noMarker, nameStyle)) + (noValue ? '' : wrapInlineValueHTML(readableValueList, valueAlignRight, valueCloseToMarker, valueStyle)), topMarginForOuterGap);
    }
    /**
     * @return markupText. null/undefined means no content.
     */


    function buildTooltipMarkup(fragment, markupStyleCreator, renderMode, orderMode, useUTC, toolTipTextStyle) {
      if (!fragment) {
        return;
      }

      var builder = getBuilder(fragment);
      var ctx = {
        useUTC: useUTC,
        renderMode: renderMode,
        orderMode: orderMode,
        markupStyleCreator: markupStyleCreator,
        valueFormatter: fragment.valueFormatter
      };
      return builder(ctx, fragment, 0, toolTipTextStyle);
    }

    function getGap(gapLevel) {
      return {
        html: HTML_GAPS[gapLevel],
        richText: RICH_TEXT_GAPS[gapLevel]
      };
    }

    function wrapBlockHTML(encodedContent, topGap) {
      var clearfix = '<div style="clear:both"></div>';
      var marginCSS = "margin: " + topGap + "px 0 0";
      return "<div style=\"" + marginCSS + ";" + TOOLTIP_LINE_HEIGHT_CSS + ";\">" + encodedContent + clearfix + '</div>';
    }

    function wrapInlineNameHTML(name, leftHasMarker, style) {
      var marginCss = leftHasMarker ? 'margin-left:2px' : '';
      return "<span style=\"" + style + ";" + marginCss + "\">" + encodeHTML(name) + '</span>';
    }

    function wrapInlineValueHTML(valueList, alignRight, valueCloseToMarker, style) {
      // Do not too close to marker, considering there are multiple values separated by spaces.
      var paddingStr = valueCloseToMarker ? '10px' : '20px';
      var alignCSS = alignRight ? "float:right;margin-left:" + paddingStr : '';
      valueList = isArray(valueList) ? valueList : [valueList];
      return "<span style=\"" + alignCSS + ";" + style + "\">" // Value has commas inside, so use '  ' as delimiter for multiple values.
      + map(valueList, function (value) {
        return encodeHTML(value);
      }).join('&nbsp;&nbsp;') + '</span>';
    }

    function wrapInlineNameRichText(ctx, name, style) {
      return ctx.markupStyleCreator.wrapRichTextStyle(name, style);
    }

    function wrapInlineValueRichText(ctx, values, alignRight, valueCloseToMarker, style) {
      var styles = [style];
      var paddingLeft = valueCloseToMarker ? 10 : 20;
      alignRight && styles.push({
        padding: [0, 0, 0, paddingLeft],
        align: 'right'
      }); // Value has commas inside, so use '  ' as delimiter for multiple values.

      return ctx.markupStyleCreator.wrapRichTextStyle(isArray(values) ? values.join('  ') : values, styles);
    }

    function retrieveVisualColorForTooltipMarker(series, dataIndex) {
      var style = series.getData().getItemVisual(dataIndex, 'style');
      var color = style[series.visualDrawType];
      return convertToColorString(color);
    }
    function getPaddingFromTooltipModel(model, renderMode) {
      var padding = model.get('padding');
      return padding != null ? padding // We give slightly different to look pretty.
      : renderMode === 'richText' ? [8, 10] : 10;
    }
    /**
     * The major feature is generate styles for `renderMode: 'richText'`.
     * But it also serves `renderMode: 'html'` to provide
     * "renderMode-independent" API.
     */

    var TooltipMarkupStyleCreator =
    /** @class */
    function () {
      function TooltipMarkupStyleCreator() {
        this.richTextStyles = {}; // Notice that "generate a style name" usuall happens repeatly when mouse moving and
        // displaying a tooltip. So we put the `_nextStyleNameId` as a member of each creator
        // rather than static shared by all creators (which will cause it increase to fast).

        this._nextStyleNameId = getRandomIdBase();
      }

      TooltipMarkupStyleCreator.prototype._generateStyleName = function () {
        return '__EC_aUTo_' + this._nextStyleNameId++;
      };

      TooltipMarkupStyleCreator.prototype.makeTooltipMarker = function (markerType, colorStr, renderMode) {
        var markerId = renderMode === 'richText' ? this._generateStyleName() : null;
        var marker = getTooltipMarker({
          color: colorStr,
          type: markerType,
          renderMode: renderMode,
          markerId: markerId
        });

        if (isString(marker)) {
          return marker;
        } else {
          if ("development" !== 'production') {
            assert(markerId);
          }

          this.richTextStyles[markerId] = marker.style;
          return marker.content;
        }
      };
      /**
       * @usage
       * ```ts
       * const styledText = markupStyleCreator.wrapRichTextStyle([
       *     // The styles will be auto merged.
       *     {
       *         fontSize: 12,
       *         color: 'blue'
       *     },
       *     {
       *         padding: 20
       *     }
       * ]);
       * ```
       */


      TooltipMarkupStyleCreator.prototype.wrapRichTextStyle = function (text, styles) {
        var finalStl = {};

        if (isArray(styles)) {
          each(styles, function (stl) {
            return extend(finalStl, stl);
          });
        } else {
          extend(finalStl, styles);
        }

        var styleName = this._generateStyleName();

        this.richTextStyles[styleName] = finalStl;
        return "{" + styleName + "|" + text + "}";
      };

      return TooltipMarkupStyleCreator;
    }();

    function defaultSeriesFormatTooltip(opt) {
      var series = opt.series;
      var dataIndex = opt.dataIndex;
      var multipleSeries = opt.multipleSeries;
      var data = series.getData();
      var tooltipDims = data.mapDimensionsAll('defaultedTooltip');
      var tooltipDimLen = tooltipDims.length;
      var value = series.getRawValue(dataIndex);
      var isValueArr = isArray(value);
      var markerColor = retrieveVisualColorForTooltipMarker(series, dataIndex); // Complicated rule for pretty tooltip.

      var inlineValue;
      var inlineValueType;
      var subBlocks;
      var sortParam;

      if (tooltipDimLen > 1 || isValueArr && !tooltipDimLen) {
        var formatArrResult = formatTooltipArrayValue(value, series, dataIndex, tooltipDims, markerColor);
        inlineValue = formatArrResult.inlineValues;
        inlineValueType = formatArrResult.inlineValueTypes;
        subBlocks = formatArrResult.blocks; // Only support tooltip sort by the first inline value. It's enough in most cases.

        sortParam = formatArrResult.inlineValues[0];
      } else if (tooltipDimLen) {
        var dimInfo = data.getDimensionInfo(tooltipDims[0]);
        sortParam = inlineValue = retrieveRawValue(data, dataIndex, tooltipDims[0]);
        inlineValueType = dimInfo.type;
      } else {
        sortParam = inlineValue = isValueArr ? value[0] : value;
      } // Do not show generated series name. It might not be readable.


      var seriesNameSpecified = isNameSpecified(series);
      var seriesName = seriesNameSpecified && series.name || '';
      var itemName = data.getName(dataIndex);
      var inlineName = multipleSeries ? seriesName : itemName;
      return createTooltipMarkup('section', {
        header: seriesName,
        // When series name not specified, do not show a header line with only '-'.
        // This case alway happen in tooltip.trigger: 'item'.
        noHeader: multipleSeries || !seriesNameSpecified,
        sortParam: sortParam,
        blocks: [createTooltipMarkup('nameValue', {
          markerType: 'item',
          markerColor: markerColor,
          // Do not mix display seriesName and itemName in one tooltip,
          // which might confuses users.
          name: inlineName,
          // name dimension might be auto assigned, where the name might
          // be not readable. So we check trim here.
          noName: !trim(inlineName),
          value: inlineValue,
          valueType: inlineValueType
        })].concat(subBlocks || [])
      });
    }

    function formatTooltipArrayValue(value, series, dataIndex, tooltipDims, colorStr) {
      // check: category-no-encode-has-axis-data in dataset.html
      var data = series.getData();
      var isValueMultipleLine = reduce(value, function (isValueMultipleLine, val, idx) {
        var dimItem = data.getDimensionInfo(idx);
        return isValueMultipleLine = isValueMultipleLine || dimItem && dimItem.tooltip !== false && dimItem.displayName != null;
      }, false);
      var inlineValues = [];
      var inlineValueTypes = [];
      var blocks = [];
      tooltipDims.length ? each(tooltipDims, function (dim) {
        setEachItem(retrieveRawValue(data, dataIndex, dim), dim);
      }) // By default, all dims is used on tooltip.
      : each(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;
        }

        if (isValueMultipleLine) {
          blocks.push(createTooltipMarkup('nameValue', {
            markerType: 'subItem',
            markerColor: colorStr,
            name: dimInfo.displayName,
            value: val,
            valueType: dimInfo.type
          }));
        } else {
          inlineValues.push(val);
          inlineValueTypes.push(dimInfo.type);
        }
      }

      return {
        inlineValues: inlineValues,
        inlineValueTypes: inlineValueTypes,
        blocks: blocks
      };
    }

    var inner$1 = makeInner();

    function getSelectionKey(data, dataIndex) {
      return data.getName(dataIndex) || data.getId(dataIndex);
    }

    var SERIES_UNIVERSAL_TRANSITION_PROP = '__universalTransitionEnabled';

    var SeriesModel =
    /** @class */
    function (_super) {
      __extends(SeriesModel, _super);

      function SeriesModel() {
        // [Caution]: Because this class or desecendants can be used as `XXX.extend(subProto)`,
        // the class members must not be initialized in constructor or declaration place.
        // Otherwise there is bad case:
        //   class A {xxx = 1;}
        //   enableClassExtend(A);
        //   class B extends A {}
        //   var C = B.extend({xxx: 5});
        //   var c = new C();
        //   console.log(c.xxx); // expect 5 but always 1.
        var _this = _super !== null && _super.apply(this, arguments) || this; // ---------------------------------------
        // Props about data selection
        // ---------------------------------------


        _this._selectedDataIndicesMap = {};
        return _this;
      }

      SeriesModel.prototype.init = function (option, parentModel, ecModel) {
        this.seriesIndex = this.componentIndex;
        this.dataTask = createTask({
          count: dataTaskCount,
          reset: dataTaskReset
        });
        this.dataTask.context = {
          model: this
        };
        this.mergeDefaultAndTheme(option, ecModel);
        var sourceManager = inner$1(this).sourceManager = new SourceManager(this);
        sourceManager.prepareSource();
        var data = this.getInitialData(option, ecModel);
        wrapData(data, this);
        this.dataTask.context.data = data;

        if ("development" !== 'production') {
          assert(data, 'getInitialData returned invalid data.');
        }

        inner$1(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/linkSeriesData
        // 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);

        this._initSelectedMapFromData(data);
      };
      /**
       * Util for merge default and theme to option
       */


      SeriesModel.prototype.mergeDefaultAndTheme = function (option, ecModel) {
        var layoutMode = fetchLayoutMode(this);
        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);
        }
      };

      SeriesModel.prototype.mergeOption = function (newSeriesOption, ecModel) {
        // this.settingTask.dirty();
        newSeriesOption = merge(this.option, newSeriesOption, true);
        this.fillDataTextStyle(newSeriesOption.data);
        var layoutMode = fetchLayoutMode(this);

        if (layoutMode) {
          mergeLayoutParam(this.option, newSeriesOption, layoutMode);
        }

        var sourceManager = inner$1(this).sourceManager;
        sourceManager.dirty();
        sourceManager.prepareSource();
        var data = this.getInitialData(newSeriesOption, ecModel);
        wrapData(data, this);
        this.dataTask.dirty();
        this.dataTask.context.data = data;
        inner$1(this).dataBeforeProcessed = data;
        autoSeriesName(this);

        this._initSelectedMapFromData(data);
      };

      SeriesModel.prototype.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 overridden.
       */


      SeriesModel.prototype.getInitialData = function (option, ecModel) {
        return;
      };
      /**
       * Append data to list
       */


      SeriesModel.prototype.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.
       */


      SeriesModel.prototype.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$1(this).data;
        }
      };

      SeriesModel.prototype.getAllData = function () {
        var mainData = this.getData();
        return mainData && mainData.getLinkedDataAll ? mainData.getLinkedDataAll() : [{
          data: mainData
        }];
      };

      SeriesModel.prototype.setData = function (data) {
        var task = getCurrentTask(this);

        if (task) {
          var context = task.context; // Consider case: filter, data sample.
          // FIXME:TS never used, so comment it
          // 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$1(this).data = data;
      };

      SeriesModel.prototype.getEncode = function () {
        var encode = this.get('encode', true);

        if (encode) {
          return createHashMap(encode);
        }
      };

      SeriesModel.prototype.getSourceManager = function () {
        return inner$1(this).sourceManager;
      };

      SeriesModel.prototype.getSource = function () {
        return this.getSourceManager().getSource();
      };
      /**
       * Get data before processed
       */


      SeriesModel.prototype.getRawData = function () {
        return inner$1(this).dataBeforeProcessed;
      };

      SeriesModel.prototype.getColorBy = function () {
        var colorBy = this.get('colorBy');
        return colorBy || 'series';
      };

      SeriesModel.prototype.isColorBySeries = function () {
        return this.getColorBy() === 'series';
      };
      /**
       * Get base axis if has coordinate system and has axis.
       * By default use coordSys.getBaseAxis();
       * Can be overridden for some chart.
       * @return {type} description
       */


      SeriesModel.prototype.getBaseAxis = function () {
        var coordSys = this.coordinateSystem; // @ts-ignore

        return coordSys && coordSys.getBaseAxis && coordSys.getBaseAxis();
      };
      /**
       * Default tooltip formatter
       *
       * @param dataIndex
       * @param multipleSeries
       * @param dataType
       * @param renderMode valid values: 'html'(by default) 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 formatted tooltip with `html` and `markers`
       *        Notice: The override method can also return string
       */


      SeriesModel.prototype.formatTooltip = function (dataIndex, multipleSeries, dataType) {
        return defaultSeriesFormatTooltip({
          series: this,
          dataIndex: dataIndex,
          multipleSeries: multipleSeries
        });
      };

      SeriesModel.prototype.isAnimationEnabled = function () {
        var ecModel = this.ecModel; // Disable animation if using echarts in node but not give ssr flag.
        // In ssr mode, renderToString will generate svg with css animation.

        if (env.node && !(ecModel && ecModel.ssr)) {
          return false;
        }

        var animationEnabled = this.getShallow('animation');

        if (animationEnabled) {
          if (this.getData().count() > this.getShallow('animationThreshold')) {
            animationEnabled = false;
          }
        }

        return !!animationEnabled;
      };

      SeriesModel.prototype.restoreData = function () {
        this.dataTask.dirty();
      };

      SeriesModel.prototype.getColorFromPalette = function (name, scope, requestColorNum) {
        var ecModel = this.ecModel; // PENDING

        var color = PaletteMixin.prototype.getColorFromPalette.call(this, name, scope, requestColorNum);

        if (!color) {
          color = ecModel.getColorFromPalette(name, scope, requestColorNum);
        }

        return color;
      };
      /**
       * Use `data.mapDimensionsAll(coordDim)` instead.
       * @deprecated
       */


      SeriesModel.prototype.coordDimToDataDim = function (coordDim) {
        return this.getRawData().mapDimensionsAll(coordDim);
      };
      /**
       * Get progressive rendering count each step
       */


      SeriesModel.prototype.getProgressive = function () {
        return this.get('progressive');
      };
      /**
       * Get progressive rendering count each step
       */


      SeriesModel.prototype.getProgressiveThreshold = function () {
        return this.get('progressiveThreshold');
      }; // PENGING If selectedMode is null ?


      SeriesModel.prototype.select = function (innerDataIndices, dataType) {
        this._innerSelect(this.getData(dataType), innerDataIndices);
      };

      SeriesModel.prototype.unselect = function (innerDataIndices, dataType) {
        var selectedMap = this.option.selectedMap;

        if (!selectedMap) {
          return;
        }

        var selectedMode = this.option.selectedMode;
        var data = this.getData(dataType);

        if (selectedMode === 'series' || selectedMap === 'all') {
          this.option.selectedMap = {};
          this._selectedDataIndicesMap = {};
          return;
        }

        for (var i = 0; i < innerDataIndices.length; i++) {
          var dataIndex = innerDataIndices[i];
          var nameOrId = getSelectionKey(data, dataIndex);
          selectedMap[nameOrId] = false;
          this._selectedDataIndicesMap[nameOrId] = -1;
        }
      };

      SeriesModel.prototype.toggleSelect = function (innerDataIndices, dataType) {
        var tmpArr = [];

        for (var i = 0; i < innerDataIndices.length; i++) {
          tmpArr[0] = innerDataIndices[i];
          this.isSelected(innerDataIndices[i], dataType) ? this.unselect(tmpArr, dataType) : this.select(tmpArr, dataType);
        }
      };

      SeriesModel.prototype.getSelectedDataIndices = function () {
        if (this.option.selectedMap === 'all') {
          return [].slice.call(this.getData().getIndices());
        }

        var selectedDataIndicesMap = this._selectedDataIndicesMap;
        var nameOrIds = keys(selectedDataIndicesMap);
        var dataIndices = [];

        for (var i = 0; i < nameOrIds.length; i++) {
          var dataIndex = selectedDataIndicesMap[nameOrIds[i]];

          if (dataIndex >= 0) {
            dataIndices.push(dataIndex);
          }
        }

        return dataIndices;
      };

      SeriesModel.prototype.isSelected = function (dataIndex, dataType) {
        var selectedMap = this.option.selectedMap;

        if (!selectedMap) {
          return false;
        }

        var data = this.getData(dataType);
        return (selectedMap === 'all' || selectedMap[getSelectionKey(data, dataIndex)]) && !data.getItemModel(dataIndex).get(['select', 'disabled']);
      };

      SeriesModel.prototype.isUniversalTransitionEnabled = function () {
        if (this[SERIES_UNIVERSAL_TRANSITION_PROP]) {
          return true;
        }

        var universalTransitionOpt = this.option.universalTransition; // Quick reject

        if (!universalTransitionOpt) {
          return false;
        }

        if (universalTransitionOpt === true) {
          return true;
        } // Can be simply 'universalTransition: true'


        return universalTransitionOpt && universalTransitionOpt.enabled;
      };

      SeriesModel.prototype._innerSelect = function (data, innerDataIndices) {
        var _a, _b;

        var option = this.option;
        var selectedMode = option.selectedMode;
        var len = innerDataIndices.length;

        if (!selectedMode || !len) {
          return;
        }

        if (selectedMode === 'series') {
          option.selectedMap = 'all';
        } else if (selectedMode === 'multiple') {
          if (!isObject(option.selectedMap)) {
            option.selectedMap = {};
          }

          var selectedMap = option.selectedMap;

          for (var i = 0; i < len; i++) {
            var dataIndex = innerDataIndices[i]; // TODO different types of data share same object.

            var nameOrId = getSelectionKey(data, dataIndex);
            selectedMap[nameOrId] = true;
            this._selectedDataIndicesMap[nameOrId] = data.getRawIndex(dataIndex);
          }
        } else if (selectedMode === 'single' || selectedMode === true) {
          var lastDataIndex = innerDataIndices[len - 1];
          var nameOrId = getSelectionKey(data, lastDataIndex);
          option.selectedMap = (_a = {}, _a[nameOrId] = true, _a);
          this._selectedDataIndicesMap = (_b = {}, _b[nameOrId] = data.getRawIndex(lastDataIndex), _b);
        }
      };

      SeriesModel.prototype._initSelectedMapFromData = function (data) {
        // Ignore select info in data if selectedMap exists.
        // NOTE It's only for legacy usage. edge data is not supported.
        if (this.option.selectedMap) {
          return;
        }

        var dataIndices = [];

        if (data.hasItemOption) {
          data.each(function (idx) {
            var rawItem = data.getRawDataItem(idx);

            if (rawItem && rawItem.selected) {
              dataIndices.push(idx);
            }
          });
        }

        if (dataIndices.length > 0) {
          this._innerSelect(data, dataIndices);
        }
      }; // /**
      //  * @see {module:echarts/stream/Scheduler}
      //  */
      // abstract pipeTask: null


      SeriesModel.registerClass = function (clz) {
        return ComponentModel.registerClass(clz);
      };

      SeriesModel.protoInitialize = function () {
        var proto = SeriesModel.prototype;
        proto.type = 'series.__base__';
        proto.seriesIndex = 0;
        proto.ignoreStyleOnData = false;
        proto.hasSymbolVisual = false;
        proto.defaultSymbol = 'circle'; // Make sure the values can be accessed!

        proto.visualStyleAccessPath = 'itemStyle';
        proto.visualDrawType = 'fill';
      }();

      return SeriesModel;
    }(ComponentModel);

    mixin(SeriesModel, DataFormatMixin);
    mixin(SeriesModel, PaletteMixin);
    mountExtend(SeriesModel, ComponentModel);
    /**
     * 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.mapDimensionsAll('seriesName');
      var nameArr = [];
      each(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(concatArray(data.CHANGABLE_METHODS, data.DOWNSAMPLE_METHODS), function (methodName) {
        data.wrapMethod(methodName, curry(onDataChange, seriesModel));
      });
    }

    function onDataChange(seriesModel, newList) {
      var task = getCurrentTask(seriesModel);

      if (task) {
        // Consider case: filter, selectRange
        task.setOutputEnd((newList || this).count());
      }

      return newList;
    }

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

    var ComponentView =
    /** @class */
    function () {
      function ComponentView() {
        this.group = new Group();
        this.uid = getUID('viewComponent');
      }

      ComponentView.prototype.init = function (ecModel, api) {};

      ComponentView.prototype.render = function (model, ecModel, api, payload) {};

      ComponentView.prototype.dispose = function (ecModel, api) {};

      ComponentView.prototype.updateView = function (model, ecModel, api, payload) {// Do nothing;
      };

      ComponentView.prototype.updateLayout = function (model, ecModel, api, payload) {// Do nothing;
      };

      ComponentView.prototype.updateVisual = function (model, ecModel, api, payload) {// Do nothing;
      };
      /**
       * Hook for toggle blur target series.
       * Can be used in marker for blur or leave blur the markers
       */


      ComponentView.prototype.toggleBlurSeries = function (seriesModels, isBlur, ecModel) {// Do nothing;
      };
      /**
       * Traverse the new rendered elements.
       *
       * It will traverse the new added element in progressive rendering.
       * And traverse all in normal rendering.
       */


      ComponentView.prototype.eachRendered = function (cb) {
        var group = this.group;

        if (group) {
          group.traverse(cb);
        }
      };

      return ComponentView;
    }();
    enableClassExtend(ComponentView);
    enableClassManagement(ComponentView);

    /**
     * @return {string} If large mode changed, return string 'reset';
     */

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

    var inner$2 = makeInner();
    var renderPlanner = createRenderPlanner();

    var ChartView =
    /** @class */
    function () {
      function ChartView() {
        this.group = new Group();
        this.uid = getUID('viewChart');
        this.renderTask = createTask({
          plan: renderTaskPlan,
          reset: renderTaskReset
        });
        this.renderTask.context = {
          view: this
        };
      }

      ChartView.prototype.init = function (ecModel, api) {};

      ChartView.prototype.render = function (seriesModel, ecModel, api, payload) {
        if ("development" !== 'production') {
          throw new Error('render method must been implemented');
        }
      };
      /**
       * Highlight series or specified data item.
       */


      ChartView.prototype.highlight = function (seriesModel, ecModel, api, payload) {
        var data = seriesModel.getData(payload && payload.dataType);

        if (!data) {
          if ("development" !== 'production') {
            error("Unknown dataType " + payload.dataType);
          }

          return;
        }

        toggleHighlight(data, payload, 'emphasis');
      };
      /**
       * Downplay series or specified data item.
       */


      ChartView.prototype.downplay = function (seriesModel, ecModel, api, payload) {
        var data = seriesModel.getData(payload && payload.dataType);

        if (!data) {
          if ("development" !== 'production') {
            error("Unknown dataType " + payload.dataType);
          }

          return;
        }

        toggleHighlight(data, payload, 'normal');
      };
      /**
       * Remove self.
       */


      ChartView.prototype.remove = function (ecModel, api) {
        this.group.removeAll();
      };
      /**
       * Dispose self.
       */


      ChartView.prototype.dispose = function (ecModel, api) {};

      ChartView.prototype.updateView = function (seriesModel, ecModel, api, payload) {
        this.render(seriesModel, ecModel, api, payload);
      }; // FIXME never used?


      ChartView.prototype.updateLayout = function (seriesModel, ecModel, api, payload) {
        this.render(seriesModel, ecModel, api, payload);
      }; // FIXME never used?


      ChartView.prototype.updateVisual = function (seriesModel, ecModel, api, payload) {
        this.render(seriesModel, ecModel, api, payload);
      };
      /**
       * Traverse the new rendered elements.
       *
       * It will traverse the new added element in progressive rendering.
       * And traverse all in normal rendering.
       */


      ChartView.prototype.eachRendered = function (cb) {
        traverseElements(this.group, cb);
      };

      ChartView.markUpdateMethod = function (payload, methodName) {
        inner$2(payload).updateMethod = methodName;
      };

      ChartView.protoInitialize = function () {
        var proto = ChartView.prototype;
        proto.type = 'chart';
      }();

      return ChartView;
    }();
    /**
     * Set state of single element
     */

    function elSetState(el, state, highlightDigit) {
      if (el && isHighDownDispatcher(el)) {
        (state === 'emphasis' ? enterEmphasis : leaveEmphasis)(el, highlightDigit);
      }
    }

    function toggleHighlight(data, payload, state) {
      var dataIndex = queryDataIndex(data, payload);
      var highlightDigit = payload && payload.highlightKey != null ? getHighlightDigit(payload.highlightKey) : null;

      if (dataIndex != null) {
        each(normalizeToArray(dataIndex), function (dataIdx) {
          elSetState(data.getItemGraphicEl(dataIdx), state, highlightDigit);
        });
      } else {
        data.eachItemGraphicEl(function (el) {
          elSetState(el, state, highlightDigit);
        });
      }
    }

    enableClassExtend(ChartView, ['dispose']);
    enableClassManagement(ChartView);

    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; // FIXME: remove updateView updateVisual

      var progressiveRender = seriesModel.pipelineContext.progressiveRender;
      var view = context.view;
      var updateMethod = payload && inner$2(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.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * 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 () {
        var cbArgs = [];

        for (var _i = 0; _i < arguments.length; _i++) {
          cbArgs[_i] = arguments[_i];
        }

        currCall = new Date().getTime();
        scope = this;
        args = cbArgs;
        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');
     * };
     *
     */

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

    function clear(obj, fnAttr) {
      var fn = obj[fnAttr];

      if (fn && fn[ORIGIN_METHOD]) {
        // Clear throttle
        fn.clear && fn.clear();
        obj[fnAttr] = fn[ORIGIN_METHOD];
      }
    }

    var inner$3 = makeInner();
    var defaultStyleMappers = {
      itemStyle: makeStyleMapper(ITEM_STYLE_KEY_MAP, true),
      lineStyle: makeStyleMapper(LINE_STYLE_KEY_MAP, true)
    };
    var defaultColorKey = {
      lineStyle: 'stroke',
      itemStyle: 'fill'
    };

    function getStyleMapper(seriesModel, stylePath) {
      var styleMapper = seriesModel.visualStyleMapper || defaultStyleMappers[stylePath];

      if (!styleMapper) {
        console.warn("Unknown style type '" + stylePath + "'.");
        return defaultStyleMappers.itemStyle;
      }

      return styleMapper;
    }

    function getDefaultColorKey(seriesModel, stylePath) {
      // return defaultColorKey[stylePath] ||
      var colorKey = seriesModel.visualDrawType || defaultColorKey[stylePath];

      if (!colorKey) {
        console.warn("Unknown style type '" + stylePath + "'.");
        return 'fill';
      }

      return colorKey;
    }

    var seriesStyleTask = {
      createOnAllSeries: true,
      performRawSeries: true,
      reset: function (seriesModel, ecModel) {
        var data = seriesModel.getData();
        var stylePath = seriesModel.visualStyleAccessPath || 'itemStyle'; // Set in itemStyle

        var styleModel = seriesModel.getModel(stylePath);
        var getStyle = getStyleMapper(seriesModel, stylePath);
        var globalStyle = getStyle(styleModel);
        var decalOption = styleModel.getShallow('decal');

        if (decalOption) {
          data.setVisual('decal', decalOption);
          decalOption.dirty = true;
        } // TODO


        var colorKey = getDefaultColorKey(seriesModel, stylePath);
        var color = globalStyle[colorKey]; // TODO style callback

        var colorCallback = isFunction(color) ? color : null;
        var hasAutoColor = globalStyle.fill === 'auto' || globalStyle.stroke === 'auto'; // Get from color palette by default.

        if (!globalStyle[colorKey] || colorCallback || hasAutoColor) {
          // Note: If some series has color specified (e.g., by itemStyle.color), we DO NOT
          // make it effect palette. Because some scenarios users need to make some series
          // transparent or as background, which should better not effect the palette.
          var colorPalette = seriesModel.getColorFromPalette( // TODO series count changed.
          seriesModel.name, null, ecModel.getSeriesCount());

          if (!globalStyle[colorKey]) {
            globalStyle[colorKey] = colorPalette;
            data.setVisual('colorFromPalette', true);
          }

          globalStyle.fill = globalStyle.fill === 'auto' || isFunction(globalStyle.fill) ? colorPalette : globalStyle.fill;
          globalStyle.stroke = globalStyle.stroke === 'auto' || isFunction(globalStyle.stroke) ? colorPalette : globalStyle.stroke;
        }

        data.setVisual('style', globalStyle);
        data.setVisual('drawType', colorKey); // Only visible series has each data be visual encoded

        if (!ecModel.isSeriesFiltered(seriesModel) && colorCallback) {
          data.setVisual('colorFromPalette', false);
          return {
            dataEach: function (data, idx) {
              var dataParams = seriesModel.getDataParams(idx);
              var itemStyle = extend({}, globalStyle);
              itemStyle[colorKey] = colorCallback(dataParams);
              data.setItemVisual(idx, 'style', itemStyle);
            }
          };
        }
      }
    };
    var sharedModel = new Model();
    var dataStyleTask = {
      createOnAllSeries: true,
      performRawSeries: true,
      reset: function (seriesModel, ecModel) {
        if (seriesModel.ignoreStyleOnData || ecModel.isSeriesFiltered(seriesModel)) {
          return;
        }

        var data = seriesModel.getData();
        var stylePath = seriesModel.visualStyleAccessPath || 'itemStyle'; // Set in itemStyle

        var getStyle = getStyleMapper(seriesModel, stylePath);
        var colorKey = data.getVisual('drawType');
        return {
          dataEach: data.hasItemOption ? function (data, idx) {
            // Not use getItemModel for performance considuration
            var rawItem = data.getRawDataItem(idx);

            if (rawItem && rawItem[stylePath]) {
              sharedModel.option = rawItem[stylePath];
              var style = getStyle(sharedModel);
              var existsStyle = data.ensureUniqueItemVisual(idx, 'style');
              extend(existsStyle, style);

              if (sharedModel.option.decal) {
                data.setItemVisual(idx, 'decal', sharedModel.option.decal);
                sharedModel.option.decal.dirty = true;
              }

              if (colorKey in style) {
                data.setItemVisual(idx, 'colorFromPalette', false);
              }
            }
          } : null
        };
      }
    }; // Pick color from palette for the data which has not been set with color yet.
    // Note: do not support stream rendering. No such cases yet.

    var dataColorPaletteTask = {
      performRawSeries: true,
      overallReset: function (ecModel) {
        // Each type of series uses one scope.
        // Pie and funnel are using different scopes.
        var paletteScopeGroupByType = createHashMap();
        ecModel.eachSeries(function (seriesModel) {
          var colorBy = seriesModel.getColorBy();

          if (seriesModel.isColorBySeries()) {
            return;
          }

          var key = seriesModel.type + '-' + colorBy;
          var colorScope = paletteScopeGroupByType.get(key);

          if (!colorScope) {
            colorScope = {};
            paletteScopeGroupByType.set(key, colorScope);
          }

          inner$3(seriesModel).scope = colorScope;
        });
        ecModel.eachSeries(function (seriesModel) {
          if (seriesModel.isColorBySeries() || ecModel.isSeriesFiltered(seriesModel)) {
            return;
          }

          var dataAll = seriesModel.getRawData();
          var idxMap = {};
          var data = seriesModel.getData();
          var colorScope = inner$3(seriesModel).scope;
          var stylePath = seriesModel.visualStyleAccessPath || 'itemStyle';
          var colorKey = getDefaultColorKey(seriesModel, stylePath);
          data.each(function (idx) {
            var rawIdx = data.getRawIndex(idx);
            idxMap[rawIdx] = idx;
          }); // Iterate on data before filtered. To make sure color from palette can be
          // Consistent when toggling legend.

          dataAll.each(function (rawIdx) {
            var idx = idxMap[rawIdx];
            var fromPalette = data.getItemVisual(idx, 'colorFromPalette'); // Get color from palette for each data only when the color is inherited from series color, which is
            // also picked from color palette. So following situation is not in the case:
            // 1. series.itemStyle.color is set
            // 2. color is encoded by visualMap

            if (fromPalette) {
              var itemStyle = data.ensureUniqueItemVisual(idx, 'style');
              var name_1 = dataAll.getName(rawIdx) || rawIdx + '';
              var dataCount = dataAll.count();
              itemStyle[colorKey] = seriesModel.getColorFromPalette(name_1, colorScope, dataCount);
            }
          });
        });
      }
    };

    var PI$3 = 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}
     */

    function defaultLoading(api, opts) {
      opts = opts || {};
      defaults(opts, {
        text: 'loading',
        textColor: '#000',
        fontSize: 12,
        fontWeight: 'normal',
        fontStyle: 'normal',
        fontFamily: 'sans-serif',
        maskColor: 'rgba(255, 255, 255, 0.8)',
        showSpinner: true,
        color: '#5470c6',
        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 textContent = new ZRText({
        style: {
          text: opts.text,
          fill: opts.textColor,
          fontSize: opts.fontSize,
          fontWeight: opts.fontWeight,
          fontStyle: opts.fontStyle,
          fontFamily: opts.fontFamily
        },
        zlevel: opts.zlevel,
        z: 10001
      });
      var labelRect = new Rect({
        style: {
          fill: 'none'
        },
        textContent: textContent,
        textConfig: {
          position: 'right',
          distance: 10
        },
        zlevel: opts.zlevel,
        z: 10001
      });
      group.add(labelRect);
      var arc;

      if (opts.showSpinner) {
        arc = new Arc({
          shape: {
            startAngle: -PI$3 / 2,
            endAngle: -PI$3 / 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$3 * 3 / 2
        }).start('circularInOut');
        arc.animateShape(true).when(1000, {
          startAngle: PI$3 * 3 / 2
        }).delay(300).start('circularInOut');
        group.add(arc);
      } // Inject resize


      group.resize = function () {
        var textWidth = textContent.getBoundingRect().width;
        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 - (opts.showSpinner && textWidth ? 0 : 5 + textWidth / 2) // only show the text
        + (opts.showSpinner ? 0 : textWidth / 2) // only show the spinner
        + (textWidth ? 0 : r);
        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;
    }

    var Scheduler =
    /** @class */
    function () {
      function Scheduler(ecInstance, api, dataProcessorHandlers, visualHandlers) {
        // key: handlerUID
        this._stageTaskMap = createHashMap();
        this.ecInstance = ecInstance;
        this.api = api; // 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.

        dataProcessorHandlers = this._dataProcessorHandlers = dataProcessorHandlers.slice();
        visualHandlers = this._visualHandlers = visualHandlers.slice();
        this._allHandlers = dataProcessorHandlers.concat(visualHandlers);
      }

      Scheduler.prototype.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.


      Scheduler.prototype.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
        };
      };

      Scheduler.prototype.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()`.
       */


      Scheduler.prototype.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
        };
      };

      Scheduler.prototype.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
          });

          scheduler._pipe(seriesModel, seriesModel.dataTask);
        });
      };

      Scheduler.prototype.prepareStageTasks = function () {
        var stageTaskMap = this._stageTaskMap;
        var ecModel = this.api.getModel();
        var api = this.api;
        each(this._allHandlers, function (handler) {
          var record = stageTaskMap.get(handler.uid) || stageTaskMap.set(handler.uid, {});
          var errMsg = '';

          if ("development" !== 'production') {
            // Currently do not need to support to sepecify them both.
            errMsg = '"reset" and "overallReset" must not be both specified.';
          }

          assert(!(handler.reset && handler.overallReset), errMsg);
          handler.reset && this._createSeriesStageTask(handler, record, ecModel, api);
          handler.overallReset && this._createOverallStageTask(handler, record, ecModel, api);
        }, this);
      };

      Scheduler.prototype.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;

        this._pipe(model, renderTask);
      };

      Scheduler.prototype.performDataProcessorTasks = function (ecModel, payload) {
        // If we do not use `block` here, it should be considered when to update modes.
        this._performStageTasks(this._dataProcessorHandlers, ecModel, payload, {
          block: true
        });
      };

      Scheduler.prototype.performVisualTasks = function (ecModel, payload, opt) {
        this._performStageTasks(this._visualHandlers, ecModel, payload, opt);
      };

      Scheduler.prototype._performStageTasks = function (stageHandlers, ecModel, payload, opt) {
        opt = opt || {};
        var unfinished = false;
        var scheduler = this;
        each(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_1;
            var agentStubMap = overallTask.agentStubMap;
            agentStubMap.each(function (stub) {
              if (needSetDirty(opt, stub)) {
                stub.dirty();
                overallNeedDirty_1 = true;
              }
            });
            overallNeedDirty_1 && overallTask.dirty();
            scheduler.updatePayload(overallTask, payload);
            var performArgs_1 = 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_1);
            });

            if (overallTask.perform(performArgs_1)) {
              unfinished = true;
            }
          } 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 declare `performRawSeries` in handlers, only
              // stream-independent (specifically, data item independent) operations can be
              // performed. Because if 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 operations
              // and stream-independent operations should better not be mixed.

              performArgs.skip = !stageHandler.performRawSeries && ecModel.isSeriesFiltered(task.context.model);
              scheduler.updatePayload(task, payload);

              if (task.perform(performArgs)) {
                unfinished = true;
              }
            });
          }
        });

        function needSetDirty(opt, task) {
          return opt.setDirty && (!opt.dirtyMap || opt.dirtyMap.get(task.__pipeline.id));
        }

        this.unfinished = unfinished || this.unfinished;
      };

      Scheduler.prototype.performSeriesTasks = function (ecModel) {
        var unfinished;
        ecModel.eachSeries(function (seriesModel) {
          // Progress to the end for dataInit and dataRestore.
          unfinished = seriesModel.dataTask.perform() || unfinished;
        });
        this.unfinished = unfinished || this.unfinished;
      };

      Scheduler.prototype.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);
        });
      };

      Scheduler.prototype.updatePayload = function (task, payload) {
        payload !== 'remain' && (task.context.payload = payload);
      };

      Scheduler.prototype._createSeriesStageTask = function (stageHandler, stageHandlerRecord, ecModel, api) {
        var scheduler = this;
        var oldSeriesTaskMap = stageHandlerRecord.seriesTaskMap; // The count of stages are totally about only several dozen, so
        // do not need to reuse the map.

        var newSeriesTaskMap = 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 = newSeriesTaskMap.set(pipelineId, oldSeriesTaskMap && oldSeriesTaskMap.get(pipelineId) || createTask({
            plan: seriesTaskPlan,
            reset: seriesTaskReset,
            count: seriesTaskCount
          }));
          task.context = {
            model: seriesModel,
            ecModel: ecModel,
            api: api,
            // PENDING: `useClearVisual` not used?
            useClearVisual: stageHandler.isVisual && !stageHandler.isLayout,
            plan: stageHandler.plan,
            reset: stageHandler.reset,
            scheduler: scheduler
          };

          scheduler._pipe(seriesModel, task);
        }
      };

      Scheduler.prototype._createOverallStageTask = function (stageHandler, stageHandlerRecord, ecModel, api) {
        var scheduler = this;
        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
        };
        var oldAgentStubMap = overallTask.agentStubMap; // The count of stages are totally about only several dozen, so
        // do not need to reuse the map.

        var newAgentStubMap = overallTask.agentStubMap = createHashMap();
        var seriesType = stageHandler.seriesType;
        var getTargetSeries = stageHandler.getTargetSeries;
        var overallProgress = true;
        var shouldOverallTaskDirty = false; // FIXME:TS never used, so comment it
        // let 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.

        var errMsg = '';

        if ("development" !== 'production') {
          errMsg = '"createOnAllSeries" is not supported for "overallReset", ' + 'because it will block all streams.';
        }

        assert(!stageHandler.createOnAllSeries, errMsg);

        if (seriesType) {
          ecModel.eachRawSeriesByType(seriesType, createStub);
        } else if (getTargetSeries) {
          getTargetSeries(ecModel, api).each(createStub);
        } // Otherwise, (usually it is legacy case), the overall task will only be
        // executed when upstream is dirty. Otherwise the progressive rendering of all
        // pipelines will be disabled unexpectedly. But it still needs stubs to receive
        // dirty info from upstream.
        else {
            overallProgress = false;
            each(ecModel.getSeries(), createStub);
          }

        function createStub(seriesModel) {
          var pipelineId = seriesModel.uid;
          var stub = newAgentStubMap.set(pipelineId, oldAgentStubMap && oldAgentStubMap.get(pipelineId) || ( // When the result of `getTargetSeries` changed, the overallTask
          // should be set as dirty and re-performed.
          shouldOverallTaskDirty = true, createTask({
            reset: stubReset,
            onDirty: stubOnDirty
          })));
          stub.context = {
            model: seriesModel,
            overallProgress: overallProgress // FIXME:TS never used, so comment it
            // modifyOutputEnd: modifyOutputEnd

          };
          stub.agent = overallTask;
          stub.__block = overallProgress;

          scheduler._pipe(seriesModel, stub);
        }

        if (shouldOverallTaskDirty) {
          overallTask.dirty();
        }
      };

      Scheduler.prototype._pipe = function (seriesModel, task) {
        var pipelineId = seriesModel.uid;

        var pipeline = this._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(stageHandler)) {
          stageHandler = {
            overallReset: stageHandler,
            seriesType: detectSeriseType(stageHandler)
          };
        }

        stageHandler.uid = getUID('stageHandler');
        visualType && (stageHandler.visualType = visualType);
        return stageHandler;
      };
      return Scheduler;
    }();

    function overallTaskReset(context) {
      context.overallReset(context.ecModel, context.api, context.payload);
    }

    function stubReset(context) {
      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) : null;
    }

    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();
    }
    /**
     * 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_1 in Clz.prototype) {
        // Do not use hasOwnProperty
        target[name_1] = 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.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

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


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * 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 = '#B9B8CE';
    var backgroundColor = '#100C2A';

    var axisCommon = function () {
      return {
        axisLine: {
          lineStyle: {
            color: contrastColor
          }
        },
        splitLine: {
          lineStyle: {
            color: '#484753'
          }
        },
        splitArea: {
          areaStyle: {
            color: ['rgba(255,255,255,0.02)', 'rgba(255,255,255,0.05)']
          }
        },
        minorSplitLine: {
          lineStyle: {
            color: '#20203B'
          }
        }
      };
    };

    var colorPalette = ['#4992ff', '#7cffb2', '#fddd60', '#ff6e76', '#58d9f9', '#05c091', '#ff8a45', '#8d48e3', '#dd79ff'];
    var theme = {
      darkMode: true,
      color: colorPalette,
      backgroundColor: backgroundColor,
      axisPointer: {
        lineStyle: {
          color: '#817f91'
        },
        crossStyle: {
          color: '#817f91'
        },
        label: {
          // TODO Contrast of label backgorundColor
          color: '#fff'
        }
      },
      legend: {
        textStyle: {
          color: contrastColor
        }
      },
      textStyle: {
        color: contrastColor
      },
      title: {
        textStyle: {
          color: '#EEF1FA'
        },
        subtextStyle: {
          color: '#B9B8CE'
        }
      },
      toolbox: {
        iconStyle: {
          borderColor: contrastColor
        }
      },
      dataZoom: {
        borderColor: '#71708A',
        textStyle: {
          color: contrastColor
        },
        brushStyle: {
          color: 'rgba(135,163,206,0.3)'
        },
        handleStyle: {
          color: '#353450',
          borderColor: '#C5CBE3'
        },
        moveHandleStyle: {
          color: '#B0B6C3',
          opacity: 0.3
        },
        fillerColor: 'rgba(135,163,206,0.2)',
        emphasis: {
          handleStyle: {
            borderColor: '#91B7F2',
            color: '#4D587D'
          },
          moveHandleStyle: {
            color: '#636D9A',
            opacity: 0.7
          }
        },
        dataBackground: {
          lineStyle: {
            color: '#71708A',
            width: 1
          },
          areaStyle: {
            color: '#71708A'
          }
        },
        selectedDataBackground: {
          lineStyle: {
            color: '#87A3CE'
          },
          areaStyle: {
            color: '#87A3CE'
          }
        }
      },
      visualMap: {
        textStyle: {
          color: contrastColor
        }
      },
      timeline: {
        lineStyle: {
          color: contrastColor
        },
        label: {
          color: contrastColor
        },
        controlStyle: {
          color: contrastColor,
          borderColor: contrastColor
        }
      },
      calendar: {
        itemStyle: {
          color: backgroundColor
        },
        dayLabel: {
          color: contrastColor
        },
        monthLabel: {
          color: contrastColor
        },
        yearLabel: {
          color: contrastColor
        }
      },
      timeAxis: axisCommon(),
      logAxis: axisCommon(),
      valueAxis: axisCommon(),
      categoryAxis: axisCommon(),
      line: {
        symbol: 'circle'
      },
      graph: {
        color: colorPalette
      },
      gauge: {
        title: {
          color: contrastColor
        },
        axisLine: {
          lineStyle: {
            color: [[1, 'rgba(207,212,219,0.2)']]
          }
        },
        axisLabel: {
          color: contrastColor
        },
        detail: {
          color: '#EEF1FA'
        }
      },
      candlestick: {
        itemStyle: {
          color: '#f64e56',
          color0: '#54ea92',
          borderColor: '#f64e56',
          borderColor0: '#54ea92' // borderColor: '#ca2824',
          // borderColor0: '#09a443'

        }
      }
    };
    theme.categoryAxis.splitLine.show = false;

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

    var ECEventProcessor =
    /** @class */
    function () {
      function ECEventProcessor() {}

      ECEventProcessor.prototype.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_1 = ['Index', 'Name', 'Id'];
            var dataKeys_1 = {
              name: 1,
              dataIndex: 1,
              dataType: 1
            };
            each(query, function (val, key) {
              var reserved = false;

              for (var i = 0; i < suffixes_1.length; i++) {
                var propSuffix = suffixes_1[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_1.hasOwnProperty(key)) {
                dataQuery[key] = val;
                reserved = true;
              }

              if (!reserved) {
                otherQuery[key] = val;
              }
            });
          }

        return {
          cptQuery: cptQuery,
          dataQuery: dataQuery,
          otherQuery: otherQuery
        };
      };

      ECEventProcessor.prototype.filter = function (eventType, query) {
        // 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];
        }
      };

      ECEventProcessor.prototype.afterTrigger = function () {
        // Make sure the eventInfo won't be used in next trigger.
        this.eventInfo = null;
      };

      return ECEventProcessor;
    }();

    var SYMBOL_PROPS_WITH_CB = ['symbol', 'symbolSize', 'symbolRotate', 'symbolOffset'];
    var SYMBOL_PROPS = SYMBOL_PROPS_WITH_CB.concat(['symbolKeepAspect']); // Encoding visual for all series include which is filtered for legend drawing

    var seriesSymbolTask = {
      createOnAllSeries: true,
      // For legend.
      performRawSeries: true,
      reset: function (seriesModel, ecModel) {
        var data = seriesModel.getData();

        if (seriesModel.legendIcon) {
          data.setVisual('legendIcon', seriesModel.legendIcon);
        }

        if (!seriesModel.hasSymbolVisual) {
          return;
        }

        var symbolOptions = {};
        var symbolOptionsCb = {};
        var hasCallback = false;

        for (var i = 0; i < SYMBOL_PROPS_WITH_CB.length; i++) {
          var symbolPropName = SYMBOL_PROPS_WITH_CB[i];
          var val = seriesModel.get(symbolPropName);

          if (isFunction(val)) {
            hasCallback = true;
            symbolOptionsCb[symbolPropName] = val;
          } else {
            symbolOptions[symbolPropName] = val;
          }
        }

        symbolOptions.symbol = symbolOptions.symbol || seriesModel.defaultSymbol;
        data.setVisual(extend({
          legendIcon: seriesModel.legendIcon || symbolOptions.symbol,
          symbolKeepAspect: seriesModel.get('symbolKeepAspect')
        }, symbolOptions)); // Only visible series has each data be visual encoded

        if (ecModel.isSeriesFiltered(seriesModel)) {
          return;
        }

        var symbolPropsCb = keys(symbolOptionsCb);

        function dataEach(data, idx) {
          var rawValue = seriesModel.getRawValue(idx);
          var params = seriesModel.getDataParams(idx);

          for (var i = 0; i < symbolPropsCb.length; i++) {
            var symbolPropName = symbolPropsCb[i];
            data.setItemVisual(idx, symbolPropName, symbolOptionsCb[symbolPropName](rawValue, params));
          }
        }

        return {
          dataEach: hasCallback ? dataEach : null
        };
      }
    };
    var dataSymbolTask = {
      createOnAllSeries: true,
      // For legend.
      performRawSeries: true,
      reset: function (seriesModel, ecModel) {
        if (!seriesModel.hasSymbolVisual) {
          return;
        } // Only visible series has each data be visual encoded


        if (ecModel.isSeriesFiltered(seriesModel)) {
          return;
        }

        var data = seriesModel.getData();

        function dataEach(data, idx) {
          var itemModel = data.getItemModel(idx);

          for (var i = 0; i < SYMBOL_PROPS.length; i++) {
            var symbolPropName = SYMBOL_PROPS[i];
            var val = itemModel.getShallow(symbolPropName, true);

            if (val != null) {
              data.setItemVisual(idx, symbolPropName, val);
            }
          }
        }

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


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * 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 getItemVisualFromData(data, dataIndex, key) {
      switch (key) {
        case 'color':
          var style = data.getItemVisual(dataIndex, 'style');
          return style[data.getVisual('drawType')];

        case 'opacity':
          return data.getItemVisual(dataIndex, 'style').opacity;

        case 'symbol':
        case 'symbolSize':
        case 'liftZ':
          return data.getItemVisual(dataIndex, key);

        default:
          if ("development" !== 'production') {
            console.warn("Unknown visual type " + key);
          }

      }
    }
    function getVisualFromData(data, key) {
      switch (key) {
        case 'color':
          var style = data.getVisual('style');
          return style[data.getVisual('drawType')];

        case 'opacity':
          return data.getVisual('style').opacity;

        case 'symbol':
        case 'symbolSize':
        case 'liftZ':
          return data.getVisual(key);

        default:
          if ("development" !== 'production') {
            console.warn("Unknown visual type " + key);
          }

      }
    }
    function setItemVisualFromData(data, dataIndex, key, value) {
      switch (key) {
        case 'color':
          // Make sure not sharing style object.
          var style = data.ensureUniqueItemVisual(dataIndex, 'style');
          style[data.getVisual('drawType')] = value; // Mark the color has been changed, not from palette anymore

          data.setItemVisual(dataIndex, 'colorFromPalette', false);
          break;

        case 'opacity':
          data.ensureUniqueItemVisual(dataIndex, 'style').opacity = value;
          break;

        case 'symbol':
        case 'symbolSize':
        case 'liftZ':
          data.setItemVisual(dataIndex, key, value);
          break;

        default:
          if ("development" !== 'production') {
            console.warn("Unknown visual type " + key);
          }

      }
    }

    // Inlucdes: pieSelect, pieUnSelect, pieToggleSelect, mapSelect, mapUnSelect, mapToggleSelect

    function createLegacyDataSelectAction(seriesType, ecRegisterAction) {
      function getSeriesIndices(ecModel, payload) {
        var seriesIndices = [];
        ecModel.eachComponent({
          mainType: 'series',
          subType: seriesType,
          query: payload
        }, function (seriesModel) {
          seriesIndices.push(seriesModel.seriesIndex);
        });
        return seriesIndices;
      }

      each([[seriesType + 'ToggleSelect', 'toggleSelect'], [seriesType + 'Select', 'select'], [seriesType + 'UnSelect', 'unselect']], function (eventsMap) {
        ecRegisterAction(eventsMap[0], function (payload, ecModel, api) {
          payload = extend({}, payload);

          if ("development" !== 'production') {
            deprecateReplaceLog(payload.type, eventsMap[1]);
          }

          api.dispatchAction(extend(payload, {
            type: eventsMap[1],
            seriesIndex: getSeriesIndices(ecModel, payload)
          }));
        });
      });
    }

    function handleSeriesLegacySelectEvents(type, eventPostfix, ecIns, ecModel, payload) {
      var legacyEventName = type + eventPostfix;

      if (!ecIns.isSilent(legacyEventName)) {
        if ("development" !== 'production') {
          deprecateLog("event " + legacyEventName + " is deprecated.");
        }

        ecModel.eachComponent({
          mainType: 'series',
          subType: 'pie'
        }, function (seriesModel) {
          var seriesIndex = seriesModel.seriesIndex;
          var selectedMap = seriesModel.option.selectedMap;
          var selected = payload.selected;

          for (var i = 0; i < selected.length; i++) {
            if (selected[i].seriesIndex === seriesIndex) {
              var data = seriesModel.getData();
              var dataIndex = queryDataIndex(data, payload.fromActionPayload);
              ecIns.trigger(legacyEventName, {
                type: legacyEventName,
                seriesId: seriesModel.id,
                name: isArray(dataIndex) ? data.getName(dataIndex[0]) : data.getName(dataIndex),
                selected: isString(selectedMap) ? selectedMap : extend({}, selectedMap)
              });
            }
          }
        });
      }
    }

    function handleLegacySelectEvents(messageCenter, ecIns, api) {
      messageCenter.on('selectchanged', function (params) {
        var ecModel = api.getModel();

        if (params.isFromClick) {
          handleSeriesLegacySelectEvents('map', 'selectchanged', ecIns, ecModel, params);
          handleSeriesLegacySelectEvents('pie', 'selectchanged', ecIns, ecModel, params);
        } else if (params.fromAction === 'select') {
          handleSeriesLegacySelectEvents('map', 'selected', ecIns, ecModel, params);
          handleSeriesLegacySelectEvents('pie', 'selected', ecIns, ecModel, params);
        } else if (params.fromAction === 'unselect') {
          handleSeriesLegacySelectEvents('map', 'unselected', ecIns, ecModel, params);
          handleSeriesLegacySelectEvents('pie', 'unselected', ecIns, ecModel, params);
        }
      });
    }

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


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * 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 findEventDispatcher(target, det, returnFirstMatch) {
      var found;

      while (target) {
        if (det(target)) {
          found = target;

          if (returnFirstMatch) {
            break;
          }
        }

        target = target.__hostTarget || target.parent;
      }

      return found;
    }

    var wmUniqueIndex = Math.round(Math.random() * 9);
    var supportDefineProperty = typeof Object.defineProperty === 'function';
    var WeakMap = (function () {
        function WeakMap() {
            this._id = '__ec_inner_' + wmUniqueIndex++;
        }
        WeakMap.prototype.get = function (key) {
            return this._guard(key)[this._id];
        };
        WeakMap.prototype.set = function (key, value) {
            var target = this._guard(key);
            if (supportDefineProperty) {
                Object.defineProperty(target, this._id, {
                    value: value,
                    enumerable: false,
                    configurable: true
                });
            }
            else {
                target[this._id] = value;
            }
            return this;
        };
        WeakMap.prototype["delete"] = function (key) {
            if (this.has(key)) {
                delete this._guard(key)[this._id];
                return true;
            }
            return false;
        };
        WeakMap.prototype.has = function (key) {
            return !!this._guard(key)[this._id];
        };
        WeakMap.prototype._guard = function (key) {
            if (key !== Object(key)) {
                throw TypeError('Value of WeakMap is not a non-null object.');
            }
            return key;
        };
        return WeakMap;
    }());

    /**
     * Triangle shape
     * @inner
     */

    var Triangle = Path.extend({
      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 = Path.extend({
      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 = Path.extend({
      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 = Path.extend({
      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 constructors
     */
    // TODO Use function to build symbol 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) {
        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(symbolCtors, function (Ctor, name) {
      symbolBuildProxies[name] = new Ctor();
    });
    var SymbolClz = Path.extend({
      type: 'symbol',
      shape: {
        symbolType: '',
        x: 0,
        y: 0,
        width: 0,
        height: 0
      },
      calculateTextPosition: function (out, config, rect) {
        var res = calculateTextPosition(out, config, rect);
        var shape = this.shape;

        if (shape && shape.symbolType === 'pin' && config.position === '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;

        if (this.__isEmptyBrush) {
          symbolStyle.stroke = color;
          symbolStyle.fill = innerColor || '#fff'; // TODO Same width with lineStyle in LineView

          symbolStyle.lineWidth = 2;
        } else if (this.shape.symbolType === 'line') {
          symbolStyle.stroke = color;
        } else {
          symbolStyle.fill = color;
        }

        this.markRedraw();
      }
    }
    /**
     * Create a symbol element with given symbol configuration: shape, x, y, width, height, color
     */


    function createSymbol(symbolType, x, y, w, h, color, // whether to keep the ratio of w/h,
    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; // TODO Should deprecate setColor

      symbolPath.setColor = symbolPathSetColor;

      if (color) {
        symbolPath.setColor(color);
      }

      return symbolPath;
    }
    function normalizeSymbolSize(symbolSize) {
      if (!isArray(symbolSize)) {
        symbolSize = [+symbolSize, +symbolSize];
      }

      return [symbolSize[0] || 0, symbolSize[1] || 0];
    }
    function normalizeSymbolOffset(symbolOffset, symbolSize) {
      if (symbolOffset == null) {
        return;
      }

      if (!isArray(symbolOffset)) {
        symbolOffset = [symbolOffset, symbolOffset];
      }

      return [parsePercent$1(symbolOffset[0], symbolSize[0]) || 0, parsePercent$1(retrieve2(symbolOffset[1], symbolOffset[0]), symbolSize[1]) || 0];
    }

    function isSafeNum(num) {
        return isFinite(num);
    }
    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;
        }
        x = isSafeNum(x) ? x : 0;
        x2 = isSafeNum(x2) ? x2 : 1;
        y = isSafeNum(y) ? y : 0;
        y2 = isSafeNum(y2) ? y2 : 0;
        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;
        }
        x = isSafeNum(x) ? x : 0.5;
        y = isSafeNum(y) ? y : 0.5;
        r = r >= 0 && isSafeNum(r) ? r : 0.5;
        var canvasGradient = ctx.createRadialGradient(x, y, 0, x, y, r);
        return canvasGradient;
    }
    function getCanvasGradient(ctx, obj, rect) {
        var canvasGradient = obj.type === 'radial'
            ? createRadialGradient(ctx, obj, rect)
            : createLinearGradient(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;
    }
    function isClipPathChanged(clipPaths, prevClipPaths) {
        if (clipPaths === prevClipPaths || (!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 parseInt10(val) {
        return parseInt(val, 10);
    }
    function getSize(root, whIdx, 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 stl = document.defaultView.getComputedStyle(root);
        return ((root[cwh] || parseInt10(stl[wh]) || parseInt10(root.style[wh]))
            - (parseInt10(stl[plt]) || 0)
            - (parseInt10(stl[prb]) || 0)) | 0;
    }

    function normalizeLineDash(lineType, lineWidth) {
        if (!lineType || lineType === 'solid' || !(lineWidth > 0)) {
            return null;
        }
        return lineType === 'dashed'
            ? [4 * lineWidth, 2 * lineWidth]
            : lineType === 'dotted'
                ? [lineWidth]
                : isNumber(lineType)
                    ? [lineType] : isArray(lineType) ? lineType : null;
    }
    function getLineDash(el) {
        var style = el.style;
        var lineDash = style.lineDash && style.lineWidth > 0 && normalizeLineDash(style.lineDash, style.lineWidth);
        var lineDashOffset = style.lineDashOffset;
        if (lineDash) {
            var lineScale_1 = (style.strokeNoScale && el.getLineScale) ? el.getLineScale() : 1;
            if (lineScale_1 && lineScale_1 !== 1) {
                lineDash = map(lineDash, function (rawVal) {
                    return rawVal / lineScale_1;
                });
                lineDashOffset /= lineScale_1;
            }
        }
        return [lineDash, lineDashOffset];
    }

    var pathProxyForDraw = new PathProxy(true);
    function styleHasStroke(style) {
        var stroke = style.stroke;
        return !(stroke == null || stroke === 'none' || !(style.lineWidth > 0));
    }
    function isValidStrokeFillStyle(strokeOrFill) {
        return typeof strokeOrFill === 'string' && strokeOrFill !== 'none';
    }
    function styleHasFill(style) {
        var fill = style.fill;
        return fill != null && fill !== 'none';
    }
    function doFillPath(ctx, style) {
        if (style.fillOpacity != null && style.fillOpacity !== 1) {
            var originalGlobalAlpha = ctx.globalAlpha;
            ctx.globalAlpha = style.fillOpacity * style.opacity;
            ctx.fill();
            ctx.globalAlpha = originalGlobalAlpha;
        }
        else {
            ctx.fill();
        }
    }
    function doStrokePath(ctx, style) {
        if (style.strokeOpacity != null && style.strokeOpacity !== 1) {
            var originalGlobalAlpha = ctx.globalAlpha;
            ctx.globalAlpha = style.strokeOpacity * style.opacity;
            ctx.stroke();
            ctx.globalAlpha = originalGlobalAlpha;
        }
        else {
            ctx.stroke();
        }
    }
    function createCanvasPattern(ctx, pattern, el) {
        var image = createOrUpdateImage(pattern.image, pattern.__image, el);
        if (isImageReady(image)) {
            var canvasPattern = ctx.createPattern(image, pattern.repeat || 'repeat');
            if (typeof DOMMatrix === 'function'
                && canvasPattern
                && canvasPattern.setTransform) {
                var matrix = new DOMMatrix();
                matrix.translateSelf((pattern.x || 0), (pattern.y || 0));
                matrix.rotateSelf(0, 0, (pattern.rotation || 0) * RADIAN_TO_DEGREE);
                matrix.scaleSelf((pattern.scaleX || 1), (pattern.scaleY || 1));
                canvasPattern.setTransform(matrix);
            }
            return canvasPattern;
        }
    }
    function brushPath(ctx, el, style, inBatch) {
        var _a;
        var hasStroke = styleHasStroke(style);
        var hasFill = styleHasFill(style);
        var strokePercent = style.strokePercent;
        var strokePart = strokePercent < 1;
        var firstDraw = !el.path;
        if ((!el.silent || strokePart) && firstDraw) {
            el.createPathProxy();
        }
        var path = el.path || pathProxyForDraw;
        var dirtyFlag = el.__dirty;
        if (!inBatch) {
            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;
            var fillGradient = void 0;
            var strokeGradient = void 0;
            var fillPattern = void 0;
            var strokePattern = void 0;
            var rect = void 0;
            if (hasFillGradient || hasStrokeGradient) {
                rect = el.getBoundingRect();
            }
            if (hasFillGradient) {
                fillGradient = dirtyFlag
                    ? getCanvasGradient(ctx, fill, rect)
                    : el.__canvasFillGradient;
                el.__canvasFillGradient = fillGradient;
            }
            if (hasStrokeGradient) {
                strokeGradient = dirtyFlag
                    ? getCanvasGradient(ctx, stroke, rect)
                    : el.__canvasStrokeGradient;
                el.__canvasStrokeGradient = strokeGradient;
            }
            if (hasFillPattern) {
                fillPattern = (dirtyFlag || !el.__canvasFillPattern)
                    ? createCanvasPattern(ctx, fill, el)
                    : el.__canvasFillPattern;
                el.__canvasFillPattern = fillPattern;
            }
            if (hasStrokePattern) {
                strokePattern = (dirtyFlag || !el.__canvasStrokePattern)
                    ? createCanvasPattern(ctx, stroke, el)
                    : el.__canvasStrokePattern;
                el.__canvasStrokePattern = fillPattern;
            }
            if (hasFillGradient) {
                ctx.fillStyle = fillGradient;
            }
            else if (hasFillPattern) {
                if (fillPattern) {
                    ctx.fillStyle = fillPattern;
                }
                else {
                    hasFill = false;
                }
            }
            if (hasStrokeGradient) {
                ctx.strokeStyle = strokeGradient;
            }
            else if (hasStrokePattern) {
                if (strokePattern) {
                    ctx.strokeStyle = strokePattern;
                }
                else {
                    hasStroke = false;
                }
            }
        }
        var scale = el.getGlobalScale();
        path.setScale(scale[0], scale[1], el.segmentIgnoreThreshold);
        var lineDash;
        var lineDashOffset;
        if (ctx.setLineDash && style.lineDash) {
            _a = getLineDash(el), lineDash = _a[0], lineDashOffset = _a[1];
        }
        var needsRebuild = true;
        if (firstDraw || (dirtyFlag & SHAPE_CHANGED_BIT)) {
            path.setDPR(ctx.dpr);
            if (strokePart) {
                path.setContext(null);
            }
            else {
                path.setContext(ctx);
                needsRebuild = false;
            }
            path.reset();
            el.buildPath(path, el.shape, inBatch);
            path.toStatic();
            el.pathUpdated();
        }
        if (needsRebuild) {
            path.rebuildPath(ctx, strokePart ? strokePercent : 1);
        }
        if (lineDash) {
            ctx.setLineDash(lineDash);
            ctx.lineDashOffset = lineDashOffset;
        }
        if (!inBatch) {
            if (style.strokeFirst) {
                if (hasStroke) {
                    doStrokePath(ctx, style);
                }
                if (hasFill) {
                    doFillPath(ctx, style);
                }
            }
            else {
                if (hasFill) {
                    doFillPath(ctx, style);
                }
                if (hasStroke) {
                    doStrokePath(ctx, style);
                }
            }
        }
        if (lineDash) {
            ctx.setLineDash([]);
        }
    }
    function brushImage(ctx, el, style) {
        var image = el.__image = createOrUpdateImage(style.image, el.__image, el, el.onload);
        if (!image || !isImageReady(image)) {
            return;
        }
        var x = style.x || 0;
        var y = style.y || 0;
        var width = el.getWidth();
        var height = el.getHeight();
        var aspect = image.width / image.height;
        if (width == null && height != null) {
            width = height * aspect;
        }
        else if (height == null && width != null) {
            height = width / aspect;
        }
        else if (width == null && height == null) {
            width = image.width;
            height = image.height;
        }
        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);
        }
    }
    function brushText(ctx, el, style) {
        var _a;
        var text = style.text;
        text != null && (text += '');
        if (text) {
            ctx.font = style.font || DEFAULT_FONT;
            ctx.textAlign = style.textAlign;
            ctx.textBaseline = style.textBaseline;
            var lineDash = void 0;
            var lineDashOffset = void 0;
            if (ctx.setLineDash && style.lineDash) {
                _a = getLineDash(el), lineDash = _a[0], lineDashOffset = _a[1];
            }
            if (lineDash) {
                ctx.setLineDash(lineDash);
                ctx.lineDashOffset = lineDashOffset;
            }
            if (style.strokeFirst) {
                if (styleHasStroke(style)) {
                    ctx.strokeText(text, style.x, style.y);
                }
                if (styleHasFill(style)) {
                    ctx.fillText(text, style.x, style.y);
                }
            }
            else {
                if (styleHasFill(style)) {
                    ctx.fillText(text, style.x, style.y);
                }
                if (styleHasStroke(style)) {
                    ctx.strokeText(text, style.x, style.y);
                }
            }
            if (lineDash) {
                ctx.setLineDash([]);
            }
        }
    }
    var SHADOW_NUMBER_PROPS = ['shadowBlur', 'shadowOffsetX', 'shadowOffsetY'];
    var STROKE_PROPS = [
        ['lineCap', 'butt'], ['lineJoin', 'miter'], ['miterLimit', 10]
    ];
    function bindCommonProps(ctx, style, prevStyle, forceSetAll, scope) {
        var styleChanged = false;
        if (!forceSetAll) {
            prevStyle = prevStyle || {};
            if (style === prevStyle) {
                return false;
            }
        }
        if (forceSetAll || style.opacity !== prevStyle.opacity) {
            flushPathDrawn(ctx, scope);
            styleChanged = true;
            var opacity = Math.max(Math.min(style.opacity, 1), 0);
            ctx.globalAlpha = isNaN(opacity) ? DEFAULT_COMMON_STYLE.opacity : opacity;
        }
        if (forceSetAll || style.blend !== prevStyle.blend) {
            if (!styleChanged) {
                flushPathDrawn(ctx, scope);
                styleChanged = true;
            }
            ctx.globalCompositeOperation = style.blend || DEFAULT_COMMON_STYLE.blend;
        }
        for (var i = 0; i < SHADOW_NUMBER_PROPS.length; i++) {
            var propName = SHADOW_NUMBER_PROPS[i];
            if (forceSetAll || style[propName] !== prevStyle[propName]) {
                if (!styleChanged) {
                    flushPathDrawn(ctx, scope);
                    styleChanged = true;
                }
                ctx[propName] = ctx.dpr * (style[propName] || 0);
            }
        }
        if (forceSetAll || style.shadowColor !== prevStyle.shadowColor) {
            if (!styleChanged) {
                flushPathDrawn(ctx, scope);
                styleChanged = true;
            }
            ctx.shadowColor = style.shadowColor || DEFAULT_COMMON_STYLE.shadowColor;
        }
        return styleChanged;
    }
    function bindPathAndTextCommonStyle(ctx, el, prevEl, forceSetAll, scope) {
        var style = getStyle(el, scope.inHover);
        var prevStyle = forceSetAll
            ? null
            : (prevEl && getStyle(prevEl, scope.inHover) || {});
        if (style === prevStyle) {
            return false;
        }
        var styleChanged = bindCommonProps(ctx, style, prevStyle, forceSetAll, scope);
        if (forceSetAll || style.fill !== prevStyle.fill) {
            if (!styleChanged) {
                flushPathDrawn(ctx, scope);
                styleChanged = true;
            }
            isValidStrokeFillStyle(style.fill) && (ctx.fillStyle = style.fill);
        }
        if (forceSetAll || style.stroke !== prevStyle.stroke) {
            if (!styleChanged) {
                flushPathDrawn(ctx, scope);
                styleChanged = true;
            }
            isValidStrokeFillStyle(style.stroke) && (ctx.strokeStyle = style.stroke);
        }
        if (forceSetAll || style.opacity !== prevStyle.opacity) {
            if (!styleChanged) {
                flushPathDrawn(ctx, scope);
                styleChanged = true;
            }
            ctx.globalAlpha = style.opacity == null ? 1 : style.opacity;
        }
        if (el.hasStroke()) {
            var lineWidth = style.lineWidth;
            var newLineWidth = lineWidth / ((style.strokeNoScale && el.getLineScale) ? el.getLineScale() : 1);
            if (ctx.lineWidth !== newLineWidth) {
                if (!styleChanged) {
                    flushPathDrawn(ctx, scope);
                    styleChanged = true;
                }
                ctx.lineWidth = newLineWidth;
            }
        }
        for (var i = 0; i < STROKE_PROPS.length; i++) {
            var prop = STROKE_PROPS[i];
            var propName = prop[0];
            if (forceSetAll || style[propName] !== prevStyle[propName]) {
                if (!styleChanged) {
                    flushPathDrawn(ctx, scope);
                    styleChanged = true;
                }
                ctx[propName] = style[propName] || prop[1];
            }
        }
        return styleChanged;
    }
    function bindImageStyle(ctx, el, prevEl, forceSetAll, scope) {
        return bindCommonProps(ctx, getStyle(el, scope.inHover), prevEl && getStyle(prevEl, scope.inHover), forceSetAll, scope);
    }
    function setContextTransform(ctx, el) {
        var m = el.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);
        }
    }
    function updateClipStatus(clipPaths, ctx, scope) {
        var allClipped = false;
        for (var i = 0; i < clipPaths.length; i++) {
            var clipPath = clipPaths[i];
            allClipped = allClipped || clipPath.isZeroArea();
            setContextTransform(ctx, clipPath);
            ctx.beginPath();
            clipPath.buildPath(ctx, clipPath.shape);
            ctx.clip();
        }
        scope.allClipped = allClipped;
    }
    function isTransformChanged(m0, m1) {
        if (m0 && m1) {
            return m0[0] !== m1[0]
                || m0[1] !== m1[1]
                || m0[2] !== m1[2]
                || m0[3] !== m1[3]
                || m0[4] !== m1[4]
                || m0[5] !== m1[5];
        }
        else if (!m0 && !m1) {
            return false;
        }
        return true;
    }
    var DRAW_TYPE_PATH = 1;
    var DRAW_TYPE_IMAGE = 2;
    var DRAW_TYPE_TEXT = 3;
    var DRAW_TYPE_INCREMENTAL = 4;
    function canPathBatch(style) {
        var hasFill = styleHasFill(style);
        var hasStroke = styleHasStroke(style);
        return !(style.lineDash
            || !(+hasFill ^ +hasStroke)
            || (hasFill && typeof style.fill !== 'string')
            || (hasStroke && typeof style.stroke !== 'string')
            || style.strokePercent < 1
            || style.strokeOpacity < 1
            || style.fillOpacity < 1);
    }
    function flushPathDrawn(ctx, scope) {
        scope.batchFill && ctx.fill();
        scope.batchStroke && ctx.stroke();
        scope.batchFill = '';
        scope.batchStroke = '';
    }
    function getStyle(el, inHover) {
        return inHover ? (el.__hoverStyle || el.style) : el.style;
    }
    function brushSingle(ctx, el) {
        brush(ctx, el, { inHover: false, viewWidth: 0, viewHeight: 0 }, true);
    }
    function brush(ctx, el, scope, isLast) {
        var m = el.transform;
        if (!el.shouldBePainted(scope.viewWidth, scope.viewHeight, false, false)) {
            el.__dirty &= ~REDRAW_BIT;
            el.__isRendered = false;
            return;
        }
        var clipPaths = el.__clipPaths;
        var prevElClipPaths = scope.prevElClipPaths;
        var forceSetTransform = false;
        var forceSetStyle = false;
        if (!prevElClipPaths || isClipPathChanged(clipPaths, prevElClipPaths)) {
            if (prevElClipPaths && prevElClipPaths.length) {
                flushPathDrawn(ctx, scope);
                ctx.restore();
                forceSetStyle = forceSetTransform = true;
                scope.prevElClipPaths = null;
                scope.allClipped = false;
                scope.prevEl = null;
            }
            if (clipPaths && clipPaths.length) {
                flushPathDrawn(ctx, scope);
                ctx.save();
                updateClipStatus(clipPaths, ctx, scope);
                forceSetTransform = true;
            }
            scope.prevElClipPaths = clipPaths;
        }
        if (scope.allClipped) {
            el.__isRendered = false;
            return;
        }
        el.beforeBrush && el.beforeBrush();
        el.innerBeforeBrush();
        var prevEl = scope.prevEl;
        if (!prevEl) {
            forceSetStyle = forceSetTransform = true;
        }
        var canBatchPath = el instanceof Path
            && el.autoBatch
            && canPathBatch(el.style);
        if (forceSetTransform || isTransformChanged(m, prevEl.transform)) {
            flushPathDrawn(ctx, scope);
            setContextTransform(ctx, el);
        }
        else if (!canBatchPath) {
            flushPathDrawn(ctx, scope);
        }
        var style = getStyle(el, scope.inHover);
        if (el instanceof Path) {
            if (scope.lastDrawType !== DRAW_TYPE_PATH) {
                forceSetStyle = true;
                scope.lastDrawType = DRAW_TYPE_PATH;
            }
            bindPathAndTextCommonStyle(ctx, el, prevEl, forceSetStyle, scope);
            if (!canBatchPath || (!scope.batchFill && !scope.batchStroke)) {
                ctx.beginPath();
            }
            brushPath(ctx, el, style, canBatchPath);
            if (canBatchPath) {
                scope.batchFill = style.fill || '';
                scope.batchStroke = style.stroke || '';
            }
        }
        else {
            if (el instanceof TSpan) {
                if (scope.lastDrawType !== DRAW_TYPE_TEXT) {
                    forceSetStyle = true;
                    scope.lastDrawType = DRAW_TYPE_TEXT;
                }
                bindPathAndTextCommonStyle(ctx, el, prevEl, forceSetStyle, scope);
                brushText(ctx, el, style);
            }
            else if (el instanceof ZRImage) {
                if (scope.lastDrawType !== DRAW_TYPE_IMAGE) {
                    forceSetStyle = true;
                    scope.lastDrawType = DRAW_TYPE_IMAGE;
                }
                bindImageStyle(ctx, el, prevEl, forceSetStyle, scope);
                brushImage(ctx, el, style);
            }
            else if (el.getTemporalDisplayables) {
                if (scope.lastDrawType !== DRAW_TYPE_INCREMENTAL) {
                    forceSetStyle = true;
                    scope.lastDrawType = DRAW_TYPE_INCREMENTAL;
                }
                brushIncremental(ctx, el, scope);
            }
        }
        if (canBatchPath && isLast) {
            flushPathDrawn(ctx, scope);
        }
        el.innerAfterBrush();
        el.afterBrush && el.afterBrush();
        scope.prevEl = el;
        el.__dirty = 0;
        el.__isRendered = true;
    }
    function brushIncremental(ctx, el, scope) {
        var displayables = el.getDisplayables();
        var temporalDisplayables = el.getTemporalDisplayables();
        ctx.save();
        var innerScope = {
            prevElClipPaths: null,
            prevEl: null,
            allClipped: false,
            viewWidth: scope.viewWidth,
            viewHeight: scope.viewHeight,
            inHover: scope.inHover
        };
        var i;
        var len;
        for (i = el.getCursor(), len = displayables.length; i < len; i++) {
            var displayable = displayables[i];
            displayable.beforeBrush && displayable.beforeBrush();
            displayable.innerBeforeBrush();
            brush(ctx, displayable, innerScope, i === len - 1);
            displayable.innerAfterBrush();
            displayable.afterBrush && displayable.afterBrush();
            innerScope.prevEl = displayable;
        }
        for (var i_1 = 0, len_1 = temporalDisplayables.length; i_1 < len_1; i_1++) {
            var displayable = temporalDisplayables[i_1];
            displayable.beforeBrush && displayable.beforeBrush();
            displayable.innerBeforeBrush();
            brush(ctx, displayable, innerScope, i_1 === len_1 - 1);
            displayable.innerAfterBrush();
            displayable.afterBrush && displayable.afterBrush();
            innerScope.prevEl = displayable;
        }
        el.clearTemporalDisplayables();
        el.notClear = true;
        ctx.restore();
    }

    var decalMap = new WeakMap();
    var decalCache = new LRU(100);
    var decalKeys = ['symbol', 'symbolSize', 'symbolKeepAspect', 'color', 'backgroundColor', 'dashArrayX', 'dashArrayY', 'maxTileWidth', 'maxTileHeight'];
    /**
     * Create or update pattern image from decal options
     *
     * @param {InnerDecalObject | 'none'} decalObject decal options, 'none' if no decal
     * @return {Pattern} pattern with generated image, null if no decal
     */

    function createOrUpdatePatternFromDecal(decalObject, api) {
      if (decalObject === 'none') {
        return null;
      }

      var dpr = api.getDevicePixelRatio();
      var zr = api.getZr();
      var isSVG = zr.painter.type === 'svg';

      if (decalObject.dirty) {
        decalMap["delete"](decalObject);
      }

      var oldPattern = decalMap.get(decalObject);

      if (oldPattern) {
        return oldPattern;
      }

      var decalOpt = defaults(decalObject, {
        symbol: 'rect',
        symbolSize: 1,
        symbolKeepAspect: true,
        color: 'rgba(0, 0, 0, 0.2)',
        backgroundColor: null,
        dashArrayX: 5,
        dashArrayY: 5,
        rotation: 0,
        maxTileWidth: 512,
        maxTileHeight: 512
      });

      if (decalOpt.backgroundColor === 'none') {
        decalOpt.backgroundColor = null;
      }

      var pattern = {
        repeat: 'repeat'
      };
      setPatternnSource(pattern);
      pattern.rotation = decalOpt.rotation;
      pattern.scaleX = pattern.scaleY = isSVG ? 1 : 1 / dpr;
      decalMap.set(decalObject, pattern);
      decalObject.dirty = false;
      return pattern;

      function setPatternnSource(pattern) {
        var keys = [dpr];
        var isValidKey = true;

        for (var i = 0; i < decalKeys.length; ++i) {
          var value = decalOpt[decalKeys[i]];

          if (value != null && !isArray(value) && !isString(value) && !isNumber(value) && typeof value !== 'boolean') {
            isValidKey = false;
            break;
          }

          keys.push(value);
        }

        var cacheKey;

        if (isValidKey) {
          cacheKey = keys.join(',') + (isSVG ? '-svg' : '');
          var cache = decalCache.get(cacheKey);

          if (cache) {
            isSVG ? pattern.svgElement = cache : pattern.image = cache;
          }
        }

        var dashArrayX = normalizeDashArrayX(decalOpt.dashArrayX);
        var dashArrayY = normalizeDashArrayY(decalOpt.dashArrayY);
        var symbolArray = normalizeSymbolArray(decalOpt.symbol);
        var lineBlockLengthsX = getLineBlockLengthX(dashArrayX);
        var lineBlockLengthY = getLineBlockLengthY(dashArrayY);
        var canvas = !isSVG && platformApi.createCanvas();
        var svgRoot = isSVG && {
          tag: 'g',
          attrs: {},
          key: 'dcl',
          children: []
        };
        var pSize = getPatternSize();
        var ctx;

        if (canvas) {
          canvas.width = pSize.width * dpr;
          canvas.height = pSize.height * dpr;
          ctx = canvas.getContext('2d');
        }

        brushDecal();

        if (isValidKey) {
          decalCache.put(cacheKey, canvas || svgRoot);
        }

        pattern.image = canvas;
        pattern.svgElement = svgRoot;
        pattern.svgWidth = pSize.width;
        pattern.svgHeight = pSize.height;
        /**
         * Get minimum length that can make a repeatable pattern.
         *
         * @return {Object} pattern width and height
         */

        function getPatternSize() {
          /**
           * For example, if dash is [[3, 2], [2, 1]] for X, it looks like
           * |---  ---  ---  ---  --- ...
           * |-- -- -- -- -- -- -- -- ...
           * |---  ---  ---  ---  --- ...
           * |-- -- -- -- -- -- -- -- ...
           * So the minimum length of X is 15,
           * which is the least common multiple of `3 + 2` and `2 + 1`
           * |---  ---  ---  |---  --- ...
           * |-- -- -- -- -- |-- -- -- ...
           */
          var width = 1;

          for (var i = 0, xlen = lineBlockLengthsX.length; i < xlen; ++i) {
            width = getLeastCommonMultiple(width, lineBlockLengthsX[i]);
          }

          var symbolRepeats = 1;

          for (var i = 0, xlen = symbolArray.length; i < xlen; ++i) {
            symbolRepeats = getLeastCommonMultiple(symbolRepeats, symbolArray[i].length);
          }

          width *= symbolRepeats;
          var height = lineBlockLengthY * lineBlockLengthsX.length * symbolArray.length;

          if ("development" !== 'production') {
            var warn = function (attrName) {
              /* eslint-disable-next-line */
              console.warn("Calculated decal size is greater than " + attrName + " due to decal option settings so " + attrName + " is used for the decal size. Please consider changing the decal option to make a smaller decal or set " + attrName + " to be larger to avoid incontinuity.");
            };

            if (width > decalOpt.maxTileWidth) {
              warn('maxTileWidth');
            }

            if (height > decalOpt.maxTileHeight) {
              warn('maxTileHeight');
            }
          }

          return {
            width: Math.max(1, Math.min(width, decalOpt.maxTileWidth)),
            height: Math.max(1, Math.min(height, decalOpt.maxTileHeight))
          };
        }

        function brushDecal() {
          if (ctx) {
            ctx.clearRect(0, 0, canvas.width, canvas.height);

            if (decalOpt.backgroundColor) {
              ctx.fillStyle = decalOpt.backgroundColor;
              ctx.fillRect(0, 0, canvas.width, canvas.height);
            }
          }

          var ySum = 0;

          for (var i = 0; i < dashArrayY.length; ++i) {
            ySum += dashArrayY[i];
          }

          if (ySum <= 0) {
            // dashArrayY is 0, draw nothing
            return;
          }

          var y = -lineBlockLengthY;
          var yId = 0;
          var yIdTotal = 0;
          var xId0 = 0;

          while (y < pSize.height) {
            if (yId % 2 === 0) {
              var symbolYId = yIdTotal / 2 % symbolArray.length;
              var x = 0;
              var xId1 = 0;
              var xId1Total = 0;

              while (x < pSize.width * 2) {
                var xSum = 0;

                for (var i = 0; i < dashArrayX[xId0].length; ++i) {
                  xSum += dashArrayX[xId0][i];
                }

                if (xSum <= 0) {
                  // Skip empty line
                  break;
                } // E.g., [15, 5, 20, 5] draws only for 15 and 20


                if (xId1 % 2 === 0) {
                  var size = (1 - decalOpt.symbolSize) * 0.5;
                  var left = x + dashArrayX[xId0][xId1] * size;
                  var top_1 = y + dashArrayY[yId] * size;
                  var width = dashArrayX[xId0][xId1] * decalOpt.symbolSize;
                  var height = dashArrayY[yId] * decalOpt.symbolSize;
                  var symbolXId = xId1Total / 2 % symbolArray[symbolYId].length;
                  brushSymbol(left, top_1, width, height, symbolArray[symbolYId][symbolXId]);
                }

                x += dashArrayX[xId0][xId1];
                ++xId1Total;
                ++xId1;

                if (xId1 === dashArrayX[xId0].length) {
                  xId1 = 0;
                }
              }

              ++xId0;

              if (xId0 === dashArrayX.length) {
                xId0 = 0;
              }
            }

            y += dashArrayY[yId];
            ++yIdTotal;
            ++yId;

            if (yId === dashArrayY.length) {
              yId = 0;
            }
          }

          function brushSymbol(x, y, width, height, symbolType) {
            var scale = isSVG ? 1 : dpr;
            var symbol = createSymbol(symbolType, x * scale, y * scale, width * scale, height * scale, decalOpt.color, decalOpt.symbolKeepAspect);

            if (isSVG) {
              var symbolVNode = zr.painter.renderOneToVNode(symbol);

              if (symbolVNode) {
                svgRoot.children.push(symbolVNode);
              }
            } else {
              // Paint to canvas for all other renderers.
              brushSingle(ctx, symbol);
            }
          }
        }
      }
    }
    /**
     * Convert symbol array into normalized array
     *
     * @param {string | (string | string[])[]} symbol symbol input
     * @return {string[][]} normolized symbol array
     */

    function normalizeSymbolArray(symbol) {
      if (!symbol || symbol.length === 0) {
        return [['rect']];
      }

      if (isString(symbol)) {
        return [[symbol]];
      }

      var isAllString = true;

      for (var i = 0; i < symbol.length; ++i) {
        if (!isString(symbol[i])) {
          isAllString = false;
          break;
        }
      }

      if (isAllString) {
        return normalizeSymbolArray([symbol]);
      }

      var result = [];

      for (var i = 0; i < symbol.length; ++i) {
        if (isString(symbol[i])) {
          result.push([symbol[i]]);
        } else {
          result.push(symbol[i]);
        }
      }

      return result;
    }
    /**
     * Convert dash input into dashArray
     *
     * @param {DecalDashArrayX} dash dash input
     * @return {number[][]} normolized dash array
     */


    function normalizeDashArrayX(dash) {
      if (!dash || dash.length === 0) {
        return [[0, 0]];
      }

      if (isNumber(dash)) {
        var dashValue = Math.ceil(dash);
        return [[dashValue, dashValue]];
      }
      /**
       * [20, 5] should be normalized into [[20, 5]],
       * while [20, [5, 10]] should be normalized into [[20, 20], [5, 10]]
       */


      var isAllNumber = true;

      for (var i = 0; i < dash.length; ++i) {
        if (!isNumber(dash[i])) {
          isAllNumber = false;
          break;
        }
      }

      if (isAllNumber) {
        return normalizeDashArrayX([dash]);
      }

      var result = [];

      for (var i = 0; i < dash.length; ++i) {
        if (isNumber(dash[i])) {
          var dashValue = Math.ceil(dash[i]);
          result.push([dashValue, dashValue]);
        } else {
          var dashValue = map(dash[i], function (n) {
            return Math.ceil(n);
          });

          if (dashValue.length % 2 === 1) {
            // [4, 2, 1] means |----  -    -- |----  -    -- |
            // so normalize it to be [4, 2, 1, 4, 2, 1]
            result.push(dashValue.concat(dashValue));
          } else {
            result.push(dashValue);
          }
        }
      }

      return result;
    }
    /**
     * Convert dash input into dashArray
     *
     * @param {DecalDashArrayY} dash dash input
     * @return {number[]} normolized dash array
     */


    function normalizeDashArrayY(dash) {
      if (!dash || typeof dash === 'object' && dash.length === 0) {
        return [0, 0];
      }

      if (isNumber(dash)) {
        var dashValue_1 = Math.ceil(dash);
        return [dashValue_1, dashValue_1];
      }

      var dashValue = map(dash, function (n) {
        return Math.ceil(n);
      });
      return dash.length % 2 ? dashValue.concat(dashValue) : dashValue;
    }
    /**
     * Get block length of each line. A block is the length of dash line and space.
     * For example, a line with [4, 1] has a dash line of 4 and a space of 1 after
     * that, so the block length of this line is 5.
     *
     * @param {number[][]} dash dash array of X or Y
     * @return {number[]} block length of each line
     */


    function getLineBlockLengthX(dash) {
      return map(dash, function (line) {
        return getLineBlockLengthY(line);
      });
    }

    function getLineBlockLengthY(dash) {
      var blockLength = 0;

      for (var i = 0; i < dash.length; ++i) {
        blockLength += dash[i];
      }

      if (dash.length % 2 === 1) {
        // [4, 2, 1] means |----  -    -- |----  -    -- |
        // So total length is (4 + 2 + 1) * 2
        return blockLength * 2;
      }

      return blockLength;
    }

    function decalVisual(ecModel, api) {
      ecModel.eachRawSeries(function (seriesModel) {
        if (ecModel.isSeriesFiltered(seriesModel)) {
          return;
        }

        var data = seriesModel.getData();

        if (data.hasItemVisual()) {
          data.each(function (idx) {
            var decal = data.getItemVisual(idx, 'decal');

            if (decal) {
              var itemStyle = data.ensureUniqueItemVisual(idx, 'style');
              itemStyle.decal = createOrUpdatePatternFromDecal(decal, api);
            }
          });
        }

        var decal = data.getVisual('decal');

        if (decal) {
          var style = data.getVisual('style');
          style.decal = createOrUpdatePatternFromDecal(decal, api);
        }
      });
    }

    var lifecycle = new Eventful();

    // The implementations will be registered when installing the component.
    // Avoid these code being bundled to the core module.

    var implsStore = {}; // TODO Type

    function registerImpl(name, impl) {
      if ("development" !== 'production') {
        if (implsStore[name]) {
          error("Already has an implementation of " + name + ".");
        }
      }

      implsStore[name] = impl;
    }
    function getImpl(name) {
      if ("development" !== 'production') {
        if (!implsStore[name]) {
          error("Implementation of " + name + " doesn't exists.");
        }
      }

      return implsStore[name];
    }

    var version$1 = '5.4.1';
    var dependencies = {
      zrender: '5.4.1'
    };
    var TEST_FRAME_REMAIN_TIME = 1;
    var PRIORITY_PROCESSOR_SERIES_FILTER = 800; // Some data processors depends on the stack result dimension (to calculate data extent).
    // So data stack stage should be in front of data processing stage.

    var PRIORITY_PROCESSOR_DATASTACK = 900; // "Data filter" will block the stream, so it should be
    // put at the beginning of data processing.

    var PRIORITY_PROCESSOR_FILTER = 1000;
    var PRIORITY_PROCESSOR_DEFAULT = 2000;
    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_COMPONENT = 4000; // Visual property in data. Greater than `PRIORITY_VISUAL_COMPONENT` to enable to
    // overwrite the viusal result of component (like `visualMap`)
    // using data item specific setting (like itemStyle.xxx on data item)

    var PRIORITY_VISUAL_CHART_DATA_CUSTOM = 4500; // Greater than `PRIORITY_VISUAL_CHART_DATA_CUSTOM` to enable to layout based on
    // visual result like `symbolSize`.

    var PRIORITY_VISUAL_POST_CHART_LAYOUT = 4600;
    var PRIORITY_VISUAL_BRUSH = 5000;
    var PRIORITY_VISUAL_ARIA = 6000;
    var PRIORITY_VISUAL_DECAL = 7000;
    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,
        CHART_ITEM: PRIORITY_VISUAL_CHART_DATA_CUSTOM,
        ARIA: PRIORITY_VISUAL_ARIA,
        DECAL: PRIORITY_VISUAL_DECAL
      }
    }; // 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_KEY = '__flagInMainProcess';
    var PENDING_UPDATE = '__pendingUpdate';
    var STATUS_NEEDS_UPDATE_KEY = '__needsUpdateStatus';
    var ACTION_REG = /^[a-zA-Z0-9_]+$/;
    var CONNECT_STATUS_KEY = '__connectUpdateStatus';
    var CONNECT_STATUS_PENDING = 0;
    var CONNECT_STATUS_UPDATING = 1;
    var CONNECT_STATUS_UPDATED = 2;

    function createRegisterEventWithLowercaseECharts(method) {
      return function () {
        var args = [];

        for (var _i = 0; _i < arguments.length; _i++) {
          args[_i] = arguments[_i];
        }

        if (this.isDisposed()) {
          disposedWarning(this.id);
          return;
        }

        return toLowercaseNameAndCallEventful(this, method, args);
      };
    }

    function createRegisterEventWithLowercaseMessageCenter(method) {
      return function () {
        var args = [];

        for (var _i = 0; _i < arguments.length; _i++) {
          args[_i] = arguments[_i];
        }

        return toLowercaseNameAndCallEventful(this, method, args);
      };
    }

    function toLowercaseNameAndCallEventful(host, method, args) {
      // `args[0]` is event name. Event name is all lowercase.
      args[0] = args[0] && args[0].toLowerCase();
      return Eventful.prototype[method].apply(host, args);
    }

    var MessageCenter =
    /** @class */
    function (_super) {
      __extends(MessageCenter, _super);

      function MessageCenter() {
        return _super !== null && _super.apply(this, arguments) || this;
      }

      return MessageCenter;
    }(Eventful);

    var messageCenterProto = MessageCenter.prototype;
    messageCenterProto.on = createRegisterEventWithLowercaseMessageCenter('on');
    messageCenterProto.off = createRegisterEventWithLowercaseMessageCenter('off'); // ---------------------------------------
    // Internal method names for class ECharts
    // ---------------------------------------

    var prepare;
    var prepareView;
    var updateDirectly;
    var updateMethods;
    var doConvertPixel;
    var updateStreamModes;
    var doDispatchAction;
    var flushPendingActions;
    var triggerUpdatedEvent;
    var bindRenderedEvent;
    var bindMouseEvent;
    var render;
    var renderComponents;
    var renderSeries;
    var createExtensionAPI;
    var enableConnect;
    var markStatusToUpdate;
    var applyChangedStates;

    var ECharts =
    /** @class */
    function (_super) {
      __extends(ECharts, _super);

      function ECharts(dom, // Theme name or themeOption.
      theme, opts) {
        var _this = _super.call(this, new ECEventProcessor()) || this;

        _this._chartsViews = [];
        _this._chartsMap = {};
        _this._componentsViews = [];
        _this._componentsMap = {}; // Can't dispatch action during rendering procedure

        _this._pendingActions = [];
        opts = opts || {}; // Get theme by name

        if (isString(theme)) {
          theme = themeStorage[theme];
        }

        _this._dom = dom;
        var defaultRenderer = 'canvas';
        var defaultCoarsePointer = 'auto';
        var defaultUseDirtyRect = false;

        if ("development" !== 'production') {
          var root =
          /* eslint-disable-next-line */
          env.hasGlobalWindow ? window : global;
          defaultRenderer = root.__ECHARTS__DEFAULT__RENDERER__ || defaultRenderer;
          defaultCoarsePointer = retrieve2(root.__ECHARTS__DEFAULT__COARSE_POINTER, defaultCoarsePointer);
          var devUseDirtyRect = root.__ECHARTS__DEFAULT__USE_DIRTY_RECT__;
          defaultUseDirtyRect = devUseDirtyRect == null ? defaultUseDirtyRect : devUseDirtyRect;
        }

        var zr = _this._zr = init(dom, {
          renderer: opts.renderer || defaultRenderer,
          devicePixelRatio: opts.devicePixelRatio,
          width: opts.width,
          height: opts.height,
          ssr: opts.ssr,
          useDirtyRect: retrieve2(opts.useDirtyRect, defaultUseDirtyRect),
          useCoarsePointer: retrieve2(opts.useCoarsePointer, defaultCoarsePointer),
          pointerSize: opts.pointerSize
        });
        _this._ssr = opts.ssr; // Expect 60 fps.

        _this._throttledZrFlush = throttle(bind(zr.flush, zr), 17);
        theme = clone(theme);
        theme && globalBackwardCompat(theme, true);
        _this._theme = theme;
        _this._locale = createLocaleObject(opts.locale || SYSTEM_LANG);
        _this._coordSysMgr = new CoordinateSystemManager();
        var api = _this._api = createExtensionAPI(_this); // Sort on demand

        function prioritySortFunc(a, b) {
          return a.__prio - b.__prio;
        }

        sort(visualFuncs, prioritySortFunc);
        sort(dataProcessorFuncs, prioritySortFunc);
        _this._scheduler = new Scheduler(_this, api, dataProcessorFuncs, visualFuncs);
        _this._messageCenter = new MessageCenter(); // Init mouse events

        _this._initEvents(); // In case some people write `window.onresize = chart.resize`


        _this.resize = bind(_this.resize, _this);
        zr.animation.on('frame', _this._onframe, _this);
        bindRenderedEvent(zr, _this);
        bindMouseEvent(zr, _this); // ECharts instance can be used as value.

        setAsPrimitive(_this);
        return _this;
      }

      ECharts.prototype._onframe = function () {
        if (this._disposed) {
          return;
        }

        applyChangedStates(this);
        var scheduler = this._scheduler; // Lazy update

        if (this[PENDING_UPDATE]) {
          var silent = this[PENDING_UPDATE].silent;
          this[IN_MAIN_PROCESS_KEY] = true;

          try {
            prepare(this);
            updateMethods.update.call(this, null, this[PENDING_UPDATE].updateParams);
          } catch (e) {
            this[IN_MAIN_PROCESS_KEY] = false;
            this[PENDING_UPDATE] = null;
            throw e;
          } // At present, in each frame, zrender performs:
          //   (1) animation step forward.
          //   (2) trigger('frame') (where this `_onframe` is called)
          //   (3) zrender flush (render).
          // If we do nothing here, since we use `setToFinal: true`, the step (3) above
          // will render the final state of the elements before the real animation started.


          this._zr.flush();

          this[IN_MAIN_PROCESS_KEY] = false;
          this[PENDING_UPDATE] = null;
          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 determined in the first frame (the
              // frame is executed immediately 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.

          }
      };

      ECharts.prototype.getDom = function () {
        return this._dom;
      };

      ECharts.prototype.getId = function () {
        return this.id;
      };

      ECharts.prototype.getZr = function () {
        return this._zr;
      };

      ECharts.prototype.isSSR = function () {
        return this._ssr;
      };
      /* eslint-disable-next-line */


      ECharts.prototype.setOption = function (option, notMerge, lazyUpdate) {
        if (this[IN_MAIN_PROCESS_KEY]) {
          if ("development" !== 'production') {
            error('`setOption` should not be called during main process.');
          }

          return;
        }

        if (this._disposed) {
          disposedWarning(this.id);
          return;
        }

        var silent;
        var replaceMerge;
        var transitionOpt;

        if (isObject(notMerge)) {
          lazyUpdate = notMerge.lazyUpdate;
          silent = notMerge.silent;
          replaceMerge = notMerge.replaceMerge;
          transitionOpt = notMerge.transition;
          notMerge = notMerge.notMerge;
        }

        this[IN_MAIN_PROCESS_KEY] = true;

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

        this._model.setOption(option, {
          replaceMerge: replaceMerge
        }, optionPreprocessorFuncs);

        var updateParams = {
          seriesTransition: transitionOpt,
          optionChanged: true
        };

        if (lazyUpdate) {
          this[PENDING_UPDATE] = {
            silent: silent,
            updateParams: updateParams
          };
          this[IN_MAIN_PROCESS_KEY] = false; // `setOption(option, {lazyMode: true})` may be called when zrender has been slept.
          // It should wake it up to make sure zrender start to render at the next frame.

          this.getZr().wakeUp();
        } else {
          try {
            prepare(this);
            updateMethods.update.call(this, null, updateParams);
          } catch (e) {
            this[PENDING_UPDATE] = null;
            this[IN_MAIN_PROCESS_KEY] = false;
            throw e;
          } // Ensure zr refresh sychronously, and then pixel in canvas can be
          // fetched after `setOption`.


          if (!this._ssr) {
            // not use flush when using ssr mode.
            this._zr.flush();
          }

          this[PENDING_UPDATE] = null;
          this[IN_MAIN_PROCESS_KEY] = false;
          flushPendingActions.call(this, silent);
          triggerUpdatedEvent.call(this, silent);
        }
      };
      /**
       * @deprecated
       */


      ECharts.prototype.setTheme = function () {
        deprecateLog('ECharts#setTheme() is DEPRECATED in ECharts 3.0');
      }; // We don't want developers to use getModel directly.


      ECharts.prototype.getModel = function () {
        return this._model;
      };

      ECharts.prototype.getOption = function () {
        return this._model && this._model.getOption();
      };

      ECharts.prototype.getWidth = function () {
        return this._zr.getWidth();
      };

      ECharts.prototype.getHeight = function () {
        return this._zr.getHeight();
      };

      ECharts.prototype.getDevicePixelRatio = function () {
        return this._zr.painter.dpr
        /* eslint-disable-next-line */
        || env.hasGlobalWindow && window.devicePixelRatio || 1;
      };
      /**
       * Get canvas which has all thing rendered
       * @deprecated Use renderToCanvas instead.
       */


      ECharts.prototype.getRenderedCanvas = function (opts) {
        if ("development" !== 'production') {
          deprecateReplaceLog('getRenderedCanvas', 'renderToCanvas');
        }

        return this.renderToCanvas(opts);
      };

      ECharts.prototype.renderToCanvas = function (opts) {
        opts = opts || {};
        var painter = this._zr.painter;

        if ("development" !== 'production') {
          if (painter.type !== 'canvas') {
            throw new Error('renderToCanvas can only be used in the canvas renderer.');
          }
        }

        return painter.getRenderedCanvas({
          backgroundColor: opts.backgroundColor || this._model.get('backgroundColor'),
          pixelRatio: opts.pixelRatio || this.getDevicePixelRatio()
        });
      };

      ECharts.prototype.renderToSVGString = function (opts) {
        opts = opts || {};
        var painter = this._zr.painter;

        if ("development" !== 'production') {
          if (painter.type !== 'svg') {
            throw new Error('renderToSVGString can only be used in the svg renderer.');
          }
        }

        return painter.renderToString({
          useViewBox: opts.useViewBox
        });
      };
      /**
       * Get svg data url
       */


      ECharts.prototype.getSvgDataURL = function () {
        if (!env.svgSupported) {
          return;
        }

        var zr = this._zr;
        var list = zr.storage.getDisplayList(); // Stop animations

        each(list, function (el) {
          el.stopAnimation(null, true);
        });
        return zr.painter.toDataURL();
      };

      ECharts.prototype.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.renderToCanvas(opts).toDataURL('image/' + (opts && opts.type || 'png'));
        each(excludesComponentViews, function (view) {
          view.group.ignore = false;
        });
        return url;
      };

      ECharts.prototype.getConnectedDataURL = function (opts) {
        if (this._disposed) {
          disposedWarning(this.id);
          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_1 = MAX_NUMBER;
          var top_1 = MAX_NUMBER;
          var right_1 = -MAX_NUMBER;
          var bottom_1 = -MAX_NUMBER;
          var canvasList_1 = [];
          var dpr_1 = opts && opts.pixelRatio || this.getDevicePixelRatio();
          each(instances$1, function (chart, id) {
            if (chart.group === groupId) {
              var canvas = isSvg ? chart.getZr().painter.getSvgDom().innerHTML : chart.renderToCanvas(clone(opts));
              var boundingRect = chart.getDom().getBoundingClientRect();
              left_1 = mathMin(boundingRect.left, left_1);
              top_1 = mathMin(boundingRect.top, top_1);
              right_1 = mathMax(boundingRect.right, right_1);
              bottom_1 = mathMax(boundingRect.bottom, bottom_1);
              canvasList_1.push({
                dom: canvas,
                left: boundingRect.left,
                top: boundingRect.top
              });
            }
          });
          left_1 *= dpr_1;
          top_1 *= dpr_1;
          right_1 *= dpr_1;
          bottom_1 *= dpr_1;
          var width = right_1 - left_1;
          var height = bottom_1 - top_1;
          var targetCanvas = platformApi.createCanvas();
          var zr_1 = init(targetCanvas, {
            renderer: isSvg ? 'svg' : 'canvas'
          });
          zr_1.resize({
            width: width,
            height: height
          });

          if (isSvg) {
            var content_1 = '';
            each(canvasList_1, function (item) {
              var x = item.left - left_1;
              var y = item.top - top_1;
              content_1 += '<g transform="translate(' + x + ',' + y + ')">' + item.dom + '</g>';
            });
            zr_1.painter.getSvgRoot().innerHTML = content_1;

            if (opts.connectedBackgroundColor) {
              zr_1.painter.setBackgroundColor(opts.connectedBackgroundColor);
            }

            zr_1.refreshImmediately();
            return zr_1.painter.toDataURL();
          } else {
            // Background between the charts
            if (opts.connectedBackgroundColor) {
              zr_1.add(new Rect({
                shape: {
                  x: 0,
                  y: 0,
                  width: width,
                  height: height
                },
                style: {
                  fill: opts.connectedBackgroundColor
                }
              }));
            }

            each(canvasList_1, function (item) {
              var img = new ZRImage({
                style: {
                  x: item.left * dpr_1 - left_1,
                  y: item.top * dpr_1 - top_1,
                  image: item.dom
                }
              });
              zr_1.add(img);
            });
            zr_1.refreshImmediately();
            return targetCanvas.toDataURL('image/' + (opts && opts.type || 'png'));
          }
        } else {
          return this.getDataURL(opts);
        }
      };

      ECharts.prototype.convertToPixel = function (finder, value) {
        return doConvertPixel(this, 'convertToPixel', finder, value);
      };

      ECharts.prototype.convertFromPixel = function (finder, value) {
        return doConvertPixel(this, 'convertFromPixel', finder, value);
      };
      /**
       * Is the specified coordinate systems or components contain the given pixel point.
       * @param {Array|number} value
       * @return {boolean} result
       */


      ECharts.prototype.containPixel = function (finder, value) {
        if (this._disposed) {
          disposedWarning(this.id);
          return;
        }

        var ecModel = this._model;
        var result;
        var findResult = parseFinder(ecModel, finder);
        each(findResult, function (models, key) {
          key.indexOf('Models') >= 0 && each(models, function (model) {
            var coordSys = model.coordinateSystem;

            if (coordSys && coordSys.containPoint) {
              result = result || !!coordSys.containPoint(value);
            } else if (key === 'seriesModels') {
              var view = this._chartsMap[model.__viewId];

              if (view && view.containPoint) {
                result = result || view.containPoint(value, model);
              } else {
                if ("development" !== 'production') {
                  warn(key + ': ' + (view ? 'The found component do not support containPoint.' : 'No view mapping to the found component.'));
                }
              }
            } else {
              if ("development" !== 'production') {
                warn(key + ': containPoint is not supported');
              }
            }
          }, this);
        }, this);
        return !!result;
      };
      /**
       * Get visual from series or data.
       * @param 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 visualType 'color', 'symbol', 'symbolSize'
       */


      ECharts.prototype.getVisual = function (finder, visualType) {
        var ecModel = this._model;
        var parsedFinder = parseFinder(ecModel, finder, {
          defaultMainType: 'series'
        });
        var seriesModel = parsedFinder.seriesModel;

        if ("development" !== 'production') {
          if (!seriesModel) {
            warn('There is no specified series model');
          }
        }

        var data = seriesModel.getData();
        var dataIndexInside = parsedFinder.hasOwnProperty('dataIndexInside') ? parsedFinder.dataIndexInside : parsedFinder.hasOwnProperty('dataIndex') ? data.indexOfRawIndex(parsedFinder.dataIndex) : null;
        return dataIndexInside != null ? getItemVisualFromData(data, dataIndexInside, visualType) : getVisualFromData(data, visualType);
      };
      /**
       * Get view of corresponding component model
       */


      ECharts.prototype.getViewOfComponentModel = function (componentModel) {
        return this._componentsMap[componentModel.__viewId];
      };
      /**
       * Get view of corresponding series model
       */


      ECharts.prototype.getViewOfSeriesModel = function (seriesModel) {
        return this._chartsMap[seriesModel.__viewId];
      };

      ECharts.prototype._initEvents = function () {
        var _this = this;

        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 {
              el && findEventDispatcher(el, function (parent) {
                var ecData = getECData(parent);

                if (ecData && ecData.dataIndex != null) {
                  var dataModel = ecData.dataModel || ecModel.getSeriesByIndex(ecData.seriesIndex);
                  params = dataModel && dataModel.getDataParams(ecData.dataIndex, ecData.dataType) || {};
                  return true;
                } // If element has custom eventData of components
                else if (ecData.eventData) {
                    params = extend({}, ecData.eventData);
                    return true;
                  }
              }, true);
            } // 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 ("development" !== 'production') {
                // `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)) {
                  warn('model or view can not be found by params');
                }
              }

              params.event = e;
              params.type = eveName;
              _this._$eventProcessor.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);
        });
        each(eventActionMap, function (actionType, eventType) {
          _this._messageCenter.on(eventType, function (event) {
            this.trigger(eventType, event);
          }, _this);
        }); // Extra events
        // TODO register?

        each(['selectchanged'], function (eventType) {
          _this._messageCenter.on(eventType, function (event) {
            this.trigger(eventType, event);
          }, _this);
        });
        handleLegacySelectEvents(this._messageCenter, this, this._api);
      };

      ECharts.prototype.isDisposed = function () {
        return this._disposed;
      };

      ECharts.prototype.clear = function () {
        if (this._disposed) {
          disposedWarning(this.id);
          return;
        }

        this.setOption({
          series: []
        }, true);
      };

      ECharts.prototype.dispose = function () {
        if (this._disposed) {
          disposedWarning(this.id);
          return;
        }

        this._disposed = true;
        var dom = this.getDom();

        if (dom) {
          setAttribute(this.getDom(), DOM_ATTRIBUTE_KEY, '');
        }

        var chart = this;
        var api = chart._api;
        var ecModel = chart._model;
        each(chart._componentsViews, function (component) {
          component.dispose(ecModel, api);
        });
        each(chart._chartsViews, function (chart) {
          chart.dispose(ecModel, api);
        }); // Dispose after all views disposed

        chart._zr.dispose(); // Set properties to null.
        // To reduce the memory cost in case the top code still holds this instance unexpectedly.


        chart._dom = chart._model = chart._chartsMap = chart._componentsMap = chart._chartsViews = chart._componentsViews = chart._scheduler = chart._api = chart._zr = chart._throttledZrFlush = chart._theme = chart._coordSysMgr = chart._messageCenter = null;
        delete instances$1[chart.id];
      };
      /**
       * Resize the chart
       */


      ECharts.prototype.resize = function (opts) {
        if (this[IN_MAIN_PROCESS_KEY]) {
          if ("development" !== 'production') {
            error('`resize` should not be called during main process.');
          }

          return;
        }

        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 needPrepare = ecModel.resetOption('media');
        var silent = opts && opts.silent; // There is some real cases that:
        // chart.setOption(option, { lazyUpdate: true });
        // chart.resize();

        if (this[PENDING_UPDATE]) {
          if (silent == null) {
            silent = this[PENDING_UPDATE].silent;
          }

          needPrepare = true;
          this[PENDING_UPDATE] = null;
        }

        this[IN_MAIN_PROCESS_KEY] = true;

        try {
          needPrepare && prepare(this);
          updateMethods.update.call(this, {
            type: 'resize',
            animation: extend({
              // Disable animation
              duration: 0
            }, opts && opts.animation)
          });
        } catch (e) {
          this[IN_MAIN_PROCESS_KEY] = false;
          throw e;
        }

        this[IN_MAIN_PROCESS_KEY] = false;
        flushPendingActions.call(this, silent);
        triggerUpdatedEvent.call(this, silent);
      };

      ECharts.prototype.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 ("development" !== 'production') {
            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
       */


      ECharts.prototype.hideLoading = function () {
        if (this._disposed) {
          disposedWarning(this.id);
          return;
        }

        this._loadingFX && this._zr.remove(this._loadingFX);
        this._loadingFX = null;
      };

      ECharts.prototype.makeActionFromEvent = function (eventObj) {
        var payload = extend({}, eventObj);
        payload.type = eventActionMap[eventObj.type];
        return payload;
      };
      /**
       * @param opt If pass boolean, means opt.silent
       * @param opt.silent Default `false`. Whether trigger events.
       * @param opt.flush Default `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.
       */


      ECharts.prototype.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_KEY]) {
          this._pendingActions.push(payload);

          return;
        }

        var silent = opt.silent;
        doDispatchAction.call(this, payload, silent);
        var flush = opt.flush;

        if (flush) {
          this._zr.flush();
        } else if (flush !== false && env.browser.weChat) {
          // In WeChat embedded browser, `requestAnimationFrame` and `setInterval`
          // hang when sliding page (on touch event), which cause that zr does not
          // refresh until 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, silent);
        triggerUpdatedEvent.call(this, silent);
      };

      ECharts.prototype.updateLabelLayout = function () {
        lifecycle.trigger('series:layoutlabels', this._model, this._api, {
          // Not adding series labels.
          // TODO
          updatedSeries: []
        });
      };

      ECharts.prototype.appendData = function (params) {
        if (this._disposed) {
          disposedWarning(this.id);
          return;
        }

        var seriesIndex = params.seriesIndex;
        var ecModel = this.getModel();
        var seriesModel = ecModel.getSeriesByIndex(seriesIndex);

        if ("development" !== 'production') {
          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;
        this.getZr().wakeUp();
      }; // A work around for no `internal` modifier in ts yet but
      // need to strictly hide private methods to JS users.


      ECharts.internalField = function () {
        prepare = function (ecIns) {
          var scheduler = ecIns._scheduler;
          scheduler.restorePipelines(ecIns._model);
          scheduler.prepareStageTasks();
          prepareView(ecIns, true);
          prepareView(ecIns, false);
          scheduler.plan();
        };
        /**
         * Prepare view instances of charts and components
         */


        prepareView = function (ecIns, isComponent) {
          var ecModel = ecIns._model;
          var scheduler = ecIns._scheduler;
          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) {
            // By default view will be reused if possible for the case that `setOption` with "notMerge"
            // mode and need to enable transition animation. (Usually, when they have the same id, or
            // especially no id but have the same type & name & index. See the `model.id` generation
            // rule in `makeIdAndName` and `viewId` generation rule here).
            // But in `replaceMerge` mode, this feature should be able to disabled when it is clear that
            // the new model has nothing to do with the old model.
            var requireNewView = model.__requireNewView; // This command should not work twice.

            model.__requireNewView = false; // Consider: id same and type changed.

            var viewId = '_ec_' + model.id + '_' + model.type;
            var view = !requireNewView && viewMap[viewId];

            if (!view) {
              var classType = parseClassType(model.type);
              var Clazz = isComponent ? ComponentView.getClass(classType.main, classType.sub) : // FIXME:TS
              // (ChartView as ChartViewConstructor).getClass('series', classType.sub)
              // For backward compat, still support a chart type declared as only subType
              // like "liquidfill", but recommend "series.liquidfill"
              // But need a base class to make a type series.
              ChartView.getClass(classType.sub);

              if ("development" !== 'production') {
                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);

              if (viewMap[view.__id] === view) {
                delete viewMap[view.__id];
              }

              view.__id = view.group.__ecComponentInfo = null;
            } else {
              i++;
            }
          }
        };

        updateDirectly = function (ecIns, method, payload, mainType, subType) {
          var ecModel = ecIns._model;
          ecModel.setUpdatePayload(payload); // broadcast

          if (!mainType) {
            // FIXME
            // Chart will not be update directly here, except set dirty.
            // But there is no such scenario now.
            each([].concat(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;
          var excludeSeriesIdMap;

          if (excludeSeriesId != null) {
            excludeSeriesIdMap = createHashMap();
            each(normalizeToArray(excludeSeriesId), function (id) {
              var modelId = convertOptionIdName(id, null);

              if (modelId != null) {
                excludeSeriesIdMap.set(modelId, true);
              }
            });
          } // If dispatchAction before setOption, do nothing.


          ecModel && ecModel.eachComponent(condition, function (model) {
            var isExcluded = excludeSeriesIdMap && excludeSeriesIdMap.get(model.id) != null;

            if (isExcluded) {
              return;
            }

            if (isHighDownPayload(payload)) {
              if (model instanceof SeriesModel) {
                if (payload.type === HIGHLIGHT_ACTION_TYPE && !payload.notBlur && !model.get(['emphasis', 'disabled'])) {
                  blurSeriesFromHighlightPayload(model, payload, ecIns._api);
                }
              } else {
                var _a = findComponentHighDownDispatchers(model.mainType, model.componentIndex, payload.name, ecIns._api),
                    focusSelf = _a.focusSelf,
                    dispatchers = _a.dispatchers;

                if (payload.type === HIGHLIGHT_ACTION_TYPE && focusSelf && !payload.notBlur) {
                  blurComponent(model.mainType, model.componentIndex, ecIns._api);
                } // PENDING:
                // Whether to put this "enter emphasis" code in `ComponentView`,
                // which will be the same as `ChartView` but might be not necessary
                // and will be far from this logic.


                if (dispatchers) {
                  each(dispatchers, function (dispatcher) {
                    payload.type === HIGHLIGHT_ACTION_TYPE ? enterEmphasis(dispatcher) : leaveEmphasis(dispatcher);
                  });
                }
              }
            } else if (isSelectChangePayload(payload)) {
              // TODO geo
              if (model instanceof SeriesModel) {
                toggleSelectionFromPayload(model, payload, ecIns._api);
                updateSeriesElementSelection(model);
                markStatusToUpdate(ecIns);
              }
            }
          }, ecIns);
          ecModel && ecModel.eachComponent(condition, function (model) {
            var isExcluded = excludeSeriesIdMap && excludeSeriesIdMap.get(model.id) != null;

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

        updateMethods = {
          prepareAndUpdate: function (payload) {
            prepare(this);
            updateMethods.update.call(this, payload, {
              // Needs to mark option changed if newOption is given.
              // It's from MagicType.
              // TODO If use a separate flag optionChanged in payload?
              optionChanged: payload.newOption != null
            });
          },
          update: function (payload, updateParams) {
            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;
            }

            ecModel.setUpdatePayload(payload);
            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 original 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
            // determine whether to 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 required in stream mode updater currently.

            coordSysMgr.update(ecModel, api);
            clearColorPalette(ecModel);
            scheduler.performVisualTasks(ecModel, payload);
            render(this, ecModel, api, payload, updateParams); // Set background

            var backgroundColor = ecModel.get('backgroundColor') || 'transparent';
            var darkMode = ecModel.get('darkMode');
            zr.setBackgroundColor(backgroundColor); // Force set dark mode.

            if (darkMode != null && darkMode !== 'auto') {
              zr.setDarkMode(darkMode);
            }

            lifecycle.trigger('afterupdate', ecModel, api);
          },
          updateTransform: function (payload) {
            var _this = this;

            var ecModel = this._model;
            var api = this._api; // update before setOption

            if (!ecModel) {
              return;
            }

            ecModel.setUpdatePayload(payload); // ChartView.markUpdateMethod(payload, 'updateTransform');

            var componentDirtyList = [];
            ecModel.eachComponent(function (componentType, componentModel) {
              if (componentType === 'series') {
                return;
              }

              var componentView = _this.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 = _this._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(this, ecModel, api, payload, {}, seriesDirtyMap);
            lifecycle.trigger('afterupdate', ecModel, api);
          },
          updateView: function (payload) {
            var ecModel = this._model; // update before setOption

            if (!ecModel) {
              return;
            }

            ecModel.setUpdatePayload(payload);
            ChartView.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, ecModel, this._api, payload, {});
            lifecycle.trigger('afterupdate', ecModel, this._api);
          },
          updateVisual: function (payload) {
            // updateMethods.update.call(this, payload);
            var _this = this;

            var ecModel = this._model; // update before setOption

            if (!ecModel) {
              return;
            }

            ecModel.setUpdatePayload(payload); // clear all visual

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

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

            ecModel.eachComponent(function (componentType, componentModel) {
              if (componentType !== 'series') {
                var componentView = _this.getViewOfComponentModel(componentModel);

                componentView && componentView.__alive && componentView.updateVisual(componentModel, ecModel, _this._api, payload);
              }
            });
            ecModel.eachSeries(function (seriesModel) {
              var chartView = _this._chartsMap[seriesModel.__viewId];
              chartView.updateVisual(seriesModel, ecModel, _this._api, payload);
            });
            lifecycle.trigger('afterupdate', ecModel, this._api);
          },
          updateLayout: function (payload) {
            updateMethods.update.call(this, payload);
          }
        };

        doConvertPixel = function (ecIns, methodName, finder, value) {
          if (ecIns._disposed) {
            disposedWarning(ecIns.id);
            return;
          }

          var ecModel = ecIns._model;

          var coordSysList = ecIns._coordSysMgr.getCoordinateSystems();

          var result;
          var parsedFinder = parseFinder(ecModel, finder);

          for (var i = 0; i < coordSysList.length; i++) {
            var coordSys = coordSysList[i];

            if (coordSys[methodName] && (result = coordSys[methodName](ecModel, parsedFinder, value)) != null) {
              return result;
            }
          }

          if ("development" !== 'production') {
            warn('No coordinate system that supports ' + methodName + ' found by the given finder.');
          }
        };

        updateStreamModes = function (ecIns, ecModel) {
          var chartsMap = ecIns._chartsMap;
          var scheduler = ecIns._scheduler;
          ecModel.eachSeries(function (seriesModel) {
            scheduler.updateStreamModes(seriesModel, chartsMap[seriesModel.__viewId]);
          });
        };

        doDispatchAction = function (payload, silent) {
          var _this = this;

          var ecModel = this.getModel();
          var payloadType = payload.type;
          var escapeConnect = payload.escapeConnect;
          var actionWrap = actions[payloadType];
          var actionInfo = actionWrap.actionInfo;
          var cptTypeTmp = (actionInfo.update || 'update').split(':');
          var updateMethod = cptTypeTmp.pop();
          var cptType = cptTypeTmp[0] != null && parseClassType(cptTypeTmp[0]);
          this[IN_MAIN_PROCESS_KEY] = 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 isSelectChange = isSelectChangePayload(payload);
          var isHighDown = isHighDownPayload(payload); // Only leave blur once if there are multiple batches.

          if (isHighDown) {
            allLeaveBlur(this._api);
          }

          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) {
              var _a = preParseFinder(payload),
                  queryOptionMap = _a.queryOptionMap,
                  mainTypeSpecified = _a.mainTypeSpecified;

              var componentMainType = mainTypeSpecified ? queryOptionMap.keys()[0] : 'series';
              updateDirectly(_this, updateMethod, batchItem, componentMainType);
              markStatusToUpdate(_this);
            } else if (isSelectChange) {
              // At present `dispatchAction({ type: 'select', ... })` is not supported on components.
              // geo still use 'geoselect'.
              updateDirectly(_this, updateMethod, batchItem, 'series');
              markStatusToUpdate(_this);
            } else if (cptType) {
              updateDirectly(_this, updateMethod, batchItem, cptType.main, cptType.sub);
            }
          });

          if (updateMethod !== 'none' && !isHighDown && !isSelectChange && !cptType) {
            try {
              // Still dirty
              if (this[PENDING_UPDATE]) {
                prepare(this);
                updateMethods.update.call(this, payload);
                this[PENDING_UPDATE] = null;
              } else {
                updateMethods[updateMethod].call(this, payload);
              }
            } catch (e) {
              this[IN_MAIN_PROCESS_KEY] = false;
              throw e;
            }
          } // 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_KEY] = false;

          if (!silent) {
            var messageCenter = this._messageCenter;
            messageCenter.trigger(eventObj.type, eventObj); // Extra triggered 'selectchanged' event

            if (isSelectChange) {
              var newObj = {
                type: 'selectchanged',
                escapeConnect: escapeConnect,
                selected: getAllSelectedIndices(ecModel),
                isFromClick: payload.isFromClick || false,
                fromAction: payload.type,
                fromActionPayload: payload
              };
              messageCenter.trigger(newObj.type, newObj);
            }
          }
        };

        flushPendingActions = function (silent) {
          var pendingActions = this._pendingActions;

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

        triggerUpdatedEvent = function (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.
         */


        bindRenderedEvent = function (zr, ecIns) {
          zr.on('rendered', function (params) {
            ecIns.trigger('rendered', params); // The `finished` event should not be triggered repeatedly,
            // so it should only be triggered when rendering indeed happens
            // 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[PENDING_UPDATE] && !ecIns._scheduler.unfinished && !ecIns._pendingActions.length) {
              ecIns.trigger('finished');
            }
          });
        };

        bindMouseEvent = function (zr, ecIns) {
          zr.on('mouseover', function (e) {
            var el = e.target;
            var dispatcher = findEventDispatcher(el, isHighDownDispatcher);

            if (dispatcher) {
              handleGlobalMouseOverForHighDown(dispatcher, e, ecIns._api);
              markStatusToUpdate(ecIns);
            }
          }).on('mouseout', function (e) {
            var el = e.target;
            var dispatcher = findEventDispatcher(el, isHighDownDispatcher);

            if (dispatcher) {
              handleGlobalMouseOutForHighDown(dispatcher, e, ecIns._api);
              markStatusToUpdate(ecIns);
            }
          }).on('click', function (e) {
            var el = e.target;
            var dispatcher = findEventDispatcher(el, function (target) {
              return getECData(target).dataIndex != null;
            }, true);

            if (dispatcher) {
              var actionType = dispatcher.selected ? 'unselect' : 'select';
              var ecData = getECData(dispatcher);

              ecIns._api.dispatchAction({
                type: actionType,
                dataType: ecData.dataType,
                dataIndexInside: ecData.dataIndex,
                seriesIndex: ecData.seriesIndex,
                isFromClick: true
              });
            }
          });
        };

        function clearColorPalette(ecModel) {
          ecModel.clearColorPalette();
          ecModel.eachSeries(function (seriesModel) {
            seriesModel.clearColorPalette();
          });
        }

        function allocateZlevels(ecModel) {
          var componentZLevels = [];
          var seriesZLevels = [];
          var hasSeperateZLevel = false;
          ecModel.eachComponent(function (componentType, componentModel) {
            var zlevel = componentModel.get('zlevel') || 0;
            var z = componentModel.get('z') || 0;
            var zlevelKey = componentModel.getZLevelKey();
            hasSeperateZLevel = hasSeperateZLevel || !!zlevelKey;
            (componentType === 'series' ? seriesZLevels : componentZLevels).push({
              zlevel: zlevel,
              z: z,
              idx: componentModel.componentIndex,
              type: componentType,
              key: zlevelKey
            });
          });

          if (hasSeperateZLevel) {
            // Series after component
            var zLevels = componentZLevels.concat(seriesZLevels);
            var lastSeriesZLevel_1;
            var lastSeriesKey_1;
            sort(zLevels, function (a, b) {
              if (a.zlevel === b.zlevel) {
                return a.z - b.z;
              }

              return a.zlevel - b.zlevel;
            });
            each(zLevels, function (item) {
              var componentModel = ecModel.getComponent(item.type, item.idx);
              var zlevel = item.zlevel;
              var key = item.key;

              if (lastSeriesZLevel_1 != null) {
                zlevel = Math.max(lastSeriesZLevel_1, zlevel);
              }

              if (key) {
                if (zlevel === lastSeriesZLevel_1 && key !== lastSeriesKey_1) {
                  zlevel++;
                }

                lastSeriesKey_1 = key;
              } else if (lastSeriesKey_1) {
                if (zlevel === lastSeriesZLevel_1) {
                  zlevel++;
                }

                lastSeriesKey_1 = '';
              }

              lastSeriesZLevel_1 = zlevel;
              componentModel.setZLevel(zlevel);
            });
          }
        }

        render = function (ecIns, ecModel, api, payload, updateParams) {
          allocateZlevels(ecModel);
          renderComponents(ecIns, ecModel, api, payload, updateParams);
          each(ecIns._chartsViews, function (chart) {
            chart.__alive = false;
          });
          renderSeries(ecIns, ecModel, api, payload, updateParams); // Remove groups of unrendered charts

          each(ecIns._chartsViews, function (chart) {
            if (!chart.__alive) {
              chart.remove(ecModel, api);
            }
          });
        };

        renderComponents = function (ecIns, ecModel, api, payload, updateParams, dirtyList) {
          each(dirtyList || ecIns._componentsViews, function (componentView) {
            var componentModel = componentView.__model;
            clearStates(componentModel, componentView);
            componentView.render(componentModel, ecModel, api, payload);
            updateZ(componentModel, componentView);
            updateStates(componentModel, componentView);
          });
        };
        /**
         * Render each chart and component
         */


        renderSeries = function (ecIns, ecModel, api, payload, updateParams, dirtyMap) {
          // Render all charts
          var scheduler = ecIns._scheduler;
          updateParams = extend(updateParams || {}, {
            updatedSeries: ecModel.getSeries()
          }); // TODO progressive?

          lifecycle.trigger('series:beforeupdate', ecModel, api, updateParams);
          var unfinished = false;
          ecModel.eachSeries(function (seriesModel) {
            var chartView = ecIns._chartsMap[seriesModel.__viewId];
            chartView.__alive = true;
            var renderTask = chartView.renderTask;
            scheduler.updatePayload(renderTask, payload); // TODO states on marker.

            clearStates(seriesModel, chartView);

            if (dirtyMap && dirtyMap.get(seriesModel.uid)) {
              renderTask.dirty();
            }

            if (renderTask.perform(scheduler.getPerformArgs(renderTask))) {
              unfinished = true;
            }

            chartView.group.silent = !!seriesModel.get('silent'); // Should not call markRedraw on group, because it will disable zrender
            // incremental render (always render from the __startIndex each frame)
            // chartView.group.markRedraw();

            updateBlend(seriesModel, chartView);
            updateSeriesElementSelection(seriesModel);
          });
          scheduler.unfinished = unfinished || scheduler.unfinished;
          lifecycle.trigger('series:layoutlabels', ecModel, api, updateParams); // transition after label is layouted.

          lifecycle.trigger('series:transition', ecModel, api, updateParams);
          ecModel.eachSeries(function (seriesModel) {
            var chartView = ecIns._chartsMap[seriesModel.__viewId]; // Update Z after labels updated. Before applying states.

            updateZ(seriesModel, chartView); // NOTE: Update states after label is updated.
            // label should be in normal status when layouting.

            updateStates(seriesModel, chartView);
          }); // If use hover layer

          updateHoverLayerStatus(ecIns, ecModel);
          lifecycle.trigger('series:afterupdate', ecModel, api, updateParams);
        };

        markStatusToUpdate = function (ecIns) {
          ecIns[STATUS_NEEDS_UPDATE_KEY] = true; // Wake up zrender if it's sleep. Let it update states in the next frame.

          ecIns.getZr().wakeUp();
        };

        applyChangedStates = function (ecIns) {
          if (!ecIns[STATUS_NEEDS_UPDATE_KEY]) {
            return;
          }

          ecIns.getZr().storage.traverse(function (el) {
            // Not applied on removed elements, it may still in fading.
            if (isElementRemoved(el)) {
              return;
            }

            applyElementStates(el);
          });
          ecIns[STATUS_NEEDS_UPDATE_KEY] = false;
        };

        function applyElementStates(el) {
          var newStates = [];
          var oldStates = el.currentStates; // Keep other states.

          for (var i = 0; i < oldStates.length; i++) {
            var stateName = oldStates[i];

            if (!(stateName === 'emphasis' || stateName === 'blur' || stateName === 'select')) {
              newStates.push(stateName);
            }
          } // Only use states when it's exists.


          if (el.selected && el.states.select) {
            newStates.push('select');
          }

          if (el.hoverState === HOVER_STATE_EMPHASIS && el.states.emphasis) {
            newStates.push('emphasis');
          } else if (el.hoverState === HOVER_STATE_BLUR && el.states.blur) {
            newStates.push('blur');
          }

          el.useStates(newStates);
        }

        function updateHoverLayerStatus(ecIns, ecModel) {
          var zr = ecIns._zr;
          var storage = zr.storage;
          var elCount = 0;
          storage.traverse(function (el) {
            if (!el.isGroup) {
              elCount++;
            }
          });

          if (elCount > ecModel.get('hoverLayerThreshold') && !env.node && !env.worker) {
            ecModel.eachSeries(function (seriesModel) {
              if (seriesModel.preventUsingHoverLayer) {
                return;
              }

              var chartView = ecIns._chartsMap[seriesModel.__viewId];

              if (chartView.__alive) {
                chartView.eachRendered(function (el) {
                  if (el.states.emphasis) {
                    el.states.emphasis.hoverLayer = true;
                  }
                });
              }
            });
          }
        }
        /**
         * Update chart and blend.
         */

        function updateBlend(seriesModel, chartView) {
          var blendMode = seriesModel.get('blendMode') || null;
          chartView.eachRendered(function (el) {
            // FIXME marker and other components
            if (!el.isGroup) {
              // DON'T mark the element dirty. In case element is incremental and don't want to rerender.
              el.style.blend = blendMode;
            }
          });
        }

        function updateZ(model, view) {
          if (model.preventAutoZ) {
            return;
          }

          var z = model.get('z') || 0;
          var zlevel = model.get('zlevel') || 0; // Set z and zlevel

          view.eachRendered(function (el) {
            doUpdateZ(el, z, zlevel, -Infinity); // Don't traverse the children because it has been traversed in _updateZ.

            return true;
          });
        }

        function doUpdateZ(el, z, zlevel, maxZ2) {
          // Group may also have textContent
          var label = el.getTextContent();
          var labelLine = el.getTextGuideLine();
          var isGroup = el.isGroup;

          if (isGroup) {
            // set z & zlevel of children elements of Group
            var children = el.childrenRef();

            for (var i = 0; i < children.length; i++) {
              maxZ2 = Math.max(doUpdateZ(children[i], z, zlevel, maxZ2), maxZ2);
            }
          } else {
            // not Group
            el.z = z;
            el.zlevel = zlevel;
            maxZ2 = Math.max(el.z2, maxZ2);
          } // always set z and zlevel if label/labelLine exists


          if (label) {
            label.z = z;
            label.zlevel = zlevel; // lift z2 of text content
            // TODO if el.emphasis.z2 is spcefied, what about textContent.

            isFinite(maxZ2) && (label.z2 = maxZ2 + 2);
          }

          if (labelLine) {
            var textGuideLineConfig = el.textGuideLineConfig;
            labelLine.z = z;
            labelLine.zlevel = zlevel;
            isFinite(maxZ2) && (labelLine.z2 = maxZ2 + (textGuideLineConfig && textGuideLineConfig.showAbove ? 1 : -1));
          }

          return maxZ2;
        } // Clear states without animation.
        // TODO States on component.


        function clearStates(model, view) {
          view.eachRendered(function (el) {
            // Not applied on removed elements, it may still in fading.
            if (isElementRemoved(el)) {
              return;
            }

            var textContent = el.getTextContent();
            var textGuide = el.getTextGuideLine();

            if (el.stateTransition) {
              el.stateTransition = null;
            }

            if (textContent && textContent.stateTransition) {
              textContent.stateTransition = null;
            }

            if (textGuide && textGuide.stateTransition) {
              textGuide.stateTransition = null;
            } // TODO If el is incremental.


            if (el.hasState()) {
              el.prevStates = el.currentStates;
              el.clearStates();
            } else if (el.prevStates) {
              el.prevStates = null;
            }
          });
        }

        function updateStates(model, view) {
          var stateAnimationModel = model.getModel('stateAnimation');
          var enableAnimation = model.isAnimationEnabled();
          var duration = stateAnimationModel.get('duration');
          var stateTransition = duration > 0 ? {
            duration: duration,
            delay: stateAnimationModel.get('delay'),
            easing: stateAnimationModel.get('easing') // additive: stateAnimationModel.get('additive')

          } : null;
          view.eachRendered(function (el) {
            if (el.states && el.states.emphasis) {
              // Not applied on removed elements, it may still in fading.
              if (isElementRemoved(el)) {
                return;
              }

              if (el instanceof Path) {
                savePathStates(el);
              } // Only updated on changed element. In case element is incremental and don't want to rerender.
              // TODO, a more proper way?


              if (el.__dirty) {
                var prevStates = el.prevStates; // Restore states without animation

                if (prevStates) {
                  el.useStates(prevStates);
                }
              } // Update state transition and enable animation again.


              if (enableAnimation) {
                el.stateTransition = stateTransition;
                var textContent = el.getTextContent();
                var textGuide = el.getTextGuideLine(); // TODO Is it necessary to animate label?

                if (textContent) {
                  textContent.stateTransition = stateTransition;
                }

                if (textGuide) {
                  textGuide.stateTransition = stateTransition;
                }
              } // Use highlighted and selected flag to toggle states.


              if (el.__dirty) {
                applyElementStates(el);
              }
            }
          });
        }

        createExtensionAPI = function (ecIns) {
          return new (
          /** @class */
          function (_super) {
            __extends(class_1, _super);

            function class_1() {
              return _super !== null && _super.apply(this, arguments) || this;
            }

            class_1.prototype.getCoordinateSystems = function () {
              return ecIns._coordSysMgr.getCoordinateSystems();
            };

            class_1.prototype.getComponentByElement = function (el) {
              while (el) {
                var modelInfo = el.__ecComponentInfo;

                if (modelInfo != null) {
                  return ecIns._model.getComponent(modelInfo.mainType, modelInfo.index);
                }

                el = el.parent;
              }
            };

            class_1.prototype.enterEmphasis = function (el, highlightDigit) {
              enterEmphasis(el, highlightDigit);
              markStatusToUpdate(ecIns);
            };

            class_1.prototype.leaveEmphasis = function (el, highlightDigit) {
              leaveEmphasis(el, highlightDigit);
              markStatusToUpdate(ecIns);
            };

            class_1.prototype.enterBlur = function (el) {
              enterBlur(el);
              markStatusToUpdate(ecIns);
            };

            class_1.prototype.leaveBlur = function (el) {
              leaveBlur(el);
              markStatusToUpdate(ecIns);
            };

            class_1.prototype.enterSelect = function (el) {
              enterSelect(el);
              markStatusToUpdate(ecIns);
            };

            class_1.prototype.leaveSelect = function (el) {
              leaveSelect(el);
              markStatusToUpdate(ecIns);
            };

            class_1.prototype.getModel = function () {
              return ecIns.getModel();
            };

            class_1.prototype.getViewOfComponentModel = function (componentModel) {
              return ecIns.getViewOfComponentModel(componentModel);
            };

            class_1.prototype.getViewOfSeriesModel = function (seriesModel) {
              return ecIns.getViewOfSeriesModel(seriesModel);
            };

            return class_1;
          }(ExtensionAPI))(ecIns);
        };

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

          each(eventActionMap, function (actionType, eventType) {
            chart._messageCenter.on(eventType, function (event) {
              if (connectedGroups[chart.group] && chart[CONNECT_STATUS_KEY] !== CONNECT_STATUS_PENDING) {
                if (event && event.escapeConnect) {
                  return;
                }

                var action_1 = chart.makeActionFromEvent(event);
                var otherCharts_1 = [];
                each(instances$1, function (otherChart) {
                  if (otherChart !== chart && otherChart.group === chart.group) {
                    otherCharts_1.push(otherChart);
                  }
                });
                updateConnectedChartsStatus(otherCharts_1, CONNECT_STATUS_PENDING);
                each(otherCharts_1, function (otherChart) {
                  if (otherChart[CONNECT_STATUS_KEY] !== CONNECT_STATUS_UPDATING) {
                    otherChart.dispatchAction(action_1);
                  }
                });
                updateConnectedChartsStatus(otherCharts_1, CONNECT_STATUS_UPDATED);
              }
            });
          });
        };
      }();

      return ECharts;
    }(Eventful);

    var echartsProto = ECharts.prototype;
    echartsProto.on = createRegisterEventWithLowercaseECharts('on');
    echartsProto.off = createRegisterEventWithLowercaseECharts('off');
    /**
     * @deprecated
     */
    // @ts-ignore

    echartsProto.one = function (eventName, cb, ctx) {
      var self = this;
      deprecateLog('ECharts#one is deprecated.');

      function wrapped() {
        var args2 = [];

        for (var _i = 0; _i < arguments.length; _i++) {
          args2[_i] = arguments[_i];
        }

        cb && cb.apply && cb.apply(this, args2); // @ts-ignore

        self.off(eventName, wrapped);
      }

      this.on.call(this, eventName, wrapped, ctx);
    };

    var MOUSE_EVENT_NAMES = ['click', 'dblclick', 'mouseover', 'mouseout', 'mousemove', 'mousedown', 'mouseup', 'globalout', 'contextmenu'];

    function disposedWarning(id) {
      if ("development" !== 'production') {
        warn('Instance ' + id + ' has been disposed');
      }
    }

    var actions = {};
    /**
     * Map eventType to actionType
     */

    var eventActionMap = {};
    var dataProcessorFuncs = [];
    var optionPreprocessorFuncs = [];
    var visualFuncs = [];
    var themeStorage = {};
    var loadingEffects = {};
    var instances$1 = {};
    var connectedGroups = {};
    var idBase = +new Date() - 0;
    var groupIdBase = +new Date() - 0;
    var DOM_ATTRIBUTE_KEY = '_echarts_instance_';
    /**
     * @param opts.devicePixelRatio Use window.devicePixelRatio by default
     * @param opts.renderer Can choose 'canvas' or 'svg' to render the chart.
     * @param opts.width Use clientWidth of the input `dom` by default.
     *        Can be 'auto' (the same as null/undefined)
     * @param opts.height Use clientHeight of the input `dom` by default.
     *        Can be 'auto' (the same as null/undefined)
     * @param opts.locale Specify the locale.
     * @param opts.useDirtyRect Enable dirty rectangle rendering or not.
     */

    function init$1(dom, theme, opts) {
      var isClient = !(opts && opts.ssr);

      if (isClient) {
        if ("development" !== 'production') {
          if (!dom) {
            throw new Error('Initialize failed: invalid dom.');
          }
        }

        var existInstance = getInstanceByDom(dom);

        if (existInstance) {
          if ("development" !== 'production') {
            warn('There is a chart instance already initialized on the dom.');
          }

          return existInstance;
        }

        if ("development" !== 'production') {
          if (isDom(dom) && dom.nodeName.toUpperCase() !== 'CANVAS' && (!dom.clientWidth && (!opts || opts.width == null) || !dom.clientHeight && (!opts || opts.height == null))) {
            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, opts);
      chart.id = 'ec_' + idBase++;
      instances$1[chart.id] = chart;
      isClient && setAttribute(dom, DOM_ATTRIBUTE_KEY, chart.id);
      enableConnect(chart);
      lifecycle.trigger('afterinit', chart);
      return chart;
    }
    /**
     * @usage
     * (A)
     * ```js
     * let chart1 = echarts.init(dom1);
     * let chart2 = echarts.init(dom2);
     * chart1.group = 'xxx';
     * chart2.group = 'xxx';
     * echarts.connect('xxx');
     * ```
     * (B)
     * ```js
     * let chart1 = echarts.init(dom1);
     * let chart2 = echarts.init(dom2);
     * echarts.connect('xxx', [chart1, chart2]);
     * ```
     */

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

    function disConnect(groupId) {
      connectedGroups[groupId] = false;
    }
    /**
     * Alias and backward compatibility
     */

    var disconnect = disConnect;
    /**
     * Dispose a chart instance
     */

    function dispose$1(chart) {
      if (isString(chart)) {
        chart = instances$1[chart];
      } else if (!(chart instanceof ECharts)) {
        // Try to treat as dom
        chart = getInstanceByDom(chart);
      }

      if (chart instanceof ECharts && !chart.isDisposed()) {
        chart.dispose();
      }
    }
    function getInstanceByDom(dom) {
      return instances$1[getAttribute(dom, DOM_ATTRIBUTE_KEY)];
    }
    function getInstanceById(key) {
      return instances$1[key];
    }
    /**
     * Register theme
     */

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

    function registerPreprocessor(preprocessorFunc) {
      if (indexOf(optionPreprocessorFuncs, preprocessorFunc) < 0) {
        optionPreprocessorFuncs.push(preprocessorFunc);
      }
    }
    function registerProcessor(priority, processor) {
      normalizeRegister(dataProcessorFuncs, priority, processor, PRIORITY_PROCESSOR_DEFAULT);
    }
    /**
     * Register postIniter
     * @param {Function} postInitFunc
     */

    function registerPostInit(postInitFunc) {
      registerUpdateLifecycle('afterinit', postInitFunc);
    }
    /**
     * Register postUpdater
     * @param {Function} postUpdateFunc
     */

    function registerPostUpdate(postUpdateFunc) {
      registerUpdateLifecycle('afterupdate', postUpdateFunc);
    }
    function registerUpdateLifecycle(name, cb) {
      lifecycle.on(name, cb);
    }
    function registerAction(actionInfo, eventName, action) {
      if (isFunction(eventName)) {
        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;

      if (eventActionMap[eventName]) {
        // Already registered.
        return;
      } // 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;
    }
    function registerCoordinateSystem(type, coordSysCreator) {
      CoordinateSystemManager.register(type, coordSysCreator);
    }
    /**
     * 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();
      }
    }

    function registerLayout(priority, layoutTask) {
      normalizeRegister(visualFuncs, priority, layoutTask, PRIORITY_VISUAL_LAYOUT, 'layout');
    }

    function registerVisual(priority, visualTask) {
      normalizeRegister(visualFuncs, priority, visualTask, PRIORITY_VISUAL_CHART, 'visual');
    }
    var registeredTasks = [];

    function normalizeRegister(targetList, priority, fn, defaultPriority, visualType) {
      if (isFunction(priority) || isObject(priority)) {
        fn = priority;
        priority = defaultPriority;
      }

      if ("development" !== 'production') {
        if (isNaN(priority) || priority == null) {
          throw new Error('Illegal priority');
        } // Check duplicate


        each(targetList, function (wrap) {
          assert(wrap.__raw !== fn);
        });
      } // Already registered


      if (indexOf(registeredTasks, fn) >= 0) {
        return;
      }

      registeredTasks.push(fn);
      var stageHandler = Scheduler.wrapStageHandler(fn, visualType);
      stageHandler.__prio = priority;
      stageHandler.__raw = fn;
      targetList.push(stageHandler);
    }

    function registerLoading(name, loadingFx) {
      loadingEffects[name] = loadingFx;
    }
    /**
     * 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')
     *
     *
     * @deprecated use setPlatformAPI({ createCanvas }) instead.
     *
     * @example
     *     let Canvas = require('canvas');
     *     let echarts = require('echarts');
     *     echarts.setCanvasCreator(function () {
     *         // Small size is enough.
     *         return new Canvas(32, 32);
     *     });
     */

    function setCanvasCreator(creator) {
      if ("development" !== 'production') {
        deprecateLog('setCanvasCreator is deprecated. Use setPlatformAPI({ createCanvas }) instead.');
      }

      setPlatformAPI({
        createCanvas: creator
      });
    }
    /**
     * The parameters and usage: see `geoSourceManager.registerMap`.
     * Compatible with previous `echarts.registerMap`.
     */

    function registerMap(mapName, geoJson, specialAreas) {
      var registerMap = getImpl('registerMap');
      registerMap && registerMap(mapName, geoJson, specialAreas);
    }
    function getMap(mapName) {
      var getMap = getImpl('getMap');
      return getMap && getMap(mapName);
    }
    var registerTransform = registerExternalTransform;
    /**
     * Globa dispatchAction to a specified chart instance.
     */
    // export function dispatchAction(payload: { chartId: string } & Payload, opt?: Parameters<ECharts['dispatchAction']>[1]) {
    //     if (!payload || !payload.chartId) {
    //         // Must have chartId to find chart
    //         return;
    //     }
    //     const chart = instances[payload.chartId];
    //     if (chart) {
    //         chart.dispatchAction(payload, opt);
    //     }
    // }
    // Builtin global visual

    registerVisual(PRIORITY_VISUAL_GLOBAL, seriesStyleTask);
    registerVisual(PRIORITY_VISUAL_CHART_DATA_CUSTOM, dataStyleTask);
    registerVisual(PRIORITY_VISUAL_CHART_DATA_CUSTOM, dataColorPaletteTask);
    registerVisual(PRIORITY_VISUAL_GLOBAL, seriesSymbolTask);
    registerVisual(PRIORITY_VISUAL_CHART_DATA_CUSTOM, dataSymbolTask);
    registerVisual(PRIORITY_VISUAL_DECAL, decalVisual);
    registerPreprocessor(globalBackwardCompat);
    registerProcessor(PRIORITY_PROCESSOR_DATASTACK, dataStack);
    registerLoading('default', defaultLoading); // Default actions

    registerAction({
      type: HIGHLIGHT_ACTION_TYPE,
      event: HIGHLIGHT_ACTION_TYPE,
      update: HIGHLIGHT_ACTION_TYPE
    }, noop);
    registerAction({
      type: DOWNPLAY_ACTION_TYPE,
      event: DOWNPLAY_ACTION_TYPE,
      update: DOWNPLAY_ACTION_TYPE
    }, noop);
    registerAction({
      type: SELECT_ACTION_TYPE,
      event: SELECT_ACTION_TYPE,
      update: SELECT_ACTION_TYPE
    }, noop);
    registerAction({
      type: UNSELECT_ACTION_TYPE,
      event: UNSELECT_ACTION_TYPE,
      update: UNSELECT_ACTION_TYPE
    }, noop);
    registerAction({
      type: TOGGLE_SELECT_ACTION_TYPE,
      event: TOGGLE_SELECT_ACTION_TYPE,
      update: TOGGLE_SELECT_ACTION_TYPE
    }, 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 = {};

    var extensions = [];
    var extensionRegisters = {
      registerPreprocessor: registerPreprocessor,
      registerProcessor: registerProcessor,
      registerPostInit: registerPostInit,
      registerPostUpdate: registerPostUpdate,
      registerUpdateLifecycle: registerUpdateLifecycle,
      registerAction: registerAction,
      registerCoordinateSystem: registerCoordinateSystem,
      registerLayout: registerLayout,
      registerVisual: registerVisual,
      registerTransform: registerTransform,
      registerLoading: registerLoading,
      registerMap: registerMap,
      registerImpl: registerImpl,
      PRIORITY: PRIORITY,
      ComponentModel: ComponentModel,
      ComponentView: ComponentView,
      SeriesModel: SeriesModel,
      ChartView: ChartView,
      // TODO Use ComponentModel and SeriesModel instead of Constructor
      registerComponentModel: function (ComponentModelClass) {
        ComponentModel.registerClass(ComponentModelClass);
      },
      registerComponentView: function (ComponentViewClass) {
        ComponentView.registerClass(ComponentViewClass);
      },
      registerSeriesModel: function (SeriesModelClass) {
        SeriesModel.registerClass(SeriesModelClass);
      },
      registerChartView: function (ChartViewClass) {
        ChartView.registerClass(ChartViewClass);
      },
      registerSubTypeDefaulter: function (componentType, defaulter) {
        ComponentModel.registerSubTypeDefaulter(componentType, defaulter);
      },
      registerPainter: function (painterType, PainterCtor) {
        registerPainter(painterType, PainterCtor);
      }
    };
    function use(ext) {
      if (isArray(ext)) {
        // use([ChartLine, ChartBar]);
        each(ext, function (singleExt) {
          use(singleExt);
        });
        return;
      }

      if (indexOf(extensions, ext) >= 0) {
        return;
      }

      extensions.push(ext);

      if (isFunction(ext)) {
        ext = {
          install: ext
        };
      }

      ext.install(extensionRegisters);
    }

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


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * 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 dataIndexMapValueLength(valNumOrArrLengthMoreThan2) {
      return valNumOrArrLengthMoreThan2 == null ? 0 : valNumOrArrLengthMoreThan2.length || 1;
    }

    function defaultKeyGetter(item) {
      return item;
    }

    var DataDiffer =
    /** @class */
    function () {
      /**
       * @param context Can be visited by this.context in callback.
       */
      function DataDiffer(oldArr, newArr, oldKeyGetter, newKeyGetter, context, // By default: 'oneToOne'.
      diffMode) {
        this._old = oldArr;
        this._new = newArr;
        this._oldKeyGetter = oldKeyGetter || defaultKeyGetter;
        this._newKeyGetter = newKeyGetter || defaultKeyGetter; // Visible in callback via `this.context`;

        this.context = context;
        this._diffModeMultiple = diffMode === 'multiple';
      }
      /**
       * Callback function when add a data
       */


      DataDiffer.prototype.add = function (func) {
        this._add = func;
        return this;
      };
      /**
       * Callback function when update a data
       */


      DataDiffer.prototype.update = function (func) {
        this._update = func;
        return this;
      };
      /**
       * Callback function when update a data and only work in `cbMode: 'byKey'`.
       */


      DataDiffer.prototype.updateManyToOne = function (func) {
        this._updateManyToOne = func;
        return this;
      };
      /**
       * Callback function when update a data and only work in `cbMode: 'byKey'`.
       */


      DataDiffer.prototype.updateOneToMany = function (func) {
        this._updateOneToMany = func;
        return this;
      };
      /**
       * Callback function when update a data and only work in `cbMode: 'byKey'`.
       */


      DataDiffer.prototype.updateManyToMany = function (func) {
        this._updateManyToMany = func;
        return this;
      };
      /**
       * Callback function when remove a data
       */


      DataDiffer.prototype.remove = function (func) {
        this._remove = func;
        return this;
      };

      DataDiffer.prototype.execute = function () {
        this[this._diffModeMultiple ? '_executeMultiple' : '_executeOneToOne']();
      };

      DataDiffer.prototype._executeOneToOne = function () {
        var oldArr = this._old;
        var newArr = this._new;
        var newDataIndexMap = {};
        var oldDataKeyArr = new Array(oldArr.length);
        var newDataKeyArr = new Array(newArr.length);

        this._initIndexMap(oldArr, null, oldDataKeyArr, '_oldKeyGetter');

        this._initIndexMap(newArr, newDataIndexMap, newDataKeyArr, '_newKeyGetter');

        for (var i = 0; i < oldArr.length; i++) {
          var oldKey = oldDataKeyArr[i];
          var newIdxMapVal = newDataIndexMap[oldKey];
          var newIdxMapValLen = dataIndexMapValueLength(newIdxMapVal); // idx can never be empty array here. see 'set null' logic below.

          if (newIdxMapValLen > 1) {
            // 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 newIdx = newIdxMapVal.shift();

            if (newIdxMapVal.length === 1) {
              newDataIndexMap[oldKey] = newIdxMapVal[0];
            }

            this._update && this._update(newIdx, i);
          } else if (newIdxMapValLen === 1) {
            newDataIndexMap[oldKey] = null;
            this._update && this._update(newIdxMapVal, i);
          } else {
            this._remove && this._remove(i);
          }
        }

        this._performRestAdd(newDataKeyArr, newDataIndexMap);
      };
      /**
       * For example, consider the case:
       * oldData: [o0, o1, o2, o3, o4, o5, o6, o7],
       * newData: [n0, n1, n2, n3, n4, n5, n6, n7, n8],
       * Where:
       *     o0, o1, n0 has key 'a' (many to one)
       *     o5, n4, n5, n6 has key 'b' (one to many)
       *     o2, n1 has key 'c' (one to one)
       *     n2, n3 has key 'd' (add)
       *     o3, o4 has key 'e' (remove)
       *     o6, o7, n7, n8 has key 'f' (many to many, treated as add and remove)
       * Then:
       *     (The order of the following directives are not ensured.)
       *     this._updateManyToOne(n0, [o0, o1]);
       *     this._updateOneToMany([n4, n5, n6], o5);
       *     this._update(n1, o2);
       *     this._remove(o3);
       *     this._remove(o4);
       *     this._remove(o6);
       *     this._remove(o7);
       *     this._add(n2);
       *     this._add(n3);
       *     this._add(n7);
       *     this._add(n8);
       */


      DataDiffer.prototype._executeMultiple = function () {
        var oldArr = this._old;
        var newArr = this._new;
        var oldDataIndexMap = {};
        var newDataIndexMap = {};
        var oldDataKeyArr = [];
        var newDataKeyArr = [];

        this._initIndexMap(oldArr, oldDataIndexMap, oldDataKeyArr, '_oldKeyGetter');

        this._initIndexMap(newArr, newDataIndexMap, newDataKeyArr, '_newKeyGetter');

        for (var i = 0; i < oldDataKeyArr.length; i++) {
          var oldKey = oldDataKeyArr[i];
          var oldIdxMapVal = oldDataIndexMap[oldKey];
          var newIdxMapVal = newDataIndexMap[oldKey];
          var oldIdxMapValLen = dataIndexMapValueLength(oldIdxMapVal);
          var newIdxMapValLen = dataIndexMapValueLength(newIdxMapVal);

          if (oldIdxMapValLen > 1 && newIdxMapValLen === 1) {
            this._updateManyToOne && this._updateManyToOne(newIdxMapVal, oldIdxMapVal);
            newDataIndexMap[oldKey] = null;
          } else if (oldIdxMapValLen === 1 && newIdxMapValLen > 1) {
            this._updateOneToMany && this._updateOneToMany(newIdxMapVal, oldIdxMapVal);
            newDataIndexMap[oldKey] = null;
          } else if (oldIdxMapValLen === 1 && newIdxMapValLen === 1) {
            this._update && this._update(newIdxMapVal, oldIdxMapVal);
            newDataIndexMap[oldKey] = null;
          } else if (oldIdxMapValLen > 1 && newIdxMapValLen > 1) {
            this._updateManyToMany && this._updateManyToMany(newIdxMapVal, oldIdxMapVal);
            newDataIndexMap[oldKey] = null;
          } else if (oldIdxMapValLen > 1) {
            for (var i_1 = 0; i_1 < oldIdxMapValLen; i_1++) {
              this._remove && this._remove(oldIdxMapVal[i_1]);
            }
          } else {
            this._remove && this._remove(oldIdxMapVal);
          }
        }

        this._performRestAdd(newDataKeyArr, newDataIndexMap);
      };

      DataDiffer.prototype._performRestAdd = function (newDataKeyArr, newDataIndexMap) {
        for (var i = 0; i < newDataKeyArr.length; i++) {
          var newKey = newDataKeyArr[i];
          var newIdxMapVal = newDataIndexMap[newKey];
          var idxMapValLen = dataIndexMapValueLength(newIdxMapVal);

          if (idxMapValLen > 1) {
            for (var j = 0; j < idxMapValLen; j++) {
              this._add && this._add(newIdxMapVal[j]);
            }
          } else if (idxMapValLen === 1) {
            this._add && this._add(newIdxMapVal);
          } // Support both `newDataKeyArr` are duplication removed or not removed.


          newDataIndexMap[newKey] = null;
        }
      };

      DataDiffer.prototype._initIndexMap = function (arr, // Can be null.
      map, // In 'byKey', the output `keyArr` is duplication removed.
      // In 'byIndex', the output `keyArr` is not duplication removed and
      //     its indices are accurately corresponding to `arr`.
      keyArr, keyGetterName) {
        var cbModeMultiple = this._diffModeMultiple;

        for (var i = 0; i < arr.length; i++) {
          // Add prefix to avoid conflict with Object.prototype.
          var key = '_ec_' + this[keyGetterName](arr[i], i);

          if (!cbModeMultiple) {
            keyArr[i] = key;
          }

          if (!map) {
            continue;
          }

          var idxMapVal = map[key];
          var idxMapValLen = dataIndexMapValueLength(idxMapVal);

          if (idxMapValLen === 0) {
            // Simple optimize: in most cases, one index has one key,
            // do not need array.
            map[key] = i;

            if (cbModeMultiple) {
              keyArr.push(key);
            }
          } else if (idxMapValLen === 1) {
            map[key] = [idxMapVal, i];
          } else {
            idxMapVal.push(i);
          }
        }
      };

      return DataDiffer;
    }();

    var DimensionUserOuput =
    /** @class */
    function () {
      function DimensionUserOuput(encode, dimRequest) {
        this._encode = encode;
        this._schema = dimRequest;
      }

      DimensionUserOuput.prototype.get = function () {
        return {
          // Do not generate full dimension name until fist used.
          fullDimensions: this._getFullDimensionNames(),
          encode: this._encode
        };
      };
      /**
       * Get all data store dimension names.
       * Theoretically a series data store is defined both by series and used dataset (if any).
       * If some dimensions are omitted for performance reason in `this.dimensions`,
       * the dimension name may not be auto-generated if user does not specify a dimension name.
       * In this case, the dimension name is `null`/`undefined`.
       */


      DimensionUserOuput.prototype._getFullDimensionNames = function () {
        if (!this._cachedDimNames) {
          this._cachedDimNames = this._schema ? this._schema.makeOutputDimensionNames() : [];
        }

        return this._cachedDimNames;
      };

      return DimensionUserOuput;
    }();
    function summarizeDimensions(data, schema) {
      var summary = {};
      var encode = summary.encode = {};
      var notExtraCoordDimMap = createHashMap();
      var defaultedLabel = [];
      var defaultedTooltip = [];
      var userOutputEncode = {};
      each(data.dimensions, function (dimName) {
        var dimItem = data.getDimensionInfo(dimName);
        var coordDim = dimItem.coordDim;

        if (coordDim) {
          if ("development" !== 'production') {
            assert(VISUAL_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(userOutputEncode, coordDim)[coordDimIndex] = data.getDimensionIndex(dimItem.name);
          }

          if (dimItem.defaultTooltip) {
            defaultedTooltip.push(dimName);
          }
        }

        VISUAL_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];
        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.dataDimIndicesOnCoord = map(dataDimsOnCoord, function (dimName) {
        return data.getDimensionInfo(dimName).storeDimIndex;
      });
      summary.encodeFirstDimNotExtra = encodeFirstDimNotExtra;
      var encodeLabel = encode.label; // FIXME `encode.label` is not recommended, because formatter cannot be set
      // in this way. Use label.formatter instead. Maybe 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;
      summary.userOutput = new DimensionUserOuput(userOutputEncode, schema);
      return summary;
    }

    function getOrCreateEncodeArr(encode, dim) {
      if (!encode.hasOwnProperty(dim)) {
        encode[dim] = [];
      }

      return encode[dim];
    } // FIXME:TS should be type `AxisType`


    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
    //     let dimensions = data.dimensions.slice();
    //     let valueType;
    //     let valueDim;
    //     while (dimensions.length && (
    //         valueDim = dimensions.pop(),
    //         valueType = data.getDimensionInfo(valueDim).type,
    //         valueType === 'ordinal' || valueType === 'time'
    //     )) {} // jshint ignore:line
    //     return valueDim;
    // }

    var SeriesDimensionDefine =
    /** @class */
    function () {
      /**
       * @param opt All of the fields will be shallow copied.
       */
      function SeriesDimensionDefine(opt) {
        /**
         * The format of `otherDims` is:
         * ```js
         * {
         *     tooltip?: number
         *     label?: number
         *     itemName?: number
         *     seriesName?: number
         * }
         * ```
         *
         * 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.label`
         *     label: 1
         * };
         * ```
         *
         * This prop should never be `null`/`undefined` after initialized.
         */
        this.otherDims = {};

        if (opt != null) {
          extend(this, opt);
        }
      }

      return SeriesDimensionDefine;
    }();

    var inner$4 = makeInner();
    var dimTypeShort = {
      float: 'f',
      int: 'i',
      ordinal: 'o',
      number: 'n',
      time: 't'
    };
    /**
     * Represents the dimension requirement of a series.
     *
     * NOTICE:
     * When there are too many dimensions in dataset and many series, only the used dimensions
     * (i.e., used by coord sys and declared in `series.encode`) are add to `dimensionDefineList`.
     * But users may query data by other unused dimension names.
     * In this case, users can only query data if and only if they have defined dimension names
     * via ec option, so we provide `getDimensionIndexFromSource`, which only query them from
     * `source` dimensions.
     */

    var SeriesDataSchema =
    /** @class */
    function () {
      function SeriesDataSchema(opt) {
        this.dimensions = opt.dimensions;
        this._dimOmitted = opt.dimensionOmitted;
        this.source = opt.source;
        this._fullDimCount = opt.fullDimensionCount;

        this._updateDimOmitted(opt.dimensionOmitted);
      }

      SeriesDataSchema.prototype.isDimensionOmitted = function () {
        return this._dimOmitted;
      };

      SeriesDataSchema.prototype._updateDimOmitted = function (dimensionOmitted) {
        this._dimOmitted = dimensionOmitted;

        if (!dimensionOmitted) {
          return;
        }

        if (!this._dimNameMap) {
          this._dimNameMap = ensureSourceDimNameMap(this.source);
        }
      };
      /**
       * @caution Can only be used when `dimensionOmitted: true`.
       *
       * Get index by user defined dimension name (i.e., not internal generate name).
       * That is, get index from `dimensionsDefine`.
       * If no `dimensionsDefine`, or no name get, return -1.
       */


      SeriesDataSchema.prototype.getSourceDimensionIndex = function (dimName) {
        return retrieve2(this._dimNameMap.get(dimName), -1);
      };
      /**
       * @caution Can only be used when `dimensionOmitted: true`.
       *
       * Notice: may return `null`/`undefined` if user not specify dimension names.
       */


      SeriesDataSchema.prototype.getSourceDimension = function (dimIndex) {
        var dimensionsDefine = this.source.dimensionsDefine;

        if (dimensionsDefine) {
          return dimensionsDefine[dimIndex];
        }
      };

      SeriesDataSchema.prototype.makeStoreSchema = function () {
        var dimCount = this._fullDimCount;
        var willRetrieveDataByName = shouldRetrieveDataByName(this.source);
        var makeHashStrict = !shouldOmitUnusedDimensions(dimCount); // If source don't have dimensions or series don't omit unsed dimensions.
        // Generate from seriesDimList directly

        var dimHash = '';
        var dims = [];

        for (var fullDimIdx = 0, seriesDimIdx = 0; fullDimIdx < dimCount; fullDimIdx++) {
          var property = void 0;
          var type = void 0;
          var ordinalMeta = void 0;
          var seriesDimDef = this.dimensions[seriesDimIdx]; // The list has been sorted by `storeDimIndex` asc.

          if (seriesDimDef && seriesDimDef.storeDimIndex === fullDimIdx) {
            property = willRetrieveDataByName ? seriesDimDef.name : null;
            type = seriesDimDef.type;
            ordinalMeta = seriesDimDef.ordinalMeta;
            seriesDimIdx++;
          } else {
            var sourceDimDef = this.getSourceDimension(fullDimIdx);

            if (sourceDimDef) {
              property = willRetrieveDataByName ? sourceDimDef.name : null;
              type = sourceDimDef.type;
            }
          }

          dims.push({
            property: property,
            type: type,
            ordinalMeta: ordinalMeta
          }); // If retrieving data by index,
          //   use <index, type, ordinalMeta> to determine whether data can be shared.
          //   (Because in this case there might be no dimension name defined in dataset, but indices always exists).
          //   (Indices are always 0, 1, 2, ..., so we can ignore them to shorten the hash).
          // Otherwise if retrieving data by property name (like `data: [{aa: 123, bb: 765}, ...]`),
          //   use <property, type, ordinalMeta> in hash.

          if (willRetrieveDataByName && property != null // For data stack, we have make sure each series has its own dim on this store.
          // So we do not add property to hash to make sure they can share this store.
          && (!seriesDimDef || !seriesDimDef.isCalculationCoord)) {
            dimHash += makeHashStrict // Use escape character '`' in case that property name contains '$'.
            ? property.replace(/\`/g, '`1').replace(/\$/g, '`2') // For better performance, when there are large dimensions, tolerant this defects that hardly meet.
            : property;
          }

          dimHash += '$';
          dimHash += dimTypeShort[type] || 'f';

          if (ordinalMeta) {
            dimHash += ordinalMeta.uid;
          }

          dimHash += '$';
        } // Source from endpoint(usually series) will be read differently
        // when seriesLayoutBy or startIndex(which is affected by sourceHeader) are different.
        // So we use this three props as key.


        var source = this.source;
        var hash = [source.seriesLayoutBy, source.startIndex, dimHash].join('$$');
        return {
          dimensions: dims,
          hash: hash
        };
      };

      SeriesDataSchema.prototype.makeOutputDimensionNames = function () {
        var result = [];

        for (var fullDimIdx = 0, seriesDimIdx = 0; fullDimIdx < this._fullDimCount; fullDimIdx++) {
          var name_1 = void 0;
          var seriesDimDef = this.dimensions[seriesDimIdx]; // The list has been sorted by `storeDimIndex` asc.

          if (seriesDimDef && seriesDimDef.storeDimIndex === fullDimIdx) {
            if (!seriesDimDef.isCalculationCoord) {
              name_1 = seriesDimDef.name;
            }

            seriesDimIdx++;
          } else {
            var sourceDimDef = this.getSourceDimension(fullDimIdx);

            if (sourceDimDef) {
              name_1 = sourceDimDef.name;
            }
          }

          result.push(name_1);
        }

        return result;
      };

      SeriesDataSchema.prototype.appendCalculationDimension = function (dimDef) {
        this.dimensions.push(dimDef);
        dimDef.isCalculationCoord = true;
        this._fullDimCount++; // If append dimension on a data store, consider the store
        // might be shared by different series, series dimensions not
        // really map to store dimensions.

        this._updateDimOmitted(true);
      };

      return SeriesDataSchema;
    }();
    function isSeriesDataSchema(schema) {
      return schema instanceof SeriesDataSchema;
    }
    function createDimNameMap(dimsDef) {
      var dataDimNameMap = createHashMap();

      for (var i = 0; i < (dimsDef || []).length; i++) {
        var dimDefItemRaw = dimsDef[i];
        var userDimName = isObject(dimDefItemRaw) ? dimDefItemRaw.name : dimDefItemRaw;

        if (userDimName != null && dataDimNameMap.get(userDimName) == null) {
          dataDimNameMap.set(userDimName, i);
        }
      }

      return dataDimNameMap;
    }
    function ensureSourceDimNameMap(source) {
      var innerSource = inner$4(source);
      return innerSource.dimNameMap || (innerSource.dimNameMap = createDimNameMap(source.dimensionsDefine));
    }
    function shouldOmitUnusedDimensions(dimCount) {
      return dimCount > 30;
    }

    var isObject$2 = isObject;
    var map$1 = map;
    var CtorInt32Array$1 = typeof Int32Array === 'undefined' ? Array : Int32Array; // Use prefix to avoid index to be the same as otherIdList[idx],
    // which will cause weird update animation.

    var ID_PREFIX = 'e\0\0';
    var INDEX_NOT_FOUND = -1; // type SeriesDimensionIndex = DimensionIndex;

    var TRANSFERABLE_PROPERTIES = ['hasItemOption', '_nameList', '_idList', '_invertedIndicesMap', '_dimSummary', 'userOutput', '_rawData', '_dimValueGetter', '_nameDimIdx', '_idDimIdx', '_nameRepeatCount'];
    var CLONE_PROPERTIES = ['_approximateExtent']; // -----------------------------
    // Internal method declarations:
    // -----------------------------

    var prepareInvertedIndex;
    var getId;
    var getIdNameFromStore;
    var normalizeDimensions;
    var transferProperties;
    var cloneListForMapAndSample;
    var makeIdFromName;

    var SeriesData =
    /** @class */
    function () {
      /**
       * @param dimensionsInput.dimensions
       *        For example, ['someDimName', {name: 'someDimName', type: 'someDimType'}, ...].
       *        Dimensions should be concrete names like x, y, z, lng, lat, angle, radius
       */
      function SeriesData(dimensionsInput, hostModel) {
        this.type = 'list';
        this._dimOmitted = false;
        this._nameList = [];
        this._idList = []; // Models of data option is stored sparse for optimizing memory cost
        // Never used yet (not used yet).
        // private _optionModels: Model[] = [];
        // Global visual properties after visual coding

        this._visual = {}; // Global layout properties.

        this._layout = {}; // Item visual properties after visual coding

        this._itemVisuals = []; // Item layout properties after layout

        this._itemLayouts = []; // Graphic elements

        this._graphicEls = []; // key: dim, value: extent

        this._approximateExtent = {};
        this._calculationInfo = {}; // Having detected that there is data item is non primitive type
        // (in type `OptionDataItemObject`).
        // Like `data: [ { value: xx, itemStyle: {...} }, ...]`
        // At present it only happen in `SOURCE_FORMAT_ORIGINAL`.

        this.hasItemOption = false; // Methods that create a new list based on this list should be listed here.
        // Notice that those method should `RETURN` the new list.

        this.TRANSFERABLE_METHODS = ['cloneShallow', 'downSample', 'lttbDownSample', 'map']; // Methods that change indices of this list should be listed here.

        this.CHANGABLE_METHODS = ['filterSelf', 'selectRange'];
        this.DOWNSAMPLE_METHODS = ['downSample', 'lttbDownSample'];
        var dimensions;
        var assignStoreDimIdx = false;

        if (isSeriesDataSchema(dimensionsInput)) {
          dimensions = dimensionsInput.dimensions;
          this._dimOmitted = dimensionsInput.isDimensionOmitted();
          this._schema = dimensionsInput;
        } else {
          assignStoreDimIdx = true;
          dimensions = dimensionsInput;
        }

        dimensions = dimensions || ['x', 'y'];
        var dimensionInfos = {};
        var dimensionNames = [];
        var invertedIndicesMap = {};
        var needsHasOwn = false;
        var emptyObj = {};

        for (var i = 0; i < dimensions.length; i++) {
          // Use the original dimensions[i], where other flag props may exists.
          var dimInfoInput = dimensions[i];
          var dimensionInfo = isString(dimInfoInput) ? new SeriesDimensionDefine({
            name: dimInfoInput
          }) : !(dimInfoInput instanceof SeriesDimensionDefine) ? new SeriesDimensionDefine(dimInfoInput) : dimInfoInput;
          var dimensionName = dimensionInfo.name;
          dimensionInfo.type = dimensionInfo.type || 'float';

          if (!dimensionInfo.coordDim) {
            dimensionInfo.coordDim = dimensionName;
            dimensionInfo.coordDimIndex = 0;
          }

          var otherDims = dimensionInfo.otherDims = dimensionInfo.otherDims || {};
          dimensionNames.push(dimensionName);
          dimensionInfos[dimensionName] = dimensionInfo;

          if (emptyObj[dimensionName] != null) {
            needsHasOwn = true;
          }

          if (dimensionInfo.createInvertedIndices) {
            invertedIndicesMap[dimensionName] = [];
          }

          if (otherDims.itemName === 0) {
            this._nameDimIdx = i;
          }

          if (otherDims.itemId === 0) {
            this._idDimIdx = i;
          }

          if ("development" !== 'production') {
            assert(assignStoreDimIdx || dimensionInfo.storeDimIndex >= 0);
          }

          if (assignStoreDimIdx) {
            dimensionInfo.storeDimIndex = i;
          }
        }

        this.dimensions = dimensionNames;
        this._dimInfos = dimensionInfos;

        this._initGetDimensionInfo(needsHasOwn);

        this.hostModel = hostModel;
        this._invertedIndicesMap = invertedIndicesMap;

        if (this._dimOmitted) {
          var dimIdxToName_1 = this._dimIdxToName = createHashMap();
          each(dimensionNames, function (dimName) {
            dimIdxToName_1.set(dimensionInfos[dimName].storeDimIndex, dimName);
          });
        }
      }
      /**
       *
       * Get concrete dimension name by dimension name or dimension index.
       * If input a dimension name, do not validate whether the dimension name exits.
       *
       * @caution
       * @param dim Must make sure the dimension is `SeriesDimensionLoose`.
       * Because only those dimensions will have auto-generated dimension names if not
       * have a user-specified name, and other dimensions will get a return of null/undefined.
       *
       * @notice Because of this reason, should better use `getDimensionIndex` instead, for examples:
       * ```js
       * const val = data.getStore().get(data.getDimensionIndex(dim), dataIdx);
       * ```
       *
       * @return Concrete dim name.
       */


      SeriesData.prototype.getDimension = function (dim) {
        var dimIdx = this._recognizeDimIndex(dim);

        if (dimIdx == null) {
          return dim;
        }

        dimIdx = dim;

        if (!this._dimOmitted) {
          return this.dimensions[dimIdx];
        } // Retrieve from series dimension definition because it probably contains
        // generated dimension name (like 'x', 'y').


        var dimName = this._dimIdxToName.get(dimIdx);

        if (dimName != null) {
          return dimName;
        }

        var sourceDimDef = this._schema.getSourceDimension(dimIdx);

        if (sourceDimDef) {
          return sourceDimDef.name;
        }
      };
      /**
       * Get dimension index in data store. Return -1 if not found.
       * Can be used to index value from getRawValue.
       */


      SeriesData.prototype.getDimensionIndex = function (dim) {
        var dimIdx = this._recognizeDimIndex(dim);

        if (dimIdx != null) {
          return dimIdx;
        }

        if (dim == null) {
          return -1;
        }

        var dimInfo = this._getDimInfo(dim);

        return dimInfo ? dimInfo.storeDimIndex : this._dimOmitted ? this._schema.getSourceDimensionIndex(dim) : -1;
      };
      /**
       * 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 `series.dimensions` or `dataset.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 compatibility. 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"`.
       *
       * @return recognized `DimensionIndex`. Otherwise return null/undefined (means that dim is `DimensionName`).
       */


      SeriesData.prototype._recognizeDimIndex = function (dim) {
        if (isNumber(dim) // If being a number-like string but not being defined as a dimension name.
        || dim != null && !isNaN(dim) && !this._getDimInfo(dim) && (!this._dimOmitted || this._schema.getSourceDimensionIndex(dim) < 0)) {
          return +dim;
        }
      };

      SeriesData.prototype._getStoreDimIndex = function (dim) {
        var dimIdx = this.getDimensionIndex(dim);

        if ("development" !== 'production') {
          if (dimIdx == null) {
            throw new Error('Unknown dimension ' + dim);
          }
        }

        return dimIdx;
      };
      /**
       * Get type and calculation info of particular dimension
       * @param 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'
       */


      SeriesData.prototype.getDimensionInfo = function (dim) {
        // Do not clone, because there may be categories in dimInfo.
        return this._getDimInfo(this.getDimension(dim));
      };

      SeriesData.prototype._initGetDimensionInfo = function (needsHasOwn) {
        var dimensionInfos = this._dimInfos;
        this._getDimInfo = needsHasOwn ? function (dimName) {
          return dimensionInfos.hasOwnProperty(dimName) ? dimensionInfos[dimName] : undefined;
        } : function (dimName) {
          return dimensionInfos[dimName];
        };
      };
      /**
       * concrete dimension name list on coord.
       */


      SeriesData.prototype.getDimensionsOnCoord = function () {
        return this._dimSummary.dataDimsOnCoord.slice();
      };

      SeriesData.prototype.mapDimension = function (coordDim, idx) {
        var dimensionsSummary = this._dimSummary;

        if (idx == null) {
          return dimensionsSummary.encodeFirstDimNotExtra[coordDim];
        }

        var dims = dimensionsSummary.encode[coordDim];
        return dims ? dims[idx] : null;
      };

      SeriesData.prototype.mapDimensionsAll = function (coordDim) {
        var dimensionsSummary = this._dimSummary;
        var dims = dimensionsSummary.encode[coordDim];
        return (dims || []).slice();
      };

      SeriesData.prototype.getStore = function () {
        return this._store;
      };
      /**
       * Initialize from data
       * @param data source or data or data store.
       * @param 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.
       */


      SeriesData.prototype.initData = function (data, nameList, dimValueGetter) {
        var _this = this;

        var store;

        if (data instanceof DataStore) {
          store = data;
        }

        if (!store) {
          var dimensions = this.dimensions;
          var provider = isSourceInstance(data) || isArrayLike(data) ? new DefaultDataProvider(data, dimensions.length) : data;
          store = new DataStore();
          var dimensionInfos = map$1(dimensions, function (dimName) {
            return {
              type: _this._dimInfos[dimName].type,
              property: dimName
            };
          });
          store.initData(provider, dimensionInfos, dimValueGetter);
        }

        this._store = store; // Reset

        this._nameList = (nameList || []).slice();
        this._idList = [];
        this._nameRepeatCount = {};

        this._doInit(0, store.count()); // Cache summary info for fast visit. See "dimensionHelper".
        // Needs to be initialized after store is prepared.


        this._dimSummary = summarizeDimensions(this, this._schema);
        this.userOutput = this._dimSummary.userOutput;
      };
      /**
       * Caution: Can be only called on raw data (before `this._indices` created).
       */


      SeriesData.prototype.appendData = function (data) {
        var range = this._store.appendData(data);

        this._doInit(range[0], range[1]);
      };
      /**
       * Caution: Can be only called on raw data (before `this._indices` created).
       * This method does not modify `rawData` (`dataProvider`), but only
       * add values to store.
       *
       * The final count will be increased by `Math.max(values.length, names.length)`.
       *
       * @param values That is the SourceType: 'arrayRows', like
       *        [
       *            [12, 33, 44],
       *            [NaN, 43, 1],
       *            ['-', 'asdf', 0]
       *        ]
       *        Each item is exactly corresponding to a dimension.
       */


      SeriesData.prototype.appendValues = function (values, names) {
        var _a = this._store.appendValues(values, names.length),
            start = _a.start,
            end = _a.end;

        var shouldMakeIdFromName = this._shouldMakeIdFromName();

        this._updateOrdinalMeta();

        if (names) {
          for (var idx = start; idx < end; idx++) {
            var sourceIdx = idx - start;
            this._nameList[idx] = names[sourceIdx];

            if (shouldMakeIdFromName) {
              makeIdFromName(this, idx);
            }
          }
        }
      };

      SeriesData.prototype._updateOrdinalMeta = function () {
        var store = this._store;
        var dimensions = this.dimensions;

        for (var i = 0; i < dimensions.length; i++) {
          var dimInfo = this._dimInfos[dimensions[i]];

          if (dimInfo.ordinalMeta) {
            store.collectOrdinalMeta(dimInfo.storeDimIndex, dimInfo.ordinalMeta);
          }
        }
      };

      SeriesData.prototype._shouldMakeIdFromName = function () {
        var provider = this._store.getProvider();

        return this._idDimIdx == null && provider.getSource().sourceFormat !== SOURCE_FORMAT_TYPED_ARRAY && !provider.fillStorage;
      };

      SeriesData.prototype._doInit = function (start, end) {
        if (start >= end) {
          return;
        }

        var store = this._store;
        var provider = store.getProvider();

        this._updateOrdinalMeta();

        var nameList = this._nameList;
        var idList = this._idList;
        var sourceFormat = provider.getSource().sourceFormat;
        var isFormatOriginal = sourceFormat === SOURCE_FORMAT_ORIGINAL; // 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
        // If dataItem is {name: ...} or {id: ...}, it has highest priority.
        // This kind of ids and names are always stored `_nameList` and `_idList`.

        if (isFormatOriginal && !provider.pure) {
          var sharedDataItem = [];

          for (var idx = start; idx < end; idx++) {
            // NOTICE: Try not to write things into dataItem
            var dataItem = provider.getItem(idx, sharedDataItem);

            if (!this.hasItemOption && isDataItemOption(dataItem)) {
              this.hasItemOption = true;
            }

            if (dataItem) {
              var itemName = dataItem.name;

              if (nameList[idx] == null && itemName != null) {
                nameList[idx] = convertOptionIdName(itemName, null);
              }

              var itemId = dataItem.id;

              if (idList[idx] == null && itemId != null) {
                idList[idx] = convertOptionIdName(itemId, null);
              }
            }
          }
        }

        if (this._shouldMakeIdFromName()) {
          for (var idx = start; idx < end; idx++) {
            makeIdFromName(this, idx);
          }
        }

        prepareInvertedIndex(this);
      };
      /**
       * PENDING: In fact currently this function is only used to short-circuit
       * the calling of `scale.unionExtentFromData` when data have been filtered by modules
       * like "dataZoom". `scale.unionExtentFromData` is used to calculate data extent for series on
       * an axis, but if a "axis related data filter module" is used, the extent of the axis have
       * been fixed and no need to calling `scale.unionExtentFromData` actually.
       * But if we add "custom data filter" in future, which is not "axis related", this method may
       * be still needed.
       *
       * 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.
       */


      SeriesData.prototype.getApproximateExtent = function (dim) {
        return this._approximateExtent[dim] || this._store.getDataExtent(this._getStoreDimIndex(dim));
      };
      /**
       * Calculate extent on a filtered data might be time consuming.
       * Approximate extent is only used for: calculate extent of filtered data outside.
       */


      SeriesData.prototype.setApproximateExtent = function (extent, dim) {
        dim = this.getDimension(dim);
        this._approximateExtent[dim] = extent.slice();
      };

      SeriesData.prototype.getCalculationInfo = function (key) {
        return this._calculationInfo[key];
      };

      SeriesData.prototype.setCalculationInfo = function (key, value) {
        isObject$2(key) ? extend(this._calculationInfo, key) : this._calculationInfo[key] = value;
      };
      /**
       * @return Never be null/undefined. `number` will be converted to string. Because:
       * In most cases, name is used in display, where returning a string is more convenient.
       * In other cases, name is used in query (see `indexOfName`), where we can keep the
       * rule that name `2` equals to name `'2'`.
       */


      SeriesData.prototype.getName = function (idx) {
        var rawIndex = this.getRawIndex(idx);
        var name = this._nameList[rawIndex];

        if (name == null && this._nameDimIdx != null) {
          name = getIdNameFromStore(this, this._nameDimIdx, rawIndex);
        }

        if (name == null) {
          name = '';
        }

        return name;
      };

      SeriesData.prototype._getCategory = function (dimIdx, idx) {
        var ordinal = this._store.get(dimIdx, idx);

        var ordinalMeta = this._store.getOrdinalMeta(dimIdx);

        if (ordinalMeta) {
          return ordinalMeta.categories[ordinal];
        }

        return ordinal;
      };
      /**
       * @return Never null/undefined. `number` will be converted to string. Because:
       * In all cases having encountered at present, id is used in making diff comparison, which
       * are usually based on hash map. We can keep the rule that the internal id are always string
       * (treat `2` is the same as `'2'`) to make the related logic simple.
       */


      SeriesData.prototype.getId = function (idx) {
        return getId(this, this.getRawIndex(idx));
      };

      SeriesData.prototype.count = function () {
        return this._store.count();
      };
      /**
       * Get value. Return NaN if idx is out of range.
       *
       * @notice Should better to use `data.getStore().get(dimIndex, dataIdx)` instead.
       */


      SeriesData.prototype.get = function (dim, idx) {
        var store = this._store;
        var dimInfo = this._dimInfos[dim];

        if (dimInfo) {
          return store.get(dimInfo.storeDimIndex, idx);
        }
      };
      /**
       * @notice Should better to use `data.getStore().getByRawIndex(dimIndex, dataIdx)` instead.
       */


      SeriesData.prototype.getByRawIndex = function (dim, rawIdx) {
        var store = this._store;
        var dimInfo = this._dimInfos[dim];

        if (dimInfo) {
          return store.getByRawIndex(dimInfo.storeDimIndex, rawIdx);
        }
      };

      SeriesData.prototype.getIndices = function () {
        return this._store.getIndices();
      };

      SeriesData.prototype.getDataExtent = function (dim) {
        return this._store.getDataExtent(this._getStoreDimIndex(dim));
      };

      SeriesData.prototype.getSum = function (dim) {
        return this._store.getSum(this._getStoreDimIndex(dim));
      };

      SeriesData.prototype.getMedian = function (dim) {
        return this._store.getMedian(this._getStoreDimIndex(dim));
      };

      SeriesData.prototype.getValues = function (dimensions, idx) {
        var _this = this;

        var store = this._store;
        return isArray(dimensions) ? store.getValues(map$1(dimensions, function (dim) {
          return _this._getStoreDimIndex(dim);
        }), idx) : store.getValues(dimensions);
      };
      /**
       * If value is NaN. Including '-'
       * Only check the coord dimensions.
       */


      SeriesData.prototype.hasValue = function (idx) {
        var dataDimIndicesOnCoord = this._dimSummary.dataDimIndicesOnCoord;

        for (var i = 0, len = dataDimIndicesOnCoord.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._store.get(dataDimIndicesOnCoord[i], idx))) {
            return false;
          }
        }

        return true;
      };
      /**
       * Retrieve the index with given name
       */


      SeriesData.prototype.indexOfName = function (name) {
        for (var i = 0, len = this._store.count(); i < len; i++) {
          if (this.getName(i) === name) {
            return i;
          }
        }

        return -1;
      };

      SeriesData.prototype.getRawIndex = function (idx) {
        return this._store.getRawIndex(idx);
      };

      SeriesData.prototype.indexOfRawIndex = function (rawIndex) {
        return this._store.indexOfRawIndex(rawIndex);
      };
      /**
       * Only support the dimension which inverted index created.
       * Do not support other cases until required.
       * @param dim concrete dim
       * @param value ordinal index
       * @return rawIndex
       */


      SeriesData.prototype.rawIndexOf = function (dim, value) {
        var invertedIndices = dim && this._invertedIndicesMap[dim];

        if ("development" !== 'production') {
          if (!invertedIndices) {
            throw new Error('Do not supported yet');
          }
        }

        var rawIndex = invertedIndices[value];

        if (rawIndex == null || isNaN(rawIndex)) {
          return INDEX_NOT_FOUND;
        }

        return rawIndex;
      };
      /**
       * Retrieve the index of nearest value
       * @param dim
       * @param value
       * @param [maxDistance=Infinity]
       * @return If and only if multiple indices has
       *         the same value, they are put to the result.
       */


      SeriesData.prototype.indicesOfNearest = function (dim, value, maxDistance) {
        return this._store.indicesOfNearest(this._getStoreDimIndex(dim), value, maxDistance);
      };

      SeriesData.prototype.each = function (dims, cb, ctx) {

        if (isFunction(dims)) {
          ctx = cb;
          cb = dims;
          dims = [];
        } // ctxCompat just for compat echarts3


        var fCtx = ctx || this;
        var dimIndices = map$1(normalizeDimensions(dims), this._getStoreDimIndex, this);

        this._store.each(dimIndices, fCtx ? bind(cb, fCtx) : cb);
      };

      SeriesData.prototype.filterSelf = function (dims, cb, ctx) {

        if (isFunction(dims)) {
          ctx = cb;
          cb = dims;
          dims = [];
        } // ctxCompat just for compat echarts3


        var fCtx = ctx || this;
        var dimIndices = map$1(normalizeDimensions(dims), this._getStoreDimIndex, this);
        this._store = this._store.filter(dimIndices, fCtx ? bind(cb, fCtx) : cb);
        return this;
      };
      /**
       * Select data in range. (For optimization of filter)
       * (Manually inline code, support 5 million data filtering in data zoom.)
       */


      SeriesData.prototype.selectRange = function (range) {

        var _this = this;

        var innerRange = {};
        var dims = keys(range);
        each(dims, function (dim) {
          var dimIdx = _this._getStoreDimIndex(dim);

          innerRange[dimIdx] = range[dim];
        });
        this._store = this._store.selectRange(innerRange);
        return this;
      };
      /* eslint-enable max-len */


      SeriesData.prototype.mapArray = function (dims, cb, ctx) {

        if (isFunction(dims)) {
          ctx = cb;
          cb = dims;
          dims = [];
        } // ctxCompat just for compat echarts3


        ctx = ctx || this;
        var result = [];
        this.each(dims, function () {
          result.push(cb && cb.apply(this, arguments));
        }, ctx);
        return result;
      };

      SeriesData.prototype.map = function (dims, cb, ctx, ctxCompat) {

        var fCtx = ctx || ctxCompat || this;
        var dimIndices = map$1(normalizeDimensions(dims), this._getStoreDimIndex, this);
        var list = cloneListForMapAndSample(this);
        list._store = this._store.map(dimIndices, fCtx ? bind(cb, fCtx) : cb);
        return list;
      };

      SeriesData.prototype.modify = function (dims, cb, ctx, ctxCompat) {
        var _this = this; // ctxCompat just for compat echarts3


        var fCtx = ctx || ctxCompat || this;

        if ("development" !== 'production') {
          each(normalizeDimensions(dims), function (dim) {
            var dimInfo = _this.getDimensionInfo(dim);

            if (!dimInfo.isCalculationCoord) {
              console.error('Danger: only stack dimension can be modified');
            }
          });
        }

        var dimIndices = map$1(normalizeDimensions(dims), this._getStoreDimIndex, this); // If do shallow clone here, if there are too many stacked series,
        // it still cost lots of memory, because `_store.dimensions` are not shared.
        // We should consider there probably be shallow clone happen in each series
        // in consequent filter/map.

        this._store.modify(dimIndices, fCtx ? bind(cb, fCtx) : cb);
      };
      /**
       * Large data down sampling on given dimension
       * @param sampleIndex Sample index for name and id
       */


      SeriesData.prototype.downSample = function (dimension, rate, sampleValue, sampleIndex) {
        var list = cloneListForMapAndSample(this);
        list._store = this._store.downSample(this._getStoreDimIndex(dimension), rate, sampleValue, sampleIndex);
        return list;
      };
      /**
       * Large data down sampling using largest-triangle-three-buckets
       * @param {string} valueDimension
       * @param {number} targetCount
       */


      SeriesData.prototype.lttbDownSample = function (valueDimension, rate) {
        var list = cloneListForMapAndSample(this);
        list._store = this._store.lttbDownSample(this._getStoreDimIndex(valueDimension), rate);
        return list;
      };

      SeriesData.prototype.getRawDataItem = function (idx) {
        return this._store.getRawDataItem(idx);
      };
      /**
       * Get model of one data item.
       */
      // TODO: Type of data item


      SeriesData.prototype.getItemModel = function (idx) {
        var hostModel = this.hostModel;
        var dataItem = this.getRawDataItem(idx);
        return new Model(dataItem, hostModel, hostModel && hostModel.ecModel);
      };
      /**
       * Create a data differ
       */


      SeriesData.prototype.diff = function (otherList) {
        var thisList = this;
        return new DataDiffer(otherList ? otherList.getStore().getIndices() : [], this.getStore().getIndices(), function (idx) {
          return getId(otherList, idx);
        }, function (idx) {
          return getId(thisList, idx);
        });
      };
      /**
       * Get visual property.
       */


      SeriesData.prototype.getVisual = function (key) {
        var visual = this._visual;
        return visual && visual[key];
      };

      SeriesData.prototype.setVisual = function (kvObj, val) {
        this._visual = this._visual || {};

        if (isObject$2(kvObj)) {
          extend(this._visual, kvObj);
        } else {
          this._visual[kvObj] = val;
        }
      };
      /**
       * Get visual property of single data item
       */
      // eslint-disable-next-line


      SeriesData.prototype.getItemVisual = function (idx, key) {
        var itemVisual = this._itemVisuals[idx];
        var val = itemVisual && itemVisual[key];

        if (val == null) {
          // Use global visual property
          return this.getVisual(key);
        }

        return val;
      };
      /**
       * If exists visual property of single data item
       */


      SeriesData.prototype.hasItemVisual = function () {
        return this._itemVisuals.length > 0;
      };
      /**
       * Make sure itemVisual property is unique
       */
      // TODO: use key to save visual to reduce memory.


      SeriesData.prototype.ensureUniqueItemVisual = function (idx, key) {
        var itemVisuals = this._itemVisuals;
        var itemVisual = itemVisuals[idx];

        if (!itemVisual) {
          itemVisual = itemVisuals[idx] = {};
        }

        var val = itemVisual[key];

        if (val == null) {
          val = this.getVisual(key); // TODO Performance?

          if (isArray(val)) {
            val = val.slice();
          } else if (isObject$2(val)) {
            val = extend({}, val);
          }

          itemVisual[key] = val;
        }

        return val;
      }; // eslint-disable-next-line


      SeriesData.prototype.setItemVisual = function (idx, key, value) {
        var itemVisual = this._itemVisuals[idx] || {};
        this._itemVisuals[idx] = itemVisual;

        if (isObject$2(key)) {
          extend(itemVisual, key);
        } else {
          itemVisual[key] = value;
        }
      };
      /**
       * Clear itemVisuals and list visual.
       */


      SeriesData.prototype.clearAllVisual = function () {
        this._visual = {};
        this._itemVisuals = [];
      };

      SeriesData.prototype.setLayout = function (key, val) {
        isObject$2(key) ? extend(this._layout, key) : this._layout[key] = val;
      };
      /**
       * Get layout property.
       */


      SeriesData.prototype.getLayout = function (key) {
        return this._layout[key];
      };
      /**
       * Get layout of single data item
       */


      SeriesData.prototype.getItemLayout = function (idx) {
        return this._itemLayouts[idx];
      };
      /**
       * Set layout of single data item
       */


      SeriesData.prototype.setItemLayout = function (idx, layout, merge) {
        this._itemLayouts[idx] = merge ? extend(this._itemLayouts[idx] || {}, layout) : layout;
      };
      /**
       * Clear all layout of single data item
       */


      SeriesData.prototype.clearItemLayouts = function () {
        this._itemLayouts.length = 0;
      };
      /**
       * Set graphic element relative to data. It can be set as null
       */


      SeriesData.prototype.setItemGraphicEl = function (idx, el) {
        var seriesIndex = this.hostModel && this.hostModel.seriesIndex;
        setCommonECData(seriesIndex, this.dataType, idx, el);
        this._graphicEls[idx] = el;
      };

      SeriesData.prototype.getItemGraphicEl = function (idx) {
        return this._graphicEls[idx];
      };

      SeriesData.prototype.eachItemGraphicEl = function (cb, context) {
        each(this._graphicEls, function (el, idx) {
          if (el) {
            cb && cb.call(context, el, idx);
          }
        });
      };
      /**
       * Shallow clone a new list except visual and layout properties, and graph elements.
       * New list only change the indices.
       */


      SeriesData.prototype.cloneShallow = function (list) {
        if (!list) {
          list = new SeriesData(this._schema ? this._schema : map$1(this.dimensions, this._getDimInfo, this), this.hostModel);
        }

        transferProperties(list, this);
        list._store = this._store;
        return list;
      };
      /**
       * Wrap some method to add more feature
       */


      SeriesData.prototype.wrapMethod = function (methodName, injectFunction) {
        var originalMethod = this[methodName];

        if (!isFunction(originalMethod)) {
          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)));
        };
      }; // ----------------------------------------------------------
      // A work around for internal method visiting private member.
      // ----------------------------------------------------------


      SeriesData.internalField = function () {
        prepareInvertedIndex = function (data) {
          var invertedIndicesMap = data._invertedIndicesMap;
          each(invertedIndicesMap, function (invertedIndices, dim) {
            var dimInfo = data._dimInfos[dim]; // Currently, only dimensions that has ordinalMeta can create inverted indices.

            var ordinalMeta = dimInfo.ordinalMeta;
            var store = data._store;

            if (ordinalMeta) {
              invertedIndices = invertedIndicesMap[dim] = new CtorInt32Array$1(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 < store.count(); i++) {
                // Only support the case that all values are distinct.
                invertedIndices[store.get(dimInfo.storeDimIndex, i)] = i;
              }
            }
          });
        };

        getIdNameFromStore = function (data, dimIdx, idx) {
          return convertOptionIdName(data._getCategory(dimIdx, idx), null);
        };
        /**
         * @see the comment of `List['getId']`.
         */


        getId = function (data, rawIndex) {
          var id = data._idList[rawIndex];

          if (id == null && data._idDimIdx != null) {
            id = getIdNameFromStore(data, data._idDimIdx, rawIndex);
          }

          if (id == null) {
            id = ID_PREFIX + rawIndex;
          }

          return id;
        };

        normalizeDimensions = function (dimensions) {
          if (!isArray(dimensions)) {
            dimensions = dimensions != null ? [dimensions] : [];
          }

          return dimensions;
        };
        /**
         * Data in excludeDimensions is copied, otherwise transferred.
         */


        cloneListForMapAndSample = function (original) {
          var list = new SeriesData(original._schema ? original._schema : map$1(original.dimensions, original._getDimInfo, original), original.hostModel); // FIXME If needs stackedOn, value may already been stacked

          transferProperties(list, original);
          return list;
        };

        transferProperties = function (target, source) {
          each(TRANSFERABLE_PROPERTIES.concat(source.__wrappedMethods || []), function (propName) {
            if (source.hasOwnProperty(propName)) {
              target[propName] = source[propName];
            }
          });
          target.__wrappedMethods = source.__wrappedMethods;
          each(CLONE_PROPERTIES, function (propName) {
            target[propName] = clone(source[propName]);
          });
          target._calculationInfo = extend({}, source._calculationInfo);
        };

        makeIdFromName = function (data, idx) {
          var nameList = data._nameList;
          var idList = data._idList;
          var nameDimIdx = data._nameDimIdx;
          var idDimIdx = data._idDimIdx;
          var name = nameList[idx];
          var id = idList[idx];

          if (name == null && nameDimIdx != null) {
            nameList[idx] = name = getIdNameFromStore(data, nameDimIdx, idx);
          }

          if (id == null && idDimIdx != null) {
            idList[idx] = id = getIdNameFromStore(data, idDimIdx, idx);
          }

          if (id == null && name != null) {
            var nameRepeatCount = data._nameRepeatCount;
            var nmCnt = nameRepeatCount[name] = (nameRepeatCount[name] || 0) + 1;
            id = name;

            if (nmCnt > 1) {
              id += '__ec__' + nmCnt;
            }

            idList[idx] = id;
          }
        };
      }();

      return SeriesData;
    }();

    /**
     * For outside usage compat (like echarts-gl are using it).
     */

    function createDimensions(source, opt) {
      return prepareSeriesDataSchema(source, opt).dimensions;
    }
    /**
     * This method builds the relationship between:
     * + "what the coord sys or series requires (see `coordDimensions`)",
     * + "what the user defines (in `encode` and `dimensions`, see `opt.dimensionsDefine` and `opt.encodeDefine`)"
     * + "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'.
     *
     * @return The results are always sorted by `storeDimIndex` asc.
     */

    function prepareSeriesDataSchema( // TODO: TYPE completeDimensions type
    source, opt) {
      if (!isSourceInstance(source)) {
        source = createSourceFromSeriesDataOption(source);
      }

      opt = opt || {};
      var sysDims = opt.coordDimensions || [];
      var dimsDef = opt.dimensionsDefine || source.dimensionsDefine || [];
      var coordDimNameMap = createHashMap();
      var resultList = [];
      var dimCount = getDimCount(source, sysDims, dimsDef, opt.dimensionsCount); // Try to ignore unused dimensions if sharing a high dimension datastore
      // 30 is an experience value.

      var omitUnusedDimensions = opt.canOmitUnusedDimensions && shouldOmitUnusedDimensions(dimCount);
      var isUsingSourceDimensionsDef = dimsDef === source.dimensionsDefine;
      var dataDimNameMap = isUsingSourceDimensionsDef ? ensureSourceDimNameMap(source) : createDimNameMap(dimsDef);
      var encodeDef = opt.encodeDefine;

      if (!encodeDef && opt.encodeDefaulter) {
        encodeDef = opt.encodeDefaulter(source, dimCount);
      }

      var encodeDefMap = createHashMap(encodeDef);
      var indicesMap = new CtorInt32Array(dimCount);

      for (var i = 0; i < indicesMap.length; i++) {
        indicesMap[i] = -1;
      }

      function getResultItem(dimIdx) {
        var idx = indicesMap[dimIdx];

        if (idx < 0) {
          var dimDefItemRaw = dimsDef[dimIdx];
          var dimDefItem = isObject(dimDefItemRaw) ? dimDefItemRaw : {
            name: dimDefItemRaw
          };
          var resultItem = new SeriesDimensionDefine();
          var userDimName = dimDefItem.name;

          if (userDimName != null && dataDimNameMap.get(userDimName) != null) {
            // Only if `series.dimensions` is defined in option
            // displayName, will be set, and dimension will be displayed vertically in
            // tooltip by default.
            resultItem.name = resultItem.displayName = userDimName;
          }

          dimDefItem.type != null && (resultItem.type = dimDefItem.type);
          dimDefItem.displayName != null && (resultItem.displayName = dimDefItem.displayName);
          var newIdx = resultList.length;
          indicesMap[dimIdx] = newIdx;
          resultItem.storeDimIndex = dimIdx;
          resultList.push(resultItem);
          return resultItem;
        }

        return resultList[idx];
      }

      if (!omitUnusedDimensions) {
        for (var i = 0; i < dimCount; i++) {
          getResultItem(i);
        }
      } // Set `coordDim` and `coordDimIndex` by `encodeDefMap` and normalize `encodeDefMap`.


      encodeDefMap.each(function (dataDimsRaw, coordDim) {
        var dataDims = normalizeToArray(dataDimsRaw).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) {
          encodeDefMap.set(coordDim, false);
          return;
        }

        var validDataDims = encodeDefMap.set(coordDim, []);
        each(dataDims, function (resultDimIdxOrName, idx) {
          // The input resultDimIdx can be dim name or index.
          var resultDimIdx = isString(resultDimIdxOrName) ? dataDimNameMap.get(resultDimIdxOrName) : resultDimIdxOrName;

          if (resultDimIdx != null && resultDimIdx < dimCount) {
            validDataDims[idx] = resultDimIdx;
            applyDim(getResultItem(resultDimIdx), coordDim, idx);
          }
        });
      }); // Apply templates and default order from `sysDims`.

      var availDimIdx = 0;
      each(sysDims, function (sysDimItemRaw) {
        var coordDim;
        var sysDimItemDimsDef;
        var sysDimItemOtherDims;
        var sysDimItem;

        if (isString(sysDimItemRaw)) {
          coordDim = sysDimItemRaw;
          sysDimItem = {};
        } else {
          sysDimItem = sysDimItemRaw;
          coordDim = sysDimItem.name;
          var ordinalMeta = sysDimItem.ordinalMeta;
          sysDimItem.ordinalMeta = null;
          sysDimItem = extend({}, 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 = encodeDefMap.get(coordDim); // negative resultDimIdx means no need to mapping.

        if (dataDims === false) {
          return;
        }

        dataDims = normalizeToArray(dataDims); // dimensions provides default dim sequences.

        if (!dataDims.length) {
          for (var i = 0; i < (sysDimItemDimsDef && sysDimItemDimsDef.length || 1); i++) {
            while (availDimIdx < dimCount && getResultItem(availDimIdx).coordDim != null) {
              availDimIdx++;
            }

            availDimIdx < dimCount && dataDims.push(availDimIdx++);
          }
        } // Apply templates.


        each(dataDims, function (resultDimIdx, coordDimIndex) {
          var resultItem = getResultItem(resultDimIdx); // Coordinate system has a higher priority on dim type than source.

          if (isUsingSourceDimensionsDef && sysDimItem.type != null) {
            resultItem.type = sysDimItem.type;
          }

          applyDim(defaults(resultItem, sysDimItem), coordDim, coordDimIndex);

          if (resultItem.name == null && sysDimItemDimsDef) {
            var sysDimItemDimsDefItem = sysDimItemDimsDef[coordDimIndex];
            !isObject(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 (VISUAL_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';

      function ifNoNameFillWithCoordName(resultItem) {
        if (resultItem.name == null) {
          // Duplication will be removed in the next step.
          resultItem.name = resultItem.coordDim;
        }
      } // Set dim `name` and other `coordDim` and other props.


      if (!omitUnusedDimensions) {
        for (var resultDimIdx = 0; resultDimIdx < dimCount; resultDimIdx++) {
          var resultItem = getResultItem(resultDimIdx);
          var coordDim = resultItem.coordDim;

          if (coordDim == null) {
            // TODO no need to generate coordDim for isExtraCoord?
            resultItem.coordDim = genCoordDimName(extra, coordDimNameMap, fromZero);
            resultItem.coordDimIndex = 0; // Series specified generateCoord is using out.

            if (!generateCoord || generateCoordCount <= 0) {
              resultItem.isExtraCoord = true;
            }

            generateCoordCount--;
          }

          ifNoNameFillWithCoordName(resultItem);

          if (resultItem.type == null && (guessOrdinal(source, resultDimIdx) === BE_ORDINAL.Must // Consider the case:
          // {
          //    dataset: {source: [
          //        ['2001', 123],
          //        ['2002', 456],
          //        ...
          //        ['The others', 987],
          //    ]},
          //    series: {type: 'pie'}
          // }
          // The first column should better be treated as a "ordinal" although it
          // might not be detected as an "ordinal" by `guessOrdinal`.
          || resultItem.isExtraCoord && (resultItem.otherDims.itemName != null || resultItem.otherDims.seriesName != null))) {
            resultItem.type = 'ordinal';
          }
        }
      } else {
        each(resultList, function (resultItem) {
          // PENDING: guessOrdinal or let user specify type: 'ordinal' manually?
          ifNoNameFillWithCoordName(resultItem);
        }); // Sort dimensions: there are some rule that use the last dim as label,
        // and for some latter travel process easier.

        resultList.sort(function (item0, item1) {
          return item0.storeDimIndex - item1.storeDimIndex;
        });
      }

      removeDuplication(resultList);
      return new SeriesDataSchema({
        source: source,
        dimensions: resultList,
        fullDimensionCount: dimCount,
        dimensionOmitted: omitUnusedDimensions
      });
    }

    function removeDuplication(result) {
      var duplicationMap = createHashMap();

      for (var i = 0; i < result.length; i++) {
        var dim = result[i];
        var dimOriginalName = dim.name;
        var count = duplicationMap.get(dimOriginalName) || 0;

        if (count > 0) {
          // Starts from 0.
          dim.name = dimOriginalName + (count - 1);
        }

        count++;
        duplicationMap.set(dimOriginalName, count);
      }
    } // ??? 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 calculate bubble size or use visualMap
    // on other dimensions besides coordSys needed.
    // So, dims that is not used by system, should be shared in data store?


    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.dimensionsDetectedCount || 1, sysDims.length, dimsDef.length, optDimCount || 0);
      each(sysDims, function (sysDimItem) {
        var sysDimItemDimsDef;

        if (isObject(sysDimItem) && (sysDimItemDimsDef = sysDimItem.dimsDef)) {
          dimCount = Math.max(dimCount, sysDimItemDimsDef.length);
        }
      });
      return dimCount;
    }

    function genCoordDimName(name, map, fromZero) {
      if (fromZero || map.hasKey(name)) {
        var i = 0;

        while (map.hasKey(name + i)) {
          i++;
        }

        name += i;
      }

      map.set(name, true);
      return name;
    }

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

    var CoordSysInfo =
    /** @class */
    function () {
      function CoordSysInfo(coordSysName) {
        this.coordSysDims = [];
        this.axisMap = createHashMap();
        this.categoryAxisMap = createHashMap();
        this.coordSysName = coordSysName;
      }

      return 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', SINGLE_REFERRING).models[0];
        var yAxisModel = seriesModel.getReferringComponents('yAxis', SINGLE_REFERRING).models[0];

        if ("development" !== 'production') {
          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', SINGLE_REFERRING).models[0];

        if ("development" !== 'production') {
          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', SINGLE_REFERRING).models[0];
        var radiusAxisModel = polarModel.findAxisModel('radiusAxis');
        var angleAxisModel = polarModel.findAxisModel('angleAxis');

        if ("development" !== 'production') {
          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(parallelModel.parallelAxisIndex, function (axisIndex, index) {
          var axisModel = ecModel.getComponent('parallelAxis', axisIndex);
          var axisDim = coordSysDims[index];
          axisMap.set(axisDim, axisModel);

          if (isCategory(axisModel)) {
            categoryAxisMap.set(axisDim, axisModel);

            if (result.firstCategoryDimIndex == null) {
              result.firstCategoryDimIndex = index;
            }
          }
        });
      }
    };

    function isCategory(axisModel) {
      return axisModel.get('type') === 'category';
    }

    /**
     * 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 seriesModel
     * @param dimensionsInput The same as the input of <module:echarts/data/SeriesData>.
     *        The input will be modified.
     * @param opt
     * @param opt.stackedCoordDimension Specify a coord dimension if needed.
     * @param opt.byIndex=false
     * @return calculationInfo
     * {
     *     stackedDimension: string
     *     stackedByDimension: string
     *     isStackedByIndex: boolean
     *     stackedOverDimension: string
     *     stackResultDimension: string
     * }
     */

    function enableDataStack(seriesModel, dimensionsInput, opt) {
      opt = opt || {};
      var byIndex = opt.byIndex;
      var stackedCoordDimension = opt.stackedCoordDimension;
      var dimensionDefineList;
      var schema;
      var store;

      if (isLegacyDimensionsInput(dimensionsInput)) {
        dimensionDefineList = dimensionsInput;
      } else {
        schema = dimensionsInput.schema;
        dimensionDefineList = schema.dimensions;
        store = dimensionsInput.store;
      } // Compatibal: when `stack` is set as '', do not stack.


      var mayStack = !!(seriesModel && seriesModel.get('stack'));
      var stackedByDimInfo;
      var stackedDimInfo;
      var stackResultDimension;
      var stackedOverDimension;
      each(dimensionDefineList, function (dimensionInfo, index) {
        if (isString(dimensionInfo)) {
          dimensionDefineList[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.
        // Also need to use seriesModel.id as postfix because different
        // series may share same data store. The stack dimension needs to be distinguished.
        stackResultDimension = '__\0ecstackresult_' + seriesModel.id;
        stackedOverDimension = '__\0ecstackedover_' + seriesModel.id; // Create inverted index to fast query index by value.

        if (stackedByDimInfo) {
          stackedByDimInfo.createInvertedIndices = true;
        }

        var stackedDimCoordDim_1 = stackedDimInfo.coordDim;
        var stackedDimType = stackedDimInfo.type;
        var stackedDimCoordIndex_1 = 0;
        each(dimensionDefineList, function (dimensionInfo) {
          if (dimensionInfo.coordDim === stackedDimCoordDim_1) {
            stackedDimCoordIndex_1++;
          }
        });
        var stackedOverDimensionDefine = {
          name: stackResultDimension,
          coordDim: stackedDimCoordDim_1,
          coordDimIndex: stackedDimCoordIndex_1,
          type: stackedDimType,
          isExtraCoord: true,
          isCalculationCoord: true,
          storeDimIndex: dimensionDefineList.length
        };
        var stackResultDimensionDefine = {
          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_1 + 1,
          type: stackedDimType,
          isExtraCoord: true,
          isCalculationCoord: true,
          storeDimIndex: dimensionDefineList.length + 1
        };

        if (schema) {
          if (store) {
            stackedOverDimensionDefine.storeDimIndex = store.ensureCalculationDimension(stackedOverDimension, stackedDimType);
            stackResultDimensionDefine.storeDimIndex = store.ensureCalculationDimension(stackResultDimension, stackedDimType);
          }

          schema.appendCalculationDimension(stackedOverDimensionDefine);
          schema.appendCalculationDimension(stackResultDimensionDefine);
        } else {
          dimensionDefineList.push(stackedOverDimensionDefine);
          dimensionDefineList.push(stackResultDimensionDefine);
        }
      }

      return {
        stackedDimension: stackedDimInfo && stackedDimInfo.name,
        stackedByDimension: stackedByDimInfo && stackedByDimInfo.name,
        isStackedByIndex: byIndex,
        stackedOverDimension: stackedOverDimension,
        stackResultDimension: stackResultDimension
      };
    }

    function isLegacyDimensionsInput(dimensionsInput) {
      return !isSeriesDataSchema(dimensionsInput.schema);
    }

    function isDimensionStacked(data, stackedDim) {
      // 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');
    }
    function getStackedDimension(data, targetDim) {
      return isDimensionStacked(data, targetDim) ? data.getCalculationInfo('stackResultDimension') : targetDim;
    }

    function getCoordSysDimDefs(seriesModel, coordSysInfo) {
      var coordSysName = seriesModel.get('coordinateSystem');
      var registeredCoordSys = CoordinateSystemManager.get(coordSysName);
      var coordSysDimDefs;

      if (coordSysInfo && coordSysInfo.coordSysDims) {
        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);
          }

          return dimInfo;
        });
      }

      if (!coordSysDimDefs) {
        // Get dimensions from registered coordinate system
        coordSysDimDefs = registeredCoordSys && (registeredCoordSys.getDimensionsInfo ? registeredCoordSys.getDimensionsInfo() : registeredCoordSys.dimensions.slice()) || ['x', 'y'];
      }

      return coordSysDimDefs;
    }

    function injectOrdinalMeta(dimInfoList, createInvertedIndices, coordSysInfo) {
      var firstCategoryDimIndex;
      var hasNameEncode;
      coordSysInfo && each(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 (createInvertedIndices) {
            dimInfo.createInvertedIndices = true;
          }
        }

        if (dimInfo.otherDims.itemName != null) {
          hasNameEncode = true;
        }
      });

      if (!hasNameEncode && firstCategoryDimIndex != null) {
        dimInfoList[firstCategoryDimIndex].otherDims.itemName = 0;
      }

      return firstCategoryDimIndex;
    }
    /**
     * Caution: there are side effects to `sourceManager` in this method.
     * Should better only be called in `Series['getInitialData']`.
     */


    function createSeriesData(sourceRaw, seriesModel, opt) {
      opt = opt || {};
      var sourceManager = seriesModel.getSourceManager();
      var source;
      var isOriginalSource = false;

      if (sourceRaw) {
        isOriginalSource = true;
        source = createSourceFromSeriesDataOption(sourceRaw);
      } else {
        source = sourceManager.getSource(); // Is series.data. not dataset.

        isOriginalSource = source.sourceFormat === SOURCE_FORMAT_ORIGINAL;
      }

      var coordSysInfo = getCoordSysInfoBySeries(seriesModel);
      var coordSysDimDefs = getCoordSysDimDefs(seriesModel, coordSysInfo);
      var useEncodeDefaulter = opt.useEncodeDefaulter;
      var encodeDefaulter = isFunction(useEncodeDefaulter) ? useEncodeDefaulter : useEncodeDefaulter ? curry(makeSeriesEncodeForAxisCoordSys, coordSysDimDefs, seriesModel) : null;
      var createDimensionOptions = {
        coordDimensions: coordSysDimDefs,
        generateCoord: opt.generateCoord,
        encodeDefine: seriesModel.getEncode(),
        encodeDefaulter: encodeDefaulter,
        canOmitUnusedDimensions: !isOriginalSource
      };
      var schema = prepareSeriesDataSchema(source, createDimensionOptions);
      var firstCategoryDimIndex = injectOrdinalMeta(schema.dimensions, opt.createInvertedIndices, coordSysInfo);
      var store = !isOriginalSource ? sourceManager.getSharedDataStore(schema) : null;
      var stackCalculationInfo = enableDataStack(seriesModel, {
        schema: schema,
        store: store
      });
      var data = new SeriesData(schema, seriesModel);
      data.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;
      data.hasItemOption = false;
      data.initData( // Try to reuse the data store in sourceManager if using dataset.
      isOriginalSource ? source : store, null, dimValueGetter);
      return data;
    }

    function isNeedCompleteOrdinalData(source) {
      if (source.sourceFormat === SOURCE_FORMAT_ORIGINAL) {
        var sampleItem = firstDataNotNull(source.data || []);
        return !isArray(getDataItemValue(sampleItem));
      }
    }

    function firstDataNotNull(arr) {
      var i = 0;

      while (i < arr.length && arr[i] == null) {
        i++;
      }

      return arr[i];
    }

    var Scale =
    /** @class */
    function () {
      function Scale(setting) {
        this._setting = setting || {};
        this._extent = [Infinity, -Infinity];
      }

      Scale.prototype.getSetting = function (name) {
        return this._setting[name];
      };
      /**
       * Set extent from data
       */


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


      Scale.prototype.unionExtentFromData = function (data, dim) {
        this.unionExtent(data.getApproximateExtent(dim));
      };
      /**
       * Get extent
       *
       * Extent is always in increase order.
       */


      Scale.prototype.getExtent = function () {
        return this._extent.slice();
      };
      /**
       * Set extent
       */


      Scale.prototype.setExtent = function (start, end) {
        var thisExtent = this._extent;

        if (!isNaN(start)) {
          thisExtent[0] = start;
        }

        if (!isNaN(end)) {
          thisExtent[1] = end;
        }
      };
      /**
       * If value is in extent range
       */


      Scale.prototype.isInExtentRange = function (value) {
        return this._extent[0] <= value && this._extent[1] >= value;
      };
      /**
       * 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;
      };

      return Scale;
    }();

    enableClassManagement(Scale);

    var uidBase = 0;

    var OrdinalMeta =
    /** @class */
    function () {
      function OrdinalMeta(opt) {
        this.categories = opt.categories || [];
        this._needCollect = opt.needCollect;
        this._deduplication = opt.deduplication;
        this.uid = ++uidBase;
      }

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

      OrdinalMeta.prototype.getOrdinal = function (category) {
        // @ts-ignore
        return this._getOrCreateMap().get(category);
      };
      /**
       * @return The ordinal. If not found, return NaN.
       */


      OrdinalMeta.prototype.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 (!isString(category) && !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 = this._getOrCreateMap(); // @ts-ignore


        index = map.get(category);

        if (index == null) {
          if (needCollect) {
            index = this.categories.length;
            this.categories[index] = category; // @ts-ignore

            map.set(category, index);
          } else {
            index = NaN;
          }
        }

        return index;
      }; // Consider big data, do not create map until needed.


      OrdinalMeta.prototype._getOrCreateMap = function () {
        return this._map || (this._map = createHashMap(this.categories));
      };

      return OrdinalMeta;
    }();

    function getName(obj) {
      if (isObject(obj) && obj.value != null) {
        return obj.value;
      } else {
        return obj + '';
      }
    }

    function isValueNice(val) {
      var exp10 = Math.pow(10, quantityExponent(Math.abs(val)));
      var f = Math.abs(val / exp10);
      return f === 0 || f === 1 || f === 2 || f === 3 || f === 5;
    }
    function isIntervalOrLogScale(scale) {
      return scale.type === 'interval' || scale.type === 'log';
    }
    /**
     * @param extent Both extent[0] and extent[1] should be valid number.
     *               Should be extent[0] < extent[1].
     * @param splitNumber splitNumber should be >= 1.
     */

    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 = [round(Math.ceil(extent[0] / interval) * interval, precision), round(Math.floor(extent[1] / interval) * interval, precision)];
      fixExtent(niceTickExtent, extent);
      return result;
    }
    function increaseInterval(interval) {
      var exp10 = Math.pow(10, quantityExponent(interval)); // Increase interval

      var f = interval / exp10;

      if (!f) {
        f = 1;
      } else if (f === 2) {
        f = 3;
      } else if (f === 3) {
        f = 5;
      } else {
        // f is 1 or 5
        f *= 2;
      }

      return round(f * exp10);
    }
    /**
     * @return interval precision
     */

    function getIntervalPrecision(interval) {
      // Tow more digital for tick.
      return getPrecision(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];
      }
    }
    function contain$1(val, extent) {
      return val >= extent[0] && val <= extent[1];
    }
    function normalize$1(val, extent) {
      if (extent[1] === extent[0]) {
        return 0.5;
      }

      return (val - extent[0]) / (extent[1] - extent[0]);
    }
    function scale$2(val, extent) {
      return val * (extent[1] - extent[0]) + extent[0];
    }

    var OrdinalScale =
    /** @class */
    function (_super) {
      __extends(OrdinalScale, _super);

      function OrdinalScale(setting) {
        var _this = _super.call(this, setting) || this;

        _this.type = 'ordinal';

        var ordinalMeta = _this.getSetting('ordinalMeta'); // Caution: Should not use instanceof, consider ec-extensions using
        // import approach to get OrdinalMeta class.


        if (!ordinalMeta) {
          ordinalMeta = new OrdinalMeta({});
        }

        if (isArray(ordinalMeta)) {
          ordinalMeta = new OrdinalMeta({
            categories: map(ordinalMeta, function (item) {
              return isObject(item) ? item.value : item;
            })
          });
        }

        _this._ordinalMeta = ordinalMeta;
        _this._extent = _this.getSetting('extent') || [0, ordinalMeta.categories.length - 1];
        return _this;
      }

      OrdinalScale.prototype.parse = function (val) {
        // Caution: Math.round(null) will return `0` rather than `NaN`
        if (val == null) {
          return NaN;
        }

        return isString(val) ? this._ordinalMeta.getOrdinal(val) // val might be float.
        : Math.round(val);
      };

      OrdinalScale.prototype.contain = function (rank) {
        rank = this.parse(rank);
        return contain$1(rank, this._extent) && this._ordinalMeta.categories[rank] != null;
      };
      /**
       * Normalize given rank or name to linear [0, 1]
       * @param val raw ordinal number.
       * @return normalized value in [0, 1].
       */


      OrdinalScale.prototype.normalize = function (val) {
        val = this._getTickNumber(this.parse(val));
        return normalize$1(val, this._extent);
      };
      /**
       * @param val normalized value in [0, 1].
       * @return raw ordinal number.
       */


      OrdinalScale.prototype.scale = function (val) {
        val = Math.round(scale$2(val, this._extent));
        return this.getRawOrdinalNumber(val);
      };

      OrdinalScale.prototype.getTicks = function () {
        var ticks = [];
        var extent = this._extent;
        var rank = extent[0];

        while (rank <= extent[1]) {
          ticks.push({
            value: rank
          });
          rank++;
        }

        return ticks;
      };

      OrdinalScale.prototype.getMinorTicks = function (splitNumber) {
        // Not support.
        return;
      };
      /**
       * @see `Ordinal['_ordinalNumbersByTick']`
       */


      OrdinalScale.prototype.setSortInfo = function (info) {
        if (info == null) {
          this._ordinalNumbersByTick = this._ticksByOrdinalNumber = null;
          return;
        }

        var infoOrdinalNumbers = info.ordinalNumbers;
        var ordinalsByTick = this._ordinalNumbersByTick = [];
        var ticksByOrdinal = this._ticksByOrdinalNumber = []; // Unnecessary support negative tick in `realtimeSort`.

        var tickNum = 0;
        var allCategoryLen = this._ordinalMeta.categories.length;

        for (var len = Math.min(allCategoryLen, infoOrdinalNumbers.length); tickNum < len; ++tickNum) {
          var ordinalNumber = infoOrdinalNumbers[tickNum];
          ordinalsByTick[tickNum] = ordinalNumber;
          ticksByOrdinal[ordinalNumber] = tickNum;
        } // Handle that `series.data` only covers part of the `axis.category.data`.


        var unusedOrdinal = 0;

        for (; tickNum < allCategoryLen; ++tickNum) {
          while (ticksByOrdinal[unusedOrdinal] != null) {
            unusedOrdinal++;
          }
          ordinalsByTick.push(unusedOrdinal);
          ticksByOrdinal[unusedOrdinal] = tickNum;
        }
      };

      OrdinalScale.prototype._getTickNumber = function (ordinal) {
        var ticksByOrdinalNumber = this._ticksByOrdinalNumber; // also support ordinal out of range of `ordinalMeta.categories.length`,
        // where ordinal numbers are used as tick value directly.

        return ticksByOrdinalNumber && ordinal >= 0 && ordinal < ticksByOrdinalNumber.length ? ticksByOrdinalNumber[ordinal] : ordinal;
      };
      /**
       * @usage
       * ```js
       * const ordinalNumber = ordinalScale.getRawOrdinalNumber(tickVal);
       *
       * // case0
       * const rawOrdinalValue = axisModel.getCategories()[ordinalNumber];
       * // case1
       * const rawOrdinalValue = this._ordinalMeta.categories[ordinalNumber];
       * // case2
       * const coord = axis.dataToCoord(ordinalNumber);
       * ```
       *
       * @param {OrdinalNumber} tickNumber index of display
       */


      OrdinalScale.prototype.getRawOrdinalNumber = function (tickNumber) {
        var ordinalNumbersByTick = this._ordinalNumbersByTick; // tickNumber may be out of range, e.g., when axis max is larger than `ordinalMeta.categories.length`.,
        // where ordinal numbers are used as tick value directly.

        return ordinalNumbersByTick && tickNumber >= 0 && tickNumber < ordinalNumbersByTick.length ? ordinalNumbersByTick[tickNumber] : tickNumber;
      };
      /**
       * Get item on tick
       */


      OrdinalScale.prototype.getLabel = function (tick) {
        if (!this.isBlank()) {
          var ordinalNumber = this.getRawOrdinalNumber(tick.value);
          var cateogry = this._ordinalMeta.categories[ordinalNumber]; // Note that if no data, ordinalMeta.categories is an empty array.
          // Return empty if it's not exist.

          return cateogry == null ? '' : cateogry + '';
        }
      };

      OrdinalScale.prototype.count = function () {
        return this._extent[1] - this._extent[0] + 1;
      };

      OrdinalScale.prototype.unionExtentFromData = function (data, dim) {
        this.unionExtent(data.getApproximateExtent(dim));
      };
      /**
       * @override
       * If value is in extent range
       */


      OrdinalScale.prototype.isInExtentRange = function (value) {
        value = this._getTickNumber(value);
        return this._extent[0] <= value && this._extent[1] >= value;
      };

      OrdinalScale.prototype.getOrdinalMeta = function () {
        return this._ordinalMeta;
      };

      OrdinalScale.prototype.calcNiceTicks = function () {};

      OrdinalScale.prototype.calcNiceExtent = function () {};

      OrdinalScale.type = 'ordinal';
      return OrdinalScale;
    }(Scale);

    Scale.registerClass(OrdinalScale);

    var roundNumber = round;

    var IntervalScale =
    /** @class */
    function (_super) {
      __extends(IntervalScale, _super);

      function IntervalScale() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = 'interval'; // Step is calculated in adjustExtent.

        _this._interval = 0;
        _this._intervalPrecision = 2;
        return _this;
      }

      IntervalScale.prototype.parse = function (val) {
        return val;
      };

      IntervalScale.prototype.contain = function (val) {
        return contain$1(val, this._extent);
      };

      IntervalScale.prototype.normalize = function (val) {
        return normalize$1(val, this._extent);
      };

      IntervalScale.prototype.scale = function (val) {
        return scale$2(val, this._extent);
      };

      IntervalScale.prototype.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);
        }
      };

      IntervalScale.prototype.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

        this.setExtent(extent[0], extent[1]);
      };

      IntervalScale.prototype.getInterval = function () {
        return this._interval;
      };

      IntervalScale.prototype.setInterval = function (interval) {
        this._interval = interval; // Dropped auto calculated niceExtent and use user-set extent.
        // We assume user wants to set both interval, min, max to get a better result.

        this._niceExtent = this._extent.slice();
        this._intervalPrecision = getIntervalPrecision(interval);
      };
      /**
       * @param expandToNicedExtent Whether expand the ticks to niced extent.
       */


      IntervalScale.prototype.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({
              value: roundNumber(niceTickExtent[0] - interval, intervalPrecision)
            });
          } else {
            ticks.push({
              value: extent[0]
            });
          }
        }

        var tick = niceTickExtent[0];

        while (tick <= niceTickExtent[1]) {
          ticks.push({
            value: tick
          }); // Avoid rounding error

          tick = roundNumber(tick + interval, intervalPrecision);

          if (tick === ticks[ticks.length - 1].value) {
            // 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].value : niceTickExtent[1];

        if (extent[1] > lastNiceTick) {
          if (expandToNicedExtent) {
            ticks.push({
              value: roundNumber(lastNiceTick + interval, intervalPrecision)
            });
          } else {
            ticks.push({
              value: extent[1]
            });
          }
        }

        return ticks;
      };

      IntervalScale.prototype.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.value - prevTick.value;
          var minorInterval = interval / splitNumber;

          while (count < splitNumber - 1) {
            var minorTick = roundNumber(prevTick.value + (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 opt.precision If 'auto', use nice presision.
       * @param opt.pad returns 1.50 but not 1.5 if precision is 2.
       */


      IntervalScale.prototype.getLabel = function (data, opt) {
        if (data == null) {
          return '';
        }

        var precision = opt && opt.precision;

        if (precision == null) {
          precision = getPrecision(data.value) || 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'.


        var dataNum = roundNumber(data.value, precision, true);
        return addCommas(dataNum);
      };
      /**
       * @param splitNumber By default `5`.
       */


      IntervalScale.prototype.calcNiceTicks = 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;
      };

      IntervalScale.prototype.calcNiceExtent = 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
            // Note that extents can be both negative. See #13154
            var expandSize = Math.abs(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.calcNiceTicks(opt.splitNumber, opt.minInterval, opt.maxInterval); // let 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);
        }
      };

      IntervalScale.prototype.setNiceExtent = function (min, max) {
        this._niceExtent = [min, max];
      };

      IntervalScale.type = 'interval';
      return IntervalScale;
    }(Scale);

    Scale.registerClass(IntervalScale);

    /* global Float32Array */

    var supportFloat32Array = typeof Float32Array !== 'undefined';
    var Float32ArrayCtor = !supportFloat32Array ? Array : Float32Array;
    function createFloat32Array(arg) {
      if (isArray(arg)) {
        // Return self directly if don't support TypedArray.
        return supportFloat32Array ? new Float32Array(arg) : arg;
      } // Else is number


      return new Float32ArrayCtor(arg);
    }

    var STACK_PREFIX = '__ec_stack_';

    function getSeriesStackId(seriesModel) {
      return seriesModel.get('stack') || STACK_PREFIX + seriesModel.seriesIndex;
    }

    function getAxisKey(axis) {
      return axis.dim + axis.index;
    }
    /**
     * @return {Object} {width, offset, offsetCenter} If axis.type is not 'category', return undefined.
     */


    function getLayoutOnAxis(opt) {
      var params = [];
      var baseAxis = opt.axis;
      var axisKey = 'axis0';

      if (baseAxis.type !== 'category') {
        return;
      }

      var bandWidth = baseAxis.getBandWidth();

      for (var i = 0; i < opt.count || 0; i++) {
        params.push(defaults({
          bandWidth: bandWidth,
          axisKey: axisKey,
          stackId: STACK_PREFIX + i
        }, opt));
      }

      var widthAndOffsets = doCalBarWidthAndOffset(params);
      var result = [];

      for (var i = 0; i < opt.count; i++) {
        var item = widthAndOffsets[axisKey][STACK_PREFIX + i];
        item.offsetCenter = item.offset + item.width / 2;
        result.push(item);
      }

      return result;
    }
    function prepareLayoutBarSeries(seriesType, ecModel) {
      var seriesModels = [];
      ecModel.eachSeriesByType(seriesType, function (seriesModel) {
        // Check series coordinate, do layout for cartesian2d only
        if (isOnCartesian(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(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 dimIdx = data.getDimensionIndex(data.mapDimension(baseAxis.dim));
        var store = data.getStore();

        for (var i = 0, cnt = store.count(); i < cnt; ++i) {
          var value = store.get(dimIdx, 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(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 0.5 / 1 in cartesian. Because in value axis,
        // the auto-calculated bar width might be less than 0.5 / 1.
        seriesModel.get('barMinWidth') || (isInLargeMode(seriesModel) ? 0.5 : 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(seriesInfoList, function (seriesInfo, idx) {
        var axisKey = seriesInfo.axisKey;
        var bandWidth = seriesInfo.bandWidth;
        var columnsOnAxis = columnsMap[axisKey] || {
          bandWidth: bandWidth,
          remainedWidth: bandWidth,
          autoWidthCount: 0,
          categoryGap: null,
          gap: '20%',
          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(columnsMap, function (columnsOnAxis, coordSysName) {
        result[coordSysName] = {};
        var stacks = columnsOnAxis.stacks;
        var bandWidth = columnsOnAxis.bandWidth;
        var categoryGapPercent = columnsOnAxis.categoryGap;

        if (categoryGapPercent == null) {
          var columnCount = keys(stacks).length; // More columns in one group
          // the spaces between group is smaller. Or the column will be too thin.

          categoryGapPercent = Math.max(35 - columnCount * 4, 15) + '%';
        }

        var categoryGap = parsePercent$1(categoryGapPercent, 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(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 whether 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. Because 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(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(stacks, function (column, stackId) {
          result[coordSysName][stackId] = result[coordSysName][stackId] || {
            bandWidth: bandWidth,
            offset: offset,
            width: column.width
          };
          offset += column.width * (1 + barGapPercent);
        });
      });
      return result;
    }

    function retrieveColumnLayout(barWidthAndOffset, axis, seriesModel) {
      if (barWidthAndOffset && axis) {
        var result = barWidthAndOffset[getAxisKey(axis)];

        if (result != null && seriesModel != null) {
          return result[getSeriesStackId(seriesModel)];
        }

        return result;
      }
    }
    function layout(seriesType, ecModel) {
      var seriesModels = prepareLayoutBarSeries(seriesType, ecModel);
      var barWidthAndOffset = makeColumnLayout(seriesModels);
      each(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;
        data.setLayout({
          bandWidth: columnLayoutInfo.bandWidth,
          offset: columnOffset,
          size: columnWidth
        });
      });
    } // TODO: Do not support stack in large mode yet.

    function createProgressiveLayout(seriesType) {
      return {
        seriesType: seriesType,
        plan: createRenderPlanner(),
        reset: function (seriesModel) {
          if (!isOnCartesian(seriesModel)) {
            return;
          }

          var data = seriesModel.getData();
          var cartesian = seriesModel.coordinateSystem;
          var baseAxis = cartesian.getBaseAxis();
          var valueAxis = cartesian.getOtherAxis(baseAxis);
          var valueDimIdx = data.getDimensionIndex(data.mapDimension(valueAxis.dim));
          var baseDimIdx = data.getDimensionIndex(data.mapDimension(baseAxis.dim));
          var drawBackground = seriesModel.get('showBackground', true);
          var valueDim = data.mapDimension(valueAxis.dim);
          var stackResultDim = data.getCalculationInfo('stackResultDimension');
          var stacked = isDimensionStacked(data, valueDim) && !!data.getCalculationInfo('stackedOnSeries');
          var isValueAxisH = valueAxis.isHorizontal();
          var valueAxisStart = getValueAxisStart(baseAxis, valueAxis);
          var isLarge = isInLargeMode(seriesModel);
          var barMinHeight = seriesModel.get('barMinHeight') || 0;
          var stackedDimIdx = stackResultDim && data.getDimensionIndex(stackResultDim); // Layout info.

          var columnWidth = data.getLayout('size');
          var columnOffset = data.getLayout('offset');
          return {
            progress: function (params, data) {
              var count = params.count;
              var largePoints = isLarge && createFloat32Array(count * 3);
              var largeBackgroundPoints = isLarge && drawBackground && createFloat32Array(count * 3);
              var largeDataIndices = isLarge && createFloat32Array(count);
              var coordLayout = cartesian.master.getRect();
              var bgSize = isValueAxisH ? coordLayout.width : coordLayout.height;
              var dataIndex;
              var store = data.getStore();
              var idxOffset = 0;

              while ((dataIndex = params.next()) != null) {
                var value = store.get(stacked ? stackedDimIdx : valueDimIdx, dataIndex);
                var baseValue = store.get(baseDimIdx, dataIndex);
                var baseCoord = valueAxisStart;
                var startValue = void 0; // Because of the barMinHeight, we can not use the value in
                // stackResultDimension directly.

                if (stacked) {
                  startValue = +value - store.get(valueDimIdx, dataIndex);
                }

                var x = void 0;
                var y = void 0;
                var width = void 0;
                var height = void 0;

                if (isValueAxisH) {
                  var coord = cartesian.dataToPoint([value, baseValue]);

                  if (stacked) {
                    var startCoord = cartesian.dataToPoint([startValue, baseValue]);
                    baseCoord = startCoord[0];
                  }

                  x = baseCoord;
                  y = coord[1] + columnOffset;
                  width = coord[0] - baseCoord;
                  height = columnWidth;

                  if (Math.abs(width) < barMinHeight) {
                    width = (width < 0 ? -1 : 1) * barMinHeight;
                  }
                } else {
                  var coord = cartesian.dataToPoint([baseValue, value]);

                  if (stacked) {
                    var startCoord = cartesian.dataToPoint([baseValue, startValue]);
                    baseCoord = startCoord[1];
                  }

                  x = coord[0] + columnOffset;
                  y = baseCoord;
                  width = columnWidth;
                  height = coord[1] - baseCoord;

                  if (Math.abs(height) < barMinHeight) {
                    // Include zero to has a positive bar
                    height = (height <= 0 ? -1 : 1) * barMinHeight;
                  }
                }

                if (!isLarge) {
                  data.setItemLayout(dataIndex, {
                    x: x,
                    y: y,
                    width: width,
                    height: height
                  });
                } else {
                  largePoints[idxOffset] = x;
                  largePoints[idxOffset + 1] = y;
                  largePoints[idxOffset + 2] = isValueAxisH ? width : height;

                  if (largeBackgroundPoints) {
                    largeBackgroundPoints[idxOffset] = isValueAxisH ? coordLayout.x : x;
                    largeBackgroundPoints[idxOffset + 1] = isValueAxisH ? y : coordLayout.y;
                    largeBackgroundPoints[idxOffset + 2] = bgSize;
                  }

                  largeDataIndices[dataIndex] = dataIndex;
                }

                idxOffset += 3;
              }

              if (isLarge) {
                data.setLayout({
                  largePoints: largePoints,
                  largeDataIndices: largeDataIndices,
                  largeBackgroundPoints: largeBackgroundPoints,
                  valueAxisHorizontal: isValueAxisH
                });
              }
            }
          };
        }
      };
    }

    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) {
      return valueAxis.toGlobalCoord(valueAxis.dataToCoord(valueAxis.type === 'log' ? 1 : 0));
    }

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

    var TimeScale =
    /** @class */
    function (_super) {
      __extends(TimeScale, _super);

      function TimeScale(settings) {
        var _this = _super.call(this, settings) || this;

        _this.type = 'time';
        return _this;
      }
      /**
       * Get label is mainly for other components like dataZoom, tooltip.
       */


      TimeScale.prototype.getLabel = function (tick) {
        var useUTC = this.getSetting('useUTC');
        return format(tick.value, fullLeveledFormatter[getDefaultFormatPrecisionOfInterval(getPrimaryTimeUnit(this._minLevelUnit))] || fullLeveledFormatter.second, useUTC, this.getSetting('locale'));
      };

      TimeScale.prototype.getFormattedLabel = function (tick, idx, labelFormatter) {
        var isUTC = this.getSetting('useUTC');
        var lang = this.getSetting('locale');
        return leveledFormat(tick, idx, labelFormatter, lang, isUTC);
      };
      /**
       * @override
       */


      TimeScale.prototype.getTicks = function () {
        var interval = this._interval;
        var extent = this._extent;
        var ticks = []; // If interval is 0, return [];

        if (!interval) {
          return ticks;
        }

        ticks.push({
          value: extent[0],
          level: 0
        });
        var useUTC = this.getSetting('useUTC');
        var innerTicks = getIntervalTicks(this._minLevelUnit, this._approxInterval, useUTC, extent);
        ticks = ticks.concat(innerTicks);
        ticks.push({
          value: extent[1],
          level: 0
        });
        return ticks;
      };

      TimeScale.prototype.calcNiceExtent = 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.calcNiceTicks(opt.splitNumber, opt.minInterval, opt.maxInterval);
      };

      TimeScale.prototype.calcNiceTicks = function (approxTickNum, minInterval, maxInterval) {
        approxTickNum = approxTickNum || 10;
        var extent = this._extent;
        var span = extent[1] - extent[0];
        this._approxInterval = span / approxTickNum;

        if (minInterval != null && this._approxInterval < minInterval) {
          this._approxInterval = minInterval;
        }

        if (maxInterval != null && this._approxInterval > maxInterval) {
          this._approxInterval = maxInterval;
        }

        var scaleIntervalsLen = scaleIntervals.length;
        var idx = Math.min(bisect(scaleIntervals, this._approxInterval, 0, scaleIntervalsLen), scaleIntervalsLen - 1); // Interval that can be used to calculate ticks

        this._interval = scaleIntervals[idx][1]; // Min level used when picking ticks from top down.
        // We check one more level to avoid the ticks are to sparse in some case.

        this._minLevelUnit = scaleIntervals[Math.max(idx - 1, 0)][0];
      };

      TimeScale.prototype.parse = function (val) {
        // val might be float.
        return isNumber(val) ? val : +parseDate(val);
      };

      TimeScale.prototype.contain = function (val) {
        return contain$1(this.parse(val), this._extent);
      };

      TimeScale.prototype.normalize = function (val) {
        return normalize$1(this.parse(val), this._extent);
      };

      TimeScale.prototype.scale = function (val) {
        return scale$2(val, this._extent);
      };

      TimeScale.type = 'time';
      return TimeScale;
    }(IntervalScale);
    /**
     * 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 scaleIntervals = [// Format                           interval
    ['second', ONE_SECOND], ['minute', ONE_MINUTE], ['hour', ONE_HOUR], ['quarter-day', ONE_HOUR * 6], ['half-day', ONE_HOUR * 12], ['day', ONE_DAY * 1.2], ['half-week', ONE_DAY * 3.5], ['week', ONE_DAY * 7], ['month', ONE_DAY * 31], ['quarter', ONE_DAY * 95], ['half-year', ONE_YEAR / 2], ['year', ONE_YEAR] // 1Y
    ];

    function isUnitValueSame(unit, valueA, valueB, isUTC) {
      var dateA = parseDate(valueA);
      var dateB = parseDate(valueB);

      var isSame = function (unit) {
        return getUnitValue(dateA, unit, isUTC) === getUnitValue(dateB, unit, isUTC);
      };

      var isSameYear = function () {
        return isSame('year');
      }; // const isSameHalfYear = () => isSameYear() && isSame('half-year');
      // const isSameQuater = () => isSameYear() && isSame('quarter');


      var isSameMonth = function () {
        return isSameYear() && isSame('month');
      };

      var isSameDay = function () {
        return isSameMonth() && isSame('day');
      }; // const isSameHalfDay = () => isSameDay() && isSame('half-day');


      var isSameHour = function () {
        return isSameDay() && isSame('hour');
      };

      var isSameMinute = function () {
        return isSameHour() && isSame('minute');
      };

      var isSameSecond = function () {
        return isSameMinute() && isSame('second');
      };

      var isSameMilliSecond = function () {
        return isSameSecond() && isSame('millisecond');
      };

      switch (unit) {
        case 'year':
          return isSameYear();

        case 'month':
          return isSameMonth();

        case 'day':
          return isSameDay();

        case 'hour':
          return isSameHour();

        case 'minute':
          return isSameMinute();

        case 'second':
          return isSameSecond();

        case 'millisecond':
          return isSameMilliSecond();
      }
    } // const primaryUnitGetters = {
    //     year: fullYearGetterName(),
    //     month: monthGetterName(),
    //     day: dateGetterName(),
    //     hour: hoursGetterName(),
    //     minute: minutesGetterName(),
    //     second: secondsGetterName(),
    //     millisecond: millisecondsGetterName()
    // };
    // const primaryUnitUTCGetters = {
    //     year: fullYearGetterName(true),
    //     month: monthGetterName(true),
    //     day: dateGetterName(true),
    //     hour: hoursGetterName(true),
    //     minute: minutesGetterName(true),
    //     second: secondsGetterName(true),
    //     millisecond: millisecondsGetterName(true)
    // };
    // function moveTick(date: Date, unitName: TimeUnit, step: number, isUTC: boolean) {
    //     step = step || 1;
    //     switch (getPrimaryTimeUnit(unitName)) {
    //         case 'year':
    //             date[fullYearSetterName(isUTC)](date[fullYearGetterName(isUTC)]() + step);
    //             break;
    //         case 'month':
    //             date[monthSetterName(isUTC)](date[monthGetterName(isUTC)]() + step);
    //             break;
    //         case 'day':
    //             date[dateSetterName(isUTC)](date[dateGetterName(isUTC)]() + step);
    //             break;
    //         case 'hour':
    //             date[hoursSetterName(isUTC)](date[hoursGetterName(isUTC)]() + step);
    //             break;
    //         case 'minute':
    //             date[minutesSetterName(isUTC)](date[minutesGetterName(isUTC)]() + step);
    //             break;
    //         case 'second':
    //             date[secondsSetterName(isUTC)](date[secondsGetterName(isUTC)]() + step);
    //             break;
    //         case 'millisecond':
    //             date[millisecondsSetterName(isUTC)](date[millisecondsGetterName(isUTC)]() + step);
    //             break;
    //     }
    //     return date.getTime();
    // }
    // const DATE_INTERVALS = [[8, 7.5], [4, 3.5], [2, 1.5]];
    // const MONTH_INTERVALS = [[6, 5.5], [3, 2.5], [2, 1.5]];
    // const MINUTES_SECONDS_INTERVALS = [[30, 30], [20, 20], [15, 15], [10, 10], [5, 5], [2, 2]];


    function getDateInterval(approxInterval, daysInMonth) {
      approxInterval /= ONE_DAY;
      return approxInterval > 16 ? 16 // Math.floor(daysInMonth / 2) + 1  // In this case we only want one tick between two months.
      : approxInterval > 7.5 ? 7 // TODO week 7 or day 8?
      : approxInterval > 3.5 ? 4 : approxInterval > 1.5 ? 2 : 1;
    }

    function getMonthInterval(approxInterval) {
      var APPROX_ONE_MONTH = 30 * ONE_DAY;
      approxInterval /= APPROX_ONE_MONTH;
      return approxInterval > 6 ? 6 : approxInterval > 3 ? 3 : approxInterval > 2 ? 2 : 1;
    }

    function getHourInterval(approxInterval) {
      approxInterval /= ONE_HOUR;
      return approxInterval > 12 ? 12 : approxInterval > 6 ? 6 : approxInterval > 3.5 ? 4 : approxInterval > 2 ? 2 : 1;
    }

    function getMinutesAndSecondsInterval(approxInterval, isMinutes) {
      approxInterval /= isMinutes ? ONE_MINUTE : ONE_SECOND;
      return approxInterval > 30 ? 30 : approxInterval > 20 ? 20 : approxInterval > 15 ? 15 : approxInterval > 10 ? 10 : approxInterval > 5 ? 5 : approxInterval > 2 ? 2 : 1;
    }

    function getMillisecondsInterval(approxInterval) {
      return nice(approxInterval, true);
    }

    function getFirstTimestampOfUnit(date, unitName, isUTC) {
      var outDate = new Date(date);

      switch (getPrimaryTimeUnit(unitName)) {
        case 'year':
        case 'month':
          outDate[monthSetterName(isUTC)](0);

        case 'day':
          outDate[dateSetterName(isUTC)](1);

        case 'hour':
          outDate[hoursSetterName(isUTC)](0);

        case 'minute':
          outDate[minutesSetterName(isUTC)](0);

        case 'second':
          outDate[secondsSetterName(isUTC)](0);
          outDate[millisecondsSetterName(isUTC)](0);
      }

      return outDate.getTime();
    }

    function getIntervalTicks(bottomUnitName, approxInterval, isUTC, extent) {
      var safeLimit = 10000;
      var unitNames = timeUnits;
      var iter = 0;

      function addTicksInSpan(interval, minTimestamp, maxTimestamp, getMethodName, setMethodName, isDate, out) {
        var date = new Date(minTimestamp);
        var dateTime = minTimestamp;
        var d = date[getMethodName](); // if (isDate) {
        //     d -= 1; // Starts with 0;   PENDING
        // }

        while (dateTime < maxTimestamp && dateTime <= extent[1]) {
          out.push({
            value: dateTime
          });
          d += interval;
          date[setMethodName](d);
          dateTime = date.getTime();
        } // This extra tick is for calcuating ticks of next level. Will not been added to the final result


        out.push({
          value: dateTime,
          notAdd: true
        });
      }

      function addLevelTicks(unitName, lastLevelTicks, levelTicks) {
        var newAddedTicks = [];
        var isFirstLevel = !lastLevelTicks.length;

        if (isUnitValueSame(getPrimaryTimeUnit(unitName), extent[0], extent[1], isUTC)) {
          return;
        }

        if (isFirstLevel) {
          lastLevelTicks = [{
            // TODO Optimize. Not include so may ticks.
            value: getFirstTimestampOfUnit(new Date(extent[0]), unitName, isUTC)
          }, {
            value: extent[1]
          }];
        }

        for (var i = 0; i < lastLevelTicks.length - 1; i++) {
          var startTick = lastLevelTicks[i].value;
          var endTick = lastLevelTicks[i + 1].value;

          if (startTick === endTick) {
            continue;
          }

          var interval = void 0;
          var getterName = void 0;
          var setterName = void 0;
          var isDate = false;

          switch (unitName) {
            case 'year':
              interval = Math.max(1, Math.round(approxInterval / ONE_DAY / 365));
              getterName = fullYearGetterName(isUTC);
              setterName = fullYearSetterName(isUTC);
              break;

            case 'half-year':
            case 'quarter':
            case 'month':
              interval = getMonthInterval(approxInterval);
              getterName = monthGetterName(isUTC);
              setterName = monthSetterName(isUTC);
              break;

            case 'week': // PENDING If week is added. Ignore day.

            case 'half-week':
            case 'day':
              interval = getDateInterval(approxInterval); // Use 32 days and let interval been 16

              getterName = dateGetterName(isUTC);
              setterName = dateSetterName(isUTC);
              isDate = true;
              break;

            case 'half-day':
            case 'quarter-day':
            case 'hour':
              interval = getHourInterval(approxInterval);
              getterName = hoursGetterName(isUTC);
              setterName = hoursSetterName(isUTC);
              break;

            case 'minute':
              interval = getMinutesAndSecondsInterval(approxInterval, true);
              getterName = minutesGetterName(isUTC);
              setterName = minutesSetterName(isUTC);
              break;

            case 'second':
              interval = getMinutesAndSecondsInterval(approxInterval, false);
              getterName = secondsGetterName(isUTC);
              setterName = secondsSetterName(isUTC);
              break;

            case 'millisecond':
              interval = getMillisecondsInterval(approxInterval);
              getterName = millisecondsGetterName(isUTC);
              setterName = millisecondsSetterName(isUTC);
              break;
          }

          addTicksInSpan(interval, startTick, endTick, getterName, setterName, isDate, newAddedTicks);

          if (unitName === 'year' && levelTicks.length > 1 && i === 0) {
            // Add nearest years to the left extent.
            levelTicks.unshift({
              value: levelTicks[0].value - interval
            });
          }
        }

        for (var i = 0; i < newAddedTicks.length; i++) {
          levelTicks.push(newAddedTicks[i]);
        } // newAddedTicks.length && console.log(unitName, newAddedTicks);


        return newAddedTicks;
      }

      var levelsTicks = [];
      var currentLevelTicks = [];
      var tickCount = 0;
      var lastLevelTickCount = 0;

      for (var i = 0; i < unitNames.length && iter++ < safeLimit; ++i) {
        var primaryTimeUnit = getPrimaryTimeUnit(unitNames[i]);

        if (!isPrimaryTimeUnit(unitNames[i])) {
          // TODO
          continue;
        }

        addLevelTicks(unitNames[i], levelsTicks[levelsTicks.length - 1] || [], currentLevelTicks);
        var nextPrimaryTimeUnit = unitNames[i + 1] ? getPrimaryTimeUnit(unitNames[i + 1]) : null;

        if (primaryTimeUnit !== nextPrimaryTimeUnit) {
          if (currentLevelTicks.length) {
            lastLevelTickCount = tickCount; // Remove the duplicate so the tick count can be precisely.

            currentLevelTicks.sort(function (a, b) {
              return a.value - b.value;
            });
            var levelTicksRemoveDuplicated = [];

            for (var i_1 = 0; i_1 < currentLevelTicks.length; ++i_1) {
              var tickValue = currentLevelTicks[i_1].value;

              if (i_1 === 0 || currentLevelTicks[i_1 - 1].value !== tickValue) {
                levelTicksRemoveDuplicated.push(currentLevelTicks[i_1]);

                if (tickValue >= extent[0] && tickValue <= extent[1]) {
                  tickCount++;
                }
              }
            }

            var targetTickNum = (extent[1] - extent[0]) / approxInterval; // Added too much in this level and not too less in last level

            if (tickCount > targetTickNum * 1.5 && lastLevelTickCount > targetTickNum / 1.5) {
              break;
            } // Only treat primary time unit as one level.


            levelsTicks.push(levelTicksRemoveDuplicated);

            if (tickCount > targetTickNum || bottomUnitName === unitNames[i]) {
              break;
            }
          } // Reset if next unitName is primary


          currentLevelTicks = [];
        }
      }

      if ("development" !== 'production') {
        if (iter >= safeLimit) {
          warn('Exceed safe limit.');
        }
      }

      var levelsTicksInExtent = filter(map(levelsTicks, function (levelTicks) {
        return filter(levelTicks, function (tick) {
          return tick.value >= extent[0] && tick.value <= extent[1] && !tick.notAdd;
        });
      }), function (levelTicks) {
        return levelTicks.length > 0;
      });
      var ticks = [];
      var maxLevel = levelsTicksInExtent.length - 1;

      for (var i = 0; i < levelsTicksInExtent.length; ++i) {
        var levelTicks = levelsTicksInExtent[i];

        for (var k = 0; k < levelTicks.length; ++k) {
          ticks.push({
            value: levelTicks[k].value,
            level: maxLevel - i
          });
        }
      }

      ticks.sort(function (a, b) {
        return a.value - b.value;
      }); // Remove duplicates

      var result = [];

      for (var i = 0; i < ticks.length; ++i) {
        if (i === 0 || ticks[i].value !== ticks[i - 1].value) {
          result.push(ticks[i]);
        }
      }

      return result;
    }

    Scale.registerClass(TimeScale);

    var scaleProto = Scale.prototype; // FIXME:TS refactor: not good to call it directly with `this`?

    var intervalScaleProto = IntervalScale.prototype;
    var roundingErrorFix = round;
    var mathFloor = Math.floor;
    var mathCeil = Math.ceil;
    var mathPow$1 = Math.pow;
    var mathLog = Math.log;

    var LogScale =
    /** @class */
    function (_super) {
      __extends(LogScale, _super);

      function LogScale() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = 'log';
        _this.base = 10;
        _this._originalScale = new IntervalScale(); // FIXME:TS actually used by `IntervalScale`

        _this._interval = 0;
        return _this;
      }
      /**
       * @param Whether expand the ticks to niced extent.
       */


      LogScale.prototype.getTicks = function (expandToNicedExtent) {
        var originalScale = this._originalScale;
        var extent = this._extent;
        var originalExtent = originalScale.getExtent();
        var ticks = intervalScaleProto.getTicks.call(this, expandToNicedExtent);
        return map(ticks, function (tick) {
          var val = tick.value;
          var powVal = round(mathPow$1(this.base, val)); // Fix #4158

          powVal = val === extent[0] && this._fixMin ? fixRoundingError(powVal, originalExtent[0]) : powVal;
          powVal = val === extent[1] && this._fixMax ? fixRoundingError(powVal, originalExtent[1]) : powVal;
          return {
            value: powVal
          };
        }, this);
      };

      LogScale.prototype.setExtent = function (start, end) {
        var base = mathLog(this.base); // log(-Infinity) is NaN, so safe guard here

        start = mathLog(Math.max(0, start)) / base;
        end = mathLog(Math.max(0, end)) / base;
        intervalScaleProto.setExtent.call(this, start, end);
      };
      /**
       * @return {number} end
       */


      LogScale.prototype.getExtent = function () {
        var base = this.base;
        var extent = scaleProto.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();
        this._fixMin && (extent[0] = fixRoundingError(extent[0], originalExtent[0]));
        this._fixMax && (extent[1] = fixRoundingError(extent[1], originalExtent[1]));
        return extent;
      };

      LogScale.prototype.unionExtent = function (extent) {
        this._originalScale.unionExtent(extent);

        var base = this.base;
        extent[0] = mathLog(extent[0]) / mathLog(base);
        extent[1] = mathLog(extent[1]) / mathLog(base);
        scaleProto.unionExtent.call(this, extent);
      };

      LogScale.prototype.unionExtentFromData = function (data, dim) {
        // TODO
        // filter value that <= 0
        this.unionExtent(data.getApproximateExtent(dim));
      };
      /**
       * Update interval and extent of intervals for nice ticks
       * @param approxTickNum default 10 Given approx tick number
       */


      LogScale.prototype.calcNiceTicks = 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(mathCeil(extent[0] / interval) * interval), round(mathFloor(extent[1] / interval) * interval)];
        this._interval = interval;
        this._niceExtent = niceExtent;
      };

      LogScale.prototype.calcNiceExtent = function (opt) {
        intervalScaleProto.calcNiceExtent.call(this, opt);
        this._fixMin = opt.fixMin;
        this._fixMax = opt.fixMax;
      };

      LogScale.prototype.parse = function (val) {
        return val;
      };

      LogScale.prototype.contain = function (val) {
        val = mathLog(val) / mathLog(this.base);
        return contain$1(val, this._extent);
      };

      LogScale.prototype.normalize = function (val) {
        val = mathLog(val) / mathLog(this.base);
        return normalize$1(val, this._extent);
      };

      LogScale.prototype.scale = function (val) {
        val = scale$2(val, this._extent);
        return mathPow$1(this.base, val);
      };

      LogScale.type = 'log';
      return LogScale;
    }(Scale);

    var proto = LogScale.prototype;
    proto.getMinorTicks = intervalScaleProto.getMinorTicks;
    proto.getLabel = intervalScaleProto.getLabel;

    function fixRoundingError(val, originalVal) {
      return roundingErrorFix(val, getPrecision(originalVal));
    }

    Scale.registerClass(LogScale);

    var ScaleRawExtentInfo =
    /** @class */
    function () {
      function ScaleRawExtentInfo(scale, model, // Usually: data extent from all series on this axis.
      originalExtent) {
        this._prepareParams(scale, model, originalExtent);
      }
      /**
       * Parameters depending on outside (like model, user callback)
       * are prepared and fixed here.
       */


      ScaleRawExtentInfo.prototype._prepareParams = function (scale, model, // Usually: data extent from all series on this axis.
      dataExtent) {
        if (dataExtent[1] < dataExtent[0]) {
          dataExtent = [NaN, NaN];
        }

        this._dataMin = dataExtent[0];
        this._dataMax = dataExtent[1];
        var isOrdinal = this._isOrdinal = scale.type === 'ordinal';
        this._needCrossZero = scale.type === 'interval' && model.getNeedCrossZero && model.getNeedCrossZero();
        var modelMinRaw = this._modelMinRaw = model.get('min', true);

        if (isFunction(modelMinRaw)) {
          // This callback always provides users the full data extent (before data is filtered).
          this._modelMinNum = parseAxisModelMinMax(scale, modelMinRaw({
            min: dataExtent[0],
            max: dataExtent[1]
          }));
        } else if (modelMinRaw !== 'dataMin') {
          this._modelMinNum = parseAxisModelMinMax(scale, modelMinRaw);
        }

        var modelMaxRaw = this._modelMaxRaw = model.get('max', true);

        if (isFunction(modelMaxRaw)) {
          // This callback always provides users the full data extent (before data is filtered).
          this._modelMaxNum = parseAxisModelMinMax(scale, modelMaxRaw({
            min: dataExtent[0],
            max: dataExtent[1]
          }));
        } else if (modelMaxRaw !== 'dataMax') {
          this._modelMaxNum = parseAxisModelMinMax(scale, modelMaxRaw);
        }

        if (isOrdinal) {
          // FIXME: there is a flaw here: if there is no "block" data processor like `dataZoom`,
          // and progressive rendering is using, here the category result might just only contain
          // the processed chunk rather than the entire result.
          this._axisDataLen = model.getCategories().length;
        } else {
          var boundaryGap = model.get('boundaryGap');
          var boundaryGapArr = isArray(boundaryGap) ? boundaryGap : [boundaryGap || 0, boundaryGap || 0];

          if (typeof boundaryGapArr[0] === 'boolean' || typeof boundaryGapArr[1] === 'boolean') {
            if ("development" !== 'production') {
              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.');
            }

            this._boundaryGapInner = [0, 0];
          } else {
            this._boundaryGapInner = [parsePercent(boundaryGapArr[0], 1), parsePercent(boundaryGapArr[1], 1)];
          }
        }
      };
      /**
       * Calculate extent by prepared parameters.
       * This method has no external dependency and can be called duplicatedly,
       * getting the same result.
       * If parameters changed, should call this method to recalcuate.
       */


      ScaleRawExtentInfo.prototype.calculate = function () {
        // 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.
        var isOrdinal = this._isOrdinal;
        var dataMin = this._dataMin;
        var dataMax = this._dataMax;
        var axisDataLen = this._axisDataLen;
        var boundaryGapInner = this._boundaryGapInner;
        var span = !isOrdinal ? dataMax - dataMin || Math.abs(dataMin) : null; // Currently if a `'value'` axis model min is specified as 'dataMin'/'dataMax',
        // `boundaryGap` will not be used. It's the different from specifying as `null`/`undefined`.

        var min = this._modelMinRaw === 'dataMin' ? dataMin : this._modelMinNum;
        var max = this._modelMaxRaw === 'dataMax' ? dataMax : this._modelMaxNum; // If `_modelMinNum`/`_modelMaxNum` is `null`/`undefined`, should not be fixed.

        var minFixed = min != null;
        var maxFixed = max != null;

        if (min == null) {
          min = isOrdinal ? axisDataLen ? 0 : NaN : dataMin - boundaryGapInner[0] * span;
        }

        if (max == null) {
          max = isOrdinal ? axisDataLen ? axisDataLen - 1 : NaN : dataMax + boundaryGapInner[1] * span;
        }

        (min == null || !isFinite(min)) && (min = NaN);
        (max == null || !isFinite(max)) && (max = NaN);
        var isBlank = eqNaN(min) || eqNaN(max) || isOrdinal && !axisDataLen; // If data extent modified, need to recalculated to ensure cross zero.

        if (this._needCrossZero) {
          // Axis is over zero and min is not set
          if (min > 0 && max > 0 && !minFixed) {
            min = 0; // minFixed = true;
          } // Axis is under zero and max is not set


          if (min < 0 && max < 0 && !maxFixed) {
            max = 0; // maxFixed = true;
          } // PENDING:
          // When `needCrossZero` and all data is positive/negative, should it be ensured
          // that the results processed by boundaryGap are positive/negative?
          // If so, here `minFixed`/`maxFixed` need to be set.

        }

        var determinedMin = this._determinedMin;
        var determinedMax = this._determinedMax;

        if (determinedMin != null) {
          min = determinedMin;
          minFixed = true;
        }

        if (determinedMax != null) {
          max = determinedMax;
          maxFixed = true;
        } // Ensure min/max be finite number or NaN here. (not to be null/undefined)
        // `NaN` means min/max axis is blank.


        return {
          min: min,
          max: max,
          minFixed: minFixed,
          maxFixed: maxFixed,
          isBlank: isBlank
        };
      };

      ScaleRawExtentInfo.prototype.modifyDataMinMax = function (minMaxName, val) {
        if ("development" !== 'production') {
          assert(!this.frozen);
        }

        this[DATA_MIN_MAX_ATTR[minMaxName]] = val;
      };

      ScaleRawExtentInfo.prototype.setDeterminedMinMax = function (minMaxName, val) {
        var attr = DETERMINED_MIN_MAX_ATTR[minMaxName];

        if ("development" !== 'production') {
          assert(!this.frozen // Earse them usually means logic flaw.
          && this[attr] == null);
        }

        this[attr] = val;
      };

      ScaleRawExtentInfo.prototype.freeze = function () {
        // @ts-ignore
        this.frozen = true;
      };

      return ScaleRawExtentInfo;
    }();
    var DETERMINED_MIN_MAX_ATTR = {
      min: '_determinedMin',
      max: '_determinedMax'
    };
    var DATA_MIN_MAX_ATTR = {
      min: '_dataMin',
      max: '_dataMax'
    };
    /**
     * Get scale min max and related info only depends on model settings.
     * This method can be called after coordinate system created.
     * For example, in data processing stage.
     *
     * Scale extent info probably be required multiple times during a workflow.
     * For example:
     * (1) `dataZoom` depends it to get the axis extent in "100%" state.
     * (2) `processor/extentCalculator` depends it to make sure whether axis extent is specified.
     * (3) `coordSys.update` use it to finally decide the scale extent.
     * But the callback of `min`/`max` should not be called multiple times.
     * The code below should not be implemented repeatedly either.
     * So we cache the result in the scale instance, which will be recreated at the beginning
     * of the workflow (because `scale` instance will be recreated each round of the workflow).
     */

    function ensureScaleRawExtentInfo(scale, model, // Usually: data extent from all series on this axis.
    originalExtent) {
      // Do not permit to recreate.
      var rawExtentInfo = scale.rawExtentInfo;

      if (rawExtentInfo) {
        return rawExtentInfo;
      }

      rawExtentInfo = new ScaleRawExtentInfo(scale, model, originalExtent); // @ts-ignore

      scale.rawExtentInfo = rawExtentInfo;
      return rawExtentInfo;
    }
    function parseAxisModelMinMax(scale, minMax) {
      return minMax == null ? null : eqNaN(minMax) ? NaN : scale.parse(minMax);
    }

    /**
     * Get axis scale extent before niced.
     * Item of returned array can only be number (including Infinity and NaN).
     *
     * Caution:
     * Precondition of calling this method:
     * The scale extent has been initialized using series data extent via
     * `scale.setExtent` or `scale.unionExtentFromData`;
     */

    function getScaleExtent(scale, model) {
      var scaleType = scale.type;
      var rawExtentResult = ensureScaleRawExtentInfo(scale, model, scale.getExtent()).calculate();
      scale.setBlank(rawExtentResult.isBlank);
      var min = rawExtentResult.min;
      var max = rawExtentResult.max; // 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_1 = false;
        each(barSeriesModels, function (seriesModel) {
          isBaseAxisAndHasBarSeries_1 = isBaseAxisAndHasBarSeries_1 || seriesModel.getBaseAxis() === model.axis;
        });

        if (isBaseAxisAndHasBarSeries_1) {
          // Calculate placement of bars on axis. TODO should be decoupled
          // with barLayout
          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: rawExtentResult.minFixed,
        fixMax: rawExtentResult.maxFixed
      };
    }

    function adjustScaleForOverflow(min, max, model, // Only support cartesian coord yet.
    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(barsOnCurrentAxis, function (item) {
        minOverflow = Math.min(item.offset, minOverflow);
      });
      var maxOverflow = -Infinity;
      each(barsOnCurrentAxis, function (item) {
        maxOverflow = Math.max(item.offset + item.width, maxOverflow);
      });
      minOverflow = Math.abs(minOverflow);
      maxOverflow = Math.abs(maxOverflow);
      var totalOverFlow = minOverflow + maxOverflow; // Calculate 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
      };
    } // Precondition of calling this method:
    // The scale extent has been initialized using series data extent via
    // `scale.setExtent` or `scale.unionExtentFromData`;


    function niceScaleExtent(scale, inModel) {
      var model = inModel;
      var extentInfo = getScaleExtent(scale, model);
      var extent = extentInfo.extent;
      var splitNumber = model.get('splitNumber');

      if (scale instanceof LogScale) {
        scale.base = model.get('logBase');
      }

      var scaleType = scale.type;
      var interval = model.get('interval');
      var isIntervalOrTime = scaleType === 'interval' || scaleType === 'time';
      scale.setExtent(extent[0], extent[1]);
      scale.calcNiceExtent({
        splitNumber: splitNumber,
        fixMin: extentInfo.fixMin,
        fixMax: extentInfo.fixMax,
        minInterval: isIntervalOrTime ? model.get('minInterval') : null,
        maxInterval: isIntervalOrTime ? 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

      if (interval != null) {
        scale.setInterval && scale.setInterval(interval);
      }
    }
    /**
     * @param axisType Default retrieve from model.type
     */

    function createScaleByModel(model, axisType) {
      axisType = axisType || model.get('type');

      if (axisType) {
        switch (axisType) {
          // Buildin scale
          case 'category':
            return new OrdinalScale({
              ordinalMeta: model.getOrdinalMeta ? model.getOrdinalMeta() : model.getCategories(),
              extent: [Infinity, -Infinity]
            });

          case 'time':
            return new TimeScale({
              locale: model.ecModel.getLocaleModel(),
              useUTC: model.ecModel.get('useUTC')
            });

          default:
            // case 'value'/'interval', 'log', or others.
            return new (Scale.getClass(axisType) || IntervalScale)();
        }
      }
    }
    /**
     * Check if the axis cross 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 axis
     * @return Label formatter function.
     *         param: {number} tickValue,
     *         param: {number} idx, the index in all ticks.
     *                         If category axis, this param is not required.
     *         return: {string} label string.
     */

    function makeLabelFormatter(axis) {
      var labelFormatter = axis.getLabelModel().get('formatter');
      var categoryTickStart = axis.type === 'category' ? axis.scale.getExtent()[0] : null;

      if (axis.scale.type === 'time') {
        return function (tpl) {
          return function (tick, idx) {
            return axis.scale.getFormattedLabel(tick, idx, tpl);
          };
        }(labelFormatter);
      } else if (isString(labelFormatter)) {
        return function (tpl) {
          return function (tick) {
            // For category axis, get raw value; for numeric axis,
            // get formatted label like '1,333,444'.
            var label = axis.scale.getLabel(tick);
            var text = tpl.replace('{value}', label != null ? label : '');
            return text;
          };
        }(labelFormatter);
      } else if (isFunction(labelFormatter)) {
        return function (cb) {
          return function (tick, 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 = tick.value - categoryTickStart;
            }

            return cb(getAxisRawValue(axis, tick), idx, tick.level != null ? {
              level: tick.level
            } : null);
          };
        }(labelFormatter);
      } else {
        return function (tick) {
          return axis.scale.getLabel(tick);
        };
      }
    }
    function getAxisRawValue(axis, tick) {
      // 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(tick) : tick.value;
    }
    /**
     * @param axis
     * @return 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 realNumberScaleTicks;
      var tickCount;
      var categoryScaleExtent = scale.getExtent(); // Optimize for large category data, avoid call `getTicks()`.

      if (scale instanceof OrdinalScale) {
        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 tick = realNumberScaleTicks ? realNumberScaleTicks[i] : {
          value: categoryScaleExtent[0] + i
        };
        var label = labelFormatter(tick, i);
        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 beforeWidth = textRect.width;
      var beforeHeight = textRect.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(textRect.x, textRect.y, afterWidth, afterHeight);
      return rotatedRect;
    }
    /**
     * @param 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 regardless of overlap.
     * @param {Object} axis axisModel.axis
     */

    function shouldShowAllLabels(axis) {
      return axis.type === 'category' && getOptionCategoryInterval(axis.getLabelModel()) === 0;
    }
    function getDataDimensionsOnAxis(data, axisDim) {
      // Remove duplicated dat dimensions caused by `getStackedDimension`.
      var dataDimMap = {}; // Currently `mapDimensionsAll` will contain stack result dimension ('__\0ecstackresult').
      // PENDING: is it reasonable? Do we need to remove the original dim from "coord dim" since
      // there has been stacked result dim?

      each(data.mapDimensionsAll(axisDim), function (dataDim) {
        // For example, the extent of the original dimension
        // is [0.1, 0.5], the extent of the `stackResultDimension`
        // is [7, 9], the final extent should NOT include [0.1, 0.5],
        // because there is no graphic corresponding to [0.1, 0.5].
        // See the case in `test/area-stack.html` `main1`, where area line
        // stack needs `yAxis` not start from 0.
        dataDimMap[getStackedDimension(data, dataDim)] = true;
      });
      return keys(dataDimMap);
    }
    function unionAxisExtentFromData(dataExtent, data, axisDim) {
      if (data) {
        each(getDataDimensionsOnAxis(data, axisDim), function (dim) {
          var seriesExtent = data.getApproximateExtent(dim);
          seriesExtent[0] < dataExtent[0] && (dataExtent[0] = seriesExtent[0]);
          seriesExtent[1] > dataExtent[1] && (dataExtent[1] = seriesExtent[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.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * 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.
    */
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    var AxisModelCommonMixin =
    /** @class */
    function () {
      function AxisModelCommonMixin() {}

      AxisModelCommonMixin.prototype.getNeedCrossZero = function () {
        var option = this.option;
        return !option.scale;
      };
      /**
       * Should be implemented by each axis model if necessary.
       * @return coordinate system model
       */


      AxisModelCommonMixin.prototype.getCoordSysModel = function () {
        return;
      };

      return AxisModelCommonMixin;
    }();

    /**
     * Create a multi dimension List structure from seriesModel.
     */

    function createList(seriesModel) {
      return createSeriesData(null, seriesModel);
    } // export function createGraph(seriesModel) {
    var dataStack$1 = {
      isDimensionStacked: isDimensionStacked,
      enableDataStack: enableDataStack,
      getStackedDimension: getStackedDimension
    };
    /**
     * Create scale
     * @param {Array.<number>} dataExtent
     * @param {Object|module:echarts/Model} option If `optoin.type`
     *        is secified, it can only be `'value'` currently.
     */

    function createScale(dataExtent, option) {
      var axisModel = option;

      if (!(option instanceof Model)) {
        axisModel = new Model(option); // FIXME
        // Currently AxisModelCommonMixin has nothing to do with the
        // the requirements of `axisHelper.createScaleByModel`. For
        // example the methods `getCategories` and `getOrdinalMeta`
        // are required for `'category'` axis, and ecModel is required
        // for `'time'` axis. But occasionally echarts-gl happened
        // to only use `'value'` axis.
        // zrUtil.mixin(axisModel, AxisModelCommonMixin);
      }

      var scale = createScaleByModel(axisModel);
      scale.setExtent(dataExtent[0], dataExtent[1]);
      niceScaleExtent(scale, axisModel);
      return scale;
    }
    /**
     * Mixin common methods to axis model,
     *
     * Include methods
     * `getFormattedLabels() => Array.<string>`
     * `getCategories() => Array.<string>`
     * `getMin(origin: boolean) => number`
     * `getMax(origin: boolean) => number`
     * `getNeedCrossZero() => boolean`
     */

    function mixinAxisModelCommonMethods(Model) {
      mixin(Model, AxisModelCommonMixin);
    }
    function createTextStyle$1(textStyleModel, opts) {
      opts = opts || {};
      return createTextStyle(textStyleModel, null, null, opts.state !== 'normal');
    }

    var helper = /*#__PURE__*/Object.freeze({
        __proto__: null,
        createList: createList,
        getLayoutRect: getLayoutRect,
        dataStack: dataStack$1,
        createScale: createScale,
        mixinAxisModelCommonMethods: mixinAxisModelCommonMethods,
        getECData: getECData,
        createTextStyle: createTextStyle$1,
        createDimensions: createDimensions,
        createSymbol: createSymbol,
        enableHoverEmphasis: enableHoverEmphasis
    });

    var EPSILON$4 = 1e-8;
    function isAroundEqual$1(a, b) {
        return Math.abs(a - b) < EPSILON$4;
    }
    function contain$2(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;
        }
        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;
    }

    var TMP_TRANSFORM = [];

    function transformPoints(points, transform) {
      for (var p = 0; p < points.length; p++) {
        applyTransform(points[p], points[p], transform);
      }
    }

    function updateBBoxFromPoints(points, min$1, max$1, projection) {
      for (var i = 0; i < points.length; i++) {
        var p = points[i];

        if (projection) {
          // projection may return null point.
          p = projection.project(p);
        }

        if (p && isFinite(p[0]) && isFinite(p[1])) {
          min(min$1, min$1, p);
          max(max$1, max$1, p);
        }
      }
    }

    function centroid(points) {
      var signedArea = 0;
      var cx = 0;
      var cy = 0;
      var len = points.length;
      var x0 = points[len - 1][0];
      var y0 = points[len - 1][1]; // Polygon should been closed.

      for (var i = 0; i < len; i++) {
        var x1 = points[i][0];
        var y1 = points[i][1];
        var a = x0 * y1 - x1 * y0;
        signedArea += a;
        cx += (x0 + x1) * a;
        cy += (y0 + y1) * a;
        x0 = x1;
        y0 = y1;
      }

      return signedArea ? [cx / signedArea / 3, cy / signedArea / 3, signedArea] : [points[0][0] || 0, points[0][1] || 0];
    }

    var Region =
    /** @class */
    function () {
      function Region(name) {
        this.name = name;
      }

      Region.prototype.setCenter = function (center) {
        this._center = center;
      };
      /**
       * Get center point in data unit. That is,
       * for GeoJSONRegion, the unit is lat/lng,
       * for GeoSVGRegion, the unit is SVG local coord.
       */


      Region.prototype.getCenter = function () {
        var center = this._center;

        if (!center) {
          // In most cases there are no need to calculate this center.
          // So calculate only when called.
          center = this._center = this.calcCenter();
        }

        return center;
      };

      return Region;
    }();

    var GeoJSONPolygonGeometry =
    /** @class */
    function () {
      function GeoJSONPolygonGeometry(exterior, interiors) {
        this.type = 'polygon';
        this.exterior = exterior;
        this.interiors = interiors;
      }

      return GeoJSONPolygonGeometry;
    }();

    var GeoJSONLineStringGeometry =
    /** @class */
    function () {
      function GeoJSONLineStringGeometry(points) {
        this.type = 'linestring';
        this.points = points;
      }

      return GeoJSONLineStringGeometry;
    }();

    var GeoJSONRegion =
    /** @class */
    function (_super) {
      __extends(GeoJSONRegion, _super);

      function GeoJSONRegion(name, geometries, cp) {
        var _this = _super.call(this, name) || this;

        _this.type = 'geoJSON';
        _this.geometries = geometries;
        _this._center = cp && [cp[0], cp[1]];
        return _this;
      }

      GeoJSONRegion.prototype.calcCenter = function () {
        var geometries = this.geometries;
        var largestGeo;
        var largestGeoSize = 0;

        for (var i = 0; i < geometries.length; i++) {
          var geo = geometries[i];
          var exterior = geo.exterior; // Simple trick to use points count instead of polygon area as region size.
          // Ignore linestring

          var size = exterior && exterior.length;

          if (size > largestGeoSize) {
            largestGeo = geo;
            largestGeoSize = size;
          }
        }

        if (largestGeo) {
          return centroid(largestGeo.exterior);
        } // from bounding rect by default.


        var rect = this.getBoundingRect();
        return [rect.x + rect.width / 2, rect.y + rect.height / 2];
      };

      GeoJSONRegion.prototype.getBoundingRect = function (projection) {
        var rect = this._rect; // Always recalculate if using projection.

        if (rect && !projection) {
          return rect;
        }

        var min = [Infinity, Infinity];
        var max = [-Infinity, -Infinity];
        var geometries = this.geometries;
        each(geometries, function (geo) {
          if (geo.type === 'polygon') {
            // Doesn't consider hole
            updateBBoxFromPoints(geo.exterior, min, max, projection);
          } else {
            each(geo.points, function (points) {
              updateBBoxFromPoints(points, min, max, projection);
            });
          }
        }); // Normalie invalid bounding.

        if (!(isFinite(min[0]) && isFinite(min[1]) && isFinite(max[0]) && isFinite(max[1]))) {
          min[0] = min[1] = max[0] = max[1] = 0;
        }

        rect = new BoundingRect(min[0], min[1], max[0] - min[0], max[1] - min[1]);

        if (!projection) {
          this._rect = rect;
        }

        return rect;
      };

      GeoJSONRegion.prototype.contain = function (coord) {
        var rect = this.getBoundingRect();
        var geometries = this.geometries;

        if (!rect.contain(coord[0], coord[1])) {
          return false;
        }

        loopGeo: for (var i = 0, len = geometries.length; i < len; i++) {
          var geo = geometries[i]; // Only support polygon.

          if (geo.type !== 'polygon') {
            continue;
          }

          var exterior = geo.exterior;
          var interiors = geo.interiors;

          if (contain$2(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$2(interiors[k], coord[0], coord[1])) {
                continue loopGeo;
              }
            }

            return true;
          }
        }

        return false;
      };
      /**
       * Transform the raw coords to target bounding.
       * @param x
       * @param y
       * @param width
       * @param height
       */


      GeoJSONRegion.prototype.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++) {
          var geo = geometries[i];

          if (geo.type === 'polygon') {
            transformPoints(geo.exterior, transform);
            each(geo.interiors, function (interior) {
              transformPoints(interior, transform);
            });
          } else {
            each(geo.points, function (points) {
              transformPoints(points, transform);
            });
          }
        }

        rect = this._rect;
        rect.copy(target); // Update center

        this._center = [rect.x + rect.width / 2, rect.y + rect.height / 2];
      };

      GeoJSONRegion.prototype.cloneShallow = function (name) {
        name == null && (name = this.name);
        var newRegion = new GeoJSONRegion(name, this.geometries, this._center);
        newRegion._rect = this._rect;
        newRegion.transformTo = null; // Simply avoid to be called.

        return newRegion;
      };

      return GeoJSONRegion;
    }(Region);

    var GeoSVGRegion =
    /** @class */
    function (_super) {
      __extends(GeoSVGRegion, _super);

      function GeoSVGRegion(name, elOnlyForCalculate) {
        var _this = _super.call(this, name) || this;

        _this.type = 'geoSVG';
        _this._elOnlyForCalculate = elOnlyForCalculate;
        return _this;
      }

      GeoSVGRegion.prototype.calcCenter = function () {
        var el = this._elOnlyForCalculate;
        var rect = el.getBoundingRect();
        var center = [rect.x + rect.width / 2, rect.y + rect.height / 2];
        var mat = identity(TMP_TRANSFORM);
        var target = el;

        while (target && !target.isGeoSVGGraphicRoot) {
          mul$1(mat, target.getLocalTransform(), mat);
          target = target.parent;
        }

        invert(mat, mat);
        applyTransform(center, center, mat);
        return center;
      };

      return GeoSVGRegion;
    }(Region);

    function decode(json) {
      if (!json.UTF8Encoding) {
        return json;
      }

      var jsonCompressed = json;
      var encodeScale = jsonCompressed.UTF8Scale;

      if (encodeScale == null) {
        encodeScale = 1024;
      }

      var features = jsonCompressed.features;
      each(features, function (feature) {
        var geometry = feature.geometry;
        var encodeOffsets = geometry.encodeOffsets;
        var coordinates = geometry.coordinates; // Geometry may be appeded manually in the script after json loaded.
        // In this case this geometry is usually not encoded.

        if (!encodeOffsets) {
          return;
        }

        switch (geometry.type) {
          case 'LineString':
            geometry.coordinates = decodeRing(coordinates, encodeOffsets, encodeScale);
            break;

          case 'Polygon':
            decodeRings(coordinates, encodeOffsets, encodeScale);
            break;

          case 'MultiLineString':
            decodeRings(coordinates, encodeOffsets, encodeScale);
            break;

          case 'MultiPolygon':
            each(coordinates, function (rings, idx) {
              return decodeRings(rings, encodeOffsets[idx], encodeScale);
            });
        }
      }); // Has been decoded

      jsonCompressed.UTF8Encoding = false;
      return jsonCompressed;
    }

    function decodeRings(rings, encodeOffsets, encodeScale) {
      for (var c = 0; c < rings.length; c++) {
        rings[c] = decodeRing(rings[c], encodeOffsets[c], encodeScale);
      }
    }

    function decodeRing(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;
    }

    function parseGeoJSON(geoJson, nameProperty) {
      geoJson = 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 geometries = [];

        switch (geo.type) {
          case 'Polygon':
            var coordinates = geo.coordinates; // According to the GeoJSON specification.
            // First must be exterior, and the rest are all interior(holes).

            geometries.push(new GeoJSONPolygonGeometry(coordinates[0], coordinates.slice(1)));
            break;

          case 'MultiPolygon':
            each(geo.coordinates, function (item) {
              if (item[0]) {
                geometries.push(new GeoJSONPolygonGeometry(item[0], item.slice(1)));
              }
            });
            break;

          case 'LineString':
            geometries.push(new GeoJSONLineStringGeometry([geo.coordinates]));
            break;

          case 'MultiLineString':
            geometries.push(new GeoJSONLineStringGeometry(geo.coordinates));
        }

        var region = new GeoJSONRegion(properties[nameProperty || 'name'], geometries, properties.cp);
        region.properties = properties;
        return region;
      });
    }

    var number = /*#__PURE__*/Object.freeze({
        __proto__: null,
        linearMap: linearMap,
        round: round,
        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,
        numericToNumber: numericToNumber
    });

    var time = /*#__PURE__*/Object.freeze({
        __proto__: null,
        parse: parseDate,
        format: format
    });

    var graphic$1 = /*#__PURE__*/Object.freeze({
        __proto__: null,
        extendShape: extendShape,
        extendPath: extendPath,
        makePath: makePath,
        makeImage: makeImage,
        mergePath: mergePath$1,
        resizePath: resizePath,
        createIcon: createIcon,
        updateProps: updateProps,
        initProps: initProps,
        getTransform: getTransform,
        clipPointsByRect: clipPointsByRect,
        clipRectByRect: clipRectByRect,
        registerShape: registerShape,
        getShapeClass: getShapeClass,
        Group: Group,
        Image: ZRImage,
        Text: ZRText,
        Circle: Circle,
        Ellipse: Ellipse,
        Sector: Sector,
        Ring: Ring,
        Polygon: Polygon,
        Polyline: Polyline,
        Rect: Rect,
        Line: Line,
        BezierCurve: BezierCurve,
        Arc: Arc,
        IncrementalDisplayable: IncrementalDisplayable,
        CompoundPath: CompoundPath,
        LinearGradient: LinearGradient,
        RadialGradient: RadialGradient,
        BoundingRect: BoundingRect
    });

    var format$1 = /*#__PURE__*/Object.freeze({
        __proto__: null,
        addCommas: addCommas,
        toCamelCase: toCamelCase,
        normalizeCssArray: normalizeCssArray$1,
        encodeHTML: encodeHTML,
        formatTpl: formatTpl,
        getTooltipMarker: getTooltipMarker,
        formatTime: formatTime,
        capitalFirst: capitalFirst,
        truncateText: truncateText,
        getTextRect: getTextRect
    });

    var util$1 = /*#__PURE__*/Object.freeze({
        __proto__: null,
        map: map,
        each: each,
        indexOf: indexOf,
        inherits: inherits,
        reduce: reduce,
        filter: filter,
        bind: bind,
        curry: curry,
        isArray: isArray,
        isString: isString,
        isObject: isObject,
        isFunction: isFunction,
        extend: extend,
        defaults: defaults,
        clone: clone,
        merge: merge
    });

    var inner$5 = makeInner();
    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: map(axis.scale.getTicks(), function (tick) {
          return tick.value;
        })
      };
    }

    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(optionLabelInterval)) {
        labels = makeLabelsByCustomizedCategoryInterval(axis, optionLabelInterval);
      } else {
        numericLabelInterval = optionLabelInterval === 'auto' ? makeAutoCategoryInterval(axis) : optionLabelInterval;
        labels = makeLabelsByNumericCategoryInterval(axis, numericLabelInterval);
      } // Cache to avoid calling interval function repeatedly.


      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(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 repeatedly.


      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 (tick, idx) {
          return {
            level: tick.level,
            formattedLabel: labelFormatter(tick, idx),
            rawLabel: axis.scale.getLabel(tick),
            tickValue: tick.value
          };
        })
      };
    }

    function getListCache(axis, prop) {
      // Because key can be a function, and cache size always is small, we use array cache.
      return inner$5(axis)[prop] || (inner$5(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$5(axis).autoInterval;
      return result != null ? result : inner$5(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({
          value: 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$5(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 hidden labels might not be shown again.
      && cache.axisExtent0 === axisExtent[0] && cache.axisExtent1 === 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.axisExtent0 = axisExtent[0];
          cache.axisExtent1 = 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(tickValue) {
        var tickObj = {
          value: tickValue
        };
        result.push(onlyTick ? tickValue : {
          formattedLabel: labelFormatter(tickObj),
          rawLabel: ordinalScale.getLabel(tickObj),
          tickValue: tickValue
        });
      }

      return result;
    }

    function makeLabelsByCustomizedCategoryInterval(axis, categoryInterval, onlyTick) {
      var ordinalScale = axis.scale;
      var labelFormatter = makeLabelFormatter(axis);
      var result = [];
      each(ordinalScale.getTicks(), function (tick) {
        var rawLabel = ordinalScale.getLabel(tick);
        var tickValue = tick.value;

        if (categoryInterval(tick.value, rawLabel)) {
          result.push(onlyTick ? tickValue : {
            formattedLabel: labelFormatter(tick),
            rawLabel: rawLabel,
            tickValue: tickValue
          });
        }
      });
      return result;
    }

    var NORMALIZED_EXTENT = [0, 1];
    /**
     * Base class of Axis.
     */

    var Axis =
    /** @class */
    function () {
      function Axis(dim, scale, extent) {
        this.onBand = false;
        this.inverse = false;
        this.dim = dim;
        this.scale = scale;
        this._extent = extent || [0, 0];
      }
      /**
       * If axis extent contain given coord
       */


      Axis.prototype.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
       */


      Axis.prototype.containData = function (data) {
        return this.scale.contain(data);
      };
      /**
       * Get coord extent.
       */


      Axis.prototype.getExtent = function () {
        return this._extent.slice();
      };
      /**
       * Get precision used for formatting
       */


      Axis.prototype.getPixelPrecision = function (dataExtent) {
        return getPixelPrecision(dataExtent || this.scale.getExtent(), this._extent);
      };
      /**
       * Set coord extent
       */


      Axis.prototype.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
       */


      Axis.prototype.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
       */


      Axis.prototype.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
       */


      Axis.prototype.pointToData = function (point, clamp) {
        // Should be implemented in derived class if necessary.
        return;
      };
      /**
       * 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 opt.tickModel default: axis.model.getModel('axisTick')
       * @param 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.
       */


      Axis.prototype.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 (tickVal) {
          return {
            coord: this.dataToCoord(this.scale.type === 'ordinal' ? this.scale.getRawOrdinalNumber(tickVal) : tickVal),
            tickValue: tickVal
          };
        }, this);
        var alignWithLabel = tickModel.get('alignWithLabel');
        fixOnBandTicksCoords(this, ticksCoords, alignWithLabel, opt.clamp);
        return ticksCoords;
      };

      Axis.prototype.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;
      };

      Axis.prototype.getViewLabels = function () {
        return createAxisLabels(this).labels;
      };

      Axis.prototype.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 overridden to:
       * `axisModel.getModel('axisTick', grid3DModel.getModel('axisTick'));`
       */


      Axis.prototype.getTickModel = function () {
        return this.model.getModel('axisTick');
      };
      /**
       * Get width of band
       */


      Axis.prototype.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;
      };
      /**
       * Only be called in category axis.
       * Can be overridden, consider other axes like in 3D.
       * @return Auto interval for cateogry axis tick and label
       */


      Axis.prototype.calculateCategoryInterval = function () {
        return calculateCategoryInterval(this);
      };

      return Axis;
    }();

    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_1 = (ticksCoords[ticksLen - 1].coord - ticksCoords[0].coord) / crossLen;
        each(ticksCoords, function (ticksItem) {
          ticksItem.coord -= shift_1 / 2;
        });
        var dataExtent = axis.scale.getExtent();
        diffSize = 1 + dataExtent[1] - ticksCoords[ticksLen - 1].tickValue;
        last = {
          coord: ticksCoords[ticksLen - 1].coord + shift_1 * 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 unnecessary tick added.
        a = round(a);
        b = round(b);
        return inverse ? a > b : a < b;
      }
    }

    // Should use `ComponentModel.extend` or `class XXXX extend ComponentModel` to create class.
    // Then use `registerComponentModel` in `install` parameter when `use` this extension. For example:
    // class Bar3DModel extends ComponentModel {}
    // export function install(registers) { registers.registerComponentModel(Bar3DModel); }
    // echarts.use(install);

    function extendComponentModel(proto) {
      var Model = ComponentModel.extend(proto);
      ComponentModel.registerClass(Model);
      return Model;
    }
    function extendComponentView(proto) {
      var View = ComponentView.extend(proto);
      ComponentView.registerClass(View);
      return View;
    }
    function extendSeriesModel(proto) {
      var Model = SeriesModel.extend(proto);
      SeriesModel.registerClass(Model);
      return Model;
    }
    function extendChartView(proto) {
      var View = ChartView.extend(proto);
      ChartView.registerClass(View);
      return View;
    }

    var PI2$6 = Math.PI * 2;
    var CMD$3 = PathProxy.CMD;
    var DEFAULT_SEARCH_SPACE = ['top', 'right', 'bottom', 'left'];

    function getCandidateAnchor(pos, distance, rect, outPt, outDir) {
      var width = rect.width;
      var height = rect.height;

      switch (pos) {
        case 'top':
          outPt.set(rect.x + width / 2, rect.y - distance);
          outDir.set(0, -1);
          break;

        case 'bottom':
          outPt.set(rect.x + width / 2, rect.y + height + distance);
          outDir.set(0, 1);
          break;

        case 'left':
          outPt.set(rect.x - distance, rect.y + height / 2);
          outDir.set(-1, 0);
          break;

        case 'right':
          outPt.set(rect.x + width + distance, rect.y + height / 2);
          outDir.set(1, 0);
          break;
      }
    }

    function projectPointToArc(cx, cy, r, startAngle, endAngle, anticlockwise, x, y, out) {
      x -= cx;
      y -= cy;
      var d = Math.sqrt(x * x + y * y);
      x /= d;
      y /= d; // Intersect point.

      var ox = x * r + cx;
      var oy = y * r + cy;

      if (Math.abs(startAngle - endAngle) % PI2$6 < 1e-4) {
        // Is a circle
        out[0] = ox;
        out[1] = oy;
        return d - r;
      }

      if (anticlockwise) {
        var tmp = startAngle;
        startAngle = normalizeRadian(endAngle);
        endAngle = normalizeRadian(tmp);
      } else {
        startAngle = normalizeRadian(startAngle);
        endAngle = normalizeRadian(endAngle);
      }

      if (startAngle > endAngle) {
        endAngle += PI2$6;
      }

      var angle = Math.atan2(y, x);

      if (angle < 0) {
        angle += PI2$6;
      }

      if (angle >= startAngle && angle <= endAngle || angle + PI2$6 >= startAngle && angle + PI2$6 <= endAngle) {
        // Project point is on the arc.
        out[0] = ox;
        out[1] = oy;
        return d - r;
      }

      var x1 = r * Math.cos(startAngle) + cx;
      var y1 = r * Math.sin(startAngle) + cy;
      var x2 = r * Math.cos(endAngle) + cx;
      var y2 = r * Math.sin(endAngle) + cy;
      var d1 = (x1 - x) * (x1 - x) + (y1 - y) * (y1 - y);
      var d2 = (x2 - x) * (x2 - x) + (y2 - y) * (y2 - y);

      if (d1 < d2) {
        out[0] = x1;
        out[1] = y1;
        return Math.sqrt(d1);
      } else {
        out[0] = x2;
        out[1] = y2;
        return Math.sqrt(d2);
      }
    }

    function projectPointToLine(x1, y1, x2, y2, x, y, out, limitToEnds) {
      var dx = x - x1;
      var dy = y - y1;
      var dx1 = x2 - x1;
      var dy1 = y2 - y1;
      var lineLen = Math.sqrt(dx1 * dx1 + dy1 * dy1);
      dx1 /= lineLen;
      dy1 /= lineLen; // dot product

      var projectedLen = dx * dx1 + dy * dy1;
      var t = projectedLen / lineLen;

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

      t *= lineLen;
      var ox = out[0] = x1 + t * dx1;
      var oy = out[1] = y1 + t * dy1;
      return Math.sqrt((ox - x) * (ox - x) + (oy - y) * (oy - y));
    }

    function projectPointToRect(x1, y1, width, height, x, y, out) {
      if (width < 0) {
        x1 = x1 + width;
        width = -width;
      }

      if (height < 0) {
        y1 = y1 + height;
        height = -height;
      }

      var x2 = x1 + width;
      var y2 = y1 + height;
      var ox = out[0] = Math.min(Math.max(x, x1), x2);
      var oy = out[1] = Math.min(Math.max(y, y1), y2);
      return Math.sqrt((ox - x) * (ox - x) + (oy - y) * (oy - y));
    }

    var tmpPt = [];

    function nearestPointOnRect(pt, rect, out) {
      var dist = projectPointToRect(rect.x, rect.y, rect.width, rect.height, pt.x, pt.y, tmpPt);
      out.set(tmpPt[0], tmpPt[1]);
      return dist;
    }
    /**
     * Calculate min distance corresponding point.
     * This method won't evaluate if point is in the path.
     */


    function nearestPointOnPath(pt, path, out) {
      var xi = 0;
      var yi = 0;
      var x0 = 0;
      var y0 = 0;
      var x1;
      var y1;
      var minDist = Infinity;
      var data = path.data;
      var x = pt.x;
      var y = pt.y;

      for (var i = 0; i < data.length;) {
        var cmd = data[i++];

        if (i === 1) {
          xi = data[i];
          yi = data[i + 1];
          x0 = xi;
          y0 = yi;
        }

        var d = minDist;

        switch (cmd) {
          case CMD$3.M:
            // moveTo 命令重新创建一个新的 subpath, 并且更新新的起点
            // 在 closePath 的时候使用
            x0 = data[i++];
            y0 = data[i++];
            xi = x0;
            yi = y0;
            break;

          case CMD$3.L:
            d = projectPointToLine(xi, yi, data[i], data[i + 1], x, y, tmpPt, true);
            xi = data[i++];
            yi = data[i++];
            break;

          case CMD$3.C:
            d = cubicProjectPoint(xi, yi, data[i++], data[i++], data[i++], data[i++], data[i], data[i + 1], x, y, tmpPt);
            xi = data[i++];
            yi = data[i++];
            break;

          case CMD$3.Q:
            d = quadraticProjectPoint(xi, yi, data[i++], data[i++], data[i], data[i + 1], x, y, tmpPt);
            xi = data[i++];
            yi = data[i++];
            break;

          case CMD$3.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++]);
            x1 = Math.cos(theta) * rx + cx;
            y1 = Math.sin(theta) * ry + cy; // 不是直接使用 arc 命令

            if (i <= 1) {
              // 第一个命令起点还未定义
              x0 = x1;
              y0 = y1;
            } // zr 使用scale来模拟椭圆, 这里也对x做一定的缩放


            var _x = (x - cx) * ry / rx + cx;

            d = projectPointToArc(cx, cy, ry, theta, theta + dTheta, anticlockwise, _x, y, tmpPt);
            xi = Math.cos(theta + dTheta) * rx + cx;
            yi = Math.sin(theta + dTheta) * ry + cy;
            break;

          case CMD$3.R:
            x0 = xi = data[i++];
            y0 = yi = data[i++];
            var width = data[i++];
            var height = data[i++];
            d = projectPointToRect(x0, y0, width, height, x, y, tmpPt);
            break;

          case CMD$3.Z:
            d = projectPointToLine(xi, yi, x0, y0, x, y, tmpPt, true);
            xi = x0;
            yi = y0;
            break;
        }

        if (d < minDist) {
          minDist = d;
          out.set(tmpPt[0], tmpPt[1]);
        }
      }

      return minDist;
    } // Temporal variable for intermediate usage.


    var pt0 = new Point();
    var pt1 = new Point();
    var pt2 = new Point();
    var dir = new Point();
    var dir2 = new Point();
    /**
     * Calculate a proper guide line based on the label position and graphic element definition
     * @param label
     * @param labelRect
     * @param target
     * @param targetRect
     */

    function updateLabelLinePoints(target, labelLineModel) {
      if (!target) {
        return;
      }

      var labelLine = target.getTextGuideLine();
      var label = target.getTextContent(); // Needs to create text guide in each charts.

      if (!(label && labelLine)) {
        return;
      }

      var labelGuideConfig = target.textGuideLineConfig || {};
      var points = [[0, 0], [0, 0], [0, 0]];
      var searchSpace = labelGuideConfig.candidates || DEFAULT_SEARCH_SPACE;
      var labelRect = label.getBoundingRect().clone();
      labelRect.applyTransform(label.getComputedTransform());
      var minDist = Infinity;
      var anchorPoint = labelGuideConfig.anchor;
      var targetTransform = target.getComputedTransform();
      var targetInversedTransform = targetTransform && invert([], targetTransform);
      var len = labelLineModel.get('length2') || 0;

      if (anchorPoint) {
        pt2.copy(anchorPoint);
      }

      for (var i = 0; i < searchSpace.length; i++) {
        var candidate = searchSpace[i];
        getCandidateAnchor(candidate, 0, labelRect, pt0, dir);
        Point.scaleAndAdd(pt1, pt0, dir, len); // Transform to target coord space.

        pt1.transform(targetInversedTransform); // Note: getBoundingRect will ensure the `path` being created.

        var boundingRect = target.getBoundingRect();
        var dist = anchorPoint ? anchorPoint.distance(pt1) : target instanceof Path ? nearestPointOnPath(pt1, target.path, pt2) : nearestPointOnRect(pt1, boundingRect, pt2); // TODO pt2 is in the path

        if (dist < minDist) {
          minDist = dist; // Transform back to global space.

          pt1.transform(targetTransform);
          pt2.transform(targetTransform);
          pt2.toArray(points[0]);
          pt1.toArray(points[1]);
          pt0.toArray(points[2]);
        }
      }

      limitTurnAngle(points, labelLineModel.get('minTurnAngle'));
      labelLine.setShape({
        points: points
      });
    } // Temporal variable for the limitTurnAngle function

    var tmpArr = [];
    var tmpProjPoint = new Point();
    /**
     * Reduce the line segment attached to the label to limit the turn angle between two segments.
     * @param linePoints
     * @param minTurnAngle Radian of minimum turn angle. 0 - 180
     */

    function limitTurnAngle(linePoints, minTurnAngle) {
      if (!(minTurnAngle <= 180 && minTurnAngle > 0)) {
        return;
      }

      minTurnAngle = minTurnAngle / 180 * Math.PI; // The line points can be
      //      /pt1----pt2 (label)
      //     /
      // pt0/

      pt0.fromArray(linePoints[0]);
      pt1.fromArray(linePoints[1]);
      pt2.fromArray(linePoints[2]);
      Point.sub(dir, pt0, pt1);
      Point.sub(dir2, pt2, pt1);
      var len1 = dir.len();
      var len2 = dir2.len();

      if (len1 < 1e-3 || len2 < 1e-3) {
        return;
      }

      dir.scale(1 / len1);
      dir2.scale(1 / len2);
      var angleCos = dir.dot(dir2);
      var minTurnAngleCos = Math.cos(minTurnAngle);

      if (minTurnAngleCos < angleCos) {
        // Smaller than minTurnAngle
        // Calculate project point of pt0 on pt1-pt2
        var d = projectPointToLine(pt1.x, pt1.y, pt2.x, pt2.y, pt0.x, pt0.y, tmpArr, false);
        tmpProjPoint.fromArray(tmpArr); // Calculate new projected length with limited minTurnAngle and get the new connect point

        tmpProjPoint.scaleAndAdd(dir2, d / Math.tan(Math.PI - minTurnAngle)); // Limit the new calculated connect point between pt1 and pt2.

        var t = pt2.x !== pt1.x ? (tmpProjPoint.x - pt1.x) / (pt2.x - pt1.x) : (tmpProjPoint.y - pt1.y) / (pt2.y - pt1.y);

        if (isNaN(t)) {
          return;
        }

        if (t < 0) {
          Point.copy(tmpProjPoint, pt1);
        } else if (t > 1) {
          Point.copy(tmpProjPoint, pt2);
        }

        tmpProjPoint.toArray(linePoints[1]);
      }
    }
    /**
     * Limit the angle of line and the surface
     * @param maxSurfaceAngle Radian of minimum turn angle. 0 - 180. 0 is same direction to normal. 180 is opposite
     */

    function limitSurfaceAngle(linePoints, surfaceNormal, maxSurfaceAngle) {
      if (!(maxSurfaceAngle <= 180 && maxSurfaceAngle > 0)) {
        return;
      }

      maxSurfaceAngle = maxSurfaceAngle / 180 * Math.PI;
      pt0.fromArray(linePoints[0]);
      pt1.fromArray(linePoints[1]);
      pt2.fromArray(linePoints[2]);
      Point.sub(dir, pt1, pt0);
      Point.sub(dir2, pt2, pt1);
      var len1 = dir.len();
      var len2 = dir2.len();

      if (len1 < 1e-3 || len2 < 1e-3) {
        return;
      }

      dir.scale(1 / len1);
      dir2.scale(1 / len2);
      var angleCos = dir.dot(surfaceNormal);
      var maxSurfaceAngleCos = Math.cos(maxSurfaceAngle);

      if (angleCos < maxSurfaceAngleCos) {
        // Calculate project point of pt0 on pt1-pt2
        var d = projectPointToLine(pt1.x, pt1.y, pt2.x, pt2.y, pt0.x, pt0.y, tmpArr, false);
        tmpProjPoint.fromArray(tmpArr);
        var HALF_PI = Math.PI / 2;
        var angle2 = Math.acos(dir2.dot(surfaceNormal));
        var newAngle = HALF_PI + angle2 - maxSurfaceAngle;

        if (newAngle >= HALF_PI) {
          // parallel
          Point.copy(tmpProjPoint, pt2);
        } else {
          // Calculate new projected length with limited minTurnAngle and get the new connect point
          tmpProjPoint.scaleAndAdd(dir2, d / Math.tan(Math.PI / 2 - newAngle)); // Limit the new calculated connect point between pt1 and pt2.

          var t = pt2.x !== pt1.x ? (tmpProjPoint.x - pt1.x) / (pt2.x - pt1.x) : (tmpProjPoint.y - pt1.y) / (pt2.y - pt1.y);

          if (isNaN(t)) {
            return;
          }

          if (t < 0) {
            Point.copy(tmpProjPoint, pt1);
          } else if (t > 1) {
            Point.copy(tmpProjPoint, pt2);
          }
        }

        tmpProjPoint.toArray(linePoints[1]);
      }
    }

    function setLabelLineState(labelLine, ignore, stateName, stateModel) {
      var isNormal = stateName === 'normal';
      var stateObj = isNormal ? labelLine : labelLine.ensureState(stateName); // Make sure display.

      stateObj.ignore = ignore; // Set smooth

      var smooth = stateModel.get('smooth');

      if (smooth && smooth === true) {
        smooth = 0.3;
      }

      stateObj.shape = stateObj.shape || {};

      if (smooth > 0) {
        stateObj.shape.smooth = smooth;
      }

      var styleObj = stateModel.getModel('lineStyle').getLineStyle();
      isNormal ? labelLine.useStyle(styleObj) : stateObj.style = styleObj;
    }

    function buildLabelLinePath(path, shape) {
      var smooth = shape.smooth;
      var points = shape.points;

      if (!points) {
        return;
      }

      path.moveTo(points[0][0], points[0][1]);

      if (smooth > 0 && points.length >= 3) {
        var len1 = dist(points[0], points[1]);
        var len2 = dist(points[1], points[2]);

        if (!len1 || !len2) {
          path.lineTo(points[1][0], points[1][1]);
          path.lineTo(points[2][0], points[2][1]);
          return;
        }

        var moveLen = Math.min(len1, len2) * smooth;
        var midPoint0 = lerp([], points[1], points[0], moveLen / len1);
        var midPoint2 = lerp([], points[1], points[2], moveLen / len2);
        var midPoint1 = lerp([], midPoint0, midPoint2, 0.5);
        path.bezierCurveTo(midPoint0[0], midPoint0[1], midPoint0[0], midPoint0[1], midPoint1[0], midPoint1[1]);
        path.bezierCurveTo(midPoint2[0], midPoint2[1], midPoint2[0], midPoint2[1], points[2][0], points[2][1]);
      } else {
        for (var i = 1; i < points.length; i++) {
          path.lineTo(points[i][0], points[i][1]);
        }
      }
    }
    /**
     * Create a label line if necessary and set it's style.
     */


    function setLabelLineStyle(targetEl, statesModels, defaultStyle) {
      var labelLine = targetEl.getTextGuideLine();
      var label = targetEl.getTextContent();

      if (!label) {
        // Not show label line if there is no label.
        if (labelLine) {
          targetEl.removeTextGuideLine();
        }

        return;
      }

      var normalModel = statesModels.normal;
      var showNormal = normalModel.get('show');
      var labelIgnoreNormal = label.ignore;

      for (var i = 0; i < DISPLAY_STATES.length; i++) {
        var stateName = DISPLAY_STATES[i];
        var stateModel = statesModels[stateName];
        var isNormal = stateName === 'normal';

        if (stateModel) {
          var stateShow = stateModel.get('show');
          var isLabelIgnored = isNormal ? labelIgnoreNormal : retrieve2(label.states[stateName] && label.states[stateName].ignore, labelIgnoreNormal);

          if (isLabelIgnored // Not show when label is not shown in this state.
          || !retrieve2(stateShow, showNormal) // Use normal state by default if not set.
          ) {
              var stateObj = isNormal ? labelLine : labelLine && labelLine.states[stateName];

              if (stateObj) {
                stateObj.ignore = true;
              }

              continue;
            } // Create labelLine if not exists


          if (!labelLine) {
            labelLine = new Polyline();
            targetEl.setTextGuideLine(labelLine); // Reset state of normal because it's new created.
            // NOTE: NORMAL should always been the first!

            if (!isNormal && (labelIgnoreNormal || !showNormal)) {
              setLabelLineState(labelLine, true, 'normal', statesModels.normal);
            } // Use same state proxy.


            if (targetEl.stateProxy) {
              labelLine.stateProxy = targetEl.stateProxy;
            }
          }

          setLabelLineState(labelLine, false, stateName, stateModel);
        }
      }

      if (labelLine) {
        defaults(labelLine.style, defaultStyle); // Not fill.

        labelLine.style.fill = null;
        var showAbove = normalModel.get('showAbove');
        var labelLineConfig = targetEl.textGuideLineConfig = targetEl.textGuideLineConfig || {};
        labelLineConfig.showAbove = showAbove || false; // Custom the buildPath.

        labelLine.buildPath = buildLabelLinePath;
      }
    }
    function getLabelLineStatesModels(itemModel, labelLineName) {
      labelLineName = labelLineName || 'labelLine';
      var statesModels = {
        normal: itemModel.getModel(labelLineName)
      };

      for (var i = 0; i < SPECIAL_STATES.length; i++) {
        var stateName = SPECIAL_STATES[i];
        statesModels[stateName] = itemModel.getModel([stateName, labelLineName]);
      }

      return statesModels;
    }

    function prepareLayoutList(input) {
      var list = [];

      for (var i = 0; i < input.length; i++) {
        var rawItem = input[i];

        if (rawItem.defaultAttr.ignore) {
          continue;
        }

        var label = rawItem.label;
        var transform = label.getComputedTransform(); // NOTE: Get bounding rect after getComputedTransform, or label may not been updated by the host el.

        var localRect = label.getBoundingRect();
        var isAxisAligned = !transform || transform[1] < 1e-5 && transform[2] < 1e-5;
        var minMargin = label.style.margin || 0;
        var globalRect = localRect.clone();
        globalRect.applyTransform(transform);
        globalRect.x -= minMargin / 2;
        globalRect.y -= minMargin / 2;
        globalRect.width += minMargin;
        globalRect.height += minMargin;
        var obb = isAxisAligned ? new OrientedBoundingRect(localRect, transform) : null;
        list.push({
          label: label,
          labelLine: rawItem.labelLine,
          rect: globalRect,
          localRect: localRect,
          obb: obb,
          priority: rawItem.priority,
          defaultAttr: rawItem.defaultAttr,
          layoutOption: rawItem.computedLayoutOption,
          axisAligned: isAxisAligned,
          transform: transform
        });
      }

      return list;
    }

    function shiftLayout(list, xyDim, sizeDim, minBound, maxBound, balanceShift) {
      var len = list.length;

      if (len < 2) {
        return;
      }

      list.sort(function (a, b) {
        return a.rect[xyDim] - b.rect[xyDim];
      });
      var lastPos = 0;
      var delta;
      var adjusted = false;
      var totalShifts = 0;

      for (var i = 0; i < len; i++) {
        var item = list[i];
        var rect = item.rect;
        delta = rect[xyDim] - lastPos;

        if (delta < 0) {
          // shiftForward(i, len, -delta);
          rect[xyDim] -= delta;
          item.label[xyDim] -= delta;
          adjusted = true;
        }

        var shift = Math.max(-delta, 0);
        totalShifts += shift;
        lastPos = rect[xyDim] + rect[sizeDim];
      }

      if (totalShifts > 0 && balanceShift) {
        // Shift back to make the distribution more equally.
        shiftList(-totalShifts / len, 0, len);
      } // TODO bleedMargin?


      var first = list[0];
      var last = list[len - 1];
      var minGap;
      var maxGap;
      updateMinMaxGap(); // If ends exceed two bounds, squeeze at most 80%, then take the gap of two bounds.

      minGap < 0 && squeezeGaps(-minGap, 0.8);
      maxGap < 0 && squeezeGaps(maxGap, 0.8);
      updateMinMaxGap();
      takeBoundsGap(minGap, maxGap, 1);
      takeBoundsGap(maxGap, minGap, -1); // Handle bailout when there is not enough space.

      updateMinMaxGap();

      if (minGap < 0) {
        squeezeWhenBailout(-minGap);
      }

      if (maxGap < 0) {
        squeezeWhenBailout(maxGap);
      }

      function updateMinMaxGap() {
        minGap = first.rect[xyDim] - minBound;
        maxGap = maxBound - last.rect[xyDim] - last.rect[sizeDim];
      }

      function takeBoundsGap(gapThisBound, gapOtherBound, moveDir) {
        if (gapThisBound < 0) {
          // Move from other gap if can.
          var moveFromMaxGap = Math.min(gapOtherBound, -gapThisBound);

          if (moveFromMaxGap > 0) {
            shiftList(moveFromMaxGap * moveDir, 0, len);
            var remained = moveFromMaxGap + gapThisBound;

            if (remained < 0) {
              squeezeGaps(-remained * moveDir, 1);
            }
          } else {
            squeezeGaps(-gapThisBound * moveDir, 1);
          }
        }
      }

      function shiftList(delta, start, end) {
        if (delta !== 0) {
          adjusted = true;
        }

        for (var i = start; i < end; i++) {
          var item = list[i];
          var rect = item.rect;
          rect[xyDim] += delta;
          item.label[xyDim] += delta;
        }
      } // Squeeze gaps if the labels exceed margin.


      function squeezeGaps(delta, maxSqeezePercent) {
        var gaps = [];
        var totalGaps = 0;

        for (var i = 1; i < len; i++) {
          var prevItemRect = list[i - 1].rect;
          var gap = Math.max(list[i].rect[xyDim] - prevItemRect[xyDim] - prevItemRect[sizeDim], 0);
          gaps.push(gap);
          totalGaps += gap;
        }

        if (!totalGaps) {
          return;
        }

        var squeezePercent = Math.min(Math.abs(delta) / totalGaps, maxSqeezePercent);

        if (delta > 0) {
          for (var i = 0; i < len - 1; i++) {
            // Distribute the shift delta to all gaps.
            var movement = gaps[i] * squeezePercent; // Forward

            shiftList(movement, 0, i + 1);
          }
        } else {
          // Backward
          for (var i = len - 1; i > 0; i--) {
            // Distribute the shift delta to all gaps.
            var movement = gaps[i - 1] * squeezePercent;
            shiftList(-movement, i, len);
          }
        }
      }
      /**
       * Squeeze to allow overlap if there is no more space available.
       * Let other overlapping strategy like hideOverlap do the job instead of keep exceeding the bounds.
       */


      function squeezeWhenBailout(delta) {
        var dir = delta < 0 ? -1 : 1;
        delta = Math.abs(delta);
        var moveForEachLabel = Math.ceil(delta / (len - 1));

        for (var i = 0; i < len - 1; i++) {
          if (dir > 0) {
            // Forward
            shiftList(moveForEachLabel, 0, i + 1);
          } else {
            // Backward
            shiftList(-moveForEachLabel, len - i - 1, len);
          }

          delta -= moveForEachLabel;

          if (delta <= 0) {
            return;
          }
        }
      }

      return adjusted;
    }
    /**
     * Adjust labels on x direction to avoid overlap.
     */


    function shiftLayoutOnX(list, leftBound, rightBound, // If average the shifts on all labels and add them to 0
    // TODO: Not sure if should enable it.
    // Pros: The angle of lines will distribute more equally
    // Cons: In some layout. It may not what user wanted. like in pie. the label of last sector is usually changed unexpectedly.
    balanceShift) {
      return shiftLayout(list, 'x', 'width', leftBound, rightBound, balanceShift);
    }
    /**
     * Adjust labels on y direction to avoid overlap.
     */

    function shiftLayoutOnY(list, topBound, bottomBound, // If average the shifts on all labels and add them to 0
    balanceShift) {
      return shiftLayout(list, 'y', 'height', topBound, bottomBound, balanceShift);
    }
    function hideOverlap(labelList) {
      var displayedLabels = []; // TODO, render overflow visible first, put in the displayedLabels.

      labelList.sort(function (a, b) {
        return b.priority - a.priority;
      });
      var globalRect = new BoundingRect(0, 0, 0, 0);

      function hideEl(el) {
        if (!el.ignore) {
          // Show on emphasis.
          var emphasisState = el.ensureState('emphasis');

          if (emphasisState.ignore == null) {
            emphasisState.ignore = false;
          }
        }

        el.ignore = true;
      }

      for (var i = 0; i < labelList.length; i++) {
        var labelItem = labelList[i];
        var isAxisAligned = labelItem.axisAligned;
        var localRect = labelItem.localRect;
        var transform = labelItem.transform;
        var label = labelItem.label;
        var labelLine = labelItem.labelLine;
        globalRect.copy(labelItem.rect); // Add a threshold because layout may be aligned precisely.

        globalRect.width -= 0.1;
        globalRect.height -= 0.1;
        globalRect.x += 0.05;
        globalRect.y += 0.05;
        var obb = labelItem.obb;
        var overlapped = false;

        for (var j = 0; j < displayedLabels.length; j++) {
          var existsTextCfg = displayedLabels[j]; // Fast rejection.

          if (!globalRect.intersect(existsTextCfg.rect)) {
            continue;
          }

          if (isAxisAligned && existsTextCfg.axisAligned) {
            // Is overlapped
            overlapped = true;
            break;
          }

          if (!existsTextCfg.obb) {
            // If self is not axis aligned. But other is.
            existsTextCfg.obb = new OrientedBoundingRect(existsTextCfg.localRect, existsTextCfg.transform);
          }

          if (!obb) {
            // If self is axis aligned. But other is not.
            obb = new OrientedBoundingRect(localRect, transform);
          }

          if (obb.intersect(existsTextCfg.obb)) {
            overlapped = true;
            break;
          }
        } // TODO Callback to determine if this overlap should be handled?


        if (overlapped) {
          hideEl(label);
          labelLine && hideEl(labelLine);
        } else {
          label.attr('ignore', labelItem.defaultAttr.ignore);
          labelLine && labelLine.attr('ignore', labelItem.defaultAttr.labelGuideIgnore);
          displayedLabels.push(labelItem);
        }
      }
    }

    function cloneArr(points) {
      if (points) {
        var newPoints = [];

        for (var i = 0; i < points.length; i++) {
          newPoints.push(points[i].slice());
        }

        return newPoints;
      }
    }

    function prepareLayoutCallbackParams(labelItem, hostEl) {
      var label = labelItem.label;
      var labelLine = hostEl && hostEl.getTextGuideLine();
      return {
        dataIndex: labelItem.dataIndex,
        dataType: labelItem.dataType,
        seriesIndex: labelItem.seriesModel.seriesIndex,
        text: labelItem.label.style.text,
        rect: labelItem.hostRect,
        labelRect: labelItem.rect,
        // x: labelAttr.x,
        // y: labelAttr.y,
        align: label.style.align,
        verticalAlign: label.style.verticalAlign,
        labelLinePoints: cloneArr(labelLine && labelLine.shape.points)
      };
    }

    var LABEL_OPTION_TO_STYLE_KEYS = ['align', 'verticalAlign', 'width', 'height', 'fontSize'];
    var dummyTransformable = new Transformable();
    var labelLayoutInnerStore = makeInner();
    var labelLineAnimationStore = makeInner();

    function extendWithKeys(target, source, keys) {
      for (var i = 0; i < keys.length; i++) {
        var key = keys[i];

        if (source[key] != null) {
          target[key] = source[key];
        }
      }
    }

    var LABEL_LAYOUT_PROPS = ['x', 'y', 'rotation'];

    var LabelManager =
    /** @class */
    function () {
      function LabelManager() {
        this._labelList = [];
        this._chartViewList = [];
      }

      LabelManager.prototype.clearLabels = function () {
        this._labelList = [];
        this._chartViewList = [];
      };
      /**
       * Add label to manager
       */


      LabelManager.prototype._addLabel = function (dataIndex, dataType, seriesModel, label, layoutOption) {
        var labelStyle = label.style;
        var hostEl = label.__hostTarget;
        var textConfig = hostEl.textConfig || {}; // TODO: If label is in other state.

        var labelTransform = label.getComputedTransform();
        var labelRect = label.getBoundingRect().plain();
        BoundingRect.applyTransform(labelRect, labelRect, labelTransform);

        if (labelTransform) {
          dummyTransformable.setLocalTransform(labelTransform);
        } else {
          // Identity transform.
          dummyTransformable.x = dummyTransformable.y = dummyTransformable.rotation = dummyTransformable.originX = dummyTransformable.originY = 0;
          dummyTransformable.scaleX = dummyTransformable.scaleY = 1;
        }

        var host = label.__hostTarget;
        var hostRect;

        if (host) {
          hostRect = host.getBoundingRect().plain();
          var transform = host.getComputedTransform();
          BoundingRect.applyTransform(hostRect, hostRect, transform);
        }

        var labelGuide = hostRect && host.getTextGuideLine();

        this._labelList.push({
          label: label,
          labelLine: labelGuide,
          seriesModel: seriesModel,
          dataIndex: dataIndex,
          dataType: dataType,
          layoutOption: layoutOption,
          computedLayoutOption: null,
          rect: labelRect,
          hostRect: hostRect,
          // Label with lower priority will be hidden when overlapped
          // Use rect size as default priority
          priority: hostRect ? hostRect.width * hostRect.height : 0,
          // Save default label attributes.
          // For restore if developers want get back to default value in callback.
          defaultAttr: {
            ignore: label.ignore,
            labelGuideIgnore: labelGuide && labelGuide.ignore,
            x: dummyTransformable.x,
            y: dummyTransformable.y,
            scaleX: dummyTransformable.scaleX,
            scaleY: dummyTransformable.scaleY,
            rotation: dummyTransformable.rotation,
            style: {
              x: labelStyle.x,
              y: labelStyle.y,
              align: labelStyle.align,
              verticalAlign: labelStyle.verticalAlign,
              width: labelStyle.width,
              height: labelStyle.height,
              fontSize: labelStyle.fontSize
            },
            cursor: label.cursor,
            attachedPos: textConfig.position,
            attachedRot: textConfig.rotation
          }
        });
      };

      LabelManager.prototype.addLabelsOfSeries = function (chartView) {
        var _this = this;

        this._chartViewList.push(chartView);

        var seriesModel = chartView.__model;
        var layoutOption = seriesModel.get('labelLayout');
        /**
         * Ignore layouting if it's not specified anything.
         */

        if (!(isFunction(layoutOption) || keys(layoutOption).length)) {
          return;
        }

        chartView.group.traverse(function (child) {
          if (child.ignore) {
            return true; // Stop traverse descendants.
          } // Only support label being hosted on graphic elements.


          var textEl = child.getTextContent();
          var ecData = getECData(child); // Can only attach the text on the element with dataIndex

          if (textEl && !textEl.disableLabelLayout) {
            _this._addLabel(ecData.dataIndex, ecData.dataType, seriesModel, textEl, layoutOption);
          }
        });
      };

      LabelManager.prototype.updateLayoutConfig = function (api) {
        var width = api.getWidth();
        var height = api.getHeight();

        function createDragHandler(el, labelLineModel) {
          return function () {
            updateLabelLinePoints(el, labelLineModel);
          };
        }

        for (var i = 0; i < this._labelList.length; i++) {
          var labelItem = this._labelList[i];
          var label = labelItem.label;
          var hostEl = label.__hostTarget;
          var defaultLabelAttr = labelItem.defaultAttr;
          var layoutOption = void 0; // TODO A global layout option?

          if (isFunction(labelItem.layoutOption)) {
            layoutOption = labelItem.layoutOption(prepareLayoutCallbackParams(labelItem, hostEl));
          } else {
            layoutOption = labelItem.layoutOption;
          }

          layoutOption = layoutOption || {};
          labelItem.computedLayoutOption = layoutOption;
          var degreeToRadian = Math.PI / 180; // TODO hostEl should always exists.
          // Or label should not have parent because the x, y is all in global space.

          if (hostEl) {
            hostEl.setTextConfig({
              // Force to set local false.
              local: false,
              // Ignore position and rotation config on the host el if x or y is changed.
              position: layoutOption.x != null || layoutOption.y != null ? null : defaultLabelAttr.attachedPos,
              // Ignore rotation config on the host el if rotation is changed.
              rotation: layoutOption.rotate != null ? layoutOption.rotate * degreeToRadian : defaultLabelAttr.attachedRot,
              offset: [layoutOption.dx || 0, layoutOption.dy || 0]
            });
          }

          var needsUpdateLabelLine = false;

          if (layoutOption.x != null) {
            // TODO width of chart view.
            label.x = parsePercent$1(layoutOption.x, width);
            label.setStyle('x', 0); // Ignore movement in style. TODO: origin.

            needsUpdateLabelLine = true;
          } else {
            label.x = defaultLabelAttr.x;
            label.setStyle('x', defaultLabelAttr.style.x);
          }

          if (layoutOption.y != null) {
            // TODO height of chart view.
            label.y = parsePercent$1(layoutOption.y, height);
            label.setStyle('y', 0); // Ignore movement in style.

            needsUpdateLabelLine = true;
          } else {
            label.y = defaultLabelAttr.y;
            label.setStyle('y', defaultLabelAttr.style.y);
          }

          if (layoutOption.labelLinePoints) {
            var guideLine = hostEl.getTextGuideLine();

            if (guideLine) {
              guideLine.setShape({
                points: layoutOption.labelLinePoints
              }); // Not update

              needsUpdateLabelLine = false;
            }
          }

          var labelLayoutStore = labelLayoutInnerStore(label);
          labelLayoutStore.needsUpdateLabelLine = needsUpdateLabelLine;
          label.rotation = layoutOption.rotate != null ? layoutOption.rotate * degreeToRadian : defaultLabelAttr.rotation;
          label.scaleX = defaultLabelAttr.scaleX;
          label.scaleY = defaultLabelAttr.scaleY;

          for (var k = 0; k < LABEL_OPTION_TO_STYLE_KEYS.length; k++) {
            var key = LABEL_OPTION_TO_STYLE_KEYS[k];
            label.setStyle(key, layoutOption[key] != null ? layoutOption[key] : defaultLabelAttr.style[key]);
          }

          if (layoutOption.draggable) {
            label.draggable = true;
            label.cursor = 'move';

            if (hostEl) {
              var hostModel = labelItem.seriesModel;

              if (labelItem.dataIndex != null) {
                var data = labelItem.seriesModel.getData(labelItem.dataType);
                hostModel = data.getItemModel(labelItem.dataIndex);
              }

              label.on('drag', createDragHandler(hostEl, hostModel.getModel('labelLine')));
            }
          } else {
            // TODO Other drag functions?
            label.off('drag');
            label.cursor = defaultLabelAttr.cursor;
          }
        }
      };

      LabelManager.prototype.layout = function (api) {
        var width = api.getWidth();
        var height = api.getHeight();
        var labelList = prepareLayoutList(this._labelList);
        var labelsNeedsAdjustOnX = filter(labelList, function (item) {
          return item.layoutOption.moveOverlap === 'shiftX';
        });
        var labelsNeedsAdjustOnY = filter(labelList, function (item) {
          return item.layoutOption.moveOverlap === 'shiftY';
        });
        shiftLayoutOnX(labelsNeedsAdjustOnX, 0, width);
        shiftLayoutOnY(labelsNeedsAdjustOnY, 0, height);
        var labelsNeedsHideOverlap = filter(labelList, function (item) {
          return item.layoutOption.hideOverlap;
        });
        hideOverlap(labelsNeedsHideOverlap);
      };
      /**
       * Process all labels. Not only labels with layoutOption.
       */


      LabelManager.prototype.processLabelsOverall = function () {
        var _this = this;

        each(this._chartViewList, function (chartView) {
          var seriesModel = chartView.__model;
          var ignoreLabelLineUpdate = chartView.ignoreLabelLineUpdate;
          var animationEnabled = seriesModel.isAnimationEnabled();
          chartView.group.traverse(function (child) {
            if (child.ignore && !child.forceLabelAnimation) {
              return true; // Stop traverse descendants.
            }

            var needsUpdateLabelLine = !ignoreLabelLineUpdate;
            var label = child.getTextContent();

            if (!needsUpdateLabelLine && label) {
              needsUpdateLabelLine = labelLayoutInnerStore(label).needsUpdateLabelLine;
            }

            if (needsUpdateLabelLine) {
              _this._updateLabelLine(child, seriesModel);
            }

            if (animationEnabled) {
              _this._animateLabels(child, seriesModel);
            }
          });
        });
      };

      LabelManager.prototype._updateLabelLine = function (el, seriesModel) {
        // Only support label being hosted on graphic elements.
        var textEl = el.getTextContent(); // Update label line style.

        var ecData = getECData(el);
        var dataIndex = ecData.dataIndex; // Only support labelLine on the labels represent data.

        if (textEl && dataIndex != null) {
          var data = seriesModel.getData(ecData.dataType);
          var itemModel = data.getItemModel(dataIndex);
          var defaultStyle = {};
          var visualStyle = data.getItemVisual(dataIndex, 'style');
          var visualType = data.getVisual('drawType'); // Default to be same with main color

          defaultStyle.stroke = visualStyle[visualType];
          var labelLineModel = itemModel.getModel('labelLine');
          setLabelLineStyle(el, getLabelLineStatesModels(itemModel), defaultStyle);
          updateLabelLinePoints(el, labelLineModel);
        }
      };

      LabelManager.prototype._animateLabels = function (el, seriesModel) {
        var textEl = el.getTextContent();
        var guideLine = el.getTextGuideLine(); // Animate

        if (textEl // `forceLabelAnimation` has the highest priority
        && (el.forceLabelAnimation || !textEl.ignore && !textEl.invisible && !el.disableLabelAnimation && !isElementRemoved(el))) {
          var layoutStore = labelLayoutInnerStore(textEl);
          var oldLayout = layoutStore.oldLayout;
          var ecData = getECData(el);
          var dataIndex = ecData.dataIndex;
          var newProps = {
            x: textEl.x,
            y: textEl.y,
            rotation: textEl.rotation
          };
          var data = seriesModel.getData(ecData.dataType);

          if (!oldLayout) {
            textEl.attr(newProps); // Disable fade in animation if value animation is enabled.

            if (!labelInner(textEl).valueAnimation) {
              var oldOpacity = retrieve2(textEl.style.opacity, 1); // Fade in animation

              textEl.style.opacity = 0;
              initProps(textEl, {
                style: {
                  opacity: oldOpacity
                }
              }, seriesModel, dataIndex);
            }
          } else {
            textEl.attr(oldLayout); // Make sure the animation from is in the right status.

            var prevStates = el.prevStates;

            if (prevStates) {
              if (indexOf(prevStates, 'select') >= 0) {
                textEl.attr(layoutStore.oldLayoutSelect);
              }

              if (indexOf(prevStates, 'emphasis') >= 0) {
                textEl.attr(layoutStore.oldLayoutEmphasis);
              }
            }

            updateProps(textEl, newProps, seriesModel, dataIndex);
          }

          layoutStore.oldLayout = newProps;

          if (textEl.states.select) {
            var layoutSelect = layoutStore.oldLayoutSelect = {};
            extendWithKeys(layoutSelect, newProps, LABEL_LAYOUT_PROPS);
            extendWithKeys(layoutSelect, textEl.states.select, LABEL_LAYOUT_PROPS);
          }

          if (textEl.states.emphasis) {
            var layoutEmphasis = layoutStore.oldLayoutEmphasis = {};
            extendWithKeys(layoutEmphasis, newProps, LABEL_LAYOUT_PROPS);
            extendWithKeys(layoutEmphasis, textEl.states.emphasis, LABEL_LAYOUT_PROPS);
          }

          animateLabelValue(textEl, dataIndex, data, seriesModel, seriesModel);
        }

        if (guideLine && !guideLine.ignore && !guideLine.invisible) {
          var layoutStore = labelLineAnimationStore(guideLine);
          var oldLayout = layoutStore.oldLayout;
          var newLayout = {
            points: guideLine.shape.points
          };

          if (!oldLayout) {
            guideLine.setShape(newLayout);
            guideLine.style.strokePercent = 0;
            initProps(guideLine, {
              style: {
                strokePercent: 1
              }
            }, seriesModel);
          } else {
            guideLine.attr({
              shape: oldLayout
            });
            updateProps(guideLine, {
              shape: newLayout
            }, seriesModel);
          }

          layoutStore.oldLayout = newLayout;
        }
      };

      return LabelManager;
    }();

    var getLabelManager = makeInner();
    function installLabelLayout(registers) {
      registers.registerUpdateLifecycle('series:beforeupdate', function (ecModel, api, params) {
        // TODO api provide an namespace that can save stuff per instance
        var labelManager = getLabelManager(api).labelManager;

        if (!labelManager) {
          labelManager = getLabelManager(api).labelManager = new LabelManager();
        }

        labelManager.clearLabels();
      });
      registers.registerUpdateLifecycle('series:layoutlabels', function (ecModel, api, params) {
        var labelManager = getLabelManager(api).labelManager;
        params.updatedSeries.forEach(function (series) {
          labelManager.addLabelsOfSeries(api.getViewOfSeriesModel(series));
        });
        labelManager.updateLayoutConfig(api);
        labelManager.layout(api);
        labelManager.processLabelsOverall();
      });
    }

    var mathSin$4 = Math.sin;
    var mathCos$4 = Math.cos;
    var PI$4 = Math.PI;
    var PI2$7 = Math.PI * 2;
    var degree = 180 / PI$4;
    var SVGPathRebuilder = (function () {
        function SVGPathRebuilder() {
        }
        SVGPathRebuilder.prototype.reset = function (precision) {
            this._start = true;
            this._d = [];
            this._str = '';
            this._p = Math.pow(10, precision || 4);
        };
        SVGPathRebuilder.prototype.moveTo = function (x, y) {
            this._add('M', x, y);
        };
        SVGPathRebuilder.prototype.lineTo = function (x, y) {
            this._add('L', x, y);
        };
        SVGPathRebuilder.prototype.bezierCurveTo = function (x, y, x2, y2, x3, y3) {
            this._add('C', x, y, x2, y2, x3, y3);
        };
        SVGPathRebuilder.prototype.quadraticCurveTo = function (x, y, x2, y2) {
            this._add('Q', x, y, x2, y2);
        };
        SVGPathRebuilder.prototype.arc = function (cx, cy, r, startAngle, endAngle, anticlockwise) {
            this.ellipse(cx, cy, r, r, 0, startAngle, endAngle, anticlockwise);
        };
        SVGPathRebuilder.prototype.ellipse = function (cx, cy, rx, ry, psi, startAngle, endAngle, anticlockwise) {
            var dTheta = endAngle - startAngle;
            var clockwise = !anticlockwise;
            var dThetaPositive = Math.abs(dTheta);
            var isCircle = isAroundZero$1(dThetaPositive - PI2$7)
                || (clockwise ? dTheta >= PI2$7 : -dTheta >= PI2$7);
            var unifiedTheta = dTheta > 0 ? dTheta % PI2$7 : (dTheta % PI2$7 + PI2$7);
            var large = false;
            if (isCircle) {
                large = true;
            }
            else if (isAroundZero$1(dThetaPositive)) {
                large = false;
            }
            else {
                large = (unifiedTheta >= PI$4) === !!clockwise;
            }
            var x0 = cx + rx * mathCos$4(startAngle);
            var y0 = cy + ry * mathSin$4(startAngle);
            if (this._start) {
                this._add('M', x0, y0);
            }
            var xRot = Math.round(psi * degree);
            if (isCircle) {
                var p = 1 / this._p;
                var dTheta_1 = (clockwise ? 1 : -1) * (PI2$7 - p);
                this._add('A', rx, ry, xRot, 1, +clockwise, cx + rx * mathCos$4(startAngle + dTheta_1), cy + ry * mathSin$4(startAngle + dTheta_1));
                if (p > 1e-2) {
                    this._add('A', rx, ry, xRot, 0, +clockwise, x0, y0);
                }
            }
            else {
                var x = cx + rx * mathCos$4(endAngle);
                var y = cy + ry * mathSin$4(endAngle);
                this._add('A', rx, ry, xRot, +large, +clockwise, x, y);
            }
        };
        SVGPathRebuilder.prototype.rect = function (x, y, w, h) {
            this._add('M', x, y);
            this._add('l', w, 0);
            this._add('l', 0, h);
            this._add('l', -w, 0);
            this._add('Z');
        };
        SVGPathRebuilder.prototype.closePath = function () {
            if (this._d.length > 0) {
                this._add('Z');
            }
        };
        SVGPathRebuilder.prototype._add = function (cmd, a, b, c, d, e, f, g, h) {
            var vals = [];
            var p = this._p;
            for (var i = 1; i < arguments.length; i++) {
                var val = arguments[i];
                if (isNaN(val)) {
                    this._invalid = true;
                    return;
                }
                vals.push(Math.round(val * p) / p);
            }
            this._d.push(cmd + vals.join(' '));
            this._start = cmd === 'Z';
        };
        SVGPathRebuilder.prototype.generateStr = function () {
            this._str = this._invalid ? '' : this._d.join('');
            this._d = [];
        };
        SVGPathRebuilder.prototype.getStr = function () {
            return this._str;
        };
        return SVGPathRebuilder;
    }());

    var NONE = 'none';
    var mathRound$1 = Math.round;
    function pathHasFill(style) {
        var fill = style.fill;
        return fill != null && fill !== NONE;
    }
    function pathHasStroke(style) {
        var stroke = style.stroke;
        return stroke != null && stroke !== NONE;
    }
    var strokeProps = ['lineCap', 'miterLimit', 'lineJoin'];
    var svgStrokeProps = map(strokeProps, function (prop) { return "stroke-" + prop.toLowerCase(); });
    function mapStyleToAttrs(updateAttr, style, el, forceUpdate) {
        var opacity = style.opacity == null ? 1 : style.opacity;
        if (el instanceof ZRImage) {
            updateAttr('opacity', opacity);
            return;
        }
        if (pathHasFill(style)) {
            var fill = normalizeColor(style.fill);
            updateAttr('fill', fill.color);
            var fillOpacity = style.fillOpacity != null
                ? style.fillOpacity * fill.opacity * opacity
                : fill.opacity * opacity;
            if (forceUpdate || fillOpacity < 1) {
                updateAttr('fill-opacity', fillOpacity);
            }
        }
        else {
            updateAttr('fill', NONE);
        }
        if (pathHasStroke(style)) {
            var stroke = normalizeColor(style.stroke);
            updateAttr('stroke', stroke.color);
            var strokeScale = style.strokeNoScale
                ? el.getLineScale()
                : 1;
            var strokeWidth = (strokeScale ? (style.lineWidth || 0) / strokeScale : 0);
            var strokeOpacity = style.strokeOpacity != null
                ? style.strokeOpacity * stroke.opacity * opacity
                : stroke.opacity * opacity;
            var strokeFirst = style.strokeFirst;
            if (forceUpdate || strokeWidth !== 1) {
                updateAttr('stroke-width', strokeWidth);
            }
            if (forceUpdate || strokeFirst) {
                updateAttr('paint-order', strokeFirst ? 'stroke' : 'fill');
            }
            if (forceUpdate || strokeOpacity < 1) {
                updateAttr('stroke-opacity', strokeOpacity);
            }
            if (style.lineDash) {
                var _a = getLineDash(el), lineDash = _a[0], lineDashOffset = _a[1];
                if (lineDash) {
                    lineDashOffset = mathRound$1(lineDashOffset || 0);
                    updateAttr('stroke-dasharray', lineDash.join(','));
                    if (lineDashOffset || forceUpdate) {
                        updateAttr('stroke-dashoffset', lineDashOffset);
                    }
                }
            }
            else if (forceUpdate) {
                updateAttr('stroke-dasharray', NONE);
            }
            for (var i = 0; i < strokeProps.length; i++) {
                var propName = strokeProps[i];
                if (forceUpdate || style[propName] !== DEFAULT_PATH_STYLE[propName]) {
                    var val = style[propName] || DEFAULT_PATH_STYLE[propName];
                    val && updateAttr(svgStrokeProps[i], val);
                }
            }
        }
        else if (forceUpdate) {
            updateAttr('stroke', NONE);
        }
    }

    var SVGNS = 'http://www.w3.org/2000/svg';
    var XLINKNS = 'http://www.w3.org/1999/xlink';
    var XMLNS = 'http://www.w3.org/2000/xmlns/';
    var XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
    function createElement(name) {
        return document.createElementNS(SVGNS, name);
    }
    function createVNode(tag, key, attrs, children, text) {
        return {
            tag: tag,
            attrs: attrs || {},
            children: children,
            text: text,
            key: key
        };
    }
    function createElementOpen(name, attrs) {
        var attrsStr = [];
        if (attrs) {
            for (var key in attrs) {
                var val = attrs[key];
                var part = key;
                if (val === false) {
                    continue;
                }
                else if (val !== true && val != null) {
                    part += "=\"" + val + "\"";
                }
                attrsStr.push(part);
            }
        }
        return "<" + name + " " + attrsStr.join(' ') + ">";
    }
    function createElementClose(name) {
        return "</" + name + ">";
    }
    function vNodeToString(el, opts) {
        opts = opts || {};
        var S = opts.newline ? '\n' : '';
        function convertElToString(el) {
            var children = el.children, tag = el.tag, attrs = el.attrs;
            return createElementOpen(tag, attrs)
                + encodeHTML(el.text)
                + (children ? "" + S + map(children, function (child) { return convertElToString(child); }).join(S) + S : '')
                + createElementClose(tag);
        }
        return convertElToString(el);
    }
    function getCssString(selectorNodes, animationNodes, opts) {
        opts = opts || {};
        var S = opts.newline ? '\n' : '';
        var bracketBegin = " {" + S;
        var bracketEnd = S + "}";
        var selectors = map(keys(selectorNodes), function (className) {
            return className + bracketBegin + map(keys(selectorNodes[className]), function (attrName) {
                return attrName + ":" + selectorNodes[className][attrName] + ";";
            }).join(S) + bracketEnd;
        }).join(S);
        var animations = map(keys(animationNodes), function (animationName) {
            return "@keyframes " + animationName + bracketBegin + map(keys(animationNodes[animationName]), function (percent) {
                return percent + bracketBegin + map(keys(animationNodes[animationName][percent]), function (attrName) {
                    var val = animationNodes[animationName][percent][attrName];
                    if (attrName === 'd') {
                        val = "path(\"" + val + "\")";
                    }
                    return attrName + ":" + val + ";";
                }).join(S) + bracketEnd;
            }).join(S) + bracketEnd;
        }).join(S);
        if (!selectors && !animations) {
            return '';
        }
        return ['<![CDATA[', selectors, animations, ']]>'].join(S);
    }
    function createBrushScope(zrId) {
        return {
            zrId: zrId,
            shadowCache: {},
            patternCache: {},
            gradientCache: {},
            clipPathCache: {},
            defs: {},
            cssNodes: {},
            cssAnims: {},
            cssClassIdx: 0,
            cssAnimIdx: 0,
            shadowIdx: 0,
            gradientIdx: 0,
            patternIdx: 0,
            clipPathIdx: 0
        };
    }
    function createSVGVNode(width, height, children, useViewBox) {
        return createVNode('svg', 'root', {
            'width': width,
            'height': height,
            'xmlns': SVGNS,
            'xmlns:xlink': XLINKNS,
            'version': '1.1',
            'baseProfile': 'full',
            'viewBox': useViewBox ? "0 0 " + width + " " + height : false
        }, children);
    }

    var EASING_MAP = {
        cubicIn: '0.32,0,0.67,0',
        cubicOut: '0.33,1,0.68,1',
        cubicInOut: '0.65,0,0.35,1',
        quadraticIn: '0.11,0,0.5,0',
        quadraticOut: '0.5,1,0.89,1',
        quadraticInOut: '0.45,0,0.55,1',
        quarticIn: '0.5,0,0.75,0',
        quarticOut: '0.25,1,0.5,1',
        quarticInOut: '0.76,0,0.24,1',
        quinticIn: '0.64,0,0.78,0',
        quinticOut: '0.22,1,0.36,1',
        quinticInOut: '0.83,0,0.17,1',
        sinusoidalIn: '0.12,0,0.39,0',
        sinusoidalOut: '0.61,1,0.88,1',
        sinusoidalInOut: '0.37,0,0.63,1',
        exponentialIn: '0.7,0,0.84,0',
        exponentialOut: '0.16,1,0.3,1',
        exponentialInOut: '0.87,0,0.13,1',
        circularIn: '0.55,0,1,0.45',
        circularOut: '0,0.55,0.45,1',
        circularInOut: '0.85,0,0.15,1'
    };
    var transformOriginKey = 'transform-origin';
    function buildPathString(el, kfShape, path) {
        var shape = extend({}, el.shape);
        extend(shape, kfShape);
        el.buildPath(path, shape);
        var svgPathBuilder = new SVGPathRebuilder();
        svgPathBuilder.reset(getPathPrecision(el));
        path.rebuildPath(svgPathBuilder, 1);
        svgPathBuilder.generateStr();
        return svgPathBuilder.getStr();
    }
    function setTransformOrigin(target, transform) {
        var originX = transform.originX, originY = transform.originY;
        if (originX || originY) {
            target[transformOriginKey] = originX + "px " + originY + "px";
        }
    }
    var ANIMATE_STYLE_MAP = {
        fill: 'fill',
        opacity: 'opacity',
        lineWidth: 'stroke-width',
        lineDashOffset: 'stroke-dashoffset'
    };
    function addAnimation(cssAnim, scope) {
        var animationName = scope.zrId + '-ani-' + scope.cssAnimIdx++;
        scope.cssAnims[animationName] = cssAnim;
        return animationName;
    }
    function createCompoundPathCSSAnimation(el, attrs, scope) {
        var paths = el.shape.paths;
        var composedAnim = {};
        var cssAnimationCfg;
        var cssAnimationName;
        each(paths, function (path) {
            var subScope = createBrushScope(scope.zrId);
            subScope.animation = true;
            createCSSAnimation(path, {}, subScope, true);
            var cssAnims = subScope.cssAnims;
            var cssNodes = subScope.cssNodes;
            var animNames = keys(cssAnims);
            var len = animNames.length;
            if (!len) {
                return;
            }
            cssAnimationName = animNames[len - 1];
            var lastAnim = cssAnims[cssAnimationName];
            for (var percent in lastAnim) {
                var kf = lastAnim[percent];
                composedAnim[percent] = composedAnim[percent] || { d: '' };
                composedAnim[percent].d += kf.d || '';
            }
            for (var className in cssNodes) {
                var val = cssNodes[className].animation;
                if (val.indexOf(cssAnimationName) >= 0) {
                    cssAnimationCfg = val;
                }
            }
        });
        if (!cssAnimationCfg) {
            return;
        }
        attrs.d = false;
        var animationName = addAnimation(composedAnim, scope);
        return cssAnimationCfg.replace(cssAnimationName, animationName);
    }
    function getEasingFunc(easing) {
        return isString(easing)
            ? EASING_MAP[easing]
                ? "cubic-bezier(" + EASING_MAP[easing] + ")"
                : createCubicEasingFunc(easing) ? easing : ''
            : '';
    }
    function createCSSAnimation(el, attrs, scope, onlyShape) {
        var animators = el.animators;
        var len = animators.length;
        var cssAnimations = [];
        if (el instanceof CompoundPath) {
            var animationCfg = createCompoundPathCSSAnimation(el, attrs, scope);
            if (animationCfg) {
                cssAnimations.push(animationCfg);
            }
            else if (!len) {
                return;
            }
        }
        else if (!len) {
            return;
        }
        var groupAnimators = {};
        for (var i = 0; i < len; i++) {
            var animator = animators[i];
            var cfgArr = [animator.getMaxTime() / 1000 + 's'];
            var easing = getEasingFunc(animator.getClip().easing);
            var delay = animator.getDelay();
            if (easing) {
                cfgArr.push(easing);
            }
            else {
                cfgArr.push('linear');
            }
            if (delay) {
                cfgArr.push(delay / 1000 + 's');
            }
            if (animator.getLoop()) {
                cfgArr.push('infinite');
            }
            var cfg = cfgArr.join(' ');
            groupAnimators[cfg] = groupAnimators[cfg] || [cfg, []];
            groupAnimators[cfg][1].push(animator);
        }
        function createSingleCSSAnimation(groupAnimator) {
            var animators = groupAnimator[1];
            var len = animators.length;
            var transformKfs = {};
            var shapeKfs = {};
            var finalKfs = {};
            var animationTimingFunctionAttrName = 'animation-timing-function';
            function saveAnimatorTrackToCssKfs(animator, cssKfs, toCssAttrName) {
                var tracks = animator.getTracks();
                var maxTime = animator.getMaxTime();
                for (var k = 0; k < tracks.length; k++) {
                    var track = tracks[k];
                    if (track.needsAnimate()) {
                        var kfs = track.keyframes;
                        var attrName = track.propName;
                        toCssAttrName && (attrName = toCssAttrName(attrName));
                        if (attrName) {
                            for (var i = 0; i < kfs.length; i++) {
                                var kf = kfs[i];
                                var percent = Math.round(kf.time / maxTime * 100) + '%';
                                var kfEasing = getEasingFunc(kf.easing);
                                var rawValue = kf.rawValue;
                                if (isString(rawValue) || isNumber(rawValue)) {
                                    cssKfs[percent] = cssKfs[percent] || {};
                                    cssKfs[percent][attrName] = kf.rawValue;
                                    if (kfEasing) {
                                        cssKfs[percent][animationTimingFunctionAttrName] = kfEasing;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            for (var i = 0; i < len; i++) {
                var animator = animators[i];
                var targetProp = animator.targetName;
                if (!targetProp) {
                    !onlyShape && saveAnimatorTrackToCssKfs(animator, transformKfs);
                }
                else if (targetProp === 'shape') {
                    saveAnimatorTrackToCssKfs(animator, shapeKfs);
                }
            }
            for (var percent in transformKfs) {
                var transform = {};
                copyTransform(transform, el);
                extend(transform, transformKfs[percent]);
                var str = getSRTTransformString(transform);
                var timingFunction = transformKfs[percent][animationTimingFunctionAttrName];
                finalKfs[percent] = str ? {
                    transform: str
                } : {};
                setTransformOrigin(finalKfs[percent], transform);
                if (timingFunction) {
                    finalKfs[percent][animationTimingFunctionAttrName] = timingFunction;
                }
            }
            var path;
            var canAnimateShape = true;
            for (var percent in shapeKfs) {
                finalKfs[percent] = finalKfs[percent] || {};
                var isFirst = !path;
                var timingFunction = shapeKfs[percent][animationTimingFunctionAttrName];
                if (isFirst) {
                    path = new PathProxy();
                }
                var len_1 = path.len();
                path.reset();
                finalKfs[percent].d = buildPathString(el, shapeKfs[percent], path);
                var newLen = path.len();
                if (!isFirst && len_1 !== newLen) {
                    canAnimateShape = false;
                    break;
                }
                if (timingFunction) {
                    finalKfs[percent][animationTimingFunctionAttrName] = timingFunction;
                }
            }
            if (!canAnimateShape) {
                for (var percent in finalKfs) {
                    delete finalKfs[percent].d;
                }
            }
            if (!onlyShape) {
                for (var i = 0; i < len; i++) {
                    var animator = animators[i];
                    var targetProp = animator.targetName;
                    if (targetProp === 'style') {
                        saveAnimatorTrackToCssKfs(animator, finalKfs, function (propName) { return ANIMATE_STYLE_MAP[propName]; });
                    }
                }
            }
            var percents = keys(finalKfs);
            var allTransformOriginSame = true;
            var transformOrigin;
            for (var i = 1; i < percents.length; i++) {
                var p0 = percents[i - 1];
                var p1 = percents[i];
                if (finalKfs[p0][transformOriginKey] !== finalKfs[p1][transformOriginKey]) {
                    allTransformOriginSame = false;
                    break;
                }
                transformOrigin = finalKfs[p0][transformOriginKey];
            }
            if (allTransformOriginSame && transformOrigin) {
                for (var percent in finalKfs) {
                    if (finalKfs[percent][transformOriginKey]) {
                        delete finalKfs[percent][transformOriginKey];
                    }
                }
                attrs[transformOriginKey] = transformOrigin;
            }
            if (filter(percents, function (percent) { return keys(finalKfs[percent]).length > 0; }).length) {
                var animationName = addAnimation(finalKfs, scope);
                return animationName + " " + groupAnimator[0] + " both";
            }
        }
        for (var key in groupAnimators) {
            var animationCfg = createSingleCSSAnimation(groupAnimators[key]);
            if (animationCfg) {
                cssAnimations.push(animationCfg);
            }
        }
        if (cssAnimations.length) {
            var className = scope.zrId + '-cls-' + scope.cssClassIdx++;
            scope.cssNodes['.' + className] = {
                animation: cssAnimations.join(',')
            };
            attrs["class"] = className;
        }
    }

    var round$2 = Math.round;
    function isImageLike$1(val) {
        return val && isString(val.src);
    }
    function isCanvasLike(val) {
        return val && isFunction(val.toDataURL);
    }
    function setStyleAttrs(attrs, style, el, scope) {
        mapStyleToAttrs(function (key, val) {
            var isFillStroke = key === 'fill' || key === 'stroke';
            if (isFillStroke && isGradient(val)) {
                setGradient(style, attrs, key, scope);
            }
            else if (isFillStroke && isPattern(val)) {
                setPattern(el, attrs, key, scope);
            }
            else {
                attrs[key] = val;
            }
        }, style, el, false);
        setShadow(el, attrs, scope);
    }
    function noRotateScale(m) {
        return isAroundZero$1(m[0] - 1)
            && isAroundZero$1(m[1])
            && isAroundZero$1(m[2])
            && isAroundZero$1(m[3] - 1);
    }
    function noTranslate(m) {
        return isAroundZero$1(m[4]) && isAroundZero$1(m[5]);
    }
    function setTransform(attrs, m, compress) {
        if (m && !(noTranslate(m) && noRotateScale(m))) {
            var mul = compress ? 10 : 1e4;
            attrs.transform = noRotateScale(m)
                ? "translate(" + round$2(m[4] * mul) / mul + " " + round$2(m[5] * mul) / mul + ")" : getMatrixStr(m);
        }
    }
    function convertPolyShape(shape, attrs, mul) {
        var points = shape.points;
        var strArr = [];
        for (var i = 0; i < points.length; i++) {
            strArr.push(round$2(points[i][0] * mul) / mul);
            strArr.push(round$2(points[i][1] * mul) / mul);
        }
        attrs.points = strArr.join(' ');
    }
    function validatePolyShape(shape) {
        return !shape.smooth;
    }
    function createAttrsConvert(desc) {
        var normalizedDesc = map(desc, function (item) {
            return (typeof item === 'string' ? [item, item] : item);
        });
        return function (shape, attrs, mul) {
            for (var i = 0; i < normalizedDesc.length; i++) {
                var item = normalizedDesc[i];
                var val = shape[item[0]];
                if (val != null) {
                    attrs[item[1]] = round$2(val * mul) / mul;
                }
            }
        };
    }
    var builtinShapesDef = {
        circle: [createAttrsConvert(['cx', 'cy', 'r'])],
        polyline: [convertPolyShape, validatePolyShape],
        polygon: [convertPolyShape, validatePolyShape]
    };
    function hasShapeAnimation(el) {
        var animators = el.animators;
        for (var i = 0; i < animators.length; i++) {
            if (animators[i].targetName === 'shape') {
                return true;
            }
        }
        return false;
    }
    function brushSVGPath(el, scope) {
        var style = el.style;
        var shape = el.shape;
        var builtinShpDef = builtinShapesDef[el.type];
        var attrs = {};
        var needsAnimate = scope.animation;
        var svgElType = 'path';
        var strokePercent = el.style.strokePercent;
        var precision = (scope.compress && getPathPrecision(el)) || 4;
        if (builtinShpDef
            && !scope.willUpdate
            && !(builtinShpDef[1] && !builtinShpDef[1](shape))
            && !(needsAnimate && hasShapeAnimation(el))
            && !(strokePercent < 1)) {
            svgElType = el.type;
            var mul = Math.pow(10, precision);
            builtinShpDef[0](shape, attrs, mul);
        }
        else {
            var needBuildPath = !el.path || el.shapeChanged();
            if (!el.path) {
                el.createPathProxy();
            }
            var path = el.path;
            if (needBuildPath) {
                path.beginPath();
                el.buildPath(path, el.shape);
                el.pathUpdated();
            }
            var pathVersion = path.getVersion();
            var elExt = el;
            var svgPathBuilder = elExt.__svgPathBuilder;
            if (elExt.__svgPathVersion !== pathVersion
                || !svgPathBuilder
                || strokePercent !== elExt.__svgPathStrokePercent) {
                if (!svgPathBuilder) {
                    svgPathBuilder = elExt.__svgPathBuilder = new SVGPathRebuilder();
                }
                svgPathBuilder.reset(precision);
                path.rebuildPath(svgPathBuilder, strokePercent);
                svgPathBuilder.generateStr();
                elExt.__svgPathVersion = pathVersion;
                elExt.__svgPathStrokePercent = strokePercent;
            }
            attrs.d = svgPathBuilder.getStr();
        }
        setTransform(attrs, el.transform);
        setStyleAttrs(attrs, style, el, scope);
        scope.animation && createCSSAnimation(el, attrs, scope);
        return createVNode(svgElType, el.id + '', attrs);
    }
    function brushSVGImage(el, scope) {
        var style = el.style;
        var image = style.image;
        if (image && !isString(image)) {
            if (isImageLike$1(image)) {
                image = image.src;
            }
            else if (isCanvasLike(image)) {
                image = image.toDataURL();
            }
        }
        if (!image) {
            return;
        }
        var x = style.x || 0;
        var y = style.y || 0;
        var dw = style.width;
        var dh = style.height;
        var attrs = {
            href: image,
            width: dw,
            height: dh
        };
        if (x) {
            attrs.x = x;
        }
        if (y) {
            attrs.y = y;
        }
        setTransform(attrs, el.transform);
        setStyleAttrs(attrs, style, el, scope);
        scope.animation && createCSSAnimation(el, attrs, scope);
        return createVNode('image', el.id + '', attrs);
    }
    function brushSVGTSpan(el, scope) {
        var style = el.style;
        var text = style.text;
        text != null && (text += '');
        if (!text || isNaN(style.x) || isNaN(style.y)) {
            return;
        }
        var font = style.font || DEFAULT_FONT;
        var x = style.x || 0;
        var y = adjustTextY(style.y || 0, getLineHeight(font), style.textBaseline);
        var textAlign = TEXT_ALIGN_TO_ANCHOR[style.textAlign]
            || style.textAlign;
        var attrs = {
            'dominant-baseline': 'central',
            'text-anchor': textAlign
        };
        if (hasSeparateFont(style)) {
            var separatedFontStr = '';
            var fontStyle = style.fontStyle;
            var fontSize = parseFontSize(style.fontSize);
            if (!parseFloat(fontSize)) {
                return;
            }
            var fontFamily = style.fontFamily || DEFAULT_FONT_FAMILY;
            var fontWeight = style.fontWeight;
            separatedFontStr += "font-size:" + fontSize + ";font-family:" + fontFamily + ";";
            if (fontStyle && fontStyle !== 'normal') {
                separatedFontStr += "font-style:" + fontStyle + ";";
            }
            if (fontWeight && fontWeight !== 'normal') {
                separatedFontStr += "font-weight:" + fontWeight + ";";
            }
            attrs.style = separatedFontStr;
        }
        else {
            attrs.style = "font: " + font;
        }
        if (text.match(/\s/)) {
            attrs['xml:space'] = 'preserve';
        }
        if (x) {
            attrs.x = x;
        }
        if (y) {
            attrs.y = y;
        }
        setTransform(attrs, el.transform);
        setStyleAttrs(attrs, style, el, scope);
        scope.animation && createCSSAnimation(el, attrs, scope);
        return createVNode('text', el.id + '', attrs, undefined, text);
    }
    function brush$1(el, scope) {
        if (el instanceof Path) {
            return brushSVGPath(el, scope);
        }
        else if (el instanceof ZRImage) {
            return brushSVGImage(el, scope);
        }
        else if (el instanceof TSpan) {
            return brushSVGTSpan(el, scope);
        }
    }
    function setShadow(el, attrs, scope) {
        var style = el.style;
        if (hasShadow(style)) {
            var shadowKey = getShadowKey(el);
            var shadowCache = scope.shadowCache;
            var shadowId = shadowCache[shadowKey];
            if (!shadowId) {
                var globalScale = el.getGlobalScale();
                var scaleX = globalScale[0];
                var scaleY = globalScale[1];
                if (!scaleX || !scaleY) {
                    return;
                }
                var offsetX = style.shadowOffsetX || 0;
                var offsetY = style.shadowOffsetY || 0;
                var blur_1 = style.shadowBlur;
                var _a = normalizeColor(style.shadowColor), opacity = _a.opacity, color = _a.color;
                var stdDx = blur_1 / 2 / scaleX;
                var stdDy = blur_1 / 2 / scaleY;
                var stdDeviation = stdDx + ' ' + stdDy;
                shadowId = scope.zrId + '-s' + scope.shadowIdx++;
                scope.defs[shadowId] = createVNode('filter', shadowId, {
                    'id': shadowId,
                    'x': '-100%',
                    'y': '-100%',
                    'width': '300%',
                    'height': '300%'
                }, [
                    createVNode('feDropShadow', '', {
                        'dx': offsetX / scaleX,
                        'dy': offsetY / scaleY,
                        'stdDeviation': stdDeviation,
                        'flood-color': color,
                        'flood-opacity': opacity
                    })
                ]);
                shadowCache[shadowKey] = shadowId;
            }
            attrs.filter = getIdURL(shadowId);
        }
    }
    function setGradient(style, attrs, target, scope) {
        var val = style[target];
        var gradientTag;
        var gradientAttrs = {
            'gradientUnits': val.global
                ? 'userSpaceOnUse'
                : 'objectBoundingBox'
        };
        if (isLinearGradient(val)) {
            gradientTag = 'linearGradient';
            gradientAttrs.x1 = val.x;
            gradientAttrs.y1 = val.y;
            gradientAttrs.x2 = val.x2;
            gradientAttrs.y2 = val.y2;
        }
        else if (isRadialGradient(val)) {
            gradientTag = 'radialGradient';
            gradientAttrs.cx = retrieve2(val.x, 0.5);
            gradientAttrs.cy = retrieve2(val.y, 0.5);
            gradientAttrs.r = retrieve2(val.r, 0.5);
        }
        else {
            if ("development" !== 'production') {
                logError('Illegal gradient type.');
            }
            return;
        }
        var colors = val.colorStops;
        var colorStops = [];
        for (var i = 0, len = colors.length; i < len; ++i) {
            var offset = round4(colors[i].offset) * 100 + '%';
            var stopColor = colors[i].color;
            var _a = normalizeColor(stopColor), color = _a.color, opacity = _a.opacity;
            var stopsAttrs = {
                'offset': offset
            };
            stopsAttrs['stop-color'] = color;
            if (opacity < 1) {
                stopsAttrs['stop-opacity'] = opacity;
            }
            colorStops.push(createVNode('stop', i + '', stopsAttrs));
        }
        var gradientVNode = createVNode(gradientTag, '', gradientAttrs, colorStops);
        var gradientKey = vNodeToString(gradientVNode);
        var gradientCache = scope.gradientCache;
        var gradientId = gradientCache[gradientKey];
        if (!gradientId) {
            gradientId = scope.zrId + '-g' + scope.gradientIdx++;
            gradientCache[gradientKey] = gradientId;
            gradientAttrs.id = gradientId;
            scope.defs[gradientId] = createVNode(gradientTag, gradientId, gradientAttrs, colorStops);
        }
        attrs[target] = getIdURL(gradientId);
    }
    function setPattern(el, attrs, target, scope) {
        var val = el.style[target];
        var boundingRect = el.getBoundingRect();
        var patternAttrs = {};
        var repeat = val.repeat;
        var noRepeat = repeat === 'no-repeat';
        var repeatX = repeat === 'repeat-x';
        var repeatY = repeat === 'repeat-y';
        var child;
        if (isImagePattern(val)) {
            var imageWidth_1 = val.imageWidth;
            var imageHeight_1 = val.imageHeight;
            var imageSrc = void 0;
            var patternImage = val.image;
            if (isString(patternImage)) {
                imageSrc = patternImage;
            }
            else if (isImageLike$1(patternImage)) {
                imageSrc = patternImage.src;
            }
            else if (isCanvasLike(patternImage)) {
                imageSrc = patternImage.toDataURL();
            }
            if (typeof Image === 'undefined') {
                var errMsg = 'Image width/height must been given explictly in svg-ssr renderer.';
                assert(imageWidth_1, errMsg);
                assert(imageHeight_1, errMsg);
            }
            else if (imageWidth_1 == null || imageHeight_1 == null) {
                var setSizeToVNode_1 = function (vNode, img) {
                    if (vNode) {
                        var svgEl = vNode.elm;
                        var width = imageWidth_1 || img.width;
                        var height = imageHeight_1 || img.height;
                        if (vNode.tag === 'pattern') {
                            if (repeatX) {
                                height = 1;
                                width /= boundingRect.width;
                            }
                            else if (repeatY) {
                                width = 1;
                                height /= boundingRect.height;
                            }
                        }
                        vNode.attrs.width = width;
                        vNode.attrs.height = height;
                        if (svgEl) {
                            svgEl.setAttribute('width', width);
                            svgEl.setAttribute('height', height);
                        }
                    }
                };
                var createdImage = createOrUpdateImage(imageSrc, null, el, function (img) {
                    noRepeat || setSizeToVNode_1(patternVNode, img);
                    setSizeToVNode_1(child, img);
                });
                if (createdImage && createdImage.width && createdImage.height) {
                    imageWidth_1 = imageWidth_1 || createdImage.width;
                    imageHeight_1 = imageHeight_1 || createdImage.height;
                }
            }
            child = createVNode('image', 'img', {
                href: imageSrc,
                width: imageWidth_1,
                height: imageHeight_1
            });
            patternAttrs.width = imageWidth_1;
            patternAttrs.height = imageHeight_1;
        }
        else if (val.svgElement) {
            child = clone(val.svgElement);
            patternAttrs.width = val.svgWidth;
            patternAttrs.height = val.svgHeight;
        }
        if (!child) {
            return;
        }
        var patternWidth;
        var patternHeight;
        if (noRepeat) {
            patternWidth = patternHeight = 1;
        }
        else if (repeatX) {
            patternHeight = 1;
            patternWidth = patternAttrs.width / boundingRect.width;
        }
        else if (repeatY) {
            patternWidth = 1;
            patternHeight = patternAttrs.height / boundingRect.height;
        }
        else {
            patternAttrs.patternUnits = 'userSpaceOnUse';
        }
        if (patternWidth != null && !isNaN(patternWidth)) {
            patternAttrs.width = patternWidth;
        }
        if (patternHeight != null && !isNaN(patternHeight)) {
            patternAttrs.height = patternHeight;
        }
        var patternTransform = getSRTTransformString(val);
        patternTransform && (patternAttrs.patternTransform = patternTransform);
        var patternVNode = createVNode('pattern', '', patternAttrs, [child]);
        var patternKey = vNodeToString(patternVNode);
        var patternCache = scope.patternCache;
        var patternId = patternCache[patternKey];
        if (!patternId) {
            patternId = scope.zrId + '-p' + scope.patternIdx++;
            patternCache[patternKey] = patternId;
            patternAttrs.id = patternId;
            patternVNode = scope.defs[patternId] = createVNode('pattern', patternId, patternAttrs, [child]);
        }
        attrs[target] = getIdURL(patternId);
    }
    function setClipPath(clipPath, attrs, scope) {
        var clipPathCache = scope.clipPathCache, defs = scope.defs;
        var clipPathId = clipPathCache[clipPath.id];
        if (!clipPathId) {
            clipPathId = scope.zrId + '-c' + scope.clipPathIdx++;
            var clipPathAttrs = {
                id: clipPathId
            };
            clipPathCache[clipPath.id] = clipPathId;
            defs[clipPathId] = createVNode('clipPath', clipPathId, clipPathAttrs, [brushSVGPath(clipPath, scope)]);
        }
        attrs['clip-path'] = getIdURL(clipPathId);
    }

    function createTextNode(text) {
        return document.createTextNode(text);
    }
    function insertBefore(parentNode, newNode, referenceNode) {
        parentNode.insertBefore(newNode, referenceNode);
    }
    function removeChild(node, child) {
        node.removeChild(child);
    }
    function appendChild(node, child) {
        node.appendChild(child);
    }
    function parentNode(node) {
        return node.parentNode;
    }
    function nextSibling(node) {
        return node.nextSibling;
    }
    function setTextContent(node, text) {
        node.textContent = text;
    }

    var colonChar = 58;
    var xChar = 120;
    var emptyNode = createVNode('', '');
    function isUndef(s) {
        return s === undefined;
    }
    function isDef(s) {
        return s !== undefined;
    }
    function createKeyToOldIdx(children, beginIdx, endIdx) {
        var map = {};
        for (var i = beginIdx; i <= endIdx; ++i) {
            var key = children[i].key;
            if (key !== undefined) {
                if ("development" !== 'production') {
                    if (map[key] != null) {
                        console.error("Duplicate key " + key);
                    }
                }
                map[key] = i;
            }
        }
        return map;
    }
    function sameVnode(vnode1, vnode2) {
        var isSameKey = vnode1.key === vnode2.key;
        var isSameTag = vnode1.tag === vnode2.tag;
        return isSameTag && isSameKey;
    }
    function createElm(vnode) {
        var i;
        var children = vnode.children;
        var tag = vnode.tag;
        if (isDef(tag)) {
            var elm = (vnode.elm = createElement(tag));
            updateAttrs(emptyNode, vnode);
            if (isArray(children)) {
                for (i = 0; i < children.length; ++i) {
                    var ch = children[i];
                    if (ch != null) {
                        appendChild(elm, createElm(ch));
                    }
                }
            }
            else if (isDef(vnode.text) && !isObject(vnode.text)) {
                appendChild(elm, createTextNode(vnode.text));
            }
        }
        else {
            vnode.elm = createTextNode(vnode.text);
        }
        return vnode.elm;
    }
    function addVnodes(parentElm, before, vnodes, startIdx, endIdx) {
        for (; startIdx <= endIdx; ++startIdx) {
            var ch = vnodes[startIdx];
            if (ch != null) {
                insertBefore(parentElm, createElm(ch), before);
            }
        }
    }
    function removeVnodes(parentElm, vnodes, startIdx, endIdx) {
        for (; startIdx <= endIdx; ++startIdx) {
            var ch = vnodes[startIdx];
            if (ch != null) {
                if (isDef(ch.tag)) {
                    var parent_1 = parentNode(ch.elm);
                    removeChild(parent_1, ch.elm);
                }
                else {
                    removeChild(parentElm, ch.elm);
                }
            }
        }
    }
    function updateAttrs(oldVnode, vnode) {
        var key;
        var elm = vnode.elm;
        var oldAttrs = oldVnode && oldVnode.attrs || {};
        var attrs = vnode.attrs || {};
        if (oldAttrs === attrs) {
            return;
        }
        for (key in attrs) {
            var cur = attrs[key];
            var old = oldAttrs[key];
            if (old !== cur) {
                if (cur === true) {
                    elm.setAttribute(key, '');
                }
                else if (cur === false) {
                    elm.removeAttribute(key);
                }
                else {
                    if (key.charCodeAt(0) !== xChar) {
                        elm.setAttribute(key, cur);
                    }
                    else if (key === 'xmlns:xlink' || key === 'xmlns') {
                        elm.setAttributeNS(XMLNS, key, cur);
                    }
                    else if (key.charCodeAt(3) === colonChar) {
                        elm.setAttributeNS(XML_NAMESPACE, key, cur);
                    }
                    else if (key.charCodeAt(5) === colonChar) {
                        elm.setAttributeNS(XLINKNS, key, cur);
                    }
                    else {
                        elm.setAttribute(key, cur);
                    }
                }
            }
        }
        for (key in oldAttrs) {
            if (!(key in attrs)) {
                elm.removeAttribute(key);
            }
        }
    }
    function updateChildren(parentElm, oldCh, newCh) {
        var oldStartIdx = 0;
        var newStartIdx = 0;
        var oldEndIdx = oldCh.length - 1;
        var oldStartVnode = oldCh[0];
        var oldEndVnode = oldCh[oldEndIdx];
        var newEndIdx = newCh.length - 1;
        var newStartVnode = newCh[0];
        var newEndVnode = newCh[newEndIdx];
        var oldKeyToIdx;
        var idxInOld;
        var elmToMove;
        var before;
        while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {
            if (oldStartVnode == null) {
                oldStartVnode = oldCh[++oldStartIdx];
            }
            else if (oldEndVnode == null) {
                oldEndVnode = oldCh[--oldEndIdx];
            }
            else if (newStartVnode == null) {
                newStartVnode = newCh[++newStartIdx];
            }
            else if (newEndVnode == null) {
                newEndVnode = newCh[--newEndIdx];
            }
            else if (sameVnode(oldStartVnode, newStartVnode)) {
                patchVnode(oldStartVnode, newStartVnode);
                oldStartVnode = oldCh[++oldStartIdx];
                newStartVnode = newCh[++newStartIdx];
            }
            else if (sameVnode(oldEndVnode, newEndVnode)) {
                patchVnode(oldEndVnode, newEndVnode);
                oldEndVnode = oldCh[--oldEndIdx];
                newEndVnode = newCh[--newEndIdx];
            }
            else if (sameVnode(oldStartVnode, newEndVnode)) {
                patchVnode(oldStartVnode, newEndVnode);
                insertBefore(parentElm, oldStartVnode.elm, nextSibling(oldEndVnode.elm));
                oldStartVnode = oldCh[++oldStartIdx];
                newEndVnode = newCh[--newEndIdx];
            }
            else if (sameVnode(oldEndVnode, newStartVnode)) {
                patchVnode(oldEndVnode, newStartVnode);
                insertBefore(parentElm, oldEndVnode.elm, oldStartVnode.elm);
                oldEndVnode = oldCh[--oldEndIdx];
                newStartVnode = newCh[++newStartIdx];
            }
            else {
                if (isUndef(oldKeyToIdx)) {
                    oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx);
                }
                idxInOld = oldKeyToIdx[newStartVnode.key];
                if (isUndef(idxInOld)) {
                    insertBefore(parentElm, createElm(newStartVnode), oldStartVnode.elm);
                }
                else {
                    elmToMove = oldCh[idxInOld];
                    if (elmToMove.tag !== newStartVnode.tag) {
                        insertBefore(parentElm, createElm(newStartVnode), oldStartVnode.elm);
                    }
                    else {
                        patchVnode(elmToMove, newStartVnode);
                        oldCh[idxInOld] = undefined;
                        insertBefore(parentElm, elmToMove.elm, oldStartVnode.elm);
                    }
                }
                newStartVnode = newCh[++newStartIdx];
            }
        }
        if (oldStartIdx <= oldEndIdx || newStartIdx <= newEndIdx) {
            if (oldStartIdx > oldEndIdx) {
                before = newCh[newEndIdx + 1] == null ? null : newCh[newEndIdx + 1].elm;
                addVnodes(parentElm, before, newCh, newStartIdx, newEndIdx);
            }
            else {
                removeVnodes(parentElm, oldCh, oldStartIdx, oldEndIdx);
            }
        }
    }
    function patchVnode(oldVnode, vnode) {
        var elm = (vnode.elm = oldVnode.elm);
        var oldCh = oldVnode.children;
        var ch = vnode.children;
        if (oldVnode === vnode) {
            return;
        }
        updateAttrs(oldVnode, vnode);
        if (isUndef(vnode.text)) {
            if (isDef(oldCh) && isDef(ch)) {
                if (oldCh !== ch) {
                    updateChildren(elm, oldCh, ch);
                }
            }
            else if (isDef(ch)) {
                if (isDef(oldVnode.text)) {
                    setTextContent(elm, '');
                }
                addVnodes(elm, null, ch, 0, ch.length - 1);
            }
            else if (isDef(oldCh)) {
                removeVnodes(elm, oldCh, 0, oldCh.length - 1);
            }
            else if (isDef(oldVnode.text)) {
                setTextContent(elm, '');
            }
        }
        else if (oldVnode.text !== vnode.text) {
            if (isDef(oldCh)) {
                removeVnodes(elm, oldCh, 0, oldCh.length - 1);
            }
            setTextContent(elm, vnode.text);
        }
    }
    function patch(oldVnode, vnode) {
        if (sameVnode(oldVnode, vnode)) {
            patchVnode(oldVnode, vnode);
        }
        else {
            var elm = oldVnode.elm;
            var parent_2 = parentNode(elm);
            createElm(vnode);
            if (parent_2 !== null) {
                insertBefore(parent_2, vnode.elm, nextSibling(elm));
                removeVnodes(parent_2, [oldVnode], 0, 0);
            }
        }
        return vnode;
    }

    var svgId = 0;
    var SVGPainter = (function () {
        function SVGPainter(root, storage, opts) {
            this.type = 'svg';
            this.refreshHover = createMethodNotSupport('refreshHover');
            this.configLayer = createMethodNotSupport('configLayer');
            this.storage = storage;
            this._opts = opts = extend({}, opts);
            this.root = root;
            this._id = 'zr' + svgId++;
            this._oldVNode = createSVGVNode(opts.width, opts.height);
            if (root && !opts.ssr) {
                var viewport = this._viewport = document.createElement('div');
                viewport.style.cssText = 'position:relative;overflow:hidden';
                var svgDom = this._svgDom = this._oldVNode.elm = createElement('svg');
                updateAttrs(null, this._oldVNode);
                viewport.appendChild(svgDom);
                root.appendChild(viewport);
            }
            this.resize(opts.width, opts.height);
        }
        SVGPainter.prototype.getType = function () {
            return this.type;
        };
        SVGPainter.prototype.getViewportRoot = function () {
            return this._viewport;
        };
        SVGPainter.prototype.getViewportRootOffset = function () {
            var viewportRoot = this.getViewportRoot();
            if (viewportRoot) {
                return {
                    offsetLeft: viewportRoot.offsetLeft || 0,
                    offsetTop: viewportRoot.offsetTop || 0
                };
            }
        };
        SVGPainter.prototype.getSvgDom = function () {
            return this._svgDom;
        };
        SVGPainter.prototype.refresh = function () {
            if (this.root) {
                var vnode = this.renderToVNode({
                    willUpdate: true
                });
                vnode.attrs.style = 'position:absolute;left:0;top:0;user-select:none';
                patch(this._oldVNode, vnode);
                this._oldVNode = vnode;
            }
        };
        SVGPainter.prototype.renderOneToVNode = function (el) {
            return brush$1(el, createBrushScope(this._id));
        };
        SVGPainter.prototype.renderToVNode = function (opts) {
            opts = opts || {};
            var list = this.storage.getDisplayList(true);
            var width = this._width;
            var height = this._height;
            var scope = createBrushScope(this._id);
            scope.animation = opts.animation;
            scope.willUpdate = opts.willUpdate;
            scope.compress = opts.compress;
            var children = [];
            var bgVNode = this._bgVNode = createBackgroundVNode(width, height, this._backgroundColor, scope);
            bgVNode && children.push(bgVNode);
            var mainVNode = !opts.compress
                ? (this._mainVNode = createVNode('g', 'main', {}, [])) : null;
            this._paintList(list, scope, mainVNode ? mainVNode.children : children);
            mainVNode && children.push(mainVNode);
            var defs = map(keys(scope.defs), function (id) { return scope.defs[id]; });
            if (defs.length) {
                children.push(createVNode('defs', 'defs', {}, defs));
            }
            if (opts.animation) {
                var animationCssStr = getCssString(scope.cssNodes, scope.cssAnims, { newline: true });
                if (animationCssStr) {
                    var styleNode = createVNode('style', 'stl', {}, [], animationCssStr);
                    children.push(styleNode);
                }
            }
            return createSVGVNode(width, height, children, opts.useViewBox);
        };
        SVGPainter.prototype.renderToString = function (opts) {
            opts = opts || {};
            return vNodeToString(this.renderToVNode({
                animation: retrieve2(opts.cssAnimation, true),
                willUpdate: false,
                compress: true,
                useViewBox: retrieve2(opts.useViewBox, true)
            }), { newline: true });
        };
        SVGPainter.prototype.setBackgroundColor = function (backgroundColor) {
            this._backgroundColor = backgroundColor;
        };
        SVGPainter.prototype.getSvgRoot = function () {
            return this._mainVNode && this._mainVNode.elm;
        };
        SVGPainter.prototype._paintList = function (list, scope, out) {
            var listLen = list.length;
            var clipPathsGroupsStack = [];
            var clipPathsGroupsStackDepth = 0;
            var currentClipPathGroup;
            var prevClipPaths;
            var clipGroupNodeIdx = 0;
            for (var i = 0; i < listLen; i++) {
                var displayable = list[i];
                if (!displayable.invisible) {
                    var clipPaths = displayable.__clipPaths;
                    var len = clipPaths && clipPaths.length || 0;
                    var prevLen = prevClipPaths && prevClipPaths.length || 0;
                    var lca = void 0;
                    for (lca = Math.max(len - 1, prevLen - 1); lca >= 0; lca--) {
                        if (clipPaths && prevClipPaths
                            && clipPaths[lca] === prevClipPaths[lca]) {
                            break;
                        }
                    }
                    for (var i_1 = prevLen - 1; i_1 > lca; i_1--) {
                        clipPathsGroupsStackDepth--;
                        currentClipPathGroup = clipPathsGroupsStack[clipPathsGroupsStackDepth - 1];
                    }
                    for (var i_2 = lca + 1; i_2 < len; i_2++) {
                        var groupAttrs = {};
                        setClipPath(clipPaths[i_2], groupAttrs, scope);
                        var g = createVNode('g', 'clip-g-' + clipGroupNodeIdx++, groupAttrs, []);
                        (currentClipPathGroup ? currentClipPathGroup.children : out).push(g);
                        clipPathsGroupsStack[clipPathsGroupsStackDepth++] = g;
                        currentClipPathGroup = g;
                    }
                    prevClipPaths = clipPaths;
                    var ret = brush$1(displayable, scope);
                    if (ret) {
                        (currentClipPathGroup ? currentClipPathGroup.children : out).push(ret);
                    }
                }
            }
        };
        SVGPainter.prototype.resize = function (width, height) {
            var opts = this._opts;
            var root = this.root;
            var viewport = this._viewport;
            width != null && (opts.width = width);
            height != null && (opts.height = height);
            if (root && viewport) {
                viewport.style.display = 'none';
                width = getSize(root, 0, opts);
                height = getSize(root, 1, opts);
                viewport.style.display = '';
            }
            if (this._width !== width || this._height !== height) {
                this._width = width;
                this._height = height;
                if (viewport) {
                    var viewportStyle = viewport.style;
                    viewportStyle.width = width + 'px';
                    viewportStyle.height = height + 'px';
                }
                if (!isPattern(this._backgroundColor)) {
                    var svgDom = this._svgDom;
                    if (svgDom) {
                        svgDom.setAttribute('width', width);
                        svgDom.setAttribute('height', height);
                    }
                    var bgEl = this._bgVNode && this._bgVNode.elm;
                    if (bgEl) {
                        bgEl.setAttribute('width', width);
                        bgEl.setAttribute('height', height);
                    }
                }
                else {
                    this.refresh();
                }
            }
        };
        SVGPainter.prototype.getWidth = function () {
            return this._width;
        };
        SVGPainter.prototype.getHeight = function () {
            return this._height;
        };
        SVGPainter.prototype.dispose = function () {
            if (this.root) {
                this.root.innerHTML = '';
            }
            this._svgDom =
                this._viewport =
                    this.storage =
                        this._oldVNode =
                            this._bgVNode =
                                this._mainVNode = null;
        };
        SVGPainter.prototype.clear = function () {
            if (this._svgDom) {
                this._svgDom.innerHTML = null;
            }
            this._oldVNode = null;
        };
        SVGPainter.prototype.toDataURL = function (base64) {
            var str = this.renderToString();
            var prefix = 'data:image/svg+xml;';
            if (base64) {
                str = encodeBase64(str);
                return str && prefix + 'base64,' + str;
            }
            return prefix + 'charset=UTF-8,' + encodeURIComponent(str);
        };
        return SVGPainter;
    }());
    function createMethodNotSupport(method) {
        return function () {
            if ("development" !== 'production') {
                logError('In SVG mode painter not support method "' + method + '"');
            }
        };
    }
    function createBackgroundVNode(width, height, backgroundColor, scope) {
        var bgVNode;
        if (backgroundColor && backgroundColor !== 'none') {
            bgVNode = createVNode('rect', 'bg', {
                width: width,
                height: height,
                x: '0',
                y: '0',
                id: '0'
            });
            if (isGradient(backgroundColor)) {
                setGradient({ fill: backgroundColor }, bgVNode.attrs, 'fill', scope);
            }
            else if (isPattern(backgroundColor)) {
                setPattern({
                    style: {
                        fill: backgroundColor
                    },
                    dirty: noop,
                    getBoundingRect: function () { return ({ width: width, height: height }); }
                }, bgVNode.attrs, 'fill', scope);
            }
            else {
                var _a = normalizeColor(backgroundColor), color = _a.color, opacity = _a.opacity;
                bgVNode.attrs.fill = color;
                opacity < 1 && (bgVNode.attrs['fill-opacity'] = opacity);
            }
        }
        return bgVNode;
    }

    function install(registers) {
      registers.registerPainter('svg', SVGPainter);
    }

    function createDom(id, painter, dpr) {
        var newDom = platformApi.createCanvas();
        var width = painter.getWidth();
        var height = painter.getHeight();
        var newDomStyle = newDom.style;
        if (newDomStyle) {
            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;
    }
    var Layer = (function (_super) {
        __extends(Layer, _super);
        function Layer(id, painter, dpr) {
            var _this = _super.call(this) || this;
            _this.motionBlur = false;
            _this.lastFrameAlpha = 0.7;
            _this.dpr = 1;
            _this.virtual = false;
            _this.config = {};
            _this.incremental = false;
            _this.zlevel = 0;
            _this.maxRepaintRectCount = 5;
            _this.__dirty = true;
            _this.__firstTimePaint = true;
            _this.__used = false;
            _this.__drawIndex = 0;
            _this.__startIndex = 0;
            _this.__endIndex = 0;
            _this.__prevStartIndex = null;
            _this.__prevEndIndex = null;
            var dom;
            dpr = dpr || devicePixelRatio;
            if (typeof id === 'string') {
                dom = createDom(id, painter, dpr);
            }
            else if (isObject(id)) {
                dom = id;
                id = dom.id;
            }
            _this.id = id;
            _this.dom = dom;
            var domStyle = dom.style;
            if (domStyle) {
                disableUserSelect(dom);
                dom.onselectstart = function () { return false; };
                domStyle.padding = '0';
                domStyle.margin = '0';
                domStyle.borderWidth = '0';
            }
            _this.painter = painter;
            _this.dpr = dpr;
            return _this;
        }
        Layer.prototype.getElementCount = function () {
            return this.__endIndex - this.__startIndex;
        };
        Layer.prototype.afterBrush = function () {
            this.__prevStartIndex = this.__startIndex;
            this.__prevEndIndex = this.__endIndex;
        };
        Layer.prototype.initContext = function () {
            this.ctx = this.dom.getContext('2d');
            this.ctx.dpr = this.dpr;
        };
        Layer.prototype.setUnpainted = function () {
            this.__firstTimePaint = true;
        };
        Layer.prototype.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);
            }
        };
        Layer.prototype.createRepaintRects = function (displayList, prevList, viewWidth, viewHeight) {
            if (this.__firstTimePaint) {
                this.__firstTimePaint = false;
                return null;
            }
            var mergedRepaintRects = [];
            var maxRepaintRectCount = this.maxRepaintRectCount;
            var full = false;
            var pendingRect = new BoundingRect(0, 0, 0, 0);
            function addRectToMergePool(rect) {
                if (!rect.isFinite() || rect.isZero()) {
                    return;
                }
                if (mergedRepaintRects.length === 0) {
                    var boundingRect = new BoundingRect(0, 0, 0, 0);
                    boundingRect.copy(rect);
                    mergedRepaintRects.push(boundingRect);
                }
                else {
                    var isMerged = false;
                    var minDeltaArea = Infinity;
                    var bestRectToMergeIdx = 0;
                    for (var i = 0; i < mergedRepaintRects.length; ++i) {
                        var mergedRect = mergedRepaintRects[i];
                        if (mergedRect.intersect(rect)) {
                            var pendingRect_1 = new BoundingRect(0, 0, 0, 0);
                            pendingRect_1.copy(mergedRect);
                            pendingRect_1.union(rect);
                            mergedRepaintRects[i] = pendingRect_1;
                            isMerged = true;
                            break;
                        }
                        else if (full) {
                            pendingRect.copy(rect);
                            pendingRect.union(mergedRect);
                            var aArea = rect.width * rect.height;
                            var bArea = mergedRect.width * mergedRect.height;
                            var pendingArea = pendingRect.width * pendingRect.height;
                            var deltaArea = pendingArea - aArea - bArea;
                            if (deltaArea < minDeltaArea) {
                                minDeltaArea = deltaArea;
                                bestRectToMergeIdx = i;
                            }
                        }
                    }
                    if (full) {
                        mergedRepaintRects[bestRectToMergeIdx].union(rect);
                        isMerged = true;
                    }
                    if (!isMerged) {
                        var boundingRect = new BoundingRect(0, 0, 0, 0);
                        boundingRect.copy(rect);
                        mergedRepaintRects.push(boundingRect);
                    }
                    if (!full) {
                        full = mergedRepaintRects.length >= maxRepaintRectCount;
                    }
                }
            }
            for (var i = this.__startIndex; i < this.__endIndex; ++i) {
                var el = displayList[i];
                if (el) {
                    var shouldPaint = el.shouldBePainted(viewWidth, viewHeight, true, true);
                    var prevRect = el.__isRendered && ((el.__dirty & REDRAW_BIT) || !shouldPaint)
                        ? el.getPrevPaintRect()
                        : null;
                    if (prevRect) {
                        addRectToMergePool(prevRect);
                    }
                    var curRect = shouldPaint && ((el.__dirty & REDRAW_BIT) || !el.__isRendered)
                        ? el.getPaintRect()
                        : null;
                    if (curRect) {
                        addRectToMergePool(curRect);
                    }
                }
            }
            for (var i = this.__prevStartIndex; i < this.__prevEndIndex; ++i) {
                var el = prevList[i];
                var shouldPaint = el.shouldBePainted(viewWidth, viewHeight, true, true);
                if (el && (!shouldPaint || !el.__zr) && el.__isRendered) {
                    var prevRect = el.getPrevPaintRect();
                    if (prevRect) {
                        addRectToMergePool(prevRect);
                    }
                }
            }
            var hasIntersections;
            do {
                hasIntersections = false;
                for (var i = 0; i < mergedRepaintRects.length;) {
                    if (mergedRepaintRects[i].isZero()) {
                        mergedRepaintRects.splice(i, 1);
                        continue;
                    }
                    for (var j = i + 1; j < mergedRepaintRects.length;) {
                        if (mergedRepaintRects[i].intersect(mergedRepaintRects[j])) {
                            hasIntersections = true;
                            mergedRepaintRects[i].union(mergedRepaintRects[j]);
                            mergedRepaintRects.splice(j, 1);
                        }
                        else {
                            j++;
                        }
                    }
                    i++;
                }
            } while (hasIntersections);
            this._paintRects = mergedRepaintRects;
            return mergedRepaintRects;
        };
        Layer.prototype.debugGetPaintRects = function () {
            return (this._paintRects || []).slice();
        };
        Layer.prototype.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);
                }
            }
        };
        Layer.prototype.clear = function (clearAll, clearColor, repaintRects) {
            var dom = this.dom;
            var ctx = this.ctx;
            var width = dom.width;
            var height = dom.height;
            clearColor = clearColor || this.clearColor;
            var haveMotionBLur = this.motionBlur && !clearAll;
            var lastFrameAlpha = this.lastFrameAlpha;
            var dpr = this.dpr;
            var self = this;
            if (haveMotionBLur) {
                if (!this.domBack) {
                    this.createBackBuffer();
                }
                this.ctxBack.globalCompositeOperation = 'copy';
                this.ctxBack.drawImage(dom, 0, 0, width / dpr, height / dpr);
            }
            var domBack = this.domBack;
            function doClear(x, y, width, height) {
                ctx.clearRect(x, y, width, height);
                if (clearColor && clearColor !== 'transparent') {
                    var clearColorGradientOrPattern = void 0;
                    if (isGradientObject(clearColor)) {
                        var shouldCache = clearColor.global || (clearColor.__width === width
                            && clearColor.__height === height);
                        clearColorGradientOrPattern = shouldCache
                            && clearColor.__canvasGradient
                            || getCanvasGradient(ctx, clearColor, {
                                x: 0,
                                y: 0,
                                width: width,
                                height: height
                            });
                        clearColor.__canvasGradient = clearColorGradientOrPattern;
                        clearColor.__width = width;
                        clearColor.__height = height;
                    }
                    else if (isImagePatternObject(clearColor)) {
                        clearColor.scaleX = clearColor.scaleX || dpr;
                        clearColor.scaleY = clearColor.scaleY || dpr;
                        clearColorGradientOrPattern = createCanvasPattern(ctx, clearColor, {
                            dirty: function () {
                                self.setUnpainted();
                                self.__painter.refresh();
                            }
                        });
                    }
                    ctx.save();
                    ctx.fillStyle = clearColorGradientOrPattern || clearColor;
                    ctx.fillRect(x, y, width, height);
                    ctx.restore();
                }
                if (haveMotionBLur) {
                    ctx.save();
                    ctx.globalAlpha = lastFrameAlpha;
                    ctx.drawImage(domBack, x, y, width, height);
                    ctx.restore();
                }
            }
            if (!repaintRects || haveMotionBLur) {
                doClear(0, 0, width, height);
            }
            else if (repaintRects.length) {
                each(repaintRects, function (rect) {
                    doClear(rect.x * dpr, rect.y * dpr, rect.width * dpr, rect.height * dpr);
                });
            }
        };
        return Layer;
    }(Eventful));

    var HOVER_LAYER_ZLEVEL = 1e5;
    var CANVAS_ZLEVEL = 314159;
    var EL_AFTER_INCREMENTAL_INC = 0.01;
    var INCREMENTAL_INC = 0.001;
    function isLayerValid(layer) {
        if (!layer) {
            return false;
        }
        if (layer.__builtin__) {
            return true;
        }
        if (typeof (layer.resize) !== 'function'
            || typeof (layer.refresh) !== 'function') {
            return false;
        }
        return true;
    }
    function createRoot(width, height) {
        var domRoot = document.createElement('div');
        domRoot.style.cssText = [
            'position:relative',
            'width:' + width + 'px',
            'height:' + height + 'px',
            'padding:0',
            'margin:0',
            'border-width:0'
        ].join(';') + ';';
        return domRoot;
    }
    var CanvasPainter = (function () {
        function CanvasPainter(root, storage, opts, id) {
            this.type = 'canvas';
            this._zlevelList = [];
            this._prevDisplayList = [];
            this._layers = {};
            this._layerConfig = {};
            this._needsManuallyCompositing = false;
            this.type = 'canvas';
            var singleCanvas = !root.nodeName
                || root.nodeName.toUpperCase() === 'CANVAS';
            this._opts = opts = extend({}, opts || {});
            this.dpr = opts.devicePixelRatio || devicePixelRatio;
            this._singleCanvas = singleCanvas;
            this.root = root;
            var rootStyle = root.style;
            if (rootStyle) {
                disableUserSelect(root);
                root.innerHTML = '';
            }
            this.storage = storage;
            var zlevelList = this._zlevelList;
            this._prevDisplayList = [];
            var layers = this._layers;
            if (!singleCanvas) {
                this._width = getSize(root, 0, opts);
                this._height = getSize(root, 1, opts);
                var domRoot = this._domRoot = createRoot(this._width, this._height);
                root.appendChild(domRoot);
            }
            else {
                var rootCanvas = root;
                var width = rootCanvas.width;
                var height = rootCanvas.height;
                if (opts.width != null) {
                    width = opts.width;
                }
                if (opts.height != null) {
                    height = opts.height;
                }
                this.dpr = opts.devicePixelRatio || 1;
                rootCanvas.width = width * this.dpr;
                rootCanvas.height = height * this.dpr;
                this._width = width;
                this._height = height;
                var mainLayer = new Layer(rootCanvas, this, this.dpr);
                mainLayer.__builtin__ = true;
                mainLayer.initContext();
                layers[CANVAS_ZLEVEL] = mainLayer;
                mainLayer.zlevel = CANVAS_ZLEVEL;
                zlevelList.push(CANVAS_ZLEVEL);
                this._domRoot = root;
            }
        }
        CanvasPainter.prototype.getType = function () {
            return 'canvas';
        };
        CanvasPainter.prototype.isSingleCanvas = function () {
            return this._singleCanvas;
        };
        CanvasPainter.prototype.getViewportRoot = function () {
            return this._domRoot;
        };
        CanvasPainter.prototype.getViewportRootOffset = function () {
            var viewportRoot = this.getViewportRoot();
            if (viewportRoot) {
                return {
                    offsetLeft: viewportRoot.offsetLeft || 0,
                    offsetTop: viewportRoot.offsetTop || 0
                };
            }
        };
        CanvasPainter.prototype.refresh = function (paintAll) {
            var list = this.storage.getDisplayList(true);
            var prevList = this._prevDisplayList;
            var zlevelList = this._zlevelList;
            this._redrawId = Math.random();
            this._paintList(list, prevList, paintAll, this._redrawId);
            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);
                }
            }
            if (this._opts.useDirtyRect) {
                this._prevDisplayList = list.slice();
            }
            return this;
        };
        CanvasPainter.prototype.refreshHover = function () {
            this._paintHoverList(this.storage.getDisplayList(false));
        };
        CanvasPainter.prototype._paintHoverList = function (list) {
            var len = list.length;
            var hoverLayer = this._hoverlayer;
            hoverLayer && hoverLayer.clear();
            if (!len) {
                return;
            }
            var scope = {
                inHover: true,
                viewWidth: this._width,
                viewHeight: this._height
            };
            var ctx;
            for (var i = 0; i < len; i++) {
                var el = list[i];
                if (el.__inHover) {
                    if (!hoverLayer) {
                        hoverLayer = this._hoverlayer = this.getLayer(HOVER_LAYER_ZLEVEL);
                    }
                    if (!ctx) {
                        ctx = hoverLayer.ctx;
                        ctx.save();
                    }
                    brush(ctx, el, scope, i === len - 1);
                }
            }
            if (ctx) {
                ctx.restore();
            }
        };
        CanvasPainter.prototype.getHoverLayer = function () {
            return this.getLayer(HOVER_LAYER_ZLEVEL);
        };
        CanvasPainter.prototype.paintOne = function (ctx, el) {
            brushSingle(ctx, el);
        };
        CanvasPainter.prototype._paintList = function (list, prevList, paintAll, redrawId) {
            if (this._redrawId !== redrawId) {
                return;
            }
            paintAll = paintAll || false;
            this._updateLayerStatus(list);
            var _a = this._doPaintList(list, prevList, paintAll), finished = _a.finished, needsRefreshHover = _a.needsRefreshHover;
            if (this._needsManuallyCompositing) {
                this._compositeManually();
            }
            if (needsRefreshHover) {
                this._paintHoverList(list);
            }
            if (!finished) {
                var self_1 = this;
                requestAnimationFrame$1(function () {
                    self_1._paintList(list, prevList, paintAll, redrawId);
                });
            }
            else {
                this.eachLayer(function (layer) {
                    layer.afterBrush && layer.afterBrush();
                });
            }
        };
        CanvasPainter.prototype._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);
            this.eachBuiltinLayer(function (layer) {
                if (layer.virtual) {
                    ctx.drawImage(layer.dom, 0, 0, width, height);
                }
            });
        };
        CanvasPainter.prototype._doPaintList = function (list, prevList, paintAll) {
            var _this = this;
            var layerList = [];
            var useDirtyRect = this._opts.useDirtyRect;
            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;
            var needsRefreshHover = false;
            var _loop_1 = function (k) {
                var layer = layerList[k];
                var ctx = layer.ctx;
                var repaintRects = useDirtyRect
                    && layer.createRepaintRects(list, prevList, this_1._width, this_1._height);
                var start = paintAll ? layer.__startIndex : layer.__drawIndex;
                var useTimer = !paintAll && layer.incremental && Date.now;
                var startTime = useTimer && Date.now();
                var clearColor = layer.zlevel === this_1._zlevelList[0]
                    ? this_1._backgroundColor : null;
                if (layer.__startIndex === layer.__endIndex) {
                    layer.clear(false, clearColor, repaintRects);
                }
                else if (start === layer.__startIndex) {
                    var firstEl = list[start];
                    if (!firstEl.incremental || !firstEl.notClear || paintAll) {
                        layer.clear(false, clearColor, repaintRects);
                    }
                }
                if (start === -1) {
                    console.error('For some unknown reason. drawIndex is -1');
                    start = layer.__startIndex;
                }
                var i;
                var repaint = function (repaintRect) {
                    var scope = {
                        inHover: false,
                        allClipped: false,
                        prevEl: null,
                        viewWidth: _this._width,
                        viewHeight: _this._height
                    };
                    for (i = start; i < layer.__endIndex; i++) {
                        var el = list[i];
                        if (el.__inHover) {
                            needsRefreshHover = true;
                        }
                        _this._doPaintEl(el, layer, useDirtyRect, repaintRect, scope, i === layer.__endIndex - 1);
                        if (useTimer) {
                            var dTime = Date.now() - startTime;
                            if (dTime > 15) {
                                break;
                            }
                        }
                    }
                    if (scope.prevElClipPaths) {
                        ctx.restore();
                    }
                };
                if (repaintRects) {
                    if (repaintRects.length === 0) {
                        i = layer.__endIndex;
                    }
                    else {
                        var dpr = this_1.dpr;
                        for (var r = 0; r < repaintRects.length; ++r) {
                            var rect = repaintRects[r];
                            ctx.save();
                            ctx.beginPath();
                            ctx.rect(rect.x * dpr, rect.y * dpr, rect.width * dpr, rect.height * dpr);
                            ctx.clip();
                            repaint(rect);
                            ctx.restore();
                        }
                    }
                }
                else {
                    ctx.save();
                    repaint();
                    ctx.restore();
                }
                layer.__drawIndex = i;
                if (layer.__drawIndex < layer.__endIndex) {
                    finished = false;
                }
            };
            var this_1 = this;
            for (var k = 0; k < layerList.length; k++) {
                _loop_1(k);
            }
            if (env.wxa) {
                each(this._layers, function (layer) {
                    if (layer && layer.ctx && layer.ctx.draw) {
                        layer.ctx.draw();
                    }
                });
            }
            return {
                finished: finished,
                needsRefreshHover: needsRefreshHover
            };
        };
        CanvasPainter.prototype._doPaintEl = function (el, currentLayer, useDirtyRect, repaintRect, scope, isLast) {
            var ctx = currentLayer.ctx;
            if (useDirtyRect) {
                var paintRect = el.getPaintRect();
                if (!repaintRect || paintRect && paintRect.intersect(repaintRect)) {
                    brush(ctx, el, scope, isLast);
                    el.setPrevPaintRect(paintRect);
                }
            }
            else {
                brush(ctx, el, scope, isLast);
            }
        };
        CanvasPainter.prototype.getLayer = function (zlevel, virtual) {
            if (this._singleCanvas && !this._needsManuallyCompositing) {
                zlevel = CANVAS_ZLEVEL;
            }
            var layer = this._layers[zlevel];
            if (!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);
                }
                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);
                layer.initContext();
            }
            return layer;
        };
        CanvasPainter.prototype.insertLayer = function (zlevel, layer) {
            var layersMap = this._layers;
            var zlevelList = this._zlevelList;
            var len = zlevelList.length;
            var domRoot = this._domRoot;
            var prevLayer = null;
            var i = -1;
            if (layersMap[zlevel]) {
                if ("development" !== 'production') {
                    logError('ZLevel ' + zlevel + ' has been used already');
                }
                return;
            }
            if (!isLayerValid(layer)) {
                if ("development" !== 'production') {
                    logError('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;
            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);
                    }
                }
            }
            layer.__painter = this;
        };
        CanvasPainter.prototype.eachLayer = function (cb, context) {
            var zlevelList = this._zlevelList;
            for (var i = 0; i < zlevelList.length; i++) {
                var z = zlevelList[i];
                cb.call(context, this._layers[z], z);
            }
        };
        CanvasPainter.prototype.eachBuiltinLayer = function (cb, context) {
            var zlevelList = this._zlevelList;
            for (var i = 0; i < zlevelList.length; i++) {
                var z = zlevelList[i];
                var layer = this._layers[z];
                if (layer.__builtin__) {
                    cb.call(context, layer, z);
                }
            }
        };
        CanvasPainter.prototype.eachOtherLayer = function (cb, context) {
            var zlevelList = this._zlevelList;
            for (var i = 0; i < zlevelList.length; i++) {
                var z = zlevelList[i];
                var layer = this._layers[z];
                if (!layer.__builtin__) {
                    cb.call(context, layer, z);
                }
            }
        };
        CanvasPainter.prototype.getLayers = function () {
            return this._layers;
        };
        CanvasPainter.prototype._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 = 1; i_1 < list.length; i_1++) {
                    var el = list[i_1];
                    if (el.zlevel !== list[i_1 - 1].zlevel || el.incremental) {
                        this._needsManuallyCompositing = true;
                        break;
                    }
                }
            }
            var prevLayer = null;
            var incrementalLayerCount = 0;
            var prevZlevel;
            var i;
            for (i = 0; i < list.length; i++) {
                var el = list[i];
                var zlevel = el.zlevel;
                var layer = void 0;
                if (prevZlevel !== zlevel) {
                    prevZlevel = zlevel;
                    incrementalLayerCount = 0;
                }
                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('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 {
                        layer.__drawIndex = -1;
                    }
                    updatePrevLayer(i);
                    prevLayer = layer;
                }
                if ((el.__dirty & REDRAW_BIT) && !el.__inHover) {
                    layer.__dirty = true;
                    if (layer.incremental && layer.__drawIndex < 0) {
                        layer.__drawIndex = i;
                    }
                }
            }
            updatePrevLayer(i);
            this.eachBuiltinLayer(function (layer, z) {
                if (!layer.__used && layer.getElementCount() > 0) {
                    layer.__dirty = true;
                    layer.__startIndex = layer.__endIndex = layer.__drawIndex = 0;
                }
                if (layer.__dirty && layer.__drawIndex < 0) {
                    layer.__drawIndex = layer.__startIndex;
                }
            });
        };
        CanvasPainter.prototype.clear = function () {
            this.eachBuiltinLayer(this._clearLayer);
            return this;
        };
        CanvasPainter.prototype._clearLayer = function (layer) {
            layer.clear();
        };
        CanvasPainter.prototype.setBackgroundColor = function (backgroundColor) {
            this._backgroundColor = backgroundColor;
            each(this._layers, function (layer) {
                layer.setUnpainted();
            });
        };
        CanvasPainter.prototype.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];
                    if (_zlevel === zlevel || _zlevel === zlevel + EL_AFTER_INCREMENTAL_INC) {
                        var layer = this._layers[_zlevel];
                        merge(layer, layerConfig[zlevel], true);
                    }
                }
            }
        };
        CanvasPainter.prototype.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);
        };
        CanvasPainter.prototype.resize = function (width, height) {
            if (!this._domRoot.style) {
                if (width == null || height == null) {
                    return;
                }
                this._width = width;
                this._height = height;
                this.getLayer(CANVAS_ZLEVEL).resize(width, height);
            }
            else {
                var domRoot = this._domRoot;
                domRoot.style.display = 'none';
                var opts = this._opts;
                var root = this.root;
                width != null && (opts.width = width);
                height != null && (opts.height = height);
                width = getSize(root, 0, opts);
                height = getSize(root, 1, opts);
                domRoot.style.display = '';
                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);
                        }
                    }
                    this.refresh(true);
                }
                this._width = width;
                this._height = height;
            }
            return this;
        };
        CanvasPainter.prototype.clearLayer = function (zlevel) {
            var layer = this._layers[zlevel];
            if (layer) {
                layer.clear();
            }
        };
        CanvasPainter.prototype.dispose = function () {
            this.root.innerHTML = '';
            this.root =
                this.storage =
                    this._domRoot =
                        this._layers = null;
        };
        CanvasPainter.prototype.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);
            var ctx = imageLayer.ctx;
            if (opts.pixelRatio <= this.dpr) {
                this.refresh();
                var width_1 = imageLayer.dom.width;
                var height_1 = imageLayer.dom.height;
                this.eachLayer(function (layer) {
                    if (layer.__builtin__) {
                        ctx.drawImage(layer.dom, 0, 0, width_1, height_1);
                    }
                    else if (layer.renderToCanvas) {
                        ctx.save();
                        layer.renderToCanvas(ctx);
                        ctx.restore();
                    }
                });
            }
            else {
                var scope = {
                    inHover: false,
                    viewWidth: this._width,
                    viewHeight: this._height
                };
                var displayList = this.storage.getDisplayList(true);
                for (var i = 0, len = displayList.length; i < len; i++) {
                    var el = displayList[i];
                    brush(ctx, el, scope, i === len - 1);
                }
            }
            return imageLayer.dom;
        };
        CanvasPainter.prototype.getWidth = function () {
            return this._width;
        };
        CanvasPainter.prototype.getHeight = function () {
            return this._height;
        };
        return CanvasPainter;
    }());

    function install$1(registers) {
      registers.registerPainter('canvas', CanvasPainter);
    }

    var LineSeriesModel =
    /** @class */
    function (_super) {
      __extends(LineSeriesModel, _super);

      function LineSeriesModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = LineSeriesModel.type;
        _this.hasSymbolVisual = true;
        return _this;
      }

      LineSeriesModel.prototype.getInitialData = function (option) {
        if ("development" !== 'production') {
          var coordSys = option.coordinateSystem;

          if (coordSys !== 'polar' && coordSys !== 'cartesian2d') {
            throw new Error('Line not support coordinateSystem besides cartesian and polar');
          }
        }

        return createSeriesData(null, this, {
          useEncodeDefaulter: true
        });
      };

      LineSeriesModel.prototype.getLegendIcon = function (opt) {
        var group = new Group();
        var line = createSymbol('line', 0, opt.itemHeight / 2, opt.itemWidth, 0, opt.lineStyle.stroke, false);
        group.add(line);
        line.setStyle(opt.lineStyle);
        var visualType = this.getData().getVisual('symbol');
        var visualRotate = this.getData().getVisual('symbolRotate');
        var symbolType = visualType === 'none' ? 'circle' : visualType; // Symbol size is 80% when there is a line

        var size = opt.itemHeight * 0.8;
        var symbol = createSymbol(symbolType, (opt.itemWidth - size) / 2, (opt.itemHeight - size) / 2, size, size, opt.itemStyle.fill);
        group.add(symbol);
        symbol.setStyle(opt.itemStyle);
        var symbolRotate = opt.iconRotate === 'inherit' ? visualRotate : opt.iconRotate || 0;
        symbol.rotation = symbolRotate * Math.PI / 180;
        symbol.setOrigin([opt.itemWidth / 2, opt.itemHeight / 2]);

        if (symbolType.indexOf('empty') > -1) {
          symbol.style.stroke = symbol.style.fill;
          symbol.style.fill = '#fff';
          symbol.style.lineWidth = 2;
        }

        return group;
      };

      LineSeriesModel.type = 'series.line';
      LineSeriesModel.dependencies = ['grid', 'polar'];
      LineSeriesModel.defaultOption = {
        // zlevel: 0,
        z: 3,
        coordinateSystem: 'cartesian2d',
        legendHoverLink: true,
        clip: true,
        label: {
          position: 'top'
        },
        // itemStyle: {
        // },
        endLabel: {
          show: false,
          valueAnimation: true,
          distance: 8
        },
        lineStyle: {
          width: 2,
          type: 'solid'
        },
        emphasis: {
          scale: true
        },
        // 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', 'lttb'.
        sampling: 'none',
        animationEasing: 'linear',
        // Disable progressive
        progressive: 0,
        hoverLayerThreshold: Infinity,
        universalTransition: {
          divideShape: 'clone'
        },
        triggerLineEvent: false
      };
      return LineSeriesModel;
    }(SeriesModel);

    /**
     * @return label string. Not null/undefined
     */

    function getDefaultLabel(data, dataIndex) {
      var labelDims = data.mapDimensionsAll('defaultedLabel');
      var len = labelDims.length; // Simple optimization (in lots of cases, label dims length is 1)

      if (len === 1) {
        var rawVal = retrieveRawValue(data, dataIndex, labelDims[0]);
        return rawVal != null ? rawVal + '' : null;
      } else if (len) {
        var vals = [];

        for (var i = 0; i < labelDims.length; i++) {
          vals.push(retrieveRawValue(data, dataIndex, labelDims[i]));
        }

        return vals.join(' ');
      }
    }
    function getDefaultInterpolatedLabel(data, interpolatedValue) {
      var labelDims = data.mapDimensionsAll('defaultedLabel');

      if (!isArray(interpolatedValue)) {
        return interpolatedValue + '';
      }

      var vals = [];

      for (var i = 0; i < labelDims.length; i++) {
        var dimIndex = data.getDimensionIndex(labelDims[i]);

        if (dimIndex >= 0) {
          vals.push(interpolatedValue[dimIndex]);
        }
      }

      return vals.join(' ');
    }

    var Symbol =
    /** @class */
    function (_super) {
      __extends(Symbol, _super);

      function Symbol(data, idx, seriesScope, opts) {
        var _this = _super.call(this) || this;

        _this.updateData(data, idx, seriesScope, opts);

        return _this;
      }

      Symbol.prototype._createSymbol = function (symbolType, data, idx, symbolSize, keepAspect) {
        // Remove paths created before
        this.removeAll(); // let 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, null, keepAspect);
        symbolPath.attr({
          z2: 100,
          culling: true,
          scaleX: symbolSize[0] / 2,
          scaleY: symbolSize[1] / 2
        }); // Rewrite drift method

        symbolPath.drift = driftSymbol;
        this._symbolType = symbolType;
        this.add(symbolPath);
      };
      /**
       * Stop animation
       * @param {boolean} toLastFrame
       */


      Symbol.prototype.stopSymbolAnimation = function (toLastFrame) {
        this.childAt(0).stopAnimation(null, toLastFrame);
      };

      Symbol.prototype.getSymbolType = function () {
        return this._symbolType;
      };
      /**
       * 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.
       */


      Symbol.prototype.getSymbolPath = function () {
        return this.childAt(0);
      };
      /**
       * Highlight symbol
       */


      Symbol.prototype.highlight = function () {
        enterEmphasis(this.childAt(0));
      };
      /**
       * Downplay symbol
       */


      Symbol.prototype.downplay = function () {
        leaveEmphasis(this.childAt(0));
      };
      /**
       * @param {number} zlevel
       * @param {number} z
       */


      Symbol.prototype.setZ = function (zlevel, z) {
        var symbolPath = this.childAt(0);
        symbolPath.zlevel = zlevel;
        symbolPath.z = z;
      };

      Symbol.prototype.setDraggable = function (draggable, hasCursorOption) {
        var symbolPath = this.childAt(0);
        symbolPath.draggable = draggable;
        symbolPath.cursor = !hasCursorOption && draggable ? 'move' : symbolPath.cursor;
      };
      /**
       * Update symbol properties
       */


      Symbol.prototype.updateData = function (data, idx, seriesScope, opts) {
        this.silent = false;
        var symbolType = data.getItemVisual(idx, 'symbol') || 'circle';
        var seriesModel = data.hostModel;
        var symbolSize = Symbol.getSymbolSize(data, idx);
        var isInit = symbolType !== this._symbolType;
        var disableAnimation = opts && opts.disableAnimation;

        if (isInit) {
          var keepAspect = data.getItemVisual(idx, 'symbolKeepAspect');

          this._createSymbol(symbolType, data, idx, symbolSize, keepAspect);
        } else {
          var symbolPath = this.childAt(0);
          symbolPath.silent = false;
          var target = {
            scaleX: symbolSize[0] / 2,
            scaleY: symbolSize[1] / 2
          };
          disableAnimation ? symbolPath.attr(target) : updateProps(symbolPath, target, seriesModel, idx);
          saveOldStyle(symbolPath);
        }

        this._updateCommon(data, idx, symbolSize, seriesScope, opts);

        if (isInit) {
          var symbolPath = this.childAt(0);

          if (!disableAnimation) {
            var target = {
              scaleX: this._sizeX,
              scaleY: this._sizeY,
              style: {
                // Always fadeIn. Because it has fadeOut animation when symbol is removed..
                opacity: symbolPath.style.opacity
              }
            };
            symbolPath.scaleX = symbolPath.scaleY = 0;
            symbolPath.style.opacity = 0;
            initProps(symbolPath, target, seriesModel, idx);
          }
        }

        if (disableAnimation) {
          // Must stop leave transition manually if don't call initProps or updateProps.
          this.childAt(0).stopAnimation('leave');
        }
      };

      Symbol.prototype._updateCommon = function (data, idx, symbolSize, seriesScope, opts) {
        var symbolPath = this.childAt(0);
        var seriesModel = data.hostModel;
        var emphasisItemStyle;
        var blurItemStyle;
        var selectItemStyle;
        var focus;
        var blurScope;
        var emphasisDisabled;
        var labelStatesModels;
        var hoverScale;
        var cursorStyle;

        if (seriesScope) {
          emphasisItemStyle = seriesScope.emphasisItemStyle;
          blurItemStyle = seriesScope.blurItemStyle;
          selectItemStyle = seriesScope.selectItemStyle;
          focus = seriesScope.focus;
          blurScope = seriesScope.blurScope;
          labelStatesModels = seriesScope.labelStatesModels;
          hoverScale = seriesScope.hoverScale;
          cursorStyle = seriesScope.cursorStyle;
          emphasisDisabled = seriesScope.emphasisDisabled;
        }

        if (!seriesScope || data.hasItemOption) {
          var itemModel = seriesScope && seriesScope.itemModel ? seriesScope.itemModel : data.getItemModel(idx);
          var emphasisModel = itemModel.getModel('emphasis');
          emphasisItemStyle = emphasisModel.getModel('itemStyle').getItemStyle();
          selectItemStyle = itemModel.getModel(['select', 'itemStyle']).getItemStyle();
          blurItemStyle = itemModel.getModel(['blur', 'itemStyle']).getItemStyle();
          focus = emphasisModel.get('focus');
          blurScope = emphasisModel.get('blurScope');
          emphasisDisabled = emphasisModel.get('disabled');
          labelStatesModels = getLabelStatesModels(itemModel);
          hoverScale = emphasisModel.getShallow('scale');
          cursorStyle = itemModel.getShallow('cursor');
        }

        var symbolRotate = data.getItemVisual(idx, 'symbolRotate');
        symbolPath.attr('rotation', (symbolRotate || 0) * Math.PI / 180 || 0);
        var symbolOffset = normalizeSymbolOffset(data.getItemVisual(idx, 'symbolOffset'), symbolSize);

        if (symbolOffset) {
          symbolPath.x = symbolOffset[0];
          symbolPath.y = symbolOffset[1];
        }

        cursorStyle && symbolPath.attr('cursor', cursorStyle);
        var symbolStyle = data.getItemVisual(idx, 'style');
        var visualColor = symbolStyle.fill;

        if (symbolPath instanceof ZRImage) {
          var pathStyle = symbolPath.style;
          symbolPath.useStyle(extend({
            // TODO other properties like x, y ?
            image: pathStyle.image,
            x: pathStyle.x,
            y: pathStyle.y,
            width: pathStyle.width,
            height: pathStyle.height
          }, symbolStyle));
        } else {
          if (symbolPath.__isEmptyBrush) {
            // fill and stroke will be swapped if it's empty.
            // So we cloned a new style to avoid it affecting the original style in visual storage.
            // TODO Better implementation. No empty logic!
            symbolPath.useStyle(extend({}, symbolStyle));
          } else {
            symbolPath.useStyle(symbolStyle);
          } // Disable decal because symbol scale will been applied on the decal.


          symbolPath.style.decal = null;
          symbolPath.setColor(visualColor, opts && opts.symbolInnerColor);
          symbolPath.style.strokeNoScale = true;
        }

        var liftZ = data.getItemVisual(idx, 'liftZ');
        var z2Origin = this._z2;

        if (liftZ != null) {
          if (z2Origin == null) {
            this._z2 = symbolPath.z2;
            symbolPath.z2 += liftZ;
          }
        } else if (z2Origin != null) {
          symbolPath.z2 = z2Origin;
          this._z2 = null;
        }

        var useNameLabel = opts && opts.useNameLabel;
        setLabelStyle(symbolPath, labelStatesModels, {
          labelFetcher: seriesModel,
          labelDataIndex: idx,
          defaultText: getLabelDefaultText,
          inheritColor: visualColor,
          defaultOpacity: symbolStyle.opacity
        }); // Do not execute util needed.

        function getLabelDefaultText(idx) {
          return useNameLabel ? data.getName(idx) : getDefaultLabel(data, idx);
        }

        this._sizeX = symbolSize[0] / 2;
        this._sizeY = symbolSize[1] / 2;
        var emphasisState = symbolPath.ensureState('emphasis');
        emphasisState.style = emphasisItemStyle;
        symbolPath.ensureState('select').style = selectItemStyle;
        symbolPath.ensureState('blur').style = blurItemStyle; // null / undefined / true means to use default strategy.
        // 0 / false / negative number / NaN / Infinity means no scale.

        var scaleRatio = hoverScale == null || hoverScale === true ? Math.max(1.1, 3 / this._sizeY) // PENDING: restrict hoverScale > 1? It seems unreasonable to scale down
        : isFinite(hoverScale) && hoverScale > 0 ? +hoverScale : 1; // always set scale to allow resetting

        emphasisState.scaleX = this._sizeX * scaleRatio;
        emphasisState.scaleY = this._sizeY * scaleRatio;
        this.setSymbolScale(1);
        toggleHoverEmphasis(this, focus, blurScope, emphasisDisabled);
      };

      Symbol.prototype.setSymbolScale = function (scale) {
        this.scaleX = this.scaleY = scale;
      };

      Symbol.prototype.fadeOut = function (cb, seriesModel, opt) {
        var symbolPath = this.childAt(0);
        var dataIndex = getECData(this).dataIndex;
        var animationOpt = opt && opt.animation; // Avoid mistaken hover when fading out

        this.silent = symbolPath.silent = true; // Not show text when animating

        if (opt && opt.fadeLabel) {
          var textContent = symbolPath.getTextContent();

          if (textContent) {
            removeElement(textContent, {
              style: {
                opacity: 0
              }
            }, seriesModel, {
              dataIndex: dataIndex,
              removeOpt: animationOpt,
              cb: function () {
                symbolPath.removeTextContent();
              }
            });
          }
        } else {
          symbolPath.removeTextContent();
        }

        removeElement(symbolPath, {
          style: {
            opacity: 0
          },
          scaleX: 0,
          scaleY: 0
        }, seriesModel, {
          dataIndex: dataIndex,
          cb: cb,
          removeOpt: animationOpt
        });
      };

      Symbol.getSymbolSize = function (data, idx) {
        return normalizeSymbolSize(data.getItemVisual(idx, 'symbolSize'));
      };

      return Symbol;
    }(Group);

    function driftSymbol(dx, dy) {
      this.parent.drift(dx, dy);
    }

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

    function normalizeUpdateOpt(opt) {
      if (opt != null && !isObject(opt)) {
        opt = {
          isIgnore: opt
        };
      }

      return opt || {};
    }

    function makeSeriesScope(data) {
      var seriesModel = data.hostModel;
      var emphasisModel = seriesModel.getModel('emphasis');
      return {
        emphasisItemStyle: emphasisModel.getModel('itemStyle').getItemStyle(),
        blurItemStyle: seriesModel.getModel(['blur', 'itemStyle']).getItemStyle(),
        selectItemStyle: seriesModel.getModel(['select', 'itemStyle']).getItemStyle(),
        focus: emphasisModel.get('focus'),
        blurScope: emphasisModel.get('blurScope'),
        emphasisDisabled: emphasisModel.get('disabled'),
        hoverScale: emphasisModel.get('scale'),
        labelStatesModels: getLabelStatesModels(seriesModel),
        cursorStyle: seriesModel.get('cursor')
      };
    }

    var SymbolDraw =
    /** @class */
    function () {
      function SymbolDraw(SymbolCtor) {
        this.group = new Group();
        this._SymbolCtor = SymbolCtor || Symbol;
      }
      /**
       * Update symbols draw by new data
       */


      SymbolDraw.prototype.updateData = function (data, opt) {
        // Remove progressive els.
        this._progressiveEls = null;
        opt = normalizeUpdateOpt(opt);
        var group = this.group;
        var seriesModel = data.hostModel;
        var oldData = this._data;
        var SymbolCtor = this._SymbolCtor;
        var disableAnimation = opt.disableAnimation;
        var seriesScope = makeSeriesScope(data);
        var symbolUpdateOpt = {
          disableAnimation: disableAnimation
        };

        var getSymbolPoint = opt.getSymbolPoint || function (idx) {
          return data.getItemLayout(idx);
        }; // 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 = getSymbolPoint(newIdx);

          if (symbolNeedsDraw(data, point, newIdx, opt)) {
            var symbolEl = new SymbolCtor(data, newIdx, seriesScope, symbolUpdateOpt);
            symbolEl.setPosition(point);
            data.setItemGraphicEl(newIdx, symbolEl);
            group.add(symbolEl);
          }
        }).update(function (newIdx, oldIdx) {
          var symbolEl = oldData.getItemGraphicEl(oldIdx);
          var point = getSymbolPoint(newIdx);

          if (!symbolNeedsDraw(data, point, newIdx, opt)) {
            group.remove(symbolEl);
            return;
          }

          var newSymbolType = data.getItemVisual(newIdx, 'symbol') || 'circle';
          var oldSymbolType = symbolEl && symbolEl.getSymbolType && symbolEl.getSymbolType();

          if (!symbolEl // Create a new if symbol type changed.
          || oldSymbolType && oldSymbolType !== newSymbolType) {
            group.remove(symbolEl);
            symbolEl = new SymbolCtor(data, newIdx, seriesScope, symbolUpdateOpt);
            symbolEl.setPosition(point);
          } else {
            symbolEl.updateData(data, newIdx, seriesScope, symbolUpdateOpt);
            var target = {
              x: point[0],
              y: point[1]
            };
            disableAnimation ? symbolEl.attr(target) : updateProps(symbolEl, target, 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);
          }, seriesModel);
        }).execute();
        this._getSymbolPoint = getSymbolPoint;
        this._data = data;
      };

      SymbolDraw.prototype.updateLayout = function () {
        var _this = this;

        var data = this._data;

        if (data) {
          // Not use animation
          data.eachItemGraphicEl(function (el, idx) {
            var point = _this._getSymbolPoint(idx);

            el.setPosition(point);
            el.markRedraw();
          });
        }
      };

      SymbolDraw.prototype.incrementalPrepareUpdate = function (data) {
        this._seriesScope = makeSeriesScope(data);
        this._data = null;
        this.group.removeAll();
      };
      /**
       * Update symbols draw by new data
       */

      SymbolDraw.prototype.incrementalUpdate = function (taskParams, data, opt) {
        // Clear
        this._progressiveEls = [];
        opt = normalizeUpdateOpt(opt);

        function updateIncrementalAndHover(el) {
          if (!el.isGroup) {
            el.incremental = true;
            el.ensureState('emphasis').hoverLayer = 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.setPosition(point);
            this.group.add(el);
            data.setItemGraphicEl(idx, el);

            this._progressiveEls.push(el);
          }
        }
      };

      SymbolDraw.prototype.eachRendered = function (cb) {
        traverseElements(this._progressiveEls || this.group, cb);
      };

      SymbolDraw.prototype.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);
            }, data.hostModel);
          });
        } else {
          group.removeAll();
        }
      };
      return SymbolDraw;
    }();

    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 = false;
      var stackResultDim = data.getCalculationInfo('stackResultDimension');

      if (isDimensionStacked(data, dims[0]
      /* , dims[1] */
      )) {
        // jshint ignore:line
        stacked = true;
        dims[0] = stackResultDim;
      }

      if (isDimensionStacked(data, dims[1]
      /* , dims[0] */
      )) {
        // jshint ignore:line
        stacked = true;
        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];
      } // If origin is specified as a number, use it as
      // valueStart directly
      else if (isNumber(valueOrigin) && !isNaN(valueOrigin)) {
          valueStart = valueOrigin;
        } // 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);
    }

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

    function lineAnimationDiff(oldData, newData, oldStackedOnPoints, newStackedOnPoints, oldCoordSys, newCoordSys, oldValueOrigin, newValueOrigin) {
      var diff = diffData(oldData, newData); // let newIdList = newData.mapArray(newData.getId);
      // let 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); // const oldDataNewCoordInfo = prepareDataCoordInfo(newCoordSys, oldData, newValueOrigin);

      var oldPoints = oldData.getLayout('points') || [];
      var newPoints = newData.getLayout('points') || [];

      for (var i = 0; i < diff.length; i++) {
        var diffItem = diff[i];
        var pointAdded = true;
        var oldIdx2 = void 0;
        var newIdx2 = void 0; // 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 '=':
            oldIdx2 = diffItem.idx * 2;
            newIdx2 = diffItem.idx1 * 2;
            var currentX = oldPoints[oldIdx2];
            var currentY = oldPoints[oldIdx2 + 1];
            var nextX = newPoints[newIdx2];
            var nextY = newPoints[newIdx2 + 1]; // If previous data is NaN, use next point directly

            if (isNaN(currentX) || isNaN(currentY)) {
              currentX = nextX;
              currentY = nextY;
            }

            currPoints.push(currentX, currentY);
            nextPoints.push(nextX, nextY);
            currStackedPoints.push(oldStackedOnPoints[oldIdx2], oldStackedOnPoints[oldIdx2 + 1]);
            nextStackedPoints.push(newStackedOnPoints[newIdx2], newStackedOnPoints[newIdx2 + 1]);
            rawIndices.push(newData.getRawIndex(diffItem.idx1));
            break;

          case '+':
            var newIdx = diffItem.idx;
            var newDataDimsForPoint = newDataOldCoordInfo.dataDimsForPoint;
            var oldPt = oldCoordSys.dataToPoint([newData.get(newDataDimsForPoint[0], newIdx), newData.get(newDataDimsForPoint[1], newIdx)]);
            newIdx2 = newIdx * 2;
            currPoints.push(oldPt[0], oldPt[1]);
            nextPoints.push(newPoints[newIdx2], newPoints[newIdx2 + 1]);
            var stackedOnPoint = getStackedOnPoint(newDataOldCoordInfo, oldCoordSys, newData, newIdx);
            currStackedPoints.push(stackedOnPoint[0], stackedOnPoint[1]);
            nextStackedPoints.push(newStackedOnPoints[newIdx2], newStackedOnPoints[newIdx2 + 1]);
            rawIndices.push(newData.getRawIndex(newIdx));
            break;

          case '-':
            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 len = currPoints.length;
      var sortedCurrPoints = createFloat32Array(len);
      var sortedNextPoints = createFloat32Array(len);
      var sortedCurrStackedPoints = createFloat32Array(len);
      var sortedNextStackedPoints = createFloat32Array(len);
      var sortedStatus = [];

      for (var i = 0; i < sortedIndices.length; i++) {
        var idx = sortedIndices[i];
        var i2 = i * 2;
        var idx2 = idx * 2;
        sortedCurrPoints[i2] = currPoints[idx2];
        sortedCurrPoints[i2 + 1] = currPoints[idx2 + 1];
        sortedNextPoints[i2] = nextPoints[idx2];
        sortedNextPoints[i2 + 1] = nextPoints[idx2 + 1];
        sortedCurrStackedPoints[i2] = currStackedPoints[idx2];
        sortedCurrStackedPoints[i2 + 1] = currStackedPoints[idx2 + 1];
        sortedNextStackedPoints[i2] = nextStackedPoints[idx2];
        sortedNextStackedPoints[i2 + 1] = nextStackedPoints[idx2 + 1];
        sortedStatus[i] = status[idx];
      }

      return {
        current: sortedCurrPoints,
        next: sortedNextPoints,
        stackedOnCurrent: sortedCurrStackedPoints,
        stackedOnNext: sortedNextStackedPoints,
        status: sortedStatus
      };
    }

    var mathMin$5 = Math.min;
    var mathMax$5 = Math.max;

    function isPointNull(x, y) {
      return isNaN(x) || isNaN(y);
    }
    /**
     * 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 drawSegment(ctx, points, start, segLen, allLen, dir, smooth, smoothMonotone, connectNulls) {
      var prevX;
      var prevY;
      var cpx0;
      var cpy0;
      var cpx1;
      var cpy1;
      var idx = start;
      var k = 0;

      for (; k < segLen; k++) {
        var x = points[idx * 2];
        var y = points[idx * 2 + 1];

        if (idx >= allLen || idx < 0) {
          break;
        }

        if (isPointNull(x, y)) {
          if (connectNulls) {
            idx += dir;
            continue;
          }

          break;
        }

        if (idx === start) {
          ctx[dir > 0 ? 'moveTo' : 'lineTo'](x, y);
          cpx0 = x;
          cpy0 = y;
        } else {
          var dx = x - prevX;
          var dy = y - prevY; // Ignore tiny segment.

          if (dx * dx + dy * dy < 0.5) {
            idx += dir;
            continue;
          }

          if (smooth > 0) {
            var nextIdx = idx + dir;
            var nextX = points[nextIdx * 2];
            var nextY = points[nextIdx * 2 + 1]; // Ignore duplicate point

            while (nextX === x && nextY === y && k < segLen) {
              k++;
              nextIdx += dir;
              idx += dir;
              nextX = points[nextIdx * 2];
              nextY = points[nextIdx * 2 + 1];
              x = points[idx * 2];
              y = points[idx * 2 + 1];
              dx = x - prevX;
              dy = y - prevY;
            }

            var tmpK = k + 1;

            if (connectNulls) {
              // Find next point not null
              while (isPointNull(nextX, nextY) && tmpK < segLen) {
                tmpK++;
                nextIdx += dir;
                nextX = points[nextIdx * 2];
                nextY = points[nextIdx * 2 + 1];
              }
            }

            var ratioNextSeg = 0.5;
            var vx = 0;
            var vy = 0;
            var nextCpx0 = void 0;
            var nextCpy0 = void 0; // Is last point

            if (tmpK >= segLen || isPointNull(nextX, nextY)) {
              cpx1 = x;
              cpy1 = y;
            } else {
              vx = nextX - prevX;
              vy = nextY - prevY;
              var dx0 = x - prevX;
              var dx1 = nextX - x;
              var dy0 = y - prevY;
              var dy1 = nextY - y;
              var lenPrevSeg = void 0;
              var lenNextSeg = void 0;

              if (smoothMonotone === 'x') {
                lenPrevSeg = Math.abs(dx0);
                lenNextSeg = Math.abs(dx1);
                var dir_1 = vx > 0 ? 1 : -1;
                cpx1 = x - dir_1 * lenPrevSeg * smooth;
                cpy1 = y;
                nextCpx0 = x + dir_1 * lenNextSeg * smooth;
                nextCpy0 = y;
              } else if (smoothMonotone === 'y') {
                lenPrevSeg = Math.abs(dy0);
                lenNextSeg = Math.abs(dy1);
                var dir_2 = vy > 0 ? 1 : -1;
                cpx1 = x;
                cpy1 = y - dir_2 * lenPrevSeg * smooth;
                nextCpx0 = x;
                nextCpy0 = y + dir_2 * lenNextSeg * smooth;
              } else {
                lenPrevSeg = Math.sqrt(dx0 * dx0 + dy0 * dy0);
                lenNextSeg = Math.sqrt(dx1 * dx1 + dy1 * dy1); // Use ratio of seg length

                ratioNextSeg = lenNextSeg / (lenNextSeg + lenPrevSeg);
                cpx1 = x - vx * smooth * (1 - ratioNextSeg);
                cpy1 = y - vy * smooth * (1 - ratioNextSeg); // cp0 of next segment

                nextCpx0 = x + vx * smooth * ratioNextSeg;
                nextCpy0 = y + vy * smooth * ratioNextSeg; // Smooth constraint between point and next point.
                // Avoid exceeding extreme after smoothing.

                nextCpx0 = mathMin$5(nextCpx0, mathMax$5(nextX, x));
                nextCpy0 = mathMin$5(nextCpy0, mathMax$5(nextY, y));
                nextCpx0 = mathMax$5(nextCpx0, mathMin$5(nextX, x));
                nextCpy0 = mathMax$5(nextCpy0, mathMin$5(nextY, y)); // Reclaculate cp1 based on the adjusted cp0 of next seg.

                vx = nextCpx0 - x;
                vy = nextCpy0 - y;
                cpx1 = x - vx * lenPrevSeg / lenNextSeg;
                cpy1 = y - vy * lenPrevSeg / lenNextSeg; // Smooth constraint between point and prev point.
                // Avoid exceeding extreme after smoothing.

                cpx1 = mathMin$5(cpx1, mathMax$5(prevX, x));
                cpy1 = mathMin$5(cpy1, mathMax$5(prevY, y));
                cpx1 = mathMax$5(cpx1, mathMin$5(prevX, x));
                cpy1 = mathMax$5(cpy1, mathMin$5(prevY, y)); // Adjust next cp0 again.

                vx = x - cpx1;
                vy = y - cpy1;
                nextCpx0 = x + vx * lenNextSeg / lenPrevSeg;
                nextCpy0 = y + vy * lenNextSeg / lenPrevSeg;
              }
            }

            ctx.bezierCurveTo(cpx0, cpy0, cpx1, cpy1, x, y);
            cpx0 = nextCpx0;
            cpy0 = nextCpy0;
          } else {
            ctx.lineTo(x, y);
          }
        }

        prevX = x;
        prevY = y;
        idx += dir;
      }

      return k;
    }

    var ECPolylineShape =
    /** @class */
    function () {
      function ECPolylineShape() {
        this.smooth = 0;
        this.smoothConstraint = true;
      }

      return ECPolylineShape;
    }();

    var ECPolyline =
    /** @class */
    function (_super) {
      __extends(ECPolyline, _super);

      function ECPolyline(opts) {
        var _this = _super.call(this, opts) || this;

        _this.type = 'ec-polyline';
        return _this;
      }

      ECPolyline.prototype.getDefaultStyle = function () {
        return {
          stroke: '#000',
          fill: null
        };
      };

      ECPolyline.prototype.getDefaultShape = function () {
        return new ECPolylineShape();
      };

      ECPolyline.prototype.buildPath = function (ctx, shape) {
        var points = shape.points;
        var i = 0;
        var len = points.length / 2; // const result = getBoundingBox(points, shape.smoothConstraint);

        if (shape.connectNulls) {
          // Must remove first and last null values avoid draw error in polygon
          for (; len > 0; len--) {
            if (!isPointNull(points[len * 2 - 2], points[len * 2 - 1])) {
              break;
            }
          }

          for (; i < len; i++) {
            if (!isPointNull(points[i * 2], points[i * 2 + 1])) {
              break;
            }
          }
        }

        while (i < len) {
          i += drawSegment(ctx, points, i, len, len, 1, shape.smooth, shape.smoothMonotone, shape.connectNulls) + 1;
        }
      };

      ECPolyline.prototype.getPointOn = function (xOrY, dim) {
        if (!this.path) {
          this.createPathProxy();
          this.buildPath(this.path, this.shape);
        }

        var path = this.path;
        var data = path.data;
        var CMD = PathProxy.CMD;
        var x0;
        var y0;
        var isDimX = dim === 'x';
        var roots = [];

        for (var i = 0; i < data.length;) {
          var cmd = data[i++];
          var x = void 0;
          var y = void 0;
          var x2 = void 0;
          var y2 = void 0;
          var x3 = void 0;
          var y3 = void 0;
          var t = void 0;

          switch (cmd) {
            case CMD.M:
              x0 = data[i++];
              y0 = data[i++];
              break;

            case CMD.L:
              x = data[i++];
              y = data[i++];
              t = isDimX ? (xOrY - x0) / (x - x0) : (xOrY - y0) / (y - y0);

              if (t <= 1 && t >= 0) {
                var val = isDimX ? (y - y0) * t + y0 : (x - x0) * t + x0;
                return isDimX ? [xOrY, val] : [val, xOrY];
              }

              x0 = x;
              y0 = y;
              break;

            case CMD.C:
              x = data[i++];
              y = data[i++];
              x2 = data[i++];
              y2 = data[i++];
              x3 = data[i++];
              y3 = data[i++];
              var nRoot = isDimX ? cubicRootAt(x0, x, x2, x3, xOrY, roots) : cubicRootAt(y0, y, y2, y3, xOrY, roots);

              if (nRoot > 0) {
                for (var i_1 = 0; i_1 < nRoot; i_1++) {
                  var t_1 = roots[i_1];

                  if (t_1 <= 1 && t_1 >= 0) {
                    var val = isDimX ? cubicAt(y0, y, y2, y3, t_1) : cubicAt(x0, x, x2, x3, t_1);
                    return isDimX ? [xOrY, val] : [val, xOrY];
                  }
                }
              }

              x0 = x3;
              y0 = y3;
              break;
          }
        }
      };

      return ECPolyline;
    }(Path);

    var ECPolygonShape =
    /** @class */
    function (_super) {
      __extends(ECPolygonShape, _super);

      function ECPolygonShape() {
        return _super !== null && _super.apply(this, arguments) || this;
      }

      return ECPolygonShape;
    }(ECPolylineShape);

    var ECPolygon =
    /** @class */
    function (_super) {
      __extends(ECPolygon, _super);

      function ECPolygon(opts) {
        var _this = _super.call(this, opts) || this;

        _this.type = 'ec-polygon';
        return _this;
      }

      ECPolygon.prototype.getDefaultShape = function () {
        return new ECPolygonShape();
      };

      ECPolygon.prototype.buildPath = function (ctx, shape) {
        var points = shape.points;
        var stackedOnPoints = shape.stackedOnPoints;
        var i = 0;
        var len = points.length / 2;
        var smoothMonotone = shape.smoothMonotone;

        if (shape.connectNulls) {
          // Must remove first and last null values avoid draw error in polygon
          for (; len > 0; len--) {
            if (!isPointNull(points[len * 2 - 2], points[len * 2 - 1])) {
              break;
            }
          }

          for (; i < len; i++) {
            if (!isPointNull(points[i * 2], points[i * 2 + 1])) {
              break;
            }
          }
        }

        while (i < len) {
          var k = drawSegment(ctx, points, i, len, len, 1, shape.smooth, smoothMonotone, shape.connectNulls);
          drawSegment(ctx, stackedOnPoints, i + k - 1, k, len, -1, shape.stackedOnSmooth, smoothMonotone, shape.connectNulls);
          i += k + 1;
          ctx.closePath();
        }
      };

      return ECPolygon;
    }(Path);

    function createGridClipPath(cartesian, hasAnimation, seriesModel, done, during) {
      var rect = cartesian.getArea();
      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) {
        var baseAxis = cartesian.getBaseAxis();
        var isHorizontal = baseAxis.isHorizontal();
        var isAxisInversed = baseAxis.inverse;

        if (isHorizontal) {
          if (isAxisInversed) {
            clipPath.shape.x += width;
          }

          clipPath.shape.width = 0;
        } else {
          if (!isAxisInversed) {
            clipPath.shape.y += height;
          }

          clipPath.shape.height = 0;
        }

        var duringCb = isFunction(during) ? function (percent) {
          during(percent, clipPath);
        } : null;
        initProps(clipPath, {
          shape: {
            width: width,
            height: height,
            x: x,
            y: y
          }
        }, seriesModel, null, done, duringCb);
      }

      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 r0 = round(sectorArea.r0, 1);
      var r = round(sectorArea.r, 1);
      var clipPath = new Sector({
        shape: {
          cx: round(polar.cx, 1),
          cy: round(polar.cy, 1),
          r0: r0,
          r: r,
          startAngle: sectorArea.startAngle,
          endAngle: sectorArea.endAngle,
          clockwise: sectorArea.clockwise
        }
      });

      if (hasAnimation) {
        var isRadial = polar.getBaseAxis().dim === 'angle';

        if (isRadial) {
          clipPath.shape.endAngle = sectorArea.startAngle;
        } else {
          clipPath.shape.r = r0;
        }

        initProps(clipPath, {
          shape: {
            endAngle: sectorArea.endAngle,
            r: r
          }
        }, seriesModel);
      }

      return clipPath;
    }

    function createClipPath(coordSys, hasAnimation, seriesModel, done, during) {
      if (!coordSys) {
        return null;
      } else if (coordSys.type === 'polar') {
        return createPolarClipPath(coordSys, hasAnimation, seriesModel);
      } else if (coordSys.type === 'cartesian2d') {
        return createGridClipPath(coordSys, hasAnimation, seriesModel, done, during);
      }

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


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * 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 isCoordinateSystemType(coordSys, type) {
      return coordSys.type === type;
    }

    function isPointsSame(points1, points2) {
      if (points1.length !== points2.length) {
        return;
      }

      for (var i = 0; i < points1.length; i++) {
        if (points1[i] !== points2[i]) {
          return;
        }
      }

      return true;
    }

    function bboxFromPoints(points) {
      var minX = Infinity;
      var minY = Infinity;
      var maxX = -Infinity;
      var maxY = -Infinity;

      for (var i = 0; i < points.length;) {
        var x = points[i++];
        var y = points[i++];

        if (!isNaN(x)) {
          minX = Math.min(x, minX);
          maxX = Math.max(x, maxX);
        }

        if (!isNaN(y)) {
          minY = Math.min(y, minY);
          maxY = Math.max(y, maxY);
        }
      }

      return [[minX, minY], [maxX, maxY]];
    }

    function getBoundingDiff(points1, points2) {
      var _a = bboxFromPoints(points1),
          min1 = _a[0],
          max1 = _a[1];

      var _b = bboxFromPoints(points2),
          min2 = _b[0],
          max2 = _b[1]; // 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 isNumber(smooth) ? smooth : smooth ? 0.5 : 0;
    }

    function getStackedOnPoints(coordSys, data, dataCoordInfo) {
      if (!dataCoordInfo.valueDim) {
        return [];
      }

      var len = data.count();
      var points = createFloat32Array(len * 2);

      for (var idx = 0; idx < len; idx++) {
        var pt = getStackedOnPoint(dataCoordInfo, coordSys, data, idx);
        points[idx * 2] = pt[0];
        points[idx * 2 + 1] = pt[1];
      }

      return points;
    }

    function turnPointsIntoStep(points, coordSys, stepTurnAt, connectNulls) {
      var baseAxis = coordSys.getBaseAxis();
      var baseIndex = baseAxis.dim === 'x' || baseAxis.dim === 'radius' ? 0 : 1;
      var stepPoints = [];
      var i = 0;
      var stepPt = [];
      var pt = [];
      var nextPt = [];
      var filteredPoints = [];

      if (connectNulls) {
        for (i = 0; i < points.length; i += 2) {
          if (!isNaN(points[i]) && !isNaN(points[i + 1])) {
            filteredPoints.push(points[i], points[i + 1]);
          }
        }

        points = filteredPoints;
      }

      for (i = 0; i < points.length - 2; i += 2) {
        nextPt[0] = points[i + 2];
        nextPt[1] = points[i + 3];
        pt[0] = points[i];
        pt[1] = points[i + 1];
        stepPoints.push(pt[0], pt[1]);

        switch (stepTurnAt) {
          case 'end':
            stepPt[baseIndex] = nextPt[baseIndex];
            stepPt[1 - baseIndex] = pt[1 - baseIndex];
            stepPoints.push(stepPt[0], stepPt[1]);
            break;

          case 'middle':
            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[0], stepPt[1]);
            stepPoints.push(stepPt2[0], stepPt2[1]);
            break;

          default:
            // default is start
            stepPt[baseIndex] = pt[baseIndex];
            stepPt[1 - baseIndex] = nextPt[1 - baseIndex];
            stepPoints.push(stepPt[0], stepPt[1]);
        }
      } // Last points


      stepPoints.push(points[i++], points[i++]);
      return stepPoints;
    }
    /**
     * Clip color stops to edge. Avoid creating too large gradients.
     * Which may lead to blurry when GPU acceleration is enabled. See #15680
     *
     * The stops has been sorted from small to large.
     */


    function clipColorStops(colorStops, maxSize) {
      var newColorStops = [];
      var len = colorStops.length; // coord will always < 0 in prevOutOfRangeColorStop.

      var prevOutOfRangeColorStop;
      var prevInRangeColorStop;

      function lerpStop(stop0, stop1, clippedCoord) {
        var coord0 = stop0.coord;
        var p = (clippedCoord - coord0) / (stop1.coord - coord0);
        var color = lerp$1(p, [stop0.color, stop1.color]);
        return {
          coord: clippedCoord,
          color: color
        };
      }

      for (var i = 0; i < len; i++) {
        var stop_1 = colorStops[i];
        var coord = stop_1.coord;

        if (coord < 0) {
          prevOutOfRangeColorStop = stop_1;
        } else if (coord > maxSize) {
          if (prevInRangeColorStop) {
            newColorStops.push(lerpStop(prevInRangeColorStop, stop_1, maxSize));
          } else if (prevOutOfRangeColorStop) {
            // If there are two stops and coord range is between these two stops
            newColorStops.push(lerpStop(prevOutOfRangeColorStop, stop_1, 0), lerpStop(prevOutOfRangeColorStop, stop_1, maxSize));
          } // All following stop will be out of range. So just ignore them.


          break;
        } else {
          if (prevOutOfRangeColorStop) {
            newColorStops.push(lerpStop(prevOutOfRangeColorStop, stop_1, 0)); // Reset

            prevOutOfRangeColorStop = null;
          }

          newColorStops.push(stop_1);
          prevInRangeColorStop = stop_1;
        }
      }

      return newColorStops;
    }

    function getVisualGradient(data, coordSys, api) {
      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 ("development" !== 'production') {
          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 dimInfo = data.getDimensionInfo(visualMetaList[i].dimension);
        coordDim = dimInfo && dimInfo.coordDim; // Can only be x or y

        if (coordDim === 'x' || coordDim === 'y') {
          visualMeta = visualMetaList[i];
          break;
        }
      }

      if (!visualMeta) {
        if ("development" !== 'production') {
          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); // dataToCoord mapping may not be linear, but must be monotonic.

      var colorStops = map(visualMeta.stops, function (stop) {
        // offset will be calculated later.
        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 colorStopsInRange = clipColorStops(colorStops, coordDim === 'x' ? api.getWidth() : api.getHeight());
      var inRangeStopLen = colorStopsInRange.length;

      if (!inRangeStopLen && stopLen) {
        // All stops are out of range. All will be the same color.
        return colorStops[0].coord < 0 ? outerColors[1] ? outerColors[1] : colorStops[stopLen - 1].color : outerColors[0] ? outerColors[0] : colorStops[0].color;
      }

      var tinyExtent = 10; // Arbitrary value: 10px

      var minCoord = colorStopsInRange[0].coord - tinyExtent;
      var maxCoord = colorStopsInRange[inRangeStopLen - 1].coord + tinyExtent;
      var coordSpan = maxCoord - minCoord;

      if (coordSpan < 1e-3) {
        return 'transparent';
      }

      each(colorStopsInRange, function (stop) {
        stop.offset = (stop.coord - minCoord) / coordSpan;
      });
      colorStopsInRange.push({
        // NOTE: inRangeStopLen may still be 0 if stoplen is zero.
        offset: inRangeStopLen ? colorStopsInRange[inRangeStopLen - 1].offset : 0.5,
        color: outerColors[1] || 'transparent'
      });
      colorStopsInRange.unshift({
        offset: inRangeStopLen ? colorStopsInRange[0].offset : 0.5,
        color: outerColors[0] || 'transparent'
      });
      var gradient = new LinearGradient(0, 0, 0, 0, colorStopsInRange, 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(categoryAxis.getViewLabels(), function (labelItem) {
        var ordinalNumber = categoryAxis.scale.getRawOrdinalNumber(labelItem.tickValue);
        labelMap[ordinalNumber] = 1;
      });
      return function (dataIndex) {
        return !labelMap.hasOwnProperty(data.get(categoryDataDim, dataIndex));
      };
    }

    function canShowAllSymbolForCategory(categoryAxis, data) {
      // In most 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 (Symbol.getSymbolSize(data, dataIndex // Only for cartesian, where `isHorizontal` exists.
        )[categoryAxis.isHorizontal() ? 1 : 0] // Empirical number
        * 1.5 > availSize) {
          return false;
        }
      }

      return true;
    }

    function isPointNull$1(x, y) {
      return isNaN(x) || isNaN(y);
    }

    function getLastIndexNotNull(points) {
      var len = points.length / 2;

      for (; len > 0; len--) {
        if (!isPointNull$1(points[len * 2 - 2], points[len * 2 - 1])) {
          break;
        }
      }

      return len - 1;
    }

    function getPointAtIndex(points, idx) {
      return [points[idx * 2], points[idx * 2 + 1]];
    }

    function getIndexRange(points, xOrY, dim) {
      var len = points.length / 2;
      var dimIdx = dim === 'x' ? 0 : 1;
      var a;
      var b;
      var prevIndex = 0;
      var nextIndex = -1;

      for (var i = 0; i < len; i++) {
        b = points[i * 2 + dimIdx];

        if (isNaN(b) || isNaN(points[i * 2 + 1 - dimIdx])) {
          continue;
        }

        if (i === 0) {
          a = b;
          continue;
        }

        if (a <= xOrY && b >= xOrY || a >= xOrY && b <= xOrY) {
          nextIndex = i;
          break;
        }

        prevIndex = i;
        a = b;
      }

      return {
        range: [prevIndex, nextIndex],
        t: (xOrY - a) / (b - a)
      };
    }

    function anyStateShowEndLabel(seriesModel) {
      if (seriesModel.get(['endLabel', 'show'])) {
        return true;
      }

      for (var i = 0; i < SPECIAL_STATES.length; i++) {
        if (seriesModel.get([SPECIAL_STATES[i], 'endLabel', 'show'])) {
          return true;
        }
      }

      return false;
    }

    function createLineClipPath(lineView, coordSys, hasAnimation, seriesModel) {
      if (isCoordinateSystemType(coordSys, 'cartesian2d')) {
        var endLabelModel_1 = seriesModel.getModel('endLabel');
        var valueAnimation_1 = endLabelModel_1.get('valueAnimation');
        var data_1 = seriesModel.getData();
        var labelAnimationRecord_1 = {
          lastFrameIndex: 0
        };
        var during = anyStateShowEndLabel(seriesModel) ? function (percent, clipRect) {
          lineView._endLabelOnDuring(percent, clipRect, data_1, labelAnimationRecord_1, valueAnimation_1, endLabelModel_1, coordSys);
        } : null;
        var isHorizontal = coordSys.getBaseAxis().isHorizontal();
        var clipPath = createGridClipPath(coordSys, hasAnimation, seriesModel, function () {
          var endLabel = lineView._endLabel;

          if (endLabel && hasAnimation) {
            if (labelAnimationRecord_1.originalX != null) {
              endLabel.attr({
                x: labelAnimationRecord_1.originalX,
                y: labelAnimationRecord_1.originalY
              });
            }
          }
        }, during); // 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;
          }
        } // Set to the final frame. To make sure label layout is right.


        if (during) {
          during(1, clipPath);
        }

        return clipPath;
      } else {
        if ("development" !== 'production') {
          if (seriesModel.get(['endLabel', 'show'])) {
            console.warn('endLabel is not supported for lines in polar systems.');
          }
        }

        return createPolarClipPath(coordSys, hasAnimation, seriesModel);
      }
    }

    function getEndLabelStateSpecified(endLabelModel, coordSys) {
      var baseAxis = coordSys.getBaseAxis();
      var isHorizontal = baseAxis.isHorizontal();
      var isBaseInversed = baseAxis.inverse;
      var align = isHorizontal ? isBaseInversed ? 'right' : 'left' : 'center';
      var verticalAlign = isHorizontal ? 'middle' : isBaseInversed ? 'top' : 'bottom';
      return {
        normal: {
          align: endLabelModel.get('align') || align,
          verticalAlign: endLabelModel.get('verticalAlign') || verticalAlign
        }
      };
    }

    var LineView =
    /** @class */
    function (_super) {
      __extends(LineView, _super);

      function LineView() {
        return _super !== null && _super.apply(this, arguments) || this;
      }

      LineView.prototype.init = function () {
        var lineGroup = new Group();
        var symbolDraw = new SymbolDraw();
        this.group.add(symbolDraw.group);
        this._symbolDraw = symbolDraw;
        this._lineGroup = lineGroup;
      };

      LineView.prototype.render = function (seriesModel, ecModel, api) {
        var _this = this;

        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.getLayout('points') || [];
        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 = isAreaChart && getStackedOnPoints(coordSys, data, dataCoordInfo);
        var showSymbol = seriesModel.get('showSymbol');
        var connectNulls = seriesModel.get('connectNulls');
        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') : false;
        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.r += 0.5;
          }
        }

        this._clipShapeForSymbol = clipShapeForSymbol;
        var visualColor = getVisualGradient(data, coordSys, api) || data.getVisual('style')[data.getVisual('drawType')]; // Initialization animation or coordinate system changed

        if (!(polyline && prevCoordSys.type === coordSys.type && step === this._step)) {
          showSymbol && symbolDraw.updateData(data, {
            isIgnore: isIgnoreFunc,
            clipShape: clipShapeForSymbol,
            disableAnimation: true,
            getSymbolPoint: function (idx) {
              return [points[idx * 2], points[idx * 2 + 1]];
            }
          });
          hasAnimation && this._initSymbolLabelAnimation(data, coordSys, clipShapeForSymbol);

          if (step) {
            // TODO If stacked series is not step
            points = turnPointsIntoStep(points, coordSys, step, connectNulls);

            if (stackedOnPoints) {
              stackedOnPoints = turnPointsIntoStep(stackedOnPoints, coordSys, step, connectNulls);
            }
          }

          polyline = this._newPolyline(points);

          if (isAreaChart) {
            polygon = this._newPolygon(points, stackedOnPoints);
          } // If areaStyle is removed
          else if (polygon) {
              lineGroup.remove(polygon);
              polygon = this._polygon = null;
            } // NOTE: Must update _endLabel before setClipPath.


          if (!isCoordSysPolar) {
            this._initOrUpdateEndLabel(seriesModel, coordSys, convertToColorString(visualColor));
          }

          lineGroup.setClipPath(createLineClipPath(this, coordSys, true, seriesModel));
        } else {
          if (isAreaChart && !polygon) {
            // If areaStyle is added
            polygon = this._newPolygon(points, stackedOnPoints);
          } else if (polygon && !isAreaChart) {
            // If areaStyle is removed
            lineGroup.remove(polygon);
            polygon = this._polygon = null;
          } // NOTE: Must update _endLabel before setClipPath.


          if (!isCoordSysPolar) {
            this._initOrUpdateEndLabel(seriesModel, coordSys, convertToColorString(visualColor));
          } // Update clipPath


          var oldClipPath = lineGroup.getClipPath();

          if (oldClipPath) {
            var newClipPath = createLineClipPath(this, coordSys, false, seriesModel);
            initProps(oldClipPath, {
              shape: newClipPath.shape
            }, seriesModel);
          } else {
            lineGroup.setClipPath(createLineClipPath(this, coordSys, true, 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,
            disableAnimation: true,
            getSymbolPoint: function (idx) {
              return [points[idx * 2], points[idx * 2 + 1]];
            }
          }); // In the case data zoom triggered 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._doUpdateAnimation(data, stackedOnPoints, coordSys, api, step, valueOrigin, connectNulls);
            } else {
              // Not do it in update with animation
              if (step) {
                // TODO If stacked series is not step
                points = turnPointsIntoStep(points, coordSys, step, connectNulls);

                if (stackedOnPoints) {
                  stackedOnPoints = turnPointsIntoStep(stackedOnPoints, coordSys, step, connectNulls);
                }
              }

              polyline.setShape({
                points: points
              });
              polygon && polygon.setShape({
                points: points,
                stackedOnPoints: stackedOnPoints
              });
            }
          }
        }

        var emphasisModel = seriesModel.getModel('emphasis');
        var focus = emphasisModel.get('focus');
        var blurScope = emphasisModel.get('blurScope');
        var emphasisDisabled = emphasisModel.get('disabled');
        polyline.useStyle(defaults( // Use color in lineStyle first
        lineStyleModel.getLineStyle(), {
          fill: 'none',
          stroke: visualColor,
          lineJoin: 'bevel'
        }));
        setStatesStylesFromModel(polyline, seriesModel, 'lineStyle');

        if (polyline.style.lineWidth > 0 && seriesModel.get(['emphasis', 'lineStyle', 'width']) === 'bolder') {
          var emphasisLineStyle = polyline.getState('emphasis').style;
          emphasisLineStyle.lineWidth = +polyline.style.lineWidth + 1;
        } // Needs seriesIndex for focus


        getECData(polyline).seriesIndex = seriesModel.seriesIndex;
        toggleHoverEmphasis(polyline, focus, blurScope, emphasisDisabled);
        var smooth = getSmooth(seriesModel.get('smooth'));
        var smoothMonotone = seriesModel.get('smoothMonotone');
        polyline.setShape({
          smooth: smooth,
          smoothMonotone: smoothMonotone,
          connectNulls: connectNulls
        });

        if (polygon) {
          var stackedOnSeries = data.getCalculationInfo('stackedOnSeries');
          var stackedOnSmooth = 0;
          polygon.useStyle(defaults(areaStyleModel.getAreaStyle(), {
            fill: visualColor,
            opacity: 0.7,
            lineJoin: 'bevel',
            decal: data.getVisual('style').decal
          }));

          if (stackedOnSeries) {
            stackedOnSmooth = getSmooth(stackedOnSeries.get('smooth'));
          }

          polygon.setShape({
            smooth: smooth,
            stackedOnSmooth: stackedOnSmooth,
            smoothMonotone: smoothMonotone,
            connectNulls: connectNulls
          });
          setStatesStylesFromModel(polygon, seriesModel, 'areaStyle'); // Needs seriesIndex for focus

          getECData(polygon).seriesIndex = seriesModel.seriesIndex;
          toggleHoverEmphasis(polygon, focus, blurScope, emphasisDisabled);
        }

        var changePolyState = function (toState) {
          _this._changePolyState(toState);
        };

        data.eachItemGraphicEl(function (el) {
          // Switch polyline / polygon state if element changed its state.
          el && (el.onHoverStateChange = changePolyState);
        });
        this._polyline.onHoverStateChange = changePolyState;
        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;

        if (seriesModel.get('triggerLineEvent')) {
          this.packEventData(seriesModel, polyline);
          polygon && this.packEventData(seriesModel, polygon);
        }
      };

      LineView.prototype.packEventData = function (seriesModel, el) {
        getECData(el).eventData = {
          componentType: 'series',
          componentSubType: 'line',
          componentIndex: seriesModel.componentIndex,
          seriesIndex: seriesModel.seriesIndex,
          seriesName: seriesModel.name,
          seriesType: 'line'
        };
      };

      LineView.prototype.highlight = function (seriesModel, ecModel, api, payload) {
        var data = seriesModel.getData();
        var dataIndex = queryDataIndex(data, payload);

        this._changePolyState('emphasis');

        if (!(dataIndex instanceof Array) && dataIndex != null && dataIndex >= 0) {
          var points = data.getLayout('points');
          var symbol = data.getItemGraphicEl(dataIndex);

          if (!symbol) {
            // Create a temporary symbol if it is not exists
            var x = points[dataIndex * 2];
            var y = points[dataIndex * 2 + 1];

            if (isNaN(x) || isNaN(y)) {
              // Null data
              return;
            } // fix #11360: shouldn't draw symbol outside clipShapeForSymbol


            if (this._clipShapeForSymbol && !this._clipShapeForSymbol.contain(x, y)) {
              return;
            }

            var zlevel = seriesModel.get('zlevel') || 0;
            var z = seriesModel.get('z') || 0;
            symbol = new Symbol(data, dataIndex);
            symbol.x = x;
            symbol.y = y;
            symbol.setZ(zlevel, z); // ensure label text of the temporary symbol is in front of line and area polygon

            var symbolLabel = symbol.getSymbolPath().getTextContent();

            if (symbolLabel) {
              symbolLabel.zlevel = zlevel;
              symbolLabel.z = z;
              symbolLabel.z2 = this._polyline.z2 + 1;
            }

            symbol.__temp = true;
            data.setItemGraphicEl(dataIndex, symbol); // Stop scale animation

            symbol.stopSymbolAnimation(true);
            this.group.add(symbol);
          }

          symbol.highlight();
        } else {
          // Highlight whole series
          ChartView.prototype.highlight.call(this, seriesModel, ecModel, api, payload);
        }
      };

      LineView.prototype.downplay = function (seriesModel, ecModel, api, payload) {
        var data = seriesModel.getData();
        var dataIndex = queryDataIndex(data, payload);

        this._changePolyState('normal');

        if (dataIndex != null && dataIndex >= 0) {
          var symbol = data.getItemGraphicEl(dataIndex);

          if (symbol) {
            if (symbol.__temp) {
              data.setItemGraphicEl(dataIndex, null);
              this.group.remove(symbol);
            } else {
              symbol.downplay();
            }
          }
        } else {
          // FIXME
          // can not downplay completely.
          // Downplay whole series
          ChartView.prototype.downplay.call(this, seriesModel, ecModel, api, payload);
        }
      };

      LineView.prototype._changePolyState = function (toState) {
        var polygon = this._polygon;
        setStatesFlag(this._polyline, toState);
        polygon && setStatesFlag(polygon, toState);
      };

      LineView.prototype._newPolyline = function (points) {
        var polyline = this._polyline; // Remove previous created polyline

        if (polyline) {
          this._lineGroup.remove(polyline);
        }

        polyline = new ECPolyline({
          shape: {
            points: points
          },
          segmentIgnoreThreshold: 2,
          z2: 10
        });

        this._lineGroup.add(polyline);

        this._polyline = polyline;
        return polyline;
      };

      LineView.prototype._newPolygon = function (points, stackedOnPoints) {
        var polygon = this._polygon; // Remove previous created polygon

        if (polygon) {
          this._lineGroup.remove(polygon);
        }

        polygon = new ECPolygon({
          shape: {
            points: points,
            stackedOnPoints: stackedOnPoints
          },
          segmentIgnoreThreshold: 2
        });

        this._lineGroup.add(polygon);

        this._polygon = polygon;
        return polygon;
      };

      LineView.prototype._initSymbolLabelAnimation = function (data, coordSys, clipShape) {
        var isHorizontalOrRadial;
        var isCoordSysPolar;
        var baseAxis = coordSys.getBaseAxis();
        var isAxisInverse = baseAxis.inverse;

        if (coordSys.type === 'cartesian2d') {
          isHorizontalOrRadial = baseAxis.isHorizontal();
          isCoordSysPolar = false;
        } else if (coordSys.type === 'polar') {
          isHorizontalOrRadial = baseAxis.dim === 'angle';
          isCoordSysPolar = true;
        }

        var seriesModel = data.hostModel;
        var seriesDuration = seriesModel.get('animationDuration');

        if (isFunction(seriesDuration)) {
          seriesDuration = seriesDuration(null);
        }

        var seriesDalay = seriesModel.get('animationDelay') || 0;
        var seriesDalayValue = isFunction(seriesDalay) ? seriesDalay(null) : seriesDalay;
        data.eachItemGraphicEl(function (symbol, idx) {
          var el = symbol;

          if (el) {
            var point = [symbol.x, symbol.y];
            var start = void 0;
            var end = void 0;
            var current = void 0;

            if (clipShape) {
              if (isCoordSysPolar) {
                var polarClip = clipShape;
                var coord = coordSys.pointToCoord(point);

                if (isHorizontalOrRadial) {
                  start = polarClip.startAngle;
                  end = polarClip.endAngle;
                  current = -coord[1] / 180 * Math.PI;
                } else {
                  start = polarClip.r0;
                  end = polarClip.r;
                  current = coord[0];
                }
              } else {
                var gridClip = clipShape;

                if (isHorizontalOrRadial) {
                  start = gridClip.x;
                  end = gridClip.x + gridClip.width;
                  current = symbol.x;
                } else {
                  start = gridClip.y + gridClip.height;
                  end = gridClip.y;
                  current = symbol.y;
                }
              }
            }

            var ratio = end === start ? 0 : (current - start) / (end - start);

            if (isAxisInverse) {
              ratio = 1 - ratio;
            }

            var delay = isFunction(seriesDalay) ? seriesDalay(idx) : seriesDuration * ratio + seriesDalayValue;
            var symbolPath = el.getSymbolPath();
            var text = symbolPath.getTextContent();
            el.attr({
              scaleX: 0,
              scaleY: 0
            });
            el.animateTo({
              scaleX: 1,
              scaleY: 1
            }, {
              duration: 200,
              setToFinal: true,
              delay: delay
            });

            if (text) {
              text.animateFrom({
                style: {
                  opacity: 0
                }
              }, {
                duration: 300,
                delay: delay
              });
            }

            symbolPath.disableLabelAnimation = true;
          }
        });
      };

      LineView.prototype._initOrUpdateEndLabel = function (seriesModel, coordSys, inheritColor) {
        var endLabelModel = seriesModel.getModel('endLabel');

        if (anyStateShowEndLabel(seriesModel)) {
          var data_2 = seriesModel.getData();
          var polyline = this._polyline; // series may be filtered.

          var points = data_2.getLayout('points');

          if (!points) {
            polyline.removeTextContent();
            this._endLabel = null;
            return;
          }

          var endLabel = this._endLabel;

          if (!endLabel) {
            endLabel = this._endLabel = new ZRText({
              z2: 200 // should be higher than item symbol

            });
            endLabel.ignoreClip = true;
            polyline.setTextContent(this._endLabel);
            polyline.disableLabelAnimation = true;
          } // Find last non-NaN data to display data


          var dataIndex = getLastIndexNotNull(points);

          if (dataIndex >= 0) {
            setLabelStyle(polyline, getLabelStatesModels(seriesModel, 'endLabel'), {
              inheritColor: inheritColor,
              labelFetcher: seriesModel,
              labelDataIndex: dataIndex,
              defaultText: function (dataIndex, opt, interpolatedValue) {
                return interpolatedValue != null ? getDefaultInterpolatedLabel(data_2, interpolatedValue) : getDefaultLabel(data_2, dataIndex);
              },
              enableTextSetter: true
            }, getEndLabelStateSpecified(endLabelModel, coordSys));
            polyline.textConfig.position = null;
          }
        } else if (this._endLabel) {
          this._polyline.removeTextContent();

          this._endLabel = null;
        }
      };

      LineView.prototype._endLabelOnDuring = function (percent, clipRect, data, animationRecord, valueAnimation, endLabelModel, coordSys) {
        var endLabel = this._endLabel;
        var polyline = this._polyline;

        if (endLabel) {
          // NOTE: Don't remove percent < 1. percent === 1 means the first frame during render.
          // The label is not prepared at this time.
          if (percent < 1 && animationRecord.originalX == null) {
            animationRecord.originalX = endLabel.x;
            animationRecord.originalY = endLabel.y;
          }

          var points = data.getLayout('points');
          var seriesModel = data.hostModel;
          var connectNulls = seriesModel.get('connectNulls');
          var precision = endLabelModel.get('precision');
          var distance = endLabelModel.get('distance') || 0;
          var baseAxis = coordSys.getBaseAxis();
          var isHorizontal = baseAxis.isHorizontal();
          var isBaseInversed = baseAxis.inverse;
          var clipShape = clipRect.shape;
          var xOrY = isBaseInversed ? isHorizontal ? clipShape.x : clipShape.y + clipShape.height : isHorizontal ? clipShape.x + clipShape.width : clipShape.y;
          var distanceX = (isHorizontal ? distance : 0) * (isBaseInversed ? -1 : 1);
          var distanceY = (isHorizontal ? 0 : -distance) * (isBaseInversed ? -1 : 1);
          var dim = isHorizontal ? 'x' : 'y';
          var dataIndexRange = getIndexRange(points, xOrY, dim);
          var indices = dataIndexRange.range;
          var diff = indices[1] - indices[0];
          var value = void 0;

          if (diff >= 1) {
            // diff > 1 && connectNulls, which is on the null data.
            if (diff > 1 && !connectNulls) {
              var pt = getPointAtIndex(points, indices[0]);
              endLabel.attr({
                x: pt[0] + distanceX,
                y: pt[1] + distanceY
              });
              valueAnimation && (value = seriesModel.getRawValue(indices[0]));
            } else {
              var pt = polyline.getPointOn(xOrY, dim);
              pt && endLabel.attr({
                x: pt[0] + distanceX,
                y: pt[1] + distanceY
              });
              var startValue = seriesModel.getRawValue(indices[0]);
              var endValue = seriesModel.getRawValue(indices[1]);
              valueAnimation && (value = interpolateRawValues(data, precision, startValue, endValue, dataIndexRange.t));
            }

            animationRecord.lastFrameIndex = indices[0];
          } else {
            // If diff <= 0, which is the range is not found(Include NaN)
            // Choose the first point or last point.
            var idx = percent === 1 || animationRecord.lastFrameIndex > 0 ? indices[0] : 0;
            var pt = getPointAtIndex(points, idx);
            valueAnimation && (value = seriesModel.getRawValue(idx));
            endLabel.attr({
              x: pt[0] + distanceX,
              y: pt[1] + distanceY
            });
          }

          if (valueAnimation) {
            labelInner(endLabel).setLabelText(value);
          }
        }
      };
      /**
       * @private
       */
      // FIXME Two value axis


      LineView.prototype._doUpdateAnimation = function (data, stackedOnPoints, coordSys, api, step, valueOrigin, connectNulls) {
        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);
        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, connectNulls);
          stackedOnCurrent = turnPointsIntoStep(diff.stackedOnCurrent, coordSys, step, connectNulls);
          next = turnPointsIntoStep(diff.next, coordSys, step, connectNulls);
          stackedOnNext = turnPointsIntoStep(diff.stackedOnNext, coordSys, step, connectNulls);
        } // 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.stopAnimation();
          polyline.setShape({
            points: next
          });

          if (polygon) {
            polygon.stopAnimation();
            polygon.setShape({
              points: next,
              stackedOnPoints: stackedOnNext
            });
          }

          return;
        }

        polyline.shape.__points = diff.current;
        polyline.shape.points = current;
        var target = {
          shape: {
            points: next
          }
        }; // Also animate the original points.
        // If points reference is changed when turning into step line.

        if (diff.current !== current) {
          target.shape.__points = diff.next;
        } // Stop previous animation.


        polyline.stopAnimation();
        updateProps(polyline, target, seriesModel);

        if (polygon) {
          polygon.setShape({
            // Reuse the points with polyline.
            points: current,
            stackedOnPoints: stackedOnCurrent
          });
          polygon.stopAnimation();
          updateProps(polygon, {
            shape: {
              stackedOnPoints: stackedOnNext
            }
          }, seriesModel); // If use attr directly in updateProps.

          if (polyline.shape.points !== polygon.shape.points) {
            polygon.shape.points = polyline.shape.points;
          }
        }

        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 () {
            polygon && polygon.dirtyShape();
            var points = polyline.shape.__points;

            for (var i = 0; i < updatedDataInfo.length; i++) {
              var el = updatedDataInfo[i].el;
              var offset = updatedDataInfo[i].ptIdx * 2;
              el.x = points[offset];
              el.y = points[offset + 1];
              el.markRedraw();
            }
          });
        }
      };

      LineView.prototype.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._endLabel = this._data = null;
      };

      LineView.type = 'line';
      return LineView;
    }(ChartView);

    function pointsLayout(seriesType, forceStoreInTypedArray) {
      return {
        seriesType: seriesType,
        plan: createRenderPlanner(),
        reset: function (seriesModel) {
          var data = seriesModel.getData();
          var coordSys = seriesModel.coordinateSystem;
          var pipelineContext = seriesModel.pipelineContext;
          var useTypedArray = forceStoreInTypedArray || 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[0] = stackResultDim;
          }

          if (isDimensionStacked(data, dims[1])) {
            dims[1] = stackResultDim;
          }

          var store = data.getStore();
          var dimIdx0 = data.getDimensionIndex(dims[0]);
          var dimIdx1 = data.getDimensionIndex(dims[1]);
          return dimLen && {
            progress: function (params, data) {
              var segCount = params.end - params.start;
              var points = useTypedArray && createFloat32Array(segCount * dimLen);
              var tmpIn = [];
              var tmpOut = [];

              for (var i = params.start, offset = 0; i < params.end; i++) {
                var point = void 0;

                if (dimLen === 1) {
                  var x = store.get(dimIdx0, i); // NOTE: Make sure the second parameter is null to use default strategy.

                  point = coordSys.dataToPoint(x, null, tmpOut);
                } else {
                  tmpIn[0] = store.get(dimIdx0, i);
                  tmpIn[1] = store.get(dimIdx1, i); // Let coordinate system to handle the NaN data.

                  point = coordSys.dataToPoint(tmpIn, null, tmpOut);
                }

                if (useTypedArray) {
                  points[offset++] = point[0];
                  points[offset++] = point[1];
                } else {
                  data.setItemLayout(i, point.slice());
                }
              }

              useTypedArray && data.setLayout('points', points);
            }
          };
        }
      };
    }

    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) {
      return Math.round(frame.length / 2);
    };

    function dataSample(seriesType) {
      return {
        seriesType: seriesType,
        // FIXME:TS never used, so comment it
        // modifyOutputEnd: true,
        reset: function (seriesModel, ecModel, api) {
          var data = seriesModel.getData();
          var sampling = seriesModel.get('sampling');
          var coordSys = seriesModel.coordinateSystem;
          var count = data.count(); // Only cartesian2d support down sampling. Disable it when there is few data.

          if (count > 10 && coordSys.type === 'cartesian2d' && sampling) {
            var baseAxis = coordSys.getBaseAxis();
            var valueAxis = coordSys.getOtherAxis(baseAxis);
            var extent = baseAxis.getExtent();
            var dpr = api.getDevicePixelRatio(); // Coordinste system has been resized

            var size = Math.abs(extent[1] - extent[0]) * (dpr || 1);
            var rate = Math.round(count / size);

            if (isFinite(rate) && rate > 1) {
              if (sampling === 'lttb') {
                seriesModel.setData(data.lttbDownSample(data.mapDimension(valueAxis.dim), 1 / rate));
              }

              var sampler = void 0;

              if (isString(sampling)) {
                sampler = samplers[sampling];
              } else if (isFunction(sampling)) {
                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));
              }
            }
          }
        }
      };
    }

    function install$2(registers) {
      registers.registerChartView(LineView);
      registers.registerSeriesModel(LineSeriesModel);
      registers.registerLayout(pointsLayout('line', true));
      registers.registerVisual({
        seriesType: 'line',
        reset: function (seriesModel) {
          var data = seriesModel.getData(); // Visual coding for legend

          var lineStyle = seriesModel.getModel('lineStyle').getLineStyle();

          if (lineStyle && !lineStyle.stroke) {
            // Fill in visual should be palette color if
            // has color callback
            lineStyle.stroke = data.getVisual('style').fill;
          }

          data.setVisual('legendLineStyle', lineStyle);
        }
      }); // Down sample after filter

      registers.registerProcessor(registers.PRIORITY.PROCESSOR.STATISTIC, dataSample('line'));
    }

    var BaseBarSeriesModel =
    /** @class */
    function (_super) {
      __extends(BaseBarSeriesModel, _super);

      function BaseBarSeriesModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = BaseBarSeriesModel.type;
        return _this;
      }

      BaseBarSeriesModel.prototype.getInitialData = function (option, ecModel) {
        return createSeriesData(null, this, {
          useEncodeDefaulter: true
        });
      };

      BaseBarSeriesModel.prototype.getMarkerPosition = function (value, dims, startingAtTick) {
        var coordSys = this.coordinateSystem;

        if (coordSys && coordSys.clampData) {
          // PENDING if clamp ?
          var pt_1 = coordSys.dataToPoint(coordSys.clampData(value));

          if (startingAtTick) {
            each(coordSys.getAxes(), function (axis, idx) {
              // If axis type is category, use tick coords instead
              if (axis.type === 'category') {
                var tickCoords = axis.getTicksCoords();
                var tickIdx = coordSys.clampData(value)[idx]; // The index of rightmost tick of markArea is 1 larger than x1/y1 index

                if (dims && (dims[idx] === 'x1' || dims[idx] === 'y1')) {
                  tickIdx += 1;
                }

                tickIdx > tickCoords.length - 1 && (tickIdx = tickCoords.length - 1);
                tickIdx < 0 && (tickIdx = 0);
                tickCoords[tickIdx] && (pt_1[idx] = axis.toGlobalCoord(tickCoords[tickIdx].coord));
              }
            });
          } else {
            var data = this.getData();
            var offset = data.getLayout('offset');
            var size = data.getLayout('size');
            var offsetIndex = coordSys.getBaseAxis().isHorizontal() ? 0 : 1;
            pt_1[offsetIndex] += offset + size / 2;
          }

          return pt_1;
        }

        return [NaN, NaN];
      };

      BaseBarSeriesModel.type = 'series.__base_bar__';
      BaseBarSeriesModel.defaultOption = {
        // zlevel: 0,
        z: 2,
        coordinateSystem: 'cartesian2d',
        legendHoverLink: true,
        // stack: null
        // Cartesian coordinate system
        // xAxisIndex: 0,
        // yAxisIndex: 0,
        barMinHeight: 0,
        barMinAngle: 0,
        // cursor: null,
        large: false,
        largeThreshold: 400,
        progressive: 3e3,
        progressiveChunkMode: 'mod'
      };
      return BaseBarSeriesModel;
    }(SeriesModel);

    SeriesModel.registerClass(BaseBarSeriesModel);

    var BarSeriesModel =
    /** @class */
    function (_super) {
      __extends(BarSeriesModel, _super);

      function BarSeriesModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = BarSeriesModel.type;
        return _this;
      }

      BarSeriesModel.prototype.getInitialData = function () {
        return createSeriesData(null, this, {
          useEncodeDefaulter: true,
          createInvertedIndices: !!this.get('realtimeSort', true) || null
        });
      };
      /**
       * @override
       */


      BarSeriesModel.prototype.getProgressive = function () {
        // Do not support progressive in normal mode.
        return this.get('large') ? this.get('progressive') : false;
      };
      /**
       * @override
       */


      BarSeriesModel.prototype.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;
      };

      BarSeriesModel.prototype.brushSelector = function (dataIndex, data, selectors) {
        return selectors.rect(data.getItemLayout(dataIndex));
      };

      BarSeriesModel.type = 'series.bar';
      BarSeriesModel.dependencies = ['grid', 'polar'];
      BarSeriesModel.defaultOption = inheritDefaultOption(BaseBarSeriesModel.defaultOption, {
        // If clipped
        // Only available on cartesian2d
        clip: true,
        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
        },
        select: {
          itemStyle: {
            borderColor: '#212121'
          }
        },
        realtimeSort: false
      });
      return BarSeriesModel;
    }(BaseBarSeriesModel);

    /**
     * Sausage: similar to sector, but have half circle on both sides
     */

    var SausageShape =
    /** @class */
    function () {
      function SausageShape() {
        this.cx = 0;
        this.cy = 0;
        this.r0 = 0;
        this.r = 0;
        this.startAngle = 0;
        this.endAngle = Math.PI * 2;
        this.clockwise = true;
      }

      return SausageShape;
    }();

    var SausagePath =
    /** @class */
    function (_super) {
      __extends(SausagePath, _super);

      function SausagePath(opts) {
        var _this = _super.call(this, opts) || this;

        _this.type = 'sausage';
        return _this;
      }

      SausagePath.prototype.getDefaultShape = function () {
        return new SausageShape();
      };

      SausagePath.prototype.buildPath = function (ctx, shape) {
        var cx = shape.cx;
        var cy = 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 PI2 = Math.PI * 2;
        var lessThanCircle = clockwise ? endAngle - startAngle < PI2 : startAngle - endAngle < PI2;

        if (!lessThanCircle) {
          // Normalize angles
          startAngle = endAngle - (clockwise ? PI2 : -PI2);
        }

        var unitStartX = Math.cos(startAngle);
        var unitStartY = Math.sin(startAngle);
        var unitEndX = Math.cos(endAngle);
        var unitEndY = Math.sin(endAngle);

        if (lessThanCircle) {
          ctx.moveTo(unitStartX * r0 + cx, unitStartY * r0 + cy);
          ctx.arc(unitStartX * rCenter + cx, unitStartY * rCenter + cy, dr, -Math.PI + startAngle, startAngle, !clockwise);
        } else {
          ctx.moveTo(unitStartX * r + cx, unitStartY * r + cy);
        }

        ctx.arc(cx, cy, r, startAngle, endAngle, !clockwise);
        ctx.arc(unitEndX * rCenter + cx, unitEndY * rCenter + cy, dr, endAngle - Math.PI * 2, endAngle - Math.PI, !clockwise);

        if (r0 !== 0) {
          ctx.arc(cx, cy, r0, endAngle, startAngle, clockwise);
        } // ctx.closePath();

      };

      return SausagePath;
    }(Path);

    function createSectorCalculateTextPosition(positionMapping, opts) {
      opts = opts || {};
      var isRoundCap = opts.isRoundCap;
      return function (out, opts, boundingRect) {
        var textPosition = opts.position;

        if (!textPosition || textPosition instanceof Array) {
          return calculateTextPosition(out, opts, boundingRect);
        }

        var mappedSectorPosition = positionMapping(textPosition);
        var distance = opts.distance != null ? opts.distance : 5;
        var sector = this.shape;
        var cx = sector.cx;
        var cy = sector.cy;
        var r = sector.r;
        var r0 = sector.r0;
        var middleR = (r + r0) / 2;
        var startAngle = sector.startAngle;
        var endAngle = sector.endAngle;
        var middleAngle = (startAngle + endAngle) / 2;
        var extraDist = isRoundCap ? Math.abs(r - r0) / 2 : 0;
        var mathCos = Math.cos;
        var mathSin = Math.sin; // base position: top-left

        var x = cx + r * mathCos(startAngle);
        var y = cy + r * mathSin(startAngle);
        var textAlign = 'left';
        var textVerticalAlign = 'top';

        switch (mappedSectorPosition) {
          case 'startArc':
            x = cx + (r0 - distance) * mathCos(middleAngle);
            y = cy + (r0 - distance) * mathSin(middleAngle);
            textAlign = 'center';
            textVerticalAlign = 'top';
            break;

          case 'insideStartArc':
            x = cx + (r0 + distance) * mathCos(middleAngle);
            y = cy + (r0 + distance) * mathSin(middleAngle);
            textAlign = 'center';
            textVerticalAlign = 'bottom';
            break;

          case 'startAngle':
            x = cx + middleR * mathCos(startAngle) + adjustAngleDistanceX(startAngle, distance + extraDist, false);
            y = cy + middleR * mathSin(startAngle) + adjustAngleDistanceY(startAngle, distance + extraDist, false);
            textAlign = 'right';
            textVerticalAlign = 'middle';
            break;

          case 'insideStartAngle':
            x = cx + middleR * mathCos(startAngle) + adjustAngleDistanceX(startAngle, -distance + extraDist, false);
            y = cy + middleR * mathSin(startAngle) + adjustAngleDistanceY(startAngle, -distance + extraDist, false);
            textAlign = 'left';
            textVerticalAlign = 'middle';
            break;

          case 'middle':
            x = cx + middleR * mathCos(middleAngle);
            y = cy + middleR * mathSin(middleAngle);
            textAlign = 'center';
            textVerticalAlign = 'middle';
            break;

          case 'endArc':
            x = cx + (r + distance) * mathCos(middleAngle);
            y = cy + (r + distance) * mathSin(middleAngle);
            textAlign = 'center';
            textVerticalAlign = 'bottom';
            break;

          case 'insideEndArc':
            x = cx + (r - distance) * mathCos(middleAngle);
            y = cy + (r - distance) * mathSin(middleAngle);
            textAlign = 'center';
            textVerticalAlign = 'top';
            break;

          case 'endAngle':
            x = cx + middleR * mathCos(endAngle) + adjustAngleDistanceX(endAngle, distance + extraDist, true);
            y = cy + middleR * mathSin(endAngle) + adjustAngleDistanceY(endAngle, distance + extraDist, true);
            textAlign = 'left';
            textVerticalAlign = 'middle';
            break;

          case 'insideEndAngle':
            x = cx + middleR * mathCos(endAngle) + adjustAngleDistanceX(endAngle, -distance + extraDist, true);
            y = cy + middleR * mathSin(endAngle) + adjustAngleDistanceY(endAngle, -distance + extraDist, true);
            textAlign = 'right';
            textVerticalAlign = 'middle';
            break;

          default:
            return calculateTextPosition(out, opts, boundingRect);
        }

        out = out || {};
        out.x = x;
        out.y = y;
        out.align = textAlign;
        out.verticalAlign = textVerticalAlign;
        return out;
      };
    }
    function setSectorTextRotation(sector, textPosition, positionMapping, rotateType) {
      if (isNumber(rotateType)) {
        // user-set rotation
        sector.setTextConfig({
          rotation: rotateType
        });
        return;
      } else if (isArray(textPosition)) {
        // user-set position, use 0 as auto rotation
        sector.setTextConfig({
          rotation: 0
        });
        return;
      }

      var shape = sector.shape;
      var startAngle = shape.clockwise ? shape.startAngle : shape.endAngle;
      var endAngle = shape.clockwise ? shape.endAngle : shape.startAngle;
      var middleAngle = (startAngle + endAngle) / 2;
      var anchorAngle;
      var mappedSectorPosition = positionMapping(textPosition);

      switch (mappedSectorPosition) {
        case 'startArc':
        case 'insideStartArc':
        case 'middle':
        case 'insideEndArc':
        case 'endArc':
          anchorAngle = middleAngle;
          break;

        case 'startAngle':
        case 'insideStartAngle':
          anchorAngle = startAngle;
          break;

        case 'endAngle':
        case 'insideEndAngle':
          anchorAngle = endAngle;
          break;

        default:
          sector.setTextConfig({
            rotation: 0
          });
          return;
      }

      var rotate = Math.PI * 1.5 - anchorAngle;
      /**
       * TODO: labels with rotate > Math.PI / 2 should be rotate another
       * half round flipped to increase readability. However, only middle
       * position supports this for now, because in other positions, the
       * anchor point is not at the center of the text, so the positions
       * after rotating is not as expected.
       */

      if (mappedSectorPosition === 'middle' && rotate > Math.PI / 2 && rotate < Math.PI * 1.5) {
        rotate -= Math.PI;
      }

      sector.setTextConfig({
        rotation: rotate
      });
    }

    function adjustAngleDistanceX(angle, distance, isEnd) {
      return distance * Math.sin(angle) * (isEnd ? -1 : 1);
    }

    function adjustAngleDistanceY(angle, distance, isEnd) {
      return distance * Math.cos(angle) * (isEnd ? 1 : -1);
    }

    var mathMax$6 = Math.max;
    var mathMin$6 = Math.min;

    function getClipArea(coord, data) {
      var coordSysClipArea = coord.getArea && coord.getArea();

      if (isCoordinateSystemType(coord, '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;
    }

    var BarView =
    /** @class */
    function (_super) {
      __extends(BarView, _super);

      function BarView() {
        var _this = _super.call(this) || this;

        _this.type = BarView.type;
        _this._isFirstFrame = true;
        return _this;
      }

      BarView.prototype.render = function (seriesModel, ecModel, api, payload) {
        this._model = seriesModel;

        this._removeOnRenderedListener(api);

        this._updateDrawMode(seriesModel);

        var coordinateSystemType = seriesModel.get('coordinateSystem');

        if (coordinateSystemType === 'cartesian2d' || coordinateSystemType === 'polar') {
          // Clear previously rendered progressive elements.
          this._progressiveEls = null;
          this._isLargeDraw ? this._renderLarge(seriesModel, ecModel, api) : this._renderNormal(seriesModel, ecModel, api, payload);
        } else if ("development" !== 'production') {
          warn('Only cartesian2d and polar supported for bar.');
        }
      };

      BarView.prototype.incrementalPrepareRender = function (seriesModel) {
        this._clear();

        this._updateDrawMode(seriesModel); // incremental also need to clip, otherwise might be overlow.
        // But must not set clip in each frame, otherwise all of the children will be marked redraw.


        this._updateLargeClip(seriesModel);
      };

      BarView.prototype.incrementalRender = function (params, seriesModel) {
        // Reset
        this._progressiveEls = []; // Do not support progressive in normal mode.

        this._incrementalRenderLarge(params, seriesModel);
      };

      BarView.prototype.eachRendered = function (cb) {
        traverseElements(this._progressiveEls || this.group, cb);
      };

      BarView.prototype._updateDrawMode = function (seriesModel) {
        var isLargeDraw = seriesModel.pipelineContext.large;

        if (this._isLargeDraw == null || isLargeDraw !== this._isLargeDraw) {
          this._isLargeDraw = isLargeDraw;

          this._clear();
        }
      };

      BarView.prototype._renderNormal = function (seriesModel, ecModel, api, payload) {
        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 realtimeSortCfg = shouldRealtimeSort(seriesModel, coord);

        if (realtimeSortCfg) {
          this._enableRealtimeSort(realtimeSortCfg, data, api);
        }

        var needsClip = seriesModel.get('clip', true) || realtimeSortCfg;
        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('borderRadius') || 0;
        var bgEls = [];
        var oldBgEls = this._backgroundEls;
        var isInitSort = payload && payload.isInitSort;
        var isChangeOrder = payload && payload.type === 'changeAxisOrder';

        function createBackground(dataIndex) {
          var bgLayout = getLayout[coord.type](data, dataIndex);
          var bgEl = createBackgroundEl(coord, isHorizontalOrRadial, bgLayout);
          bgEl.useStyle(backgroundModel.getItemStyle()); // 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) || !isValidLayout[coord.type](layout)) {
            return;
          }

          var isClipped = false;

          if (needsClip) {
            // Clip will modify the layout params.
            // And return a boolean to determine if the shape are fully clipped.
            isClipped = clip[coord.type](coordSysClipArea, layout);
          }

          var el = elementCreator[coord.type](seriesModel, data, dataIndex, layout, isHorizontalOrRadial, animationModel, baseAxis.model, false, roundCap);

          if (realtimeSortCfg) {
            /**
             * Force label animation because even if the element is
             * ignored because it's clipped, it may not be clipped after
             * changing order. Then, if not using forceLabelAnimation,
             * the label animation was never started, in which case,
             * the label will be the final value and doesn't have label
             * animation.
             */
            el.forceLabelAnimation = true;
          }

          updateStyle(el, data, dataIndex, itemModel, layout, seriesModel, isHorizontalOrRadial, coord.type === 'polar');

          if (isInitSort) {
            el.attr({
              shape: layout
            });
          } else if (realtimeSortCfg) {
            updateRealtimeAnimation(realtimeSortCfg, animationModel, el, layout, dataIndex, isHorizontalOrRadial, false, false);
          } else {
            initProps(el, {
              shape: layout
            }, seriesModel, dataIndex);
          }

          data.setItemGraphicEl(dataIndex, el);
          group.add(el);
          el.ignore = isClipped;
        }).update(function (newIndex, oldIndex) {
          var itemModel = data.getItemModel(newIndex);
          var layout = getLayout[coord.type](data, newIndex, itemModel);

          if (drawBackground) {
            var bgEl = void 0;

            if (oldBgEls.length === 0) {
              bgEl = createBackground(oldIndex);
            } else {
              bgEl = oldBgEls[oldIndex];
              bgEl.useStyle(backgroundModel.getItemStyle()); // 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) || !isValidLayout[coord.type](layout)) {
            group.remove(el);
            return;
          }

          var isClipped = false;

          if (needsClip) {
            isClipped = clip[coord.type](coordSysClipArea, layout);

            if (isClipped) {
              group.remove(el);
            }
          }

          if (!el) {
            el = elementCreator[coord.type](seriesModel, data, newIndex, layout, isHorizontalOrRadial, animationModel, baseAxis.model, !!el, roundCap);
          } else {
            saveOldStyle(el);
          }

          if (realtimeSortCfg) {
            el.forceLabelAnimation = true;
          }

          if (isChangeOrder) {
            var textEl = el.getTextContent();

            if (textEl) {
              var labelInnerStore = labelInner(textEl);

              if (labelInnerStore.prevValue != null) {
                /**
                 * Set preValue to be value so that no new label
                 * should be started, otherwise, it will take a full
                 * `animationDurationUpdate` time to finish the
                 * animation, which is not expected.
                 */
                labelInnerStore.prevValue = labelInnerStore.value;
              }
            }
          } // Not change anything if only order changed.
          // Especially not change label.
          else {
              updateStyle(el, data, newIndex, itemModel, layout, seriesModel, isHorizontalOrRadial, coord.type === 'polar');
            }

          if (isInitSort) {
            el.attr({
              shape: layout
            });
          } else if (realtimeSortCfg) {
            updateRealtimeAnimation(realtimeSortCfg, animationModel, el, layout, newIndex, isHorizontalOrRadial, true, isChangeOrder);
          } else {
            updateProps(el, {
              shape: layout
            }, seriesModel, newIndex, null);
          }

          data.setItemGraphicEl(newIndex, el);
          el.ignore = isClipped;
          group.add(el);
        }).remove(function (dataIndex) {
          var el = oldData.getItemGraphicEl(dataIndex);
          el && removeElementWithFadeOut(el, seriesModel, dataIndex);
        }).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;
      };

      BarView.prototype._renderLarge = function (seriesModel, ecModel, api) {
        this._clear();

        createLarge(seriesModel, this.group);

        this._updateLargeClip(seriesModel);
      };

      BarView.prototype._incrementalRenderLarge = function (params, seriesModel) {
        this._removeBackground();

        createLarge(seriesModel, this.group, this._progressiveEls, true);
      };

      BarView.prototype._updateLargeClip = function (seriesModel) {
        // Use clipPath in large mode.
        var clipPath = seriesModel.get('clip', true) && createClipPath(seriesModel.coordinateSystem, false, seriesModel);
        var group = this.group;

        if (clipPath) {
          group.setClipPath(clipPath);
        } else {
          group.removeClipPath();
        }
      };

      BarView.prototype._enableRealtimeSort = function (realtimeSortCfg, data, api) {
        var _this = this; // If no data in the first frame, wait for data to initSort


        if (!data.count()) {
          return;
        }

        var baseAxis = realtimeSortCfg.baseAxis;

        if (this._isFirstFrame) {
          this._dispatchInitSort(data, realtimeSortCfg, api);

          this._isFirstFrame = false;
        } else {
          var orderMapping_1 = function (idx) {
            var el = data.getItemGraphicEl(idx);
            var shape = el && el.shape;
            return shape && // The result should be consistent with the initial sort by data value.
            // Do not support the case that both positive and negative exist.
            Math.abs(baseAxis.isHorizontal() ? shape.height : shape.width) // If data is NaN, shape.xxx may be NaN, so use || 0 here in case
            || 0;
          };

          this._onRendered = function () {
            _this._updateSortWithinSameData(data, orderMapping_1, baseAxis, api);
          };

          api.getZr().on('rendered', this._onRendered);
        }
      };

      BarView.prototype._dataSort = function (data, baseAxis, orderMapping) {
        var info = [];
        data.each(data.mapDimension(baseAxis.dim), function (ordinalNumber, dataIdx) {
          var mappedValue = orderMapping(dataIdx);
          mappedValue = mappedValue == null ? NaN : mappedValue;
          info.push({
            dataIndex: dataIdx,
            mappedValue: mappedValue,
            ordinalNumber: ordinalNumber
          });
        });
        info.sort(function (a, b) {
          // If NaN, it will be treated as min val.
          return b.mappedValue - a.mappedValue;
        });
        return {
          ordinalNumbers: map(info, function (item) {
            return item.ordinalNumber;
          })
        };
      };

      BarView.prototype._isOrderChangedWithinSameData = function (data, orderMapping, baseAxis) {
        var scale = baseAxis.scale;
        var ordinalDataDim = data.mapDimension(baseAxis.dim);
        var lastValue = Number.MAX_VALUE;

        for (var tickNum = 0, len = scale.getOrdinalMeta().categories.length; tickNum < len; ++tickNum) {
          var rawIdx = data.rawIndexOf(ordinalDataDim, scale.getRawOrdinalNumber(tickNum));
          var value = rawIdx < 0 // If some tick have no bar, the tick will be treated as min.
          ? Number.MIN_VALUE // PENDING: if dataZoom on baseAxis exits, is it a performance issue?
          : orderMapping(data.indexOfRawIndex(rawIdx));

          if (value > lastValue) {
            return true;
          }

          lastValue = value;
        }

        return false;
      };
      /*
       * Consider the case when A and B changed order, whose representing
       * bars are both out of sight, we don't wish to trigger reorder action
       * as long as the order in the view doesn't change.
       */


      BarView.prototype._isOrderDifferentInView = function (orderInfo, baseAxis) {
        var scale = baseAxis.scale;
        var extent = scale.getExtent();
        var tickNum = Math.max(0, extent[0]);
        var tickMax = Math.min(extent[1], scale.getOrdinalMeta().categories.length - 1);

        for (; tickNum <= tickMax; ++tickNum) {
          if (orderInfo.ordinalNumbers[tickNum] !== scale.getRawOrdinalNumber(tickNum)) {
            return true;
          }
        }
      };

      BarView.prototype._updateSortWithinSameData = function (data, orderMapping, baseAxis, api) {
        if (!this._isOrderChangedWithinSameData(data, orderMapping, baseAxis)) {
          return;
        }

        var sortInfo = this._dataSort(data, baseAxis, orderMapping);

        if (this._isOrderDifferentInView(sortInfo, baseAxis)) {
          this._removeOnRenderedListener(api);

          api.dispatchAction({
            type: 'changeAxisOrder',
            componentType: baseAxis.dim + 'Axis',
            axisId: baseAxis.index,
            sortInfo: sortInfo
          });
        }
      };

      BarView.prototype._dispatchInitSort = function (data, realtimeSortCfg, api) {
        var baseAxis = realtimeSortCfg.baseAxis;

        var sortResult = this._dataSort(data, baseAxis, function (dataIdx) {
          return data.get(data.mapDimension(realtimeSortCfg.otherAxis.dim), dataIdx);
        });

        api.dispatchAction({
          type: 'changeAxisOrder',
          componentType: baseAxis.dim + 'Axis',
          isInitSort: true,
          axisId: baseAxis.index,
          sortInfo: sortResult
        });
      };

      BarView.prototype.remove = function (ecModel, api) {
        this._clear(this._model);

        this._removeOnRenderedListener(api);
      };

      BarView.prototype.dispose = function (ecModel, api) {
        this._removeOnRenderedListener(api);
      };

      BarView.prototype._removeOnRenderedListener = function (api) {
        if (this._onRendered) {
          api.getZr().off('rendered', this._onRendered);
          this._onRendered = null;
        }
      };

      BarView.prototype._clear = function (model) {
        var group = this.group;
        var data = this._data;

        if (model && model.isAnimationEnabled() && data && !this._isLargeDraw) {
          this._removeBackground();

          this._backgroundEls = [];
          data.eachItemGraphicEl(function (el) {
            removeElementWithFadeOut(el, model, getECData(el).dataIndex);
          });
        } else {
          group.removeAll();
        }

        this._data = null;
        this._isFirstFrame = true;
      };

      BarView.prototype._removeBackground = function () {
        this.group.remove(this._backgroundGroup);
        this._backgroundGroup = null;
      };

      BarView.type = 'bar';
      return BarView;
    }(ChartView);

    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 coordSysX2 = coordSysBoundingRect.x + coordSysBoundingRect.width;
        var coordSysY2 = coordSysBoundingRect.y + coordSysBoundingRect.height;
        var x = mathMax$6(layout.x, coordSysBoundingRect.x);
        var x2 = mathMin$6(layout.x + layout.width, coordSysX2);
        var y = mathMax$6(layout.y, coordSysBoundingRect.y);
        var y2 = mathMin$6(layout.y + layout.height, coordSysY2);
        var xClipped = x2 < x;
        var yClipped = y2 < y; // When xClipped or yClipped, the element will be marked as `ignore`.
        // But we should also place the element at the edge of the coord sys bounding rect.
        // Because if data changed and the bar shows again, its transition animation
        // will begin at this place.

        layout.x = xClipped && x > coordSysX2 ? x2 : x;
        layout.y = yClipped && y > coordSysY2 ? y2 : y;
        layout.width = xClipped ? 0 : x2 - x;
        layout.height = yClipped ? 0 : y2 - y; // 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 xClipped || yClipped;
      },
      polar: function (coordSysClipArea, layout) {
        var signR = layout.r0 <= layout.r ? 1 : -1; // Make sure r is larger than r0

        if (signR < 0) {
          var tmp = layout.r;
          layout.r = layout.r0;
          layout.r0 = tmp;
        }

        var r = mathMin$6(layout.r, coordSysClipArea.r);
        var r0 = mathMax$6(layout.r0, coordSysClipArea.r0);
        layout.r = r;
        layout.r0 = r0;
        var clipped = r - r0 < 0; // Reverse back

        if (signR < 0) {
          var tmp = layout.r;
          layout.r = layout.r0;
          layout.r0 = tmp;
        }

        return clipped;
      }
    };
    var elementCreator = {
      cartesian2d: function (seriesModel, data, newIndex, layout, isHorizontal, animationModel, axisModel, isUpdate, roundCap) {
        var rect = new Rect({
          shape: extend({}, layout),
          z2: 1
        });
        rect.__dataIndex = newIndex;
        rect.name = 'item';

        if (animationModel) {
          var rectShape = rect.shape;
          var animateProperty = isHorizontal ? 'height' : 'width';
          rectShape[animateProperty] = 0;
        }

        return rect;
      },
      polar: function (seriesModel, data, newIndex, layout, isRadial, animationModel, axisModel, isUpdate, roundCap) {
        var ShapeClass = !isRadial && roundCap ? SausagePath : Sector;
        var sector = new ShapeClass({
          shape: layout,
          z2: 1
        });
        sector.name = 'item';
        var positionMap = createPolarPositionMapping(isRadial);
        sector.calculateTextPosition = createSectorCalculateTextPosition(positionMap, {
          isRoundCap: ShapeClass === SausagePath
        }); // Animation

        if (animationModel) {
          var sectorShape = sector.shape;
          var animateProperty = isRadial ? 'r' : 'endAngle';
          var animateTarget = {};
          sectorShape[animateProperty] = isRadial ? 0 : layout.startAngle;
          animateTarget[animateProperty] = layout[animateProperty];
          (isUpdate ? updateProps : initProps)(sector, {
            shape: animateTarget // __value: typeof dataValue === 'string' ? parseInt(dataValue, 10) : dataValue

          }, animationModel);
        }

        return sector;
      }
    };

    function shouldRealtimeSort(seriesModel, coordSys) {
      var realtimeSortOption = seriesModel.get('realtimeSort', true);
      var baseAxis = coordSys.getBaseAxis();

      if ("development" !== 'production') {
        if (realtimeSortOption) {
          if (baseAxis.type !== 'category') {
            warn('`realtimeSort` will not work because this bar series is not based on a category axis.');
          }

          if (coordSys.type !== 'cartesian2d') {
            warn('`realtimeSort` will not work because this bar series is not on cartesian2d.');
          }
        }
      }

      if (realtimeSortOption && baseAxis.type === 'category' && coordSys.type === 'cartesian2d') {
        return {
          baseAxis: baseAxis,
          otherAxis: coordSys.getOtherAxis(baseAxis)
        };
      }
    }

    function updateRealtimeAnimation(realtimeSortCfg, seriesAnimationModel, el, layout, newIndex, isHorizontal, isUpdate, isChangeOrder) {
      var seriesTarget;
      var axisTarget;

      if (isHorizontal) {
        axisTarget = {
          x: layout.x,
          width: layout.width
        };
        seriesTarget = {
          y: layout.y,
          height: layout.height
        };
      } else {
        axisTarget = {
          y: layout.y,
          height: layout.height
        };
        seriesTarget = {
          x: layout.x,
          width: layout.width
        };
      }

      if (!isChangeOrder) {
        // Keep the original growth animation if only axis order changed.
        // Not start a new animation.
        (isUpdate ? updateProps : initProps)(el, {
          shape: seriesTarget
        }, seriesAnimationModel, newIndex, null);
      }

      var axisAnimationModel = seriesAnimationModel ? realtimeSortCfg.baseAxis.model : null;
      (isUpdate ? updateProps : initProps)(el, {
        shape: axisTarget
      }, axisAnimationModel, newIndex);
    }

    function checkPropertiesNotValid(obj, props) {
      for (var i = 0; i < props.length; i++) {
        if (!isFinite(obj[props[i]])) {
          return true;
        }
      }

      return false;
    }

    var rectPropties = ['x', 'y', 'width', 'height'];
    var polarPropties = ['cx', 'cy', 'r', 'startAngle', 'endAngle'];
    var isValidLayout = {
      cartesian2d: function (layout) {
        return !checkPropertiesNotValid(layout, rectPropties);
      },
      polar: function (layout) {
        return !checkPropertiesNotValid(layout, polarPropties);
      }
    };
    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,
          clockwise: layout.clockwise
        };
      }
    };

    function isZeroOnPolar(layout) {
      return layout.startAngle != null && layout.endAngle != null && layout.startAngle === layout.endAngle;
    }

    function createPolarPositionMapping(isRadial) {
      return function (isRadial) {
        var arcOrAngle = isRadial ? 'Arc' : 'Angle';
        return function (position) {
          switch (position) {
            case 'start':
            case 'insideStart':
            case 'end':
            case 'insideEnd':
              return position + arcOrAngle;

            default:
              return position;
          }
        };
      }(isRadial);
    }

    function updateStyle(el, data, dataIndex, itemModel, layout, seriesModel, isHorizontalOrRadial, isPolar) {
      var style = data.getItemVisual(dataIndex, 'style');

      if (!isPolar) {
        el.setShape('r', itemModel.get(['itemStyle', 'borderRadius']) || 0);
      }

      el.useStyle(style);
      var cursorStyle = itemModel.getShallow('cursor');
      cursorStyle && el.attr('cursor', cursorStyle);
      var labelPositionOutside = isPolar ? isHorizontalOrRadial ? layout.r >= layout.r0 ? 'endArc' : 'startArc' : layout.endAngle >= layout.startAngle ? 'endAngle' : 'startAngle' : isHorizontalOrRadial ? layout.height >= 0 ? 'bottom' : 'top' : layout.width >= 0 ? 'right' : 'left';
      var labelStatesModels = getLabelStatesModels(itemModel);
      setLabelStyle(el, labelStatesModels, {
        labelFetcher: seriesModel,
        labelDataIndex: dataIndex,
        defaultText: getDefaultLabel(seriesModel.getData(), dataIndex),
        inheritColor: style.fill,
        defaultOpacity: style.opacity,
        defaultOutsidePosition: labelPositionOutside
      });
      var label = el.getTextContent();

      if (isPolar && label) {
        var position = itemModel.get(['label', 'position']);
        el.textConfig.inside = position === 'middle' ? true : null;
        setSectorTextRotation(el, position === 'outside' ? labelPositionOutside : position, createPolarPositionMapping(isHorizontalOrRadial), itemModel.get(['label', 'rotate']));
      }

      setLabelValueAnimation(label, labelStatesModels, seriesModel.getRawValue(dataIndex), function (value) {
        return getDefaultInterpolatedLabel(data, value);
      });
      var emphasisModel = itemModel.getModel(['emphasis']);
      toggleHoverEmphasis(el, emphasisModel.get('focus'), emphasisModel.get('blurScope'), emphasisModel.get('disabled'));
      setStatesStylesFromModel(el, itemModel);

      if (isZeroOnPolar(layout)) {
        el.style.fill = 'none';
        el.style.stroke = 'none';
        each(el.states, function (state) {
          if (state.style) {
            state.style.fill = state.style.stroke = 'none';
          }
        });
      }
    } // In case width or height are too small.


    function getLineWidth(itemModel, rawLayout) {
      // Has no border.
      var borderColor = itemModel.get(['itemStyle', 'borderColor']);

      if (!borderColor || borderColor === 'none') {
        return 0;
      }

      var lineWidth = itemModel.get(['itemStyle', 'borderWidth']) || 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 LagePathShape =
    /** @class */
    function () {
      function LagePathShape() {}

      return LagePathShape;
    }();

    var LargePath =
    /** @class */
    function (_super) {
      __extends(LargePath, _super);

      function LargePath(opts) {
        var _this = _super.call(this, opts) || this;

        _this.type = 'largeBar';
        return _this;
      }

      LargePath.prototype.getDefaultShape = function () {
        return new LagePathShape();
      };

      LargePath.prototype.buildPath = function (ctx, shape) {
        // Drawing lines is more efficient than drawing
        // a whole line or drawing rects.
        var points = shape.points;
        var baseDimIdx = this.baseDimIdx;
        var valueDimIdx = 1 - this.baseDimIdx;
        var startPoint = [];
        var size = [];
        var barWidth = this.barWidth;

        for (var i = 0; i < points.length; i += 3) {
          size[baseDimIdx] = barWidth;
          size[valueDimIdx] = points[i + 2];
          startPoint[baseDimIdx] = points[i + baseDimIdx];
          startPoint[valueDimIdx] = points[i + valueDimIdx];
          ctx.rect(startPoint[0], startPoint[1], size[0], size[1]);
        }
      };

      return LargePath;
    }(Path);

    function createLarge(seriesModel, group, progressiveEls, incremental) {
      // TODO support polar
      var data = seriesModel.getData();
      var baseDimIdx = data.getLayout('valueAxisHorizontal') ? 1 : 0;
      var largeDataIndices = data.getLayout('largeDataIndices');
      var barWidth = data.getLayout('size');
      var backgroundModel = seriesModel.getModel('backgroundStyle');
      var bgPoints = data.getLayout('largeBackgroundPoints');

      if (bgPoints) {
        var bgEl = new LargePath({
          shape: {
            points: bgPoints
          },
          incremental: !!incremental,
          silent: true,
          z2: 0
        });
        bgEl.baseDimIdx = baseDimIdx;
        bgEl.largeDataIndices = largeDataIndices;
        bgEl.barWidth = barWidth;
        bgEl.useStyle(backgroundModel.getItemStyle());
        group.add(bgEl);
        progressiveEls && progressiveEls.push(bgEl);
      }

      var el = new LargePath({
        shape: {
          points: data.getLayout('largePoints')
        },
        incremental: !!incremental,
        ignoreCoarsePointer: true,
        z2: 1
      });
      el.baseDimIdx = baseDimIdx;
      el.largeDataIndices = largeDataIndices;
      el.barWidth = barWidth;
      group.add(el);
      el.useStyle(data.getVisual('style')); // Enable tooltip and user mouse/touch event handlers.

      getECData(el).seriesIndex = seriesModel.seriesIndex;

      if (!seriesModel.get('silent')) {
        el.on('mousedown', largePathUpdateDataIndex);
        el.on('mousemove', largePathUpdateDataIndex);
      }

      progressiveEls && progressiveEls.push(el);
    } // 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);
      getECData(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 startPoint = [];
      var size = [];
      var barWidth = largePath.barWidth;

      for (var i = 0, len = points.length / 3; i < len; i++) {
        var ii = i * 3;
        size[baseDimIdx] = barWidth;
        size[valueDimIdx] = points[ii + 2];
        startPoint[baseDimIdx] = points[ii + baseDimIdx];
        startPoint[valueDimIdx] = points[ii + valueDimIdx];

        if (size[valueDimIdx] < 0) {
          startPoint[valueDimIdx] += size[valueDimIdx];
          size[valueDimIdx] = -size[valueDimIdx];
        }

        if (x >= startPoint[0] && x <= startPoint[0] + size[0] && y >= startPoint[1] && y <= startPoint[1] + size[1]) {
          return largeDataIndices[i];
        }
      }

      return -1;
    }

    function createBackgroundShape(isHorizontalOrRadial, layout, coord) {
      if (isCoordinateSystemType(coord, 'cartesian2d')) {
        var rectShape = layout;
        var coordLayout = coord.getArea();
        return {
          x: isHorizontalOrRadial ? rectShape.x : coordLayout.x,
          y: isHorizontalOrRadial ? coordLayout.y : rectShape.y,
          width: isHorizontalOrRadial ? rectShape.width : coordLayout.width,
          height: isHorizontalOrRadial ? coordLayout.height : rectShape.height
        };
      } else {
        var coordLayout = coord.getArea();
        var sectorShape = layout;
        return {
          cx: coordLayout.cx,
          cy: coordLayout.cy,
          r0: isHorizontalOrRadial ? coordLayout.r0 : sectorShape.r0,
          r: isHorizontalOrRadial ? coordLayout.r : sectorShape.r,
          startAngle: isHorizontalOrRadial ? sectorShape.startAngle : 0,
          endAngle: isHorizontalOrRadial ? sectorShape.endAngle : Math.PI * 2
        };
      }
    }

    function createBackgroundEl(coord, isHorizontalOrRadial, layout) {
      var ElementClz = coord.type === 'polar' ? Sector : Rect;
      return new ElementClz({
        shape: createBackgroundShape(isHorizontalOrRadial, layout, coord),
        silent: true,
        z2: 0
      });
    }

    function install$3(registers) {
      registers.registerChartView(BarView);
      registers.registerSeriesModel(BarSeriesModel);
      registers.registerLayout(registers.PRIORITY.VISUAL.LAYOUT, curry(layout, 'bar')); // Do layout after other overall layout, which can prepare some information.

      registers.registerLayout(registers.PRIORITY.VISUAL.PROGRESSIVE_LAYOUT, createProgressiveLayout('bar')); // Down sample after filter

      registers.registerProcessor(registers.PRIORITY.PROCESSOR.STATISTIC, dataSample('bar'));
      /**
       * @payload
       * @property {string} [componentType=series]
       * @property {number} [dx]
       * @property {number} [dy]
       * @property {number} [zoom]
       * @property {number} [originX]
       * @property {number} [originY]
       */

      registers.registerAction({
        type: 'changeAxisOrder',
        event: 'changeAxisOrder',
        update: 'update'
      }, function (payload, ecModel) {
        var componentType = payload.componentType || 'series';
        ecModel.eachComponent({
          mainType: componentType,
          query: payload
        }, function (componentModel) {
          if (payload.sortInfo) {
            componentModel.axis.setCategorySortInfo(payload.sortInfo);
          }
        });
      });
    }

    var PI2$8 = Math.PI * 2;
    var RADIAN = Math.PI / 180;

    function getViewRect(seriesModel, api) {
      return getLayoutRect(seriesModel.getBoxLayoutParams(), {
        width: api.getWidth(),
        height: api.getHeight()
      });
    }

    function getBasicPieLayout(seriesModel, api) {
      var viewRect = getViewRect(seriesModel, api); // center can be string or number when coordinateSystem is specified

      var center = seriesModel.get('center');
      var radius = seriesModel.get('radius');

      if (!isArray(radius)) {
        radius = [0, radius];
      }

      var width = parsePercent$1(viewRect.width, api.getWidth());
      var height = parsePercent$1(viewRect.height, api.getHeight());
      var size = Math.min(width, height);
      var r0 = parsePercent$1(radius[0], size / 2);
      var r = parsePercent$1(radius[1], size / 2);
      var cx;
      var cy;
      var coordSys = seriesModel.coordinateSystem;

      if (coordSys) {
        // percentage is not allowed when coordinate system is specified
        var point = coordSys.dataToPoint(center);
        cx = point[0] || 0;
        cy = point[1] || 0;
      } else {
        if (!isArray(center)) {
          center = [center, center];
        }

        cx = parsePercent$1(center[0], width) + viewRect.x;
        cy = parsePercent$1(center[1], height) + viewRect.y;
      }

      return {
        cx: cx,
        cy: cy,
        r0: r0,
        r: r
      };
    }
    function pieLayout(seriesType, ecModel, api) {
      ecModel.eachSeriesByType(seriesType, function (seriesModel) {
        var data = seriesModel.getData();
        var valueDim = data.mapDimension('value');
        var viewRect = getViewRect(seriesModel, api);

        var _a = getBasicPieLayout(seriesModel, api),
            cx = _a.cx,
            cy = _a.cy,
            r = _a.r,
            r0 = _a.r0;

        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$8;
        var valueSumLargerThanMinAngle = 0;
        var currentAngle = startAngle;
        var dir = clockwise ? 1 : -1;
        data.setLayout({
          viewRect: viewRect,
          r: r
        });
        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
            });
            return;
          } // FIXME 兼容 2.0 但是 roseType 是 area 的时候才是这样？


          if (roseType !== 'area') {
            angle = sum === 0 && stillShowZeroSum ? unitRadian : value * unitRadian;
          } else {
            angle = PI2$8 / 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
          });
          currentAngle = endAngle;
        }); // Some sector is constrained by minAngle
        // Rest sectors needs recalculate angle

        if (restAngle < PI2$8 && validDataCount) {
          // Average the angle if rest angle is not enough after all angles is
          // Constrained by minAngle
          if (restAngle <= 1e-3) {
            var angle_1 = PI2$8 / validDataCount;
            data.each(valueDim, function (value, idx) {
              if (!isNaN(value)) {
                var layout_1 = data.getItemLayout(idx);
                layout_1.angle = angle_1;
                layout_1.startAngle = startAngle + dir * idx * angle_1;
                layout_1.endAngle = startAngle + dir * (idx + 1) * angle_1;
              }
            });
          } else {
            unitRadian = restAngle / valueSumLargerThanMinAngle;
            currentAngle = startAngle;
            data.each(valueDim, function (value, idx) {
              if (!isNaN(value)) {
                var layout_2 = data.getItemLayout(idx);
                var angle = layout_2.angle === minAngle ? minAngle : value * unitRadian;
                layout_2.startAngle = currentAngle;
                layout_2.endAngle = currentAngle + dir * angle;
                currentAngle += dir * angle;
              }
            });
          }
        }
      });
    }

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


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * 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 dataFilter(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++) {
              // @ts-ignore FIXME: LegendModel
              if (!legendModels[i].isSelected(name)) {
                return false;
              }
            }

            return true;
          });
        }
      };
    }

    var RADIAN$1 = Math.PI / 180;

    function adjustSingleSide(list, cx, cy, r, dir, viewWidth, viewHeight, viewLeft, viewTop, farthestX) {
      if (list.length < 2) {
        return;
      }

      function recalculateXOnSemiToAlignOnEllipseCurve(semi) {
        var rB = semi.rB;
        var rB2 = rB * rB;

        for (var i = 0; i < semi.list.length; i++) {
          var item = semi.list[i];
          var dy = Math.abs(item.label.y - cy); // horizontal r is always same with original r because x is not changed.

          var rA = r + item.len;
          var rA2 = rA * rA; // Use ellipse implicit function to calculate x

          var dx = Math.sqrt((1 - Math.abs(dy * dy / rB2)) * rA2);
          var newX = cx + (dx + item.len2) * dir;
          var deltaX = newX - item.label.x;
          var newTargetWidth = item.targetTextWidth - deltaX * dir; // text x is changed, so need to recalculate width.

          constrainTextWidth(item, newTargetWidth, true);
          item.label.x = newX;
        }
      } // Adjust X based on the shifted y. Make tight labels aligned on an ellipse curve.


      function recalculateX(items) {
        // Extremes of
        var topSemi = {
          list: [],
          maxY: 0
        };
        var bottomSemi = {
          list: [],
          maxY: 0
        };

        for (var i = 0; i < items.length; i++) {
          if (items[i].labelAlignTo !== 'none') {
            continue;
          }

          var item = items[i];
          var semi = item.label.y > cy ? bottomSemi : topSemi;
          var dy = Math.abs(item.label.y - cy);

          if (dy >= semi.maxY) {
            var dx = item.label.x - cx - item.len2 * dir; // horizontal r is always same with original r because x is not changed.

            var rA = r + item.len; // Canculate rB based on the topest / bottemest label.

            var rB = Math.abs(dx) < rA ? Math.sqrt(dy * dy / (1 - dx * dx / rA / rA)) : rA;
            semi.rB = rB;
            semi.maxY = dy;
          }

          semi.list.push(item);
        }

        recalculateXOnSemiToAlignOnEllipseCurve(topSemi);
        recalculateXOnSemiToAlignOnEllipseCurve(bottomSemi);
      }

      var len = list.length;

      for (var i = 0; i < len; i++) {
        if (list[i].position === 'outer' && list[i].labelAlignTo === 'labelLine') {
          var dx = list[i].label.x - farthestX;
          list[i].linePoints[1][0] += dx;
          list[i].label.x = farthestX;
        }
      }

      if (shiftLayoutOnY(list, viewTop, viewTop + viewHeight)) {
        recalculateX(list);
      }
    }

    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++) {
        var label = labelLayoutList[i].label;

        if (isPositionCenter(labelLayoutList[i])) {
          continue;
        }

        if (label.x < cx) {
          leftmostX = Math.min(leftmostX, label.x);
          leftList.push(labelLayoutList[i]);
        } else {
          rightmostX = Math.max(rightmostX, label.x);
          rightList.push(labelLayoutList[i]);
        }
      }

      for (var i = 0; i < labelLayoutList.length; i++) {
        var layout = labelLayoutList[i];

        if (!isPositionCenter(layout) && layout.linePoints) {
          if (layout.labelStyleWidth != null) {
            continue;
          }

          var label = layout.label;
          var linePoints = layout.linePoints;
          var targetTextWidth = void 0;

          if (layout.labelAlignTo === 'edge') {
            if (label.x < cx) {
              targetTextWidth = linePoints[2][0] - layout.labelDistance - viewLeft - layout.edgeDistance;
            } else {
              targetTextWidth = viewLeft + viewWidth - layout.edgeDistance - linePoints[2][0] - layout.labelDistance;
            }
          } else if (layout.labelAlignTo === 'labelLine') {
            if (label.x < cx) {
              targetTextWidth = leftmostX - viewLeft - layout.bleedMargin;
            } else {
              targetTextWidth = viewLeft + viewWidth - rightmostX - layout.bleedMargin;
            }
          } else {
            if (label.x < cx) {
              targetTextWidth = label.x - viewLeft - layout.bleedMargin;
            } else {
              targetTextWidth = viewLeft + viewWidth - label.x - layout.bleedMargin;
            }
          }

          layout.targetTextWidth = targetTextWidth;
          constrainTextWidth(layout, targetTextWidth);
        }
      }

      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) && layout.linePoints) {
          var label = layout.label;
          var linePoints = layout.linePoints;
          var isAlignToEdge = layout.labelAlignTo === 'edge';
          var padding = label.style.padding;
          var paddingH = padding ? padding[1] + padding[3] : 0; // textRect.width already contains paddingH if bgColor is set

          var extraPaddingH = label.style.backgroundColor ? 0 : paddingH;
          var realTextWidth = layout.rect.width + extraPaddingH;
          var dist = linePoints[1][0] - linePoints[2][0];

          if (isAlignToEdge) {
            if (label.x < cx) {
              linePoints[2][0] = viewLeft + layout.edgeDistance + realTextWidth + layout.labelDistance;
            } else {
              linePoints[2][0] = viewLeft + viewWidth - layout.edgeDistance - realTextWidth - layout.labelDistance;
            }
          } else {
            if (label.x < cx) {
              linePoints[2][0] = label.x + layout.labelDistance;
            } else {
              linePoints[2][0] = label.x - layout.labelDistance;
            }

            linePoints[1][0] = linePoints[2][0] + dist;
          }

          linePoints[1][1] = linePoints[2][1] = label.y;
        }
      }
    }
    /**
     * Set max width of each label, and then wrap each label to the max width.
     *
     * @param layout label layout
     * @param availableWidth max width for the label to display
     * @param forceRecalculate recaculate the text layout even if the current width
     * is smaller than `availableWidth`. This is useful when the text was previously
     * wrapped by calling `constrainTextWidth` but now `availableWidth` changed, in
     * which case, previous wrapping should be redo.
     */


    function constrainTextWidth(layout, availableWidth, forceRecalculate) {
      if (forceRecalculate === void 0) {
        forceRecalculate = false;
      }

      if (layout.labelStyleWidth != null) {
        // User-defined style.width has the highest priority.
        return;
      }

      var label = layout.label;
      var style = label.style;
      var textRect = layout.rect;
      var bgColor = style.backgroundColor;
      var padding = style.padding;
      var paddingH = padding ? padding[1] + padding[3] : 0;
      var overflow = style.overflow; // textRect.width already contains paddingH if bgColor is set

      var oldOuterWidth = textRect.width + (bgColor ? 0 : paddingH);

      if (availableWidth < oldOuterWidth || forceRecalculate) {
        var oldHeight = textRect.height;

        if (overflow && overflow.match('break')) {
          // Temporarily set background to be null to calculate
          // the bounding box without background.
          label.setStyle('backgroundColor', null); // Set constraining width

          label.setStyle('width', availableWidth - paddingH); // This is the real bounding box of the text without padding.

          var innerRect = label.getBoundingRect();
          label.setStyle('width', Math.ceil(innerRect.width));
          label.setStyle('backgroundColor', bgColor);
        } else {
          var availableInnerWidth = availableWidth - paddingH;
          var newWidth = availableWidth < oldOuterWidth // Current text is too wide, use `availableWidth` as max width.
          ? availableInnerWidth : // Current available width is enough, but the text may have
          // already been wrapped with a smaller available width.
          forceRecalculate ? availableInnerWidth > layout.unconstrainedWidth // Current available is larger than text width,
          // so don't constrain width (otherwise it may have
          // empty space in the background).
          ? null // Current available is smaller than text width, so
          // use the current available width as constraining
          // width.
          : availableInnerWidth : // Current available width is enough, so no need to
          // constrain.
          null;
          label.setStyle('width', newWidth);
        }

        var newRect = label.getBoundingRect();
        textRect.width = newRect.width;
        var margin = (label.style.margin || 0) + 2.1;
        textRect.height = newRect.height + margin;
        textRect.y -= (textRect.height - oldHeight) / 2;
      }
    }

    function isPositionCenter(sectorShape) {
      // Not change x for center label
      return sectorShape.position === 'center';
    }

    function pieLabelLayout(seriesModel) {
      var data = seriesModel.getData();
      var labelLayoutList = [];
      var cx;
      var cy;
      var hasLabelRotate = false;
      var minShowLabelRadian = (seriesModel.get('minShowLabelAngle') || 0) * RADIAN$1;
      var viewRect = data.getLayout('viewRect');
      var r = data.getLayout('r');
      var viewWidth = viewRect.width;
      var viewLeft = viewRect.x;
      var viewTop = viewRect.y;
      var viewHeight = viewRect.height;

      function setNotShow(el) {
        el.ignore = true;
      }

      function isLabelShown(label) {
        if (!label.ignore) {
          return true;
        }

        for (var key in label.states) {
          if (label.states[key].ignore === false) {
            return true;
          }
        }

        return false;
      }

      data.each(function (idx) {
        var sector = data.getItemGraphicEl(idx);
        var sectorShape = sector.shape;
        var label = sector.getTextContent();
        var labelLine = sector.getTextGuideLine();
        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 edgeDistance = parsePercent$1(labelModel.get('edgeDistance'), viewWidth);
        var bleedMargin = labelModel.get('bleedMargin');
        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 (Math.abs(sectorShape.endAngle - sectorShape.startAngle) < minShowLabelRadian) {
          each(label.states, setNotShow);
          label.ignore = true;

          if (labelLine) {
            each(labelLine.states, setNotShow);
            labelLine.ignore = true;
          }

          return;
        }

        if (!isLabelShown(label)) {
          return;
        }

        var midAngle = (sectorShape.startAngle + sectorShape.endAngle) / 2;
        var nx = Math.cos(midAngle);
        var ny = Math.sin(midAngle);
        var textX;
        var textY;
        var linePoints;
        var textAlign;
        cx = sectorShape.cx;
        cy = sectorShape.cy;
        var isLabelInside = labelPosition === 'inside' || labelPosition === 'inner';

        if (labelPosition === 'center') {
          textX = sectorShape.cx;
          textY = sectorShape.cy;
          textAlign = 'center';
        } else {
          var x1 = (isLabelInside ? (sectorShape.r + sectorShape.r0) / 2 * nx : sectorShape.r * nx) + cx;
          var y1 = (isLabelInside ? (sectorShape.r + sectorShape.r0) / 2 * ny : sectorShape.r * ny) + cy;
          textX = x1 + nx * 3;
          textY = y1 + ny * 3;

          if (!isLabelInside) {
            // For roseType
            var x2 = x1 + nx * (labelLineLen + r - sectorShape.r);
            var y2 = y1 + ny * (labelLineLen + r - sectorShape.r);
            var x3 = x2 + (nx < 0 ? -1 : 1) * labelLineLen2;
            var y3 = y2;

            if (labelAlignTo === 'edge') {
              // Adjust textX because text align of edge is opposite
              textX = nx < 0 ? viewLeft + edgeDistance : viewLeft + viewWidth - edgeDistance;
            } else {
              textX = x3 + (nx < 0 ? -labelDistance : labelDistance);
            }

            textY = y3;
            linePoints = [[x1, y1], [x2, y2], [x3, y3]];
          }

          textAlign = isLabelInside ? 'center' : labelAlignTo === 'edge' ? nx > 0 ? 'right' : 'left' : nx > 0 ? 'left' : 'right';
        }

        var PI = Math.PI;
        var labelRotate = 0;
        var rotate = labelModel.get('rotate');

        if (isNumber(rotate)) {
          labelRotate = rotate * (PI / 180);
        } else if (labelPosition === 'center') {
          labelRotate = 0;
        } else if (rotate === 'radial' || rotate === true) {
          var radialAngle = nx < 0 ? -midAngle + PI : -midAngle;
          labelRotate = radialAngle;
        } else if (rotate === 'tangential' && labelPosition !== 'outside' && labelPosition !== 'outer') {
          var rad = Math.atan2(nx, ny);

          if (rad < 0) {
            rad = PI * 2 + rad;
          }

          var isDown = ny > 0;

          if (isDown) {
            rad = PI + rad;
          }

          labelRotate = rad - PI;
        }

        hasLabelRotate = !!labelRotate;
        label.x = textX;
        label.y = textY;
        label.rotation = labelRotate;
        label.setStyle({
          verticalAlign: 'middle'
        }); // Not sectorShape the inside label

        if (!isLabelInside) {
          var textRect = label.getBoundingRect().clone();
          textRect.applyTransform(label.getComputedTransform()); // Text has a default 1px stroke. Exclude this.

          var margin = (label.style.margin || 0) + 2.1;
          textRect.y -= margin / 2;
          textRect.height += margin;
          labelLayoutList.push({
            label: label,
            labelLine: labelLine,
            position: labelPosition,
            len: labelLineLen,
            len2: labelLineLen2,
            minTurnAngle: labelLineModel.get('minTurnAngle'),
            maxSurfaceAngle: labelLineModel.get('maxSurfaceAngle'),
            surfaceNormal: new Point(nx, ny),
            linePoints: linePoints,
            textAlign: textAlign,
            labelDistance: labelDistance,
            labelAlignTo: labelAlignTo,
            edgeDistance: edgeDistance,
            bleedMargin: bleedMargin,
            rect: textRect,
            unconstrainedWidth: textRect.width,
            labelStyleWidth: label.style.width
          });
        } else {
          label.setStyle({
            align: textAlign
          });
          var selectState = label.states.select;

          if (selectState) {
            selectState.x += label.x;
            selectState.y += label.y;
          }
        }

        sector.setTextConfig({
          inside: isLabelInside
        });
      });

      if (!hasLabelRotate && seriesModel.get('avoidLabelOverlap')) {
        avoidOverlap(labelLayoutList, cx, cy, r, viewWidth, viewHeight, viewLeft, viewTop);
      }

      for (var i = 0; i < labelLayoutList.length; i++) {
        var layout = labelLayoutList[i];
        var label = layout.label;
        var labelLine = layout.labelLine;
        var notShowLabel = isNaN(label.x) || isNaN(label.y);

        if (label) {
          label.setStyle({
            align: layout.textAlign
          });

          if (notShowLabel) {
            each(label.states, setNotShow);
            label.ignore = true;
          }

          var selectState = label.states.select;

          if (selectState) {
            selectState.x += label.x;
            selectState.y += label.y;
          }
        }

        if (labelLine) {
          var linePoints = layout.linePoints;

          if (notShowLabel || !linePoints) {
            each(labelLine.states, setNotShow);
            labelLine.ignore = true;
          } else {
            limitTurnAngle(linePoints, layout.minTurnAngle);
            limitSurfaceAngle(linePoints, layout.surfaceNormal, layout.maxSurfaceAngle);
            labelLine.setShape({
              points: linePoints
            }); // Set the anchor to the midpoint of sector

            label.__hostTarget.textGuideLineConfig = {
              anchor: new Point(linePoints[0][0], linePoints[0][1])
            };
          }
        }
      }
    }

    function getSectorCornerRadius(model, shape, zeroIfNull) {
      var cornerRadius = model.get('borderRadius');

      if (cornerRadius == null) {
        return zeroIfNull ? {
          cornerRadius: 0
        } : null;
      }

      if (!isArray(cornerRadius)) {
        cornerRadius = [cornerRadius, cornerRadius, cornerRadius, cornerRadius];
      }

      var dr = Math.abs(shape.r || 0 - shape.r0 || 0);
      return {
        cornerRadius: map(cornerRadius, function (cr) {
          return parsePercent(cr, dr);
        })
      };
    }

    /**
     * Piece of pie including Sector, Label, LabelLine
     */

    var PiePiece =
    /** @class */
    function (_super) {
      __extends(PiePiece, _super);

      function PiePiece(data, idx, startAngle) {
        var _this = _super.call(this) || this;

        _this.z2 = 2;
        var text = new ZRText();

        _this.setTextContent(text);

        _this.updateData(data, idx, startAngle, true);

        return _this;
      }

      PiePiece.prototype.updateData = function (data, idx, startAngle, firstCreate) {
        var sector = this;
        var seriesModel = data.hostModel;
        var itemModel = data.getItemModel(idx);
        var emphasisModel = itemModel.getModel('emphasis');
        var layout = data.getItemLayout(idx); // cornerRadius & innerCornerRadius doesn't exist in the item layout. Use `0` if null value is specified.
        // see `setItemLayout` in `pieLayout.ts`.

        var sectorShape = extend(getSectorCornerRadius(itemModel.getModel('itemStyle'), layout, true), layout); // Ignore NaN data.

        if (isNaN(sectorShape.startAngle)) {
          // Use NaN shape to avoid drawing shape.
          sector.setShape(sectorShape);
          return;
        }

        if (firstCreate) {
          sector.setShape(sectorShape);
          var animationType = seriesModel.getShallow('animationType');

          if (seriesModel.ecModel.ssr) {
            // Use scale animation in SSR mode(opacity?)
            // Because CSS SVG animation doesn't support very customized shape animation.
            initProps(sector, {
              scaleX: 0,
              scaleY: 0
            }, seriesModel, {
              dataIndex: idx,
              isFrom: true
            });
            sector.originX = sectorShape.cx;
            sector.originY = sectorShape.cy;
          } else if (animationType === 'scale') {
            sector.shape.r = layout.r0;
            initProps(sector, {
              shape: {
                r: layout.r
              }
            }, seriesModel, idx);
          } // Expansion
          else {
              if (startAngle != null) {
                sector.setShape({
                  startAngle: startAngle,
                  endAngle: startAngle
                });
                initProps(sector, {
                  shape: {
                    startAngle: layout.startAngle,
                    endAngle: layout.endAngle
                  }
                }, seriesModel, idx);
              } else {
                sector.shape.endAngle = layout.startAngle;
                updateProps(sector, {
                  shape: {
                    endAngle: layout.endAngle
                  }
                }, seriesModel, idx);
              }
            }
        } else {
          saveOldStyle(sector); // Transition animation from the old shape

          updateProps(sector, {
            shape: sectorShape
          }, seriesModel, idx);
        }

        sector.useStyle(data.getItemVisual(idx, 'style'));
        setStatesStylesFromModel(sector, itemModel);
        var midAngle = (layout.startAngle + layout.endAngle) / 2;
        var offset = seriesModel.get('selectedOffset');
        var dx = Math.cos(midAngle) * offset;
        var dy = Math.sin(midAngle) * offset;
        var cursorStyle = itemModel.getShallow('cursor');
        cursorStyle && sector.attr('cursor', cursorStyle);

        this._updateLabel(seriesModel, data, idx);

        sector.ensureState('emphasis').shape = extend({
          r: layout.r + (emphasisModel.get('scale') ? emphasisModel.get('scaleSize') || 0 : 0)
        }, getSectorCornerRadius(emphasisModel.getModel('itemStyle'), layout));
        extend(sector.ensureState('select'), {
          x: dx,
          y: dy,
          shape: getSectorCornerRadius(itemModel.getModel(['select', 'itemStyle']), layout)
        });
        extend(sector.ensureState('blur'), {
          shape: getSectorCornerRadius(itemModel.getModel(['blur', 'itemStyle']), layout)
        });
        var labelLine = sector.getTextGuideLine();
        var labelText = sector.getTextContent();
        labelLine && extend(labelLine.ensureState('select'), {
          x: dx,
          y: dy
        }); // TODO: needs dx, dy in zrender?

        extend(labelText.ensureState('select'), {
          x: dx,
          y: dy
        });
        toggleHoverEmphasis(this, emphasisModel.get('focus'), emphasisModel.get('blurScope'), emphasisModel.get('disabled'));
      };

      PiePiece.prototype._updateLabel = function (seriesModel, data, idx) {
        var sector = this;
        var itemModel = data.getItemModel(idx);
        var labelLineModel = itemModel.getModel('labelLine');
        var style = data.getItemVisual(idx, 'style');
        var visualColor = style && style.fill;
        var visualOpacity = style && style.opacity;
        setLabelStyle(sector, getLabelStatesModels(itemModel), {
          labelFetcher: data.hostModel,
          labelDataIndex: idx,
          inheritColor: visualColor,
          defaultOpacity: visualOpacity,
          defaultText: seriesModel.getFormattedLabel(idx, 'normal') || data.getName(idx)
        });
        var labelText = sector.getTextContent(); // Set textConfig on sector.

        sector.setTextConfig({
          // reset position, rotation
          position: null,
          rotation: null
        }); // Make sure update style on labelText after setLabelStyle.
        // Because setLabelStyle will replace a new style on it.

        labelText.attr({
          z2: 10
        });
        var labelPosition = seriesModel.get(['label', 'position']);

        if (labelPosition !== 'outside' && labelPosition !== 'outer') {
          sector.removeTextGuideLine();
        } else {
          var polyline = this.getTextGuideLine();

          if (!polyline) {
            polyline = new Polyline();
            this.setTextGuideLine(polyline);
          } // Default use item visual color


          setLabelLineStyle(this, getLabelLineStatesModels(itemModel), {
            stroke: visualColor,
            opacity: retrieve3(labelLineModel.get(['lineStyle', 'opacity']), visualOpacity, 1)
          });
        }
      };

      return PiePiece;
    }(Sector); // Pie view


    var PieView =
    /** @class */
    function (_super) {
      __extends(PieView, _super);

      function PieView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.ignoreLabelLineUpdate = true;
        return _this;
      }

      PieView.prototype.render = function (seriesModel, ecModel, api, payload) {
        var data = seriesModel.getData();
        var oldData = this._data;
        var group = this.group;
        var startAngle; // First render

        if (!oldData && data.count() > 0) {
          var shape = data.getItemLayout(0);

          for (var s = 1; isNaN(shape && shape.startAngle) && s < data.count(); ++s) {
            shape = data.getItemLayout(s);
          }

          if (shape) {
            startAngle = shape.startAngle;
          }
        } // remove empty-circle if it exists


        if (this._emptyCircleSector) {
          group.remove(this._emptyCircleSector);
        } // when all data are filtered, show lightgray empty circle


        if (data.count() === 0 && seriesModel.get('showEmptyCircle')) {
          var sector = new Sector({
            shape: getBasicPieLayout(seriesModel, api)
          });
          sector.useStyle(seriesModel.getModel('emptyCircleStyle').getItemStyle());
          this._emptyCircleSector = sector;
          group.add(sector);
        }

        data.diff(oldData).add(function (idx) {
          var piePiece = new PiePiece(data, idx, startAngle);
          data.setItemGraphicEl(idx, piePiece);
          group.add(piePiece);
        }).update(function (newIdx, oldIdx) {
          var piePiece = oldData.getItemGraphicEl(oldIdx);
          piePiece.updateData(data, newIdx, startAngle);
          piePiece.off('click');
          group.add(piePiece);
          data.setItemGraphicEl(newIdx, piePiece);
        }).remove(function (idx) {
          var piePiece = oldData.getItemGraphicEl(idx);
          removeElementWithFadeOut(piePiece, seriesModel, idx);
        }).execute();
        pieLabelLayout(seriesModel); // Always use initial animation.

        if (seriesModel.get('animationTypeUpdate') !== 'expansion') {
          this._data = data;
        }
      };

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

      PieView.prototype.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;
        }
      };

      PieView.type = 'pie';
      return PieView;
    }(ChartView);

    /**
     * [Usage]:
     * (1)
     * createListSimply(seriesModel, ['value']);
     * (2)
     * createListSimply(seriesModel, {
     *     coordDimensions: ['value'],
     *     dimensionsCount: 5
     * });
     */

    function createSeriesDataSimply(seriesModel, opt, nameList) {
      opt = isArray(opt) && {
        coordDimensions: opt
      } || extend({
        encodeDefine: seriesModel.getEncode()
      }, opt);
      var source = seriesModel.getSource();
      var dimensions = prepareSeriesDataSchema(source, opt).dimensions;
      var list = new SeriesData(dimensions, 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.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * 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.
     */
    var LegendVisualProvider =
    /** @class */
    function () {
      function LegendVisualProvider( // Function to get data after filtered. It stores all the encoding info
      getDataWithEncodedVisual, // Function to get raw data before filtered.
      getRawData) {
        this._getDataWithEncodedVisual = getDataWithEncodedVisual;
        this._getRawData = getRawData;
      }

      LegendVisualProvider.prototype.getAllNames = function () {
        var rawData = this._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);
      };

      LegendVisualProvider.prototype.containName = function (name) {
        var rawData = this._getRawData();

        return rawData.indexOfName(name) >= 0;
      };

      LegendVisualProvider.prototype.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 = this._getDataWithEncodedVisual();

        return dataWithEncodedVisual.indexOfName(name);
      };

      LegendVisualProvider.prototype.getItemVisual = function (dataIndex, key) {
        // Get encoded visual properties from final filtered data.
        var dataWithEncodedVisual = this._getDataWithEncodedVisual();

        return dataWithEncodedVisual.getItemVisual(dataIndex, key);
      };

      return LegendVisualProvider;
    }();

    var innerData = makeInner();

    var PieSeriesModel =
    /** @class */
    function (_super) {
      __extends(PieSeriesModel, _super);

      function PieSeriesModel() {
        return _super !== null && _super.apply(this, arguments) || this;
      }
      /**
       * @overwrite
       */


      PieSeriesModel.prototype.init = function (option) {
        _super.prototype.init.apply(this, 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._defaultLabelLine(option);
      };
      /**
       * @overwrite
       */


      PieSeriesModel.prototype.mergeOption = function () {
        _super.prototype.mergeOption.apply(this, arguments);
      };
      /**
       * @overwrite
       */


      PieSeriesModel.prototype.getInitialData = function () {
        return createSeriesDataSimply(this, {
          coordDimensions: ['value'],
          encodeDefaulter: curry(makeSeriesEncodeForNameBased, this)
        });
      };
      /**
       * @overwrite
       */


      PieSeriesModel.prototype.getDataParams = function (dataIndex) {
        var data = this.getData(); // update seats when data is changed

        var dataInner = innerData(data);
        var seats = dataInner.seats;

        if (!seats) {
          var valueList_1 = [];
          data.each(data.mapDimension('value'), function (value) {
            valueList_1.push(value);
          });
          seats = dataInner.seats = getPercentSeats(valueList_1, data.hostModel.get('percentPrecision'));
        }

        var params = _super.prototype.getDataParams.call(this, dataIndex); // seats may be empty when sum is 0


        params.percent = seats[dataIndex] || 0;
        params.$vars.push('percent');
        return params;
      };

      PieSeriesModel.prototype._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;
      };

      PieSeriesModel.type = 'series.pie';
      PieSeriesModel.defaultOption = {
        // zlevel: 0,
        z: 2,
        legendHoverLink: true,
        colorBy: 'data',
        // 默认全局居中
        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,
        // 选择模式，默认关闭，可选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: {
          // color: 'inherit',
          // If rotate around circle
          rotate: 0,
          show: true,
          overflow: 'truncate',
          // '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'.
          edgeDistance: '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,
          minTurnAngle: 90,
          maxSurfaceAngle: 90,
          lineStyle: {
            // color: 各异,
            width: 1,
            type: 'solid'
          }
        },
        itemStyle: {
          borderWidth: 1,
          borderJoin: 'round'
        },
        showEmptyCircle: true,
        emptyCircleStyle: {
          color: 'lightgray',
          opacity: 1
        },
        labelLayout: {
          // Hide the overlapped label.
          hideOverlap: true
        },
        emphasis: {
          scale: true,
          scaleSize: 5
        },
        // If use strategy to avoid label overlapping
        avoidLabelOverlap: true,
        // Animation type. Valid values: expansion, scale
        animationType: 'expansion',
        animationDuration: 1000,
        // Animation type when update. Valid values: transition, expansion
        animationTypeUpdate: 'transition',
        animationEasingUpdate: 'cubicInOut',
        animationDurationUpdate: 500,
        animationEasing: 'cubicInOut'
      };
      return PieSeriesModel;
    }(SeriesModel);

    function negativeDataFilter(seriesType) {
      return {
        seriesType: seriesType,
        reset: function (seriesModel, ecModel) {
          var data = seriesModel.getData();
          data.filterSelf(function (idx) {
            // handle negative value condition
            var valueDim = data.mapDimension('value');
            var curValue = data.get(valueDim, idx);

            if (isNumber(curValue) && !isNaN(curValue) && curValue < 0) {
              return false;
            }

            return true;
          });
        }
      };
    }

    function install$4(registers) {
      registers.registerChartView(PieView);
      registers.registerSeriesModel(PieSeriesModel);
      createLegacyDataSelectAction('pie', registers.registerAction);
      registers.registerLayout(curry(pieLayout, 'pie'));
      registers.registerProcessor(dataFilter('pie'));
      registers.registerProcessor(negativeDataFilter('pie'));
    }

    var ScatterSeriesModel =
    /** @class */
    function (_super) {
      __extends(ScatterSeriesModel, _super);

      function ScatterSeriesModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = ScatterSeriesModel.type;
        _this.hasSymbolVisual = true;
        return _this;
      }

      ScatterSeriesModel.prototype.getInitialData = function (option, ecModel) {
        return createSeriesData(null, this, {
          useEncodeDefaulter: true
        });
      };

      ScatterSeriesModel.prototype.getProgressive = function () {
        var progressive = this.option.progressive;

        if (progressive == null) {
          // PENDING
          return this.option.large ? 5e3 : this.get('progressive');
        }

        return progressive;
      };

      ScatterSeriesModel.prototype.getProgressiveThreshold = function () {
        var progressiveThreshold = this.option.progressiveThreshold;

        if (progressiveThreshold == null) {
          // PENDING
          return this.option.large ? 1e4 : this.get('progressiveThreshold');
        }

        return progressiveThreshold;
      };

      ScatterSeriesModel.prototype.brushSelector = function (dataIndex, data, selectors) {
        return selectors.point(data.getItemLayout(dataIndex));
      };

      ScatterSeriesModel.prototype.getZLevelKey = function () {
        // Each progressive series has individual key.
        return this.getData().count() > this.getProgressiveThreshold() ? this.id : '';
      };

      ScatterSeriesModel.type = 'series.scatter';
      ScatterSeriesModel.dependencies = ['grid', 'polar', 'geo', 'singleAxis', 'calendar'];
      ScatterSeriesModel.defaultOption = {
        coordinateSystem: 'cartesian2d',
        // zlevel: 0,
        z: 2,
        legendHoverLink: true,
        symbolSize: 10,
        // symbolRotate: null,  // 图形旋转控制
        large: false,
        // Available when large is true
        largeThreshold: 2000,
        // cursor: null,
        itemStyle: {
          opacity: 0.8 // color: 各异

        },
        emphasis: {
          scale: true
        },
        // If clip the overflow graphics
        // Works on cartesian / polar series
        clip: true,
        select: {
          itemStyle: {
            borderColor: '#212121'
          }
        },
        universalTransition: {
          divideShape: 'clone'
        } // progressive: null

      };
      return ScatterSeriesModel;
    }(SeriesModel);

    var BOOST_SIZE_THRESHOLD = 4;

    var LargeSymbolPathShape =
    /** @class */
    function () {
      function LargeSymbolPathShape() {}

      return LargeSymbolPathShape;
    }();

    var LargeSymbolPath =
    /** @class */
    function (_super) {
      __extends(LargeSymbolPath, _super);

      function LargeSymbolPath(opts) {
        var _this = _super.call(this, opts) || this;

        _this._off = 0;
        _this.hoverDataIdx = -1;
        return _this;
      }

      LargeSymbolPath.prototype.getDefaultShape = function () {
        return new LargeSymbolPathShape();
      };

      LargeSymbolPath.prototype.reset = function () {
        this.notClear = false;
        this._off = 0;
      };

      LargeSymbolPath.prototype.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;
        var softClipShape = this.softClipShape;
        var i; // Do draw in afterBrush.

        if (canBoost) {
          this._ctx = ctx;
          return;
        }

        this._ctx = null;

        for (i = this._off; i < points.length;) {
          var x = points[i++];
          var y = points[i++];

          if (isNaN(x) || isNaN(y)) {
            continue;
          }

          if (softClipShape && !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);
        }

        if (this.incremental) {
          this._off = i;
          this.notClear = true;
        }
      };

      LargeSymbolPath.prototype.afterBrush = function () {
        var shape = this.shape;
        var points = shape.points;
        var size = shape.size;
        var ctx = this._ctx;
        var softClipShape = this.softClipShape;
        var i;

        if (!ctx) {
          return;
        } // PENDING If style or other canvas status changed?


        for (i = this._off; i < points.length;) {
          var x = points[i++];
          var y = points[i++];

          if (isNaN(x) || isNaN(y)) {
            continue;
          }

          if (softClipShape && !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]);
        }

        if (this.incremental) {
          this._off = i;
          this.notClear = true;
        }
      };

      LargeSymbolPath.prototype.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;
      };

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

        if (rect.contain(x, y)) {
          // Cache found data index.
          var dataIdx = this.hoverDataIdx = this.findDataIndex(x, y);
          return dataIdx >= 0;
        }

        this.hoverDataIdx = -1;
        return false;
      };

      LargeSymbolPath.prototype.getBoundingRect = function () {
        // Ignore stroke for large symbol draw.
        var rect = this._rect;

        if (!rect) {
          var shape = this.shape;
          var points = shape.points;
          var size = shape.size;
          var w = size[0];
          var h = size[1];
          var minX = Infinity;
          var minY = Infinity;
          var maxX = -Infinity;
          var maxY = -Infinity;

          for (var i = 0; i < points.length;) {
            var x = points[i++];
            var y = points[i++];
            minX = Math.min(x, minX);
            maxX = Math.max(x, maxX);
            minY = Math.min(y, minY);
            maxY = Math.max(y, maxY);
          }

          rect = this._rect = new BoundingRect(minX - w / 2, minY - h / 2, maxX - minX + w, maxY - minY + h);
        }

        return rect;
      };

      return LargeSymbolPath;
    }(Path);

    var LargeSymbolDraw =
    /** @class */
    function () {
      function LargeSymbolDraw() {
        this.group = new Group();
      }
      /**
       * Update symbols draw by new data
       */


      LargeSymbolDraw.prototype.updateData = function (data, opt) {
        this._clear();

        var symbolEl = this._create();

        symbolEl.setShape({
          points: data.getLayout('points')
        });

        this._setCommon(symbolEl, data, opt);
      };

      LargeSymbolDraw.prototype.updateLayout = function (data) {
        var points = data.getLayout('points');
        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); // Reset draw cursor.

          child.reset();
        });
      };

      LargeSymbolDraw.prototype.incrementalPrepareUpdate = function (data) {
        this._clear();
      };

      LargeSymbolDraw.prototype.incrementalUpdate = function (taskParams, data, opt) {
        var lastAdded = this._newAdded[0];
        var points = data.getLayout('points');
        var oldPoints = lastAdded && lastAdded.shape.points; // Merging the exists. Each element has 1e4 points.
        // Consider the performance balance between too much elements and too much points in one shape(may affect hover optimization)

        if (oldPoints && oldPoints.length < 2e4) {
          var oldLen = oldPoints.length;
          var newPoints = new Float32Array(oldLen + points.length); // Concat two array

          newPoints.set(oldPoints);
          newPoints.set(points, oldLen); // Update endIndex

          lastAdded.endIndex = taskParams.end;
          lastAdded.setShape({
            points: newPoints
          });
        } else {
          // Clear
          this._newAdded = [];

          var symbolEl = this._create();

          symbolEl.startIndex = taskParams.start;
          symbolEl.endIndex = taskParams.end;
          symbolEl.incremental = true;
          symbolEl.setShape({
            points: points
          });

          this._setCommon(symbolEl, data, opt);
        }
      };

      LargeSymbolDraw.prototype.eachRendered = function (cb) {
        this._newAdded[0] && cb(this._newAdded[0]);
      };

      LargeSymbolDraw.prototype._create = function () {
        var symbolEl = new LargeSymbolPath({
          cursor: 'default'
        });
        symbolEl.ignoreCoarsePointer = true;
        this.group.add(symbolEl);

        this._newAdded.push(symbolEl);

        return symbolEl;
      };

      LargeSymbolDraw.prototype._setCommon = function (symbolEl, data, opt) {
        var hostModel = data.hostModel;
        opt = opt || {};
        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 globalStyle = data.getVisual('style');
        var visualColor = globalStyle && globalStyle.fill;

        if (visualColor) {
          symbolEl.setColor(visualColor);
        }

        var ecData = getECData(symbolEl); // Enable tooltip
        // PENDING May have performance issue when path is extremely large

        ecData.seriesIndex = hostModel.seriesIndex;
        symbolEl.on('mousemove', function (e) {
          ecData.dataIndex = null;
          var dataIndex = symbolEl.hoverDataIdx;

          if (dataIndex >= 0) {
            // Provide dataIndex for tooltip
            ecData.dataIndex = dataIndex + (symbolEl.startIndex || 0);
          }
        });
      };

      LargeSymbolDraw.prototype.remove = function () {
        this._clear();
      };

      LargeSymbolDraw.prototype._clear = function () {
        this._newAdded = [];
        this.group.removeAll();
      };

      return LargeSymbolDraw;
    }();

    var ScatterView =
    /** @class */
    function (_super) {
      __extends(ScatterView, _super);

      function ScatterView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = ScatterView.type;
        return _this;
      }

      ScatterView.prototype.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;
      };

      ScatterView.prototype.incrementalPrepareRender = function (seriesModel, ecModel, api) {
        var data = seriesModel.getData();

        var symbolDraw = this._updateSymbolDraw(data, seriesModel);

        symbolDraw.incrementalPrepareUpdate(data);
        this._finished = false;
      };

      ScatterView.prototype.incrementalRender = function (taskParams, seriesModel, ecModel) {
        this._symbolDraw.incrementalUpdate(taskParams, seriesModel.getData(), {
          clipShape: this._getClipShape(seriesModel)
        });

        this._finished = taskParams.end === seriesModel.getData().count();
      };

      ScatterView.prototype.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) {
          return {
            update: true
          };
        } else {
          var res = pointsLayout('').reset(seriesModel, ecModel, api);

          if (res.progress) {
            res.progress({
              start: 0,
              end: data.count(),
              count: data.count()
            }, data);
          }

          this._symbolDraw.updateLayout(data);
        }
      };

      ScatterView.prototype.eachRendered = function (cb) {
        this._symbolDraw && this._symbolDraw.eachRendered(cb);
      };

      ScatterView.prototype._getClipShape = function (seriesModel) {
        var coordSys = seriesModel.coordinateSystem;
        var clipArea = coordSys && coordSys.getArea && coordSys.getArea();
        return seriesModel.get('clip', true) ? clipArea : null;
      };

      ScatterView.prototype._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;
      };

      ScatterView.prototype.remove = function (ecModel, api) {
        this._symbolDraw && this._symbolDraw.remove(true);
        this._symbolDraw = null;
      };

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

      ScatterView.type = 'scatter';
      return ScatterView;
    }(ChartView);

    var GridModel =
    /** @class */
    function (_super) {
      __extends(GridModel, _super);

      function GridModel() {
        return _super !== null && _super.apply(this, arguments) || this;
      }

      GridModel.type = 'grid';
      GridModel.dependencies = ['xAxis', 'yAxis'];
      GridModel.layoutMode = 'box';
      GridModel.defaultOption = {
        show: false,
        // zlevel: 0,
        z: 0,
        left: '10%',
        top: 60,
        right: '10%',
        bottom: 70,
        // 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'
      };
      return GridModel;
    }(ComponentModel);

    var CartesianAxisModel =
    /** @class */
    function (_super) {
      __extends(CartesianAxisModel, _super);

      function CartesianAxisModel() {
        return _super !== null && _super.apply(this, arguments) || this;
      }

      CartesianAxisModel.prototype.getCoordSysModel = function () {
        return this.getReferringComponents('grid', SINGLE_REFERRING).models[0];
      };

      CartesianAxisModel.type = 'cartesian2dAxis';
      return CartesianAxisModel;
    }(ComponentModel);
    mixin(CartesianAxisModel, AxisModelCommonMixin);

    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: '#6E7079',
          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: ['#E0E6F1'],
          width: 1,
          type: 'solid'
        }
      },
      splitArea: {
        show: false,
        areaStyle: {
          color: ['rgba(250,250,250,0.2)', 'rgba(210,219,238,0.2)']
        }
      }
    };
    var categoryAxis = merge({
      // The gap at both ends of the axis. For categoryAxis, boolean.
      boundaryGap: true,
      // Set false to faster category collection.
      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);
    var valueAxis = merge({
      boundaryGap: [0, 0],
      axisLine: {
        // Not shown when other axis is categoryAxis in cartesian
        show: 'auto'
      },
      axisTick: {
        // Not shown when other axis is categoryAxis in cartesian
        show: 'auto'
      },
      // TODO
      // min/max: [30, datamin, 60] or [20, datamin] or [datamin, 60]
      splitNumber: 5,
      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,
        // Length of minor tick
        length: 3,
        // Line style
        lineStyle: {// Default to be same with axisTick
        }
      },
      minorSplitLine: {
        show: false,
        lineStyle: {
          color: '#F4F7FD',
          width: 1
        }
      }
    }, defaultOption);
    var timeAxis = merge({
      splitNumber: 6,
      axisLabel: {
        // To eliminate labels that are not nice
        showMinLabel: false,
        showMaxLabel: false,
        rich: {
          primary: {
            fontWeight: 'bold'
          }
        }
      },
      splitLine: {
        show: false
      }
    }, valueAxis);
    var logAxis = defaults({
      logBase: 10
    }, valueAxis);
    var axisDefault = {
      category: categoryAxis,
      value: valueAxis,
      time: timeAxis,
      log: logAxis
    };

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


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * 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_TYPES = {
      value: 1,
      category: 1,
      time: 1,
      log: 1
    };

    /**
     * Generate sub axis model class
     * @param axisName 'x' 'y' 'radius' 'angle' 'parallel' ...
     */

    function axisModelCreator(registers, axisName, BaseAxisModelClass, extraDefaultOption) {
      each(AXIS_TYPES, function (v, axisType) {
        var defaultOption = merge(merge({}, axisDefault[axisType], true), extraDefaultOption, true);

        var AxisModel =
        /** @class */
        function (_super) {
          __extends(AxisModel, _super);

          function AxisModel() {
            var _this = _super !== null && _super.apply(this, arguments) || this;

            _this.type = axisName + 'Axis.' + axisType;
            return _this;
          }

          AxisModel.prototype.mergeDefaultAndTheme = function (option, ecModel) {
            var layoutMode = fetchLayoutMode(this);
            var inputPositionParams = layoutMode ? getLayoutParams(option) : {};
            var themeModel = ecModel.getTheme();
            merge(option, themeModel.get(axisType + 'Axis'));
            merge(option, this.getDefaultOption());
            option.type = getAxisType(option);

            if (layoutMode) {
              mergeLayoutParam(option, inputPositionParams, layoutMode);
            }
          };

          AxisModel.prototype.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.
           */


          AxisModel.prototype.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;
            }
          };

          AxisModel.prototype.getOrdinalMeta = function () {
            return this.__ordinalMeta;
          };

          AxisModel.type = axisName + 'Axis.' + axisType;
          AxisModel.defaultOption = defaultOption;
          return AxisModel;
        }(BaseAxisModelClass);

        registers.registerComponentModel(AxisModel);
      });
      registers.registerSubTypeDefaulter(axisName + 'Axis', getAxisType);
    }

    function getAxisType(option) {
      // Default axis with data is category axis
      return option.type || (option.data ? 'category' : 'value');
    }

    var Cartesian =
    /** @class */
    function () {
      function Cartesian(name) {
        this.type = 'cartesian';
        this._dimList = [];
        this._axes = {};
        this.name = name || '';
      }

      Cartesian.prototype.getAxis = function (dim) {
        return this._axes[dim];
      };

      Cartesian.prototype.getAxes = function () {
        return map(this._dimList, function (dim) {
          return this._axes[dim];
        }, this);
      };

      Cartesian.prototype.getAxesByScale = function (scaleType) {
        scaleType = scaleType.toLowerCase();
        return filter(this.getAxes(), function (axis) {
          return axis.scale.type === scaleType;
        });
      };

      Cartesian.prototype.addAxis = function (axis) {
        var dim = axis.dim;
        this._axes[dim] = axis;

        this._dimList.push(dim);
      };

      return Cartesian;
    }();

    var cartesian2DDimensions = ['x', 'y'];

    function canCalculateAffineTransform(scale) {
      return scale.type === 'interval' || scale.type === 'time';
    }

    var Cartesian2D =
    /** @class */
    function (_super) {
      __extends(Cartesian2D, _super);

      function Cartesian2D() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = 'cartesian2d';
        _this.dimensions = cartesian2DDimensions;
        return _this;
      }
      /**
       * Calculate an affine transform matrix if two axes are time or value.
       * It's mainly for accelartion on the large time series data.
       */


      Cartesian2D.prototype.calcAffineTransform = function () {
        this._transform = this._invTransform = null;
        var xAxisScale = this.getAxis('x').scale;
        var yAxisScale = this.getAxis('y').scale;

        if (!canCalculateAffineTransform(xAxisScale) || !canCalculateAffineTransform(yAxisScale)) {
          return;
        }

        var xScaleExtent = xAxisScale.getExtent();
        var yScaleExtent = yAxisScale.getExtent();
        var start = this.dataToPoint([xScaleExtent[0], yScaleExtent[0]]);
        var end = this.dataToPoint([xScaleExtent[1], yScaleExtent[1]]);
        var xScaleSpan = xScaleExtent[1] - xScaleExtent[0];
        var yScaleSpan = yScaleExtent[1] - yScaleExtent[0];

        if (!xScaleSpan || !yScaleSpan) {
          return;
        } // Accelerate data to point calculation on the special large time series data.


        var scaleX = (end[0] - start[0]) / xScaleSpan;
        var scaleY = (end[1] - start[1]) / yScaleSpan;
        var translateX = start[0] - xScaleExtent[0] * scaleX;
        var translateY = start[1] - yScaleExtent[0] * scaleY;
        var m = this._transform = [scaleX, 0, 0, scaleY, translateX, translateY];
        this._invTransform = invert([], m);
      };
      /**
       * Base axis will be used on stacking.
       */


      Cartesian2D.prototype.getBaseAxis = function () {
        return this.getAxesByScale('ordinal')[0] || this.getAxesByScale('time')[0] || this.getAxis('x');
      };

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

      Cartesian2D.prototype.containData = function (data) {
        return this.getAxis('x').containData(data[0]) && this.getAxis('y').containData(data[1]);
      };

      Cartesian2D.prototype.containZone = function (data1, data2) {
        var zoneDiag1 = this.dataToPoint(data1);
        var zoneDiag2 = this.dataToPoint(data2);
        var area = this.getArea();
        var zone = new BoundingRect(zoneDiag1[0], zoneDiag1[1], zoneDiag2[0] - zoneDiag1[0], zoneDiag2[1] - zoneDiag1[1]);
        return area.intersect(zone);
      };

      Cartesian2D.prototype.dataToPoint = function (data, clamp, out) {
        out = out || [];
        var xVal = data[0];
        var yVal = data[1]; // Fast path

        if (this._transform // It's supported that if data is like `[Inifity, 123]`, where only Y pixel calculated.
        && xVal != null && isFinite(xVal) && yVal != null && isFinite(yVal)) {
          return applyTransform(out, data, this._transform);
        }

        var xAxis = this.getAxis('x');
        var yAxis = this.getAxis('y');
        out[0] = xAxis.toGlobalCoord(xAxis.dataToCoord(xVal, clamp));
        out[1] = yAxis.toGlobalCoord(yAxis.dataToCoord(yVal, clamp));
        return out;
      };

      Cartesian2D.prototype.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;
      };

      Cartesian2D.prototype.pointToData = function (point, clamp) {
        var out = [];

        if (this._invTransform) {
          return applyTransform(out, point, this._invTransform);
        }

        var xAxis = this.getAxis('x');
        var yAxis = this.getAxis('y');
        out[0] = xAxis.coordToData(xAxis.toLocalCoord(point[0]), clamp);
        out[1] = yAxis.coordToData(yAxis.toLocalCoord(point[1]), clamp);
        return out;
      };

      Cartesian2D.prototype.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.
       */


      Cartesian2D.prototype.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;
        return new BoundingRect(x, y, width, height);
      };

      return Cartesian2D;
    }(Cartesian);

    var Axis2D =
    /** @class */
    function (_super) {
      __extends(Axis2D, _super);

      function Axis2D(dim, scale, coordExtent, axisType, position) {
        var _this = _super.call(this, dim, scale, coordExtent) || this;
        /**
         * Index of axis, can be used as key
         * Injected outside.
         */


        _this.index = 0;
        _this.type = axisType || 'value';
        _this.position = position || 'bottom';
        return _this;
      }

      Axis2D.prototype.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>}
       */


      Axis2D.prototype.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;
      };

      Axis2D.prototype.pointToData = function (point, clamp) {
        return this.coordToData(this.toLocalCoord(point[this.dim === 'x' ? 0 : 1]), clamp);
      };
      /**
       * Set ordinalSortInfo
       * @param info new OrdinalSortInfo
       */


      Axis2D.prototype.setCategorySortInfo = function (info) {
        if (this.type !== 'category') {
          return false;
        }

        this.model.option.categorySortInfo = info;
        this.scale.setSortInfo(info);
      };

      return Axis2D;
    }(Axis);

    /**
     * Can only be called after coordinate system creation stage.
     * (Can be called before coordinate system update stage).
     */

    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;
    }
    function isCartesian2DSeries(seriesModel) {
      return seriesModel.get('coordinateSystem') === 'cartesian2d';
    }
    function findAxisModels(seriesModel) {
      var axisModelMap = {
        xAxisModel: null,
        yAxisModel: null
      };
      each(axisModelMap, function (v, key) {
        var axisType = key.replace(/Model$/, '');
        var axisModel = seriesModel.getReferringComponents(axisType, SINGLE_REFERRING).models[0];

        if ("development" !== 'production') {
          if (!axisModel) {
            throw new Error(axisType + ' "' + retrieve3(seriesModel.get(axisType + 'Index'), seriesModel.get(axisType + 'Id'), 0) + '" not found');
          }
        }

        axisModelMap[key] = axisModel;
      });
      return axisModelMap;
    }

    var mathLog$1 = Math.log;
    function alignScaleTicks(scale, axisModel, alignToScale) {
      var intervalScaleProto = IntervalScale.prototype; // NOTE: There is a precondition for log scale  here:
      // In log scale we store _interval and _extent of exponent value.
      // So if we use the method of InternalScale to set/get these data.
      // It process the exponent value, which is linear and what we want here.

      var alignToTicks = intervalScaleProto.getTicks.call(alignToScale);
      var alignToNicedTicks = intervalScaleProto.getTicks.call(alignToScale, true);
      var alignToSplitNumber = alignToTicks.length - 1;
      var alignToInterval = intervalScaleProto.getInterval.call(alignToScale);
      var scaleExtent = getScaleExtent(scale, axisModel);
      var rawExtent = scaleExtent.extent;
      var isMinFixed = scaleExtent.fixMin;
      var isMaxFixed = scaleExtent.fixMax;

      if (scale.type === 'log') {
        var logBase = mathLog$1(scale.base);
        rawExtent = [mathLog$1(rawExtent[0]) / logBase, mathLog$1(rawExtent[1]) / logBase];
      }

      scale.setExtent(rawExtent[0], rawExtent[1]);
      scale.calcNiceExtent({
        splitNumber: alignToSplitNumber,
        fixMin: isMinFixed,
        fixMax: isMaxFixed
      });
      var extent = intervalScaleProto.getExtent.call(scale); // Need to update the rawExtent.
      // Because value in rawExtent may be not parsed. e.g. 'dataMin', 'dataMax'

      if (isMinFixed) {
        rawExtent[0] = extent[0];
      }

      if (isMaxFixed) {
        rawExtent[1] = extent[1];
      }

      var interval = intervalScaleProto.getInterval.call(scale);
      var min = rawExtent[0];
      var max = rawExtent[1];

      if (isMinFixed && isMaxFixed) {
        // User set min, max, divide to get new interval
        interval = (max - min) / alignToSplitNumber;
      } else if (isMinFixed) {
        max = rawExtent[0] + interval * alignToSplitNumber; // User set min, expand extent on the other side

        while (max < rawExtent[1] && isFinite(max) && isFinite(rawExtent[1])) {
          interval = increaseInterval(interval);
          max = rawExtent[0] + interval * alignToSplitNumber;
        }
      } else if (isMaxFixed) {
        // User set max, expand extent on the other side
        min = rawExtent[1] - interval * alignToSplitNumber;

        while (min > rawExtent[0] && isFinite(min) && isFinite(rawExtent[0])) {
          interval = increaseInterval(interval);
          min = rawExtent[1] - interval * alignToSplitNumber;
        }
      } else {
        var nicedSplitNumber = scale.getTicks().length - 1;

        if (nicedSplitNumber > alignToSplitNumber) {
          interval = increaseInterval(interval);
        }

        var range = interval * alignToSplitNumber;
        max = Math.ceil(rawExtent[1] / interval) * interval;
        min = round(max - range); // Not change the result that crossing zero.

        if (min < 0 && rawExtent[0] >= 0) {
          min = 0;
          max = round(range);
        } else if (max > 0 && rawExtent[1] <= 0) {
          max = 0;
          min = -round(range);
        }
      } // Adjust min, max based on the extent of alignTo. When min or max is set in alignTo scale


      var t0 = (alignToTicks[0].value - alignToNicedTicks[0].value) / alignToInterval;
      var t1 = (alignToTicks[alignToSplitNumber].value - alignToNicedTicks[alignToSplitNumber].value) / alignToInterval; // NOTE: Must in setExtent -> setInterval -> setNiceExtent order.

      intervalScaleProto.setExtent.call(scale, min + interval * t0, max + interval * t1);
      intervalScaleProto.setInterval.call(scale, interval);

      if (t0 || t1) {
        intervalScaleProto.setNiceExtent.call(scale, min + interval, max - interval);
      }

      if ("development" !== 'production') {
        var ticks = intervalScaleProto.getTicks.call(scale);

        if (ticks[1] && (!isValueNice(interval) || getPrecisionSafe(ticks[1].value) > getPrecisionSafe(interval))) {
          warn( // eslint-disable-next-line
          "The ticks may be not readable when set min: " + axisModel.get('min') + ", max: " + axisModel.get('max') + " and alignTicks: true");
        }
      }
    }

    var Grid =
    /** @class */
    function () {
      function Grid(gridModel, ecModel, api) {
        // FIXME:TS where used (different from registered type 'cartesian2d')?
        this.type = 'grid';
        this._coordsMap = {};
        this._coordsList = [];
        this._axesMap = {};
        this._axesList = [];
        this.axisPointerEnabled = true;
        this.dimensions = cartesian2DDimensions;

        this._initCartesian(gridModel, ecModel, api);

        this.model = gridModel;
      }

      Grid.prototype.getRect = function () {
        return this._rect;
      };

      Grid.prototype.update = function (ecModel, api) {
        var axesMap = this._axesMap;

        this._updateScale(ecModel, this.model);

        function updateAxisTicks(axes) {
          var alignTo; // Axis is added in order of axisIndex.

          var axesIndices = keys(axes);
          var len = axesIndices.length;

          if (!len) {
            return;
          }

          var axisNeedsAlign = []; // Process once and calculate the ticks for those don't use alignTicks.

          for (var i = len - 1; i >= 0; i--) {
            var idx = +axesIndices[i]; // Convert to number.

            var axis = axes[idx];
            var model = axis.model;
            var scale = axis.scale;

            if ( // Only value and log axis without interval support alignTicks.
            isIntervalOrLogScale(scale) && model.get('alignTicks') && model.get('interval') == null) {
              axisNeedsAlign.push(axis);
            } else {
              niceScaleExtent(scale, model);

              if (isIntervalOrLogScale(scale)) {
                // Can only align to interval or log axis.
                alignTo = axis;
              }
            }
          }
          // PENDING. Should we find the axis that both set interval, min, max and align to this one?

          if (axisNeedsAlign.length) {
            if (!alignTo) {
              alignTo = axisNeedsAlign.pop();
              niceScaleExtent(alignTo.scale, alignTo.model);
            }

            each(axisNeedsAlign, function (axis) {
              alignScaleTicks(axis.scale, axis.model, alignTo.scale);
            });
          }
        }

        updateAxisTicks(axesMap.x);
        updateAxisTicks(axesMap.y); // Key: axisDim_axisIndex, value: boolean, whether onZero target.

        var onZeroRecords = {};
        each(axesMap.x, function (xAxis) {
          fixAxisOnZero(axesMap, 'y', xAxis, onZeroRecords);
        });
        each(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);
      };
      /**
       * Resize the grid
       */


      Grid.prototype.resize = function (gridModel, api, ignoreContainLabel) {
        var boxLayoutParams = gridModel.getBoxLayoutParams();
        var isContainLabel = !ignoreContainLabel && gridModel.get('containLabel');
        var gridRect = getLayoutRect(boxLayoutParams, {
          width: api.getWidth(),
          height: api.getHeight()
        });
        this._rect = gridRect;
        var axesList = this._axesList;
        adjustAxes(); // Minus label size

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

        each(this._coordsList, function (coord) {
          // Calculate affine matrix to accelerate the data to point transform.
          // If all the axes scales are time or value.
          coord.calcAffineTransform();
        });

        function adjustAxes() {
          each(axesList, function (axis) {
            var isHorizontal = axis.isHorizontal();
            var extent = isHorizontal ? [0, gridRect.width] : [0, gridRect.height];
            var idx = axis.inverse ? 1 : 0;
            axis.setExtent(extent[idx], extent[1 - idx]);
            updateAxisTransform(axis, isHorizontal ? gridRect.x : gridRect.y);
          });
        }
      };

      Grid.prototype.getAxis = function (dim, axisIndex) {
        var axesMapOnDim = this._axesMap[dim];

        if (axesMapOnDim != null) {
          return axesMapOnDim[axisIndex || 0];
        }
      };

      Grid.prototype.getAxes = function () {
        return this._axesList.slice();
      };

      Grid.prototype.getCartesian = function (xAxisIndex, yAxisIndex) {
        if (xAxisIndex != null && yAxisIndex != null) {
          var key = 'x' + xAxisIndex + 'y' + yAxisIndex;
          return this._coordsMap[key];
        }

        if (isObject(xAxisIndex)) {
          yAxisIndex = xAxisIndex.yAxisIndex;
          xAxisIndex = xAxisIndex.xAxisIndex;
        }

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

      Grid.prototype.getCartesians = function () {
        return this._coordsList.slice();
      };
      /**
       * @implements
       */


      Grid.prototype.convertToPixel = function (ecModel, finder, value) {
        var target = this._findConvertTarget(finder);

        return target.cartesian ? target.cartesian.dataToPoint(value) : target.axis ? target.axis.toGlobalCoord(target.axis.dataToCoord(value)) : null;
      };
      /**
       * @implements
       */


      Grid.prototype.convertFromPixel = function (ecModel, finder, value) {
        var target = this._findConvertTarget(finder);

        return target.cartesian ? target.cartesian.pointToData(value) : target.axis ? target.axis.coordToData(target.axis.toLocalCoord(value)) : null;
      };

      Grid.prototype._findConvertTarget = function (finder) {
        var seriesModel = finder.seriesModel;
        var xAxisModel = finder.xAxisModel || seriesModel && seriesModel.getReferringComponents('xAxis', SINGLE_REFERRING).models[0];
        var yAxisModel = finder.yAxisModel || seriesModel && seriesModel.getReferringComponents('yAxis', SINGLE_REFERRING).models[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
       */


      Grid.prototype.containPoint = function (point) {
        var coord = this._coordsList[0];

        if (coord) {
          return coord.containPoint(point);
        }
      };
      /**
       * Initialize cartesian coordinate systems
       */


      Grid.prototype._initCartesian = function (gridModel, ecModel, api) {
        var _this = this;

        var grid = this;
        var axisPositionUsed = {
          left: false,
          right: false,
          top: false,
          bottom: false
        };
        var axesMap = {
          x: {},
          y: {}
        };
        var axesCount = {
          x: 0,
          y: 0
        }; // Create axis

        ecModel.eachComponent('xAxis', createAxisCreator('x'), this);
        ecModel.eachComponent('yAxis', createAxisCreator('y'), this);

        if (!axesCount.x || !axesCount.y) {
          // Roll back when there no either x or y axis
          this._axesMap = {};
          this._axesList = [];
          return;
        }

        this._axesMap = axesMap; // Create cartesian2d

        each(axesMap.x, function (xAxis, xAxisIndex) {
          each(axesMap.y, function (yAxis, yAxisIndex) {
            var key = 'x' + xAxisIndex + 'y' + yAxisIndex;
            var cartesian = new Cartesian2D(key);
            cartesian.master = _this;
            cartesian.model = gridModel;
            _this._coordsMap[key] = cartesian;

            _this._coordsList.push(cartesian);

            cartesian.addAxis(xAxis);
            cartesian.addAxis(yAxis);
          });
        });

        function createAxisCreator(dimName) {
          return function (axisModel, idx) {
            if (!isAxisUsedInTheGrid(axisModel, gridModel)) {
              return;
            }

            var axisPosition = axisModel.get('position');

            if (dimName === '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(dimName, 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 = grid; // Index of axis, can be used as key

            axis.index = idx;

            grid._axesList.push(axis);

            axesMap[dimName][idx] = axis;
            axesCount[dimName]++;
          };
        }
      };
      /**
       * Update cartesian properties from series.
       */


      Grid.prototype._updateScale = function (ecModel, gridModel) {
        // Reset scale
        each(this._axesList, function (axis) {
          axis.scale.setExtent(Infinity, -Infinity);

          if (axis.type === 'category') {
            var categorySortInfo = axis.model.get('categorySortInfo');
            axis.scale.setSortInfo(categorySortInfo);
          }
        });
        ecModel.eachSeries(function (seriesModel) {
          if (isCartesian2DSeries(seriesModel)) {
            var axesModelMap = findAxisModels(seriesModel);
            var xAxisModel = axesModelMap.xAxisModel;
            var yAxisModel = axesModelMap.yAxisModel;

            if (!isAxisUsedInTheGrid(xAxisModel, gridModel) || !isAxisUsedInTheGrid(yAxisModel, gridModel)) {
              return;
            }

            var cartesian = this.getCartesian(xAxisModel.componentIndex, yAxisModel.componentIndex);
            var data = seriesModel.getData();
            var xAxis = cartesian.getAxis('x');
            var yAxis = cartesian.getAxis('y');
            unionExtent(data, xAxis);
            unionExtent(data, yAxis);
          }
        }, this);

        function unionExtent(data, axis) {
          each(getDataDimensionsOnAxis(data, axis.dim), function (dim) {
            axis.scale.unionExtentFromData(data, dim);
          });
        }
      };
      /**
       * @param dim 'x' or 'y' or 'auto' or null/undefined
       */


      Grid.prototype.getTooltipAxes = function (dim) {
        var baseAxes = [];
        var otherAxes = [];
        each(this.getCartesians(), function (cartesian) {
          var baseAxis = dim != null && dim !== 'auto' ? cartesian.getAxis(dim) : cartesian.getBaseAxis();
          var otherAxis = cartesian.getOtherAxis(baseAxis);
          indexOf(baseAxes, baseAxis) < 0 && baseAxes.push(baseAxis);
          indexOf(otherAxes, otherAxis) < 0 && otherAxes.push(otherAxis);
        });
        return {
          baseAxes: baseAxes,
          otherAxes: otherAxes
        };
      };

      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 (!isCartesian2DSeries(seriesModel)) {
            return;
          }

          var axesModelMap = findAxisModels(seriesModel);
          var xAxisModel = axesModelMap.xAxisModel;
          var yAxisModel = axesModelMap.yAxisModel;
          var gridModel = xAxisModel.getCoordSysModel();

          if ("development" !== 'production') {
            if (!gridModel) {
              throw new Error('Grid "' + retrieve3(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 = cartesian2DDimensions;
      return Grid;
    }();
    /**
     * Check if the axis is used in the specified grid.
     */


    function isAxisUsedInTheGrid(axisModel, gridModel) {
      return axisModel.getCoordSysModel() === gridModel;
    }

    function fixAxisOnZero(axesMap, otherAxisDim, axis, // Key: see `getOnZeroRecordKey`
    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);
    }

    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 PI$5 = 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.
     */

    var AxisBuilder =
    /** @class */
    function () {
      function AxisBuilder(axisModel, opt) {
        this.group = new Group();
        this.opt = opt;
        this.axisModel = axisModel; // Default value

        defaults(opt, {
          labelOffset: 0,
          nameDirection: 1,
          tickDirection: 1,
          labelDirection: 1,
          silent: true,
          handleAutoShown: function () {
            return true;
          }
        }); // FIXME Not use a seperate text group?

        var transformGroup = new Group({
          x: opt.position[0],
          y: opt.position[1],
          rotation: opt.rotation
        }); // this.group.add(transformGroup);
        // this._transformGroup = transformGroup;

        transformGroup.updateTransform();
        this._transformGroup = transformGroup;
      }

      AxisBuilder.prototype.hasBuilder = function (name) {
        return !!builders[name];
      };

      AxisBuilder.prototype.add = function (name) {
        builders[name](this.opt, this.axisModel, this.group, this._transformGroup);
      };

      AxisBuilder.prototype.getGroup = function () {
        return this.group;
      };

      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$5)) {
          // Label is inverse parallel with axis line.
          textVerticalAlign = direction > 0 ? 'bottom' : 'top';
          textAlign = 'center';
        } else {
          textVerticalAlign = 'middle';

          if (rotationDiff > 0 && rotationDiff < PI$5) {
            textAlign = direction > 0 ? 'right' : 'left';
          } else {
            textAlign = direction > 0 ? 'left' : 'right';
          }
        }

        return {
          rotation: rotationDiff,
          textAlign: textAlign,
          textVerticalAlign: textVerticalAlign
        };
      };

      AxisBuilder.makeAxisEventDataBase = function (axisModel) {
        var eventData = {
          componentType: axisModel.mainType,
          componentIndex: axisModel.componentIndex
        };
        eventData[axisModel.mainType + 'Index'] = axisModel.componentIndex;
        return eventData;
      };

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

      return AxisBuilder;
    }();
    var builders = {
      axisLine: function (opt, axisModel, group, transformGroup) {
        var shown = axisModel.get(['axisLine', 'show']);

        if (shown === 'auto' && opt.handleAutoShown) {
          shown = opt.handleAutoShown('axisLine');
        }

        if (!shown) {
          return;
        }

        var extent = axisModel.axis.getExtent();
        var matrix = transformGroup.transform;
        var pt1 = [extent[0], 0];
        var pt2 = [extent[1], 0];
        var inverse = pt1[0] > pt2[0];

        if (matrix) {
          applyTransform(pt1, pt1, matrix);
          applyTransform(pt2, pt2, matrix);
        }

        var lineStyle = extend({
          lineCap: 'round'
        }, axisModel.getModel(['axisLine', 'lineStyle']).getLineStyle());
        var line = new Line({
          shape: {
            x1: pt1[0],
            y1: pt1[1],
            x2: pt2[0],
            y2: pt2[1]
          },
          style: lineStyle,
          strokeContainThreshold: opt.strokeContainThreshold || 5,
          silent: true,
          z2: 1
        });
        subPixelOptimizeLine$1(line.shape, line.style.lineWidth);
        line.anid = 'line';
        group.add(line);
        var arrows = axisModel.get(['axisLine', 'symbol']);

        if (arrows != null) {
          var arrowSize = axisModel.get(['axisLine', 'symbolSize']);

          if (isString(arrows)) {
            // Use the same arrow for start and end point
            arrows = [arrows, arrows];
          }

          if (isString(arrowSize) || isNumber(arrowSize)) {
            // Use the same size for width and height
            arrowSize = [arrowSize, arrowSize];
          }

          var arrowOffset = normalizeSymbolOffset(axisModel.get(['axisLine', 'symbolOffset']) || 0, arrowSize);
          var symbolWidth_1 = arrowSize[0];
          var symbolHeight_1 = arrowSize[1];
          each([{
            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_1 / 2, -symbolHeight_1 / 2, symbolWidth_1, symbolHeight_1, lineStyle.stroke, true); // Calculate arrow position with offset

              var r = point.r + point.offset;
              var pt = inverse ? pt2 : pt1;
              symbol.attr({
                rotation: point.rotate,
                x: pt[0] + r * Math.cos(opt.rotation),
                y: pt[1] - r * Math.sin(opt.rotation),
                silent: true,
                z2: 11
              });
              group.add(symbol);
            }
          });
        }
      },
      axisTickLabel: function (opt, axisModel, group, transformGroup) {
        var ticksEls = buildAxisMajorTicks(group, transformGroup, axisModel, opt);
        var labelEls = buildAxisLabel(group, transformGroup, axisModel, opt);
        fixMinMaxLabelShow(axisModel, labelEls, ticksEls);
        buildAxisMinorTicks(group, transformGroup, axisModel, opt.tickDirection); // This bit fixes the label overlap issue for the time chart.
        // See https://github.com/apache/echarts/issues/14266 for more.

        if (axisModel.get(['axisLabel', 'hideOverlap'])) {
          var labelList = prepareLayoutList(map(labelEls, function (label) {
            return {
              label: label,
              priority: label.z2,
              defaultAttr: {
                ignore: label.ignore
              }
            };
          }));
          hideOverlap(labelList);
        }
      },
      axisName: function (opt, axisModel, group, transformGroup) {
        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 = 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, // Reuse labelOffset.
        isNameLocationCenter(nameLocation) ? opt.labelOffset + nameDirection * gap : 0];
        var labelLayout;
        var nameRotation = axisModel.get('nameRotate');

        if (nameRotation != null) {
          nameRotation = nameRotation * PI$5 / 180; // To radian.
        }

        var axisNameAvailableWidth;

        if (isNameLocationCenter(nameLocation)) {
          labelLayout = AxisBuilder.innerTextLayout(opt.rotation, nameRotation != null ? nameRotation : opt.rotation, // Adapt to axis.
          nameDirection);
        } else {
          labelLayout = endTextLayout(opt.rotation, nameLocation, nameRotation || 0, extent);
          axisNameAvailableWidth = opt.axisNameAvailableWidth;

          if (axisNameAvailableWidth != null) {
            axisNameAvailableWidth = Math.abs(axisNameAvailableWidth / Math.sin(labelLayout.rotation));
            !isFinite(axisNameAvailableWidth) && (axisNameAvailableWidth = null);
          }
        }

        var textFont = textStyleModel.getFont();
        var truncateOpt = axisModel.get('nameTruncate', true) || {};
        var ellipsis = truncateOpt.ellipsis;
        var maxWidth = retrieve(opt.nameTruncateMaxWidth, truncateOpt.maxWidth, axisNameAvailableWidth);
        var textEl = new ZRText({
          x: pos[0],
          y: pos[1],
          rotation: labelLayout.rotation,
          silent: AxisBuilder.isLabelSilent(axisModel),
          style: createTextStyle(textStyleModel, {
            text: name,
            font: textFont,
            overflow: 'truncate',
            width: maxWidth,
            ellipsis: ellipsis,
            fill: textStyleModel.getTextColor() || axisModel.get(['axisLine', 'lineStyle', 'color']),
            align: textStyleModel.get('align') || labelLayout.textAlign,
            verticalAlign: textStyleModel.get('verticalAlign') || labelLayout.textVerticalAlign
          }),
          z2: 1
        });
        setTooltipConfig({
          el: textEl,
          componentModel: axisModel,
          itemName: name
        });
        textEl.__fullText = name; // Id for animation

        textEl.anid = 'name';

        if (axisModel.get('triggerEvent')) {
          var eventData = AxisBuilder.makeAxisEventDataBase(axisModel);
          eventData.targetType = 'axisName';
          eventData.name = name;
          getECData(textEl).eventData = eventData;
        } // FIXME


        transformGroup.add(textEl);
        textEl.updateTransform();
        group.add(textEl);
        textEl.decomposeTransform();
      }
    };

    function endTextLayout(rotation, textPosition, textRotate, extent) {
      var rotationDiff = remRadian(textRotate - rotation);
      var textAlign;
      var textVerticalAlign;
      var inverse = extent[0] > extent[1];
      var onLeft = textPosition === 'start' && !inverse || textPosition !== 'start' && inverse;

      if (isRadianAroundZero(rotationDiff - PI$5 / 2)) {
        textVerticalAlign = onLeft ? 'bottom' : 'top';
        textAlign = 'center';
      } else if (isRadianAroundZero(rotationDiff - PI$5 * 1.5)) {
        textVerticalAlign = onLeft ? 'top' : 'bottom';
        textAlign = 'center';
      } else {
        textVerticalAlign = 'middle';

        if (rotationDiff < PI$5 * 1.5 && rotationDiff > PI$5 / 2) {
          textAlign = onLeft ? 'left' : 'right';
        } else {
          textAlign = onLeft ? 'right' : 'left';
        }
      }

      return {
        rotation: rotationDiff,
        textAlign: textAlign,
        textVerticalAlign: textVerticalAlign
      };
    }

    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) {
      // 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, anidPrefix) {
      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({
          shape: {
            x1: pt1[0],
            y1: pt1[1],
            x2: pt2[0],
            y2: pt2[1]
          },
          style: tickLineStyle,
          z2: 2,
          autoBatch: true,
          silent: true
        });
        subPixelOptimizeLine$1(tickEl.shape, tickEl.style.lineWidth);
        tickEl.anid = anidPrefix + '_' + ticksCoords[i].tickValue;
        tickEls.push(tickEl);
      }

      return tickEls;
    }

    function buildAxisMajorTicks(group, transformGroup, axisModel, opt) {
      var axis = axisModel.axis;
      var tickModel = axisModel.getModel('axisTick');
      var shown = tickModel.get('show');

      if (shown === 'auto' && opt.handleAutoShown) {
        shown = opt.handleAutoShown('axisTick');
      }

      if (!shown || axis.scale.isBlank()) {
        return;
      }

      var lineStyleModel = tickModel.getModel('lineStyle');
      var tickEndCoord = opt.tickDirection * tickModel.get('length');
      var ticksCoords = axis.getTicksCoords();
      var ticksEls = createTicks(ticksCoords, transformGroup.transform, tickEndCoord, defaults(lineStyleModel.getLineStyle(), {
        stroke: axisModel.get(['axisLine', 'lineStyle', 'color'])
      }), 'ticks');

      for (var i = 0; i < ticksEls.length; i++) {
        group.add(ticksEls[i]);
      }

      return ticksEls;
    }

    function buildAxisMinorTicks(group, transformGroup, axisModel, tickDirection) {
      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 = 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], transformGroup.transform, tickEndCoord, minorTickLineStyle, 'minorticks_' + i);

        for (var k = 0; k < minorTicksEls.length; k++) {
          group.add(minorTicksEls[k]);
        }
      }
    }

    function buildAxisLabel(group, transformGroup, 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$5 / 180;
      var labelLayout = AxisBuilder.innerTextLayout(opt.rotation, labelRotation, opt.labelDirection);
      var rawCategoryData = axisModel.getCategories && axisModel.getCategories(true);
      var labelEls = [];
      var silent = AxisBuilder.isLabelSilent(axisModel);
      var triggerEvent = axisModel.get('triggerEvent');
      each(labels, function (labelItem, index) {
        var tickValue = axis.scale.type === 'ordinal' ? axis.scale.getRawOrdinalNumber(labelItem.tickValue) : labelItem.tickValue;
        var formattedLabel = labelItem.formattedLabel;
        var rawLabel = labelItem.rawLabel;
        var itemLabelModel = labelModel;

        if (rawCategoryData && rawCategoryData[tickValue]) {
          var rawCategoryItem = rawCategoryData[tickValue];

          if (isObject(rawCategoryItem) && rawCategoryItem.textStyle) {
            itemLabelModel = new Model(rawCategoryItem.textStyle, labelModel, axisModel.ecModel);
          }
        }

        var textColor = itemLabelModel.getTextColor() || axisModel.get(['axisLine', 'lineStyle', 'color']);
        var tickCoord = axis.dataToCoord(tickValue);
        var textEl = new ZRText({
          x: tickCoord,
          y: opt.labelOffset + opt.labelDirection * labelMargin,
          rotation: labelLayout.rotation,
          silent: silent,
          z2: 10 + (labelItem.level || 0),
          style: createTextStyle(itemLabelModel, {
            text: formattedLabel,
            align: itemLabelModel.getShallow('align', true) || labelLayout.textAlign,
            verticalAlign: itemLabelModel.getShallow('verticalAlign', true) || itemLabelModel.getShallow('baseline', true) || labelLayout.textVerticalAlign,
            fill: isFunction(textColor) ? 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
          })
        });
        textEl.anid = 'label_' + tickValue; // Pack data for mouse event

        if (triggerEvent) {
          var eventData = AxisBuilder.makeAxisEventDataBase(axisModel);
          eventData.targetType = 'axisLabel';
          eventData.value = rawLabel;
          eventData.tickIndex = index;

          if (axis.type === 'category') {
            eventData.dataIndex = tickValue;
          }

          getECData(textEl).eventData = eventData;
        } // FIXME


        transformGroup.add(textEl);
        textEl.updateTransform();
        labelEls.push(textEl);
        group.add(textEl);
        textEl.decomposeTransform();
      });
      return labelEls;
    }

    // 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(api.getCoordinateSystems(), function (coordSys) {
        // Some coordinate system do not support axes, like geo.
        if (!coordSys.axisPointerEnabled) {
          return;
        }

        var coordSysKey = makeKey(coordSys.model);
        var axesInfoInCoordSys = result.coordSysAxesInfo[coordSysKey] = {};
        result.coordSysMap[coordSysKey] = coordSys; // Set tooltip (like 'cross') is a convienent way to show axisPointer
        // for user. So we enable seting tooltip on coordSys model.

        var coordSysModel = coordSys.model;
        var baseTooltipModel = coordSysModel.getModel('tooltip', globalTooltipModel);
        each(coordSys.getAxes(), curry(saveTooltipAxisInfo, false, null)); // If axis tooltip used, choose tooltip axis for each coordSys.
        // Notice this case: coordSys is `grid` but not `cartesian2D` here.

        if (coordSys.getTooltipAxes && globalTooltipModel // If tooltip.showContent is set as false, tooltip will not
        // show but axisPointer will show as normal.
        && baseTooltipModel.get('show')) {
          // Compatible with previous logic. But series.tooltip.trigger: 'axis'
          // or series.data[n].tooltip.trigger: 'axis' are not support any more.
          var triggerAxis = baseTooltipModel.get('trigger') === 'axis';
          var cross = baseTooltipModel.get(['axisPointer', 'type']) === 'cross';
          var tooltipAxes = coordSys.getTooltipAxes(baseTooltipModel.get(['axisPointer', 'axis']));

          if (triggerAxis || cross) {
            each(tooltipAxes.baseAxes, curry(saveTooltipAxisInfo, cross ? 'cross' : true, triggerAxis));
          }

          if (cross) {
            each(tooltipAxes.otherAxes, curry(saveTooltipAxisInfo, 'cross', false));
          }
        } // fromTooltip: true | false | 'cross'
        // triggerTooltip: true | false | null


        function saveTooltipAxisInfo(fromTooltip, triggerTooltip, axis) {
          var axisPointerModel = axis.model.getModel('axisPointer', globalAxisPointerModel);
          var axisPointerShow = axisPointerModel.get('show');

          if (!axisPointerShow || axisPointerShow === 'auto' && !fromTooltip && !isHandleTrigger(axisPointerModel)) {
            return;
          }

          if (triggerTooltip == null) {
            triggerTooltip = axisPointerModel.get('triggerTooltip');
          }

          axisPointerModel = fromTooltip ? makeAxisPointerModel(axis, baseTooltipModel, globalAxisPointerModel, ecModel, fromTooltip, triggerTooltip) : axisPointerModel;
          var snap = axisPointerModel.get('snap');
          var axisKey = 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[axisKey] = {
            key: axisKey,
            axis: axis,
            coordSys: coordSys,
            axisPointerModel: axisPointerModel,
            triggerTooltip: triggerTooltip,
            involveSeries: involveSeries,
            snap: snap,
            useHandle: isHandleTrigger(axisPointerModel),
            seriesModels: [],
            linkGroup: null
          };
          axesInfoInCoordSys[axisKey] = axisInfo;
          result.seriesInvolved = result.seriesInvolved || involveSeries;
          var groupIndex = getLinkGroupIndex(linksOption, axis);

          if (groupIndex != null) {
            var linkGroup = linkGroups[groupIndex] || (linkGroups[groupIndex] = {
              axesInfo: {}
            });
            linkGroup.axesInfo[axisKey] = axisInfo;
            linkGroup.mapper = linksOption[groupIndex].mapper;
            axisInfo.linkGroup = linkGroup;
          }
        }
      });
    }

    function makeAxisPointerModel(axis, baseTooltipModel, globalAxisPointerModel, ecModel, fromTooltip, triggerTooltip) {
      var tooltipAxisPointerModel = baseTooltipModel.getModel('axisPointer');
      var fields = ['type', 'snap', 'lineStyle', 'shadowStyle', 'label', 'animation', 'animationDurationUpdate', 'animationEasingUpdate', 'z'];
      var volatileOption = {};
      each(fields, 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(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();
          }
        });
      });
    }
    /**
     * 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;
    }

    var axisPointerClazz = {};
    /**
     * Base class of AxisView.
     */

    var AxisView =
    /** @class */
    function (_super) {
      __extends(AxisView, _super);

      function AxisView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = AxisView.type;
        return _this;
      }
      /**
       * @override
       */


      AxisView.prototype.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);

        _super.prototype.render.apply(this, arguments);

        this._doUpdateAxisPointerClass(axisModel, api, true);
      };
      /**
       * Action handler.
       */


      AxisView.prototype.updateAxisPointer = function (axisModel, ecModel, api, payload) {
        this._doUpdateAxisPointerClass(axisModel, api, false);
      };
      /**
       * @override
       */


      AxisView.prototype.remove = function (ecModel, api) {
        var axisPointer = this._axisPointer;
        axisPointer && axisPointer.remove(api);
      };
      /**
       * @override
       */


      AxisView.prototype.dispose = function (ecModel, api) {
        this._disposeAxisPointer(api);

        _super.prototype.dispose.apply(this, arguments);
      };

      AxisView.prototype._doUpdateAxisPointerClass = function (axisModel, api, forceRender) {
        var Clazz = AxisView.getAxisPointerClass(this.axisPointerClass);

        if (!Clazz) {
          return;
        }

        var axisPointerModel = getAxisPointerModel(axisModel);
        axisPointerModel ? (this._axisPointer || (this._axisPointer = new Clazz())).render(axisModel, axisPointerModel, api, forceRender) : this._disposeAxisPointer(api);
      };

      AxisView.prototype._disposeAxisPointer = function (api) {
        this._axisPointer && this._axisPointer.dispose(api);
        this._axisPointer = null;
      };

      AxisView.registerAxisPointerClass = function (type, clazz) {
        if ("development" !== 'production') {
          if (axisPointerClazz[type]) {
            throw new Error('axisPointer ' + type + ' exists');
          }
        }

        axisPointerClazz[type] = clazz;
      };

      AxisView.getAxisPointerClass = function (type) {
        return type && axisPointerClazz[type];
      };
      AxisView.type = 'axis';
      return AxisView;
    }(ComponentView);

    var inner$6 = makeInner();
    function rectCoordAxisBuildSplitArea(axisView, axisGroup, axisModel, gridModel) {
      var axis = axisModel.axis;

      if (axis.scale.isBlank()) {
        return;
      } // TODO: TYPE


      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 = inner$6(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 = void 0;
        var y = void 0;
        var width = void 0;
        var height = void 0;

        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),
          autoBatch: true,
          silent: true
        }));
        colorIndex = (colorIndex + 1) % areaColorsLen;
      }

      inner$6(axisView).splitAreaColors = newSplitAreaColors;
    }
    function rectCoordAxisHandleRemove(axisView) {
      inner$6(axisView).splitAreaColors = null;
    }

    var axisBuilderAttrs = ['axisLine', 'axisTickLabel', 'axisName'];
    var selfBuilderAttrs = ['splitArea', 'splitLine', 'minorSplitLine'];

    var CartesianAxisView =
    /** @class */
    function (_super) {
      __extends(CartesianAxisView, _super);

      function CartesianAxisView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = CartesianAxisView.type;
        _this.axisPointerClass = 'CartesianAxisPointer';
        return _this;
      }
      /**
       * @override
       */


      CartesianAxisView.prototype.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, extend({
          handleAutoShown: function (elementType) {
            var cartesians = gridModel.coordinateSystem.getCartesians();

            for (var i = 0; i < cartesians.length; i++) {
              if (isIntervalOrLogScale(cartesians[i].getOtherAxis(axisModel.axis).scale)) {
                // Still show axis tick or axisLine if other axis is value / log
                return true;
              }
            } // Not show axisTick or axisLine if other axis is category / time


            return false;
          }
        }, layout));
        each(axisBuilderAttrs, axisBuilder.add, axisBuilder);

        this._axisGroup.add(axisBuilder.getGroup());

        each(selfBuilderAttrs, function (name) {
          if (axisModel.get([name, 'show'])) {
            axisElementBuilders[name](this, this._axisGroup, axisModel, gridModel);
          }
        }, this); // THIS is a special case for bar racing chart.
        // Update the axis label from the natural initial layout to
        // sorted layout should has no animation.

        var isInitialSortFromBarRacing = payload && payload.type === 'changeAxisOrder' && payload.isInitSort;

        if (!isInitialSortFromBarRacing) {
          groupTransition(oldAxisGroup, this._axisGroup, axisModel);
        }

        _super.prototype.render.call(this, axisModel, ecModel, api, payload);
      };

      CartesianAxisView.prototype.remove = function () {
        rectCoordAxisHandleRemove(this);
      };

      CartesianAxisView.type = 'cartesianAxis';
      return CartesianAxisView;
    }(AxisView);

    var axisElementBuilders = {
      splitLine: function (axisView, axisGroup, 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;
          var line = new Line({
            anid: tickValue != null ? 'line_' + ticksCoords[i].tickValue : null,
            autoBatch: true,
            shape: {
              x1: p1[0],
              y1: p1[1],
              x2: p2[0],
              y2: p2[1]
            },
            style: defaults({
              stroke: lineColors[colorIndex]
            }, lineStyle),
            silent: true
          });
          subPixelOptimizeLine$1(line.shape, lineStyle.lineWidth);
          axisGroup.add(line);
        }
      },
      minorSplitLine: function (axisView, axisGroup, 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;
            }

            var line = new Line({
              anid: 'minor_line_' + minorTicksCoords[i][k].tickValue,
              autoBatch: true,
              shape: {
                x1: p1[0],
                y1: p1[1],
                x2: p2[0],
                y2: p2[1]
              },
              style: lineStyle,
              silent: true
            });
            subPixelOptimizeLine$1(line.shape, lineStyle.lineWidth);
            axisGroup.add(line);
          }
        }
      },
      splitArea: function (axisView, axisGroup, axisModel, gridModel) {
        rectCoordAxisBuildSplitArea(axisView, axisGroup, axisModel, gridModel);
      }
    };

    var CartesianXAxisView =
    /** @class */
    function (_super) {
      __extends(CartesianXAxisView, _super);

      function CartesianXAxisView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = CartesianXAxisView.type;
        return _this;
      }

      CartesianXAxisView.type = 'xAxis';
      return CartesianXAxisView;
    }(CartesianAxisView);

    var CartesianYAxisView =
    /** @class */
    function (_super) {
      __extends(CartesianYAxisView, _super);

      function CartesianYAxisView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = CartesianXAxisView.type;
        return _this;
      }

      CartesianYAxisView.type = 'yAxis';
      return CartesianYAxisView;
    }(CartesianAxisView);

    var GridView =
    /** @class */
    function (_super) {
      __extends(GridView, _super);

      function GridView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = 'grid';
        return _this;
      }

      GridView.prototype.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
          }));
        }
      };

      GridView.type = 'grid';
      return GridView;
    }(ComponentView);

    var extraOption = {
      // gridIndex: 0,
      // gridId: '',
      offset: 0
    };
    function install$5(registers) {
      registers.registerComponentView(GridView);
      registers.registerComponentModel(GridModel);
      registers.registerCoordinateSystem('cartesian2d', Grid);
      axisModelCreator(registers, 'x', CartesianAxisModel, extraOption);
      axisModelCreator(registers, 'y', CartesianAxisModel, extraOption);
      registers.registerComponentView(CartesianXAxisView);
      registers.registerComponentView(CartesianYAxisView);
      registers.registerPreprocessor(function (option) {
        // Only create grid when need
        if (option.xAxis && option.yAxis && !option.grid) {
          option.grid = {};
        }
      });
    }

    function install$6(registers) {
      // In case developer forget to include grid component
      use(install$5);
      registers.registerSeriesModel(ScatterSeriesModel);
      registers.registerChartView(ScatterView);
      registers.registerLayout(pointsLayout('scatter'));
    }

    function radarLayout(ecModel) {
      ecModel.eachSeriesByType('radar', function (seriesModel) {
        var data = seriesModel.getData();
        var points = [];
        var coordSys = seriesModel.coordinateSystem;

        if (!coordSys) {
          return;
        }

        var axes = coordSys.getIndicatorAxes();
        each(axes, function (axis, axisIndex) {
          data.each(data.mapDimension(axes[axisIndex].dim), function (val, dataIndex) {
            points[dataIndex] = points[dataIndex] || [];
            var point = coordSys.dataToPoint(val, axisIndex);
            points[dataIndex][axisIndex] = isValidPoint(point) ? point : getValueMissingPoint(coordSys);
          });
        }); // Close polygon

        data.each(function (idx) {
          // TODO
          // Is it appropriate to connect to the next data when some data is missing?
          // Or, should trade it like `connectNull` in line chart?
          var firstPoint = find(points[idx], function (point) {
            return isValidPoint(point);
          }) || getValueMissingPoint(coordSys); // Copy the first actual point to the end of the array

          points[idx].push(firstPoint.slice());
          data.setItemLayout(idx, points[idx]);
        });
      });
    }

    function isValidPoint(point) {
      return !isNaN(point[0]) && !isNaN(point[1]);
    }

    function getValueMissingPoint(coordSys) {
      // It is error-prone to input [NaN, NaN] into polygon, polygon.
      // (probably cause problem when refreshing or animating)
      return [coordSys.cx, coordSys.cy];
    }

    function radarBackwardCompat(option) {
      var polarOptArr = option.polar;

      if (polarOptArr) {
        if (!isArray(polarOptArr)) {
          polarOptArr = [polarOptArr];
        }

        var polarNotRadar_1 = [];
        each(polarOptArr, function (polarOpt, idx) {
          if (polarOpt.indicator) {
            if (polarOpt.type && !polarOpt.shape) {
              polarOpt.shape = polarOpt.type;
            }

            option.radar = option.radar || [];

            if (!isArray(option.radar)) {
              option.radar = [option.radar];
            }

            option.radar.push(polarOpt);
          } else {
            polarNotRadar_1.push(polarOpt);
          }
        });
        option.polar = polarNotRadar_1;
      }

      each(option.series, function (seriesOpt) {
        if (seriesOpt && seriesOpt.type === 'radar' && seriesOpt.polarIndex) {
          seriesOpt.radarIndex = seriesOpt.polarIndex;
        }
      });
    }

    var RadarView =
    /** @class */
    function (_super) {
      __extends(RadarView, _super);

      function RadarView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = RadarView.type;
        return _this;
      }

      RadarView.prototype.render = function (seriesModel, ecModel, api) {
        var polar = seriesModel.coordinateSystem;
        var group = this.group;
        var data = seriesModel.getData();
        var oldData = this._data;

        function createSymbol$1(data, idx) {
          var symbolType = data.getItemVisual(idx, 'symbol') || 'circle';

          if (symbolType === 'none') {
            return;
          }

          var symbolSize = normalizeSymbolSize(data.getItemVisual(idx, 'symbolSize'));
          var symbolPath = createSymbol(symbolType, -1, -1, 2, 2);
          var symbolRotate = data.getItemVisual(idx, 'symbolRotate') || 0;
          symbolPath.attr({
            style: {
              strokeNoScale: true
            },
            z2: 100,
            scaleX: symbolSize[0] / 2,
            scaleY: symbolSize[1] / 2,
            rotation: symbolRotate * Math.PI / 180 || 0
          });
          return symbolPath;
        }

        function updateSymbols(oldPoints, newPoints, symbolGroup, data, idx, isInit) {
          // Simply rerender all
          symbolGroup.removeAll();

          for (var i = 0; i < newPoints.length - 1; i++) {
            var symbolPath = createSymbol$1(data, idx);

            if (symbolPath) {
              symbolPath.__dimIdx = i;

              if (oldPoints[i]) {
                symbolPath.setPosition(oldPoints[i]);
                graphic[isInit ? 'initProps' : 'updateProps'](symbolPath, {
                  x: newPoints[i][0],
                  y: newPoints[i][1]
                }, seriesModel, idx);
              } else {
                symbolPath.setPosition(newPoints[i]);
              }

              symbolGroup.add(symbolPath);
            }
          }
        }

        function getInitialPoints(points) {
          return map(points, function (pt) {
            return [polar.cx, polar.cy];
          });
        }

        data.diff(oldData).add(function (idx) {
          var points = data.getItemLayout(idx);

          if (!points) {
            return;
          }

          var polygon = new Polygon();
          var polyline = new Polyline();
          var target = {
            shape: {
              points: points
            }
          };
          polygon.shape.points = getInitialPoints(points);
          polyline.shape.points = getInitialPoints(points);
          initProps(polygon, target, seriesModel, idx);
          initProps(polyline, target, seriesModel, idx);
          var itemGroup = new Group();
          var symbolGroup = new Group();
          itemGroup.add(polyline);
          itemGroup.add(polygon);
          itemGroup.add(symbolGroup);
          updateSymbols(polyline.shape.points, points, symbolGroup, data, idx, true);
          data.setItemGraphicEl(idx, itemGroup);
        }).update(function (newIdx, oldIdx) {
          var itemGroup = oldData.getItemGraphicEl(oldIdx);
          var polyline = itemGroup.childAt(0);
          var polygon = itemGroup.childAt(1);
          var symbolGroup = itemGroup.childAt(2);
          var target = {
            shape: {
              points: data.getItemLayout(newIdx)
            }
          };

          if (!target.shape.points) {
            return;
          }

          updateSymbols(polyline.shape.points, target.shape.points, symbolGroup, data, newIdx, false);
          saveOldStyle(polygon);
          saveOldStyle(polyline);
          updateProps(polyline, target, seriesModel);
          updateProps(polygon, target, seriesModel);
          data.setItemGraphicEl(newIdx, itemGroup);
        }).remove(function (idx) {
          group.remove(oldData.getItemGraphicEl(idx));
        }).execute();
        data.eachItemGraphicEl(function (itemGroup, idx) {
          var itemModel = data.getItemModel(idx);
          var polyline = itemGroup.childAt(0);
          var polygon = itemGroup.childAt(1);
          var symbolGroup = itemGroup.childAt(2); // Radar uses the visual encoded from itemStyle.

          var itemStyle = data.getItemVisual(idx, 'style');
          var color = itemStyle.fill;
          group.add(itemGroup);
          polyline.useStyle(defaults(itemModel.getModel('lineStyle').getLineStyle(), {
            fill: 'none',
            stroke: color
          }));
          setStatesStylesFromModel(polyline, itemModel, 'lineStyle');
          setStatesStylesFromModel(polygon, itemModel, 'areaStyle');
          var areaStyleModel = itemModel.getModel('areaStyle');
          var polygonIgnore = areaStyleModel.isEmpty() && areaStyleModel.parentModel.isEmpty();
          polygon.ignore = polygonIgnore;
          each(['emphasis', 'select', 'blur'], function (stateName) {
            var stateModel = itemModel.getModel([stateName, 'areaStyle']);
            var stateIgnore = stateModel.isEmpty() && stateModel.parentModel.isEmpty(); // Won't be ignore if normal state is not ignore.

            polygon.ensureState(stateName).ignore = stateIgnore && polygonIgnore;
          });
          polygon.useStyle(defaults(areaStyleModel.getAreaStyle(), {
            fill: color,
            opacity: 0.7,
            decal: itemStyle.decal
          }));
          var emphasisModel = itemModel.getModel('emphasis');
          var itemHoverStyle = emphasisModel.getModel('itemStyle').getItemStyle();
          symbolGroup.eachChild(function (symbolPath) {
            if (symbolPath instanceof ZRImage) {
              var pathStyle = symbolPath.style;
              symbolPath.useStyle(extend({
                // TODO other properties like x, y ?
                image: pathStyle.image,
                x: pathStyle.x,
                y: pathStyle.y,
                width: pathStyle.width,
                height: pathStyle.height
              }, itemStyle));
            } else {
              symbolPath.useStyle(itemStyle);
              symbolPath.setColor(color);
              symbolPath.style.strokeNoScale = true;
            }

            var pathEmphasisState = symbolPath.ensureState('emphasis');
            pathEmphasisState.style = clone(itemHoverStyle);
            var defaultText = data.getStore().get(data.getDimensionIndex(symbolPath.__dimIdx), idx);
            (defaultText == null || isNaN(defaultText)) && (defaultText = '');
            setLabelStyle(symbolPath, getLabelStatesModels(itemModel), {
              labelFetcher: data.hostModel,
              labelDataIndex: idx,
              labelDimIndex: symbolPath.__dimIdx,
              defaultText: defaultText,
              inheritColor: color,
              defaultOpacity: itemStyle.opacity
            });
          });
          toggleHoverEmphasis(itemGroup, emphasisModel.get('focus'), emphasisModel.get('blurScope'), emphasisModel.get('disabled'));
        });
        this._data = data;
      };

      RadarView.prototype.remove = function () {
        this.group.removeAll();
        this._data = null;
      };

      RadarView.type = 'radar';
      return RadarView;
    }(ChartView);

    var RadarSeriesModel =
    /** @class */
    function (_super) {
      __extends(RadarSeriesModel, _super);

      function RadarSeriesModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = RadarSeriesModel.type;
        _this.hasSymbolVisual = true;
        return _this;
      } // Overwrite


      RadarSeriesModel.prototype.init = function (option) {
        _super.prototype.init.apply(this, 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));
      };

      RadarSeriesModel.prototype.getInitialData = function (option, ecModel) {
        return createSeriesDataSimply(this, {
          generateCoord: 'indicator_',
          generateCoordCount: Infinity
        });
      };

      RadarSeriesModel.prototype.formatTooltip = function (dataIndex, multipleSeries, dataType) {
        var data = this.getData();
        var coordSys = this.coordinateSystem;
        var indicatorAxes = coordSys.getIndicatorAxes();
        var name = this.getData().getName(dataIndex);
        var nameToDisplay = name === '' ? this.name : name;
        var markerColor = retrieveVisualColorForTooltipMarker(this, dataIndex);
        return createTooltipMarkup('section', {
          header: nameToDisplay,
          sortBlocks: true,
          blocks: map(indicatorAxes, function (axis) {
            var val = data.get(data.mapDimension(axis.dim), dataIndex);
            return createTooltipMarkup('nameValue', {
              markerType: 'subItem',
              markerColor: markerColor,
              name: axis.name,
              value: val,
              sortParam: val
            });
          })
        });
      };

      RadarSeriesModel.prototype.getTooltipPosition = function (dataIndex) {
        if (dataIndex != null) {
          var data_1 = this.getData();
          var coordSys = this.coordinateSystem;
          var values = data_1.getValues(map(coordSys.dimensions, function (dim) {
            return data_1.mapDimension(dim);
          }), dataIndex);

          for (var i = 0, len = values.length; i < len; i++) {
            if (!isNaN(values[i])) {
              var indicatorAxes = coordSys.getIndicatorAxes();
              return coordSys.coordToPoint(indicatorAxes[i].dataToCoord(values[i]), i);
            }
          }
        }
      };

      RadarSeriesModel.type = 'series.radar';
      RadarSeriesModel.dependencies = ['radar'];
      RadarSeriesModel.defaultOption = {
        // zlevel: 0,
        z: 2,
        colorBy: 'data',
        coordinateSystem: 'radar',
        legendHoverLink: true,
        radarIndex: 0,
        lineStyle: {
          width: 2,
          type: 'solid',
          join: 'round'
        },
        label: {
          position: 'top'
        },
        // areaStyle: {
        // },
        // itemStyle: {}
        symbolSize: 8 // symbolRotate: null

      };
      return RadarSeriesModel;
    }(SeriesModel);

    var valueAxisDefault = axisDefault.value;

    function defaultsShow(opt, show) {
      return defaults({
        show: show
      }, opt);
    }

    var RadarModel =
    /** @class */
    function (_super) {
      __extends(RadarModel, _super);

      function RadarModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = RadarModel.type;
        return _this;
      }

      RadarModel.prototype.optionUpdated = function () {
        var boundaryGap = this.get('boundaryGap');
        var splitNumber = this.get('splitNumber');
        var scale = this.get('scale');
        var axisLine = this.get('axisLine');
        var axisTick = this.get('axisTick'); // let axisType = this.get('axisType');

        var axisLabel = this.get('axisLabel');
        var nameTextStyle = this.get('axisName');
        var showName = this.get(['axisName', 'show']);
        var nameFormatter = this.get(['axisName', 'formatter']);
        var nameGap = this.get('axisNameGap');
        var triggerEvent = this.get('triggerEvent');
        var indicatorModels = map(this.get('indicator') || [], function (indicatorOpt) {
          // PENDING
          if (indicatorOpt.max != null && indicatorOpt.max > 0 && !indicatorOpt.min) {
            indicatorOpt.min = 0;
          } else if (indicatorOpt.min != null && indicatorOpt.min < 0 && !indicatorOpt.max) {
            indicatorOpt.max = 0;
          }

          var iNameTextStyle = nameTextStyle;

          if (indicatorOpt.color != null) {
            iNameTextStyle = defaults({
              color: indicatorOpt.color
            }, nameTextStyle);
          } // Use same configuration


          var innerIndicatorOpt = merge(clone(indicatorOpt), {
            boundaryGap: boundaryGap,
            splitNumber: splitNumber,
            scale: scale,
            axisLine: axisLine,
            axisTick: axisTick,
            // axisType: axisType,
            axisLabel: axisLabel,
            // Compatible with 2 and use text
            name: indicatorOpt.text,
            showName: showName,
            nameLocation: 'end',
            nameGap: nameGap,
            // min: 0,
            nameTextStyle: iNameTextStyle,
            triggerEvent: triggerEvent
          }, false);

          if (isString(nameFormatter)) {
            var indName = innerIndicatorOpt.name;
            innerIndicatorOpt.name = nameFormatter.replace('{value}', indName != null ? indName : '');
          } else if (isFunction(nameFormatter)) {
            innerIndicatorOpt.name = nameFormatter(innerIndicatorOpt.name, innerIndicatorOpt);
          }

          var model = new Model(innerIndicatorOpt, null, this.ecModel);
          mixin(model, AxisModelCommonMixin.prototype); // For triggerEvent.

          model.mainType = 'radar';
          model.componentIndex = this.componentIndex;
          return model;
        }, this);
        this._indicatorModels = indicatorModels;
      };

      RadarModel.prototype.getIndicatorModels = function () {
        return this._indicatorModels;
      };

      RadarModel.type = 'radar';
      RadarModel.defaultOption = {
        // zlevel: 0,
        z: 0,
        center: ['50%', '50%'],
        radius: '75%',
        startAngle: 90,
        axisName: {
          show: true // formatter: null
          // textStyle: {}

        },
        boundaryGap: [0, 0],
        splitNumber: 5,
        axisNameGap: 15,
        scale: false,
        // Polygon or circle
        shape: 'polygon',
        axisLine: merge({
          lineStyle: {
            color: '#bbb'
          }
        }, valueAxisDefault.axisLine),
        axisLabel: defaultsShow(valueAxisDefault.axisLabel, false),
        axisTick: defaultsShow(valueAxisDefault.axisTick, false),
        // axisType: 'value',
        splitLine: defaultsShow(valueAxisDefault.splitLine, true),
        splitArea: defaultsShow(valueAxisDefault.splitArea, true),
        // {text, min, max}
        indicator: []
      };
      return RadarModel;
    }(ComponentModel);

    var axisBuilderAttrs$1 = ['axisLine', 'axisTickLabel', 'axisName'];

    var RadarView$1 =
    /** @class */
    function (_super) {
      __extends(RadarView, _super);

      function RadarView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = RadarView.type;
        return _this;
      }

      RadarView.prototype.render = function (radarModel, ecModel, api) {
        var group = this.group;
        group.removeAll();

        this._buildAxes(radarModel);

        this._buildSplitLineAndArea(radarModel);
      };

      RadarView.prototype._buildAxes = function (radarModel) {
        var radar = radarModel.coordinateSystem;
        var indicatorAxes = radar.getIndicatorAxes();
        var axisBuilders = map(indicatorAxes, function (indicatorAxis) {
          var axisName = indicatorAxis.model.get('showName') ? indicatorAxis.name : ''; // hide name

          var axisBuilder = new AxisBuilder(indicatorAxis.model, {
            axisName: axisName,
            position: [radar.cx, radar.cy],
            rotation: indicatorAxis.angle,
            labelDirection: -1,
            tickDirection: -1,
            nameDirection: 1
          });
          return axisBuilder;
        });
        each(axisBuilders, function (axisBuilder) {
          each(axisBuilderAttrs$1, axisBuilder.add, axisBuilder);
          this.group.add(axisBuilder.getGroup());
        }, this);
      };

      RadarView.prototype._buildSplitLineAndArea = function (radarModel) {
        var radar = radarModel.coordinateSystem;
        var indicatorAxes = radar.getIndicatorAxes();

        if (!indicatorAxes.length) {
          return;
        }

        var shape = radarModel.get('shape');
        var splitLineModel = radarModel.getModel('splitLine');
        var splitAreaModel = radarModel.getModel('splitArea');
        var lineStyleModel = splitLineModel.getModel('lineStyle');
        var areaStyleModel = splitAreaModel.getModel('areaStyle');
        var showSplitLine = splitLineModel.get('show');
        var showSplitArea = splitAreaModel.get('show');
        var splitLineColors = lineStyleModel.get('color');
        var splitAreaColors = areaStyleModel.get('color');
        var splitLineColorsArr = isArray(splitLineColors) ? splitLineColors : [splitLineColors];
        var splitAreaColorsArr = isArray(splitAreaColors) ? splitAreaColors : [splitAreaColors];
        var splitLines = [];
        var splitAreas = [];

        function getColorIndex(areaOrLine, areaOrLineColorList, idx) {
          var colorIndex = idx % areaOrLineColorList.length;
          areaOrLine[colorIndex] = areaOrLine[colorIndex] || [];
          return colorIndex;
        }

        if (shape === 'circle') {
          var ticksRadius = indicatorAxes[0].getTicksCoords();
          var cx = radar.cx;
          var cy = radar.cy;

          for (var i = 0; i < ticksRadius.length; i++) {
            if (showSplitLine) {
              var colorIndex = getColorIndex(splitLines, splitLineColorsArr, i);
              splitLines[colorIndex].push(new Circle({
                shape: {
                  cx: cx,
                  cy: cy,
                  r: ticksRadius[i].coord
                }
              }));
            }

            if (showSplitArea && i < ticksRadius.length - 1) {
              var colorIndex = getColorIndex(splitAreas, splitAreaColorsArr, i);
              splitAreas[colorIndex].push(new Ring({
                shape: {
                  cx: cx,
                  cy: cy,
                  r0: ticksRadius[i].coord,
                  r: ticksRadius[i + 1].coord
                }
              }));
            }
          }
        } // Polyyon
        else {
            var realSplitNumber_1;
            var axesTicksPoints = map(indicatorAxes, function (indicatorAxis, idx) {
              var ticksCoords = indicatorAxis.getTicksCoords();
              realSplitNumber_1 = realSplitNumber_1 == null ? ticksCoords.length - 1 : Math.min(ticksCoords.length - 1, realSplitNumber_1);
              return map(ticksCoords, function (tickCoord) {
                return radar.coordToPoint(tickCoord.coord, idx);
              });
            });
            var prevPoints = [];

            for (var i = 0; i <= realSplitNumber_1; i++) {
              var points = [];

              for (var j = 0; j < indicatorAxes.length; j++) {
                points.push(axesTicksPoints[j][i]);
              } // Close


              if (points[0]) {
                points.push(points[0].slice());
              } else {
                if ("development" !== 'production') {
                  console.error('Can\'t draw value axis ' + i);
                }
              }

              if (showSplitLine) {
                var colorIndex = getColorIndex(splitLines, splitLineColorsArr, i);
                splitLines[colorIndex].push(new Polyline({
                  shape: {
                    points: points
                  }
                }));
              }

              if (showSplitArea && prevPoints) {
                var colorIndex = getColorIndex(splitAreas, splitAreaColorsArr, i - 1);
                splitAreas[colorIndex].push(new Polygon({
                  shape: {
                    points: points.concat(prevPoints)
                  }
                }));
              }

              prevPoints = points.slice().reverse();
            }
          }

        var lineStyle = lineStyleModel.getLineStyle();
        var areaStyle = areaStyleModel.getAreaStyle(); // Add splitArea before splitLine

        each(splitAreas, function (splitAreas, idx) {
          this.group.add(mergePath$1(splitAreas, {
            style: defaults({
              stroke: 'none',
              fill: splitAreaColorsArr[idx % splitAreaColorsArr.length]
            }, areaStyle),
            silent: true
          }));
        }, this);
        each(splitLines, function (splitLines, idx) {
          this.group.add(mergePath$1(splitLines, {
            style: defaults({
              fill: 'none',
              stroke: splitLineColorsArr[idx % splitLineColorsArr.length]
            }, lineStyle),
            silent: true
          }));
        }, this);
      };

      RadarView.type = 'radar';
      return RadarView;
    }(ComponentView);

    var IndicatorAxis =
    /** @class */
    function (_super) {
      __extends(IndicatorAxis, _super);

      function IndicatorAxis(dim, scale, radiusExtent) {
        var _this = _super.call(this, dim, scale, radiusExtent) || this;

        _this.type = 'value';
        _this.angle = 0;
        _this.name = '';
        return _this;
      }

      return IndicatorAxis;
    }(Axis);

    var Radar =
    /** @class */
    function () {
      function Radar(radarModel, ecModel, api) {
        /**
         *
         * Radar dimensions
         */
        this.dimensions = [];
        this._model = radarModel;
        this._indicatorAxes = map(radarModel.getIndicatorModels(), function (indicatorModel, idx) {
          var dim = 'indicator_' + idx;
          var indicatorAxis = new IndicatorAxis(dim, new IntervalScale() // (indicatorModel.get('axisType') === 'log') ? new LogScale() : new IntervalScale()
          );
          indicatorAxis.name = indicatorModel.get('name'); // Inject model and axis

          indicatorAxis.model = indicatorModel;
          indicatorModel.axis = indicatorAxis;
          this.dimensions.push(dim);
          return indicatorAxis;
        }, this);
        this.resize(radarModel, api);
      }

      Radar.prototype.getIndicatorAxes = function () {
        return this._indicatorAxes;
      };

      Radar.prototype.dataToPoint = function (value, indicatorIndex) {
        var indicatorAxis = this._indicatorAxes[indicatorIndex];
        return this.coordToPoint(indicatorAxis.dataToCoord(value), indicatorIndex);
      }; // TODO: API should be coordToPoint([coord, indicatorIndex])


      Radar.prototype.coordToPoint = function (coord, indicatorIndex) {
        var indicatorAxis = this._indicatorAxes[indicatorIndex];
        var angle = indicatorAxis.angle;
        var x = this.cx + coord * Math.cos(angle);
        var y = this.cy - coord * Math.sin(angle);
        return [x, y];
      };

      Radar.prototype.pointToData = function (pt) {
        var dx = pt[0] - this.cx;
        var dy = pt[1] - this.cy;
        var radius = Math.sqrt(dx * dx + dy * dy);
        dx /= radius;
        dy /= radius;
        var radian = Math.atan2(-dy, dx); // Find the closest angle
        // FIXME index can calculated directly

        var minRadianDiff = Infinity;
        var closestAxis;
        var closestAxisIdx = -1;

        for (var i = 0; i < this._indicatorAxes.length; i++) {
          var indicatorAxis = this._indicatorAxes[i];
          var diff = Math.abs(radian - indicatorAxis.angle);

          if (diff < minRadianDiff) {
            closestAxis = indicatorAxis;
            closestAxisIdx = i;
            minRadianDiff = diff;
          }
        }

        return [closestAxisIdx, +(closestAxis && closestAxis.coordToData(radius))];
      };

      Radar.prototype.resize = function (radarModel, api) {
        var center = radarModel.get('center');
        var viewWidth = api.getWidth();
        var viewHeight = api.getHeight();
        var viewSize = Math.min(viewWidth, viewHeight) / 2;
        this.cx = parsePercent$1(center[0], viewWidth);
        this.cy = parsePercent$1(center[1], viewHeight);
        this.startAngle = radarModel.get('startAngle') * Math.PI / 180; // radius may be single value like `20`, `'80%'`, or array like `[10, '80%']`

        var radius = radarModel.get('radius');

        if (isString(radius) || isNumber(radius)) {
          radius = [0, radius];
        }

        this.r0 = parsePercent$1(radius[0], viewSize);
        this.r = parsePercent$1(radius[1], viewSize);
        each(this._indicatorAxes, function (indicatorAxis, idx) {
          indicatorAxis.setExtent(this.r0, this.r);
          var angle = this.startAngle + idx * Math.PI * 2 / this._indicatorAxes.length; // Normalize to [-PI, PI]

          angle = Math.atan2(Math.sin(angle), Math.cos(angle));
          indicatorAxis.angle = angle;
        }, this);
      };

      Radar.prototype.update = function (ecModel, api) {
        var indicatorAxes = this._indicatorAxes;
        var radarModel = this._model;
        each(indicatorAxes, function (indicatorAxis) {
          indicatorAxis.scale.setExtent(Infinity, -Infinity);
        });
        ecModel.eachSeriesByType('radar', function (radarSeries, idx) {
          if (radarSeries.get('coordinateSystem') !== 'radar' // @ts-ignore
          || ecModel.getComponent('radar', radarSeries.get('radarIndex')) !== radarModel) {
            return;
          }

          var data = radarSeries.getData();
          each(indicatorAxes, function (indicatorAxis) {
            indicatorAxis.scale.unionExtentFromData(data, data.mapDimension(indicatorAxis.dim));
          });
        }, this);
        var splitNumber = radarModel.get('splitNumber');
        var dummyScale = new IntervalScale();
        dummyScale.setExtent(0, splitNumber);
        dummyScale.setInterval(1); // Force all the axis fixing the maxSplitNumber.

        each(indicatorAxes, function (indicatorAxis, idx) {
          alignScaleTicks(indicatorAxis.scale, indicatorAxis.model, dummyScale);
        });
      };

      Radar.prototype.convertToPixel = function (ecModel, finder, value) {
        console.warn('Not implemented.');
        return null;
      };

      Radar.prototype.convertFromPixel = function (ecModel, finder, pixel) {
        console.warn('Not implemented.');
        return null;
      };

      Radar.prototype.containPoint = function (point) {
        console.warn('Not implemented.');
        return false;
      };

      Radar.create = function (ecModel, api) {
        var radarList = [];
        ecModel.eachComponent('radar', function (radarModel) {
          var radar = new Radar(radarModel, ecModel, api);
          radarList.push(radar);
          radarModel.coordinateSystem = radar;
        });
        ecModel.eachSeriesByType('radar', function (radarSeries) {
          if (radarSeries.get('coordinateSystem') === 'radar') {
            // Inject coordinate system
            // @ts-ignore
            radarSeries.coordinateSystem = radarList[radarSeries.get('radarIndex') || 0];
          }
        });
        return radarList;
      };
      /**
       * Radar dimensions is based on the data
       */


      Radar.dimensions = [];
      return Radar;
    }();

    function install$7(registers) {
      registers.registerCoordinateSystem('radar', Radar);
      registers.registerComponentModel(RadarModel);
      registers.registerComponentView(RadarView$1);
      registers.registerVisual({
        seriesType: 'radar',
        reset: function (seriesModel) {
          var data = seriesModel.getData(); // itemVisual symbol is for selected data

          data.each(function (idx) {
            data.setItemVisual(idx, 'legendIcon', 'roundRect');
          }); // visual is for unselected data

          data.setVisual('legendIcon', 'roundRect');
        }
      });
    }

    function install$8(registers) {
      use(install$7);
      registers.registerChartView(RadarView);
      registers.registerSeriesModel(RadarSeriesModel);
      registers.registerLayout(radarLayout);
      registers.registerProcessor(dataFilter('radar'));
      registers.registerPreprocessor(radarBackwardCompat);
    }

    var ATTR = '\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] || (zr[ATTR] = {});
    }
    /**
     * payload: {
     *     type: 'takeGlobalCursor',
     *     key: 'dataZoomSelect', or 'brush', or ...,
     *         If no userKey, release global cursor.
     * }
     */
    // TODO: SELF REGISTERED.


    registerAction({
      type: 'takeGlobalCursor',
      event: 'globalCursorTaken',
      update: 'update'
    }, noop);

    var RoamController =
    /** @class */
    function (_super) {
      __extends(RoamController, _super);

      function RoamController(zr) {
        var _this = _super.call(this) || this;

        _this._zr = zr; // Avoid two roamController bind the same handler

        var mousedownHandler = bind(_this._mousedownHandler, _this);
        var mousemoveHandler = bind(_this._mousemoveHandler, _this);
        var mouseupHandler = bind(_this._mouseupHandler, _this);
        var mousewheelHandler = bind(_this._mousewheelHandler, _this);
        var pinchHandler = bind(_this._pinchHandler, _this);
        /**
         * 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.
         */

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

        return _this;
      }

      RoamController.prototype.isDragging = function () {
        return this._dragging;
      };

      RoamController.prototype.isPinching = function () {
        return this._pinching;
      };

      RoamController.prototype.setPointerChecker = function (pointerChecker) {
        this.pointerChecker = pointerChecker;
      };

      RoamController.prototype.dispose = function () {
        this.disable();
      };

      RoamController.prototype._mousedownHandler = function (e) {
        if (isMiddleOrRightButtonOnMouseUpDown(e)) {
          return;
        }

        var el = e.target;

        while (el) {
          if (el.draggable) {
            return;
          } // check if host is draggable


          el = el.__hostTarget || el.parent;
        }

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

      RoamController.prototype._mousemoveHandler = function (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,
          isAvailableBehavior: null
        });
      };

      RoamController.prototype._mouseupHandler = function (e) {
        if (!isMiddleOrRightButtonOnMouseUpDown(e)) {
          this._dragging = false;
        }
      };

      RoamController.prototype._mousewheelHandler = function (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,
            isAvailableBehavior: null
          });
        }

        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,
            isAvailableBehavior: null
          });
        }
      };

      RoamController.prototype._pinchHandler = function (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,
          isAvailableBehavior: null
        });
      };

      return RoamController;
    }(Eventful);

    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); // TODO should not have type issue.

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


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * 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 geo and graph.
     */
    function updateViewOnPan(controllerHost, dx, dy) {
      var target = controllerHost.target;
      target.x += dx;
      target.y += dy;
      target.dirty();
    }
    /**
     * For geo and graph.
     */

    function updateViewOnZoom(controllerHost, zoomDelta, zoomX, zoomY) {
      var target = controllerHost.target;
      var zoomLimit = controllerHost.zoomLimit;
      var newZoom = controllerHost.zoom = controllerHost.zoom || 1;
      newZoom *= zoomDelta;

      if (zoomLimit) {
        var zoomMin = zoomLimit.min || 0;
        var zoomMax = zoomLimit.max || Infinity;
        newZoom = Math.max(Math.min(zoomMax, newZoom), zoomMin);
      }

      var zoomScale = newZoom / controllerHost.zoom;
      controllerHost.zoom = newZoom; // Keep the mouse center when scaling

      target.x -= (zoomX - target.x) * (zoomScale - 1);
      target.y -= (zoomY - target.y) * (zoomScale - 1);
      target.scaleX *= zoomScale;
      target.scaleY *= zoomScale;
      target.dirty();
    }

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


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * 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.hasOwnProperty(model.mainType) && coordSys && coordSys.model !== targetCoordSysModel;
    }

    function parseXML(svg) {
        if (isString(svg)) {
            var parser = new DOMParser();
            svg = parser.parseFromString(svg, 'text/xml');
        }
        var svgNode = svg;
        if (svgNode.nodeType === 9) {
            svgNode = svgNode.firstChild;
        }
        while (svgNode.nodeName.toLowerCase() !== 'svg' || svgNode.nodeType !== 1) {
            svgNode = svgNode.nextSibling;
        }
        return svgNode;
    }

    var nodeParsers;
    var INHERITABLE_STYLE_ATTRIBUTES_MAP = {
        '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-anchor': 'textAlign',
        'visibility': 'visibility',
        'display': 'display'
    };
    var INHERITABLE_STYLE_ATTRIBUTES_MAP_KEYS = keys(INHERITABLE_STYLE_ATTRIBUTES_MAP);
    var SELF_STYLE_ATTRIBUTES_MAP = {
        'alignment-baseline': 'textBaseline',
        'stop-color': 'stopColor'
    };
    var SELF_STYLE_ATTRIBUTES_MAP_KEYS = keys(SELF_STYLE_ATTRIBUTES_MAP);
    var SVGParser = (function () {
        function SVGParser() {
            this._defs = {};
            this._root = null;
        }
        SVGParser.prototype.parse = function (xml, opt) {
            opt = opt || {};
            var svg = parseXML(xml);
            if ("development" !== 'production') {
                if (!svg) {
                    throw new Error('Illegal svg');
                }
            }
            this._defsUsePending = [];
            var root = new Group();
            this._root = root;
            var named = [];
            var viewBox = svg.getAttribute('viewBox') || '';
            var width = parseFloat((svg.getAttribute('width') || opt.width));
            var height = parseFloat((svg.getAttribute('height') || opt.height));
            isNaN(width) && (width = null);
            isNaN(height) && (height = null);
            parseAttributes(svg, root, null, true, false);
            var child = svg.firstChild;
            while (child) {
                this._parseNode(child, root, named, null, false, false);
                child = child.nextSibling;
            }
            applyDefs(this._defs, this._defsUsePending);
            this._defsUsePending = [];
            var viewBoxRect;
            var viewBoxTransform;
            if (viewBox) {
                var viewBoxArr = splitNumberSequence(viewBox);
                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, { x: 0, y: 0, width: width, height: height });
                if (!opt.ignoreViewBox) {
                    var elRoot = root;
                    root = new Group();
                    root.add(elRoot);
                    elRoot.scaleX = elRoot.scaleY = viewBoxTransform.scale;
                    elRoot.x = viewBoxTransform.x;
                    elRoot.y = viewBoxTransform.y;
                }
            }
            if (!opt.ignoreRootClip && width != null && height != null) {
                root.setClipPath(new Rect({
                    shape: { x: 0, y: 0, width: width, height: height }
                }));
            }
            return {
                root: root,
                width: width,
                height: height,
                viewBoxRect: viewBoxRect,
                viewBoxTransform: viewBoxTransform,
                named: named
            };
        };
        SVGParser.prototype._parseNode = function (xmlNode, parentGroup, named, namedFrom, isInDefs, isInText) {
            var nodeName = xmlNode.nodeName.toLowerCase();
            var el;
            var namedFromForSub = namedFrom;
            if (nodeName === 'defs') {
                isInDefs = true;
            }
            if (nodeName === 'text') {
                isInText = true;
            }
            if (nodeName === 'defs' || nodeName === 'switch') {
                el = parentGroup;
            }
            else {
                if (!isInDefs) {
                    var parser_1 = nodeParsers[nodeName];
                    if (parser_1 && hasOwn(nodeParsers, nodeName)) {
                        el = parser_1.call(this, xmlNode, parentGroup);
                        var nameAttr = xmlNode.getAttribute('name');
                        if (nameAttr) {
                            var newNamed = {
                                name: nameAttr,
                                namedFrom: null,
                                svgNodeTagLower: nodeName,
                                el: el
                            };
                            named.push(newNamed);
                            if (nodeName === 'g') {
                                namedFromForSub = newNamed;
                            }
                        }
                        else if (namedFrom) {
                            named.push({
                                name: namedFrom.name,
                                namedFrom: namedFrom,
                                svgNodeTagLower: nodeName,
                                el: el
                            });
                        }
                        parentGroup.add(el);
                    }
                }
                var parser = paintServerParsers[nodeName];
                if (parser && hasOwn(paintServerParsers, nodeName)) {
                    var def = parser.call(this, xmlNode);
                    var id = xmlNode.getAttribute('id');
                    if (id) {
                        this._defs[id] = def;
                    }
                }
            }
            if (el && el.isGroup) {
                var child = xmlNode.firstChild;
                while (child) {
                    if (child.nodeType === 1) {
                        this._parseNode(child, el, named, namedFromForSub, isInDefs, isInText);
                    }
                    else if (child.nodeType === 3 && isInText) {
                        this._parseText(child, el);
                    }
                    child = child.nextSibling;
                }
            }
        };
        SVGParser.prototype._parseText = function (xmlNode, parentGroup) {
            var text = new TSpan({
                style: {
                    text: xmlNode.textContent
                },
                silent: true,
                x: this._textX || 0,
                y: this._textY || 0
            });
            inheritStyle(parentGroup, text);
            parseAttributes(xmlNode, text, this._defsUsePending, false, false);
            applyTextAlignment(text, parentGroup);
            var textStyle = text.style;
            var fontSize = textStyle.fontSize;
            if (fontSize && fontSize < 9) {
                textStyle.fontSize = 9;
                text.scaleX *= fontSize / 9;
                text.scaleY *= fontSize / 9;
            }
            var font = (textStyle.fontSize || textStyle.fontFamily) && [
                textStyle.fontStyle,
                textStyle.fontWeight,
                (textStyle.fontSize || 12) + 'px',
                textStyle.fontFamily || 'sans-serif'
            ].join(' ');
            textStyle.font = font;
            var rect = text.getBoundingRect();
            this._textX += rect.width;
            parentGroup.add(text);
            return text;
        };
        SVGParser.internalField = (function () {
            nodeParsers = {
                'g': function (xmlNode, parentGroup) {
                    var g = new Group();
                    inheritStyle(parentGroup, g);
                    parseAttributes(xmlNode, g, this._defsUsePending, false, false);
                    return g;
                },
                'rect': function (xmlNode, parentGroup) {
                    var rect = new Rect();
                    inheritStyle(parentGroup, rect);
                    parseAttributes(xmlNode, rect, this._defsUsePending, false, false);
                    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')
                    });
                    rect.silent = true;
                    return rect;
                },
                'circle': function (xmlNode, parentGroup) {
                    var circle = new Circle();
                    inheritStyle(parentGroup, circle);
                    parseAttributes(xmlNode, circle, this._defsUsePending, false, false);
                    circle.setShape({
                        cx: parseFloat(xmlNode.getAttribute('cx') || '0'),
                        cy: parseFloat(xmlNode.getAttribute('cy') || '0'),
                        r: parseFloat(xmlNode.getAttribute('r') || '0')
                    });
                    circle.silent = true;
                    return circle;
                },
                'line': function (xmlNode, parentGroup) {
                    var line = new Line();
                    inheritStyle(parentGroup, line);
                    parseAttributes(xmlNode, line, this._defsUsePending, false, false);
                    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')
                    });
                    line.silent = true;
                    return line;
                },
                'ellipse': function (xmlNode, parentGroup) {
                    var ellipse = new Ellipse();
                    inheritStyle(parentGroup, ellipse);
                    parseAttributes(xmlNode, ellipse, this._defsUsePending, false, false);
                    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')
                    });
                    ellipse.silent = true;
                    return ellipse;
                },
                'polygon': function (xmlNode, parentGroup) {
                    var pointsStr = xmlNode.getAttribute('points');
                    var pointsArr;
                    if (pointsStr) {
                        pointsArr = parsePoints(pointsStr);
                    }
                    var polygon = new Polygon({
                        shape: {
                            points: pointsArr || []
                        },
                        silent: true
                    });
                    inheritStyle(parentGroup, polygon);
                    parseAttributes(xmlNode, polygon, this._defsUsePending, false, false);
                    return polygon;
                },
                'polyline': function (xmlNode, parentGroup) {
                    var pointsStr = xmlNode.getAttribute('points');
                    var pointsArr;
                    if (pointsStr) {
                        pointsArr = parsePoints(pointsStr);
                    }
                    var polyline = new Polyline({
                        shape: {
                            points: pointsArr || []
                        },
                        silent: true
                    });
                    inheritStyle(parentGroup, polyline);
                    parseAttributes(xmlNode, polyline, this._defsUsePending, false, false);
                    return polyline;
                },
                'image': function (xmlNode, parentGroup) {
                    var img = new ZRImage();
                    inheritStyle(parentGroup, img);
                    parseAttributes(xmlNode, img, this._defsUsePending, false, false);
                    img.setStyle({
                        image: xmlNode.getAttribute('xlink:href') || xmlNode.getAttribute('href'),
                        x: +xmlNode.getAttribute('x'),
                        y: +xmlNode.getAttribute('y'),
                        width: +xmlNode.getAttribute('width'),
                        height: +xmlNode.getAttribute('height')
                    });
                    img.silent = true;
                    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._defsUsePending, false, true);
                    return g;
                },
                'tspan': function (xmlNode, parentGroup) {
                    var x = xmlNode.getAttribute('x');
                    var y = xmlNode.getAttribute('y');
                    if (x != null) {
                        this._textX = parseFloat(x);
                    }
                    if (y != null) {
                        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._defsUsePending, false, true);
                    this._textX += parseFloat(dx);
                    this._textY += parseFloat(dy);
                    return g;
                },
                'path': function (xmlNode, parentGroup) {
                    var d = xmlNode.getAttribute('d') || '';
                    var path = createFromString(d);
                    inheritStyle(parentGroup, path);
                    parseAttributes(xmlNode, path, this._defsUsePending, false, false);
                    path.silent = true;
                    return path;
                }
            };
        })();
        return SVGParser;
    }());
    var paintServerParsers = {
        '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);
            parsePaintServerUnit(xmlNode, gradient);
            parseGradientColorStops(xmlNode, gradient);
            return gradient;
        },
        'radialgradient': function (xmlNode) {
            var cx = parseInt(xmlNode.getAttribute('cx') || '0', 10);
            var cy = parseInt(xmlNode.getAttribute('cy') || '0', 10);
            var r = parseInt(xmlNode.getAttribute('r') || '0', 10);
            var gradient = new RadialGradient(cx, cy, r);
            parsePaintServerUnit(xmlNode, gradient);
            parseGradientColorStops(xmlNode, gradient);
            return gradient;
        }
    };
    function parsePaintServerUnit(xmlNode, gradient) {
        var gradientUnits = xmlNode.getAttribute('gradientUnits');
        if (gradientUnits === 'userSpaceOnUse') {
            gradient.global = true;
        }
    }
    function parseGradientColorStops(xmlNode, gradient) {
        var stop = xmlNode.firstChild;
        while (stop) {
            if (stop.nodeType === 1
                && stop.nodeName.toLocaleLowerCase() === 'stop') {
                var offsetStr = stop.getAttribute('offset');
                var offset = void 0;
                if (offsetStr && offsetStr.indexOf('%') > 0) {
                    offset = parseInt(offsetStr, 10) / 100;
                }
                else if (offsetStr) {
                    offset = parseFloat(offsetStr);
                }
                else {
                    offset = 0;
                }
                var styleVals = {};
                parseInlineStyle(stop, styleVals, styleVals);
                var stopColor = styleVals.stopColor
                    || stop.getAttribute('stop-color')
                    || '#000000';
                gradient.colorStops.push({
                    offset: offset,
                    color: 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 = splitNumberSequence(pointsString);
        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;
    }
    function parseAttributes(xmlNode, el, defsUsePending, onlyInlineStyle, isTextGroup) {
        var disp = el;
        var inheritedStyle = disp.__inheritedStyle = disp.__inheritedStyle || {};
        var selfStyle = {};
        if (xmlNode.nodeType === 1) {
            parseTransformAttribute(xmlNode, el);
            parseInlineStyle(xmlNode, inheritedStyle, selfStyle);
            if (!onlyInlineStyle) {
                parseAttributeStyle(xmlNode, inheritedStyle, selfStyle);
            }
        }
        disp.style = disp.style || {};
        if (inheritedStyle.fill != null) {
            disp.style.fill = getFillStrokeStyle(disp, 'fill', inheritedStyle.fill, defsUsePending);
        }
        if (inheritedStyle.stroke != null) {
            disp.style.stroke = getFillStrokeStyle(disp, 'stroke', inheritedStyle.stroke, defsUsePending);
        }
        each([
            'lineWidth', 'opacity', 'fillOpacity', 'strokeOpacity', 'miterLimit', 'fontSize'
        ], function (propName) {
            if (inheritedStyle[propName] != null) {
                disp.style[propName] = parseFloat(inheritedStyle[propName]);
            }
        });
        each([
            'lineDashOffset', 'lineCap', 'lineJoin', 'fontWeight', 'fontFamily', 'fontStyle', 'textAlign'
        ], function (propName) {
            if (inheritedStyle[propName] != null) {
                disp.style[propName] = inheritedStyle[propName];
            }
        });
        if (isTextGroup) {
            disp.__selfStyle = selfStyle;
        }
        if (inheritedStyle.lineDash) {
            disp.style.lineDash = map(splitNumberSequence(inheritedStyle.lineDash), function (str) {
                return parseFloat(str);
            });
        }
        if (inheritedStyle.visibility === 'hidden' || inheritedStyle.visibility === 'collapse') {
            disp.invisible = true;
        }
        if (inheritedStyle.display === 'none') {
            disp.ignore = true;
        }
    }
    function applyTextAlignment(text, parentGroup) {
        var parentSelfStyle = parentGroup.__selfStyle;
        if (parentSelfStyle) {
            var textBaseline = parentSelfStyle.textBaseline;
            var zrTextBaseline = textBaseline;
            if (!textBaseline || textBaseline === 'auto') {
                zrTextBaseline = 'alphabetic';
            }
            else if (textBaseline === 'baseline') {
                zrTextBaseline = 'alphabetic';
            }
            else if (textBaseline === 'before-edge' || textBaseline === 'text-before-edge') {
                zrTextBaseline = 'top';
            }
            else if (textBaseline === 'after-edge' || textBaseline === 'text-after-edge') {
                zrTextBaseline = 'bottom';
            }
            else if (textBaseline === 'central' || textBaseline === 'mathematical') {
                zrTextBaseline = 'middle';
            }
            text.style.textBaseline = zrTextBaseline;
        }
        var parentInheritedStyle = parentGroup.__inheritedStyle;
        if (parentInheritedStyle) {
            var textAlign = parentInheritedStyle.textAlign;
            var zrTextAlign = textAlign;
            if (textAlign) {
                if (textAlign === 'middle') {
                    zrTextAlign = 'center';
                }
                text.style.textAlign = zrTextAlign;
            }
        }
    }
    var urlRegex = /^url\(\s*#(.*?)\)/;
    function getFillStrokeStyle(el, method, str, defsUsePending) {
        var urlMatch = str && str.match(urlRegex);
        if (urlMatch) {
            var url = trim(urlMatch[1]);
            defsUsePending.push([el, method, url]);
            return;
        }
        if (str === 'none') {
            str = null;
        }
        return str;
    }
    function applyDefs(defs, defsUsePending) {
        for (var i = 0; i < defsUsePending.length; i++) {
            var item = defsUsePending[i];
            item[0].style[item[1]] = defs[item[2]];
        }
    }
    var numberReg$1 = /-?([0-9]*\.)?[0-9]+([eE]-?[0-9]+)?/g;
    function splitNumberSequence(rawStr) {
        return rawStr.match(numberReg$1) || [];
    }
    var transformRegex = /(translate|scale|rotate|skewX|skewY|matrix)\(([\-\s0-9\.eE,]*)\)/g;
    var DEGREE_TO_ANGLE = Math.PI / 180;
    function parseTransformAttribute(xmlNode, node) {
        var transform = xmlNode.getAttribute('transform');
        if (transform) {
            transform = transform.replace(/,/g, ' ');
            var transformOps_1 = [];
            var mt = null;
            transform.replace(transformRegex, function (str, type, value) {
                transformOps_1.push(type, value);
                return '';
            });
            for (var i = transformOps_1.length - 1; i > 0; i -= 2) {
                var value = transformOps_1[i];
                var type = transformOps_1[i - 1];
                var valueArr = splitNumberSequence(value);
                mt = mt || create$1();
                switch (type) {
                    case 'translate':
                        translate(mt, mt, [parseFloat(valueArr[0]), parseFloat(valueArr[1] || '0')]);
                        break;
                    case 'scale':
                        scale$1(mt, mt, [parseFloat(valueArr[0]), parseFloat(valueArr[1] || valueArr[0])]);
                        break;
                    case 'rotate':
                        rotate(mt, mt, -parseFloat(valueArr[0]) * DEGREE_TO_ANGLE);
                        break;
                    case 'skewX':
                        var sx = Math.tan(parseFloat(valueArr[0]) * DEGREE_TO_ANGLE);
                        mul$1(mt, [1, 0, sx, 1, 0, 0], mt);
                        break;
                    case 'skewY':
                        var sy = Math.tan(parseFloat(valueArr[0]) * DEGREE_TO_ANGLE);
                        mul$1(mt, [1, sy, 0, 1, 0, 0], mt);
                        break;
                    case 'matrix':
                        mt[0] = parseFloat(valueArr[0]);
                        mt[1] = parseFloat(valueArr[1]);
                        mt[2] = parseFloat(valueArr[2]);
                        mt[3] = parseFloat(valueArr[3]);
                        mt[4] = parseFloat(valueArr[4]);
                        mt[5] = parseFloat(valueArr[5]);
                        break;
                }
            }
            node.setLocalTransform(mt);
        }
    }
    var styleRegex = /([^\s:;]+)\s*:\s*([^:;]+)/g;
    function parseInlineStyle(xmlNode, inheritableStyleResult, selfStyleResult) {
        var style = xmlNode.getAttribute('style');
        if (!style) {
            return;
        }
        styleRegex.lastIndex = 0;
        var styleRegResult;
        while ((styleRegResult = styleRegex.exec(style)) != null) {
            var svgStlAttr = styleRegResult[1];
            var zrInheritableStlAttr = hasOwn(INHERITABLE_STYLE_ATTRIBUTES_MAP, svgStlAttr)
                ? INHERITABLE_STYLE_ATTRIBUTES_MAP[svgStlAttr]
                : null;
            if (zrInheritableStlAttr) {
                inheritableStyleResult[zrInheritableStlAttr] = styleRegResult[2];
            }
            var zrSelfStlAttr = hasOwn(SELF_STYLE_ATTRIBUTES_MAP, svgStlAttr)
                ? SELF_STYLE_ATTRIBUTES_MAP[svgStlAttr]
                : null;
            if (zrSelfStlAttr) {
                selfStyleResult[zrSelfStlAttr] = styleRegResult[2];
            }
        }
    }
    function parseAttributeStyle(xmlNode, inheritableStyleResult, selfStyleResult) {
        for (var i = 0; i < INHERITABLE_STYLE_ATTRIBUTES_MAP_KEYS.length; i++) {
            var svgAttrName = INHERITABLE_STYLE_ATTRIBUTES_MAP_KEYS[i];
            var attrValue = xmlNode.getAttribute(svgAttrName);
            if (attrValue != null) {
                inheritableStyleResult[INHERITABLE_STYLE_ATTRIBUTES_MAP[svgAttrName]] = attrValue;
            }
        }
        for (var i = 0; i < SELF_STYLE_ATTRIBUTES_MAP_KEYS.length; i++) {
            var svgAttrName = SELF_STYLE_ATTRIBUTES_MAP_KEYS[i];
            var attrValue = xmlNode.getAttribute(svgAttrName);
            if (attrValue != null) {
                selfStyleResult[SELF_STYLE_ATTRIBUTES_MAP[svgAttrName]] = attrValue;
            }
        }
    }
    function makeViewBoxTransform(viewBoxRect, boundingRect) {
        var scaleX = boundingRect.width / viewBoxRect.width;
        var scaleY = boundingRect.height / viewBoxRect.height;
        var scale = Math.min(scaleX, scaleY);
        return {
            scale: scale,
            x: -(viewBoxRect.x + viewBoxRect.width / 2) * scale + (boundingRect.x + boundingRect.width / 2),
            y: -(viewBoxRect.y + viewBoxRect.height / 2) * scale + (boundingRect.y + boundingRect.height / 2)
        };
    }
    function parseSVG(xml, opt) {
        var parser = new SVGParser();
        return parser.parse(xml, opt);
    }

    /**
     * "region available" means that: enable users to set attribute `name="xxx"` on those tags
     * to make it be a region.
     * 1. region styles and its label styles can be defined in echarts opton:
     * ```js
     * geo: {
     *     regions: [{
     *         name: 'xxx',
     *         itemStyle: { ... },
     *         label: { ... }
     *     }, {
     *         ...
     *     },
     *     ...]
     * };
     * ```
     * 2. name can be duplicated in different SVG tag. All of the tags with the same name share
     * a region option. For exampel if there are two <path> representing two lung lobes. They have
     * no common parents but both of them need to display label "lung" inside.
     */

    var REGION_AVAILABLE_SVG_TAG_MAP = createHashMap(['rect', 'circle', 'line', 'ellipse', 'polygon', 'polyline', 'path', // <text> <tspan> are also enabled because some SVG might paint text itself,
    // but still need to trigger events or tooltip.
    'text', 'tspan', // <g> is also enabled because this case: if multiple tags share one name
    // and need label displayed, every tags will display the name, which is not
    // expected. So we can put them into a <g name="xxx">. Thereby only one label
    // displayed and located based on the bounding rect of the <g>.
    'g']);

    var GeoSVGResource =
    /** @class */
    function () {
      function GeoSVGResource(mapName, svg) {
        this.type = 'geoSVG'; // All used graphics. key: hostKey, value: root

        this._usedGraphicMap = createHashMap(); // All unused graphics.

        this._freedGraphics = [];
        this._mapName = mapName; // 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.

        this._parsedXML = parseXML(svg);
      }

      GeoSVGResource.prototype.load = function ()
      /* nameMap: NameMap */
      {
        // In the "load" stage, graphic need to be built to
        // get boundingRect for geo coordinate system.
        var firstGraphic = this._firstGraphic; // Create the return data structure only when first graphic created.
        // Because they will be used in geo coordinate system update stage,
        // and `regions` will be mounted at `geo` coordinate system,
        // in which there is no "view" info, so that it should better not to
        // make references to graphic elements.

        if (!firstGraphic) {
          firstGraphic = this._firstGraphic = this._buildGraphic(this._parsedXML);

          this._freedGraphics.push(firstGraphic);

          this._boundingRect = this._firstGraphic.boundingRect.clone(); // PENDING: `nameMap` will not be supported until some real requirement come.
          // if (nameMap) {
          //     named = applyNameMap(named, nameMap);
          // }

          var _a = createRegions(firstGraphic.named),
              regions = _a.regions,
              regionsMap = _a.regionsMap;

          this._regions = regions;
          this._regionsMap = regionsMap;
        }

        return {
          boundingRect: this._boundingRect,
          regions: this._regions,
          regionsMap: this._regionsMap
        };
      };

      GeoSVGResource.prototype._buildGraphic = function (svgXML) {
        var result;
        var rootFromParse;

        try {
          result = svgXML && parseSVG(svgXML, {
            ignoreViewBox: true,
            ignoreRootClip: true
          }) || {};
          rootFromParse = result.root;
          assert(rootFromParse != null);
        } catch (e) {
          throw new Error('Invalid svg format\n' + e.message);
        } // Note: we keep the covenant that the root has no transform. So always add an extra root.


        var root = new Group();
        root.add(rootFromParse);
        root.isGeoSVGGraphicRoot = true; // [THE_RULE_OF_VIEWPORT_AND_VIEWBOX]
        //
        // Consider: `<svg width="..." height="..." viewBox="...">`
        // - the `width/height` we call it `svgWidth/svgHeight` for short.
        // - `(0, 0, svgWidth, svgHeight)` defines the viewport of the SVG, or say,
        //   "viewport boundingRect", or `boundingRect` for short.
        // - `viewBox` defines the transform from the real content ot the viewport.
        //   `viewBox` has the same unit as the content of SVG.
        //   If `viewBox` exists, a transform is defined, so the unit of `svgWidth/svgHeight` become
        //   different from the content of SVG. Otherwise, they are the same.
        //
        // If both `svgWidth/svgHeight/viewBox` are specified in a SVG file, the transform rule will be:
        // 0. `boundingRect` is `(0, 0, svgWidth, svgHeight)`. Set it to Geo['_rect'] (View['_rect']).
        // 1. Make a transform from `viewBox` to `boundingRect`.
        //    Note: only support `preserveAspectRatio 'xMidYMid'` here. That is, this transform will preserve
        //    the aspect ratio.
        // 2. Make a transform from boundingRect to Geo['_viewRect'] (View['_viewRect'])
        //    (`Geo`/`View` will do this job).
        //    Note: this transform might not preserve aspect radio, which depending on how users specify
        //    viewRect in echarts option (e.g., `geo.left/top/width/height` will not preserve aspect ratio,
        //    but `geo.layoutCenter/layoutSize` will preserve aspect ratio).
        //
        // If `svgWidth/svgHeight` not specified, we use `viewBox` as the `boundingRect` to make the SVG
        // layout look good.
        //
        // If neither `svgWidth/svgHeight` nor `viewBox` are not specified, we calculate the boundingRect
        // of the SVG content and use them to make SVG layout look good.

        var svgWidth = result.width;
        var svgHeight = result.height;
        var viewBoxRect = result.viewBoxRect;
        var boundingRect = this._boundingRect;

        if (!boundingRect) {
          var bRectX = void 0;
          var bRectY = void 0;
          var bRectWidth = void 0;
          var bRectHeight = void 0;

          if (svgWidth != null) {
            bRectX = 0;
            bRectWidth = svgWidth;
          } else if (viewBoxRect) {
            bRectX = viewBoxRect.x;
            bRectWidth = viewBoxRect.width;
          }

          if (svgHeight != null) {
            bRectY = 0;
            bRectHeight = svgHeight;
          } else if (viewBoxRect) {
            bRectY = viewBoxRect.y;
            bRectHeight = viewBoxRect.height;
          } // If both viewBox and svgWidth/svgHeight not specified,
          // we have to determine how to layout those element to make them look good.


          if (bRectX == null || bRectY == null) {
            var calculatedBoundingRect = rootFromParse.getBoundingRect();

            if (bRectX == null) {
              bRectX = calculatedBoundingRect.x;
              bRectWidth = calculatedBoundingRect.width;
            }

            if (bRectY == null) {
              bRectY = calculatedBoundingRect.y;
              bRectHeight = calculatedBoundingRect.height;
            }
          }

          boundingRect = this._boundingRect = new BoundingRect(bRectX, bRectY, bRectWidth, bRectHeight);
        }

        if (viewBoxRect) {
          var viewBoxTransform = makeViewBoxTransform(viewBoxRect, boundingRect); // Only support `preserveAspectRatio 'xMidYMid'`

          rootFromParse.scaleX = rootFromParse.scaleY = viewBoxTransform.scale;
          rootFromParse.x = viewBoxTransform.x;
          rootFromParse.y = viewBoxTransform.y;
        } // SVG needs to clip based on `viewBox`. And some SVG files really rely on this feature.
        // They do not strictly confine all of the content inside a display rect, but deliberately
        // use a `viewBox` to define a displayable rect.
        // PENDING:
        // The drawback of the `setClipPath` here is: the region label (genereted by echarts) near the
        // edge might also be clipped, because region labels are put as `textContent` of the SVG path.


        root.setClipPath(new Rect({
          shape: boundingRect.plain()
        }));
        var named = [];
        each(result.named, function (namedItem) {
          if (REGION_AVAILABLE_SVG_TAG_MAP.get(namedItem.svgNodeTagLower) != null) {
            named.push(namedItem);
            setSilent(namedItem.el);
          }
        });
        return {
          root: root,
          boundingRect: boundingRect,
          named: named
        };
      };
      /**
       * Consider:
       * (1) One graphic element can not be shared by different `geoView` running simultaneously.
       *     Notice, also need to consider multiple echarts instances share a `mapRecord`.
       * (2) Converting SVG to graphic elements is time consuming.
       * (3) In the current architecture, `load` should be called frequently to get boundingRect,
       *     and it is called without view info.
       * So we maintain graphic elements in this module, and enables `view` to use/return these
       * graphics from/to the pool with it's uid.
       */


      GeoSVGResource.prototype.useGraphic = function (hostKey
      /* , nameMap: NameMap */
      ) {
        var usedRootMap = this._usedGraphicMap;
        var svgGraphic = usedRootMap.get(hostKey);

        if (svgGraphic) {
          return svgGraphic;
        }

        svgGraphic = this._freedGraphics.pop() // use the first boundingRect to avoid duplicated boundingRect calculation.
        || this._buildGraphic(this._parsedXML);
        usedRootMap.set(hostKey, svgGraphic); // PENDING: `nameMap` will not be supported until some real requirement come.
        // `nameMap` can only be obtained from echarts option.
        // The original `named` must not be modified.
        // if (nameMap) {
        //     svgGraphic = extend({}, svgGraphic);
        //     svgGraphic.named = applyNameMap(svgGraphic.named, nameMap);
        // }

        return svgGraphic;
      };

      GeoSVGResource.prototype.freeGraphic = function (hostKey) {
        var usedRootMap = this._usedGraphicMap;
        var svgGraphic = usedRootMap.get(hostKey);

        if (svgGraphic) {
          usedRootMap.removeKey(hostKey);

          this._freedGraphics.push(svgGraphic);
        }
      };

      return GeoSVGResource;
    }();

    function setSilent(el) {
      // Only named element has silent: false, other elements should
      // act as background and has no user interaction.
      el.silent = false; // text|tspan will be converted to group.

      if (el.isGroup) {
        el.traverse(function (child) {
          child.silent = false;
        });
      }
    }

    function createRegions(named) {
      var regions = [];
      var regionsMap = createHashMap(); // Create resions only for the first graphic.

      each(named, function (namedItem) {
        // Region has feature to calculate center for tooltip or other features.
        // If there is a <g name="xxx">, the center should be the center of the
        // bounding rect of the g.
        if (namedItem.namedFrom != null) {
          return;
        }

        var region = new GeoSVGRegion(namedItem.name, namedItem.el); // PENDING: if `nameMap` supported, this region can not be mounted on
        // `this`, but can only be created each time `load()` called.

        regions.push(region); // PENDING: if multiple tag named with the same name, only one will be
        // found by `_regionsMap`. `_regionsMap` is used to find a coordinate
        // by name. We use `region.getCenter()` as the coordinate.

        regionsMap.set(namedItem.name, region);
      });
      return {
        regions: regions,
        regionsMap: regionsMap
      };
    } // PENDING: `nameMap` will not be supported until some real requirement come.
    // /**
    //  * Use the alias in geoNameMap.
    //  * The input `named` must not be modified.
    //  */
    // function applyNameMap(
    //     named: GeoSVGGraphicRecord['named'],
    //     nameMap: NameMap
    // ): GeoSVGGraphicRecord['named'] {
    //     const result = [] as GeoSVGGraphicRecord['named'];
    //     for (let i = 0; i < named.length; i++) {
    //         let regionGraphic = named[i];
    //         const name = regionGraphic.name;
    //         if (nameMap && nameMap.hasOwnProperty(name)) {
    //             regionGraphic = extend({}, regionGraphic);
    //             regionGraphic.name = name;
    //         }
    //         result.push(regionGraphic);
    //     }
    //     return result;
    // }

    var geoCoord = [126, 25];
    var nanhaiName = '南海诸岛';
    var points$1 = [[[0, 3.5], [7, 11.2], [15, 11.9], [30, 7], [42, 0.7], [52, 0.7], [56, 7.7], [59, 0.7], [64, 0.7], [64, 0], [5, 0], [0, 3.5]], [[13, 16.1], [19, 14.7], [16, 21.7], [11, 23.1], [13, 16.1]], [[12, 32.2], [14, 38.5], [15, 38.5], [13, 32.2], [12, 32.2]], [[16, 47.6], [12, 53.2], [13, 53.2], [18, 47.6], [16, 47.6]], [[6, 64.4], [8, 70], [9, 70], [8, 64.4], [6, 64.4]], [[23, 82.6], [29, 79.8], [30, 79.8], [25, 82.6], [23, 82.6]], [[37, 70.7], [43, 62.3], [44, 62.3], [39, 70.7], [37, 70.7]], [[48, 51.1], [51, 45.5], [53, 45.5], [50, 51.1], [48, 51.1]], [[51, 35], [51, 28.7], [53, 28.7], [53, 35], [51, 35]], [[52, 22.4], [55, 17.5], [56, 17.5], [53, 22.4], [52, 22.4]], [[58, 12.6], [62, 7], [63, 7], [60, 12.6], [58, 12.6]], [[0, 3.5], [0, 93.1], [64, 93.1], [64, 0], [63, 0], [63, 92.4], [1, 92.4], [1, 3.5], [0, 3.5]]];

    for (var i = 0; i < points$1.length; i++) {
      for (var k = 0; k < points$1[i].length; k++) {
        points$1[i][k][0] /= 10.5;
        points$1[i][k][1] /= -10.5 / 0.75;
        points$1[i][k][0] += geoCoord[0];
        points$1[i][k][1] += geoCoord[1];
      }
    }

    function fixNanhai(mapType, regions) {
      if (mapType === 'china') {
        for (var i = 0; i < regions.length; i++) {
          // Already exists.
          if (regions[i].name === nanhaiName) {
            return;
          }
        }

        regions.push(new GeoJSONRegion(nanhaiName, map(points$1, function (exterior) {
          return {
            type: 'polygon',
            exterior: exterior
          };
        }), geoCoord));
      }
    }

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


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * 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 coordsOffsetMap = {
      '南海诸岛': [32, 80],
      // 全国
      '广东': [0, -10],
      '香港': [10, 5],
      '澳门': [-10, 10],
      // '北京': [-10, 0],
      '天津': [5, 5]
    };
    function fixTextCoords(mapType, region) {
      if (mapType === 'china') {
        var coordFix = coordsOffsetMap[region.name];

        if (coordFix) {
          var cp = region.getCenter();
          cp[0] += coordFix[0] / 10.5;
          cp[1] += -coordFix[1] / (10.5 / 0.75);
          region.setCenter(cp);
        }
      }
    }

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


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * 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.
    */
    // Fix for 钓鱼岛
    // let Region = require('../Region');
    // let zrUtil = require('zrender/lib/core/util');
    // let geoCoord = [126, 25];
    var points$2 = [[[123.45165252685547, 25.73527164402261], [123.49731445312499, 25.73527164402261], [123.49731445312499, 25.750734064600884], [123.45165252685547, 25.750734064600884], [123.45165252685547, 25.73527164402261]]];
    function fixDiaoyuIsland(mapType, region) {
      if (mapType === 'china' && region.name === '台湾') {
        region.geometries.push({
          type: 'polygon',
          exterior: points$2[0]
        });
      }
    }

    var DEFAULT_NAME_PROPERTY = 'name';

    var GeoJSONResource =
    /** @class */
    function () {
      function GeoJSONResource(mapName, geoJSON, specialAreas) {
        this.type = 'geoJSON';
        this._parsedMap = createHashMap();
        this._mapName = mapName;
        this._specialAreas = specialAreas; // PENDING: delay the parse to the first usage to rapid up the FMP?

        this._geoJSON = parseInput(geoJSON);
      }
      /**
       * @param nameMap can be null/undefined
       * @param nameProperty can be null/undefined
       */


      GeoJSONResource.prototype.load = function (nameMap, nameProperty) {
        nameProperty = nameProperty || DEFAULT_NAME_PROPERTY;

        var parsed = this._parsedMap.get(nameProperty);

        if (!parsed) {
          var rawRegions = this._parseToRegions(nameProperty);

          parsed = this._parsedMap.set(nameProperty, {
            regions: rawRegions,
            boundingRect: calculateBoundingRect(rawRegions)
          });
        }

        var regionsMap = createHashMap();
        var finalRegions = [];
        each(parsed.regions, function (region) {
          var regionName = region.name; // Try use the alias in geoNameMap

          if (nameMap && hasOwn(nameMap, regionName)) {
            region = region.cloneShallow(regionName = nameMap[regionName]);
          }

          finalRegions.push(region);
          regionsMap.set(regionName, region);
        });
        return {
          regions: finalRegions,
          boundingRect: parsed.boundingRect || new BoundingRect(0, 0, 0, 0),
          regionsMap: regionsMap
        };
      };

      GeoJSONResource.prototype._parseToRegions = function (nameProperty) {
        var mapName = this._mapName;
        var geoJSON = this._geoJSON;
        var rawRegions; // https://jsperf.com/try-catch-performance-overhead

        try {
          rawRegions = geoJSON ? parseGeoJSON(geoJSON, nameProperty) : [];
        } catch (e) {
          throw new Error('Invalid geoJson format\n' + e.message);
        }

        fixNanhai(mapName, rawRegions);
        each(rawRegions, function (region) {
          var regionName = region.name;
          fixTextCoords(mapName, region);
          fixDiaoyuIsland(mapName, region); // Some area like Alaska in USA map needs to be tansformed
          // to look better

          var specialArea = this._specialAreas && this._specialAreas[regionName];

          if (specialArea) {
            region.transformTo(specialArea.left, specialArea.top, specialArea.width, specialArea.height);
          }
        }, this);
        return rawRegions;
      };
      /**
       * Only for exporting to users.
       * **MUST NOT** used internally.
       */


      GeoJSONResource.prototype.getMapForUser = function () {
        return {
          // For backward compatibility, use geoJson
          // PENDING: it has been returning them without clone.
          // do we need to avoid outsite modification?
          geoJson: this._geoJSON,
          geoJSON: this._geoJSON,
          specialAreas: this._specialAreas
        };
      };

      return GeoJSONResource;
    }();

    function calculateBoundingRect(regions) {
      var rect;

      for (var i = 0; i < regions.length; i++) {
        var regionRect = regions[i].getBoundingRect();
        rect = rect || regionRect.clone();
        rect.union(regionRect);
      }

      return rect;
    }

    function parseInput(source) {
      return !isString(source) ? source : typeof JSON !== 'undefined' && JSON.parse ? JSON.parse(source) : new Function('return (' + source + ');')();
    }

    var storage = createHashMap();
    var geoSourceManager = {
      /**
       * Compatible with previous `echarts.registerMap`.
       *
       * @usage
       * ```js
       *
       * echarts.registerMap('USA', geoJson, specialAreas);
       *
       * echarts.registerMap('USA', {
       *     geoJson: geoJson,
       *     specialAreas: {...}
       * });
       * echarts.registerMap('USA', {
       *     geoJSON: geoJson,
       *     specialAreas: {...}
       * });
       *
       * echarts.registerMap('airport', {
       *     svg: svg
       * }
       * ```
       *
       * Note:
       * Do not support that register multiple geoJSON or SVG
       * one map name. Because different geoJSON and SVG have
       * different unit. It's not easy to make sure how those
       * units are mapping/normalize.
       * If intending to use multiple geoJSON or SVG, we can
       * use multiple geo coordinate system.
       */
      registerMap: function (mapName, rawDef, rawSpecialAreas) {
        if (rawDef.svg) {
          var resource = new GeoSVGResource(mapName, rawDef.svg);
          storage.set(mapName, resource);
        } else {
          // Recommend:
          //     echarts.registerMap('eu', { geoJSON: xxx, specialAreas: xxx });
          // Backward compatibility:
          //     echarts.registerMap('eu', geoJSON, specialAreas);
          //     echarts.registerMap('eu', { geoJson: xxx, specialAreas: xxx });
          var geoJSON = rawDef.geoJson || rawDef.geoJSON;

          if (geoJSON && !rawDef.features) {
            rawSpecialAreas = rawDef.specialAreas;
          } else {
            geoJSON = rawDef;
          }

          var resource = new GeoJSONResource(mapName, geoJSON, rawSpecialAreas);
          storage.set(mapName, resource);
        }
      },
      getGeoResource: function (mapName) {
        return storage.get(mapName);
      },

      /**
       * Only for exporting to users.
       * **MUST NOT** used internally.
       */
      getMapForUser: function (mapName) {
        var resource = storage.get(mapName); // Do not support return SVG until some real requirement come.

        return resource && resource.type === 'geoJSON' && resource.getMapForUser();
      },
      load: function (mapName, nameMap, nameProperty) {
        var resource = storage.get(mapName);

        if (!resource) {
          if ("development" !== 'production') {
            console.error('Map ' + mapName + ' not exists. The GeoJSON of the map must be provided.');
          }

          return;
        }

        return resource.load(nameMap, nameProperty);
      }
    };

    /**
     * Only these tags enable use `itemStyle` if they are named in SVG.
     * Other tags like <text> <tspan> <image> might not suitable for `itemStyle`.
     * They will not be considered to be styled until some requirements come.
     */

    var OPTION_STYLE_ENABLED_TAGS = ['rect', 'circle', 'line', 'ellipse', 'polygon', 'polyline', 'path'];
    var OPTION_STYLE_ENABLED_TAG_MAP = createHashMap(OPTION_STYLE_ENABLED_TAGS);
    var STATE_TRIGGER_TAG_MAP = createHashMap(OPTION_STYLE_ENABLED_TAGS.concat(['g']));
    var LABEL_HOST_MAP = createHashMap(OPTION_STYLE_ENABLED_TAGS.concat(['g']));
    var mapLabelRaw = makeInner();

    function getFixedItemStyle(model) {
      var itemStyle = model.getItemStyle();
      var areaColor = model.get('areaColor'); // If user want the color not to be changed when hover,
      // they should both set areaColor and color to be null.

      if (areaColor != null) {
        itemStyle.fill = areaColor;
      }

      return itemStyle;
    } // Only stroke can be used for line.
    // Using fill in style if stroke not exits.
    // TODO Not sure yet. Perhaps a separate `lineStyle`?


    function fixLineStyle(styleHost) {
      var style = styleHost.style;

      if (style) {
        style.stroke = style.stroke || style.fill;
        style.fill = null;
      }
    }

    var MapDraw =
    /** @class */
    function () {
      function MapDraw(api) {
        var group = new Group();
        this.uid = getUID('ec_map_draw');
        this._controller = new RoamController(api.getZr());
        this._controllerHost = {
          target: group
        };
        this.group = group;
        group.add(this._regionsGroup = new Group());
        group.add(this._svgGroup = new Group());
      }

      MapDraw.prototype.draw = function (mapOrGeoModel, ecModel, api, fromView, payload) {
        var isGeo = mapOrGeoModel.mainType === 'geo'; // Map series has data. GEO model that controlled by map series
        // will be assigned with map data. Other GEO model has no data.

        var data = mapOrGeoModel.getData && mapOrGeoModel.getData();
        isGeo && ecModel.eachComponent({
          mainType: 'series',
          subType: 'map'
        }, function (mapSeries) {
          if (!data && mapSeries.getHostGeoModel() === mapOrGeoModel) {
            data = mapSeries.getData();
          }
        });
        var geo = mapOrGeoModel.coordinateSystem;
        var regionsGroup = this._regionsGroup;
        var group = this.group;
        var transformInfo = geo.getTransformInfo();
        var transformInfoRaw = transformInfo.raw;
        var transformInfoRoam = transformInfo.roam; // No animation when first draw or in action

        var isFirstDraw = !regionsGroup.childAt(0) || payload;

        if (isFirstDraw) {
          group.x = transformInfoRoam.x;
          group.y = transformInfoRoam.y;
          group.scaleX = transformInfoRoam.scaleX;
          group.scaleY = transformInfoRoam.scaleY;
          group.dirty();
        } else {
          updateProps(group, transformInfoRoam, mapOrGeoModel);
        }

        var isVisualEncodedByVisualMap = data && data.getVisual('visualMeta') && data.getVisual('visualMeta').length > 0;
        var viewBuildCtx = {
          api: api,
          geo: geo,
          mapOrGeoModel: mapOrGeoModel,
          data: data,
          isVisualEncodedByVisualMap: isVisualEncodedByVisualMap,
          isGeo: isGeo,
          transformInfoRaw: transformInfoRaw
        };

        if (geo.resourceType === 'geoJSON') {
          this._buildGeoJSON(viewBuildCtx);
        } else if (geo.resourceType === 'geoSVG') {
          this._buildSVG(viewBuildCtx);
        }

        this._updateController(mapOrGeoModel, ecModel, api);

        this._updateMapSelectHandler(mapOrGeoModel, regionsGroup, api, fromView);
      };

      MapDraw.prototype._buildGeoJSON = function (viewBuildCtx) {
        var regionsGroupByName = this._regionsGroupByName = createHashMap();
        var regionsInfoByName = createHashMap();
        var regionsGroup = this._regionsGroup;
        var transformInfoRaw = viewBuildCtx.transformInfoRaw;
        var mapOrGeoModel = viewBuildCtx.mapOrGeoModel;
        var data = viewBuildCtx.data;
        var projection = viewBuildCtx.geo.projection;
        var projectionStream = projection && projection.stream;

        function transformPoint(point, project) {
          if (project) {
            // projection may return null point.
            point = project(point);
          }

          return point && [point[0] * transformInfoRaw.scaleX + transformInfoRaw.x, point[1] * transformInfoRaw.scaleY + transformInfoRaw.y];
        }

        function transformPolygonPoints(inPoints) {
          var outPoints = []; // If projectionStream is provided. Use it instead of single point project.

          var project = !projectionStream && projection && projection.project;

          for (var i = 0; i < inPoints.length; ++i) {
            var newPt = transformPoint(inPoints[i], project);
            newPt && outPoints.push(newPt);
          }

          return outPoints;
        }

        function getPolyShape(points) {
          return {
            shape: {
              points: transformPolygonPoints(points)
            }
          };
        }

        regionsGroup.removeAll(); // Only when the resource is GeoJSON, there is `geo.regions`.

        each(viewBuildCtx.geo.regions, function (region) {
          var regionName = region.name; // Consider in GeoJson properties.name may be duplicated, for example,
          // there is multiple region named "United Kindom" or "France" (so many
          // colonies). And it is not appropriate to merge them in geo, which
          // will make them share the same label and bring trouble in label
          // location calculation.

          var regionGroup = regionsGroupByName.get(regionName);

          var _a = regionsInfoByName.get(regionName) || {},
              dataIdx = _a.dataIdx,
              regionModel = _a.regionModel;

          if (!regionGroup) {
            regionGroup = regionsGroupByName.set(regionName, new Group());
            regionsGroup.add(regionGroup);
            dataIdx = data ? data.indexOfName(regionName) : null;
            regionModel = viewBuildCtx.isGeo ? mapOrGeoModel.getRegionModel(regionName) : data ? data.getItemModel(dataIdx) : null;
            regionsInfoByName.set(regionName, {
              dataIdx: dataIdx,
              regionModel: regionModel
            });
          }

          var polygonSubpaths = [];
          var polylineSubpaths = [];
          each(region.geometries, function (geometry) {
            // Polygon and MultiPolygon
            if (geometry.type === 'polygon') {
              var polys = [geometry.exterior].concat(geometry.interiors || []);

              if (projectionStream) {
                polys = projectPolys(polys, projectionStream);
              }

              each(polys, function (poly) {
                polygonSubpaths.push(new Polygon(getPolyShape(poly)));
              });
            } // LineString and MultiLineString
            else {
                var points = geometry.points;

                if (projectionStream) {
                  points = projectPolys(points, projectionStream, true);
                }

                each(points, function (points) {
                  polylineSubpaths.push(new Polyline(getPolyShape(points)));
                });
              }
          });
          var centerPt = transformPoint(region.getCenter(), projection && projection.project);

          function createCompoundPath(subpaths, isLine) {
            if (!subpaths.length) {
              return;
            }

            var compoundPath = new CompoundPath({
              culling: true,
              segmentIgnoreThreshold: 1,
              shape: {
                paths: subpaths
              }
            });
            regionGroup.add(compoundPath);
            applyOptionStyleForRegion(viewBuildCtx, compoundPath, dataIdx, regionModel);
            resetLabelForRegion(viewBuildCtx, compoundPath, regionName, regionModel, mapOrGeoModel, dataIdx, centerPt);

            if (isLine) {
              fixLineStyle(compoundPath);
              each(compoundPath.states, fixLineStyle);
            }
          }

          createCompoundPath(polygonSubpaths);
          createCompoundPath(polylineSubpaths, true);
        }); // Ensure children have been added to `regionGroup` before calling them.

        regionsGroupByName.each(function (regionGroup, regionName) {
          var _a = regionsInfoByName.get(regionName),
              dataIdx = _a.dataIdx,
              regionModel = _a.regionModel;

          resetEventTriggerForRegion(viewBuildCtx, regionGroup, regionName, regionModel, mapOrGeoModel, dataIdx);
          resetTooltipForRegion(viewBuildCtx, regionGroup, regionName, regionModel, mapOrGeoModel);
          resetStateTriggerForRegion(viewBuildCtx, regionGroup, regionName, regionModel, mapOrGeoModel);
        }, this);
      };

      MapDraw.prototype._buildSVG = function (viewBuildCtx) {
        var mapName = viewBuildCtx.geo.map;
        var transformInfoRaw = viewBuildCtx.transformInfoRaw;
        this._svgGroup.x = transformInfoRaw.x;
        this._svgGroup.y = transformInfoRaw.y;
        this._svgGroup.scaleX = transformInfoRaw.scaleX;
        this._svgGroup.scaleY = transformInfoRaw.scaleY;

        if (this._svgResourceChanged(mapName)) {
          this._freeSVG();

          this._useSVG(mapName);
        }

        var svgDispatcherMap = this._svgDispatcherMap = createHashMap();
        var focusSelf = false;
        each(this._svgGraphicRecord.named, function (namedItem) {
          // Note that we also allow different elements have the same name.
          // For example, a glyph of a city and the label of the city have
          // the same name and their tooltip info can be defined in a single
          // region option.
          var regionName = namedItem.name;
          var mapOrGeoModel = viewBuildCtx.mapOrGeoModel;
          var data = viewBuildCtx.data;
          var svgNodeTagLower = namedItem.svgNodeTagLower;
          var el = namedItem.el;
          var dataIdx = data ? data.indexOfName(regionName) : null;
          var regionModel = mapOrGeoModel.getRegionModel(regionName);

          if (OPTION_STYLE_ENABLED_TAG_MAP.get(svgNodeTagLower) != null && el instanceof Displayable) {
            applyOptionStyleForRegion(viewBuildCtx, el, dataIdx, regionModel);
          }

          if (el instanceof Displayable) {
            el.culling = true;
          } // We do not know how the SVG like so we'd better not to change z2.
          // Otherwise it might bring some unexpected result. For example,
          // an area hovered that make some inner city can not be clicked.


          el.z2EmphasisLift = 0; // If self named:

          if (!namedItem.namedFrom) {
            // label should batter to be displayed based on the center of <g>
            // if it is named rather than displayed on each child.
            if (LABEL_HOST_MAP.get(svgNodeTagLower) != null) {
              resetLabelForRegion(viewBuildCtx, el, regionName, regionModel, mapOrGeoModel, dataIdx, null);
            }

            resetEventTriggerForRegion(viewBuildCtx, el, regionName, regionModel, mapOrGeoModel, dataIdx);
            resetTooltipForRegion(viewBuildCtx, el, regionName, regionModel, mapOrGeoModel);

            if (STATE_TRIGGER_TAG_MAP.get(svgNodeTagLower) != null) {
              var focus_1 = resetStateTriggerForRegion(viewBuildCtx, el, regionName, regionModel, mapOrGeoModel);

              if (focus_1 === 'self') {
                focusSelf = true;
              }

              var els = svgDispatcherMap.get(regionName) || svgDispatcherMap.set(regionName, []);
              els.push(el);
            }
          }
        }, this);

        this._enableBlurEntireSVG(focusSelf, viewBuildCtx);
      };

      MapDraw.prototype._enableBlurEntireSVG = function (focusSelf, viewBuildCtx) {
        // It's a little complicated to support blurring the entire geoSVG in series-map.
        // So do not suport it until some requirements come.
        // At present, in series-map, only regions can be blurred.
        if (focusSelf && viewBuildCtx.isGeo) {
          var blurStyle = viewBuildCtx.mapOrGeoModel.getModel(['blur', 'itemStyle']).getItemStyle(); // Only suport `opacity` here. Because not sure that other props are suitable for
          // all of the elements generated by SVG (especially for Text/TSpan/Image/... ).

          var opacity_1 = blurStyle.opacity;

          this._svgGraphicRecord.root.traverse(function (el) {
            if (!el.isGroup) {
              // PENDING: clear those settings to SVG elements when `_freeSVG`.
              // (Currently it happen not to be needed.)
              setDefaultStateProxy(el);
              var style = el.ensureState('blur').style || {}; // Do not overwrite the region style that already set from region option.

              if (style.opacity == null && opacity_1 != null) {
                style.opacity = opacity_1;
              } // If `ensureState('blur').style = {}`, there will be default opacity.
              // Enable `stateTransition` (animation).


              el.ensureState('emphasis');
            }
          });
        }
      };

      MapDraw.prototype.remove = function () {
        this._regionsGroup.removeAll();

        this._regionsGroupByName = null;

        this._svgGroup.removeAll();

        this._freeSVG();

        this._controller.dispose();

        this._controllerHost = null;
      };

      MapDraw.prototype.findHighDownDispatchers = function (name, geoModel) {
        if (name == null) {
          return [];
        }

        var geo = geoModel.coordinateSystem;

        if (geo.resourceType === 'geoJSON') {
          var regionsGroupByName = this._regionsGroupByName;

          if (regionsGroupByName) {
            var regionGroup = regionsGroupByName.get(name);
            return regionGroup ? [regionGroup] : [];
          }
        } else if (geo.resourceType === 'geoSVG') {
          return this._svgDispatcherMap && this._svgDispatcherMap.get(name) || [];
        }
      };

      MapDraw.prototype._svgResourceChanged = function (mapName) {
        return this._svgMapName !== mapName;
      };

      MapDraw.prototype._useSVG = function (mapName) {
        var resource = geoSourceManager.getGeoResource(mapName);

        if (resource && resource.type === 'geoSVG') {
          var svgGraphic = resource.useGraphic(this.uid);

          this._svgGroup.add(svgGraphic.root);

          this._svgGraphicRecord = svgGraphic;
          this._svgMapName = mapName;
        }
      };

      MapDraw.prototype._freeSVG = function () {
        var mapName = this._svgMapName;

        if (mapName == null) {
          return;
        }

        var resource = geoSourceManager.getGeoResource(mapName);

        if (resource && resource.type === 'geoSVG') {
          resource.freeGraphic(this.uid);
        }

        this._svgGraphicRecord = null;
        this._svgDispatcherMap = null;

        this._svgGroup.removeAll();

        this._svgMapName = null;
      };

      MapDraw.prototype._updateController = function (mapOrGeoModel, ecModel, api) {
        var geo = mapOrGeoModel.coordinateSystem;
        var controller = this._controller;
        var controllerHost = this._controllerHost; // @ts-ignore FIXME:TS

        controllerHost.zoomLimit = mapOrGeoModel.get('scaleLimit');
        controllerHost.zoom = geo.getZoom(); // roamType is will be set default true if it is null
        // @ts-ignore FIXME:TS

        controller.enable(mapOrGeoModel.get('roam') || false);
        var mainType = mapOrGeoModel.mainType;

        function makeActionBase() {
          var action = {
            type: 'geoRoam',
            componentType: mainType
          };
          action[mainType + 'Id'] = mapOrGeoModel.id;
          return action;
        }

        controller.off('pan').on('pan', function (e) {
          this._mouseDownFlag = false;
          updateViewOnPan(controllerHost, e.dx, e.dy);
          api.dispatchAction(extend(makeActionBase(), {
            dx: e.dx,
            dy: e.dy,
            animation: {
              duration: 0
            }
          }));
        }, this);
        controller.off('zoom').on('zoom', function (e) {
          this._mouseDownFlag = false;
          updateViewOnZoom(controllerHost, e.scale, e.originX, e.originY);
          api.dispatchAction(extend(makeActionBase(), {
            zoom: e.scale,
            originX: e.originX,
            originY: e.originY,
            animation: {
              duration: 0
            }
          }));
        }, this);
        controller.setPointerChecker(function (e, x, y) {
          return geo.containPoint([x, y]) && !onIrrelevantElement(e, api, mapOrGeoModel);
        });
      };
      /**
       * FIXME: this is a temporarily workaround.
       * When `geoRoam` the elements need to be reset in `MapView['render']`, because the props like
       * `ignore` might have been modified by `LabelManager`, and `LabelManager#addLabelsOfSeries`
       * will subsequently cache `defaultAttr` like `ignore`. If do not do this reset, the modified
       * props will have no chance to be restored.
       * Note: This reset should be after `clearStates` in `renderSeries` because `useStates` in
       * `renderSeries` will cache the modified `ignore` to `el._normalState`.
       * TODO:
       * Use clone/immutable in `LabelManager`?
       */


      MapDraw.prototype.resetForLabelLayout = function () {
        this.group.traverse(function (el) {
          var label = el.getTextContent();

          if (label) {
            label.ignore = mapLabelRaw(label).ignore;
          }
        });
      };

      MapDraw.prototype._updateMapSelectHandler = function (mapOrGeoModel, regionsGroup, api, fromView) {
        var mapDraw = this;
        regionsGroup.off('mousedown');
        regionsGroup.off('click'); // @ts-ignore FIXME:TS resolve type conflict

        if (mapOrGeoModel.get('selectedMode')) {
          regionsGroup.on('mousedown', function () {
            mapDraw._mouseDownFlag = true;
          });
          regionsGroup.on('click', function (e) {
            if (!mapDraw._mouseDownFlag) {
              return;
            }

            mapDraw._mouseDownFlag = false;
          });
        }
      };

      return MapDraw;
    }();

    function applyOptionStyleForRegion(viewBuildCtx, el, dataIndex, regionModel) {
      // All of the path are using `itemStyle`, because
      // (1) Some SVG also use fill on polyline (The different between
      // polyline and polygon is "open" or "close" but not fill or not).
      // (2) For the common props like opacity, if some use itemStyle
      // and some use `lineStyle`, it might confuse users.
      // (3) Most SVG use <path>, where can not detect wether draw a "line"
      // or a filled shape, so use `itemStyle` for <path>.
      var normalStyleModel = regionModel.getModel('itemStyle');
      var emphasisStyleModel = regionModel.getModel(['emphasis', 'itemStyle']);
      var blurStyleModel = regionModel.getModel(['blur', 'itemStyle']);
      var selectStyleModel = regionModel.getModel(['select', 'itemStyle']); // NOTE: DONT use 'style' in visual when drawing map.
      // This component is used for drawing underlying map for both geo component and map series.

      var normalStyle = getFixedItemStyle(normalStyleModel);
      var emphasisStyle = getFixedItemStyle(emphasisStyleModel);
      var selectStyle = getFixedItemStyle(selectStyleModel);
      var blurStyle = getFixedItemStyle(blurStyleModel); // Update the itemStyle if has data visual

      var data = viewBuildCtx.data;

      if (data) {
        // Only visual color of each item will be used. It can be encoded by visualMap
        // But visual color of series is used in symbol drawing
        // Visual color for each series is for the symbol draw
        var style = data.getItemVisual(dataIndex, 'style');
        var decal = data.getItemVisual(dataIndex, 'decal');

        if (viewBuildCtx.isVisualEncodedByVisualMap && style.fill) {
          normalStyle.fill = style.fill;
        }

        if (decal) {
          normalStyle.decal = createOrUpdatePatternFromDecal(decal, viewBuildCtx.api);
        }
      } // SVG text, tspan and image can be named but not supporeted
      // to be styled by region option yet.


      el.setStyle(normalStyle);
      el.style.strokeNoScale = true;
      el.ensureState('emphasis').style = emphasisStyle;
      el.ensureState('select').style = selectStyle;
      el.ensureState('blur').style = blurStyle; // Enable blur

      setDefaultStateProxy(el);
    }

    function resetLabelForRegion(viewBuildCtx, el, regionName, regionModel, mapOrGeoModel, // Exist only if `viewBuildCtx.data` exists.
    dataIdx, // If labelXY not provided, use `textConfig.position: 'inside'`
    labelXY) {
      var data = viewBuildCtx.data;
      var isGeo = viewBuildCtx.isGeo;
      var isDataNaN = data && isNaN(data.get(data.mapDimension('value'), dataIdx));
      var itemLayout = data && data.getItemLayout(dataIdx); // In the following cases label will be drawn
      // 1. In map series and data value is NaN
      // 2. In geo component
      // 3. Region has no series legendIcon, which will be add a showLabel flag in mapSymbolLayout

      if (isGeo || isDataNaN || itemLayout && itemLayout.showLabel) {
        var query = !isGeo ? dataIdx : regionName;
        var labelFetcher = void 0; // Consider dataIdx not found.

        if (!data || dataIdx >= 0) {
          labelFetcher = mapOrGeoModel;
        }

        var specifiedTextOpt = labelXY ? {
          normal: {
            align: 'center',
            verticalAlign: 'middle'
          }
        } : null; // Caveat: must be called after `setDefaultStateProxy(el);` called.
        // because textContent will be assign with `el.stateProxy` inside.

        setLabelStyle(el, getLabelStatesModels(regionModel), {
          labelFetcher: labelFetcher,
          labelDataIndex: query,
          defaultText: regionName
        }, specifiedTextOpt);
        var textEl = el.getTextContent();

        if (textEl) {
          mapLabelRaw(textEl).ignore = textEl.ignore;

          if (el.textConfig && labelXY) {
            // Compute a relative offset based on the el bounding rect.
            var rect = el.getBoundingRect().clone(); // Need to make sure the percent position base on the same rect in normal and
            // emphasis state. Otherwise if using boundingRect of el, but the emphasis state
            // has borderWidth (even 0.5px), the text position will be changed obviously
            // if the position is very big like ['1234%', '1345%'].

            el.textConfig.layoutRect = rect;
            el.textConfig.position = [(labelXY[0] - rect.x) / rect.width * 100 + '%', (labelXY[1] - rect.y) / rect.height * 100 + '%'];
          }
        } // PENDING:
        // If labelLayout is enabled (test/label-layout.html), el.dataIndex should be specified.
        // But el.dataIndex is also used to determine whether user event should be triggered,
        // where el.seriesIndex or el.dataModel must be specified. At present for a single el
        // there is not case that "only label layout enabled but user event disabled", so here
        // we depends `resetEventTriggerForRegion` to do the job of setting `el.dataIndex`.


        el.disableLabelAnimation = true;
      } else {
        el.removeTextContent();
        el.removeTextConfig();
        el.disableLabelAnimation = null;
      }
    }

    function resetEventTriggerForRegion(viewBuildCtx, eventTrigger, regionName, regionModel, mapOrGeoModel, // Exist only if `viewBuildCtx.data` exists.
    dataIdx) {
      // setItemGraphicEl, setHoverStyle after all polygons and labels
      // are added to the regionGroup
      if (viewBuildCtx.data) {
        // FIXME: when series-map use a SVG map, and there are duplicated name specified
        // on different SVG elements, after `data.setItemGraphicEl(...)`:
        // (1) all of them will be mounted with `dataIndex`, `seriesIndex`, so that tooltip
        // can be triggered only mouse hover. That's correct.
        // (2) only the last element will be kept in `data`, so that if trigger tooltip
        // by `dispatchAction`, only the last one can be found and triggered. That might be
        // not correct. We will fix it in future if anyone demanding that.
        viewBuildCtx.data.setItemGraphicEl(dataIdx, eventTrigger);
      } // series-map will not trigger "geoselectchange" no matter it is
      // based on a declared geo component. Because series-map will
      // trigger "selectchange". If it trigger both the two events,
      // If users call `chart.dispatchAction({type: 'toggleSelect'})`,
      // it not easy to also fire event "geoselectchanged".
      else {
          // Package custom mouse event for geo component
          getECData(eventTrigger).eventData = {
            componentType: 'geo',
            componentIndex: mapOrGeoModel.componentIndex,
            geoIndex: mapOrGeoModel.componentIndex,
            name: regionName,
            region: regionModel && regionModel.option || {}
          };
        }
    }

    function resetTooltipForRegion(viewBuildCtx, el, regionName, regionModel, mapOrGeoModel) {
      if (!viewBuildCtx.data) {
        setTooltipConfig({
          el: el,
          componentModel: mapOrGeoModel,
          itemName: regionName,
          // @ts-ignore FIXME:TS fix the "compatible with each other"?
          itemTooltipOption: regionModel.get('tooltip')
        });
      }
    }

    function resetStateTriggerForRegion(viewBuildCtx, el, regionName, regionModel, mapOrGeoModel) {
      // @ts-ignore FIXME:TS fix the "compatible with each other"?
      el.highDownSilentOnTouch = !!mapOrGeoModel.get('selectedMode'); // @ts-ignore FIXME:TS fix the "compatible with each other"?

      var emphasisModel = regionModel.getModel('emphasis');
      var focus = emphasisModel.get('focus');
      toggleHoverEmphasis(el, focus, emphasisModel.get('blurScope'), emphasisModel.get('disabled'));

      if (viewBuildCtx.isGeo) {
        enableComponentHighDownFeatures(el, mapOrGeoModel, regionName);
      }

      return focus;
    }

    function projectPolys(rings, // Polygons include exterior and interiors. Or polylines.
    createStream, isLine) {
      var polygons = [];
      var curPoly;

      function startPolygon() {
        curPoly = [];
      }

      function endPolygon() {
        if (curPoly.length) {
          polygons.push(curPoly);
          curPoly = [];
        }
      }

      var stream = createStream({
        polygonStart: startPolygon,
        polygonEnd: endPolygon,
        lineStart: startPolygon,
        lineEnd: endPolygon,
        point: function (x, y) {
          // May have NaN values from stream.
          if (isFinite(x) && isFinite(y)) {
            curPoly.push([x, y]);
          }
        },
        sphere: function () {}
      });
      !isLine && stream.polygonStart();
      each(rings, function (ring) {
        stream.lineStart();

        for (var i = 0; i < ring.length; i++) {
          stream.point(ring[i][0], ring[i][1]);
        }

        stream.lineEnd();
      });
      !isLine && stream.polygonEnd();
      return polygons;
    }
     // @ts-ignore FIXME:TS fix the "compatible with each other"?

    var MapView =
    /** @class */
    function (_super) {
      __extends(MapView, _super);

      function MapView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = MapView.type;
        return _this;
      }

      MapView.prototype.render = function (mapModel, ecModel, api, payload) {
        // Not render if it is an toggleSelect action from self
        if (payload && payload.type === 'mapToggleSelect' && payload.from === this.uid) {
          return;
        }

        var group = this.group;
        group.removeAll();

        if (mapModel.getHostGeoModel()) {
          return;
        }

        if (this._mapDraw && payload && payload.type === 'geoRoam') {
          this._mapDraw.resetForLabelLayout();
        } // Not update map if it is an roam action from self


        if (!(payload && payload.type === 'geoRoam' && payload.componentType === 'series' && payload.seriesId === mapModel.id)) {
          if (mapModel.needsDrawMap) {
            var mapDraw = this._mapDraw || new MapDraw(api);
            group.add(mapDraw.group);
            mapDraw.draw(mapModel, ecModel, api, this, payload);
            this._mapDraw = mapDraw;
          } else {
            // Remove drawn map
            this._mapDraw && this._mapDraw.remove();
            this._mapDraw = null;
          }
        } else {
          var mapDraw = this._mapDraw;
          mapDraw && group.add(mapDraw.group);
        }

        mapModel.get('showLegendSymbol') && ecModel.getComponent('legend') && this._renderSymbols(mapModel, ecModel, api);
      };

      MapView.prototype.remove = function () {
        this._mapDraw && this._mapDraw.remove();
        this._mapDraw = null;
        this.group.removeAll();
      };

      MapView.prototype.dispose = function () {
        this._mapDraw && this._mapDraw.remove();
        this._mapDraw = null;
      };

      MapView.prototype._renderSymbols = function (mapModel, ecModel, api) {
        var originalData = mapModel.originalData;
        var group = this.group;
        originalData.each(originalData.mapDimension('value'), function (value, originalDataIndex) {
          if (isNaN(value)) {
            return;
          }

          var layout = originalData.getItemLayout(originalDataIndex);

          if (!layout || !layout.point) {
            // Not exists in map
            return;
          }

          var point = layout.point;
          var offset = layout.offset;
          var circle = new Circle({
            style: {
              // Because the special of map draw.
              // Which needs statistic of multiple series and draw on one map.
              // And each series also need a symbol with legend color
              //
              // Layout and visual are put one the different data
              // TODO
              fill: mapModel.getData().getVisual('style').fill
            },
            shape: {
              cx: point[0] + offset * 9,
              cy: point[1],
              r: 3
            },
            silent: true,
            // Do not overlap the first series, on which labels are displayed.
            z2: 8 + (!offset ? Z2_EMPHASIS_LIFT + 1 : 0)
          }); // Only the series that has the first value on the same region is in charge of rendering the label.
          // But consider the case:
          // series: [
          //     {id: 'X', type: 'map', map: 'm', {data: [{name: 'A', value: 11}, {name: 'B', {value: 22}]},
          //     {id: 'Y', type: 'map', map: 'm', {data: [{name: 'A', value: 21}, {name: 'C', {value: 33}]}
          // ]
          // The offset `0` of item `A` is at series `X`, but of item `C` is at series `Y`.
          // For backward compatibility, we follow the rule that render label `A` by the
          // settings on series `X` but render label `C` by the settings on series `Y`.

          if (!offset) {
            var fullData = mapModel.mainSeries.getData();
            var name_1 = originalData.getName(originalDataIndex);
            var fullIndex_1 = fullData.indexOfName(name_1);
            var itemModel = originalData.getItemModel(originalDataIndex);
            var labelModel = itemModel.getModel('label');
            var regionGroup = fullData.getItemGraphicEl(fullIndex_1); // `getFormattedLabel` needs to use `getData` inside. Here
            // `mapModel.getData()` is shallow cloned from `mainSeries.getData()`.
            // FIXME
            // If this is not the `mainSeries`, the item model (like label formatter)
            // set on original data item will never get. But it has been working
            // like that from the beginning, and this scenario is rarely encountered.
            // So it won't be fixed until we have to.

            setLabelStyle(circle, getLabelStatesModels(itemModel), {
              labelFetcher: {
                getFormattedLabel: function (idx, state) {
                  return mapModel.getFormattedLabel(fullIndex_1, state);
                }
              },
              defaultText: name_1
            });
            circle.disableLabelAnimation = true;

            if (!labelModel.get('position')) {
              circle.setTextConfig({
                position: 'bottom'
              });
            }

            regionGroup.onHoverStateChange = function (toState) {
              setStatesFlag(circle, toState);
            };
          }

          group.add(circle);
        });
      };

      MapView.type = 'map';
      return MapView;
    }(ChartView);

    var MapSeries =
    /** @class */
    function (_super) {
      __extends(MapSeries, _super);

      function MapSeries() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = MapSeries.type; // Only first map series of same mapType will drawMap.

        _this.needsDrawMap = false; // Group of all map series with same mapType

        _this.seriesGroup = [];

        _this.getTooltipPosition = function (dataIndex) {
          if (dataIndex != null) {
            var name_1 = this.getData().getName(dataIndex);
            var geo = this.coordinateSystem;
            var region = geo.getRegion(name_1);
            return region && geo.dataToPoint(region.getCenter());
          }
        };

        return _this;
      }

      MapSeries.prototype.getInitialData = function (option) {
        var data = createSeriesDataSimply(this, {
          coordDimensions: ['value'],
          encodeDefaulter: curry(makeSeriesEncodeForNameBased, this)
        });
        var dataNameMap = createHashMap();
        var toAppendNames = [];

        for (var i = 0, len = data.count(); i < len; i++) {
          var name_2 = data.getName(i);
          dataNameMap.set(name_2, true);
        }

        var geoSource = geoSourceManager.load(this.getMapType(), this.option.nameMap, this.option.nameProperty);
        each(geoSource.regions, function (region) {
          var name = region.name;

          if (!dataNameMap.get(name)) {
            toAppendNames.push(name);
          }
        }); // Complete data with missing regions. The consequent processes (like visual
        // map and render) can not be performed without a "full data". For example,
        // find `dataIndex` by name.

        data.appendValues([], toAppendNames);
        return data;
      };
      /**
       * If no host geo model, return null, which means using a
       * inner exclusive geo model.
       */


      MapSeries.prototype.getHostGeoModel = function () {
        var geoIndex = this.option.geoIndex;
        return geoIndex != null ? this.ecModel.getComponent('geo', geoIndex) : null;
      };

      MapSeries.prototype.getMapType = function () {
        return (this.getHostGeoModel() || this).option.map;
      }; // _fillOption(option, mapName) {
      // Shallow clone
      // option = zrUtil.extend({}, option);
      // option.data = geoCreator.getFilledRegions(option.data, mapName, option.nameMap);
      // return option;
      // }


      MapSeries.prototype.getRawValue = function (dataIndex) {
        // Use value stored in data instead because it is calculated from multiple series
        // FIXME Provide all value of multiple series ?
        var data = this.getData();
        return data.get(data.mapDimension('value'), dataIndex);
      };
      /**
       * Get model of region
       */


      MapSeries.prototype.getRegionModel = function (regionName) {
        var data = this.getData();
        return data.getItemModel(data.indexOfName(regionName));
      };
      /**
       * Map tooltip formatter
       */


      MapSeries.prototype.formatTooltip = function (dataIndex, multipleSeries, dataType) {
        // FIXME orignalData and data is a bit confusing
        var data = this.getData();
        var value = this.getRawValue(dataIndex);
        var name = data.getName(dataIndex);
        var seriesGroup = this.seriesGroup;
        var seriesNames = [];

        for (var i = 0; i < seriesGroup.length; i++) {
          var otherIndex = seriesGroup[i].originalData.indexOfName(name);
          var valueDim = data.mapDimension('value');

          if (!isNaN(seriesGroup[i].originalData.get(valueDim, otherIndex))) {
            seriesNames.push(seriesGroup[i].name);
          }
        }

        return createTooltipMarkup('section', {
          header: seriesNames.join(', '),
          noHeader: !seriesNames.length,
          blocks: [createTooltipMarkup('nameValue', {
            name: name,
            value: value
          })]
        });
      };

      MapSeries.prototype.setZoom = function (zoom) {
        this.option.zoom = zoom;
      };

      MapSeries.prototype.setCenter = function (center) {
        this.option.center = center;
      };

      MapSeries.prototype.getLegendIcon = function (opt) {
        var iconType = opt.icon || 'roundRect';
        var icon = createSymbol(iconType, 0, 0, opt.itemWidth, opt.itemHeight, opt.itemStyle.fill);
        icon.setStyle(opt.itemStyle); // Map do not use itemStyle.borderWidth as border width

        icon.style.stroke = 'none'; // No rotation because no series visual symbol for map

        if (iconType.indexOf('empty') > -1) {
          icon.style.stroke = icon.style.fill;
          icon.style.fill = '#fff';
          icon.style.lineWidth = 2;
        }

        return icon;
      };

      MapSeries.type = 'series.map';
      MapSeries.dependencies = ['geo'];
      MapSeries.layoutMode = 'box';
      MapSeries.defaultOption = {
        // 一级层叠
        // zlevel: 0,
        // 二级层叠
        z: 2,
        coordinateSystem: 'geo',
        // map should be explicitly specified since ec3.
        map: '',
        // If `geoIndex` is not specified, a exclusive geo will be
        // created. Otherwise use the specified geo component, and
        // `map` and `mapType` are ignored.
        // geoIndex: 0,
        // 'center' | 'left' | 'right' | 'x%' | {number}
        left: 'center',
        // 'center' | 'top' | 'bottom' | 'x%' | {number}
        top: 'center',
        // right
        // bottom
        // width:
        // height
        // Aspect is width / height. Inited to be geoJson bbox aspect
        // This parameter is used for scale this aspect
        // Default value:
        // for geoSVG source: 1,
        // for geoJSON source: 0.75.
        aspectScale: null,
        // Layout with center and size
        // If you want to put map in a fixed size box with right aspect ratio
        // This two properties may be more convenient.
        // layoutCenter: [50%, 50%]
        // layoutSize: 100
        showLegendSymbol: true,
        // Define left-top, right-bottom coords to control view
        // For example, [ [180, 90], [-180, -90] ],
        // higher priority than center and zoom
        boundingCoords: null,
        // Default on center of map
        center: null,
        zoom: 1,
        scaleLimit: null,
        selectedMode: true,
        label: {
          show: false,
          color: '#000'
        },
        // scaleLimit: null,
        itemStyle: {
          borderWidth: 0.5,
          borderColor: '#444',
          areaColor: '#eee'
        },
        emphasis: {
          label: {
            show: true,
            color: 'rgb(100,0,0)'
          },
          itemStyle: {
            areaColor: 'rgba(255,215,0,0.8)'
          }
        },
        select: {
          label: {
            show: true,
            color: 'rgb(100,0,0)'
          },
          itemStyle: {
            color: 'rgba(255,215,0,0.8)'
          }
        },
        nameProperty: 'name'
      };
      return MapSeries;
    }(SeriesModel);

    function dataStatistics(datas, statisticType) {
      var dataNameMap = {};
      each(datas, function (data) {
        data.each(data.mapDimension('value'), function (value, idx) {
          // Add prefix to avoid conflict with Object.prototype.
          var mapKey = 'ec-' + data.getName(idx);
          dataNameMap[mapKey] = dataNameMap[mapKey] || [];

          if (!isNaN(value)) {
            dataNameMap[mapKey].push(value);
          }
        });
      });
      return datas[0].map(datas[0].mapDimension('value'), function (value, idx) {
        var mapKey = 'ec-' + datas[0].getName(idx);
        var sum = 0;
        var min = Infinity;
        var max = -Infinity;
        var len = dataNameMap[mapKey].length;

        for (var i = 0; i < len; i++) {
          min = Math.min(min, dataNameMap[mapKey][i]);
          max = Math.max(max, dataNameMap[mapKey][i]);
          sum += dataNameMap[mapKey][i];
        }

        var result;

        if (statisticType === 'min') {
          result = min;
        } else if (statisticType === 'max') {
          result = max;
        } else if (statisticType === 'average') {
          result = sum / len;
        } else {
          result = sum;
        }

        return len === 0 ? NaN : result;
      });
    }

    function mapDataStatistic(ecModel) {
      var seriesGroups = {};
      ecModel.eachSeriesByType('map', function (seriesModel) {
        var hostGeoModel = seriesModel.getHostGeoModel();
        var key = hostGeoModel ? 'o' + hostGeoModel.id : 'i' + seriesModel.getMapType();
        (seriesGroups[key] = seriesGroups[key] || []).push(seriesModel);
      });
      each(seriesGroups, function (seriesList, key) {
        var data = dataStatistics(map(seriesList, function (seriesModel) {
          return seriesModel.getData();
        }), seriesList[0].get('mapValueCalculation'));

        for (var i = 0; i < seriesList.length; i++) {
          seriesList[i].originalData = seriesList[i].getData();
        } // FIXME Put where?


        for (var i = 0; i < seriesList.length; i++) {
          seriesList[i].seriesGroup = seriesList;
          seriesList[i].needsDrawMap = i === 0 && !seriesList[i].getHostGeoModel();
          seriesList[i].setData(data.cloneShallow());
          seriesList[i].mainSeries = seriesList[0];
        }
      });
    }

    function mapSymbolLayout(ecModel) {
      var processedMapType = {};
      ecModel.eachSeriesByType('map', function (mapSeries) {
        var mapType = mapSeries.getMapType();

        if (mapSeries.getHostGeoModel() || processedMapType[mapType]) {
          return;
        }

        var mapSymbolOffsets = {};
        each(mapSeries.seriesGroup, function (subMapSeries) {
          var geo = subMapSeries.coordinateSystem;
          var data = subMapSeries.originalData;

          if (subMapSeries.get('showLegendSymbol') && ecModel.getComponent('legend')) {
            data.each(data.mapDimension('value'), function (value, idx) {
              var name = data.getName(idx);
              var region = geo.getRegion(name); // If input series.data is [11, 22, '-'/null/undefined, 44],
              // it will be filled with NaN: [11, 22, NaN, 44] and NaN will
              // not be drawn. So here must validate if value is NaN.

              if (!region || isNaN(value)) {
                return;
              }

              var offset = mapSymbolOffsets[name] || 0;
              var point = geo.dataToPoint(region.getCenter());
              mapSymbolOffsets[name] = offset + 1;
              data.setItemLayout(idx, {
                point: point,
                offset: offset
              });
            });
          }
        }); // Show label of those region not has legendIcon (which is offset 0)

        var data = mapSeries.getData();
        data.each(function (idx) {
          var name = data.getName(idx);
          var layout = data.getItemLayout(idx) || {};
          layout.showLabel = !mapSymbolOffsets[name];
          data.setItemLayout(idx, layout);
        });
        processedMapType[mapType] = true;
      });
    }

    var v2ApplyTransform = applyTransform;

    var View =
    /** @class */
    function (_super) {
      __extends(View, _super);

      function View(name) {
        var _this = _super.call(this) || this;

        _this.type = 'view';
        _this.dimensions = ['x', 'y'];
        /**
         * Represents the transform brought by roam/zoom.
         * If `View['_viewRect']` applies roam transform,
         * we can get the final displayed rect.
         */

        _this._roamTransformable = new Transformable();
        /**
         * Represents the transform from `View['_rect']` to `View['_viewRect']`.
         */

        _this._rawTransformable = new Transformable();
        _this.name = name;
        return _this;
      }

      View.prototype.setBoundingRect = function (x, y, width, height) {
        this._rect = new BoundingRect(x, y, width, height);
        return this._rect;
      };
      /**
       * @return {module:zrender/core/BoundingRect}
       */


      View.prototype.getBoundingRect = function () {
        return this._rect;
      };

      View.prototype.setViewRect = function (x, y, width, height) {
        this._transformTo(x, y, width, height);

        this._viewRect = new BoundingRect(x, y, width, height);
      };
      /**
       * Transformed to particular position and size
       */


      View.prototype._transformTo = function (x, y, width, height) {
        var rect = this.getBoundingRect();
        var rawTransform = this._rawTransformable;
        rawTransform.transform = rect.calculateTransform(new BoundingRect(x, y, width, height));
        var rawParent = rawTransform.parent;
        rawTransform.parent = null;
        rawTransform.decomposeTransform();
        rawTransform.parent = rawParent;

        this._updateTransform();
      };
      /**
       * Set center of view
       */


      View.prototype.setCenter = function (centerCoord, api) {
        if (!centerCoord) {
          return;
        }

        this._center = [parsePercent$1(centerCoord[0], api.getWidth()), parsePercent$1(centerCoord[1], api.getHeight())];

        this._updateCenterAndZoom();
      };

      View.prototype.setZoom = function (zoom) {
        zoom = zoom || 1;
        var zoomLimit = this.zoomLimit;

        if (zoomLimit) {
          if (zoomLimit.max != null) {
            zoom = Math.min(zoomLimit.max, zoom);
          }

          if (zoomLimit.min != null) {
            zoom = Math.max(zoomLimit.min, zoom);
          }
        }

        this._zoom = zoom;

        this._updateCenterAndZoom();
      };
      /**
       * Get default center without roam
       */


      View.prototype.getDefaultCenter = function () {
        // Rect before any transform
        var rawRect = this.getBoundingRect();
        var cx = rawRect.x + rawRect.width / 2;
        var cy = rawRect.y + rawRect.height / 2;
        return [cx, cy];
      };

      View.prototype.getCenter = function () {
        return this._center || this.getDefaultCenter();
      };

      View.prototype.getZoom = function () {
        return this._zoom || 1;
      };

      View.prototype.getRoamTransform = function () {
        return this._roamTransformable.getLocalTransform();
      };
      /**
       * Remove roam
       */


      View.prototype._updateCenterAndZoom = function () {
        // Must update after view transform updated
        var rawTransformMatrix = this._rawTransformable.getLocalTransform();

        var roamTransform = this._roamTransformable;
        var defaultCenter = this.getDefaultCenter();
        var center = this.getCenter();
        var zoom = this.getZoom();
        center = applyTransform([], center, rawTransformMatrix);
        defaultCenter = applyTransform([], defaultCenter, rawTransformMatrix);
        roamTransform.originX = center[0];
        roamTransform.originY = center[1];
        roamTransform.x = defaultCenter[0] - center[0];
        roamTransform.y = defaultCenter[1] - center[1];
        roamTransform.scaleX = roamTransform.scaleY = zoom;

        this._updateTransform();
      };
      /**
       * Update transform props on `this` based on the current
       * `this._roamTransformable` and `this._rawTransformable`.
       */


      View.prototype._updateTransform = function () {
        var roamTransformable = this._roamTransformable;
        var rawTransformable = this._rawTransformable;
        rawTransformable.parent = roamTransformable;
        roamTransformable.updateTransform();
        rawTransformable.updateTransform();
        copy$1(this.transform || (this.transform = []), rawTransformable.transform || create$1());
        this._rawTransform = rawTransformable.getLocalTransform();
        this.invTransform = this.invTransform || [];
        invert(this.invTransform, this.transform);
        this.decomposeTransform();
      };

      View.prototype.getTransformInfo = function () {
        var rawTransformable = this._rawTransformable;
        var roamTransformable = this._roamTransformable; // Because roamTransformabel has `originX/originY` modified,
        // but the caller of `getTransformInfo` can not handle `originX/originY`,
        // so need to recalculate them.

        var dummyTransformable = new Transformable();
        dummyTransformable.transform = roamTransformable.transform;
        dummyTransformable.decomposeTransform();
        return {
          roam: {
            x: dummyTransformable.x,
            y: dummyTransformable.y,
            scaleX: dummyTransformable.scaleX,
            scaleY: dummyTransformable.scaleY
          },
          raw: {
            x: rawTransformable.x,
            y: rawTransformable.y,
            scaleX: rawTransformable.scaleX,
            scaleY: rawTransformable.scaleY
          }
        };
      };

      View.prototype.getViewRect = function () {
        return this._viewRect;
      };
      /**
       * Get view rect after roam transform
       */


      View.prototype.getViewRectAfterRoam = function () {
        var rect = this.getBoundingRect().clone();
        rect.applyTransform(this.transform);
        return rect;
      };
      /**
       * Convert a single (lon, lat) data item to (x, y) point.
       */


      View.prototype.dataToPoint = function (data, noRoam, out) {
        var transform = noRoam ? this._rawTransform : this.transform;
        out = out || [];
        return transform ? v2ApplyTransform(out, data, transform) : copy(out, data);
      };
      /**
       * Convert a (x, y) point to (lon, lat) data
       */


      View.prototype.pointToData = function (point) {
        var invTransform = this.invTransform;
        return invTransform ? v2ApplyTransform([], point, invTransform) : [point[0], point[1]];
      };

      View.prototype.convertToPixel = function (ecModel, finder, value) {
        var coordSys = getCoordSys(finder);
        return coordSys === this ? coordSys.dataToPoint(value) : null;
      };

      View.prototype.convertFromPixel = function (ecModel, finder, pixel) {
        var coordSys = getCoordSys(finder);
        return coordSys === this ? coordSys.pointToData(pixel) : null;
      };
      /**
       * @implements
       */


      View.prototype.containPoint = function (point) {
        return this.getViewRectAfterRoam().contain(point[0], point[1]);
      };

      View.dimensions = ['x', 'y'];
      return View;
    }(Transformable);

    function getCoordSys(finder) {
      var seriesModel = finder.seriesModel;
      return seriesModel ? seriesModel.coordinateSystem : null; // e.g., graph.
    }

    var GEO_DEFAULT_PARAMS = {
      'geoJSON': {
        aspectScale: 0.75,
        invertLongitute: true
      },
      'geoSVG': {
        aspectScale: 1,
        invertLongitute: false
      }
    };
    var geo2DDimensions = ['lng', 'lat'];

    var Geo =
    /** @class */
    function (_super) {
      __extends(Geo, _super);

      function Geo(name, map, opt) {
        var _this = _super.call(this, name) || this;

        _this.dimensions = geo2DDimensions;
        _this.type = 'geo'; // Only store specified name coord via `addGeoCoord`.

        _this._nameCoordMap = createHashMap();
        _this.map = map;
        var projection = opt.projection;
        var source = geoSourceManager.load(map, opt.nameMap, opt.nameProperty);
        var resource = geoSourceManager.getGeoResource(map);
        var resourceType = _this.resourceType = resource ? resource.type : null;
        var regions = _this.regions = source.regions;
        var defaultParams = GEO_DEFAULT_PARAMS[resource.type];
        _this._regionsMap = source.regionsMap;
        _this.regions = source.regions;

        if ("development" !== 'production' && projection) {
          // Do some check
          if (resourceType === 'geoSVG') {
            if ("development" !== 'production') {
              warn("Map " + map + " with SVG source can't use projection. Only GeoJSON source supports projection.");
            }

            projection = null;
          }

          if (!(projection.project && projection.unproject)) {
            if ("development" !== 'production') {
              warn('project and unproject must be both provided in the projeciton.');
            }

            projection = null;
          }
        }

        _this.projection = projection;
        var boundingRect;

        if (projection) {
          // Can't reuse the raw bounding rect
          for (var i = 0; i < regions.length; i++) {
            var regionRect = regions[i].getBoundingRect(projection);
            boundingRect = boundingRect || regionRect.clone();
            boundingRect.union(regionRect);
          }
        } else {
          boundingRect = source.boundingRect;
        }

        _this.setBoundingRect(boundingRect.x, boundingRect.y, boundingRect.width, boundingRect.height); // aspectScale and invertLongitute actually is the parameters default raw projection.
        // So we ignore them if projection is given.
        // Ignore default aspect scale if projection exits.


        _this.aspectScale = projection ? 1 : retrieve2(opt.aspectScale, defaultParams.aspectScale); // Not invert longitude if projection exits.

        _this._invertLongitute = projection ? false : defaultParams.invertLongitute;
        return _this;
      }

      Geo.prototype._transformTo = function (x, y, width, height) {
        var rect = this.getBoundingRect();
        var invertLongitute = this._invertLongitute;
        rect = rect.clone();

        if (invertLongitute) {
          // Longitude is inverted.
          rect.y = -rect.y - rect.height;
        }

        var rawTransformable = this._rawTransformable;
        rawTransformable.transform = rect.calculateTransform(new BoundingRect(x, y, width, height));
        var rawParent = rawTransformable.parent;
        rawTransformable.parent = null;
        rawTransformable.decomposeTransform();
        rawTransformable.parent = rawParent;

        if (invertLongitute) {
          rawTransformable.scaleY = -rawTransformable.scaleY;
        }

        this._updateTransform();
      };

      Geo.prototype.getRegion = function (name) {
        return this._regionsMap.get(name);
      };

      Geo.prototype.getRegionByCoord = function (coord) {
        var regions = this.regions;

        for (var i = 0; i < regions.length; i++) {
          var region = regions[i];

          if (region.type === 'geoJSON' && region.contain(coord)) {
            return regions[i];
          }
        }
      };
      /**
       * Add geoCoord for indexing by name
       */


      Geo.prototype.addGeoCoord = function (name, geoCoord) {
        this._nameCoordMap.set(name, geoCoord);
      };
      /**
       * Get geoCoord by name
       */


      Geo.prototype.getGeoCoord = function (name) {
        var region = this._regionsMap.get(name); // Calculate center only on demand.


        return this._nameCoordMap.get(name) || region && region.getCenter();
      };

      Geo.prototype.dataToPoint = function (data, noRoam, out) {
        if (isString(data)) {
          // Map area name to geoCoord
          data = this.getGeoCoord(data);
        }

        if (data) {
          var projection = this.projection;

          if (projection) {
            // projection may return null point.
            data = projection.project(data);
          }

          return data && this.projectedToPoint(data, noRoam, out);
        }
      };

      Geo.prototype.pointToData = function (point) {
        var projection = this.projection;

        if (projection) {
          // projection may return null point.
          point = projection.unproject(point);
        }

        return point && this.pointToProjected(point);
      };
      /**
       * Point to projected data. Same with pointToData when projection is used.
       */


      Geo.prototype.pointToProjected = function (point) {
        return _super.prototype.pointToData.call(this, point);
      };

      Geo.prototype.projectedToPoint = function (projected, noRoam, out) {
        return _super.prototype.dataToPoint.call(this, projected, noRoam, out);
      };

      Geo.prototype.convertToPixel = function (ecModel, finder, value) {
        var coordSys = getCoordSys$1(finder);
        return coordSys === this ? coordSys.dataToPoint(value) : null;
      };

      Geo.prototype.convertFromPixel = function (ecModel, finder, pixel) {
        var coordSys = getCoordSys$1(finder);
        return coordSys === this ? coordSys.pointToData(pixel) : null;
      };

      return Geo;
    }(View);
    mixin(Geo, View);

    function getCoordSys$1(finder) {
      var geoModel = finder.geoModel;
      var seriesModel = finder.seriesModel;
      return geoModel ? geoModel.coordinateSystem : seriesModel ? seriesModel.coordinateSystem // For map series.
      || (seriesModel.getReferringComponents('geo', SINGLE_REFERRING).models[0] || {}).coordinateSystem : null;
    }

    /**
     * Resize method bound to the geo
     */

    function resizeGeo(geoModel, api) {
      var boundingCoords = geoModel.get('boundingCoords');

      if (boundingCoords != null) {
        var leftTop_1 = boundingCoords[0];
        var rightBottom_1 = boundingCoords[1];

        if (!(isFinite(leftTop_1[0]) && isFinite(leftTop_1[1]) && isFinite(rightBottom_1[0]) && isFinite(rightBottom_1[1]))) {
          if ("development" !== 'production') {
            console.error('Invalid boundingCoords');
          }
        } else {
          // Sample around the lng/lat rect and use projection to calculate actual bounding rect.
          var projection_1 = this.projection;

          if (projection_1) {
            var xMin = leftTop_1[0];
            var yMin = leftTop_1[1];
            var xMax = rightBottom_1[0];
            var yMax = rightBottom_1[1];
            leftTop_1 = [Infinity, Infinity];
            rightBottom_1 = [-Infinity, -Infinity]; // TODO better way?

            var sampleLine = function (x0, y0, x1, y1) {
              var dx = x1 - x0;
              var dy = y1 - y0;

              for (var i = 0; i <= 100; i++) {
                var p = i / 100;
                var pt = projection_1.project([x0 + dx * p, y0 + dy * p]);
                min(leftTop_1, leftTop_1, pt);
                max(rightBottom_1, rightBottom_1, pt);
              }
            }; // Top


            sampleLine(xMin, yMin, xMax, yMin); // Right

            sampleLine(xMax, yMin, xMax, yMax); // Bottom

            sampleLine(xMax, yMax, xMin, yMax); // Left

            sampleLine(xMin, yMax, xMax, yMin);
          }

          this.setBoundingRect(leftTop_1[0], leftTop_1[1], rightBottom_1[0] - leftTop_1[0], rightBottom_1[1] - leftTop_1[1]);
        }
      }

      var rect = this.getBoundingRect();
      var centerOption = geoModel.get('layoutCenter');
      var sizeOption = geoModel.get('layoutSize');
      var viewWidth = api.getWidth();
      var viewHeight = api.getHeight();
      var aspect = rect.width / rect.height * this.aspectScale;
      var useCenterAndSize = false;
      var center;
      var size;

      if (centerOption && sizeOption) {
        center = [parsePercent$1(centerOption[0], viewWidth), parsePercent$1(centerOption[1], viewHeight)];
        size = parsePercent$1(sizeOption, Math.min(viewWidth, viewHeight));

        if (!isNaN(center[0]) && !isNaN(center[1]) && !isNaN(size)) {
          useCenterAndSize = true;
        } else {
          if ("development" !== 'production') {
            console.warn('Given layoutCenter or layoutSize data are invalid. Use left/top/width/height instead.');
          }
        }
      }

      var viewRect;

      if (useCenterAndSize) {
        viewRect = {};

        if (aspect > 1) {
          // Width is same with size
          viewRect.width = size;
          viewRect.height = size / aspect;
        } else {
          viewRect.height = size;
          viewRect.width = size * aspect;
        }

        viewRect.y = center[1] - viewRect.height / 2;
        viewRect.x = center[0] - viewRect.width / 2;
      } else {
        // Use left/top/width/height
        var boxLayoutOption = geoModel.getBoxLayoutParams();
        boxLayoutOption.aspect = aspect;
        viewRect = getLayoutRect(boxLayoutOption, {
          width: viewWidth,
          height: viewHeight
        });
      }

      this.setViewRect(viewRect.x, viewRect.y, viewRect.width, viewRect.height);
      this.setCenter(geoModel.get('center'), api);
      this.setZoom(geoModel.get('zoom'));
    } // Back compat for ECharts2, where the coord map is set on map series:
    // {type: 'map', geoCoord: {'cityA': [116.46,39.92], 'cityA': [119.12,24.61]}},


    function setGeoCoords(geo, model) {
      each(model.get('geoCoord'), function (geoCoord, name) {
        geo.addGeoCoord(name, geoCoord);
      });
    }

    var GeoCreator =
    /** @class */
    function () {
      function GeoCreator() {
        // For deciding which dimensions to use when creating list data
        this.dimensions = geo2DDimensions;
      }

      GeoCreator.prototype.create = function (ecModel, api) {
        var geoList = [];

        function getCommonGeoProperties(model) {
          return {
            nameProperty: model.get('nameProperty'),
            aspectScale: model.get('aspectScale'),
            projection: model.get('projection')
          };
        } // FIXME Create each time may be slow


        ecModel.eachComponent('geo', function (geoModel, idx) {
          var mapName = geoModel.get('map');
          var geo = new Geo(mapName + idx, mapName, extend({
            nameMap: geoModel.get('nameMap')
          }, getCommonGeoProperties(geoModel)));
          geo.zoomLimit = geoModel.get('scaleLimit');
          geoList.push(geo); // setGeoCoords(geo, geoModel);

          geoModel.coordinateSystem = geo;
          geo.model = geoModel; // Inject resize method

          geo.resize = resizeGeo;
          geo.resize(geoModel, api);
        });
        ecModel.eachSeries(function (seriesModel) {
          var coordSys = seriesModel.get('coordinateSystem');

          if (coordSys === 'geo') {
            var geoIndex = seriesModel.get('geoIndex') || 0;
            seriesModel.coordinateSystem = geoList[geoIndex];
          }
        }); // If has map series

        var mapModelGroupBySeries = {};
        ecModel.eachSeriesByType('map', function (seriesModel) {
          if (!seriesModel.getHostGeoModel()) {
            var mapType = seriesModel.getMapType();
            mapModelGroupBySeries[mapType] = mapModelGroupBySeries[mapType] || [];
            mapModelGroupBySeries[mapType].push(seriesModel);
          }
        });
        each(mapModelGroupBySeries, function (mapSeries, mapType) {
          var nameMapList = map(mapSeries, function (singleMapSeries) {
            return singleMapSeries.get('nameMap');
          });
          var geo = new Geo(mapType, mapType, extend({
            nameMap: mergeAll(nameMapList)
          }, getCommonGeoProperties(mapSeries[0])));
          geo.zoomLimit = retrieve.apply(null, map(mapSeries, function (singleMapSeries) {
            return singleMapSeries.get('scaleLimit');
          }));
          geoList.push(geo); // Inject resize method

          geo.resize = resizeGeo;
          geo.resize(mapSeries[0], api);
          each(mapSeries, function (singleMapSeries) {
            singleMapSeries.coordinateSystem = geo;
            setGeoCoords(geo, singleMapSeries);
          });
        });
        return geoList;
      };
      /**
       * Fill given regions array
       */


      GeoCreator.prototype.getFilledRegions = function (originRegionArr, mapName, nameMap, nameProperty) {
        // Not use the original
        var regionsArr = (originRegionArr || []).slice();
        var dataNameMap = createHashMap();

        for (var i = 0; i < regionsArr.length; i++) {
          dataNameMap.set(regionsArr[i].name, regionsArr[i]);
        }

        var source = geoSourceManager.load(mapName, nameMap, nameProperty);
        each(source.regions, function (region) {
          var name = region.name;
          !dataNameMap.get(name) && regionsArr.push({
            name: name
          });
        });
        return regionsArr;
      };

      return GeoCreator;
    }();

    var geoCreator = new GeoCreator();

    var GeoModel =
    /** @class */
    function (_super) {
      __extends(GeoModel, _super);

      function GeoModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = GeoModel.type;
        return _this;
      }

      GeoModel.prototype.init = function (option, parentModel, ecModel) {
        var source = geoSourceManager.getGeoResource(option.map);

        if (source && source.type === 'geoJSON') {
          var itemStyle = option.itemStyle = option.itemStyle || {};

          if (!('color' in itemStyle)) {
            itemStyle.color = '#eee';
          }
        }

        this.mergeDefaultAndTheme(option, ecModel); // Default label emphasis `show`

        defaultEmphasis(option, 'label', ['show']);
      };

      GeoModel.prototype.optionUpdated = function () {
        var _this = this;

        var option = this.option;
        option.regions = geoCreator.getFilledRegions(option.regions, option.map, option.nameMap, option.nameProperty);
        var selectedMap = {};
        this._optionModelMap = reduce(option.regions || [], function (optionModelMap, regionOpt) {
          var regionName = regionOpt.name;

          if (regionName) {
            optionModelMap.set(regionName, new Model(regionOpt, _this, _this.ecModel));

            if (regionOpt.selected) {
              selectedMap[regionName] = true;
            }
          }

          return optionModelMap;
        }, createHashMap());

        if (!option.selectedMap) {
          option.selectedMap = selectedMap;
        }
      };
      /**
       * Get model of region.
       */


      GeoModel.prototype.getRegionModel = function (name) {
        return this._optionModelMap.get(name) || new Model(null, this, this.ecModel);
      };
      /**
       * Format label
       * @param name Region name
       */


      GeoModel.prototype.getFormattedLabel = function (name, status) {
        var regionModel = this.getRegionModel(name);
        var formatter = status === 'normal' ? regionModel.get(['label', 'formatter']) : regionModel.get(['emphasis', 'label', 'formatter']);
        var params = {
          name: name
        };

        if (isFunction(formatter)) {
          params.status = status;
          return formatter(params);
        } else if (isString(formatter)) {
          return formatter.replace('{a}', name != null ? name : '');
        }
      };

      GeoModel.prototype.setZoom = function (zoom) {
        this.option.zoom = zoom;
      };

      GeoModel.prototype.setCenter = function (center) {
        this.option.center = center;
      }; // PENGING If selectedMode is null ?


      GeoModel.prototype.select = function (name) {
        var option = this.option;
        var selectedMode = option.selectedMode;

        if (!selectedMode) {
          return;
        }

        if (selectedMode !== 'multiple') {
          option.selectedMap = null;
        }

        var selectedMap = option.selectedMap || (option.selectedMap = {});
        selectedMap[name] = true;
      };

      GeoModel.prototype.unSelect = function (name) {
        var selectedMap = this.option.selectedMap;

        if (selectedMap) {
          selectedMap[name] = false;
        }
      };

      GeoModel.prototype.toggleSelected = function (name) {
        this[this.isSelected(name) ? 'unSelect' : 'select'](name);
      };

      GeoModel.prototype.isSelected = function (name) {
        var selectedMap = this.option.selectedMap;
        return !!(selectedMap && selectedMap[name]);
      };

      GeoModel.type = 'geo';
      GeoModel.layoutMode = 'box';
      GeoModel.defaultOption = {
        // zlevel: 0,
        z: 0,
        show: true,
        left: 'center',
        top: 'center',
        // Default value:
        // for geoSVG source: 1,
        // for geoJSON source: 0.75.
        aspectScale: null,
        // /// Layout with center and size
        // If you want to put map in a fixed size box with right aspect ratio
        // This two properties may be more convenient
        // layoutCenter: [50%, 50%]
        // layoutSize: 100
        silent: false,
        // Map type
        map: '',
        // Define left-top, right-bottom coords to control view
        // For example, [ [180, 90], [-180, -90] ]
        boundingCoords: null,
        // Default on center of map
        center: null,
        zoom: 1,
        scaleLimit: null,
        // selectedMode: false
        label: {
          show: false,
          color: '#000'
        },
        itemStyle: {
          borderWidth: 0.5,
          borderColor: '#444' // Default color:
          // + geoJSON: #eee
          // + geoSVG: null (use SVG original `fill`)
          // color: '#eee'

        },
        emphasis: {
          label: {
            show: true,
            color: 'rgb(100,0,0)'
          },
          itemStyle: {
            color: 'rgba(255,215,0,0.8)'
          }
        },
        select: {
          label: {
            show: true,
            color: 'rgb(100,0,0)'
          },
          itemStyle: {
            color: 'rgba(255,215,0,0.8)'
          }
        },
        regions: [] // tooltip: {
        //     show: false
        // }

      };
      return GeoModel;
    }(ComponentModel);

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


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * 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 getCenterCoord(view, point) {
      // Use projected coord as center because it's linear.
      return view.pointToProjected ? view.pointToProjected(point) : view.pointToData(point);
    }

    function updateCenterAndZoom(view, payload, zoomLimit, api) {
      var previousZoom = view.getZoom();
      var center = view.getCenter();
      var zoom = payload.zoom;
      var point = view.projectedToPoint ? view.projectedToPoint(center) : view.dataToPoint(center);

      if (payload.dx != null && payload.dy != null) {
        point[0] -= payload.dx;
        point[1] -= payload.dy;
        view.setCenter(getCenterCoord(view, point), api);
      }

      if (zoom != null) {
        if (zoomLimit) {
          var zoomMin = zoomLimit.min || 0;
          var zoomMax = zoomLimit.max || Infinity;
          zoom = Math.max(Math.min(previousZoom * zoom, zoomMax), zoomMin) / previousZoom;
        } // Zoom on given point(originX, originY)


        view.scaleX *= zoom;
        view.scaleY *= zoom;
        var fixX = (payload.originX - view.x) * (zoom - 1);
        var fixY = (payload.originY - view.y) * (zoom - 1);
        view.x -= fixX;
        view.y -= fixY;
        view.updateTransform(); // Get the new center

        view.setCenter(getCenterCoord(view, point), api);
        view.setZoom(zoom * previousZoom);
      }

      return {
        center: view.getCenter(),
        zoom: view.getZoom()
      };
    }

    var GeoView =
    /** @class */
    function (_super) {
      __extends(GeoView, _super);

      function GeoView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = GeoView.type;
        _this.focusBlurEnabled = true;
        return _this;
      }

      GeoView.prototype.init = function (ecModel, api) {
        this._api = api;
      };

      GeoView.prototype.render = function (geoModel, ecModel, api, payload) {
        this._model = geoModel;

        if (!geoModel.get('show')) {
          this._mapDraw && this._mapDraw.remove();
          this._mapDraw = null;
          return;
        }

        if (!this._mapDraw) {
          this._mapDraw = new MapDraw(api);
        }

        var mapDraw = this._mapDraw;
        mapDraw.draw(geoModel, ecModel, api, this, payload);
        mapDraw.group.on('click', this._handleRegionClick, this);
        mapDraw.group.silent = geoModel.get('silent');
        this.group.add(mapDraw.group);
        this.updateSelectStatus(geoModel, ecModel, api);
      };

      GeoView.prototype._handleRegionClick = function (e) {
        var eventData;
        findEventDispatcher(e.target, function (current) {
          return (eventData = getECData(current).eventData) != null;
        }, true);

        if (eventData) {
          this._api.dispatchAction({
            type: 'geoToggleSelect',
            geoId: this._model.id,
            name: eventData.name
          });
        }
      };

      GeoView.prototype.updateSelectStatus = function (model, ecModel, api) {
        var _this = this;

        this._mapDraw.group.traverse(function (node) {
          var eventData = getECData(node).eventData;

          if (eventData) {
            _this._model.isSelected(eventData.name) ? api.enterSelect(node) : api.leaveSelect(node); // No need to traverse children.

            return true;
          }
        });
      };

      GeoView.prototype.findHighDownDispatchers = function (name) {
        return this._mapDraw && this._mapDraw.findHighDownDispatchers(name, this._model);
      };

      GeoView.prototype.dispose = function () {
        this._mapDraw && this._mapDraw.remove();
      };

      GeoView.type = 'geo';
      return GeoView;
    }(ComponentView);

    function registerMap$1(mapName, geoJson, specialAreas) {
      geoSourceManager.registerMap(mapName, geoJson, specialAreas);
    }

    function install$9(registers) {
      registers.registerCoordinateSystem('geo', geoCreator);
      registers.registerComponentModel(GeoModel);
      registers.registerComponentView(GeoView);
      registers.registerImpl('registerMap', registerMap$1);
      registers.registerImpl('getMap', function (mapName) {
        return geoSourceManager.getMapForUser(mapName);
      });

      function makeAction(method, actionInfo) {
        actionInfo.update = 'geo:updateSelectStatus';
        registers.registerAction(actionInfo, function (payload, ecModel) {
          var selected = {};
          var allSelected = [];
          ecModel.eachComponent({
            mainType: 'geo',
            query: payload
          }, function (geoModel) {
            geoModel[method](payload.name);
            var geo = geoModel.coordinateSystem;
            each(geo.regions, function (region) {
              selected[region.name] = geoModel.isSelected(region.name) || false;
            }); // Notice: there might be duplicated name in different regions.

            var names = [];
            each(selected, function (v, name) {
              selected[name] && names.push(name);
            });
            allSelected.push({
              geoIndex: geoModel.componentIndex,
              // Use singular, the same naming convention as the event `selectchanged`.
              name: names
            });
          });
          return {
            selected: selected,
            allSelected: allSelected,
            name: payload.name
          };
        });
      }

      makeAction('toggleSelected', {
        type: 'geoToggleSelect',
        event: 'geoselectchanged'
      });
      makeAction('select', {
        type: 'geoSelect',
        event: 'geoselected'
      });
      makeAction('unSelect', {
        type: 'geoUnSelect',
        event: 'geounselected'
      });
      /**
       * @payload
       * @property {string} [componentType=series]
       * @property {number} [dx]
       * @property {number} [dy]
       * @property {number} [zoom]
       * @property {number} [originX]
       * @property {number} [originY]
       */

      registers.registerAction({
        type: 'geoRoam',
        event: 'geoRoam',
        update: 'updateTransform'
      }, function (payload, ecModel, api) {
        var componentType = payload.componentType || 'series';
        ecModel.eachComponent({
          mainType: componentType,
          query: payload
        }, function (componentModel) {
          var geo = componentModel.coordinateSystem;

          if (geo.type !== 'geo') {
            return;
          }

          var res = updateCenterAndZoom(geo, payload, componentModel.get('scaleLimit'), api);
          componentModel.setCenter && componentModel.setCenter(res.center);
          componentModel.setZoom && componentModel.setZoom(res.zoom); // All map series with same `map` use the same geo coordinate system
          // So the center and zoom must be in sync. Include the series not selected by legend

          if (componentType === 'series') {
            each(componentModel.seriesGroup, function (seriesModel) {
              seriesModel.setCenter(res.center);
              seriesModel.setZoom(res.zoom);
            });
          }
        });
      });
    }

    function install$a(registers) {
      use(install$9);
      registers.registerChartView(MapView);
      registers.registerSeriesModel(MapSeries);
      registers.registerLayout(mapSymbolLayout);
      registers.registerProcessor(registers.PRIORITY.PROCESSOR.STATISTIC, mapDataStatistic);
      createLegacyDataSelectAction('map', registers.registerAction);
    }

    /**
     * Initialize all computational message for following algorithm.
     */

    function init$2(inRoot) {
      var root = inRoot;
      root.hierNode = {
        defaultAncestor: null,
        ancestor: root,
        prelim: 0,
        modifier: 0,
        change: 0,
        shift: 0,
        i: 0,
        thread: null
      };
      var nodes = [root];
      var node;
      var children;

      while (node = nodes.pop()) {
        // jshint ignore:line
        children = node.children;

        if (node.isExpand && children.length) {
          var n = children.length;

          for (var i = n - 1; i >= 0; i--) {
            var child = children[i];
            child.hierNode = {
              defaultAncestor: null,
              ancestor: child,
              prelim: 0,
              modifier: 0,
              change: 0,
              shift: 0,
              i: i,
              thread: null
            };
            nodes.push(child);
          }
        }
      }
    }
    /**
     * The implementation of this function was originally copied from "d3.js"
     * <https://github.com/d3/d3-hierarchy/blob/4c1f038f2725d6eae2e49b61d01456400694bac4/src/tree.js>
     * with some modifications made for this program.
     * See the license statement at the head of this file.
     *
     * Computes a preliminary x coordinate for node. Before that, this function is
     * applied recursively to the children of node, as well as the function
     * apportion(). After spacing out the children by calling executeShifts(), the
     * node is placed to the midpoint of its outermost children.
     */

    function firstWalk(node, separation) {
      var children = node.isExpand ? node.children : [];
      var siblings = node.parentNode.children;
      var subtreeW = node.hierNode.i ? siblings[node.hierNode.i - 1] : null;

      if (children.length) {
        executeShifts(node);
        var midPoint = (children[0].hierNode.prelim + children[children.length - 1].hierNode.prelim) / 2;

        if (subtreeW) {
          node.hierNode.prelim = subtreeW.hierNode.prelim + separation(node, subtreeW);
          node.hierNode.modifier = node.hierNode.prelim - midPoint;
        } else {
          node.hierNode.prelim = midPoint;
        }
      } else if (subtreeW) {
        node.hierNode.prelim = subtreeW.hierNode.prelim + separation(node, subtreeW);
      }

      node.parentNode.hierNode.defaultAncestor = apportion(node, subtreeW, node.parentNode.hierNode.defaultAncestor || siblings[0], separation);
    }
    /**
     * The implementation of this function was originally copied from "d3.js"
     * <https://github.com/d3/d3-hierarchy/blob/4c1f038f2725d6eae2e49b61d01456400694bac4/src/tree.js>
     * with some modifications made for this program.
     * See the license statement at the head of this file.
     *
     * Computes all real x-coordinates by summing up the modifiers recursively.
     */

    function secondWalk(node) {
      var nodeX = node.hierNode.prelim + node.parentNode.hierNode.modifier;
      node.setLayout({
        x: nodeX
      }, true);
      node.hierNode.modifier += node.parentNode.hierNode.modifier;
    }
    function separation(cb) {
      return arguments.length ? cb : defaultSeparation;
    }
    /**
     * Transform the common coordinate to radial coordinate.
     */

    function radialCoordinate(rad, r) {
      rad -= Math.PI / 2;
      return {
        x: r * Math.cos(rad),
        y: r * Math.sin(rad)
      };
    }
    /**
     * Get the layout position of the whole view.
     */

    function getViewRect$1(seriesModel, api) {
      return getLayoutRect(seriesModel.getBoxLayoutParams(), {
        width: api.getWidth(),
        height: api.getHeight()
      });
    }
    /**
     * All other shifts, applied to the smaller subtrees between w- and w+, are
     * performed by this function.
     *
     * The implementation of this function was originally copied from "d3.js"
     * <https://github.com/d3/d3-hierarchy/blob/4c1f038f2725d6eae2e49b61d01456400694bac4/src/tree.js>
     * with some modifications made for this program.
     * See the license statement at the head of this file.
     */

    function executeShifts(node) {
      var children = node.children;
      var n = children.length;
      var shift = 0;
      var change = 0;

      while (--n >= 0) {
        var child = children[n];
        child.hierNode.prelim += shift;
        child.hierNode.modifier += shift;
        change += child.hierNode.change;
        shift += child.hierNode.shift + change;
      }
    }
    /**
     * The implementation of this function was originally copied from "d3.js"
     * <https://github.com/d3/d3-hierarchy/blob/4c1f038f2725d6eae2e49b61d01456400694bac4/src/tree.js>
     * with some modifications made for this program.
     * See the license statement at the head of this file.
     *
     * The core of the algorithm. Here, a new subtree is combined with the
     * previous subtrees. Threads are used to traverse the inside and outside
     * contours of the left and right subtree up to the highest common level.
     * Whenever two nodes of the inside contours conflict, we compute the left
     * one of the greatest uncommon ancestors using the function nextAncestor()
     * and call moveSubtree() to shift the subtree and prepare the shifts of
     * smaller subtrees. Finally, we add a new thread (if necessary).
     */


    function apportion(subtreeV, subtreeW, ancestor, separation) {
      if (subtreeW) {
        var nodeOutRight = subtreeV;
        var nodeInRight = subtreeV;
        var nodeOutLeft = nodeInRight.parentNode.children[0];
        var nodeInLeft = subtreeW;
        var sumOutRight = nodeOutRight.hierNode.modifier;
        var sumInRight = nodeInRight.hierNode.modifier;
        var sumOutLeft = nodeOutLeft.hierNode.modifier;
        var sumInLeft = nodeInLeft.hierNode.modifier;

        while (nodeInLeft = nextRight(nodeInLeft), nodeInRight = nextLeft(nodeInRight), nodeInLeft && nodeInRight) {
          nodeOutRight = nextRight(nodeOutRight);
          nodeOutLeft = nextLeft(nodeOutLeft);
          nodeOutRight.hierNode.ancestor = subtreeV;
          var shift = nodeInLeft.hierNode.prelim + sumInLeft - nodeInRight.hierNode.prelim - sumInRight + separation(nodeInLeft, nodeInRight);

          if (shift > 0) {
            moveSubtree(nextAncestor(nodeInLeft, subtreeV, ancestor), subtreeV, shift);
            sumInRight += shift;
            sumOutRight += shift;
          }

          sumInLeft += nodeInLeft.hierNode.modifier;
          sumInRight += nodeInRight.hierNode.modifier;
          sumOutRight += nodeOutRight.hierNode.modifier;
          sumOutLeft += nodeOutLeft.hierNode.modifier;
        }

        if (nodeInLeft && !nextRight(nodeOutRight)) {
          nodeOutRight.hierNode.thread = nodeInLeft;
          nodeOutRight.hierNode.modifier += sumInLeft - sumOutRight;
        }

        if (nodeInRight && !nextLeft(nodeOutLeft)) {
          nodeOutLeft.hierNode.thread = nodeInRight;
          nodeOutLeft.hierNode.modifier += sumInRight - sumOutLeft;
          ancestor = subtreeV;
        }
      }

      return ancestor;
    }
    /**
     * This function is used to traverse the right contour of a subtree.
     * It returns the rightmost child of node or the thread of node. The function
     * returns null if and only if node is on the highest depth of its subtree.
     */


    function nextRight(node) {
      var children = node.children;
      return children.length && node.isExpand ? children[children.length - 1] : node.hierNode.thread;
    }
    /**
     * This function is used to traverse the left contour of a subtree (or a subforest).
     * It returns the leftmost child of node or the thread of node. The function
     * returns null if and only if node is on the highest depth of its subtree.
     */


    function nextLeft(node) {
      var children = node.children;
      return children.length && node.isExpand ? children[0] : node.hierNode.thread;
    }
    /**
     * If nodeInLeft’s ancestor is a sibling of node, returns nodeInLeft’s ancestor.
     * Otherwise, returns the specified ancestor.
     */


    function nextAncestor(nodeInLeft, node, ancestor) {
      return nodeInLeft.hierNode.ancestor.parentNode === node.parentNode ? nodeInLeft.hierNode.ancestor : ancestor;
    }
    /**
     * The implementation of this function was originally copied from "d3.js"
     * <https://github.com/d3/d3-hierarchy/blob/4c1f038f2725d6eae2e49b61d01456400694bac4/src/tree.js>
     * with some modifications made for this program.
     * See the license statement at the head of this file.
     *
     * Shifts the current subtree rooted at wr.
     * This is done by increasing prelim(w+) and modifier(w+) by shift.
     */


    function moveSubtree(wl, wr, shift) {
      var change = shift / (wr.hierNode.i - wl.hierNode.i);
      wr.hierNode.change -= change;
      wr.hierNode.shift += shift;
      wr.hierNode.modifier += shift;
      wr.hierNode.prelim += shift;
      wl.hierNode.change += change;
    }
    /**
     * The implementation of this function was originally copied from "d3.js"
     * <https://github.com/d3/d3-hierarchy/blob/4c1f038f2725d6eae2e49b61d01456400694bac4/src/tree.js>
     * with some modifications made for this program.
     * See the license statement at the head of this file.
     */


    function defaultSeparation(node1, node2) {
      return node1.parentNode === node2.parentNode ? 1 : 2;
    }

    var TreeEdgeShape =
    /** @class */
    function () {
      function TreeEdgeShape() {
        this.parentPoint = [];
        this.childPoints = [];
      }

      return TreeEdgeShape;
    }();

    var TreePath =
    /** @class */
    function (_super) {
      __extends(TreePath, _super);

      function TreePath(opts) {
        return _super.call(this, opts) || this;
      }

      TreePath.prototype.getDefaultStyle = function () {
        return {
          stroke: '#000',
          fill: null
        };
      };

      TreePath.prototype.getDefaultShape = function () {
        return new TreeEdgeShape();
      };

      TreePath.prototype.buildPath = function (ctx, shape) {
        var childPoints = shape.childPoints;
        var childLen = childPoints.length;
        var parentPoint = shape.parentPoint;
        var firstChildPos = childPoints[0];
        var lastChildPos = childPoints[childLen - 1];

        if (childLen === 1) {
          ctx.moveTo(parentPoint[0], parentPoint[1]);
          ctx.lineTo(firstChildPos[0], firstChildPos[1]);
          return;
        }

        var orient = shape.orient;
        var forkDim = orient === 'TB' || orient === 'BT' ? 0 : 1;
        var otherDim = 1 - forkDim;
        var forkPosition = parsePercent$1(shape.forkPosition, 1);
        var tmpPoint = [];
        tmpPoint[forkDim] = parentPoint[forkDim];
        tmpPoint[otherDim] = parentPoint[otherDim] + (lastChildPos[otherDim] - parentPoint[otherDim]) * forkPosition;
        ctx.moveTo(parentPoint[0], parentPoint[1]);
        ctx.lineTo(tmpPoint[0], tmpPoint[1]);
        ctx.moveTo(firstChildPos[0], firstChildPos[1]);
        tmpPoint[forkDim] = firstChildPos[forkDim];
        ctx.lineTo(tmpPoint[0], tmpPoint[1]);
        tmpPoint[forkDim] = lastChildPos[forkDim];
        ctx.lineTo(tmpPoint[0], tmpPoint[1]);
        ctx.lineTo(lastChildPos[0], lastChildPos[1]);

        for (var i = 1; i < childLen - 1; i++) {
          var point = childPoints[i];
          ctx.moveTo(point[0], point[1]);
          tmpPoint[forkDim] = point[forkDim];
          ctx.lineTo(tmpPoint[0], tmpPoint[1]);
        }
      };

      return TreePath;
    }(Path);

    var TreeView =
    /** @class */
    function (_super) {
      __extends(TreeView, _super);

      function TreeView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = TreeView.type;
        _this._mainGroup = new Group();
        return _this;
      }

      TreeView.prototype.init = function (ecModel, api) {
        this._controller = new RoamController(api.getZr());
        this._controllerHost = {
          target: this.group
        };
        this.group.add(this._mainGroup);
      };

      TreeView.prototype.render = function (seriesModel, ecModel, api) {
        var data = seriesModel.getData();
        var layoutInfo = seriesModel.layoutInfo;
        var group = this._mainGroup;
        var layout = seriesModel.get('layout');

        if (layout === 'radial') {
          group.x = layoutInfo.x + layoutInfo.width / 2;
          group.y = layoutInfo.y + layoutInfo.height / 2;
        } else {
          group.x = layoutInfo.x;
          group.y = layoutInfo.y;
        }

        this._updateViewCoordSys(seriesModel, api);

        this._updateController(seriesModel, ecModel, api);

        var oldData = this._data;
        data.diff(oldData).add(function (newIdx) {
          if (symbolNeedsDraw$1(data, newIdx)) {
            // Create node and edge
            updateNode(data, newIdx, null, group, seriesModel);
          }
        }).update(function (newIdx, oldIdx) {
          var symbolEl = oldData.getItemGraphicEl(oldIdx);

          if (!symbolNeedsDraw$1(data, newIdx)) {
            symbolEl && removeNode(oldData, oldIdx, symbolEl, group, seriesModel);
            return;
          } // Update node and edge


          updateNode(data, newIdx, symbolEl, group, seriesModel);
        }).remove(function (oldIdx) {
          var symbolEl = oldData.getItemGraphicEl(oldIdx); // When remove a collapsed node of subtree, since the collapsed
          // node haven't been initialized with a symbol element,
          // you can't found it's symbol element through index.
          // so if we want to remove the symbol element we should insure
          // that the symbol element is not null.

          if (symbolEl) {
            removeNode(oldData, oldIdx, symbolEl, group, seriesModel);
          }
        }).execute();
        this._nodeScaleRatio = seriesModel.get('nodeScaleRatio');

        this._updateNodeAndLinkScale(seriesModel);

        if (seriesModel.get('expandAndCollapse') === true) {
          data.eachItemGraphicEl(function (el, dataIndex) {
            el.off('click').on('click', function () {
              api.dispatchAction({
                type: 'treeExpandAndCollapse',
                seriesId: seriesModel.id,
                dataIndex: dataIndex
              });
            });
          });
        }

        this._data = data;
      };

      TreeView.prototype._updateViewCoordSys = function (seriesModel, api) {
        var data = seriesModel.getData();
        var points = [];
        data.each(function (idx) {
          var layout = data.getItemLayout(idx);

          if (layout && !isNaN(layout.x) && !isNaN(layout.y)) {
            points.push([+layout.x, +layout.y]);
          }
        });
        var min = [];
        var max = [];
        fromPoints(points, min, max); // If don't Store min max when collapse the root node after roam,
        // the root node will disappear.

        var oldMin = this._min;
        var oldMax = this._max; // If width or height is 0

        if (max[0] - min[0] === 0) {
          min[0] = oldMin ? oldMin[0] : min[0] - 1;
          max[0] = oldMax ? oldMax[0] : max[0] + 1;
        }

        if (max[1] - min[1] === 0) {
          min[1] = oldMin ? oldMin[1] : min[1] - 1;
          max[1] = oldMax ? oldMax[1] : max[1] + 1;
        }

        var viewCoordSys = seriesModel.coordinateSystem = new View();
        viewCoordSys.zoomLimit = seriesModel.get('scaleLimit');
        viewCoordSys.setBoundingRect(min[0], min[1], max[0] - min[0], max[1] - min[1]);
        viewCoordSys.setCenter(seriesModel.get('center'), api);
        viewCoordSys.setZoom(seriesModel.get('zoom')); // Here we use viewCoordSys just for computing the 'position' and 'scale' of the group

        this.group.attr({
          x: viewCoordSys.x,
          y: viewCoordSys.y,
          scaleX: viewCoordSys.scaleX,
          scaleY: viewCoordSys.scaleY
        });
        this._min = min;
        this._max = max;
      };

      TreeView.prototype._updateController = function (seriesModel, ecModel, api) {
        var _this = this;

        var controller = this._controller;
        var controllerHost = this._controllerHost;
        var group = this.group;
        controller.setPointerChecker(function (e, x, y) {
          var rect = group.getBoundingRect();
          rect.applyTransform(group.transform);
          return rect.contain(x, y) && !onIrrelevantElement(e, api, seriesModel);
        });
        controller.enable(seriesModel.get('roam'));
        controllerHost.zoomLimit = seriesModel.get('scaleLimit');
        controllerHost.zoom = seriesModel.coordinateSystem.getZoom();
        controller.off('pan').off('zoom').on('pan', function (e) {
          updateViewOnPan(controllerHost, e.dx, e.dy);
          api.dispatchAction({
            seriesId: seriesModel.id,
            type: 'treeRoam',
            dx: e.dx,
            dy: e.dy
          });
        }).on('zoom', function (e) {
          updateViewOnZoom(controllerHost, e.scale, e.originX, e.originY);
          api.dispatchAction({
            seriesId: seriesModel.id,
            type: 'treeRoam',
            zoom: e.scale,
            originX: e.originX,
            originY: e.originY
          });

          _this._updateNodeAndLinkScale(seriesModel); // Only update label layout on zoom


          api.updateLabelLayout();
        });
      };

      TreeView.prototype._updateNodeAndLinkScale = function (seriesModel) {
        var data = seriesModel.getData();

        var nodeScale = this._getNodeGlobalScale(seriesModel);

        data.eachItemGraphicEl(function (el, idx) {
          el.setSymbolScale(nodeScale);
        });
      };

      TreeView.prototype._getNodeGlobalScale = function (seriesModel) {
        var coordSys = seriesModel.coordinateSystem;

        if (coordSys.type !== 'view') {
          return 1;
        }

        var nodeScaleRatio = this._nodeScaleRatio;
        var groupZoom = coordSys.scaleX || 1; // Scale node when zoom changes

        var roamZoom = coordSys.getZoom();
        var nodeScale = (roamZoom - 1) * nodeScaleRatio + 1;
        return nodeScale / groupZoom;
      };

      TreeView.prototype.dispose = function () {
        this._controller && this._controller.dispose();
        this._controllerHost = null;
      };

      TreeView.prototype.remove = function () {
        this._mainGroup.removeAll();

        this._data = null;
      };

      TreeView.type = 'tree';
      return TreeView;
    }(ChartView);

    function symbolNeedsDraw$1(data, dataIndex) {
      var layout = data.getItemLayout(dataIndex);
      return layout && !isNaN(layout.x) && !isNaN(layout.y);
    }

    function updateNode(data, dataIndex, symbolEl, group, seriesModel) {
      var isInit = !symbolEl;
      var node = data.tree.getNodeByDataIndex(dataIndex);
      var itemModel = node.getModel();
      var visualColor = node.getVisual('style').fill;
      var symbolInnerColor = node.isExpand === false && node.children.length !== 0 ? visualColor : '#fff';
      var virtualRoot = data.tree.root;
      var source = node.parentNode === virtualRoot ? node : node.parentNode || node;
      var sourceSymbolEl = data.getItemGraphicEl(source.dataIndex);
      var sourceLayout = source.getLayout();
      var sourceOldLayout = sourceSymbolEl ? {
        x: sourceSymbolEl.__oldX,
        y: sourceSymbolEl.__oldY,
        rawX: sourceSymbolEl.__radialOldRawX,
        rawY: sourceSymbolEl.__radialOldRawY
      } : sourceLayout;
      var targetLayout = node.getLayout();

      if (isInit) {
        symbolEl = new Symbol(data, dataIndex, null, {
          symbolInnerColor: symbolInnerColor,
          useNameLabel: true
        });
        symbolEl.x = sourceOldLayout.x;
        symbolEl.y = sourceOldLayout.y;
      } else {
        symbolEl.updateData(data, dataIndex, null, {
          symbolInnerColor: symbolInnerColor,
          useNameLabel: true
        });
      }

      symbolEl.__radialOldRawX = symbolEl.__radialRawX;
      symbolEl.__radialOldRawY = symbolEl.__radialRawY;
      symbolEl.__radialRawX = targetLayout.rawX;
      symbolEl.__radialRawY = targetLayout.rawY;
      group.add(symbolEl);
      data.setItemGraphicEl(dataIndex, symbolEl);
      symbolEl.__oldX = symbolEl.x;
      symbolEl.__oldY = symbolEl.y;
      updateProps(symbolEl, {
        x: targetLayout.x,
        y: targetLayout.y
      }, seriesModel);
      var symbolPath = symbolEl.getSymbolPath();

      if (seriesModel.get('layout') === 'radial') {
        var realRoot = virtualRoot.children[0];
        var rootLayout = realRoot.getLayout();
        var length_1 = realRoot.children.length;
        var rad = void 0;
        var isLeft = void 0;

        if (targetLayout.x === rootLayout.x && node.isExpand === true && realRoot.children.length) {
          var center = {
            x: (realRoot.children[0].getLayout().x + realRoot.children[length_1 - 1].getLayout().x) / 2,
            y: (realRoot.children[0].getLayout().y + realRoot.children[length_1 - 1].getLayout().y) / 2
          };
          rad = Math.atan2(center.y - rootLayout.y, center.x - rootLayout.x);

          if (rad < 0) {
            rad = Math.PI * 2 + rad;
          }

          isLeft = center.x < rootLayout.x;

          if (isLeft) {
            rad = rad - Math.PI;
          }
        } else {
          rad = Math.atan2(targetLayout.y - rootLayout.y, targetLayout.x - rootLayout.x);

          if (rad < 0) {
            rad = Math.PI * 2 + rad;
          }

          if (node.children.length === 0 || node.children.length !== 0 && node.isExpand === false) {
            isLeft = targetLayout.x < rootLayout.x;

            if (isLeft) {
              rad = rad - Math.PI;
            }
          } else {
            isLeft = targetLayout.x > rootLayout.x;

            if (!isLeft) {
              rad = rad - Math.PI;
            }
          }
        }

        var textPosition = isLeft ? 'left' : 'right';
        var normalLabelModel = itemModel.getModel('label');
        var rotate = normalLabelModel.get('rotate');
        var labelRotateRadian = rotate * (Math.PI / 180);
        var textContent = symbolPath.getTextContent();

        if (textContent) {
          symbolPath.setTextConfig({
            position: normalLabelModel.get('position') || textPosition,
            rotation: rotate == null ? -rad : labelRotateRadian,
            origin: 'center'
          });
          textContent.setStyle('verticalAlign', 'middle');
        }
      } // Handle status


      var focus = itemModel.get(['emphasis', 'focus']);
      var focusDataIndices = focus === 'relative' ? concatArray(node.getAncestorsIndices(), node.getDescendantIndices()) : focus === 'ancestor' ? node.getAncestorsIndices() : focus === 'descendant' ? node.getDescendantIndices() : null;

      if (focusDataIndices) {
        // Modify the focus to data indices.
        getECData(symbolEl).focus = focusDataIndices;
      }

      drawEdge(seriesModel, node, virtualRoot, symbolEl, sourceOldLayout, sourceLayout, targetLayout, group);

      if (symbolEl.__edge) {
        symbolEl.onHoverStateChange = function (toState) {
          if (toState !== 'blur') {
            // NOTE: Ensure the parent elements will been blurred firstly.
            // According to the return of getAncestorsIndices and getDescendantIndices
            // TODO: A bit tricky.
            var parentEl = node.parentNode && data.getItemGraphicEl(node.parentNode.dataIndex);

            if (!(parentEl && parentEl.hoverState === HOVER_STATE_BLUR)) {
              setStatesFlag(symbolEl.__edge, toState);
            }
          }
        };
      }
    }

    function drawEdge(seriesModel, node, virtualRoot, symbolEl, sourceOldLayout, sourceLayout, targetLayout, group) {
      var itemModel = node.getModel();
      var edgeShape = seriesModel.get('edgeShape');
      var layout = seriesModel.get('layout');
      var orient = seriesModel.getOrient();
      var curvature = seriesModel.get(['lineStyle', 'curveness']);
      var edgeForkPosition = seriesModel.get('edgeForkPosition');
      var lineStyle = itemModel.getModel('lineStyle').getLineStyle();
      var edge = symbolEl.__edge; // curve edge from node -> parent
      // polyline edge from node -> children

      if (edgeShape === 'curve') {
        if (node.parentNode && node.parentNode !== virtualRoot) {
          if (!edge) {
            edge = symbolEl.__edge = new BezierCurve({
              shape: getEdgeShape(layout, orient, curvature, sourceOldLayout, sourceOldLayout)
            });
          }

          updateProps(edge, {
            shape: getEdgeShape(layout, orient, curvature, sourceLayout, targetLayout)
          }, seriesModel);
        }
      } else if (edgeShape === 'polyline') {
        if (layout === 'orthogonal') {
          if (node !== virtualRoot && node.children && node.children.length !== 0 && node.isExpand === true) {
            var children = node.children;
            var childPoints = [];

            for (var i = 0; i < children.length; i++) {
              var childLayout = children[i].getLayout();
              childPoints.push([childLayout.x, childLayout.y]);
            }

            if (!edge) {
              edge = symbolEl.__edge = new TreePath({
                shape: {
                  parentPoint: [targetLayout.x, targetLayout.y],
                  childPoints: [[targetLayout.x, targetLayout.y]],
                  orient: orient,
                  forkPosition: edgeForkPosition
                }
              });
            }

            updateProps(edge, {
              shape: {
                parentPoint: [targetLayout.x, targetLayout.y],
                childPoints: childPoints
              }
            }, seriesModel);
          }
        } else {
          if ("development" !== 'production') {
            throw new Error('The polyline edgeShape can only be used in orthogonal layout');
          }
        }
      } // show all edge when edgeShape is 'curve', filter node `isExpand` is false when edgeShape is 'polyline'


      if (edge && !(edgeShape === 'polyline' && !node.isExpand)) {
        edge.useStyle(defaults({
          strokeNoScale: true,
          fill: null
        }, lineStyle));
        setStatesStylesFromModel(edge, itemModel, 'lineStyle');
        setDefaultStateProxy(edge);
        group.add(edge);
      }
    }

    function removeNodeEdge(node, data, group, seriesModel, removeAnimationOpt) {
      var virtualRoot = data.tree.root;

      var _a = getSourceNode(virtualRoot, node),
          source = _a.source,
          sourceLayout = _a.sourceLayout;

      var symbolEl = data.getItemGraphicEl(node.dataIndex);

      if (!symbolEl) {
        return;
      }

      var sourceSymbolEl = data.getItemGraphicEl(source.dataIndex);
      var sourceEdge = sourceSymbolEl.__edge; // 1. when expand the sub tree, delete the children node should delete the edge of
      // the source at the same time. because the polyline edge shape is only owned by the source.
      // 2.when the node is the only children of the source, delete the node should delete the edge of
      // the source at the same time. the same reason as above.

      var edge = symbolEl.__edge || (source.isExpand === false || source.children.length === 1 ? sourceEdge : undefined);
      var edgeShape = seriesModel.get('edgeShape');
      var layoutOpt = seriesModel.get('layout');
      var orient = seriesModel.get('orient');
      var curvature = seriesModel.get(['lineStyle', 'curveness']);

      if (edge) {
        if (edgeShape === 'curve') {
          removeElement(edge, {
            shape: getEdgeShape(layoutOpt, orient, curvature, sourceLayout, sourceLayout),
            style: {
              opacity: 0
            }
          }, seriesModel, {
            cb: function () {
              group.remove(edge);
            },
            removeOpt: removeAnimationOpt
          });
        } else if (edgeShape === 'polyline' && seriesModel.get('layout') === 'orthogonal') {
          removeElement(edge, {
            shape: {
              parentPoint: [sourceLayout.x, sourceLayout.y],
              childPoints: [[sourceLayout.x, sourceLayout.y]]
            },
            style: {
              opacity: 0
            }
          }, seriesModel, {
            cb: function () {
              group.remove(edge);
            },
            removeOpt: removeAnimationOpt
          });
        }
      }
    }

    function getSourceNode(virtualRoot, node) {
      var source = node.parentNode === virtualRoot ? node : node.parentNode || node;
      var sourceLayout;

      while (sourceLayout = source.getLayout(), sourceLayout == null) {
        source = source.parentNode === virtualRoot ? source : source.parentNode || source;
      }

      return {
        source: source,
        sourceLayout: sourceLayout
      };
    }

    function removeNode(data, dataIndex, symbolEl, group, seriesModel) {
      var node = data.tree.getNodeByDataIndex(dataIndex);
      var virtualRoot = data.tree.root;
      var sourceLayout = getSourceNode(virtualRoot, node).sourceLayout; // Use same duration and easing with update to have more consistent animation.

      var removeAnimationOpt = {
        duration: seriesModel.get('animationDurationUpdate'),
        easing: seriesModel.get('animationEasingUpdate')
      };
      removeElement(symbolEl, {
        x: sourceLayout.x + 1,
        y: sourceLayout.y + 1
      }, seriesModel, {
        cb: function () {
          group.remove(symbolEl);
          data.setItemGraphicEl(dataIndex, null);
        },
        removeOpt: removeAnimationOpt
      });
      symbolEl.fadeOut(null, data.hostModel, {
        fadeLabel: true,
        animation: removeAnimationOpt
      }); // remove edge as parent node

      node.children.forEach(function (childNode) {
        removeNodeEdge(childNode, data, group, seriesModel, removeAnimationOpt);
      }); // remove edge as child node

      removeNodeEdge(node, data, group, seriesModel, removeAnimationOpt);
    }

    function getEdgeShape(layoutOpt, orient, curvature, sourceLayout, targetLayout) {
      var cpx1;
      var cpy1;
      var cpx2;
      var cpy2;
      var x1;
      var x2;
      var y1;
      var y2;

      if (layoutOpt === 'radial') {
        x1 = sourceLayout.rawX;
        y1 = sourceLayout.rawY;
        x2 = targetLayout.rawX;
        y2 = targetLayout.rawY;
        var radialCoor1 = radialCoordinate(x1, y1);
        var radialCoor2 = radialCoordinate(x1, y1 + (y2 - y1) * curvature);
        var radialCoor3 = radialCoordinate(x2, y2 + (y1 - y2) * curvature);
        var radialCoor4 = radialCoordinate(x2, y2);
        return {
          x1: radialCoor1.x || 0,
          y1: radialCoor1.y || 0,
          x2: radialCoor4.x || 0,
          y2: radialCoor4.y || 0,
          cpx1: radialCoor2.x || 0,
          cpy1: radialCoor2.y || 0,
          cpx2: radialCoor3.x || 0,
          cpy2: radialCoor3.y || 0
        };
      } else {
        x1 = sourceLayout.x;
        y1 = sourceLayout.y;
        x2 = targetLayout.x;
        y2 = targetLayout.y;

        if (orient === 'LR' || orient === 'RL') {
          cpx1 = x1 + (x2 - x1) * curvature;
          cpy1 = y1;
          cpx2 = x2 + (x1 - x2) * curvature;
          cpy2 = y2;
        }

        if (orient === 'TB' || orient === 'BT') {
          cpx1 = x1;
          cpy1 = y1 + (y2 - y1) * curvature;
          cpx2 = x2;
          cpy2 = y2 + (y1 - y2) * curvature;
        }
      }

      return {
        x1: x1,
        y1: y1,
        x2: x2,
        y2: y2,
        cpx1: cpx1,
        cpy1: cpy1,
        cpx2: cpx2,
        cpy2: cpy2
      };
    }

    var inner$7 = makeInner();

    function linkSeriesData(opt) {
      var mainData = opt.mainData;
      var datas = opt.datas;

      if (!datas) {
        datas = {
          main: mainData
        };
        opt.datasAttr = {
          main: 'data'
        };
      }

      opt.datas = opt.mainData = null;
      linkAll(mainData, datas, opt); // Porxy data original methods.

      each(datas, function (data) {
        each(mainData.TRANSFERABLE_METHODS, function (methodName) {
          data.wrapMethod(methodName, curry(transferInjection, opt));
        });
      }); // Beyond transfer, additional features should be added to `cloneShallow`.

      mainData.wrapMethod('cloneShallow', curry(cloneShallowInjection, opt)); // Only mainData trigger change, because struct.update may trigger
      // another changable methods, which may bring about dead lock.

      each(mainData.CHANGABLE_METHODS, function (methodName) {
        mainData.wrapMethod(methodName, curry(changeInjection, opt));
      }); // Make sure datas contains mainData.

      assert(datas[mainData.dataType] === mainData);
    }

    function transferInjection(opt, res) {
      if (isMainData(this)) {
        // Transfer datas to new main data.
        var datas = extend({}, inner$7(this).datas);
        datas[this.dataType] = res;
        linkAll(res, datas, opt);
      } else {
        // Modify the reference in main data to point newData.
        linkSingle(res, this.dataType, inner$7(this).mainData, opt);
      }

      return res;
    }

    function changeInjection(opt, res) {
      opt.struct && opt.struct.update();
      return res;
    }

    function cloneShallowInjection(opt, res) {
      // cloneShallow, which brings about some fragilities, may be inappropriate
      // to be exposed as an API. So for implementation simplicity we can make
      // the restriction that cloneShallow of not-mainData should not be invoked
      // outside, but only be invoked here.
      each(inner$7(res).datas, function (data, dataType) {
        data !== res && linkSingle(data.cloneShallow(), dataType, res, opt);
      });
      return res;
    }
    /**
     * Supplement method to List.
     *
     * @public
     * @param [dataType] If not specified, return mainData.
     */


    function getLinkedData(dataType) {
      var mainData = inner$7(this).mainData;
      return dataType == null || mainData == null ? mainData : inner$7(mainData).datas[dataType];
    }
    /**
     * Get list of all linked data
     */


    function getLinkedDataAll() {
      var mainData = inner$7(this).mainData;
      return mainData == null ? [{
        data: mainData
      }] : map(keys(inner$7(mainData).datas), function (type) {
        return {
          type: type,
          data: inner$7(mainData).datas[type]
        };
      });
    }

    function isMainData(data) {
      return inner$7(data).mainData === data;
    }

    function linkAll(mainData, datas, opt) {
      inner$7(mainData).datas = {};
      each(datas, function (data, dataType) {
        linkSingle(data, dataType, mainData, opt);
      });
    }

    function linkSingle(data, dataType, mainData, opt) {
      inner$7(mainData).datas[dataType] = data;
      inner$7(data).mainData = mainData;
      data.dataType = dataType;

      if (opt.struct) {
        data[opt.structAttr] = opt.struct;
        opt.struct[opt.datasAttr[dataType]] = data;
      } // Supplement method.


      data.getLinkedData = getLinkedData;
      data.getLinkedDataAll = getLinkedDataAll;
    }

    var TreeNode =
    /** @class */
    function () {
      function TreeNode(name, hostTree) {
        this.depth = 0;
        this.height = 0;
        /**
         * Reference to list item.
         * Do not persistent dataIndex outside,
         * besause it may be changed by list.
         * If dataIndex -1,
         * this node is logical deleted (filtered) in list.
         */

        this.dataIndex = -1;
        this.children = [];
        this.viewChildren = [];
        this.isExpand = false;
        this.name = name || '';
        this.hostTree = hostTree;
      }
      /**
       * The node is removed.
       */


      TreeNode.prototype.isRemoved = function () {
        return this.dataIndex < 0;
      };

      TreeNode.prototype.eachNode = function (options, cb, context) {
        if (isFunction(options)) {
          context = cb;
          cb = options;
          options = null;
        }

        options = options || {};

        if (isString(options)) {
          options = {
            order: options
          };
        }

        var order = options.order || 'preorder';
        var children = this[options.attr || 'children'];
        var suppressVisitSub;
        order === 'preorder' && (suppressVisitSub = cb.call(context, this));

        for (var i = 0; !suppressVisitSub && i < children.length; i++) {
          children[i].eachNode(options, cb, context);
        }

        order === 'postorder' && cb.call(context, this);
      };
      /**
       * Update depth and height of this subtree.
       */


      TreeNode.prototype.updateDepthAndHeight = function (depth) {
        var height = 0;
        this.depth = depth;

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

          if (child.height > height) {
            height = child.height;
          }
        }

        this.height = height + 1;
      };

      TreeNode.prototype.getNodeById = function (id) {
        if (this.getId() === id) {
          return this;
        }

        for (var i = 0, children = this.children, len = children.length; i < len; i++) {
          var res = children[i].getNodeById(id);

          if (res) {
            return res;
          }
        }
      };

      TreeNode.prototype.contains = function (node) {
        if (node === this) {
          return true;
        }

        for (var i = 0, children = this.children, len = children.length; i < len; i++) {
          var res = children[i].contains(node);

          if (res) {
            return res;
          }
        }
      };
      /**
       * @param includeSelf Default false.
       * @return order: [root, child, grandchild, ...]
       */


      TreeNode.prototype.getAncestors = function (includeSelf) {
        var ancestors = [];
        var node = includeSelf ? this : this.parentNode;

        while (node) {
          ancestors.push(node);
          node = node.parentNode;
        }

        ancestors.reverse();
        return ancestors;
      };

      TreeNode.prototype.getAncestorsIndices = function () {
        var indices = [];
        var currNode = this;

        while (currNode) {
          indices.push(currNode.dataIndex);
          currNode = currNode.parentNode;
        }

        indices.reverse();
        return indices;
      };

      TreeNode.prototype.getDescendantIndices = function () {
        var indices = [];
        this.eachNode(function (childNode) {
          indices.push(childNode.dataIndex);
        });
        return indices;
      };

      TreeNode.prototype.getValue = function (dimension) {
        var data = this.hostTree.data;
        return data.getStore().get(data.getDimensionIndex(dimension || 'value'), this.dataIndex);
      };

      TreeNode.prototype.setLayout = function (layout, merge) {
        this.dataIndex >= 0 && this.hostTree.data.setItemLayout(this.dataIndex, layout, merge);
      };
      /**
       * @return {Object} layout
       */


      TreeNode.prototype.getLayout = function () {
        return this.hostTree.data.getItemLayout(this.dataIndex);
      }; // @depcrecated
      // getModel<T = unknown, S extends keyof T = keyof T>(path: S): Model<T[S]>
      // eslint-disable-next-line @typescript-eslint/no-unused-vars


      TreeNode.prototype.getModel = function (path) {
        if (this.dataIndex < 0) {
          return;
        }

        var hostTree = this.hostTree;
        var itemModel = hostTree.data.getItemModel(this.dataIndex);
        return itemModel.getModel(path);
      }; // TODO: TYPE More specific model


      TreeNode.prototype.getLevelModel = function () {
        return (this.hostTree.levelModels || [])[this.depth];
      };

      TreeNode.prototype.setVisual = function (key, value) {
        this.dataIndex >= 0 && this.hostTree.data.setItemVisual(this.dataIndex, key, value);
      };
      /**
       * Get item visual
       * FIXME: make return type better
       */


      TreeNode.prototype.getVisual = function (key) {
        return this.hostTree.data.getItemVisual(this.dataIndex, key);
      };

      TreeNode.prototype.getRawIndex = function () {
        return this.hostTree.data.getRawIndex(this.dataIndex);
      };

      TreeNode.prototype.getId = function () {
        return this.hostTree.data.getId(this.dataIndex);
      };
      /**
       * index in parent's children
       */


      TreeNode.prototype.getChildIndex = function () {
        if (this.parentNode) {
          var children = this.parentNode.children;

          for (var i = 0; i < children.length; ++i) {
            if (children[i] === this) {
              return i;
            }
          }

          return -1;
        }

        return -1;
      };
      /**
       * if this is an ancestor of another node
       *
       * @param node another node
       * @return if is ancestor
       */


      TreeNode.prototype.isAncestorOf = function (node) {
        var parent = node.parentNode;

        while (parent) {
          if (parent === this) {
            return true;
          }

          parent = parent.parentNode;
        }

        return false;
      };
      /**
       * if this is an descendant of another node
       *
       * @param node another node
       * @return if is descendant
       */


      TreeNode.prototype.isDescendantOf = function (node) {
        return node !== this && node.isAncestorOf(this);
      };

      return TreeNode;
    }();

    var Tree =
    /** @class */
    function () {
      function Tree(hostModel) {
        this.type = 'tree';
        this._nodes = [];
        this.hostModel = hostModel;
      }

      Tree.prototype.eachNode = function (options, cb, context) {
        this.root.eachNode(options, cb, context);
      };

      Tree.prototype.getNodeByDataIndex = function (dataIndex) {
        var rawIndex = this.data.getRawIndex(dataIndex);
        return this._nodes[rawIndex];
      };

      Tree.prototype.getNodeById = function (name) {
        return this.root.getNodeById(name);
      };
      /**
       * Update item available by list,
       * when list has been performed options like 'filterSelf' or 'map'.
       */


      Tree.prototype.update = function () {
        var data = this.data;
        var nodes = this._nodes;

        for (var i = 0, len = nodes.length; i < len; i++) {
          nodes[i].dataIndex = -1;
        }

        for (var i = 0, len = data.count(); i < len; i++) {
          nodes[data.getRawIndex(i)].dataIndex = i;
        }
      };
      /**
       * Clear all layouts
       */


      Tree.prototype.clearLayouts = function () {
        this.data.clearItemLayouts();
      };
      /**
       * data node format:
       * {
       *     name: ...
       *     value: ...
       *     children: [
       *         {
       *             name: ...
       *             value: ...
       *             children: ...
       *         },
       *         ...
       *     ]
       * }
       */


      Tree.createTree = function (dataRoot, hostModel, beforeLink) {
        var tree = new Tree(hostModel);
        var listData = [];
        var dimMax = 1;
        buildHierarchy(dataRoot);

        function buildHierarchy(dataNode, parentNode) {
          var value = dataNode.value;
          dimMax = Math.max(dimMax, isArray(value) ? value.length : 1);
          listData.push(dataNode);
          var node = new TreeNode(convertOptionIdName(dataNode.name, ''), tree);
          parentNode ? addChild(node, parentNode) : tree.root = node;

          tree._nodes.push(node);

          var children = dataNode.children;

          if (children) {
            for (var i = 0; i < children.length; i++) {
              buildHierarchy(children[i], node);
            }
          }
        }

        tree.root.updateDepthAndHeight(0);
        var dimensions = prepareSeriesDataSchema(listData, {
          coordDimensions: ['value'],
          dimensionsCount: dimMax
        }).dimensions;
        var list = new SeriesData(dimensions, hostModel);
        list.initData(listData);
        beforeLink && beforeLink(list);
        linkSeriesData({
          mainData: list,
          struct: tree,
          structAttr: 'tree'
        });
        tree.update();
        return tree;
      };

      return Tree;
    }();
    /**
     * It is needed to consider the mess of 'list', 'hostModel' when creating a TreeNote,
     * so this function is not ready and not necessary to be public.
     */


    function addChild(child, node) {
      var children = node.children;

      if (child.parentNode === node) {
        return;
      }

      children.push(child);
      child.parentNode = node;
    }

    function retrieveTargetInfo(payload, validPayloadTypes, seriesModel) {
      if (payload && indexOf(validPayloadTypes, payload.type) >= 0) {
        var root = seriesModel.getData().tree.root;
        var targetNode = payload.targetNode;

        if (isString(targetNode)) {
          targetNode = root.getNodeById(targetNode);
        }

        if (targetNode && root.contains(targetNode)) {
          return {
            node: targetNode
          };
        }

        var targetNodeId = payload.targetNodeId;

        if (targetNodeId != null && (targetNode = root.getNodeById(targetNodeId))) {
          return {
            node: targetNode
          };
        }
      }
    } // Not includes the given node at the last item.

    function getPathToRoot(node) {
      var path = [];

      while (node) {
        node = node.parentNode;
        node && path.push(node);
      }

      return path.reverse();
    }
    function aboveViewRoot(viewRoot, node) {
      var viewPath = getPathToRoot(viewRoot);
      return indexOf(viewPath, node) >= 0;
    } // From root to the input node (the input node will be included).

    function wrapTreePathInfo(node, seriesModel) {
      var treePathInfo = [];

      while (node) {
        var nodeDataIndex = node.dataIndex;
        treePathInfo.push({
          name: node.name,
          dataIndex: nodeDataIndex,
          value: seriesModel.getRawValue(nodeDataIndex)
        });
        node = node.parentNode;
      }

      treePathInfo.reverse();
      return treePathInfo;
    }

    var TreeSeriesModel =
    /** @class */
    function (_super) {
      __extends(TreeSeriesModel, _super);

      function TreeSeriesModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.hasSymbolVisual = true; // Do it self.

        _this.ignoreStyleOnData = true;
        return _this;
      }
      /**
       * Init a tree data structure from data in option series
       */


      TreeSeriesModel.prototype.getInitialData = function (option) {
        // create a virtual root
        var root = {
          name: option.name,
          children: option.data
        };
        var leaves = option.leaves || {};
        var leavesModel = new Model(leaves, this, this.ecModel);
        var tree = Tree.createTree(root, this, beforeLink);

        function beforeLink(nodeData) {
          nodeData.wrapMethod('getItemModel', function (model, idx) {
            var node = tree.getNodeByDataIndex(idx);

            if (!(node && node.children.length && node.isExpand)) {
              model.parentModel = leavesModel;
            }

            return model;
          });
        }

        var treeDepth = 0;
        tree.eachNode('preorder', function (node) {
          if (node.depth > treeDepth) {
            treeDepth = node.depth;
          }
        });
        var expandAndCollapse = option.expandAndCollapse;
        var expandTreeDepth = expandAndCollapse && option.initialTreeDepth >= 0 ? option.initialTreeDepth : treeDepth;
        tree.root.eachNode('preorder', function (node) {
          var item = node.hostTree.data.getRawDataItem(node.dataIndex); // Add item.collapsed != null, because users can collapse node original in the series.data.

          node.isExpand = item && item.collapsed != null ? !item.collapsed : node.depth <= expandTreeDepth;
        });
        return tree.data;
      };
      /**
       * Make the configuration 'orient' backward compatibly, with 'horizontal = LR', 'vertical = TB'.
       * @returns {string} orient
       */


      TreeSeriesModel.prototype.getOrient = function () {
        var orient = this.get('orient');

        if (orient === 'horizontal') {
          orient = 'LR';
        } else if (orient === 'vertical') {
          orient = 'TB';
        }

        return orient;
      };

      TreeSeriesModel.prototype.setZoom = function (zoom) {
        this.option.zoom = zoom;
      };

      TreeSeriesModel.prototype.setCenter = function (center) {
        this.option.center = center;
      };

      TreeSeriesModel.prototype.formatTooltip = function (dataIndex, multipleSeries, dataType) {
        var tree = this.getData().tree;
        var realRoot = tree.root.children[0];
        var node = tree.getNodeByDataIndex(dataIndex);
        var value = node.getValue();
        var name = node.name;

        while (node && node !== realRoot) {
          name = node.parentNode.name + '.' + name;
          node = node.parentNode;
        }

        return createTooltipMarkup('nameValue', {
          name: name,
          value: value,
          noValue: isNaN(value) || value == null
        });
      }; // Add tree path to tooltip param


      TreeSeriesModel.prototype.getDataParams = function (dataIndex) {
        var params = _super.prototype.getDataParams.apply(this, arguments);

        var node = this.getData().tree.getNodeByDataIndex(dataIndex);
        params.treeAncestors = wrapTreePathInfo(node, this);
        params.collapsed = !node.isExpand;
        return params;
      };

      TreeSeriesModel.type = 'series.tree'; // can support the position parameters 'left', 'top','right','bottom', 'width',
      // 'height' in the setOption() with 'merge' mode normal.

      TreeSeriesModel.layoutMode = 'box';
      TreeSeriesModel.defaultOption = {
        // zlevel: 0,
        z: 2,
        coordinateSystem: 'view',
        // the position of the whole view
        left: '12%',
        top: '12%',
        right: '12%',
        bottom: '12%',
        // the layout of the tree, two value can be selected, 'orthogonal' or 'radial'
        layout: 'orthogonal',
        // value can be 'polyline'
        edgeShape: 'curve',
        edgeForkPosition: '50%',
        // true | false | 'move' | 'scale', see module:component/helper/RoamController.
        roam: false,
        // Symbol size scale ratio in roam
        nodeScaleRatio: 0.4,
        // Default on center of graph
        center: null,
        zoom: 1,
        orient: 'LR',
        symbol: 'emptyCircle',
        symbolSize: 7,
        expandAndCollapse: true,
        initialTreeDepth: 2,
        lineStyle: {
          color: '#ccc',
          width: 1.5,
          curveness: 0.5
        },
        itemStyle: {
          color: 'lightsteelblue',
          // borderColor: '#c23531',
          borderWidth: 1.5
        },
        label: {
          show: true
        },
        animationEasing: 'linear',
        animationDuration: 700,
        animationDurationUpdate: 500
      };
      return TreeSeriesModel;
    }(SeriesModel);

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


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

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

    /**
     * Traverse the tree from bottom to top and do something
     */
    function eachAfter(root, callback, separation) {
      var nodes = [root];
      var next = [];
      var node;

      while (node = nodes.pop()) {
        // jshint ignore:line
        next.push(node);

        if (node.isExpand) {
          var children = node.children;

          if (children.length) {
            for (var i = 0; i < children.length; i++) {
              nodes.push(children[i]);
            }
          }
        }
      }

      while (node = next.pop()) {
        // jshint ignore:line
        callback(node, separation);
      }
    }
    /**
     * Traverse the tree from top to bottom and do something
     */


    function eachBefore(root, callback) {
      var nodes = [root];
      var node;

      while (node = nodes.pop()) {
        // jshint ignore:line
        callback(node);

        if (node.isExpand) {
          var children = node.children;

          if (children.length) {
            for (var i = children.length - 1; i >= 0; i--) {
              nodes.push(children[i]);
            }
          }
        }
      }
    }

    function treeLayout(ecModel, api) {
      ecModel.eachSeriesByType('tree', function (seriesModel) {
        commonLayout(seriesModel, api);
      });
    }

    function commonLayout(seriesModel, api) {
      var layoutInfo = getViewRect$1(seriesModel, api);
      seriesModel.layoutInfo = layoutInfo;
      var layout = seriesModel.get('layout');
      var width = 0;
      var height = 0;
      var separation$1 = null;

      if (layout === 'radial') {
        width = 2 * Math.PI;
        height = Math.min(layoutInfo.height, layoutInfo.width) / 2;
        separation$1 = separation(function (node1, node2) {
          return (node1.parentNode === node2.parentNode ? 1 : 2) / node1.depth;
        });
      } else {
        width = layoutInfo.width;
        height = layoutInfo.height;
        separation$1 = separation();
      }

      var virtualRoot = seriesModel.getData().tree.root;
      var realRoot = virtualRoot.children[0];

      if (realRoot) {
        init$2(virtualRoot);
        eachAfter(realRoot, firstWalk, separation$1);
        virtualRoot.hierNode.modifier = -realRoot.hierNode.prelim;
        eachBefore(realRoot, secondWalk);
        var left_1 = realRoot;
        var right_1 = realRoot;
        var bottom_1 = realRoot;
        eachBefore(realRoot, function (node) {
          var x = node.getLayout().x;

          if (x < left_1.getLayout().x) {
            left_1 = node;
          }

          if (x > right_1.getLayout().x) {
            right_1 = node;
          }

          if (node.depth > bottom_1.depth) {
            bottom_1 = node;
          }
        });
        var delta = left_1 === right_1 ? 1 : separation$1(left_1, right_1) / 2;
        var tx_1 = delta - left_1.getLayout().x;
        var kx_1 = 0;
        var ky_1 = 0;
        var coorX_1 = 0;
        var coorY_1 = 0;

        if (layout === 'radial') {
          kx_1 = width / (right_1.getLayout().x + delta + tx_1); // here we use (node.depth - 1), bucause the real root's depth is 1

          ky_1 = height / (bottom_1.depth - 1 || 1);
          eachBefore(realRoot, function (node) {
            coorX_1 = (node.getLayout().x + tx_1) * kx_1;
            coorY_1 = (node.depth - 1) * ky_1;
            var finalCoor = radialCoordinate(coorX_1, coorY_1);
            node.setLayout({
              x: finalCoor.x,
              y: finalCoor.y,
              rawX: coorX_1,
              rawY: coorY_1
            }, true);
          });
        } else {
          var orient_1 = seriesModel.getOrient();

          if (orient_1 === 'RL' || orient_1 === 'LR') {
            ky_1 = height / (right_1.getLayout().x + delta + tx_1);
            kx_1 = width / (bottom_1.depth - 1 || 1);
            eachBefore(realRoot, function (node) {
              coorY_1 = (node.getLayout().x + tx_1) * ky_1;
              coorX_1 = orient_1 === 'LR' ? (node.depth - 1) * kx_1 : width - (node.depth - 1) * kx_1;
              node.setLayout({
                x: coorX_1,
                y: coorY_1
              }, true);
            });
          } else if (orient_1 === 'TB' || orient_1 === 'BT') {
            kx_1 = width / (right_1.getLayout().x + delta + tx_1);
            ky_1 = height / (bottom_1.depth - 1 || 1);
            eachBefore(realRoot, function (node) {
              coorX_1 = (node.getLayout().x + tx_1) * kx_1;
              coorY_1 = orient_1 === 'TB' ? (node.depth - 1) * ky_1 : height - (node.depth - 1) * ky_1;
              node.setLayout({
                x: coorX_1,
                y: coorY_1
              }, true);
            });
          }
        }
      }
    }

    function treeVisual(ecModel) {
      ecModel.eachSeriesByType('tree', function (seriesModel) {
        var data = seriesModel.getData();
        var tree = data.tree;
        tree.eachNode(function (node) {
          var model = node.getModel(); // TODO Optimize

          var style = model.getModel('itemStyle').getItemStyle();
          var existsStyle = data.ensureUniqueItemVisual(node.dataIndex, 'style');
          extend(existsStyle, style);
        });
      });
    }

    function installTreeAction(registers) {
      registers.registerAction({
        type: 'treeExpandAndCollapse',
        event: 'treeExpandAndCollapse',
        update: 'update'
      }, function (payload, ecModel) {
        ecModel.eachComponent({
          mainType: 'series',
          subType: 'tree',
          query: payload
        }, function (seriesModel) {
          var dataIndex = payload.dataIndex;
          var tree = seriesModel.getData().tree;
          var node = tree.getNodeByDataIndex(dataIndex);
          node.isExpand = !node.isExpand;
        });
      });
      registers.registerAction({
        type: 'treeRoam',
        event: 'treeRoam',
        // Here we set 'none' instead of 'update', because roam action
        // just need to update the transform matrix without having to recalculate
        // the layout. So don't need to go through the whole update process, such
        // as 'dataPrcocess', 'coordSystemUpdate', 'layout' and so on.
        update: 'none'
      }, function (payload, ecModel, api) {
        ecModel.eachComponent({
          mainType: 'series',
          subType: 'tree',
          query: payload
        }, function (seriesModel) {
          var coordSys = seriesModel.coordinateSystem;
          var res = updateCenterAndZoom(coordSys, payload, undefined, api);
          seriesModel.setCenter && seriesModel.setCenter(res.center);
          seriesModel.setZoom && seriesModel.setZoom(res.zoom);
        });
      });
    }

    function install$b(registers) {
      registers.registerChartView(TreeView);
      registers.registerSeriesModel(TreeSeriesModel);
      registers.registerLayout(treeLayout);
      registers.registerVisual(treeVisual);
      installTreeAction(registers);
    }

    var actionTypes = ['treemapZoomToNode', 'treemapRender', 'treemapMove'];
    function installTreemapAction(registers) {
      for (var i = 0; i < actionTypes.length; i++) {
        registers.registerAction({
          type: actionTypes[i],
          update: 'updateView'
        }, noop);
      }

      registers.registerAction({
        type: 'treemapRootToNode',
        update: 'updateView'
      }, function (payload, ecModel) {
        ecModel.eachComponent({
          mainType: 'series',
          subType: 'treemap',
          query: payload
        }, handleRootToNode);

        function handleRootToNode(model, index) {
          var types = ['treemapZoomToNode', 'treemapRootToNode'];
          var targetInfo = retrieveTargetInfo(payload, types, model);

          if (targetInfo) {
            var originViewRoot = model.getViewRoot();

            if (originViewRoot) {
              payload.direction = aboveViewRoot(originViewRoot, targetInfo.node) ? 'rollUp' : 'drillDown';
            }

            model.resetViewRoot(targetInfo.node);
          }
        }
      });
    }

    function enableAriaDecalForTree(seriesModel) {
      var data = seriesModel.getData();
      var tree = data.tree;
      var decalPaletteScope = {};
      tree.eachNode(function (node) {
        // Use decal of level 1 node
        var current = node;

        while (current && current.depth > 1) {
          current = current.parentNode;
        }

        var decal = getDecalFromPalette(seriesModel.ecModel, current.name || current.dataIndex + '', decalPaletteScope);
        node.setVisual('decal', decal);
      });
    }

    var TreemapSeriesModel =
    /** @class */
    function (_super) {
      __extends(TreemapSeriesModel, _super);

      function TreemapSeriesModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = TreemapSeriesModel.type;
        _this.preventUsingHoverLayer = true;
        return _this;
      }
      /**
       * @override
       */


      TreemapSeriesModel.prototype.getInitialData = function (option, ecModel) {
        // Create a virtual root.
        var root = {
          name: option.name,
          children: option.data
        };
        completeTreeValue(root);
        var levels = option.levels || []; // Used in "visual priority" in `treemapVisual.js`.
        // This way is a little tricky, must satisfy the precondition:
        //   1. There is no `treeNode.getModel('itemStyle.xxx')` used.
        //   2. The `Model.prototype.getModel()` will not use any clone-like way.

        var designatedVisualItemStyle = this.designatedVisualItemStyle = {};
        var designatedVisualModel = new Model({
          itemStyle: designatedVisualItemStyle
        }, this, ecModel);
        levels = option.levels = setDefault(levels, ecModel);
        var levelModels = map(levels || [], function (levelDefine) {
          return new Model(levelDefine, designatedVisualModel, ecModel);
        }, this); // Make sure always a new tree is created when setOption,
        // in TreemapView, we check whether oldTree === newTree
        // to choose mappings approach among old shapes and new shapes.

        var tree = Tree.createTree(root, this, beforeLink);

        function beforeLink(nodeData) {
          nodeData.wrapMethod('getItemModel', function (model, idx) {
            var node = tree.getNodeByDataIndex(idx);
            var levelModel = node ? levelModels[node.depth] : null; // If no levelModel, we also need `designatedVisualModel`.

            model.parentModel = levelModel || designatedVisualModel;
            return model;
          });
        }

        return tree.data;
      };

      TreemapSeriesModel.prototype.optionUpdated = function () {
        this.resetViewRoot();
      };
      /**
       * @override
       * @param {number} dataIndex
       * @param {boolean} [mutipleSeries=false]
       */


      TreemapSeriesModel.prototype.formatTooltip = function (dataIndex, multipleSeries, dataType) {
        var data = this.getData();
        var value = this.getRawValue(dataIndex);
        var name = data.getName(dataIndex);
        return createTooltipMarkup('nameValue', {
          name: name,
          value: value
        });
      };
      /**
       * Add tree path to tooltip param
       *
       * @override
       * @param {number} dataIndex
       * @return {Object}
       */


      TreemapSeriesModel.prototype.getDataParams = function (dataIndex) {
        var params = _super.prototype.getDataParams.apply(this, arguments);

        var node = this.getData().tree.getNodeByDataIndex(dataIndex);
        params.treeAncestors = wrapTreePathInfo(node, this); // compatitable the previous code.

        params.treePathInfo = params.treeAncestors;
        return params;
      };
      /**
       * @public
       * @param {Object} layoutInfo {
       *                                x: containerGroup x
       *                                y: containerGroup y
       *                                width: containerGroup width
       *                                height: containerGroup height
       *                            }
       */


      TreemapSeriesModel.prototype.setLayoutInfo = function (layoutInfo) {
        /**
         * @readOnly
         * @type {Object}
         */
        this.layoutInfo = this.layoutInfo || {};
        extend(this.layoutInfo, layoutInfo);
      };
      /**
       * @param  {string} id
       * @return {number} index
       */


      TreemapSeriesModel.prototype.mapIdToIndex = function (id) {
        // A feature is implemented:
        // index is monotone increasing with the sequence of
        // input id at the first time.
        // This feature can make sure that each data item and its
        // mapped color have the same index between data list and
        // color list at the beginning, which is useful for user
        // to adjust data-color mapping.

        /**
         * @private
         * @type {Object}
         */
        var idIndexMap = this._idIndexMap;

        if (!idIndexMap) {
          idIndexMap = this._idIndexMap = createHashMap();
          /**
           * @private
           * @type {number}
           */

          this._idIndexMapCount = 0;
        }

        var index = idIndexMap.get(id);

        if (index == null) {
          idIndexMap.set(id, index = this._idIndexMapCount++);
        }

        return index;
      };

      TreemapSeriesModel.prototype.getViewRoot = function () {
        return this._viewRoot;
      };

      TreemapSeriesModel.prototype.resetViewRoot = function (viewRoot) {
        viewRoot ? this._viewRoot = viewRoot : viewRoot = this._viewRoot;
        var root = this.getRawData().tree.root;

        if (!viewRoot || viewRoot !== root && !root.contains(viewRoot)) {
          this._viewRoot = root;
        }
      };

      TreemapSeriesModel.prototype.enableAriaDecal = function () {
        enableAriaDecalForTree(this);
      };

      TreemapSeriesModel.type = 'series.treemap';
      TreemapSeriesModel.layoutMode = 'box';
      TreemapSeriesModel.defaultOption = {
        // Disable progressive rendering
        progressive: 0,
        // size: ['80%', '80%'],            // deprecated, compatible with ec2.
        left: 'center',
        top: 'middle',
        width: '80%',
        height: '80%',
        sort: true,
        clipWindow: 'origin',
        squareRatio: 0.5 * (1 + Math.sqrt(5)),
        leafDepth: null,
        drillDownIcon: '▶',
        // to align specialized icon. ▷▶❒❐▼✚
        zoomToNodeRatio: 0.32 * 0.32,
        roam: true,
        nodeClick: 'zoomToNode',
        animation: true,
        animationDurationUpdate: 900,
        animationEasing: 'quinticInOut',
        breadcrumb: {
          show: true,
          height: 22,
          left: 'center',
          top: 'bottom',
          // right
          // bottom
          emptyItemWidth: 25,
          itemStyle: {
            color: 'rgba(0,0,0,0.7)',
            textStyle: {
              color: '#fff'
            }
          },
          emphasis: {
            itemStyle: {
              color: 'rgba(0,0,0,0.9)' // '#5793f3',

            }
          }
        },
        label: {
          show: true,
          // Do not use textDistance, for ellipsis rect just the same as treemap node rect.
          distance: 0,
          padding: 5,
          position: 'inside',
          // formatter: null,
          color: '#fff',
          overflow: 'truncate' // align
          // verticalAlign

        },
        upperLabel: {
          show: false,
          position: [0, '50%'],
          height: 20,
          // formatter: null,
          // color: '#fff',
          overflow: 'truncate',
          // align: null,
          verticalAlign: 'middle'
        },
        itemStyle: {
          color: null,
          colorAlpha: null,
          colorSaturation: null,
          borderWidth: 0,
          gapWidth: 0,
          borderColor: '#fff',
          borderColorSaturation: null // If specified, borderColor will be ineffective, and the
          // border color is evaluated by color of current node and
          // borderColorSaturation.

        },
        emphasis: {
          upperLabel: {
            show: true,
            position: [0, '50%'],
            overflow: 'truncate',
            verticalAlign: 'middle'
          }
        },
        visualDimension: 0,
        visualMin: null,
        visualMax: null,
        color: [],
        // level[n].color (if necessary).
        // + Specify color list of each level. level[0].color would be global
        // color list if not specified. (see method `setDefault`).
        // + But set as a empty array to forbid fetch color from global palette
        // when using nodeModel.get('color'), otherwise nodes on deep level
        // will always has color palette set and are not able to inherit color
        // from parent node.
        // + TreemapSeries.color can not be set as 'none', otherwise effect
        // legend color fetching (see seriesColor.js).
        colorAlpha: null,
        colorSaturation: null,
        colorMappingBy: 'index',
        visibleMin: 10,
        // be rendered. Only works when sort is 'asc' or 'desc'.
        childrenVisibleMin: null,
        // grandchildren will not show.
        // Why grandchildren? If not grandchildren but children,
        // some siblings show children and some not,
        // the appearance may be mess and not consistent,
        levels: [] // Each item: {
        //     visibleMin, itemStyle, visualDimension, label
        // }

      };
      return TreemapSeriesModel;
    }(SeriesModel);
    /**
     * @param {Object} dataNode
     */


    function completeTreeValue(dataNode) {
      // Postorder travel tree.
      // If value of none-leaf node is not set,
      // calculate it by suming up the value of all children.
      var sum = 0;
      each(dataNode.children, function (child) {
        completeTreeValue(child);
        var childValue = child.value;
        isArray(childValue) && (childValue = childValue[0]);
        sum += childValue;
      });
      var thisValue = dataNode.value;

      if (isArray(thisValue)) {
        thisValue = thisValue[0];
      }

      if (thisValue == null || isNaN(thisValue)) {
        thisValue = sum;
      } // Value should not less than 0.


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

      isArray(dataNode.value) ? dataNode.value[0] = thisValue : dataNode.value = thisValue;
    }
    /**
     * set default to level configuration
     */


    function setDefault(levels, ecModel) {
      var globalColorList = normalizeToArray(ecModel.get('color'));
      var globalDecalList = normalizeToArray(ecModel.get(['aria', 'decal', 'decals']));

      if (!globalColorList) {
        return;
      }

      levels = levels || [];
      var hasColorDefine;
      var hasDecalDefine;
      each(levels, function (levelDefine) {
        var model = new Model(levelDefine);
        var modelColor = model.get('color');
        var modelDecal = model.get('decal');

        if (model.get(['itemStyle', 'color']) || modelColor && modelColor !== 'none') {
          hasColorDefine = true;
        }

        if (model.get(['itemStyle', 'decal']) || modelDecal && modelDecal !== 'none') {
          hasDecalDefine = true;
        }
      });
      var level0 = levels[0] || (levels[0] = {});

      if (!hasColorDefine) {
        level0.color = globalColorList.slice();
      }

      if (!hasDecalDefine && globalDecalList) {
        level0.decal = globalDecalList.slice();
      }

      return levels;
    }

    var TEXT_PADDING = 8;
    var ITEM_GAP = 8;
    var ARRAY_LENGTH = 5;

    var Breadcrumb =
    /** @class */
    function () {
      function Breadcrumb(containerGroup) {
        this.group = new Group();
        containerGroup.add(this.group);
      }

      Breadcrumb.prototype.render = function (seriesModel, api, targetNode, onSelect) {
        var model = seriesModel.getModel('breadcrumb');
        var thisGroup = this.group;
        thisGroup.removeAll();

        if (!model.get('show') || !targetNode) {
          return;
        }

        var normalStyleModel = model.getModel('itemStyle');
        var emphasisModel = model.getModel('emphasis');
        var textStyleModel = normalStyleModel.getModel('textStyle');
        var emphasisTextStyleModel = emphasisModel.getModel(['itemStyle', 'textStyle']);
        var layoutParam = {
          pos: {
            left: model.get('left'),
            right: model.get('right'),
            top: model.get('top'),
            bottom: model.get('bottom')
          },
          box: {
            width: api.getWidth(),
            height: api.getHeight()
          },
          emptyItemWidth: model.get('emptyItemWidth'),
          totalWidth: 0,
          renderList: []
        };

        this._prepare(targetNode, layoutParam, textStyleModel);

        this._renderContent(seriesModel, layoutParam, normalStyleModel, emphasisModel, textStyleModel, emphasisTextStyleModel, onSelect);

        positionElement(thisGroup, layoutParam.pos, layoutParam.box);
      };
      /**
       * Prepare render list and total width
       * @private
       */


      Breadcrumb.prototype._prepare = function (targetNode, layoutParam, textStyleModel) {
        for (var node = targetNode; node; node = node.parentNode) {
          var text = convertOptionIdName(node.getModel().get('name'), '');
          var textRect = textStyleModel.getTextRect(text);
          var itemWidth = Math.max(textRect.width + TEXT_PADDING * 2, layoutParam.emptyItemWidth);
          layoutParam.totalWidth += itemWidth + ITEM_GAP;
          layoutParam.renderList.push({
            node: node,
            text: text,
            width: itemWidth
          });
        }
      };
      /**
       * @private
       */


      Breadcrumb.prototype._renderContent = function (seriesModel, layoutParam, normalStyleModel, emphasisModel, textStyleModel, emphasisTextStyleModel, onSelect) {
        // Start rendering.
        var lastX = 0;
        var emptyItemWidth = layoutParam.emptyItemWidth;
        var height = seriesModel.get(['breadcrumb', 'height']);
        var availableSize = getAvailableSize(layoutParam.pos, layoutParam.box);
        var totalWidth = layoutParam.totalWidth;
        var renderList = layoutParam.renderList;
        var emphasisItemStyle = emphasisModel.getModel('itemStyle').getItemStyle();

        for (var i = renderList.length - 1; i >= 0; i--) {
          var item = renderList[i];
          var itemNode = item.node;
          var itemWidth = item.width;
          var text = item.text; // Hdie text and shorten width if necessary.

          if (totalWidth > availableSize.width) {
            totalWidth -= itemWidth - emptyItemWidth;
            itemWidth = emptyItemWidth;
            text = null;
          }

          var el = new Polygon({
            shape: {
              points: makeItemPoints(lastX, 0, itemWidth, height, i === renderList.length - 1, i === 0)
            },
            style: defaults(normalStyleModel.getItemStyle(), {
              lineJoin: 'bevel'
            }),
            textContent: new ZRText({
              style: createTextStyle(textStyleModel, {
                text: text
              })
            }),
            textConfig: {
              position: 'inside'
            },
            z2: Z2_EMPHASIS_LIFT * 1e4,
            onclick: curry(onSelect, itemNode)
          });
          el.disableLabelAnimation = true;
          el.getTextContent().ensureState('emphasis').style = createTextStyle(emphasisTextStyleModel, {
            text: text
          });
          el.ensureState('emphasis').style = emphasisItemStyle;
          toggleHoverEmphasis(el, emphasisModel.get('focus'), emphasisModel.get('blurScope'), emphasisModel.get('disabled'));
          this.group.add(el);
          packEventData(el, seriesModel, itemNode);
          lastX += itemWidth + ITEM_GAP;
        }
      };

      Breadcrumb.prototype.remove = function () {
        this.group.removeAll();
      };

      return Breadcrumb;
    }();

    function makeItemPoints(x, y, itemWidth, itemHeight, head, tail) {
      var points = [[head ? x : x - ARRAY_LENGTH, y], [x + itemWidth, y], [x + itemWidth, y + itemHeight], [head ? x : x - ARRAY_LENGTH, y + itemHeight]];
      !tail && points.splice(2, 0, [x + itemWidth + ARRAY_LENGTH, y + itemHeight / 2]);
      !head && points.push([x, y + itemHeight / 2]);
      return points;
    } // Package custom mouse event.


    function packEventData(el, seriesModel, itemNode) {
      getECData(el).eventData = {
        componentType: 'series',
        componentSubType: 'treemap',
        componentIndex: seriesModel.componentIndex,
        seriesIndex: seriesModel.seriesIndex,
        seriesName: seriesModel.name,
        seriesType: 'treemap',
        selfType: 'breadcrumb',
        nodeData: {
          dataIndex: itemNode && itemNode.dataIndex,
          name: itemNode && itemNode.name
        },
        treePathInfo: itemNode && wrapTreePathInfo(itemNode, seriesModel)
      };
    }

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


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

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

    /**
     * Animate multiple elements with a single done-callback.
     *
     * @example
     *  animation
     *      .createWrap()
     *      .add(el1, {x: 10, y: 10})
     *      .add(el2, {shape: {width: 500}, style: {fill: 'red'}}, 400)
     *      .done(function () { // done })
     *      .start('cubicOut');
     */
    var AnimationWrap =
    /** @class */
    function () {
      function AnimationWrap() {
        this._storage = [];
        this._elExistsMap = {};
      }
      /**
       * Caution: a el can only be added once, otherwise 'done'
       * might not be called. This method checks this (by el.id),
       * suppresses adding and returns false when existing el found.
       *
       * @return Whether adding succeeded.
       */


      AnimationWrap.prototype.add = function (el, target, duration, delay, easing) {
        if (this._elExistsMap[el.id]) {
          return false;
        }

        this._elExistsMap[el.id] = true;

        this._storage.push({
          el: el,
          target: target,
          duration: duration,
          delay: delay,
          easing: easing
        });

        return true;
      };
      /**
       * Only execute when animation done/aborted.
       */


      AnimationWrap.prototype.finished = function (callback) {
        this._finishedCallback = callback;
        return this;
      };
      /**
       * Will stop exist animation firstly.
       */


      AnimationWrap.prototype.start = function () {
        var _this = this;

        var count = this._storage.length;

        var checkTerminate = function () {
          count--;

          if (count <= 0) {
            // Guard.
            _this._storage.length = 0;
            _this._elExistsMap = {};
            _this._finishedCallback && _this._finishedCallback();
          }
        };

        for (var i = 0, len = this._storage.length; i < len; i++) {
          var item = this._storage[i];
          item.el.animateTo(item.target, {
            duration: item.duration,
            delay: item.delay,
            easing: item.easing,
            setToFinal: true,
            done: checkTerminate,
            aborted: checkTerminate
          });
        }

        return this;
      };

      return AnimationWrap;
    }();

    function createWrap() {
      return new AnimationWrap();
    }

    var Group$1 = Group;
    var Rect$1 = Rect;
    var DRAG_THRESHOLD = 3;
    var PATH_LABEL_NOAMAL = 'label';
    var PATH_UPPERLABEL_NORMAL = 'upperLabel'; // Should larger than emphasis states lift z

    var Z2_BASE = Z2_EMPHASIS_LIFT * 10; // Should bigger than every z2.

    var Z2_BG = Z2_EMPHASIS_LIFT * 2;
    var Z2_CONTENT = Z2_EMPHASIS_LIFT * 3;
    var getStateItemStyle = makeStyleMapper([['fill', 'color'], // `borderColor` and `borderWidth` has been occupied,
    // so use `stroke` to indicate the stroke of the rect.
    ['stroke', 'strokeColor'], ['lineWidth', 'strokeWidth'], ['shadowBlur'], ['shadowOffsetX'], ['shadowOffsetY'], ['shadowColor'] // Option decal is in `DecalObject` but style.decal is in `PatternObject`.
    // So do not transfer decal directly.
    ]);

    var getItemStyleNormal = function (model) {
      // Normal style props should include emphasis style props.
      var itemStyle = getStateItemStyle(model); // Clear styles set by emphasis.

      itemStyle.stroke = itemStyle.fill = itemStyle.lineWidth = null;
      return itemStyle;
    };

    var inner$8 = makeInner();

    var TreemapView =
    /** @class */
    function (_super) {
      __extends(TreemapView, _super);

      function TreemapView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = TreemapView.type;
        _this._state = 'ready';
        _this._storage = createStorage();
        return _this;
      }
      /**
       * @override
       */


      TreemapView.prototype.render = function (seriesModel, ecModel, api, payload) {
        var models = ecModel.findComponents({
          mainType: 'series',
          subType: 'treemap',
          query: payload
        });

        if (indexOf(models, seriesModel) < 0) {
          return;
        }

        this.seriesModel = seriesModel;
        this.api = api;
        this.ecModel = ecModel;
        var types = ['treemapZoomToNode', 'treemapRootToNode'];
        var targetInfo = retrieveTargetInfo(payload, types, seriesModel);
        var payloadType = payload && payload.type;
        var layoutInfo = seriesModel.layoutInfo;
        var isInit = !this._oldTree;
        var thisStorage = this._storage; // Mark new root when action is treemapRootToNode.

        var reRoot = payloadType === 'treemapRootToNode' && targetInfo && thisStorage ? {
          rootNodeGroup: thisStorage.nodeGroup[targetInfo.node.getRawIndex()],
          direction: payload.direction
        } : null;

        var containerGroup = this._giveContainerGroup(layoutInfo);

        var hasAnimation = seriesModel.get('animation');

        var renderResult = this._doRender(containerGroup, seriesModel, reRoot);

        hasAnimation && !isInit && (!payloadType || payloadType === 'treemapZoomToNode' || payloadType === 'treemapRootToNode') ? this._doAnimation(containerGroup, renderResult, seriesModel, reRoot) : renderResult.renderFinally();

        this._resetController(api);

        this._renderBreadcrumb(seriesModel, api, targetInfo);
      };

      TreemapView.prototype._giveContainerGroup = function (layoutInfo) {
        var containerGroup = this._containerGroup;

        if (!containerGroup) {
          // FIXME
          // 加一层containerGroup是为了clip，但是现在clip功能并没有实现。
          containerGroup = this._containerGroup = new Group$1();

          this._initEvents(containerGroup);

          this.group.add(containerGroup);
        }

        containerGroup.x = layoutInfo.x;
        containerGroup.y = layoutInfo.y;
        return containerGroup;
      };

      TreemapView.prototype._doRender = function (containerGroup, seriesModel, reRoot) {
        var thisTree = seriesModel.getData().tree;
        var oldTree = this._oldTree; // Clear last shape records.

        var lastsForAnimation = createStorage();
        var thisStorage = createStorage();
        var oldStorage = this._storage;
        var willInvisibleEls = [];

        function doRenderNode(thisNode, oldNode, parentGroup, depth) {
          return renderNode(seriesModel, thisStorage, oldStorage, reRoot, lastsForAnimation, willInvisibleEls, thisNode, oldNode, parentGroup, depth);
        } // Notice: When thisTree and oldTree are the same tree (see list.cloneShallow),
        // the oldTree is actually losted, so we cannot find all of the old graphic
        // elements from tree. So we use this strategy: make element storage, move
        // from old storage to new storage, clear old storage.


        dualTravel(thisTree.root ? [thisTree.root] : [], oldTree && oldTree.root ? [oldTree.root] : [], containerGroup, thisTree === oldTree || !oldTree, 0); // Process all removing.

        var willDeleteEls = clearStorage(oldStorage);
        this._oldTree = thisTree;
        this._storage = thisStorage;
        return {
          lastsForAnimation: lastsForAnimation,
          willDeleteEls: willDeleteEls,
          renderFinally: renderFinally
        };

        function dualTravel(thisViewChildren, oldViewChildren, parentGroup, sameTree, depth) {
          // When 'render' is triggered by action,
          // 'this' and 'old' may be the same tree,
          // we use rawIndex in that case.
          if (sameTree) {
            oldViewChildren = thisViewChildren;
            each(thisViewChildren, function (child, index) {
              !child.isRemoved() && processNode(index, index);
            });
          } // Diff hierarchically (diff only in each subtree, but not whole).
          // because, consistency of view is important.
          else {
              new DataDiffer(oldViewChildren, thisViewChildren, getKey, getKey).add(processNode).update(processNode).remove(curry(processNode, null)).execute();
            }

          function getKey(node) {
            // Identify by name or raw index.
            return node.getId();
          }

          function processNode(newIndex, oldIndex) {
            var thisNode = newIndex != null ? thisViewChildren[newIndex] : null;
            var oldNode = oldIndex != null ? oldViewChildren[oldIndex] : null;
            var group = doRenderNode(thisNode, oldNode, parentGroup, depth);
            group && dualTravel(thisNode && thisNode.viewChildren || [], oldNode && oldNode.viewChildren || [], group, sameTree, depth + 1);
          }
        }

        function clearStorage(storage) {
          var willDeleteEls = createStorage();
          storage && each(storage, function (store, storageName) {
            var delEls = willDeleteEls[storageName];
            each(store, function (el) {
              el && (delEls.push(el), inner$8(el).willDelete = true);
            });
          });
          return willDeleteEls;
        }

        function renderFinally() {
          each(willDeleteEls, function (els) {
            each(els, function (el) {
              el.parent && el.parent.remove(el);
            });
          });
          each(willInvisibleEls, function (el) {
            el.invisible = true; // Setting invisible is for optimizing, so no need to set dirty,
            // just mark as invisible.

            el.dirty();
          });
        }
      };

      TreemapView.prototype._doAnimation = function (containerGroup, renderResult, seriesModel, reRoot) {
        var durationOption = seriesModel.get('animationDurationUpdate');
        var easingOption = seriesModel.get('animationEasing'); // TODO: do not support function until necessary.

        var duration = (isFunction(durationOption) ? 0 : durationOption) || 0;
        var easing = (isFunction(easingOption) ? null : easingOption) || 'cubicOut';
        var animationWrap = createWrap(); // Make delete animations.

        each(renderResult.willDeleteEls, function (store, storageName) {
          each(store, function (el, rawIndex) {
            if (el.invisible) {
              return;
            }

            var parent = el.parent; // Always has parent, and parent is nodeGroup.

            var target;
            var innerStore = inner$8(parent);

            if (reRoot && reRoot.direction === 'drillDown') {
              target = parent === reRoot.rootNodeGroup // This is the content element of view root.
              // Only `content` will enter this branch, because
              // `background` and `nodeGroup` will not be deleted.
              ? {
                shape: {
                  x: 0,
                  y: 0,
                  width: innerStore.nodeWidth,
                  height: innerStore.nodeHeight
                },
                style: {
                  opacity: 0
                }
              } // Others.
              : {
                style: {
                  opacity: 0
                }
              };
            } else {
              var targetX = 0;
              var targetY = 0;

              if (!innerStore.willDelete) {
                // Let node animate to right-bottom corner, cooperating with fadeout,
                // which is appropriate for user understanding.
                // Divided by 2 for reRoot rolling up effect.
                targetX = innerStore.nodeWidth / 2;
                targetY = innerStore.nodeHeight / 2;
              }

              target = storageName === 'nodeGroup' ? {
                x: targetX,
                y: targetY,
                style: {
                  opacity: 0
                }
              } : {
                shape: {
                  x: targetX,
                  y: targetY,
                  width: 0,
                  height: 0
                },
                style: {
                  opacity: 0
                }
              };
            } // TODO: do not support delay until necessary.


            target && animationWrap.add(el, target, duration, 0, easing);
          });
        }); // Make other animations

        each(this._storage, function (store, storageName) {
          each(store, function (el, rawIndex) {
            var last = renderResult.lastsForAnimation[storageName][rawIndex];
            var target = {};

            if (!last) {
              return;
            }

            if (el instanceof Group) {
              if (last.oldX != null) {
                target.x = el.x;
                target.y = el.y;
                el.x = last.oldX;
                el.y = last.oldY;
              }
            } else {
              if (last.oldShape) {
                target.shape = extend({}, el.shape);
                el.setShape(last.oldShape);
              }

              if (last.fadein) {
                el.setStyle('opacity', 0);
                target.style = {
                  opacity: 1
                };
              } // When animation is stopped for succedent animation starting,
              // el.style.opacity might not be 1
              else if (el.style.opacity !== 1) {
                  target.style = {
                    opacity: 1
                  };
                }
            }

            animationWrap.add(el, target, duration, 0, easing);
          });
        }, this);
        this._state = 'animating';
        animationWrap.finished(bind(function () {
          this._state = 'ready';
          renderResult.renderFinally();
        }, this)).start();
      };

      TreemapView.prototype._resetController = function (api) {
        var controller = this._controller; // Init controller.

        if (!controller) {
          controller = this._controller = new RoamController(api.getZr());
          controller.enable(this.seriesModel.get('roam'));
          controller.on('pan', bind(this._onPan, this));
          controller.on('zoom', bind(this._onZoom, this));
        }

        var rect = new BoundingRect(0, 0, api.getWidth(), api.getHeight());
        controller.setPointerChecker(function (e, x, y) {
          return rect.contain(x, y);
        });
      };

      TreemapView.prototype._clearController = function () {
        var controller = this._controller;

        if (controller) {
          controller.dispose();
          controller = null;
        }
      };

      TreemapView.prototype._onPan = function (e) {
        if (this._state !== 'animating' && (Math.abs(e.dx) > DRAG_THRESHOLD || Math.abs(e.dy) > DRAG_THRESHOLD)) {
          // These param must not be cached.
          var root = this.seriesModel.getData().tree.root;

          if (!root) {
            return;
          }

          var rootLayout = root.getLayout();

          if (!rootLayout) {
            return;
          }

          this.api.dispatchAction({
            type: 'treemapMove',
            from: this.uid,
            seriesId: this.seriesModel.id,
            rootRect: {
              x: rootLayout.x + e.dx,
              y: rootLayout.y + e.dy,
              width: rootLayout.width,
              height: rootLayout.height
            }
          });
        }
      };

      TreemapView.prototype._onZoom = function (e) {
        var mouseX = e.originX;
        var mouseY = e.originY;

        if (this._state !== 'animating') {
          // These param must not be cached.
          var root = this.seriesModel.getData().tree.root;

          if (!root) {
            return;
          }

          var rootLayout = root.getLayout();

          if (!rootLayout) {
            return;
          }

          var rect = new BoundingRect(rootLayout.x, rootLayout.y, rootLayout.width, rootLayout.height);
          var layoutInfo = this.seriesModel.layoutInfo; // Transform mouse coord from global to containerGroup.

          mouseX -= layoutInfo.x;
          mouseY -= layoutInfo.y; // Scale root bounding rect.

          var m = create$1();
          translate(m, m, [-mouseX, -mouseY]);
          scale$1(m, m, [e.scale, e.scale]);
          translate(m, m, [mouseX, mouseY]);
          rect.applyTransform(m);
          this.api.dispatchAction({
            type: 'treemapRender',
            from: this.uid,
            seriesId: this.seriesModel.id,
            rootRect: {
              x: rect.x,
              y: rect.y,
              width: rect.width,
              height: rect.height
            }
          });
        }
      };

      TreemapView.prototype._initEvents = function (containerGroup) {
        var _this = this;

        containerGroup.on('click', function (e) {
          if (_this._state !== 'ready') {
            return;
          }

          var nodeClick = _this.seriesModel.get('nodeClick', true);

          if (!nodeClick) {
            return;
          }

          var targetInfo = _this.findTarget(e.offsetX, e.offsetY);

          if (!targetInfo) {
            return;
          }

          var node = targetInfo.node;

          if (node.getLayout().isLeafRoot) {
            _this._rootToNode(targetInfo);
          } else {
            if (nodeClick === 'zoomToNode') {
              _this._zoomToNode(targetInfo);
            } else if (nodeClick === 'link') {
              var itemModel = node.hostTree.data.getItemModel(node.dataIndex);
              var link = itemModel.get('link', true);
              var linkTarget = itemModel.get('target', true) || 'blank';
              link && windowOpen(link, linkTarget);
            }
          }
        }, this);
      };

      TreemapView.prototype._renderBreadcrumb = function (seriesModel, api, targetInfo) {
        var _this = this;

        if (!targetInfo) {
          targetInfo = seriesModel.get('leafDepth', true) != null ? {
            node: seriesModel.getViewRoot()
          } // FIXME
          // better way?
          // Find breadcrumb tail on center of containerGroup.
          : this.findTarget(api.getWidth() / 2, api.getHeight() / 2);

          if (!targetInfo) {
            targetInfo = {
              node: seriesModel.getData().tree.root
            };
          }
        }

        (this._breadcrumb || (this._breadcrumb = new Breadcrumb(this.group))).render(seriesModel, api, targetInfo.node, function (node) {
          if (_this._state !== 'animating') {
            aboveViewRoot(seriesModel.getViewRoot(), node) ? _this._rootToNode({
              node: node
            }) : _this._zoomToNode({
              node: node
            });
          }
        });
      };
      /**
       * @override
       */


      TreemapView.prototype.remove = function () {
        this._clearController();

        this._containerGroup && this._containerGroup.removeAll();
        this._storage = createStorage();
        this._state = 'ready';
        this._breadcrumb && this._breadcrumb.remove();
      };

      TreemapView.prototype.dispose = function () {
        this._clearController();
      };

      TreemapView.prototype._zoomToNode = function (targetInfo) {
        this.api.dispatchAction({
          type: 'treemapZoomToNode',
          from: this.uid,
          seriesId: this.seriesModel.id,
          targetNode: targetInfo.node
        });
      };

      TreemapView.prototype._rootToNode = function (targetInfo) {
        this.api.dispatchAction({
          type: 'treemapRootToNode',
          from: this.uid,
          seriesId: this.seriesModel.id,
          targetNode: targetInfo.node
        });
      };
      /**
       * @public
       * @param {number} x Global coord x.
       * @param {number} y Global coord y.
       * @return {Object} info If not found, return undefined;
       * @return {number} info.node Target node.
       * @return {number} info.offsetX x refer to target node.
       * @return {number} info.offsetY y refer to target node.
       */


      TreemapView.prototype.findTarget = function (x, y) {
        var targetInfo;
        var viewRoot = this.seriesModel.getViewRoot();
        viewRoot.eachNode({
          attr: 'viewChildren',
          order: 'preorder'
        }, function (node) {
          var bgEl = this._storage.background[node.getRawIndex()]; // If invisible, there might be no element.


          if (bgEl) {
            var point = bgEl.transformCoordToLocal(x, y);
            var shape = bgEl.shape; // For performance consideration, don't use 'getBoundingRect'.

            if (shape.x <= point[0] && point[0] <= shape.x + shape.width && shape.y <= point[1] && point[1] <= shape.y + shape.height) {
              targetInfo = {
                node: node,
                offsetX: point[0],
                offsetY: point[1]
              };
            } else {
              return false; // Suppress visit subtree.
            }
          }
        }, this);
        return targetInfo;
      };

      TreemapView.type = 'treemap';
      return TreemapView;
    }(ChartView);
    /**
     * @inner
     */


    function createStorage() {
      return {
        nodeGroup: [],
        background: [],
        content: []
      };
    }
    /**
     * @inner
     * @return Return undefined means do not travel further.
     */


    function renderNode(seriesModel, thisStorage, oldStorage, reRoot, lastsForAnimation, willInvisibleEls, thisNode, oldNode, parentGroup, depth) {
      // Whether under viewRoot.
      if (!thisNode) {
        // Deleting nodes will be performed finally. This method just find
        // element from old storage, or create new element, set them to new
        // storage, and set styles.
        return;
      } // -------------------------------------------------------------------
      // Start of closure variables available in "Procedures in renderNode".


      var thisLayout = thisNode.getLayout();
      var data = seriesModel.getData();
      var nodeModel = thisNode.getModel(); // Only for enabling highlight/downplay. Clear firstly.
      // Because some node will not be rendered.

      data.setItemGraphicEl(thisNode.dataIndex, null);

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

      var thisWidth = thisLayout.width;
      var thisHeight = thisLayout.height;
      var borderWidth = thisLayout.borderWidth;
      var thisInvisible = thisLayout.invisible;
      var thisRawIndex = thisNode.getRawIndex();
      var oldRawIndex = oldNode && oldNode.getRawIndex();
      var thisViewChildren = thisNode.viewChildren;
      var upperHeight = thisLayout.upperHeight;
      var isParent = thisViewChildren && thisViewChildren.length;
      var itemStyleNormalModel = nodeModel.getModel('itemStyle');
      var itemStyleEmphasisModel = nodeModel.getModel(['emphasis', 'itemStyle']);
      var itemStyleBlurModel = nodeModel.getModel(['blur', 'itemStyle']);
      var itemStyleSelectModel = nodeModel.getModel(['select', 'itemStyle']);
      var borderRadius = itemStyleNormalModel.get('borderRadius') || 0; // End of closure ariables available in "Procedures in renderNode".
      // -----------------------------------------------------------------
      // Node group

      var group = giveGraphic('nodeGroup', Group$1);

      if (!group) {
        return;
      }

      parentGroup.add(group); // x,y are not set when el is above view root.

      group.x = thisLayout.x || 0;
      group.y = thisLayout.y || 0;
      group.markRedraw();
      inner$8(group).nodeWidth = thisWidth;
      inner$8(group).nodeHeight = thisHeight;

      if (thisLayout.isAboveViewRoot) {
        return group;
      } // Background


      var bg = giveGraphic('background', Rect$1, depth, Z2_BG);
      bg && renderBackground(group, bg, isParent && thisLayout.upperLabelHeight);
      var emphasisModel = nodeModel.getModel('emphasis');
      var focus = emphasisModel.get('focus');
      var blurScope = emphasisModel.get('blurScope');
      var isDisabled = emphasisModel.get('disabled');
      var focusOrIndices = focus === 'ancestor' ? thisNode.getAncestorsIndices() : focus === 'descendant' ? thisNode.getDescendantIndices() : focus; // No children, render content.

      if (isParent) {
        // Because of the implementation about "traverse" in graphic hover style, we
        // can not set hover listener on the "group" of non-leaf node. Otherwise the
        // hover event from the descendents will be listenered.
        if (isHighDownDispatcher(group)) {
          setAsHighDownDispatcher(group, false);
        }

        if (bg) {
          setAsHighDownDispatcher(bg, !isDisabled); // Only for enabling highlight/downplay.

          data.setItemGraphicEl(thisNode.dataIndex, bg);
          enableHoverFocus(bg, focusOrIndices, blurScope);
        }
      } else {
        var content = giveGraphic('content', Rect$1, depth, Z2_CONTENT);
        content && renderContent(group, content);
        bg.disableMorphing = true;

        if (bg && isHighDownDispatcher(bg)) {
          setAsHighDownDispatcher(bg, false);
        }

        setAsHighDownDispatcher(group, !isDisabled); // Only for enabling highlight/downplay.

        data.setItemGraphicEl(thisNode.dataIndex, group);
        enableHoverFocus(group, focusOrIndices, blurScope);
      }

      return group; // ----------------------------
      // | Procedures in renderNode |
      // ----------------------------

      function renderBackground(group, bg, useUpperLabel) {
        var ecData = getECData(bg); // For tooltip.

        ecData.dataIndex = thisNode.dataIndex;
        ecData.seriesIndex = seriesModel.seriesIndex;
        bg.setShape({
          x: 0,
          y: 0,
          width: thisWidth,
          height: thisHeight,
          r: borderRadius
        });

        if (thisInvisible) {
          // If invisible, do not set visual, otherwise the element will
          // change immediately before animation. We think it is OK to
          // remain its origin color when moving out of the view window.
          processInvisible(bg);
        } else {
          bg.invisible = false;
          var style = thisNode.getVisual('style');
          var visualBorderColor = style.stroke;
          var normalStyle = getItemStyleNormal(itemStyleNormalModel);
          normalStyle.fill = visualBorderColor;
          var emphasisStyle = getStateItemStyle(itemStyleEmphasisModel);
          emphasisStyle.fill = itemStyleEmphasisModel.get('borderColor');
          var blurStyle = getStateItemStyle(itemStyleBlurModel);
          blurStyle.fill = itemStyleBlurModel.get('borderColor');
          var selectStyle = getStateItemStyle(itemStyleSelectModel);
          selectStyle.fill = itemStyleSelectModel.get('borderColor');

          if (useUpperLabel) {
            var upperLabelWidth = thisWidth - 2 * borderWidth;
            prepareText( // PENDING: convert ZRColor to ColorString for text.
            bg, visualBorderColor, style.opacity, {
              x: borderWidth,
              y: 0,
              width: upperLabelWidth,
              height: upperHeight
            });
          } // For old bg.
          else {
              bg.removeTextContent();
            }

          bg.setStyle(normalStyle);
          bg.ensureState('emphasis').style = emphasisStyle;
          bg.ensureState('blur').style = blurStyle;
          bg.ensureState('select').style = selectStyle;
          setDefaultStateProxy(bg);
        }

        group.add(bg);
      }

      function renderContent(group, content) {
        var ecData = getECData(content); // For tooltip.

        ecData.dataIndex = thisNode.dataIndex;
        ecData.seriesIndex = seriesModel.seriesIndex;
        var contentWidth = Math.max(thisWidth - 2 * borderWidth, 0);
        var contentHeight = Math.max(thisHeight - 2 * borderWidth, 0);
        content.culling = true;
        content.setShape({
          x: borderWidth,
          y: borderWidth,
          width: contentWidth,
          height: contentHeight,
          r: borderRadius
        });

        if (thisInvisible) {
          // If invisible, do not set visual, otherwise the element will
          // change immediately before animation. We think it is OK to
          // remain its origin color when moving out of the view window.
          processInvisible(content);
        } else {
          content.invisible = false;
          var nodeStyle = thisNode.getVisual('style');
          var visualColor = nodeStyle.fill;
          var normalStyle = getItemStyleNormal(itemStyleNormalModel);
          normalStyle.fill = visualColor;
          normalStyle.decal = nodeStyle.decal;
          var emphasisStyle = getStateItemStyle(itemStyleEmphasisModel);
          var blurStyle = getStateItemStyle(itemStyleBlurModel);
          var selectStyle = getStateItemStyle(itemStyleSelectModel); // PENDING: convert ZRColor to ColorString for text.

          prepareText(content, visualColor, nodeStyle.opacity, null);
          content.setStyle(normalStyle);
          content.ensureState('emphasis').style = emphasisStyle;
          content.ensureState('blur').style = blurStyle;
          content.ensureState('select').style = selectStyle;
          setDefaultStateProxy(content);
        }

        group.add(content);
      }

      function processInvisible(element) {
        // Delay invisible setting utill animation finished,
        // avoid element vanish suddenly before animation.
        !element.invisible && willInvisibleEls.push(element);
      }

      function prepareText(rectEl, visualColor, visualOpacity, // Can be null/undefined
      upperLabelRect) {
        var normalLabelModel = nodeModel.getModel(upperLabelRect ? PATH_UPPERLABEL_NORMAL : PATH_LABEL_NOAMAL);
        var defaultText = convertOptionIdName(nodeModel.get('name'), null);
        var isShow = normalLabelModel.getShallow('show');
        setLabelStyle(rectEl, getLabelStatesModels(nodeModel, upperLabelRect ? PATH_UPPERLABEL_NORMAL : PATH_LABEL_NOAMAL), {
          defaultText: isShow ? defaultText : null,
          inheritColor: visualColor,
          defaultOpacity: visualOpacity,
          labelFetcher: seriesModel,
          labelDataIndex: thisNode.dataIndex
        });
        var textEl = rectEl.getTextContent();

        if (!textEl) {
          return;
        }

        var textStyle = textEl.style;
        var textPadding = normalizeCssArray(textStyle.padding || 0);

        if (upperLabelRect) {
          rectEl.setTextConfig({
            layoutRect: upperLabelRect
          });
          textEl.disableLabelLayout = true;
        }

        textEl.beforeUpdate = function () {
          var width = Math.max((upperLabelRect ? upperLabelRect.width : rectEl.shape.width) - textPadding[1] - textPadding[3], 0);
          var height = Math.max((upperLabelRect ? upperLabelRect.height : rectEl.shape.height) - textPadding[0] - textPadding[2], 0);

          if (textStyle.width !== width || textStyle.height !== height) {
            textEl.setStyle({
              width: width,
              height: height
            });
          }
        };

        textStyle.truncateMinChar = 2;
        textStyle.lineOverflow = 'truncate';
        addDrillDownIcon(textStyle, upperLabelRect, thisLayout);
        var textEmphasisState = textEl.getState('emphasis');
        addDrillDownIcon(textEmphasisState ? textEmphasisState.style : null, upperLabelRect, thisLayout);
      }

      function addDrillDownIcon(style, upperLabelRect, thisLayout) {
        var text = style ? style.text : null;

        if (!upperLabelRect && thisLayout.isLeafRoot && text != null) {
          var iconChar = seriesModel.get('drillDownIcon', true);
          style.text = iconChar ? iconChar + ' ' + text : text;
        }
      }

      function giveGraphic(storageName, Ctor, depth, z) {
        var element = oldRawIndex != null && oldStorage[storageName][oldRawIndex];
        var lasts = lastsForAnimation[storageName];

        if (element) {
          // Remove from oldStorage
          oldStorage[storageName][oldRawIndex] = null;
          prepareAnimationWhenHasOld(lasts, element);
        } // If invisible and no old element, do not create new element (for optimizing).
        else if (!thisInvisible) {
            element = new Ctor();

            if (element instanceof Displayable) {
              element.z2 = calculateZ2(depth, z);
            }

            prepareAnimationWhenNoOld(lasts, element);
          } // Set to thisStorage


        return thisStorage[storageName][thisRawIndex] = element;
      }

      function prepareAnimationWhenHasOld(lasts, element) {
        var lastCfg = lasts[thisRawIndex] = {};

        if (element instanceof Group$1) {
          lastCfg.oldX = element.x;
          lastCfg.oldY = element.y;
        } else {
          lastCfg.oldShape = extend({}, element.shape);
        }
      } // If a element is new, we need to find the animation start point carefully,
      // otherwise it will looks strange when 'zoomToNode'.


      function prepareAnimationWhenNoOld(lasts, element) {
        var lastCfg = lasts[thisRawIndex] = {};
        var parentNode = thisNode.parentNode;
        var isGroup = element instanceof Group;

        if (parentNode && (!reRoot || reRoot.direction === 'drillDown')) {
          var parentOldX = 0;
          var parentOldY = 0; // New nodes appear from right-bottom corner in 'zoomToNode' animation.
          // For convenience, get old bounding rect from background.

          var parentOldBg = lastsForAnimation.background[parentNode.getRawIndex()];

          if (!reRoot && parentOldBg && parentOldBg.oldShape) {
            parentOldX = parentOldBg.oldShape.width;
            parentOldY = parentOldBg.oldShape.height;
          } // When no parent old shape found, its parent is new too,
          // so we can just use {x:0, y:0}.


          if (isGroup) {
            lastCfg.oldX = 0;
            lastCfg.oldY = parentOldY;
          } else {
            lastCfg.oldShape = {
              x: parentOldX,
              y: parentOldY,
              width: 0,
              height: 0
            };
          }
        } // Fade in, user can be aware that these nodes are new.


        lastCfg.fadein = !isGroup;
      }
    } // We cannot set all background with the same z, because the behaviour of
    // drill down and roll up differ background creation sequence from tree
    // hierarchy sequence, which cause lower background elements to overlap
    // upper ones. So we calculate z based on depth.
    // Moreover, we try to shrink down z interval to [0, 1] to avoid that
    // treemap with large z overlaps other components.


    function calculateZ2(depth, z2InLevel) {
      return depth * Z2_BASE + z2InLevel;
    }

    var each$3 = each;
    var isObject$3 = isObject;
    var CATEGORY_DEFAULT_VISUAL_INDEX = -1;

    var VisualMapping =
    /** @class */
    function () {
      function VisualMapping(option) {
        var mappingMethod = option.mappingMethod;
        var visualType = option.type;
        var thisOption = this.option = clone(option);
        this.type = visualType;
        this.mappingMethod = mappingMethod;
        this._normalizeData = normalizers[mappingMethod];
        var visualHandler = VisualMapping.visualHandlers[visualType];
        this.applyVisual = visualHandler.applyVisual;
        this.getColorMapper = visualHandler.getColorMapper;
        this._normalizedToVisual = visualHandler._normalizedToVisual[mappingMethod];

        if (mappingMethod === 'piecewise') {
          normalizeVisualRange(thisOption);
          preprocessForPiecewise(thisOption);
        } else if (mappingMethod === 'category') {
          thisOption.categories ? preprocessForSpecifiedCategory(thisOption) // categories is ordinal when thisOption.categories not specified,
          // which need no more preprocess except normalize visual.
          : normalizeVisualRange(thisOption, true);
        } else {
          // mappingMethod === 'linear' or 'fixed'
          assert(mappingMethod !== 'linear' || thisOption.dataExtent);
          normalizeVisualRange(thisOption);
        }
      }

      VisualMapping.prototype.mapValueToVisual = function (value) {
        var normalized = this._normalizeData(value);

        return this._normalizedToVisual(normalized, value);
      };

      VisualMapping.prototype.getNormalizer = function () {
        return bind(this._normalizeData, this);
      };
      /**
       * List available visual types.
       *
       * @public
       * @return {Array.<string>}
       */


      VisualMapping.listVisualTypes = function () {
        return keys(VisualMapping.visualHandlers);
      }; // /**
      //  * @public
      //  */
      // static addVisualHandler(name, handler) {
      //     visualHandlers[name] = handler;
      // }

      /**
       * @public
       */


      VisualMapping.isValidType = function (visualType) {
        return VisualMapping.visualHandlers.hasOwnProperty(visualType);
      };
      /**
       * Convenient method.
       * Visual can be Object or Array or primary type.
       */


      VisualMapping.eachVisual = function (visual, callback, context) {
        if (isObject(visual)) {
          each(visual, callback, context);
        } else {
          callback.call(context, visual);
        }
      };

      VisualMapping.mapVisual = function (visual, callback, context) {
        var isPrimary;
        var newVisual = isArray(visual) ? [] : isObject(visual) ? {} : (isPrimary = true, null);
        VisualMapping.eachVisual(visual, function (v, key) {
          var newVal = callback.call(context, v, key);
          isPrimary ? newVisual = newVal : newVisual[key] = newVal;
        });
        return newVisual;
      };
      /**
       * Retrieve visual properties from given object.
       */


      VisualMapping.retrieveVisuals = function (obj) {
        var ret = {};
        var hasVisual;
        obj && each$3(VisualMapping.visualHandlers, function (h, visualType) {
          if (obj.hasOwnProperty(visualType)) {
            ret[visualType] = obj[visualType];
            hasVisual = true;
          }
        });
        return hasVisual ? ret : null;
      };
      /**
       * Give order to visual types, considering colorSaturation, colorAlpha depends on color.
       *
       * @public
       * @param {(Object|Array)} visualTypes If Object, like: {color: ..., colorSaturation: ...}
       *                                     IF Array, like: ['color', 'symbol', 'colorSaturation']
       * @return {Array.<string>} Sorted visual types.
       */


      VisualMapping.prepareVisualTypes = function (visualTypes) {
        if (isArray(visualTypes)) {
          visualTypes = visualTypes.slice();
        } else if (isObject$3(visualTypes)) {
          var types_1 = [];
          each$3(visualTypes, function (item, type) {
            types_1.push(type);
          });
          visualTypes = types_1;
        } else {
          return [];
        }

        visualTypes.sort(function (type1, type2) {
          // color should be front of colorSaturation, colorAlpha, ...
          // symbol and symbolSize do not matter.
          return type2 === 'color' && type1 !== 'color' && type1.indexOf('color') === 0 ? 1 : -1;
        });
        return visualTypes;
      };
      /**
       * 'color', 'colorSaturation', 'colorAlpha', ... are depends on 'color'.
       * Other visuals are only depends on themself.
       */


      VisualMapping.dependsOn = function (visualType1, visualType2) {
        return visualType2 === 'color' ? !!(visualType1 && visualType1.indexOf(visualType2) === 0) : visualType1 === visualType2;
      };
      /**
       * @param value
       * @param pieceList [{value: ..., interval: [min, max]}, ...]
       *                         Always from small to big.
       * @param findClosestWhenOutside Default to be false
       * @return index
       */


      VisualMapping.findPieceIndex = function (value, pieceList, findClosestWhenOutside) {
        var possibleI;
        var abs = Infinity; // value has the higher priority.

        for (var i = 0, len = pieceList.length; i < len; i++) {
          var pieceValue = pieceList[i].value;

          if (pieceValue != null) {
            if (pieceValue === value // FIXME
            // It is supposed to compare value according to value type of dimension,
            // but currently value type can exactly be string or number.
            // Compromise for numeric-like string (like '12'), especially
            // in the case that visualMap.categories is ['22', '33'].
            || isString(pieceValue) && pieceValue === value + '') {
              return i;
            }

            findClosestWhenOutside && updatePossible(pieceValue, i);
          }
        }

        for (var i = 0, len = pieceList.length; i < len; i++) {
          var piece = pieceList[i];
          var interval = piece.interval;
          var close_1 = piece.close;

          if (interval) {
            if (interval[0] === -Infinity) {
              if (littleThan(close_1[1], value, interval[1])) {
                return i;
              }
            } else if (interval[1] === Infinity) {
              if (littleThan(close_1[0], interval[0], value)) {
                return i;
              }
            } else if (littleThan(close_1[0], interval[0], value) && littleThan(close_1[1], value, interval[1])) {
              return i;
            }

            findClosestWhenOutside && updatePossible(interval[0], i);
            findClosestWhenOutside && updatePossible(interval[1], i);
          }
        }

        if (findClosestWhenOutside) {
          return value === Infinity ? pieceList.length - 1 : value === -Infinity ? 0 : possibleI;
        }

        function updatePossible(val, index) {
          var newAbs = Math.abs(val - value);

          if (newAbs < abs) {
            abs = newAbs;
            possibleI = index;
          }
        }
      };

      VisualMapping.visualHandlers = {
        color: {
          applyVisual: makeApplyVisual('color'),
          getColorMapper: function () {
            var thisOption = this.option;
            return bind(thisOption.mappingMethod === 'category' ? function (value, isNormalized) {
              !isNormalized && (value = this._normalizeData(value));
              return doMapCategory.call(this, value);
            } : function (value, isNormalized, out) {
              // If output rgb array
              // which will be much faster and useful in pixel manipulation
              var returnRGBArray = !!out;
              !isNormalized && (value = this._normalizeData(value));
              out = fastLerp(value, thisOption.parsedVisual, out);
              return returnRGBArray ? out : stringify(out, 'rgba');
            }, this);
          },
          _normalizedToVisual: {
            linear: function (normalized) {
              return stringify(fastLerp(normalized, this.option.parsedVisual), 'rgba');
            },
            category: doMapCategory,
            piecewise: function (normalized, value) {
              var result = getSpecifiedVisual.call(this, value);

              if (result == null) {
                result = stringify(fastLerp(normalized, this.option.parsedVisual), 'rgba');
              }

              return result;
            },
            fixed: doMapFixed
          }
        },
        colorHue: makePartialColorVisualHandler(function (color$1, value) {
          return modifyHSL(color$1, value);
        }),
        colorSaturation: makePartialColorVisualHandler(function (color$1, value) {
          return modifyHSL(color$1, null, value);
        }),
        colorLightness: makePartialColorVisualHandler(function (color$1, value) {
          return modifyHSL(color$1, null, null, value);
        }),
        colorAlpha: makePartialColorVisualHandler(function (color$1, value) {
          return modifyAlpha(color$1, value);
        }),
        decal: {
          applyVisual: makeApplyVisual('decal'),
          _normalizedToVisual: {
            linear: null,
            category: doMapCategory,
            piecewise: null,
            fixed: null
          }
        },
        opacity: {
          applyVisual: makeApplyVisual('opacity'),
          _normalizedToVisual: createNormalizedToNumericVisual([0, 1])
        },
        liftZ: {
          applyVisual: makeApplyVisual('liftZ'),
          _normalizedToVisual: {
            linear: doMapFixed,
            category: doMapFixed,
            piecewise: doMapFixed,
            fixed: doMapFixed
          }
        },
        symbol: {
          applyVisual: function (value, getter, setter) {
            var symbolCfg = this.mapValueToVisual(value);
            setter('symbol', symbolCfg);
          },
          _normalizedToVisual: {
            linear: doMapToArray,
            category: doMapCategory,
            piecewise: function (normalized, value) {
              var result = getSpecifiedVisual.call(this, value);

              if (result == null) {
                result = doMapToArray.call(this, normalized);
              }

              return result;
            },
            fixed: doMapFixed
          }
        },
        symbolSize: {
          applyVisual: makeApplyVisual('symbolSize'),
          _normalizedToVisual: createNormalizedToNumericVisual([0, 1])
        }
      };
      return VisualMapping;
    }();

    function preprocessForPiecewise(thisOption) {
      var pieceList = thisOption.pieceList;
      thisOption.hasSpecialVisual = false;
      each(pieceList, function (piece, index) {
        piece.originIndex = index; // piece.visual is "result visual value" but not
        // a visual range, so it does not need to be normalized.

        if (piece.visual != null) {
          thisOption.hasSpecialVisual = true;
        }
      });
    }

    function preprocessForSpecifiedCategory(thisOption) {
      // Hash categories.
      var categories = thisOption.categories;
      var categoryMap = thisOption.categoryMap = {};
      var visual = thisOption.visual;
      each$3(categories, function (cate, index) {
        categoryMap[cate] = index;
      }); // Process visual map input.

      if (!isArray(visual)) {
        var visualArr_1 = [];

        if (isObject(visual)) {
          each$3(visual, function (v, cate) {
            var index = categoryMap[cate];
            visualArr_1[index != null ? index : CATEGORY_DEFAULT_VISUAL_INDEX] = v;
          });
        } else {
          // Is primary type, represents default visual.
          visualArr_1[CATEGORY_DEFAULT_VISUAL_INDEX] = visual;
        }

        visual = setVisualToOption(thisOption, visualArr_1);
      } // Remove categories that has no visual,
      // then we can mapping them to CATEGORY_DEFAULT_VISUAL_INDEX.


      for (var i = categories.length - 1; i >= 0; i--) {
        if (visual[i] == null) {
          delete categoryMap[categories[i]];
          categories.pop();
        }
      }
    }

    function normalizeVisualRange(thisOption, isCategory) {
      var visual = thisOption.visual;
      var visualArr = [];

      if (isObject(visual)) {
        each$3(visual, function (v) {
          visualArr.push(v);
        });
      } else if (visual != null) {
        visualArr.push(visual);
      }

      var doNotNeedPair = {
        color: 1,
        symbol: 1
      };

      if (!isCategory && visualArr.length === 1 && !doNotNeedPair.hasOwnProperty(thisOption.type)) {
        // Do not care visualArr.length === 0, which is illegal.
        visualArr[1] = visualArr[0];
      }

      setVisualToOption(thisOption, visualArr);
    }

    function makePartialColorVisualHandler(applyValue) {
      return {
        applyVisual: function (value, getter, setter) {
          // Only used in HSL
          var colorChannel = this.mapValueToVisual(value); // Must not be array value

          setter('color', applyValue(getter('color'), colorChannel));
        },
        _normalizedToVisual: createNormalizedToNumericVisual([0, 1])
      };
    }

    function doMapToArray(normalized) {
      var visual = this.option.visual;
      return visual[Math.round(linearMap(normalized, [0, 1], [0, visual.length - 1], true))] || {}; // TODO {}?
    }

    function makeApplyVisual(visualType) {
      return function (value, getter, setter) {
        setter(visualType, this.mapValueToVisual(value));
      };
    }

    function doMapCategory(normalized) {
      var visual = this.option.visual;
      return visual[this.option.loop && normalized !== CATEGORY_DEFAULT_VISUAL_INDEX ? normalized % visual.length : normalized];
    }

    function doMapFixed() {
      // visual will be convert to array.
      return this.option.visual[0];
    }
    /**
     * Create mapped to numeric visual
     */


    function createNormalizedToNumericVisual(sourceExtent) {
      return {
        linear: function (normalized) {
          return linearMap(normalized, sourceExtent, this.option.visual, true);
        },
        category: doMapCategory,
        piecewise: function (normalized, value) {
          var result = getSpecifiedVisual.call(this, value);

          if (result == null) {
            result = linearMap(normalized, sourceExtent, this.option.visual, true);
          }

          return result;
        },
        fixed: doMapFixed
      };
    }

    function getSpecifiedVisual(value) {
      var thisOption = this.option;
      var pieceList = thisOption.pieceList;

      if (thisOption.hasSpecialVisual) {
        var pieceIndex = VisualMapping.findPieceIndex(value, pieceList);
        var piece = pieceList[pieceIndex];

        if (piece && piece.visual) {
          return piece.visual[this.type];
        }
      }
    }

    function setVisualToOption(thisOption, visualArr) {
      thisOption.visual = visualArr;

      if (thisOption.type === 'color') {
        thisOption.parsedVisual = map(visualArr, function (item) {
          var color$1 = parse(item);

          if (!color$1 && "development" !== 'production') {
            warn("'" + item + "' is an illegal color, fallback to '#000000'", true);
          }

          return color$1 || [0, 0, 0, 1];
        });
      }

      return visualArr;
    }
    /**
     * Normalizers by mapping methods.
     */


    var normalizers = {
      linear: function (value) {
        return linearMap(value, this.option.dataExtent, [0, 1], true);
      },
      piecewise: function (value) {
        var pieceList = this.option.pieceList;
        var pieceIndex = VisualMapping.findPieceIndex(value, pieceList, true);

        if (pieceIndex != null) {
          return linearMap(pieceIndex, [0, pieceList.length - 1], [0, 1], true);
        }
      },
      category: function (value) {
        var index = this.option.categories ? this.option.categoryMap[value] : value; // ordinal value

        return index == null ? CATEGORY_DEFAULT_VISUAL_INDEX : index;
      },
      fixed: noop
    };

    function littleThan(close, a, b) {
      return close ? a <= b : a < b;
    }

    var ITEM_STYLE_NORMAL = 'itemStyle';
    var inner$9 = makeInner();
    var treemapVisual = {
      seriesType: 'treemap',
      reset: function (seriesModel) {
        var tree = seriesModel.getData().tree;
        var root = tree.root;

        if (root.isRemoved()) {
          return;
        }

        travelTree(root, // Visual should calculate from tree root but not view root.
        {}, seriesModel.getViewRoot().getAncestors(), seriesModel);
      }
    };

    function travelTree(node, designatedVisual, viewRootAncestors, seriesModel) {
      var nodeModel = node.getModel();
      var nodeLayout = node.getLayout();
      var data = node.hostTree.data; // Optimize

      if (!nodeLayout || nodeLayout.invisible || !nodeLayout.isInView) {
        return;
      }

      var nodeItemStyleModel = nodeModel.getModel(ITEM_STYLE_NORMAL);
      var visuals = buildVisuals(nodeItemStyleModel, designatedVisual, seriesModel);
      var existsStyle = data.ensureUniqueItemVisual(node.dataIndex, 'style'); // calculate border color

      var borderColor = nodeItemStyleModel.get('borderColor');
      var borderColorSaturation = nodeItemStyleModel.get('borderColorSaturation');
      var thisNodeColor;

      if (borderColorSaturation != null) {
        // For performance, do not always execute 'calculateColor'.
        thisNodeColor = calculateColor(visuals);
        borderColor = calculateBorderColor(borderColorSaturation, thisNodeColor);
      }

      existsStyle.stroke = borderColor;
      var viewChildren = node.viewChildren;

      if (!viewChildren || !viewChildren.length) {
        thisNodeColor = calculateColor(visuals); // Apply visual to this node.

        existsStyle.fill = thisNodeColor;
      } else {
        var mapping_1 = buildVisualMapping(node, nodeModel, nodeLayout, nodeItemStyleModel, visuals, viewChildren); // Designate visual to children.

        each(viewChildren, function (child, index) {
          // If higher than viewRoot, only ancestors of viewRoot is needed to visit.
          if (child.depth >= viewRootAncestors.length || child === viewRootAncestors[child.depth]) {
            var childVisual = mapVisual(nodeModel, visuals, child, index, mapping_1, seriesModel);
            travelTree(child, childVisual, viewRootAncestors, seriesModel);
          }
        });
      }
    }

    function buildVisuals(nodeItemStyleModel, designatedVisual, seriesModel) {
      var visuals = extend({}, designatedVisual);
      var designatedVisualItemStyle = seriesModel.designatedVisualItemStyle;
      each(['color', 'colorAlpha', 'colorSaturation'], function (visualName) {
        // Priority: thisNode > thisLevel > parentNodeDesignated > seriesModel
        designatedVisualItemStyle[visualName] = designatedVisual[visualName];
        var val = nodeItemStyleModel.get(visualName);
        designatedVisualItemStyle[visualName] = null;
        val != null && (visuals[visualName] = val);
      });
      return visuals;
    }

    function calculateColor(visuals) {
      var color = getValueVisualDefine(visuals, 'color');

      if (color) {
        var colorAlpha = getValueVisualDefine(visuals, 'colorAlpha');
        var colorSaturation = getValueVisualDefine(visuals, 'colorSaturation');

        if (colorSaturation) {
          color = modifyHSL(color, null, null, colorSaturation);
        }

        if (colorAlpha) {
          color = modifyAlpha(color, colorAlpha);
        }

        return color;
      }
    }

    function calculateBorderColor(borderColorSaturation, thisNodeColor) {
      return thisNodeColor != null // Can only be string
      ? modifyHSL(thisNodeColor, null, null, borderColorSaturation) : null;
    }

    function getValueVisualDefine(visuals, name) {
      var value = visuals[name];

      if (value != null && value !== 'none') {
        return value;
      }
    }

    function buildVisualMapping(node, nodeModel, nodeLayout, nodeItemStyleModel, visuals, viewChildren) {
      if (!viewChildren || !viewChildren.length) {
        return;
      }

      var rangeVisual = getRangeVisual(nodeModel, 'color') || visuals.color != null && visuals.color !== 'none' && (getRangeVisual(nodeModel, 'colorAlpha') || getRangeVisual(nodeModel, 'colorSaturation'));

      if (!rangeVisual) {
        return;
      }

      var visualMin = nodeModel.get('visualMin');
      var visualMax = nodeModel.get('visualMax');
      var dataExtent = nodeLayout.dataExtent.slice();
      visualMin != null && visualMin < dataExtent[0] && (dataExtent[0] = visualMin);
      visualMax != null && visualMax > dataExtent[1] && (dataExtent[1] = visualMax);
      var colorMappingBy = nodeModel.get('colorMappingBy');
      var opt = {
        type: rangeVisual.name,
        dataExtent: dataExtent,
        visual: rangeVisual.range
      };

      if (opt.type === 'color' && (colorMappingBy === 'index' || colorMappingBy === 'id')) {
        opt.mappingMethod = 'category';
        opt.loop = true; // categories is ordinal, so do not set opt.categories.
      } else {
        opt.mappingMethod = 'linear';
      }

      var mapping = new VisualMapping(opt);
      inner$9(mapping).drColorMappingBy = colorMappingBy;
      return mapping;
    } // Notice: If we don't have the attribute 'colorRange', but only use
    // attribute 'color' to represent both concepts of 'colorRange' and 'color',
    // (It means 'colorRange' when 'color' is Array, means 'color' when not array),
    // this problem will be encountered:
    // If a level-1 node doesn't have children, and its siblings have children,
    // and colorRange is set on level-1, then the node cannot be colored.
    // So we separate 'colorRange' and 'color' to different attributes.


    function getRangeVisual(nodeModel, name) {
      // 'colorRange', 'colorARange', 'colorSRange'.
      // If not exists on this node, fetch from levels and series.
      var range = nodeModel.get(name);
      return isArray(range) && range.length ? {
        name: name,
        range: range
      } : null;
    }

    function mapVisual(nodeModel, visuals, child, index, mapping, seriesModel) {
      var childVisuals = extend({}, visuals);

      if (mapping) {
        // Only support color, colorAlpha, colorSaturation.
        var mappingType = mapping.type;
        var colorMappingBy = mappingType === 'color' && inner$9(mapping).drColorMappingBy;
        var value = colorMappingBy === 'index' ? index : colorMappingBy === 'id' ? seriesModel.mapIdToIndex(child.getId()) : child.getValue(nodeModel.get('visualDimension'));
        childVisuals[mappingType] = mapping.mapValueToVisual(value);
      }

      return childVisuals;
    }

    var mathMax$7 = Math.max;
    var mathMin$7 = Math.min;
    var retrieveValue = retrieve;
    var each$4 = each;
    var PATH_BORDER_WIDTH = ['itemStyle', 'borderWidth'];
    var PATH_GAP_WIDTH = ['itemStyle', 'gapWidth'];
    var PATH_UPPER_LABEL_SHOW = ['upperLabel', 'show'];
    var PATH_UPPER_LABEL_HEIGHT = ['upperLabel', 'height'];
    /**
     * @public
     */

    var treemapLayout = {
      seriesType: 'treemap',
      reset: function (seriesModel, ecModel, api, payload) {
        // Layout result in each node:
        // {x, y, width, height, area, borderWidth}
        var ecWidth = api.getWidth();
        var ecHeight = api.getHeight();
        var seriesOption = seriesModel.option;
        var layoutInfo = getLayoutRect(seriesModel.getBoxLayoutParams(), {
          width: api.getWidth(),
          height: api.getHeight()
        });
        var size = seriesOption.size || []; // Compatible with ec2.

        var containerWidth = parsePercent$1(retrieveValue(layoutInfo.width, size[0]), ecWidth);
        var containerHeight = parsePercent$1(retrieveValue(layoutInfo.height, size[1]), ecHeight); // Fetch payload info.

        var payloadType = payload && payload.type;
        var types = ['treemapZoomToNode', 'treemapRootToNode'];
        var targetInfo = retrieveTargetInfo(payload, types, seriesModel);
        var rootRect = payloadType === 'treemapRender' || payloadType === 'treemapMove' ? payload.rootRect : null;
        var viewRoot = seriesModel.getViewRoot();
        var viewAbovePath = getPathToRoot(viewRoot);

        if (payloadType !== 'treemapMove') {
          var rootSize = payloadType === 'treemapZoomToNode' ? estimateRootSize(seriesModel, targetInfo, viewRoot, containerWidth, containerHeight) : rootRect ? [rootRect.width, rootRect.height] : [containerWidth, containerHeight];
          var sort_1 = seriesOption.sort;

          if (sort_1 && sort_1 !== 'asc' && sort_1 !== 'desc') {
            // Default to be desc order.
            sort_1 = 'desc';
          }

          var options = {
            squareRatio: seriesOption.squareRatio,
            sort: sort_1,
            leafDepth: seriesOption.leafDepth
          }; // layout should be cleared because using updateView but not update.

          viewRoot.hostTree.clearLayouts(); // TODO
          // optimize: if out of view clip, do not layout.
          // But take care that if do not render node out of view clip,
          // how to calculate start po

          var viewRootLayout_1 = {
            x: 0,
            y: 0,
            width: rootSize[0],
            height: rootSize[1],
            area: rootSize[0] * rootSize[1]
          };
          viewRoot.setLayout(viewRootLayout_1);
          squarify(viewRoot, options, false, 0); // Supplement layout.

          viewRootLayout_1 = viewRoot.getLayout();
          each$4(viewAbovePath, function (node, index) {
            var childValue = (viewAbovePath[index + 1] || viewRoot).getValue();
            node.setLayout(extend({
              dataExtent: [childValue, childValue],
              borderWidth: 0,
              upperHeight: 0
            }, viewRootLayout_1));
          });
        }

        var treeRoot = seriesModel.getData().tree.root;
        treeRoot.setLayout(calculateRootPosition(layoutInfo, rootRect, targetInfo), true);
        seriesModel.setLayoutInfo(layoutInfo); // FIXME
        // 现在没有clip功能，暂时取ec高宽。

        prunning(treeRoot, // Transform to base element coordinate system.
        new BoundingRect(-layoutInfo.x, -layoutInfo.y, ecWidth, ecHeight), viewAbovePath, viewRoot, 0);
      }
    };
    /**
     * Layout treemap with squarify algorithm.
     * The original presentation of this algorithm
     * was made by Mark Bruls, Kees Huizing, and Jarke J. van Wijk
     * <https://graphics.ethz.ch/teaching/scivis_common/Literature/squarifiedTreeMaps.pdf>.
     * The implementation of this algorithm was originally copied from "d3.js"
     * <https://github.com/d3/d3/blob/9cc9a875e636a1dcf36cc1e07bdf77e1ad6e2c74/src/layout/treemap.js>
     * with some modifications made for this program.
     * See the license statement at the head of this file.
     *
     * @protected
     * @param {module:echarts/data/Tree~TreeNode} node
     * @param {Object} options
     * @param {string} options.sort 'asc' or 'desc'
     * @param {number} options.squareRatio
     * @param {boolean} hideChildren
     * @param {number} depth
     */

    function squarify(node, options, hideChildren, depth) {
      var width;
      var height;

      if (node.isRemoved()) {
        return;
      }

      var thisLayout = node.getLayout();
      width = thisLayout.width;
      height = thisLayout.height; // Considering border and gap

      var nodeModel = node.getModel();
      var borderWidth = nodeModel.get(PATH_BORDER_WIDTH);
      var halfGapWidth = nodeModel.get(PATH_GAP_WIDTH) / 2;
      var upperLabelHeight = getUpperLabelHeight(nodeModel);
      var upperHeight = Math.max(borderWidth, upperLabelHeight);
      var layoutOffset = borderWidth - halfGapWidth;
      var layoutOffsetUpper = upperHeight - halfGapWidth;
      node.setLayout({
        borderWidth: borderWidth,
        upperHeight: upperHeight,
        upperLabelHeight: upperLabelHeight
      }, true);
      width = mathMax$7(width - 2 * layoutOffset, 0);
      height = mathMax$7(height - layoutOffset - layoutOffsetUpper, 0);
      var totalArea = width * height;
      var viewChildren = initChildren(node, nodeModel, totalArea, options, hideChildren, depth);

      if (!viewChildren.length) {
        return;
      }

      var rect = {
        x: layoutOffset,
        y: layoutOffsetUpper,
        width: width,
        height: height
      };
      var rowFixedLength = mathMin$7(width, height);
      var best = Infinity; // the best row score so far

      var row = [];
      row.area = 0;

      for (var i = 0, len = viewChildren.length; i < len;) {
        var child = viewChildren[i];
        row.push(child);
        row.area += child.getLayout().area;
        var score = worst(row, rowFixedLength, options.squareRatio); // continue with this orientation

        if (score <= best) {
          i++;
          best = score;
        } // abort, and try a different orientation
        else {
            row.area -= row.pop().getLayout().area;
            position(row, rowFixedLength, rect, halfGapWidth, false);
            rowFixedLength = mathMin$7(rect.width, rect.height);
            row.length = row.area = 0;
            best = Infinity;
          }
      }

      if (row.length) {
        position(row, rowFixedLength, rect, halfGapWidth, true);
      }

      if (!hideChildren) {
        var childrenVisibleMin = nodeModel.get('childrenVisibleMin');

        if (childrenVisibleMin != null && totalArea < childrenVisibleMin) {
          hideChildren = true;
        }
      }

      for (var i = 0, len = viewChildren.length; i < len; i++) {
        squarify(viewChildren[i], options, hideChildren, depth + 1);
      }
    }
    /**
     * Set area to each child, and calculate data extent for visual coding.
     */


    function initChildren(node, nodeModel, totalArea, options, hideChildren, depth) {
      var viewChildren = node.children || [];
      var orderBy = options.sort;
      orderBy !== 'asc' && orderBy !== 'desc' && (orderBy = null);
      var overLeafDepth = options.leafDepth != null && options.leafDepth <= depth; // leafDepth has higher priority.

      if (hideChildren && !overLeafDepth) {
        return node.viewChildren = [];
      } // Sort children, order by desc.


      viewChildren = filter(viewChildren, function (child) {
        return !child.isRemoved();
      });
      sort$1(viewChildren, orderBy);
      var info = statistic(nodeModel, viewChildren, orderBy);

      if (info.sum === 0) {
        return node.viewChildren = [];
      }

      info.sum = filterByThreshold(nodeModel, totalArea, info.sum, orderBy, viewChildren);

      if (info.sum === 0) {
        return node.viewChildren = [];
      } // Set area to each child.


      for (var i = 0, len = viewChildren.length; i < len; i++) {
        var area = viewChildren[i].getValue() / info.sum * totalArea; // Do not use setLayout({...}, true), because it is needed to clear last layout.

        viewChildren[i].setLayout({
          area: area
        });
      }

      if (overLeafDepth) {
        viewChildren.length && node.setLayout({
          isLeafRoot: true
        }, true);
        viewChildren.length = 0;
      }

      node.viewChildren = viewChildren;
      node.setLayout({
        dataExtent: info.dataExtent
      }, true);
      return viewChildren;
    }
    /**
     * Consider 'visibleMin'. Modify viewChildren and get new sum.
     */


    function filterByThreshold(nodeModel, totalArea, sum, orderBy, orderedChildren) {
      // visibleMin is not supported yet when no option.sort.
      if (!orderBy) {
        return sum;
      }

      var visibleMin = nodeModel.get('visibleMin');
      var len = orderedChildren.length;
      var deletePoint = len; // Always travel from little value to big value.

      for (var i = len - 1; i >= 0; i--) {
        var value = orderedChildren[orderBy === 'asc' ? len - i - 1 : i].getValue();

        if (value / sum * totalArea < visibleMin) {
          deletePoint = i;
          sum -= value;
        }
      }

      orderBy === 'asc' ? orderedChildren.splice(0, len - deletePoint) : orderedChildren.splice(deletePoint, len - deletePoint);
      return sum;
    }
    /**
     * Sort
     */


    function sort$1(viewChildren, orderBy) {
      if (orderBy) {
        viewChildren.sort(function (a, b) {
          var diff = orderBy === 'asc' ? a.getValue() - b.getValue() : b.getValue() - a.getValue();
          return diff === 0 ? orderBy === 'asc' ? a.dataIndex - b.dataIndex : b.dataIndex - a.dataIndex : diff;
        });
      }

      return viewChildren;
    }
    /**
     * Statistic
     */


    function statistic(nodeModel, children, orderBy) {
      // Calculate sum.
      var sum = 0;

      for (var i = 0, len = children.length; i < len; i++) {
        sum += children[i].getValue();
      } // Statistic data extent for latter visual coding.
      // Notice: data extent should be calculate based on raw children
      // but not filtered view children, otherwise visual mapping will not
      // be stable when zoom (where children is filtered by visibleMin).


      var dimension = nodeModel.get('visualDimension');
      var dataExtent; // The same as area dimension.

      if (!children || !children.length) {
        dataExtent = [NaN, NaN];
      } else if (dimension === 'value' && orderBy) {
        dataExtent = [children[children.length - 1].getValue(), children[0].getValue()];
        orderBy === 'asc' && dataExtent.reverse();
      } // Other dimension.
      else {
          dataExtent = [Infinity, -Infinity];
          each$4(children, function (child) {
            var value = child.getValue(dimension);
            value < dataExtent[0] && (dataExtent[0] = value);
            value > dataExtent[1] && (dataExtent[1] = value);
          });
        }

      return {
        sum: sum,
        dataExtent: dataExtent
      };
    }
    /**
     * Computes the score for the specified row,
     * as the worst aspect ratio.
     */


    function worst(row, rowFixedLength, ratio) {
      var areaMax = 0;
      var areaMin = Infinity;

      for (var i = 0, area = void 0, len = row.length; i < len; i++) {
        area = row[i].getLayout().area;

        if (area) {
          area < areaMin && (areaMin = area);
          area > areaMax && (areaMax = area);
        }
      }

      var squareArea = row.area * row.area;
      var f = rowFixedLength * rowFixedLength * ratio;
      return squareArea ? mathMax$7(f * areaMax / squareArea, squareArea / (f * areaMin)) : Infinity;
    }
    /**
     * Positions the specified row of nodes. Modifies `rect`.
     */


    function position(row, rowFixedLength, rect, halfGapWidth, flush) {
      // When rowFixedLength === rect.width,
      // it is horizontal subdivision,
      // rowFixedLength is the width of the subdivision,
      // rowOtherLength is the height of the subdivision,
      // and nodes will be positioned from left to right.
      // wh[idx0WhenH] means: when horizontal,
      //      wh[idx0WhenH] => wh[0] => 'width'.
      //      xy[idx1WhenH] => xy[1] => 'y'.
      var idx0WhenH = rowFixedLength === rect.width ? 0 : 1;
      var idx1WhenH = 1 - idx0WhenH;
      var xy = ['x', 'y'];
      var wh = ['width', 'height'];
      var last = rect[xy[idx0WhenH]];
      var rowOtherLength = rowFixedLength ? row.area / rowFixedLength : 0;

      if (flush || rowOtherLength > rect[wh[idx1WhenH]]) {
        rowOtherLength = rect[wh[idx1WhenH]]; // over+underflow
      }

      for (var i = 0, rowLen = row.length; i < rowLen; i++) {
        var node = row[i];
        var nodeLayout = {};
        var step = rowOtherLength ? node.getLayout().area / rowOtherLength : 0;
        var wh1 = nodeLayout[wh[idx1WhenH]] = mathMax$7(rowOtherLength - 2 * halfGapWidth, 0); // We use Math.max/min to avoid negative width/height when considering gap width.

        var remain = rect[xy[idx0WhenH]] + rect[wh[idx0WhenH]] - last;
        var modWH = i === rowLen - 1 || remain < step ? remain : step;
        var wh0 = nodeLayout[wh[idx0WhenH]] = mathMax$7(modWH - 2 * halfGapWidth, 0);
        nodeLayout[xy[idx1WhenH]] = rect[xy[idx1WhenH]] + mathMin$7(halfGapWidth, wh1 / 2);
        nodeLayout[xy[idx0WhenH]] = last + mathMin$7(halfGapWidth, wh0 / 2);
        last += modWH;
        node.setLayout(nodeLayout, true);
      }

      rect[xy[idx1WhenH]] += rowOtherLength;
      rect[wh[idx1WhenH]] -= rowOtherLength;
    } // Return [containerWidth, containerHeight] as default.


    function estimateRootSize(seriesModel, targetInfo, viewRoot, containerWidth, containerHeight) {
      // If targetInfo.node exists, we zoom to the node,
      // so estimate whole width and height by target node.
      var currNode = (targetInfo || {}).node;
      var defaultSize = [containerWidth, containerHeight];

      if (!currNode || currNode === viewRoot) {
        return defaultSize;
      }

      var parent;
      var viewArea = containerWidth * containerHeight;
      var area = viewArea * seriesModel.option.zoomToNodeRatio;

      while (parent = currNode.parentNode) {
        // jshint ignore:line
        var sum = 0;
        var siblings = parent.children;

        for (var i = 0, len = siblings.length; i < len; i++) {
          sum += siblings[i].getValue();
        }

        var currNodeValue = currNode.getValue();

        if (currNodeValue === 0) {
          return defaultSize;
        }

        area *= sum / currNodeValue; // Considering border, suppose aspect ratio is 1.

        var parentModel = parent.getModel();
        var borderWidth = parentModel.get(PATH_BORDER_WIDTH);
        var upperHeight = Math.max(borderWidth, getUpperLabelHeight(parentModel));
        area += 4 * borderWidth * borderWidth + (3 * borderWidth + upperHeight) * Math.pow(area, 0.5);
        area > MAX_SAFE_INTEGER && (area = MAX_SAFE_INTEGER);
        currNode = parent;
      }

      area < viewArea && (area = viewArea);
      var scale = Math.pow(area / viewArea, 0.5);
      return [containerWidth * scale, containerHeight * scale];
    } // Root position based on coord of containerGroup


    function calculateRootPosition(layoutInfo, rootRect, targetInfo) {
      if (rootRect) {
        return {
          x: rootRect.x,
          y: rootRect.y
        };
      }

      var defaultPosition = {
        x: 0,
        y: 0
      };

      if (!targetInfo) {
        return defaultPosition;
      } // If targetInfo is fetched by 'retrieveTargetInfo',
      // old tree and new tree are the same tree,
      // so the node still exists and we can visit it.


      var targetNode = targetInfo.node;
      var layout = targetNode.getLayout();

      if (!layout) {
        return defaultPosition;
      } // Transform coord from local to container.


      var targetCenter = [layout.width / 2, layout.height / 2];
      var node = targetNode;

      while (node) {
        var nodeLayout = node.getLayout();
        targetCenter[0] += nodeLayout.x;
        targetCenter[1] += nodeLayout.y;
        node = node.parentNode;
      }

      return {
        x: layoutInfo.width / 2 - targetCenter[0],
        y: layoutInfo.height / 2 - targetCenter[1]
      };
    } // Mark nodes visible for prunning when visual coding and rendering.
    // Prunning depends on layout and root position, so we have to do it after layout.


    function prunning(node, clipRect, viewAbovePath, viewRoot, depth) {
      var nodeLayout = node.getLayout();
      var nodeInViewAbovePath = viewAbovePath[depth];
      var isAboveViewRoot = nodeInViewAbovePath && nodeInViewAbovePath === node;

      if (nodeInViewAbovePath && !isAboveViewRoot || depth === viewAbovePath.length && node !== viewRoot) {
        return;
      }

      node.setLayout({
        // isInView means: viewRoot sub tree + viewAbovePath
        isInView: true,
        // invisible only means: outside view clip so that the node can not
        // see but still layout for animation preparation but not render.
        invisible: !isAboveViewRoot && !clipRect.intersect(nodeLayout),
        isAboveViewRoot: isAboveViewRoot
      }, true); // Transform to child coordinate.

      var childClipRect = new BoundingRect(clipRect.x - nodeLayout.x, clipRect.y - nodeLayout.y, clipRect.width, clipRect.height);
      each$4(node.viewChildren || [], function (child) {
        prunning(child, childClipRect, viewAbovePath, viewRoot, depth + 1);
      });
    }

    function getUpperLabelHeight(model) {
      return model.get(PATH_UPPER_LABEL_SHOW) ? model.get(PATH_UPPER_LABEL_HEIGHT) : 0;
    }

    function install$c(registers) {
      registers.registerSeriesModel(TreemapSeriesModel);
      registers.registerChartView(TreemapView);
      registers.registerVisual(treemapVisual);
      registers.registerLayout(treemapLayout);
      installTreemapAction(registers);
    }

    function categoryFilter(ecModel) {
      var legendModels = ecModel.findComponents({
        mainType: 'legend'
      });

      if (!legendModels || !legendModels.length) {
        return;
      }

      ecModel.eachSeriesByType('graph', function (graphSeries) {
        var categoriesData = graphSeries.getCategoriesData();
        var graph = graphSeries.getGraph();
        var data = graph.data;
        var categoryNames = categoriesData.mapArray(categoriesData.getName);
        data.filterSelf(function (idx) {
          var model = data.getItemModel(idx);
          var category = model.getShallow('category');

          if (category != null) {
            if (isNumber(category)) {
              category = categoryNames[category];
            } // If in any legend component the status is not selected.


            for (var i = 0; i < legendModels.length; i++) {
              if (!legendModels[i].isSelected(category)) {
                return false;
              }
            }
          }

          return true;
        });
      });
    }

    function categoryVisual(ecModel) {
      var paletteScope = {};
      ecModel.eachSeriesByType('graph', function (seriesModel) {
        var categoriesData = seriesModel.getCategoriesData();
        var data = seriesModel.getData();
        var categoryNameIdxMap = {};
        categoriesData.each(function (idx) {
          var name = categoriesData.getName(idx); // Add prefix to avoid conflict with Object.prototype.

          categoryNameIdxMap['ec-' + name] = idx;
          var itemModel = categoriesData.getItemModel(idx);
          var style = itemModel.getModel('itemStyle').getItemStyle();

          if (!style.fill) {
            // Get color from palette.
            style.fill = seriesModel.getColorFromPalette(name, paletteScope);
          }

          categoriesData.setItemVisual(idx, 'style', style);
          var symbolVisualList = ['symbol', 'symbolSize', 'symbolKeepAspect'];

          for (var i = 0; i < symbolVisualList.length; i++) {
            var symbolVisual = itemModel.getShallow(symbolVisualList[i], true);

            if (symbolVisual != null) {
              categoriesData.setItemVisual(idx, symbolVisualList[i], symbolVisual);
            }
          }
        }); // Assign category color to visual

        if (categoriesData.count()) {
          data.each(function (idx) {
            var model = data.getItemModel(idx);
            var categoryIdx = model.getShallow('category');

            if (categoryIdx != null) {
              if (isString(categoryIdx)) {
                categoryIdx = categoryNameIdxMap['ec-' + categoryIdx];
              }

              var categoryStyle = categoriesData.getItemVisual(categoryIdx, 'style');
              var style = data.ensureUniqueItemVisual(idx, 'style');
              extend(style, categoryStyle);
              var visualList = ['symbol', 'symbolSize', 'symbolKeepAspect'];

              for (var i = 0; i < visualList.length; i++) {
                data.setItemVisual(idx, visualList[i], categoriesData.getItemVisual(categoryIdx, visualList[i]));
              }
            }
          });
        }
      });
    }

    function normalize$2(a) {
      if (!(a instanceof Array)) {
        a = [a, a];
      }

      return a;
    }

    function graphEdgeVisual(ecModel) {
      ecModel.eachSeriesByType('graph', function (seriesModel) {
        var graph = seriesModel.getGraph();
        var edgeData = seriesModel.getEdgeData();
        var symbolType = normalize$2(seriesModel.get('edgeSymbol'));
        var symbolSize = normalize$2(seriesModel.get('edgeSymbolSize')); // const colorQuery = ['lineStyle', 'color'] as const;
        // const opacityQuery = ['lineStyle', 'opacity'] as const;

        edgeData.setVisual('fromSymbol', symbolType && symbolType[0]);
        edgeData.setVisual('toSymbol', symbolType && symbolType[1]);
        edgeData.setVisual('fromSymbolSize', symbolSize && symbolSize[0]);
        edgeData.setVisual('toSymbolSize', symbolSize && symbolSize[1]);
        edgeData.setVisual('style', seriesModel.getModel('lineStyle').getLineStyle());
        edgeData.each(function (idx) {
          var itemModel = edgeData.getItemModel(idx);
          var edge = graph.getEdgeByIndex(idx);
          var symbolType = normalize$2(itemModel.getShallow('symbol', true));
          var symbolSize = normalize$2(itemModel.getShallow('symbolSize', true)); // Edge visual must after node visual

          var style = itemModel.getModel('lineStyle').getLineStyle();
          var existsStyle = edgeData.ensureUniqueItemVisual(idx, 'style');
          extend(existsStyle, style);

          switch (existsStyle.stroke) {
            case 'source':
              {
                var nodeStyle = edge.node1.getVisual('style');
                existsStyle.stroke = nodeStyle && nodeStyle.fill;
                break;
              }

            case 'target':
              {
                var nodeStyle = edge.node2.getVisual('style');
                existsStyle.stroke = nodeStyle && nodeStyle.fill;
                break;
              }
          }

          symbolType[0] && edge.setVisual('fromSymbol', symbolType[0]);
          symbolType[1] && edge.setVisual('toSymbol', symbolType[1]);
          symbolSize[0] && edge.setVisual('fromSymbolSize', symbolSize[0]);
          symbolSize[1] && edge.setVisual('toSymbolSize', symbolSize[1]);
        });
      });
    }

    var KEY_DELIMITER = '-->';
    /**
     * params handler
     * @param {module:echarts/model/SeriesModel} seriesModel
     * @returns {*}
     */

    var getAutoCurvenessParams = function (seriesModel) {
      return seriesModel.get('autoCurveness') || null;
    };
    /**
     * Generate a list of edge curvatures, 20 is the default
     * @param {module:echarts/model/SeriesModel} seriesModel
     * @param {number} appendLength
     * @return  20 => [0, -0.2, 0.2, -0.4, 0.4, -0.6, 0.6, -0.8, 0.8, -1, 1, -1.2, 1.2, -1.4, 1.4, -1.6, 1.6, -1.8, 1.8, -2]
     */


    var createCurveness = function (seriesModel, appendLength) {
      var autoCurvenessParmas = getAutoCurvenessParams(seriesModel);
      var length = 20;
      var curvenessList = []; // handler the function set

      if (isNumber(autoCurvenessParmas)) {
        length = autoCurvenessParmas;
      } else if (isArray(autoCurvenessParmas)) {
        seriesModel.__curvenessList = autoCurvenessParmas;
        return;
      } // append length


      if (appendLength > length) {
        length = appendLength;
      } // make sure the length is even


      var len = length % 2 ? length + 2 : length + 3;
      curvenessList = [];

      for (var i = 0; i < len; i++) {
        curvenessList.push((i % 2 ? i + 1 : i) / 10 * (i % 2 ? -1 : 1));
      }

      seriesModel.__curvenessList = curvenessList;
    };
    /**
     * Create different cache key data in the positive and negative directions, in order to set the curvature later
     * @param {number|string|module:echarts/data/Graph.Node} n1
     * @param {number|string|module:echarts/data/Graph.Node} n2
     * @param {module:echarts/model/SeriesModel} seriesModel
     * @returns {string} key
     */


    var getKeyOfEdges = function (n1, n2, seriesModel) {
      var source = [n1.id, n1.dataIndex].join('.');
      var target = [n2.id, n2.dataIndex].join('.');
      return [seriesModel.uid, source, target].join(KEY_DELIMITER);
    };
    /**
     * get opposite key
     * @param {string} key
     * @returns {string}
     */


    var getOppositeKey = function (key) {
      var keys = key.split(KEY_DELIMITER);
      return [keys[0], keys[2], keys[1]].join(KEY_DELIMITER);
    };
    /**
     * get edgeMap with key
     * @param edge
     * @param {module:echarts/model/SeriesModel} seriesModel
     */


    var getEdgeFromMap = function (edge, seriesModel) {
      var key = getKeyOfEdges(edge.node1, edge.node2, seriesModel);
      return seriesModel.__edgeMap[key];
    };
    /**
     * calculate all cases total length
     * @param edge
     * @param seriesModel
     * @returns {number}
     */


    var getTotalLengthBetweenNodes = function (edge, seriesModel) {
      var len = getEdgeMapLengthWithKey(getKeyOfEdges(edge.node1, edge.node2, seriesModel), seriesModel);
      var lenV = getEdgeMapLengthWithKey(getKeyOfEdges(edge.node2, edge.node1, seriesModel), seriesModel);
      return len + lenV;
    };
    /**
     *
     * @param key
     */


    var getEdgeMapLengthWithKey = function (key, seriesModel) {
      var edgeMap = seriesModel.__edgeMap;
      return edgeMap[key] ? edgeMap[key].length : 0;
    };
    /**
     * Count the number of edges between the same two points, used to obtain the curvature table and the parity of the edge
     * @see /graph/GraphSeries.js@getInitialData
     * @param {module:echarts/model/SeriesModel} seriesModel
     */


    function initCurvenessList(seriesModel) {
      if (!getAutoCurvenessParams(seriesModel)) {
        return;
      }

      seriesModel.__curvenessList = [];
      seriesModel.__edgeMap = {}; // calc the array of curveness List

      createCurveness(seriesModel);
    }
    /**
     * set edgeMap with key
     * @param {number|string|module:echarts/data/Graph.Node} n1
     * @param {number|string|module:echarts/data/Graph.Node} n2
     * @param {module:echarts/model/SeriesModel} seriesModel
     * @param {number} index
     */

    function createEdgeMapForCurveness(n1, n2, seriesModel, index) {
      if (!getAutoCurvenessParams(seriesModel)) {
        return;
      }

      var key = getKeyOfEdges(n1, n2, seriesModel);
      var edgeMap = seriesModel.__edgeMap;
      var oppositeEdges = edgeMap[getOppositeKey(key)]; // set direction

      if (edgeMap[key] && !oppositeEdges) {
        edgeMap[key].isForward = true;
      } else if (oppositeEdges && edgeMap[key]) {
        oppositeEdges.isForward = true;
        edgeMap[key].isForward = false;
      }

      edgeMap[key] = edgeMap[key] || [];
      edgeMap[key].push(index);
    }
    /**
     * get curvature for edge
     * @param edge
     * @param {module:echarts/model/SeriesModel} seriesModel
     * @param index
     */

    function getCurvenessForEdge(edge, seriesModel, index, needReverse) {
      var autoCurvenessParams = getAutoCurvenessParams(seriesModel);
      var isArrayParam = isArray(autoCurvenessParams);

      if (!autoCurvenessParams) {
        return null;
      }

      var edgeArray = getEdgeFromMap(edge, seriesModel);

      if (!edgeArray) {
        return null;
      }

      var edgeIndex = -1;

      for (var i = 0; i < edgeArray.length; i++) {
        if (edgeArray[i] === index) {
          edgeIndex = i;
          break;
        }
      } // if totalLen is Longer createCurveness


      var totalLen = getTotalLengthBetweenNodes(edge, seriesModel);
      createCurveness(seriesModel, totalLen);
      edge.lineStyle = edge.lineStyle || {}; // if is opposite edge, must set curvenss to opposite number

      var curKey = getKeyOfEdges(edge.node1, edge.node2, seriesModel);
      var curvenessList = seriesModel.__curvenessList; // if pass array no need parity

      var parityCorrection = isArrayParam ? 0 : totalLen % 2 ? 0 : 1;

      if (!edgeArray.isForward) {
        // the opposite edge show outside
        var oppositeKey = getOppositeKey(curKey);
        var len = getEdgeMapLengthWithKey(oppositeKey, seriesModel);
        var resValue = curvenessList[edgeIndex + len + parityCorrection]; // isNeedReverse, simple, force type need reverse the curveness in the junction of the forword and the opposite

        if (needReverse) {
          // set as array may make the parity handle with the len of opposite
          if (isArrayParam) {
            if (autoCurvenessParams && autoCurvenessParams[0] === 0) {
              return (len + parityCorrection) % 2 ? resValue : -resValue;
            } else {
              return ((len % 2 ? 0 : 1) + parityCorrection) % 2 ? resValue : -resValue;
            }
          } else {
            return (len + parityCorrection) % 2 ? resValue : -resValue;
          }
        } else {
          return curvenessList[edgeIndex + len + parityCorrection];
        }
      } else {
        return curvenessList[parityCorrection + edgeIndex];
      }
    }

    function simpleLayout(seriesModel) {
      var coordSys = seriesModel.coordinateSystem;

      if (coordSys && coordSys.type !== 'view') {
        return;
      }

      var graph = seriesModel.getGraph();
      graph.eachNode(function (node) {
        var model = node.getModel();
        node.setLayout([+model.get('x'), +model.get('y')]);
      });
      simpleLayoutEdge(graph, seriesModel);
    }
    function simpleLayoutEdge(graph, seriesModel) {
      graph.eachEdge(function (edge, index) {
        var curveness = retrieve3(edge.getModel().get(['lineStyle', 'curveness']), -getCurvenessForEdge(edge, seriesModel, index, true), 0);
        var p1 = clone$1(edge.node1.getLayout());
        var p2 = clone$1(edge.node2.getLayout());
        var points = [p1, p2];

        if (+curveness) {
          points.push([(p1[0] + p2[0]) / 2 - (p1[1] - p2[1]) * curveness, (p1[1] + p2[1]) / 2 - (p2[0] - p1[0]) * curveness]);
        }

        edge.setLayout(points);
      });
    }

    function graphSimpleLayout(ecModel, api) {
      ecModel.eachSeriesByType('graph', function (seriesModel) {
        var layout = seriesModel.get('layout');
        var coordSys = seriesModel.coordinateSystem;

        if (coordSys && coordSys.type !== 'view') {
          var data_1 = seriesModel.getData();
          var dimensions_1 = [];
          each(coordSys.dimensions, function (coordDim) {
            dimensions_1 = dimensions_1.concat(data_1.mapDimensionsAll(coordDim));
          });

          for (var dataIndex = 0; dataIndex < data_1.count(); dataIndex++) {
            var value = [];
            var hasValue = false;

            for (var i = 0; i < dimensions_1.length; i++) {
              var val = data_1.get(dimensions_1[i], dataIndex);

              if (!isNaN(val)) {
                hasValue = true;
              }

              value.push(val);
            }

            if (hasValue) {
              data_1.setItemLayout(dataIndex, coordSys.dataToPoint(value));
            } else {
              // Also {Array.<number>}, not undefined to avoid if...else... statement
              data_1.setItemLayout(dataIndex, [NaN, NaN]);
            }
          }

          simpleLayoutEdge(data_1.graph, seriesModel);
        } else if (!layout || layout === 'none') {
          simpleLayout(seriesModel);
        }
      });
    }

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


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * 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 getNodeGlobalScale(seriesModel) {
      var coordSys = seriesModel.coordinateSystem;

      if (coordSys.type !== 'view') {
        return 1;
      }

      var nodeScaleRatio = seriesModel.option.nodeScaleRatio;
      var groupZoom = coordSys.scaleX; // Scale node when zoom changes

      var roamZoom = coordSys.getZoom();
      var nodeScale = (roamZoom - 1) * nodeScaleRatio + 1;
      return nodeScale / groupZoom;
    }
    function getSymbolSize(node) {
      var symbolSize = node.getVisual('symbolSize');

      if (symbolSize instanceof Array) {
        symbolSize = (symbolSize[0] + symbolSize[1]) / 2;
      }

      return +symbolSize;
    }

    var PI$6 = Math.PI;
    var _symbolRadiansHalf = [];
    /**
     * `basedOn` can be:
     * 'value':
     *     This layout is not accurate and have same bad case. For example,
     *     if the min value is very smaller than the max value, the nodes
     *     with the min value probably overlap even though there is enough
     *     space to layout them. So we only use this approach in the as the
     *     init layout of the force layout.
     *     FIXME
     *     Probably we do not need this method any more but use
     *     `basedOn: 'symbolSize'` in force layout if
     *     delay its init operations to GraphView.
     * 'symbolSize':
     *     This approach work only if all of the symbol size calculated.
     *     That is, the progressive rendering is not applied to graph.
     *     FIXME
     *     If progressive rendering is applied to graph some day,
     *     probably we have to use `basedOn: 'value'`.
     */

    function circularLayout(seriesModel, basedOn, draggingNode, pointer) {
      var coordSys = seriesModel.coordinateSystem;

      if (coordSys && coordSys.type !== 'view') {
        return;
      }

      var rect = coordSys.getBoundingRect();
      var nodeData = seriesModel.getData();
      var graph = nodeData.graph;
      var cx = rect.width / 2 + rect.x;
      var cy = rect.height / 2 + rect.y;
      var r = Math.min(rect.width, rect.height) / 2;
      var count = nodeData.count();
      nodeData.setLayout({
        cx: cx,
        cy: cy
      });

      if (!count) {
        return;
      }

      if (draggingNode) {
        var _a = coordSys.pointToData(pointer),
            tempX = _a[0],
            tempY = _a[1];

        var v = [tempX - cx, tempY - cy];
        normalize(v, v);
        scale(v, v, r);
        draggingNode.setLayout([cx + v[0], cy + v[1]], true);
        var circularRotateLabel = seriesModel.get(['circular', 'rotateLabel']);
        rotateNodeLabel(draggingNode, circularRotateLabel, cx, cy);
      }

      _layoutNodesBasedOn[basedOn](seriesModel, graph, nodeData, r, cx, cy, count);

      graph.eachEdge(function (edge, index) {
        var curveness = retrieve3(edge.getModel().get(['lineStyle', 'curveness']), getCurvenessForEdge(edge, seriesModel, index), 0);
        var p1 = clone$1(edge.node1.getLayout());
        var p2 = clone$1(edge.node2.getLayout());
        var cp1;
        var x12 = (p1[0] + p2[0]) / 2;
        var y12 = (p1[1] + p2[1]) / 2;

        if (+curveness) {
          curveness *= 3;
          cp1 = [cx * curveness + x12 * (1 - curveness), cy * curveness + y12 * (1 - curveness)];
        }

        edge.setLayout([p1, p2, cp1]);
      });
    }
    var _layoutNodesBasedOn = {
      value: function (seriesModel, graph, nodeData, r, cx, cy, count) {
        var angle = 0;
        var sum = nodeData.getSum('value');
        var unitAngle = Math.PI * 2 / (sum || count);
        graph.eachNode(function (node) {
          var value = node.getValue('value');
          var radianHalf = unitAngle * (sum ? value : 1) / 2;
          angle += radianHalf;
          node.setLayout([r * Math.cos(angle) + cx, r * Math.sin(angle) + cy]);
          angle += radianHalf;
        });
      },
      symbolSize: function (seriesModel, graph, nodeData, r, cx, cy, count) {
        var sumRadian = 0;
        _symbolRadiansHalf.length = count;
        var nodeScale = getNodeGlobalScale(seriesModel);
        graph.eachNode(function (node) {
          var symbolSize = getSymbolSize(node); // Normally this case will not happen, but we still add
          // some the defensive code (2px is an arbitrary value).

          isNaN(symbolSize) && (symbolSize = 2);
          symbolSize < 0 && (symbolSize = 0);
          symbolSize *= nodeScale;
          var symbolRadianHalf = Math.asin(symbolSize / 2 / r); // when `symbolSize / 2` is bigger than `r`.

          isNaN(symbolRadianHalf) && (symbolRadianHalf = PI$6 / 2);
          _symbolRadiansHalf[node.dataIndex] = symbolRadianHalf;
          sumRadian += symbolRadianHalf * 2;
        });
        var halfRemainRadian = (2 * PI$6 - sumRadian) / count / 2;
        var angle = 0;
        graph.eachNode(function (node) {
          var radianHalf = halfRemainRadian + _symbolRadiansHalf[node.dataIndex];
          angle += radianHalf; // init circular layout for
          // 1. layout undefined node
          // 2. not fixed node

          (!node.getLayout() || !node.getLayout().fixed) && node.setLayout([r * Math.cos(angle) + cx, r * Math.sin(angle) + cy]);
          angle += radianHalf;
        });
      }
    };
    function rotateNodeLabel(node, circularRotateLabel, cx, cy) {
      var el = node.getGraphicEl(); // need to check if el exists. '-' value may not create node element.

      if (!el) {
        return;
      }

      var nodeModel = node.getModel();
      var labelRotate = nodeModel.get(['label', 'rotate']) || 0;
      var symbolPath = el.getSymbolPath();

      if (circularRotateLabel) {
        var pos = node.getLayout();
        var rad = Math.atan2(pos[1] - cy, pos[0] - cx);

        if (rad < 0) {
          rad = Math.PI * 2 + rad;
        }

        var isLeft = pos[0] < cx;

        if (isLeft) {
          rad = rad - Math.PI;
        }

        var textPosition = isLeft ? 'left' : 'right';
        symbolPath.setTextConfig({
          rotation: -rad,
          position: textPosition,
          origin: 'center'
        });
        var emphasisState = symbolPath.ensureState('emphasis');
        extend(emphasisState.textConfig || (emphasisState.textConfig = {}), {
          position: textPosition
        });
      } else {
        symbolPath.setTextConfig({
          rotation: labelRotate *= Math.PI / 180
        });
      }
    }

    function graphCircularLayout(ecModel) {
      ecModel.eachSeriesByType('graph', function (seriesModel) {
        if (seriesModel.get('layout') === 'circular') {
          circularLayout(seriesModel, 'symbolSize');
        }
      });
    }

    var scaleAndAdd$1 = scaleAndAdd; // function adjacentNode(n, e) {
    //     return e.n1 === n ? e.n2 : e.n1;
    // }

    function forceLayout(inNodes, inEdges, opts) {
      var nodes = inNodes;
      var edges = inEdges;
      var rect = opts.rect;
      var width = rect.width;
      var height = rect.height;
      var center = [rect.x + width / 2, rect.y + height / 2]; // let scale = opts.scale || 1;

      var gravity = opts.gravity == null ? 0.1 : opts.gravity; // for (let i = 0; i < edges.length; i++) {
      //     let e = edges[i];
      //     let n1 = e.n1;
      //     let n2 = e.n2;
      //     n1.edges = n1.edges || [];
      //     n2.edges = n2.edges || [];
      //     n1.edges.push(e);
      //     n2.edges.push(e);
      // }
      // Init position

      for (var i = 0; i < nodes.length; i++) {
        var n = nodes[i];

        if (!n.p) {
          n.p = create(width * (Math.random() - 0.5) + center[0], height * (Math.random() - 0.5) + center[1]);
        }

        n.pp = clone$1(n.p);
        n.edges = null;
      } // Formula in 'Graph Drawing by Force-directed Placement'
      // let k = scale * Math.sqrt(width * height / nodes.length);
      // let k2 = k * k;


      var initialFriction = opts.friction == null ? 0.6 : opts.friction;
      var friction = initialFriction;
      var beforeStepCallback;
      var afterStepCallback;
      return {
        warmUp: function () {
          friction = initialFriction * 0.8;
        },
        setFixed: function (idx) {
          nodes[idx].fixed = true;
        },
        setUnfixed: function (idx) {
          nodes[idx].fixed = false;
        },

        /**
         * Before step hook
         */
        beforeStep: function (cb) {
          beforeStepCallback = cb;
        },

        /**
         * After step hook
         */
        afterStep: function (cb) {
          afterStepCallback = cb;
        },

        /**
         * Some formulas were originally copied from "d3.js"
         * https://github.com/d3/d3/blob/b516d77fb8566b576088e73410437494717ada26/src/layout/force.js
         * with some modifications made for this project.
         * See the license statement at the head of this file.
         */
        step: function (cb) {
          beforeStepCallback && beforeStepCallback(nodes, edges);
          var v12 = [];
          var nLen = nodes.length;

          for (var i = 0; i < edges.length; i++) {
            var e = edges[i];

            if (e.ignoreForceLayout) {
              continue;
            }

            var n1 = e.n1;
            var n2 = e.n2;
            sub(v12, n2.p, n1.p);
            var d = len(v12) - e.d;
            var w = n2.w / (n1.w + n2.w);

            if (isNaN(w)) {
              w = 0;
            }

            normalize(v12, v12);
            !n1.fixed && scaleAndAdd$1(n1.p, n1.p, v12, w * d * friction);
            !n2.fixed && scaleAndAdd$1(n2.p, n2.p, v12, -(1 - w) * d * friction);
          } // Gravity


          for (var i = 0; i < nLen; i++) {
            var n = nodes[i];

            if (!n.fixed) {
              sub(v12, center, n.p); // let d = vec2.len(v12);
              // vec2.scale(v12, v12, 1 / d);
              // let gravityFactor = gravity;

              scaleAndAdd$1(n.p, n.p, v12, gravity * friction);
            }
          } // Repulsive
          // PENDING


          for (var i = 0; i < nLen; i++) {
            var n1 = nodes[i];

            for (var j = i + 1; j < nLen; j++) {
              var n2 = nodes[j];
              sub(v12, n2.p, n1.p);
              var d = len(v12);

              if (d === 0) {
                // Random repulse
                set(v12, Math.random() - 0.5, Math.random() - 0.5);
                d = 1;
              }

              var repFact = (n1.rep + n2.rep) / d / d;
              !n1.fixed && scaleAndAdd$1(n1.pp, n1.pp, v12, repFact);
              !n2.fixed && scaleAndAdd$1(n2.pp, n2.pp, v12, -repFact);
            }
          }

          var v = [];

          for (var i = 0; i < nLen; i++) {
            var n = nodes[i];

            if (!n.fixed) {
              sub(v, n.p, n.pp);
              scaleAndAdd$1(n.p, n.p, v, friction);
              copy(n.pp, n.p);
            }
          }

          friction = friction * 0.992;
          var finished = friction < 0.01;
          afterStepCallback && afterStepCallback(nodes, edges, finished);
          cb && cb(finished);
        }
      };
    }

    function graphForceLayout(ecModel) {
      ecModel.eachSeriesByType('graph', function (graphSeries) {
        var coordSys = graphSeries.coordinateSystem;

        if (coordSys && coordSys.type !== 'view') {
          return;
        }

        if (graphSeries.get('layout') === 'force') {
          var preservedPoints_1 = graphSeries.preservedPoints || {};
          var graph_1 = graphSeries.getGraph();
          var nodeData_1 = graph_1.data;
          var edgeData = graph_1.edgeData;
          var forceModel = graphSeries.getModel('force');
          var initLayout = forceModel.get('initLayout');

          if (graphSeries.preservedPoints) {
            nodeData_1.each(function (idx) {
              var id = nodeData_1.getId(idx);
              nodeData_1.setItemLayout(idx, preservedPoints_1[id] || [NaN, NaN]);
            });
          } else if (!initLayout || initLayout === 'none') {
            simpleLayout(graphSeries);
          } else if (initLayout === 'circular') {
            circularLayout(graphSeries, 'value');
          }

          var nodeDataExtent_1 = nodeData_1.getDataExtent('value');
          var edgeDataExtent_1 = edgeData.getDataExtent('value'); // let edgeDataExtent = edgeData.getDataExtent('value');

          var repulsion = forceModel.get('repulsion');
          var edgeLength = forceModel.get('edgeLength');
          var repulsionArr_1 = isArray(repulsion) ? repulsion : [repulsion, repulsion];
          var edgeLengthArr_1 = isArray(edgeLength) ? edgeLength : [edgeLength, edgeLength]; // Larger value has smaller length

          edgeLengthArr_1 = [edgeLengthArr_1[1], edgeLengthArr_1[0]];
          var nodes_1 = nodeData_1.mapArray('value', function (value, idx) {
            var point = nodeData_1.getItemLayout(idx);
            var rep = linearMap(value, nodeDataExtent_1, repulsionArr_1);

            if (isNaN(rep)) {
              rep = (repulsionArr_1[0] + repulsionArr_1[1]) / 2;
            }

            return {
              w: rep,
              rep: rep,
              fixed: nodeData_1.getItemModel(idx).get('fixed'),
              p: !point || isNaN(point[0]) || isNaN(point[1]) ? null : point
            };
          });
          var edges = edgeData.mapArray('value', function (value, idx) {
            var edge = graph_1.getEdgeByIndex(idx);
            var d = linearMap(value, edgeDataExtent_1, edgeLengthArr_1);

            if (isNaN(d)) {
              d = (edgeLengthArr_1[0] + edgeLengthArr_1[1]) / 2;
            }

            var edgeModel = edge.getModel();
            var curveness = retrieve3(edge.getModel().get(['lineStyle', 'curveness']), -getCurvenessForEdge(edge, graphSeries, idx, true), 0);
            return {
              n1: nodes_1[edge.node1.dataIndex],
              n2: nodes_1[edge.node2.dataIndex],
              d: d,
              curveness: curveness,
              ignoreForceLayout: edgeModel.get('ignoreForceLayout')
            };
          }); // let coordSys = graphSeries.coordinateSystem;

          var rect = coordSys.getBoundingRect();
          var forceInstance = forceLayout(nodes_1, edges, {
            rect: rect,
            gravity: forceModel.get('gravity'),
            friction: forceModel.get('friction')
          });
          forceInstance.beforeStep(function (nodes, edges) {
            for (var i = 0, l = nodes.length; i < l; i++) {
              if (nodes[i].fixed) {
                // Write back to layout instance
                copy(nodes[i].p, graph_1.getNodeByIndex(i).getLayout());
              }
            }
          });
          forceInstance.afterStep(function (nodes, edges, stopped) {
            for (var i = 0, l = nodes.length; i < l; i++) {
              if (!nodes[i].fixed) {
                graph_1.getNodeByIndex(i).setLayout(nodes[i].p);
              }

              preservedPoints_1[nodeData_1.getId(i)] = nodes[i].p;
            }

            for (var i = 0, l = edges.length; i < l; i++) {
              var e = edges[i];
              var edge = graph_1.getEdgeByIndex(i);
              var p1 = e.n1.p;
              var p2 = e.n2.p;
              var points = edge.getLayout();
              points = points ? points.slice() : [];
              points[0] = points[0] || [];
              points[1] = points[1] || [];
              copy(points[0], p1);
              copy(points[1], p2);

              if (+e.curveness) {
                points[2] = [(p1[0] + p2[0]) / 2 - (p1[1] - p2[1]) * e.curveness, (p1[1] + p2[1]) / 2 - (p2[0] - p1[0]) * e.curveness];
              }

              edge.setLayout(points);
            }
          });
          graphSeries.forceLayout = forceInstance;
          graphSeries.preservedPoints = preservedPoints_1; // Step to get the layout

          forceInstance.step();
        } else {
          // Remove prev injected forceLayout instance
          graphSeries.forceLayout = null;
        }
      });
    }

    function getViewRect$2(seriesModel, api, aspect) {
      var option = extend(seriesModel.getBoxLayoutParams(), {
        aspect: aspect
      });
      return getLayoutRect(option, {
        width: api.getWidth(),
        height: api.getHeight()
      });
    }

    function createViewCoordSys(ecModel, api) {
      var viewList = [];
      ecModel.eachSeriesByType('graph', function (seriesModel) {
        var coordSysType = seriesModel.get('coordinateSystem');

        if (!coordSysType || coordSysType === 'view') {
          var data_1 = seriesModel.getData();
          var positions = data_1.mapArray(function (idx) {
            var itemModel = data_1.getItemModel(idx);
            return [+itemModel.get('x'), +itemModel.get('y')];
          });
          var min = [];
          var max = [];
          fromPoints(positions, min, max); // If width or height is 0

          if (max[0] - min[0] === 0) {
            max[0] += 1;
            min[0] -= 1;
          }

          if (max[1] - min[1] === 0) {
            max[1] += 1;
            min[1] -= 1;
          }

          var aspect = (max[0] - min[0]) / (max[1] - min[1]); // FIXME If get view rect after data processed?

          var viewRect = getViewRect$2(seriesModel, api, aspect); // Position may be NaN, use view rect instead

          if (isNaN(aspect)) {
            min = [viewRect.x, viewRect.y];
            max = [viewRect.x + viewRect.width, viewRect.y + viewRect.height];
          }

          var bbWidth = max[0] - min[0];
          var bbHeight = max[1] - min[1];
          var viewWidth = viewRect.width;
          var viewHeight = viewRect.height;
          var viewCoordSys = seriesModel.coordinateSystem = new View();
          viewCoordSys.zoomLimit = seriesModel.get('scaleLimit');
          viewCoordSys.setBoundingRect(min[0], min[1], bbWidth, bbHeight);
          viewCoordSys.setViewRect(viewRect.x, viewRect.y, viewWidth, viewHeight); // Update roam info

          viewCoordSys.setCenter(seriesModel.get('center'), api);
          viewCoordSys.setZoom(seriesModel.get('zoom'));
          viewList.push(viewCoordSys);
        }
      });
      return viewList;
    }

    var straightLineProto = Line.prototype;
    var bezierCurveProto = BezierCurve.prototype;

    var StraightLineShape =
    /** @class */
    function () {
      function StraightLineShape() {
        // Start point
        this.x1 = 0;
        this.y1 = 0; // End point

        this.x2 = 0;
        this.y2 = 0;
        this.percent = 1;
      }

      return StraightLineShape;
    }();

    var CurveShape =
    /** @class */
    function (_super) {
      __extends(CurveShape, _super);

      function CurveShape() {
        return _super !== null && _super.apply(this, arguments) || this;
      }

      return CurveShape;
    }(StraightLineShape);

    function isStraightLine(shape) {
      return isNaN(+shape.cpx1) || isNaN(+shape.cpy1);
    }

    var ECLinePath =
    /** @class */
    function (_super) {
      __extends(ECLinePath, _super);

      function ECLinePath(opts) {
        var _this = _super.call(this, opts) || this;

        _this.type = 'ec-line';
        return _this;
      }

      ECLinePath.prototype.getDefaultStyle = function () {
        return {
          stroke: '#000',
          fill: null
        };
      };

      ECLinePath.prototype.getDefaultShape = function () {
        return new StraightLineShape();
      };

      ECLinePath.prototype.buildPath = function (ctx, shape) {
        if (isStraightLine(shape)) {
          straightLineProto.buildPath.call(this, ctx, shape);
        } else {
          bezierCurveProto.buildPath.call(this, ctx, shape);
        }
      };

      ECLinePath.prototype.pointAt = function (t) {
        if (isStraightLine(this.shape)) {
          return straightLineProto.pointAt.call(this, t);
        } else {
          return bezierCurveProto.pointAt.call(this, t);
        }
      };

      ECLinePath.prototype.tangentAt = function (t) {
        var shape = this.shape;
        var p = isStraightLine(shape) ? [shape.x2 - shape.x1, shape.y2 - shape.y1] : bezierCurveProto.tangentAt.call(this, t);
        return normalize(p, p);
      };

      return ECLinePath;
    }(Path);

    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 symbolSize = lineData.getItemVisual(idx, name + 'Size');
      var symbolRotate = lineData.getItemVisual(idx, name + 'Rotate');
      var symbolOffset = lineData.getItemVisual(idx, name + 'Offset');
      var symbolKeepAspect = lineData.getItemVisual(idx, name + 'KeepAspect');
      var symbolSizeArr = normalizeSymbolSize(symbolSize);
      var symbolOffsetArr = normalizeSymbolOffset(symbolOffset || 0, symbolSizeArr);
      var symbolPath = createSymbol(symbolType, -symbolSizeArr[0] / 2 + symbolOffsetArr[0], -symbolSizeArr[1] / 2 + symbolOffsetArr[1], symbolSizeArr[0], symbolSizeArr[1], null, symbolKeepAspect);
      symbolPath.__specifiedRotation = symbolRotate == null || isNaN(symbolRotate) ? void 0 : +symbolRotate * Math.PI / 180 || 0;
      symbolPath.name = name;
      return symbolPath;
    }

    function createLine(points) {
      var line = new ECLinePath({
        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;
      }
    }

    var Line$1 =
    /** @class */
    function (_super) {
      __extends(Line, _super);

      function Line(lineData, idx, seriesScope) {
        var _this = _super.call(this) || this;

        _this._createLine(lineData, idx, seriesScope);

        return _this;
      }

      Line.prototype._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);
        each(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);
      }; // TODO More strict on the List type in parameters?


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

      Line.prototype.getLinePath = function () {
        return this.childAt(0);
      };

      Line.prototype._updateCommonStl = function (lineData, idx, seriesScope) {
        var seriesModel = lineData.hostModel;
        var line = this.childOfName('line');
        var emphasisLineStyle = seriesScope && seriesScope.emphasisLineStyle;
        var blurLineStyle = seriesScope && seriesScope.blurLineStyle;
        var selectLineStyle = seriesScope && seriesScope.selectLineStyle;
        var labelStatesModels = seriesScope && seriesScope.labelStatesModels;
        var emphasisDisabled = seriesScope && seriesScope.emphasisDisabled;
        var focus = seriesScope && seriesScope.focus;
        var blurScope = seriesScope && seriesScope.blurScope; // Optimization for large dataset

        if (!seriesScope || lineData.hasItemOption) {
          var itemModel = lineData.getItemModel(idx);
          var emphasisModel = itemModel.getModel('emphasis');
          emphasisLineStyle = emphasisModel.getModel('lineStyle').getLineStyle();
          blurLineStyle = itemModel.getModel(['blur', 'lineStyle']).getLineStyle();
          selectLineStyle = itemModel.getModel(['select', 'lineStyle']).getLineStyle();
          emphasisDisabled = emphasisModel.get('disabled');
          focus = emphasisModel.get('focus');
          blurScope = emphasisModel.get('blurScope');
          labelStatesModels = getLabelStatesModels(itemModel);
        }

        var lineStyle = lineData.getItemVisual(idx, 'style');
        var visualColor = lineStyle.stroke;
        line.useStyle(lineStyle);
        line.style.fill = null;
        line.style.strokeNoScale = true;
        line.ensureState('emphasis').style = emphasisLineStyle;
        line.ensureState('blur').style = blurLineStyle;
        line.ensureState('select').style = selectLineStyle; // Update symbol

        each(SYMBOL_CATEGORIES, function (symbolCategory) {
          var symbol = this.childOfName(symbolCategory);

          if (symbol) {
            // Share opacity and color with line.
            symbol.setColor(visualColor);
            symbol.style.opacity = lineStyle.opacity;

            for (var i = 0; i < SPECIAL_STATES.length; i++) {
              var stateName = SPECIAL_STATES[i];
              var lineState = line.getState(stateName);

              if (lineState) {
                var lineStateStyle = lineState.style || {};
                var state = symbol.ensureState(stateName);
                var stateStyle = state.style || (state.style = {});

                if (lineStateStyle.stroke != null) {
                  stateStyle[symbol.__isEmptyBrush ? 'stroke' : 'fill'] = lineStateStyle.stroke;
                }

                if (lineStateStyle.opacity != null) {
                  stateStyle.opacity = lineStateStyle.opacity;
                }
              }
            }

            symbol.markRedraw();
          }
        }, this);
        var rawVal = seriesModel.getRawValue(idx);
        setLabelStyle(this, labelStatesModels, {
          labelDataIndex: idx,
          labelFetcher: {
            getFormattedLabel: function (dataIndex, stateName) {
              return seriesModel.getFormattedLabel(dataIndex, stateName, lineData.dataType);
            }
          },
          inheritColor: visualColor || '#000',
          defaultOpacity: lineStyle.opacity,
          defaultText: (rawVal == null ? lineData.getName(idx) : isFinite(rawVal) ? round(rawVal) : rawVal) + ''
        });
        var label = this.getTextContent(); // Always set `textStyle` even if `normalStyle.text` is null, because default
        // values have to be set on `normalStyle`.

        if (label) {
          var labelNormalModel = labelStatesModels.normal;
          label.__align = label.style.align;
          label.__verticalAlign = label.style.verticalAlign; // 'start', 'middle', 'end'

          label.__position = labelNormalModel.get('position') || 'middle';
          var distance = labelNormalModel.get('distance');

          if (!isArray(distance)) {
            distance = [distance, distance];
          }

          label.__labelDistance = distance;
        }

        this.setTextConfig({
          position: null,
          local: true,
          inside: false // Can't be inside for stroke element.

        });
        toggleHoverEmphasis(this, focus, blurScope, emphasisDisabled);
      };

      Line.prototype.highlight = function () {
        enterEmphasis(this);
      };

      Line.prototype.downplay = function () {
        leaveEmphasis(this);
      };

      Line.prototype.updateLayout = function (lineData, idx) {
        this.setLinePoints(lineData.getItemLayout(idx));
      };

      Line.prototype.setLinePoints = function (points) {
        var linePath = this.childOfName('line');
        setLinePoints(linePath.shape, points);
        linePath.dirty();
      };

      Line.prototype.beforeUpdate = function () {
        var lineGroup = this;
        var symbolFrom = lineGroup.childOfName('fromSymbol');
        var symbolTo = lineGroup.childOfName('toSymbol');
        var label = lineGroup.getTextContent(); // Quick reject

        if (!symbolFrom && !symbolTo && (!label || label.ignore)) {
          return;
        }

        var invScale = 1;
        var parentNode = this.parent;

        while (parentNode) {
          if (parentNode.scaleX) {
            invScale /= parentNode.scaleX;
          }

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

        function setSymbolRotation(symbol, percent) {
          // 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 = symbol.__specifiedRotation;

          if (specifiedRotation == null) {
            var tangent = line.tangentAt(percent);
            symbol.attr('rotation', (percent === 1 ? -1 : 1) * Math.PI / 2 - Math.atan2(tangent[1], tangent[0]));
          } else {
            symbol.attr('rotation', specifiedRotation);
          }
        }

        if (symbolFrom) {
          symbolFrom.setPosition(fromPos);
          setSymbolRotation(symbolFrom, 0);
          symbolFrom.scaleX = symbolFrom.scaleY = invScale * percent;
          symbolFrom.markRedraw();
        }

        if (symbolTo) {
          symbolTo.setPosition(toPos);
          setSymbolRotation(symbolTo, 1);
          symbolTo.scaleX = symbolTo.scaleY = invScale * percent;
          symbolTo.markRedraw();
        }

        if (label && !label.ignore) {
          label.x = label.y = 0;
          label.originX = label.originY = 0;
          var textAlign = void 0;
          var textVerticalAlign = void 0;
          var distance = label.__labelDistance;
          var distanceX = distance[0] * invScale;
          var distanceY = distance[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.rotation = rotation;
          }

          var dy = void 0;

          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':
              label.x = d[0] * distanceX + toPos[0];
              label.y = 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':
              label.x = -d[0] * distanceX + fromPos[0];
              label.y = -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':
              label.x = distanceX * dir + fromPos[0];
              label.y = fromPos[1] + dy;
              textAlign = tangent[0] < 0 ? 'right' : 'left';
              label.originX = -distanceX * dir;
              label.originY = -dy;
              break;

            case 'insideMiddleTop':
            case 'insideMiddle':
            case 'insideMiddleBottom':
            case 'middle':
              label.x = cp[0];
              label.y = cp[1] + dy;
              textAlign = 'center';
              label.originY = -dy;
              break;

            case 'insideEndTop':
            case 'insideEnd':
            case 'insideEndBottom':
              label.x = -distanceX * dir + toPos[0];
              label.y = toPos[1] + dy;
              textAlign = tangent[0] >= 0 ? 'right' : 'left';
              label.originX = distanceX * dir;
              label.originY = -dy;
              break;
          }

          label.scaleX = label.scaleY = invScale;
          label.setStyle({
            // Use the user specified text align and baseline first
            verticalAlign: label.__verticalAlign || textVerticalAlign,
            align: label.__align || textAlign
          });
        }
      };

      return Line;
    }(Group);

    var LineDraw =
    /** @class */
    function () {
      function LineDraw(LineCtor) {
        this.group = new Group();
        this._LineCtor = LineCtor || Line$1;
      }

      LineDraw.prototype.updateData = function (lineData) {
        var _this = this; // Remove progressive els.


        this._progressiveEls = null;
        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) {
          _this._doAdd(lineData, idx, seriesScope);
        }).update(function (newIdx, oldIdx) {
          _this._doUpdate(oldLineData, lineData, oldIdx, newIdx, seriesScope);
        }).remove(function (idx) {
          group.remove(oldLineData.getItemGraphicEl(idx));
        }).execute();
      };

      LineDraw.prototype.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);
      };

      LineDraw.prototype.incrementalPrepareUpdate = function (lineData) {
        this._seriesScope = makeSeriesScope$1(lineData);
        this._lineData = null;
        this.group.removeAll();
      };

      LineDraw.prototype.incrementalUpdate = function (taskParams, lineData) {
        this._progressiveEls = [];

        function updateIncrementalAndHover(el) {
          if (!el.isGroup && !isEffectObject(el)) {
            el.incremental = true;
            el.ensureState('emphasis').hoverLayer = true;
          }
        }

        for (var idx = taskParams.start; idx < taskParams.end; idx++) {
          var itemLayout = lineData.getItemLayout(idx);

          if (lineNeedsDraw(itemLayout)) {
            var el = new this._LineCtor(lineData, idx, this._seriesScope);
            el.traverse(updateIncrementalAndHover);
            this.group.add(el);
            lineData.setItemGraphicEl(idx, el);

            this._progressiveEls.push(el);
          }
        }
      };

      LineDraw.prototype.remove = function () {
        this.group.removeAll();
      };

      LineDraw.prototype.eachRendered = function (cb) {
        traverseElements(this._progressiveEls || this.group, cb);
      };

      LineDraw.prototype._doAdd = function (lineData, idx, seriesScope) {
        var itemLayout = lineData.getItemLayout(idx);

        if (!lineNeedsDraw(itemLayout)) {
          return;
        }

        var el = new this._LineCtor(lineData, idx, seriesScope);
        lineData.setItemGraphicEl(idx, el);
        this.group.add(el);
      };

      LineDraw.prototype._doUpdate = function (oldLineData, newLineData, oldIdx, newIdx, seriesScope) {
        var itemEl = oldLineData.getItemGraphicEl(oldIdx);

        if (!lineNeedsDraw(newLineData.getItemLayout(newIdx))) {
          this.group.remove(itemEl);
          return;
        }

        if (!itemEl) {
          itemEl = new this._LineCtor(newLineData, newIdx, seriesScope);
        } else {
          itemEl.updateData(newLineData, newIdx, seriesScope);
        }

        newLineData.setItemGraphicEl(newIdx, itemEl);
        this.group.add(itemEl);
      };

      return LineDraw;
    }();

    function isEffectObject(el) {
      return el.animators && el.animators.length > 0;
    }

    function makeSeriesScope$1(lineData) {
      var hostModel = lineData.hostModel;
      var emphasisModel = hostModel.getModel('emphasis');
      return {
        lineStyle: hostModel.getModel('lineStyle').getLineStyle(),
        emphasisLineStyle: emphasisModel.getModel(['lineStyle']).getLineStyle(),
        blurLineStyle: hostModel.getModel(['blur', 'lineStyle']).getLineStyle(),
        selectLineStyle: hostModel.getModel(['select', 'lineStyle']).getLineStyle(),
        emphasisDisabled: emphasisModel.get('disabled'),
        blurScope: emphasisModel.get('blurScope'),
        focus: emphasisModel.get('focus'),
        labelStatesModels: getLabelStatesModels(hostModel)
      };
    }

    function isPointNaN(pt) {
      return isNaN(pt[0]) || isNaN(pt[1]);
    }

    function lineNeedsDraw(pts) {
      return pts && !isPointNaN(pts[0]) && !isPointNaN(pts[1]);
    }

    var v1 = [];
    var v2 = [];
    var v3 = [];
    var quadraticAt$1 = quadraticAt;
    var v2DistSquare = distSquare;
    var mathAbs$2 = Math.abs;

    function intersectCurveCircle(curvePoints, center, radius) {
      var p0 = curvePoints[0];
      var p1 = curvePoints[1];
      var p2 = curvePoints[2];
      var d = Infinity;
      var t;
      var radiusSquare = radius * radius;
      var interval = 0.1;

      for (var _t = 0.1; _t <= 0.9; _t += 0.1) {
        v1[0] = quadraticAt$1(p0[0], p1[0], p2[0], _t);
        v1[1] = quadraticAt$1(p0[1], p1[1], p2[1], _t);
        var diff = mathAbs$2(v2DistSquare(v1, center) - radiusSquare);

        if (diff < d) {
          d = diff;
          t = _t;
        }
      } // Assume the segment is monotone，Find root through Bisection method
      // At most 32 iteration


      for (var i = 0; i < 32; i++) {
        // let prev = t - interval;
        var next = t + interval; // v1[0] = quadraticAt(p0[0], p1[0], p2[0], prev);
        // v1[1] = quadraticAt(p0[1], p1[1], p2[1], prev);

        v2[0] = quadraticAt$1(p0[0], p1[0], p2[0], t);
        v2[1] = quadraticAt$1(p0[1], p1[1], p2[1], t);
        v3[0] = quadraticAt$1(p0[0], p1[0], p2[0], next);
        v3[1] = quadraticAt$1(p0[1], p1[1], p2[1], next);
        var diff = v2DistSquare(v2, center) - radiusSquare;

        if (mathAbs$2(diff) < 1e-2) {
          break;
        } // let prevDiff = v2DistSquare(v1, center) - radiusSquare;


        var nextDiff = v2DistSquare(v3, center) - radiusSquare;
        interval /= 2;

        if (diff < 0) {
          if (nextDiff >= 0) {
            t = t + interval;
          } else {
            t = t - interval;
          }
        } else {
          if (nextDiff >= 0) {
            t = t - interval;
          } else {
            t = t + interval;
          }
        }
      }

      return t;
    } // Adjust edge to avoid


    function adjustEdge(graph, scale) {
      var tmp0 = [];
      var quadraticSubdivide$1 = quadraticSubdivide;
      var pts = [[], [], []];
      var pts2 = [[], []];
      var v = [];
      scale /= 2;
      graph.eachEdge(function (edge, idx) {
        var linePoints = edge.getLayout();
        var fromSymbol = edge.getVisual('fromSymbol');
        var toSymbol = edge.getVisual('toSymbol');

        if (!linePoints.__original) {
          linePoints.__original = [clone$1(linePoints[0]), clone$1(linePoints[1])];

          if (linePoints[2]) {
            linePoints.__original.push(clone$1(linePoints[2]));
          }
        }

        var originalPoints = linePoints.__original; // Quadratic curve

        if (linePoints[2] != null) {
          copy(pts[0], originalPoints[0]);
          copy(pts[1], originalPoints[2]);
          copy(pts[2], originalPoints[1]);

          if (fromSymbol && fromSymbol !== 'none') {
            var symbolSize = getSymbolSize(edge.node1);
            var t = intersectCurveCircle(pts, originalPoints[0], symbolSize * scale); // Subdivide and get the second

            quadraticSubdivide$1(pts[0][0], pts[1][0], pts[2][0], t, tmp0);
            pts[0][0] = tmp0[3];
            pts[1][0] = tmp0[4];
            quadraticSubdivide$1(pts[0][1], pts[1][1], pts[2][1], t, tmp0);
            pts[0][1] = tmp0[3];
            pts[1][1] = tmp0[4];
          }

          if (toSymbol && toSymbol !== 'none') {
            var symbolSize = getSymbolSize(edge.node2);
            var t = intersectCurveCircle(pts, originalPoints[1], symbolSize * scale); // Subdivide and get the first

            quadraticSubdivide$1(pts[0][0], pts[1][0], pts[2][0], t, tmp0);
            pts[1][0] = tmp0[1];
            pts[2][0] = tmp0[2];
            quadraticSubdivide$1(pts[0][1], pts[1][1], pts[2][1], t, tmp0);
            pts[1][1] = tmp0[1];
            pts[2][1] = tmp0[2];
          } // Copy back to layout


          copy(linePoints[0], pts[0]);
          copy(linePoints[1], pts[2]);
          copy(linePoints[2], pts[1]);
        } // Line
        else {
            copy(pts2[0], originalPoints[0]);
            copy(pts2[1], originalPoints[1]);
            sub(v, pts2[1], pts2[0]);
            normalize(v, v);

            if (fromSymbol && fromSymbol !== 'none') {
              var symbolSize = getSymbolSize(edge.node1);
              scaleAndAdd(pts2[0], pts2[0], v, symbolSize * scale);
            }

            if (toSymbol && toSymbol !== 'none') {
              var symbolSize = getSymbolSize(edge.node2);
              scaleAndAdd(pts2[1], pts2[1], v, -symbolSize * scale);
            }

            copy(linePoints[0], pts2[0]);
            copy(linePoints[1], pts2[1]);
          }
      });
    }

    function isViewCoordSys(coordSys) {
      return coordSys.type === 'view';
    }

    var GraphView =
    /** @class */
    function (_super) {
      __extends(GraphView, _super);

      function GraphView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = GraphView.type;
        return _this;
      }

      GraphView.prototype.init = function (ecModel, api) {
        var symbolDraw = new SymbolDraw();
        var lineDraw = new LineDraw();
        var group = this.group;
        this._controller = new RoamController(api.getZr());
        this._controllerHost = {
          target: group
        };
        group.add(symbolDraw.group);
        group.add(lineDraw.group);
        this._symbolDraw = symbolDraw;
        this._lineDraw = lineDraw;
        this._firstRender = true;
      };

      GraphView.prototype.render = function (seriesModel, ecModel, api) {
        var _this = this;

        var coordSys = seriesModel.coordinateSystem;
        this._model = seriesModel;
        var symbolDraw = this._symbolDraw;
        var lineDraw = this._lineDraw;
        var group = this.group;

        if (isViewCoordSys(coordSys)) {
          var groupNewProp = {
            x: coordSys.x,
            y: coordSys.y,
            scaleX: coordSys.scaleX,
            scaleY: coordSys.scaleY
          };

          if (this._firstRender) {
            group.attr(groupNewProp);
          } else {
            updateProps(group, groupNewProp, seriesModel);
          }
        } // Fix edge contact point with node


        adjustEdge(seriesModel.getGraph(), getNodeGlobalScale(seriesModel));
        var data = seriesModel.getData();
        symbolDraw.updateData(data);
        var edgeData = seriesModel.getEdgeData(); // TODO: TYPE

        lineDraw.updateData(edgeData);

        this._updateNodeAndLinkScale();

        this._updateController(seriesModel, ecModel, api);

        clearTimeout(this._layoutTimeout);
        var forceLayout = seriesModel.forceLayout;
        var layoutAnimation = seriesModel.get(['force', 'layoutAnimation']);

        if (forceLayout) {
          this._startForceLayoutIteration(forceLayout, layoutAnimation);
        }

        var layout = seriesModel.get('layout');
        data.graph.eachNode(function (node) {
          var idx = node.dataIndex;
          var el = node.getGraphicEl();
          var itemModel = node.getModel();

          if (!el) {
            return;
          } // Update draggable


          el.off('drag').off('dragend');
          var draggable = itemModel.get('draggable');

          if (draggable) {
            el.on('drag', function (e) {
              switch (layout) {
                case 'force':
                  forceLayout.warmUp();
                  !_this._layouting && _this._startForceLayoutIteration(forceLayout, layoutAnimation);
                  forceLayout.setFixed(idx); // Write position back to layout

                  data.setItemLayout(idx, [el.x, el.y]);
                  break;

                case 'circular':
                  data.setItemLayout(idx, [el.x, el.y]); // mark node fixed

                  node.setLayout({
                    fixed: true
                  }, true); // recalculate circular layout

                  circularLayout(seriesModel, 'symbolSize', node, [e.offsetX, e.offsetY]);

                  _this.updateLayout(seriesModel);

                  break;

                case 'none':
                default:
                  data.setItemLayout(idx, [el.x, el.y]); // update edge

                  simpleLayoutEdge(seriesModel.getGraph(), seriesModel);

                  _this.updateLayout(seriesModel);

                  break;
              }
            }).on('dragend', function () {
              if (forceLayout) {
                forceLayout.setUnfixed(idx);
              }
            });
          }

          el.setDraggable(draggable, !!itemModel.get('cursor'));
          var focus = itemModel.get(['emphasis', 'focus']);

          if (focus === 'adjacency') {
            getECData(el).focus = node.getAdjacentDataIndices();
          }
        });
        data.graph.eachEdge(function (edge) {
          var el = edge.getGraphicEl();
          var focus = edge.getModel().get(['emphasis', 'focus']);

          if (!el) {
            return;
          }

          if (focus === 'adjacency') {
            getECData(el).focus = {
              edge: [edge.dataIndex],
              node: [edge.node1.dataIndex, edge.node2.dataIndex]
            };
          }
        });
        var circularRotateLabel = seriesModel.get('layout') === 'circular' && seriesModel.get(['circular', 'rotateLabel']);
        var cx = data.getLayout('cx');
        var cy = data.getLayout('cy');
        data.graph.eachNode(function (node) {
          rotateNodeLabel(node, circularRotateLabel, cx, cy);
        });
        this._firstRender = false;
      };

      GraphView.prototype.dispose = function () {
        this._controller && this._controller.dispose();
        this._controllerHost = null;
      };

      GraphView.prototype._startForceLayoutIteration = function (forceLayout, layoutAnimation) {
        var self = this;

        (function step() {
          forceLayout.step(function (stopped) {
            self.updateLayout(self._model);
            (self._layouting = !stopped) && (layoutAnimation ? self._layoutTimeout = setTimeout(step, 16) : step());
          });
        })();
      };

      GraphView.prototype._updateController = function (seriesModel, ecModel, api) {
        var _this = this;

        var controller = this._controller;
        var controllerHost = this._controllerHost;
        var group = this.group;
        controller.setPointerChecker(function (e, x, y) {
          var rect = group.getBoundingRect();
          rect.applyTransform(group.transform);
          return rect.contain(x, y) && !onIrrelevantElement(e, api, seriesModel);
        });

        if (!isViewCoordSys(seriesModel.coordinateSystem)) {
          controller.disable();
          return;
        }

        controller.enable(seriesModel.get('roam'));
        controllerHost.zoomLimit = seriesModel.get('scaleLimit');
        controllerHost.zoom = seriesModel.coordinateSystem.getZoom();
        controller.off('pan').off('zoom').on('pan', function (e) {
          updateViewOnPan(controllerHost, e.dx, e.dy);
          api.dispatchAction({
            seriesId: seriesModel.id,
            type: 'graphRoam',
            dx: e.dx,
            dy: e.dy
          });
        }).on('zoom', function (e) {
          updateViewOnZoom(controllerHost, e.scale, e.originX, e.originY);
          api.dispatchAction({
            seriesId: seriesModel.id,
            type: 'graphRoam',
            zoom: e.scale,
            originX: e.originX,
            originY: e.originY
          });

          _this._updateNodeAndLinkScale();

          adjustEdge(seriesModel.getGraph(), getNodeGlobalScale(seriesModel));

          _this._lineDraw.updateLayout(); // Only update label layout on zoom


          api.updateLabelLayout();
        });
      };

      GraphView.prototype._updateNodeAndLinkScale = function () {
        var seriesModel = this._model;
        var data = seriesModel.getData();
        var nodeScale = getNodeGlobalScale(seriesModel);
        data.eachItemGraphicEl(function (el, idx) {
          el && el.setSymbolScale(nodeScale);
        });
      };

      GraphView.prototype.updateLayout = function (seriesModel) {
        adjustEdge(seriesModel.getGraph(), getNodeGlobalScale(seriesModel));

        this._symbolDraw.updateLayout();

        this._lineDraw.updateLayout();
      };

      GraphView.prototype.remove = function (ecModel, api) {
        this._symbolDraw && this._symbolDraw.remove();
        this._lineDraw && this._lineDraw.remove();
      };

      GraphView.type = 'graph';
      return GraphView;
    }(ChartView);

    function generateNodeKey(id) {
      return '_EC_' + id;
    }

    var Graph =
    /** @class */
    function () {
      function Graph(directed) {
        this.type = 'graph';
        this.nodes = [];
        this.edges = [];
        this._nodesMap = {};
        /**
         * @type {Object.<string, module:echarts/data/Graph.Edge>}
         * @private
         */

        this._edgesMap = {};
        this._directed = directed || false;
      }
      /**
       * If is directed graph
       */


      Graph.prototype.isDirected = function () {
        return this._directed;
      };
      /**
       * Add a new node
       */

      Graph.prototype.addNode = function (id, dataIndex) {
        id = id == null ? '' + dataIndex : '' + id;
        var nodesMap = this._nodesMap;

        if (nodesMap[generateNodeKey(id)]) {
          if ("development" !== 'production') {
            console.error('Graph nodes have duplicate name or id');
          }

          return;
        }

        var node = new GraphNode(id, dataIndex);
        node.hostGraph = this;
        this.nodes.push(node);
        nodesMap[generateNodeKey(id)] = node;
        return node;
      };
      /**
       * Get node by data index
       */

      Graph.prototype.getNodeByIndex = function (dataIndex) {
        var rawIdx = this.data.getRawIndex(dataIndex);
        return this.nodes[rawIdx];
      };
      /**
       * Get node by id
       */

      Graph.prototype.getNodeById = function (id) {
        return this._nodesMap[generateNodeKey(id)];
      };
      /**
       * Add a new edge
       */

      Graph.prototype.addEdge = function (n1, n2, dataIndex) {
        var nodesMap = this._nodesMap;
        var edgesMap = this._edgesMap; // PNEDING

        if (isNumber(n1)) {
          n1 = this.nodes[n1];
        }

        if (isNumber(n2)) {
          n2 = this.nodes[n2];
        }

        if (!(n1 instanceof GraphNode)) {
          n1 = nodesMap[generateNodeKey(n1)];
        }

        if (!(n2 instanceof GraphNode)) {
          n2 = nodesMap[generateNodeKey(n2)];
        }

        if (!n1 || !n2) {
          return;
        }

        var key = n1.id + '-' + n2.id;
        var edge = new GraphEdge(n1, n2, dataIndex);
        edge.hostGraph = this;

        if (this._directed) {
          n1.outEdges.push(edge);
          n2.inEdges.push(edge);
        }

        n1.edges.push(edge);

        if (n1 !== n2) {
          n2.edges.push(edge);
        }

        this.edges.push(edge);
        edgesMap[key] = edge;
        return edge;
      };
      /**
       * Get edge by data index
       */

      Graph.prototype.getEdgeByIndex = function (dataIndex) {
        var rawIdx = this.edgeData.getRawIndex(dataIndex);
        return this.edges[rawIdx];
      };
      /**
       * Get edge by two linked nodes
       */

      Graph.prototype.getEdge = function (n1, n2) {
        if (n1 instanceof GraphNode) {
          n1 = n1.id;
        }

        if (n2 instanceof GraphNode) {
          n2 = n2.id;
        }

        var edgesMap = this._edgesMap;

        if (this._directed) {
          return edgesMap[n1 + '-' + n2];
        } else {
          return edgesMap[n1 + '-' + n2] || edgesMap[n2 + '-' + n1];
        }
      };
      /**
       * Iterate all nodes
       */

      Graph.prototype.eachNode = function (cb, context) {
        var nodes = this.nodes;
        var len = nodes.length;

        for (var i = 0; i < len; i++) {
          if (nodes[i].dataIndex >= 0) {
            cb.call(context, nodes[i], i);
          }
        }
      };
      /**
       * Iterate all edges
       */

      Graph.prototype.eachEdge = function (cb, context) {
        var edges = this.edges;
        var len = edges.length;

        for (var i = 0; i < len; i++) {
          if (edges[i].dataIndex >= 0 && edges[i].node1.dataIndex >= 0 && edges[i].node2.dataIndex >= 0) {
            cb.call(context, edges[i], i);
          }
        }
      };
      /**
       * Breadth first traverse
       * Return true to stop traversing
       */

      Graph.prototype.breadthFirstTraverse = function (cb, startNode, direction, context) {
        if (!(startNode instanceof GraphNode)) {
          startNode = this._nodesMap[generateNodeKey(startNode)];
        }

        if (!startNode) {
          return;
        }

        var edgeType = direction === 'out' ? 'outEdges' : direction === 'in' ? 'inEdges' : 'edges';

        for (var i = 0; i < this.nodes.length; i++) {
          this.nodes[i].__visited = false;
        }

        if (cb.call(context, startNode, null)) {
          return;
        }

        var queue = [startNode];

        while (queue.length) {
          var currentNode = queue.shift();
          var edges = currentNode[edgeType];

          for (var i = 0; i < edges.length; i++) {
            var e = edges[i];
            var otherNode = e.node1 === currentNode ? e.node2 : e.node1;

            if (!otherNode.__visited) {
              if (cb.call(context, otherNode, currentNode)) {
                // Stop traversing
                return;
              }

              queue.push(otherNode);
              otherNode.__visited = true;
            }
          }
        }
      };
      // depthFirstTraverse(
      //     cb, startNode, direction, context
      // ) {
      // };
      // Filter update

      Graph.prototype.update = function () {
        var data = this.data;
        var edgeData = this.edgeData;
        var nodes = this.nodes;
        var edges = this.edges;

        for (var i = 0, len = nodes.length; i < len; i++) {
          nodes[i].dataIndex = -1;
        }

        for (var i = 0, len = data.count(); i < len; i++) {
          nodes[data.getRawIndex(i)].dataIndex = i;
        }

        edgeData.filterSelf(function (idx) {
          var edge = edges[edgeData.getRawIndex(idx)];
          return edge.node1.dataIndex >= 0 && edge.node2.dataIndex >= 0;
        }); // Update edge

        for (var i = 0, len = edges.length; i < len; i++) {
          edges[i].dataIndex = -1;
        }

        for (var i = 0, len = edgeData.count(); i < len; i++) {
          edges[edgeData.getRawIndex(i)].dataIndex = i;
        }
      };
      /**
       * @return {module:echarts/data/Graph}
       */

      Graph.prototype.clone = function () {
        var graph = new Graph(this._directed);
        var nodes = this.nodes;
        var edges = this.edges;

        for (var i = 0; i < nodes.length; i++) {
          graph.addNode(nodes[i].id, nodes[i].dataIndex);
        }

        for (var i = 0; i < edges.length; i++) {
          var e = edges[i];
          graph.addEdge(e.node1.id, e.node2.id, e.dataIndex);
        }

        return graph;
      };
      return Graph;
    }();

    var GraphNode =
    /** @class */
    function () {
      function GraphNode(id, dataIndex) {
        this.inEdges = [];
        this.outEdges = [];
        this.edges = [];
        this.dataIndex = -1;
        this.id = id == null ? '' : id;
        this.dataIndex = dataIndex == null ? -1 : dataIndex;
      }
      /**
       * @return {number}
       */


      GraphNode.prototype.degree = function () {
        return this.edges.length;
      };
      /**
       * @return {number}
       */


      GraphNode.prototype.inDegree = function () {
        return this.inEdges.length;
      };
      /**
      * @return {number}
      */


      GraphNode.prototype.outDegree = function () {
        return this.outEdges.length;
      };

      GraphNode.prototype.getModel = function (path) {
        if (this.dataIndex < 0) {
          return;
        }

        var graph = this.hostGraph;
        var itemModel = graph.data.getItemModel(this.dataIndex);
        return itemModel.getModel(path);
      };

      GraphNode.prototype.getAdjacentDataIndices = function () {
        var dataIndices = {
          edge: [],
          node: []
        };

        for (var i = 0; i < this.edges.length; i++) {
          var adjacentEdge = this.edges[i];

          if (adjacentEdge.dataIndex < 0) {
            continue;
          }

          dataIndices.edge.push(adjacentEdge.dataIndex);
          dataIndices.node.push(adjacentEdge.node1.dataIndex, adjacentEdge.node2.dataIndex);
        }

        return dataIndices;
      };

      return GraphNode;
    }();

    var GraphEdge =
    /** @class */
    function () {
      function GraphEdge(n1, n2, dataIndex) {
        this.dataIndex = -1;
        this.node1 = n1;
        this.node2 = n2;
        this.dataIndex = dataIndex == null ? -1 : dataIndex;
      } // eslint-disable-next-line @typescript-eslint/no-unused-vars


      GraphEdge.prototype.getModel = function (path) {
        if (this.dataIndex < 0) {
          return;
        }

        var graph = this.hostGraph;
        var itemModel = graph.edgeData.getItemModel(this.dataIndex);
        return itemModel.getModel(path);
      };

      GraphEdge.prototype.getAdjacentDataIndices = function () {
        return {
          edge: [this.dataIndex],
          node: [this.node1.dataIndex, this.node2.dataIndex]
        };
      };

      return GraphEdge;
    }();

    function createGraphDataProxyMixin(hostName, dataName) {
      return {
        /**
         * @param Default 'value'. can be 'a', 'b', 'c', 'd', 'e'.
         */
        getValue: function (dimension) {
          var data = this[hostName][dataName];
          return data.getStore().get(data.getDimensionIndex(dimension || 'value'), this.dataIndex);
        },
        // TODO: TYPE stricter type.
        setVisual: function (key, value) {
          this.dataIndex >= 0 && this[hostName][dataName].setItemVisual(this.dataIndex, key, value);
        },
        getVisual: function (key) {
          return this[hostName][dataName].getItemVisual(this.dataIndex, key);
        },
        setLayout: function (layout, merge) {
          this.dataIndex >= 0 && this[hostName][dataName].setItemLayout(this.dataIndex, layout, merge);
        },
        getLayout: function () {
          return this[hostName][dataName].getItemLayout(this.dataIndex);
        },
        getGraphicEl: function () {
          return this[hostName][dataName].getItemGraphicEl(this.dataIndex);
        },
        getRawIndex: function () {
          return this[hostName][dataName].getRawIndex(this.dataIndex);
        }
      };
    }
    mixin(GraphNode, createGraphDataProxyMixin('hostGraph', 'data'));
    mixin(GraphEdge, createGraphDataProxyMixin('hostGraph', 'edgeData'));

    function createGraphFromNodeEdge(nodes, edges, seriesModel, directed, beforeLink) {
      // ??? TODO
      // support dataset?
      var graph = new Graph(directed);

      for (var i = 0; i < nodes.length; i++) {
        graph.addNode(retrieve( // Id, name, dataIndex
        nodes[i].id, nodes[i].name, i), i);
      }

      var linkNameList = [];
      var validEdges = [];
      var linkCount = 0;

      for (var i = 0; i < edges.length; i++) {
        var link = edges[i];
        var source = link.source;
        var target = link.target; // addEdge may fail when source or target not exists

        if (graph.addEdge(source, target, linkCount)) {
          validEdges.push(link);
          linkNameList.push(retrieve(convertOptionIdName(link.id, null), source + ' > ' + target));
          linkCount++;
        }
      }

      var coordSys = seriesModel.get('coordinateSystem');
      var nodeData;

      if (coordSys === 'cartesian2d' || coordSys === 'polar') {
        nodeData = createSeriesData(nodes, seriesModel);
      } else {
        var coordSysCtor = CoordinateSystemManager.get(coordSys);
        var coordDimensions = coordSysCtor ? coordSysCtor.dimensions || [] : []; // FIXME: Some geo do not need `value` dimenson, whereas `calendar` needs
        // `value` dimension, but graph need `value` dimension. It's better to
        // uniform this behavior.

        if (indexOf(coordDimensions, 'value') < 0) {
          coordDimensions.concat(['value']);
        }

        var dimensions = prepareSeriesDataSchema(nodes, {
          coordDimensions: coordDimensions,
          encodeDefine: seriesModel.getEncode()
        }).dimensions;
        nodeData = new SeriesData(dimensions, seriesModel);
        nodeData.initData(nodes);
      }

      var edgeData = new SeriesData(['value'], seriesModel);
      edgeData.initData(validEdges, linkNameList);
      beforeLink && beforeLink(nodeData, edgeData);
      linkSeriesData({
        mainData: nodeData,
        struct: graph,
        structAttr: 'graph',
        datas: {
          node: nodeData,
          edge: edgeData
        },
        datasAttr: {
          node: 'data',
          edge: 'edgeData'
        }
      }); // Update dataIndex of nodes and edges because invalid edge may be removed

      graph.update();
      return graph;
    }

    var GraphSeriesModel =
    /** @class */
    function (_super) {
      __extends(GraphSeriesModel, _super);

      function GraphSeriesModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = GraphSeriesModel.type;
        _this.hasSymbolVisual = true;
        return _this;
      }

      GraphSeriesModel.prototype.init = function (option) {
        _super.prototype.init.apply(this, arguments);

        var self = this;

        function getCategoriesData() {
          return self._categoriesData;
        } // Provide data for legend select


        this.legendVisualProvider = new LegendVisualProvider(getCategoriesData, getCategoriesData);
        this.fillDataTextStyle(option.edges || option.links);

        this._updateCategoriesData();
      };

      GraphSeriesModel.prototype.mergeOption = function (option) {
        _super.prototype.mergeOption.apply(this, arguments);

        this.fillDataTextStyle(option.edges || option.links);

        this._updateCategoriesData();
      };

      GraphSeriesModel.prototype.mergeDefaultAndTheme = function (option) {
        _super.prototype.mergeDefaultAndTheme.apply(this, arguments);

        defaultEmphasis(option, 'edgeLabel', ['show']);
      };

      GraphSeriesModel.prototype.getInitialData = function (option, ecModel) {
        var edges = option.edges || option.links || [];
        var nodes = option.data || option.nodes || [];
        var self = this;

        if (nodes && edges) {
          // auto curveness
          initCurvenessList(this);
          var graph = createGraphFromNodeEdge(nodes, edges, this, true, beforeLink);
          each(graph.edges, function (edge) {
            createEdgeMapForCurveness(edge.node1, edge.node2, this, edge.dataIndex);
          }, this);
          return graph.data;
        }

        function beforeLink(nodeData, edgeData) {
          // Overwrite nodeData.getItemModel to
          nodeData.wrapMethod('getItemModel', function (model) {
            var categoriesModels = self._categoriesModels;
            var categoryIdx = model.getShallow('category');
            var categoryModel = categoriesModels[categoryIdx];

            if (categoryModel) {
              categoryModel.parentModel = model.parentModel;
              model.parentModel = categoryModel;
            }

            return model;
          }); // TODO Inherit resolveParentPath by default in Model#getModel?

          var oldGetModel = Model.prototype.getModel;

          function newGetModel(path, parentModel) {
            var model = oldGetModel.call(this, path, parentModel);
            model.resolveParentPath = resolveParentPath;
            return model;
          }

          edgeData.wrapMethod('getItemModel', function (model) {
            model.resolveParentPath = resolveParentPath;
            model.getModel = newGetModel;
            return model;
          });

          function resolveParentPath(pathArr) {
            if (pathArr && (pathArr[0] === 'label' || pathArr[1] === 'label')) {
              var newPathArr = pathArr.slice();

              if (pathArr[0] === 'label') {
                newPathArr[0] = 'edgeLabel';
              } else if (pathArr[1] === 'label') {
                newPathArr[1] = 'edgeLabel';
              }

              return newPathArr;
            }

            return pathArr;
          }
        }
      };

      GraphSeriesModel.prototype.getGraph = function () {
        return this.getData().graph;
      };

      GraphSeriesModel.prototype.getEdgeData = function () {
        return this.getGraph().edgeData;
      };

      GraphSeriesModel.prototype.getCategoriesData = function () {
        return this._categoriesData;
      };

      GraphSeriesModel.prototype.formatTooltip = function (dataIndex, multipleSeries, dataType) {
        if (dataType === 'edge') {
          var nodeData = this.getData();
          var params = this.getDataParams(dataIndex, dataType);
          var edge = nodeData.graph.getEdgeByIndex(dataIndex);
          var sourceName = nodeData.getName(edge.node1.dataIndex);
          var targetName = nodeData.getName(edge.node2.dataIndex);
          var nameArr = [];
          sourceName != null && nameArr.push(sourceName);
          targetName != null && nameArr.push(targetName);
          return createTooltipMarkup('nameValue', {
            name: nameArr.join(' > '),
            value: params.value,
            noValue: params.value == null
          });
        } // dataType === 'node' or empty


        var nodeMarkup = defaultSeriesFormatTooltip({
          series: this,
          dataIndex: dataIndex,
          multipleSeries: multipleSeries
        });
        return nodeMarkup;
      };

      GraphSeriesModel.prototype._updateCategoriesData = function () {
        var categories = map(this.option.categories || [], function (category) {
          // Data must has value
          return category.value != null ? category : extend({
            value: 0
          }, category);
        });
        var categoriesData = new SeriesData(['value'], this);
        categoriesData.initData(categories);
        this._categoriesData = categoriesData;
        this._categoriesModels = categoriesData.mapArray(function (idx) {
          return categoriesData.getItemModel(idx);
        });
      };

      GraphSeriesModel.prototype.setZoom = function (zoom) {
        this.option.zoom = zoom;
      };

      GraphSeriesModel.prototype.setCenter = function (center) {
        this.option.center = center;
      };

      GraphSeriesModel.prototype.isAnimationEnabled = function () {
        return _super.prototype.isAnimationEnabled.call(this) // Not enable animation when do force layout
        && !(this.get('layout') === 'force' && this.get(['force', 'layoutAnimation']));
      };

      GraphSeriesModel.type = 'series.graph';
      GraphSeriesModel.dependencies = ['grid', 'polar', 'geo', 'singleAxis', 'calendar'];
      GraphSeriesModel.defaultOption = {
        // zlevel: 0,
        z: 2,
        coordinateSystem: 'view',
        // Default option for all coordinate systems
        // xAxisIndex: 0,
        // yAxisIndex: 0,
        // polarIndex: 0,
        // geoIndex: 0,
        legendHoverLink: true,
        layout: null,
        // Configuration of circular layout
        circular: {
          rotateLabel: false
        },
        // Configuration of force directed layout
        force: {
          initLayout: null,
          // Node repulsion. Can be an array to represent range.
          repulsion: [0, 50],
          gravity: 0.1,
          // Initial friction
          friction: 0.6,
          // Edge length. Can be an array to represent range.
          edgeLength: 30,
          layoutAnimation: true
        },
        left: 'center',
        top: 'center',
        // right: null,
        // bottom: null,
        // width: '80%',
        // height: '80%',
        symbol: 'circle',
        symbolSize: 10,
        edgeSymbol: ['none', 'none'],
        edgeSymbolSize: 10,
        edgeLabel: {
          position: 'middle',
          distance: 5
        },
        draggable: false,
        roam: false,
        // Default on center of graph
        center: null,
        zoom: 1,
        // Symbol size scale ratio in roam
        nodeScaleRatio: 0.6,
        // cursor: null,
        // categories: [],
        // data: []
        // Or
        // nodes: []
        //
        // links: []
        // Or
        // edges: []
        label: {
          show: false,
          formatter: '{b}'
        },
        itemStyle: {},
        lineStyle: {
          color: '#aaa',
          width: 1,
          opacity: 0.5
        },
        emphasis: {
          scale: true,
          label: {
            show: true
          }
        },
        select: {
          itemStyle: {
            borderColor: '#212121'
          }
        }
      };
      return GraphSeriesModel;
    }(SeriesModel);

    var actionInfo = {
      type: 'graphRoam',
      event: 'graphRoam',
      update: 'none'
    };
    function install$d(registers) {
      registers.registerChartView(GraphView);
      registers.registerSeriesModel(GraphSeriesModel);
      registers.registerProcessor(categoryFilter);
      registers.registerVisual(categoryVisual);
      registers.registerVisual(graphEdgeVisual);
      registers.registerLayout(graphSimpleLayout);
      registers.registerLayout(registers.PRIORITY.VISUAL.POST_CHART_LAYOUT, graphCircularLayout);
      registers.registerLayout(graphForceLayout);
      registers.registerCoordinateSystem('graphView', {
        dimensions: View.dimensions,
        create: createViewCoordSys
      }); // Register legacy focus actions

      registers.registerAction({
        type: 'focusNodeAdjacency',
        event: 'focusNodeAdjacency',
        update: 'series:focusNodeAdjacency'
      }, noop);
      registers.registerAction({
        type: 'unfocusNodeAdjacency',
        event: 'unfocusNodeAdjacency',
        update: 'series:unfocusNodeAdjacency'
      }, noop); // Register roam action.

      registers.registerAction(actionInfo, function (payload, ecModel, api) {
        ecModel.eachComponent({
          mainType: 'series',
          query: payload
        }, function (seriesModel) {
          var coordSys = seriesModel.coordinateSystem;
          var res = updateCenterAndZoom(coordSys, payload, undefined, api);
          seriesModel.setCenter && seriesModel.setCenter(res.center);
          seriesModel.setZoom && seriesModel.setZoom(res.zoom);
        });
      });
    }

    var PointerShape =
    /** @class */
    function () {
      function PointerShape() {
        this.angle = 0;
        this.width = 10;
        this.r = 10;
        this.x = 0;
        this.y = 0;
      }

      return PointerShape;
    }();

    var PointerPath =
    /** @class */
    function (_super) {
      __extends(PointerPath, _super);

      function PointerPath(opts) {
        var _this = _super.call(this, opts) || this;

        _this.type = 'pointer';
        return _this;
      }

      PointerPath.prototype.getDefaultShape = function () {
        return new PointerShape();
      };

      PointerPath.prototype.buildPath = function (ctx, shape) {
        var mathCos = Math.cos;
        var mathSin = Math.sin;
        var r = shape.r;
        var width = shape.width;
        var angle = shape.angle;
        var x = shape.x - mathCos(angle) * width * (width >= r / 3 ? 1 : 2);
        var y = shape.y - mathSin(angle) * width * (width >= r / 3 ? 1 : 2);
        angle = shape.angle - Math.PI / 2;
        ctx.moveTo(x, y);
        ctx.lineTo(shape.x + mathCos(angle) * width, shape.y + mathSin(angle) * width);
        ctx.lineTo(shape.x + mathCos(shape.angle) * r, shape.y + mathSin(shape.angle) * r);
        ctx.lineTo(shape.x - mathCos(angle) * width, shape.y - mathSin(angle) * width);
        ctx.lineTo(x, y);
      };

      return PointerPath;
    }(Path);

    function parsePosition(seriesModel, api) {
      var center = seriesModel.get('center');
      var width = api.getWidth();
      var height = api.getHeight();
      var size = Math.min(width, height);
      var cx = parsePercent$1(center[0], api.getWidth());
      var cy = parsePercent$1(center[1], api.getHeight());
      var r = parsePercent$1(seriesModel.get('radius'), size / 2);
      return {
        cx: cx,
        cy: cy,
        r: r
      };
    }

    function formatLabel(value, labelFormatter) {
      var label = value == null ? '' : value + '';

      if (labelFormatter) {
        if (isString(labelFormatter)) {
          label = labelFormatter.replace('{value}', label);
        } else if (isFunction(labelFormatter)) {
          label = labelFormatter(value);
        }
      }

      return label;
    }

    var GaugeView =
    /** @class */
    function (_super) {
      __extends(GaugeView, _super);

      function GaugeView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = GaugeView.type;
        return _this;
      }

      GaugeView.prototype.render = function (seriesModel, ecModel, api) {
        this.group.removeAll();
        var colorList = seriesModel.get(['axisLine', 'lineStyle', 'color']);
        var posInfo = parsePosition(seriesModel, api);

        this._renderMain(seriesModel, ecModel, api, colorList, posInfo);

        this._data = seriesModel.getData();
      };

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

      GaugeView.prototype._renderMain = function (seriesModel, ecModel, api, colorList, posInfo) {
        var group = this.group;
        var clockwise = seriesModel.get('clockwise');
        var startAngle = -seriesModel.get('startAngle') / 180 * Math.PI;
        var endAngle = -seriesModel.get('endAngle') / 180 * Math.PI;
        var axisLineModel = seriesModel.getModel('axisLine');
        var roundCap = axisLineModel.get('roundCap');
        var MainPath = roundCap ? SausagePath : Sector;
        var showAxis = axisLineModel.get('show');
        var lineStyleModel = axisLineModel.getModel('lineStyle');
        var axisLineWidth = lineStyleModel.get('width');
        var angles = [startAngle, endAngle];
        normalizeArcAngles(angles, !clockwise);
        startAngle = angles[0];
        endAngle = angles[1];
        var angleRangeSpan = endAngle - startAngle;
        var prevEndAngle = startAngle;
        var sectors = [];

        for (var i = 0; showAxis && i < colorList.length; i++) {
          // Clamp
          var percent = Math.min(Math.max(colorList[i][0], 0), 1);
          endAngle = startAngle + angleRangeSpan * percent;
          var sector = new MainPath({
            shape: {
              startAngle: prevEndAngle,
              endAngle: endAngle,
              cx: posInfo.cx,
              cy: posInfo.cy,
              clockwise: clockwise,
              r0: posInfo.r - axisLineWidth,
              r: posInfo.r
            },
            silent: true
          });
          sector.setStyle({
            fill: colorList[i][1]
          });
          sector.setStyle(lineStyleModel.getLineStyle( // Because we use sector to simulate arc
          // so the properties for stroking are useless
          ['color', 'width']));
          sectors.push(sector);
          prevEndAngle = endAngle;
        }

        sectors.reverse();
        each(sectors, function (sector) {
          return group.add(sector);
        });

        var getColor = function (percent) {
          // Less than 0
          if (percent <= 0) {
            return colorList[0][1];
          }

          var i;

          for (i = 0; i < colorList.length; i++) {
            if (colorList[i][0] >= percent && (i === 0 ? 0 : colorList[i - 1][0]) < percent) {
              return colorList[i][1];
            }
          } // More than 1


          return colorList[i - 1][1];
        };

        this._renderTicks(seriesModel, ecModel, api, getColor, posInfo, startAngle, endAngle, clockwise, axisLineWidth);

        this._renderTitleAndDetail(seriesModel, ecModel, api, getColor, posInfo);

        this._renderAnchor(seriesModel, posInfo);

        this._renderPointer(seriesModel, ecModel, api, getColor, posInfo, startAngle, endAngle, clockwise, axisLineWidth);
      };

      GaugeView.prototype._renderTicks = function (seriesModel, ecModel, api, getColor, posInfo, startAngle, endAngle, clockwise, axisLineWidth) {
        var group = this.group;
        var cx = posInfo.cx;
        var cy = posInfo.cy;
        var r = posInfo.r;
        var minVal = +seriesModel.get('min');
        var maxVal = +seriesModel.get('max');
        var splitLineModel = seriesModel.getModel('splitLine');
        var tickModel = seriesModel.getModel('axisTick');
        var labelModel = seriesModel.getModel('axisLabel');
        var splitNumber = seriesModel.get('splitNumber');
        var subSplitNumber = tickModel.get('splitNumber');
        var splitLineLen = parsePercent$1(splitLineModel.get('length'), r);
        var tickLen = parsePercent$1(tickModel.get('length'), r);
        var angle = startAngle;
        var step = (endAngle - startAngle) / splitNumber;
        var subStep = step / subSplitNumber;
        var splitLineStyle = splitLineModel.getModel('lineStyle').getLineStyle();
        var tickLineStyle = tickModel.getModel('lineStyle').getLineStyle();
        var splitLineDistance = splitLineModel.get('distance');
        var unitX;
        var unitY;

        for (var i = 0; i <= splitNumber; i++) {
          unitX = Math.cos(angle);
          unitY = Math.sin(angle); // Split line

          if (splitLineModel.get('show')) {
            var distance = splitLineDistance ? splitLineDistance + axisLineWidth : axisLineWidth;
            var splitLine = new Line({
              shape: {
                x1: unitX * (r - distance) + cx,
                y1: unitY * (r - distance) + cy,
                x2: unitX * (r - splitLineLen - distance) + cx,
                y2: unitY * (r - splitLineLen - distance) + cy
              },
              style: splitLineStyle,
              silent: true
            });

            if (splitLineStyle.stroke === 'auto') {
              splitLine.setStyle({
                stroke: getColor(i / splitNumber)
              });
            }

            group.add(splitLine);
          } // Label


          if (labelModel.get('show')) {
            var distance = labelModel.get('distance') + splitLineDistance;
            var label = formatLabel(round(i / splitNumber * (maxVal - minVal) + minVal), labelModel.get('formatter'));
            var autoColor = getColor(i / splitNumber);
            var textStyleX = unitX * (r - splitLineLen - distance) + cx;
            var textStyleY = unitY * (r - splitLineLen - distance) + cy;
            var rotateType = labelModel.get('rotate');
            var rotate = 0;

            if (rotateType === 'radial') {
              rotate = -angle + 2 * Math.PI;

              if (rotate > Math.PI / 2) {
                rotate += Math.PI;
              }
            } else if (rotateType === 'tangential') {
              rotate = -angle - Math.PI / 2;
            } else if (isNumber(rotateType)) {
              rotate = rotateType * Math.PI / 180;
            }

            if (rotate === 0) {
              group.add(new ZRText({
                style: createTextStyle(labelModel, {
                  text: label,
                  x: textStyleX,
                  y: textStyleY,
                  verticalAlign: unitY < -0.8 ? 'top' : unitY > 0.8 ? 'bottom' : 'middle',
                  align: unitX < -0.4 ? 'left' : unitX > 0.4 ? 'right' : 'center'
                }, {
                  inheritColor: autoColor
                }),
                silent: true
              }));
            } else {
              group.add(new ZRText({
                style: createTextStyle(labelModel, {
                  text: label,
                  x: textStyleX,
                  y: textStyleY,
                  verticalAlign: 'middle',
                  align: 'center'
                }, {
                  inheritColor: autoColor
                }),
                silent: true,
                originX: textStyleX,
                originY: textStyleY,
                rotation: rotate
              }));
            }
          } // Axis tick


          if (tickModel.get('show') && i !== splitNumber) {
            var distance = tickModel.get('distance');
            distance = distance ? distance + axisLineWidth : axisLineWidth;

            for (var j = 0; j <= subSplitNumber; j++) {
              unitX = Math.cos(angle);
              unitY = Math.sin(angle);
              var tickLine = new Line({
                shape: {
                  x1: unitX * (r - distance) + cx,
                  y1: unitY * (r - distance) + cy,
                  x2: unitX * (r - tickLen - distance) + cx,
                  y2: unitY * (r - tickLen - distance) + cy
                },
                silent: true,
                style: tickLineStyle
              });

              if (tickLineStyle.stroke === 'auto') {
                tickLine.setStyle({
                  stroke: getColor((i + j / subSplitNumber) / splitNumber)
                });
              }

              group.add(tickLine);
              angle += subStep;
            }

            angle -= subStep;
          } else {
            angle += step;
          }
        }
      };

      GaugeView.prototype._renderPointer = function (seriesModel, ecModel, api, getColor, posInfo, startAngle, endAngle, clockwise, axisLineWidth) {
        var group = this.group;
        var oldData = this._data;
        var oldProgressData = this._progressEls;
        var progressList = [];
        var showPointer = seriesModel.get(['pointer', 'show']);
        var progressModel = seriesModel.getModel('progress');
        var showProgress = progressModel.get('show');
        var data = seriesModel.getData();
        var valueDim = data.mapDimension('value');
        var minVal = +seriesModel.get('min');
        var maxVal = +seriesModel.get('max');
        var valueExtent = [minVal, maxVal];
        var angleExtent = [startAngle, endAngle];

        function createPointer(idx, angle) {
          var itemModel = data.getItemModel(idx);
          var pointerModel = itemModel.getModel('pointer');
          var pointerWidth = parsePercent$1(pointerModel.get('width'), posInfo.r);
          var pointerLength = parsePercent$1(pointerModel.get('length'), posInfo.r);
          var pointerStr = seriesModel.get(['pointer', 'icon']);
          var pointerOffset = pointerModel.get('offsetCenter');
          var pointerOffsetX = parsePercent$1(pointerOffset[0], posInfo.r);
          var pointerOffsetY = parsePercent$1(pointerOffset[1], posInfo.r);
          var pointerKeepAspect = pointerModel.get('keepAspect');
          var pointer; // not exist icon type will be set 'rect'

          if (pointerStr) {
            pointer = createSymbol(pointerStr, pointerOffsetX - pointerWidth / 2, pointerOffsetY - pointerLength, pointerWidth, pointerLength, null, pointerKeepAspect);
          } else {
            pointer = new PointerPath({
              shape: {
                angle: -Math.PI / 2,
                width: pointerWidth,
                r: pointerLength,
                x: pointerOffsetX,
                y: pointerOffsetY
              }
            });
          }

          pointer.rotation = -(angle + Math.PI / 2);
          pointer.x = posInfo.cx;
          pointer.y = posInfo.cy;
          return pointer;
        }

        function createProgress(idx, endAngle) {
          var roundCap = progressModel.get('roundCap');
          var ProgressPath = roundCap ? SausagePath : Sector;
          var isOverlap = progressModel.get('overlap');
          var progressWidth = isOverlap ? progressModel.get('width') : axisLineWidth / data.count();
          var r0 = isOverlap ? posInfo.r - progressWidth : posInfo.r - (idx + 1) * progressWidth;
          var r = isOverlap ? posInfo.r : posInfo.r - idx * progressWidth;
          var progress = new ProgressPath({
            shape: {
              startAngle: startAngle,
              endAngle: endAngle,
              cx: posInfo.cx,
              cy: posInfo.cy,
              clockwise: clockwise,
              r0: r0,
              r: r
            }
          });
          isOverlap && (progress.z2 = maxVal - data.get(valueDim, idx) % maxVal);
          return progress;
        }

        if (showProgress || showPointer) {
          data.diff(oldData).add(function (idx) {
            var val = data.get(valueDim, idx);

            if (showPointer) {
              var pointer = createPointer(idx, startAngle); // TODO hide pointer on NaN value?

              initProps(pointer, {
                rotation: -((isNaN(+val) ? angleExtent[0] : linearMap(val, valueExtent, angleExtent, true)) + Math.PI / 2)
              }, seriesModel);
              group.add(pointer);
              data.setItemGraphicEl(idx, pointer);
            }

            if (showProgress) {
              var progress = createProgress(idx, startAngle);
              var isClip = progressModel.get('clip');
              initProps(progress, {
                shape: {
                  endAngle: linearMap(val, valueExtent, angleExtent, isClip)
                }
              }, seriesModel);
              group.add(progress); // Add data index and series index for indexing the data by element
              // Useful in tooltip

              setCommonECData(seriesModel.seriesIndex, data.dataType, idx, progress);
              progressList[idx] = progress;
            }
          }).update(function (newIdx, oldIdx) {
            var val = data.get(valueDim, newIdx);

            if (showPointer) {
              var previousPointer = oldData.getItemGraphicEl(oldIdx);
              var previousRotate = previousPointer ? previousPointer.rotation : startAngle;
              var pointer = createPointer(newIdx, previousRotate);
              pointer.rotation = previousRotate;
              updateProps(pointer, {
                rotation: -((isNaN(+val) ? angleExtent[0] : linearMap(val, valueExtent, angleExtent, true)) + Math.PI / 2)
              }, seriesModel);
              group.add(pointer);
              data.setItemGraphicEl(newIdx, pointer);
            }

            if (showProgress) {
              var previousProgress = oldProgressData[oldIdx];
              var previousEndAngle = previousProgress ? previousProgress.shape.endAngle : startAngle;
              var progress = createProgress(newIdx, previousEndAngle);
              var isClip = progressModel.get('clip');
              updateProps(progress, {
                shape: {
                  endAngle: linearMap(val, valueExtent, angleExtent, isClip)
                }
              }, seriesModel);
              group.add(progress); // Add data index and series index for indexing the data by element
              // Useful in tooltip

              setCommonECData(seriesModel.seriesIndex, data.dataType, newIdx, progress);
              progressList[newIdx] = progress;
            }
          }).execute();
          data.each(function (idx) {
            var itemModel = data.getItemModel(idx);
            var emphasisModel = itemModel.getModel('emphasis');
            var focus = emphasisModel.get('focus');
            var blurScope = emphasisModel.get('blurScope');
            var emphasisDisabled = emphasisModel.get('disabled');

            if (showPointer) {
              var pointer = data.getItemGraphicEl(idx);
              var symbolStyle = data.getItemVisual(idx, 'style');
              var visualColor = symbolStyle.fill;

              if (pointer instanceof ZRImage) {
                var pathStyle = pointer.style;
                pointer.useStyle(extend({
                  image: pathStyle.image,
                  x: pathStyle.x,
                  y: pathStyle.y,
                  width: pathStyle.width,
                  height: pathStyle.height
                }, symbolStyle));
              } else {
                pointer.useStyle(symbolStyle);
                pointer.type !== 'pointer' && pointer.setColor(visualColor);
              }

              pointer.setStyle(itemModel.getModel(['pointer', 'itemStyle']).getItemStyle());

              if (pointer.style.fill === 'auto') {
                pointer.setStyle('fill', getColor(linearMap(data.get(valueDim, idx), valueExtent, [0, 1], true)));
              }

              pointer.z2EmphasisLift = 0;
              setStatesStylesFromModel(pointer, itemModel);
              toggleHoverEmphasis(pointer, focus, blurScope, emphasisDisabled);
            }

            if (showProgress) {
              var progress = progressList[idx];
              progress.useStyle(data.getItemVisual(idx, 'style'));
              progress.setStyle(itemModel.getModel(['progress', 'itemStyle']).getItemStyle());
              progress.z2EmphasisLift = 0;
              setStatesStylesFromModel(progress, itemModel);
              toggleHoverEmphasis(progress, focus, blurScope, emphasisDisabled);
            }
          });
          this._progressEls = progressList;
        }
      };

      GaugeView.prototype._renderAnchor = function (seriesModel, posInfo) {
        var anchorModel = seriesModel.getModel('anchor');
        var showAnchor = anchorModel.get('show');

        if (showAnchor) {
          var anchorSize = anchorModel.get('size');
          var anchorType = anchorModel.get('icon');
          var offsetCenter = anchorModel.get('offsetCenter');
          var anchorKeepAspect = anchorModel.get('keepAspect');
          var anchor = createSymbol(anchorType, posInfo.cx - anchorSize / 2 + parsePercent$1(offsetCenter[0], posInfo.r), posInfo.cy - anchorSize / 2 + parsePercent$1(offsetCenter[1], posInfo.r), anchorSize, anchorSize, null, anchorKeepAspect);
          anchor.z2 = anchorModel.get('showAbove') ? 1 : 0;
          anchor.setStyle(anchorModel.getModel('itemStyle').getItemStyle());
          this.group.add(anchor);
        }
      };

      GaugeView.prototype._renderTitleAndDetail = function (seriesModel, ecModel, api, getColor, posInfo) {
        var _this = this;

        var data = seriesModel.getData();
        var valueDim = data.mapDimension('value');
        var minVal = +seriesModel.get('min');
        var maxVal = +seriesModel.get('max');
        var contentGroup = new Group();
        var newTitleEls = [];
        var newDetailEls = [];
        var hasAnimation = seriesModel.isAnimationEnabled();
        var showPointerAbove = seriesModel.get(['pointer', 'showAbove']);
        data.diff(this._data).add(function (idx) {
          newTitleEls[idx] = new ZRText({
            silent: true
          });
          newDetailEls[idx] = new ZRText({
            silent: true
          });
        }).update(function (idx, oldIdx) {
          newTitleEls[idx] = _this._titleEls[oldIdx];
          newDetailEls[idx] = _this._detailEls[oldIdx];
        }).execute();
        data.each(function (idx) {
          var itemModel = data.getItemModel(idx);
          var value = data.get(valueDim, idx);
          var itemGroup = new Group();
          var autoColor = getColor(linearMap(value, [minVal, maxVal], [0, 1], true));
          var itemTitleModel = itemModel.getModel('title');

          if (itemTitleModel.get('show')) {
            var titleOffsetCenter = itemTitleModel.get('offsetCenter');
            var titleX = posInfo.cx + parsePercent$1(titleOffsetCenter[0], posInfo.r);
            var titleY = posInfo.cy + parsePercent$1(titleOffsetCenter[1], posInfo.r);
            var labelEl = newTitleEls[idx];
            labelEl.attr({
              z2: showPointerAbove ? 0 : 2,
              style: createTextStyle(itemTitleModel, {
                x: titleX,
                y: titleY,
                text: data.getName(idx),
                align: 'center',
                verticalAlign: 'middle'
              }, {
                inheritColor: autoColor
              })
            });
            itemGroup.add(labelEl);
          }

          var itemDetailModel = itemModel.getModel('detail');

          if (itemDetailModel.get('show')) {
            var detailOffsetCenter = itemDetailModel.get('offsetCenter');
            var detailX = posInfo.cx + parsePercent$1(detailOffsetCenter[0], posInfo.r);
            var detailY = posInfo.cy + parsePercent$1(detailOffsetCenter[1], posInfo.r);
            var width = parsePercent$1(itemDetailModel.get('width'), posInfo.r);
            var height = parsePercent$1(itemDetailModel.get('height'), posInfo.r);
            var detailColor = seriesModel.get(['progress', 'show']) ? data.getItemVisual(idx, 'style').fill : autoColor;
            var labelEl = newDetailEls[idx];
            var formatter_1 = itemDetailModel.get('formatter');
            labelEl.attr({
              z2: showPointerAbove ? 0 : 2,
              style: createTextStyle(itemDetailModel, {
                x: detailX,
                y: detailY,
                text: formatLabel(value, formatter_1),
                width: isNaN(width) ? null : width,
                height: isNaN(height) ? null : height,
                align: 'center',
                verticalAlign: 'middle'
              }, {
                inheritColor: detailColor
              })
            });
            setLabelValueAnimation(labelEl, {
              normal: itemDetailModel
            }, value, function (value) {
              return formatLabel(value, formatter_1);
            });
            hasAnimation && animateLabelValue(labelEl, idx, data, seriesModel, {
              getFormattedLabel: function (labelDataIndex, status, dataType, labelDimIndex, fmt, extendParams) {
                return formatLabel(extendParams ? extendParams.interpolatedValue : value, formatter_1);
              }
            });
            itemGroup.add(labelEl);
          }

          contentGroup.add(itemGroup);
        });
        this.group.add(contentGroup);
        this._titleEls = newTitleEls;
        this._detailEls = newDetailEls;
      };

      GaugeView.type = 'gauge';
      return GaugeView;
    }(ChartView);

    var GaugeSeriesModel =
    /** @class */
    function (_super) {
      __extends(GaugeSeriesModel, _super);

      function GaugeSeriesModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = GaugeSeriesModel.type;
        _this.visualStyleAccessPath = 'itemStyle';
        return _this;
      }

      GaugeSeriesModel.prototype.getInitialData = function (option, ecModel) {
        return createSeriesDataSimply(this, ['value']);
      };

      GaugeSeriesModel.type = 'series.gauge';
      GaugeSeriesModel.defaultOption = {
        // zlevel: 0,
        z: 2,
        colorBy: 'data',
        // 默认全局居中
        center: ['50%', '50%'],
        legendHoverLink: true,
        radius: '75%',
        startAngle: 225,
        endAngle: -45,
        clockwise: true,
        // 最小值
        min: 0,
        // 最大值
        max: 100,
        // 分割段数，默认为10
        splitNumber: 10,
        // 坐标轴线
        axisLine: {
          // 默认显示，属性show控制显示与否
          show: true,
          roundCap: false,
          lineStyle: {
            color: [[1, '#E6EBF8']],
            width: 10
          }
        },
        // 坐标轴线
        progress: {
          // 默认显示，属性show控制显示与否
          show: false,
          overlap: true,
          width: 10,
          roundCap: false,
          clip: true
        },
        // 分隔线
        splitLine: {
          // 默认显示，属性show控制显示与否
          show: true,
          // 属性length控制线长
          length: 10,
          distance: 10,
          // 属性lineStyle（详见lineStyle）控制线条样式
          lineStyle: {
            color: '#63677A',
            width: 3,
            type: 'solid'
          }
        },
        // 坐标轴小标记
        axisTick: {
          // 属性show控制显示与否，默认不显示
          show: true,
          // 每份split细分多少段
          splitNumber: 5,
          // 属性length控制线长
          length: 6,
          distance: 10,
          // 属性lineStyle控制线条样式
          lineStyle: {
            color: '#63677A',
            width: 1,
            type: 'solid'
          }
        },
        axisLabel: {
          show: true,
          distance: 15,
          // formatter: null,
          color: '#464646',
          fontSize: 12,
          rotate: 0
        },
        pointer: {
          icon: null,
          offsetCenter: [0, 0],
          show: true,
          showAbove: true,
          length: '60%',
          width: 6,
          keepAspect: false
        },
        anchor: {
          show: false,
          showAbove: false,
          size: 6,
          icon: 'circle',
          offsetCenter: [0, 0],
          keepAspect: false,
          itemStyle: {
            color: '#fff',
            borderWidth: 0,
            borderColor: '#5470c6'
          }
        },
        title: {
          show: true,
          // x, y，单位px
          offsetCenter: [0, '20%'],
          // 其余属性默认使用全局文本样式，详见TEXTSTYLE
          color: '#464646',
          fontSize: 16,
          valueAnimation: false
        },
        detail: {
          show: true,
          backgroundColor: 'rgba(0,0,0,0)',
          borderWidth: 0,
          borderColor: '#ccc',
          width: 100,
          height: null,
          padding: [5, 10],
          // x, y，单位px
          offsetCenter: [0, '40%'],
          // formatter: null,
          // 其余属性默认使用全局文本样式，详见TEXTSTYLE
          color: '#464646',
          fontSize: 30,
          fontWeight: 'bold',
          lineHeight: 30,
          valueAnimation: false
        }
      };
      return GaugeSeriesModel;
    }(SeriesModel);

    function install$e(registers) {
      registers.registerChartView(GaugeView);
      registers.registerSeriesModel(GaugeSeriesModel);
    }

    var opacityAccessPath = ['itemStyle', 'opacity'];
    /**
     * Piece of pie including Sector, Label, LabelLine
     */

    var FunnelPiece =
    /** @class */
    function (_super) {
      __extends(FunnelPiece, _super);

      function FunnelPiece(data, idx) {
        var _this = _super.call(this) || this;

        var polygon = _this;
        var labelLine = new Polyline();
        var text = new ZRText();
        polygon.setTextContent(text);

        _this.setTextGuideLine(labelLine);

        _this.updateData(data, idx, true);

        return _this;
      }

      FunnelPiece.prototype.updateData = function (data, idx, firstCreate) {
        var polygon = this;
        var seriesModel = data.hostModel;
        var itemModel = data.getItemModel(idx);
        var layout = data.getItemLayout(idx);
        var emphasisModel = itemModel.getModel('emphasis');
        var opacity = itemModel.get(opacityAccessPath);
        opacity = opacity == null ? 1 : opacity;

        if (!firstCreate) {
          saveOldStyle(polygon);
        } // Update common style


        polygon.useStyle(data.getItemVisual(idx, 'style'));
        polygon.style.lineJoin = 'round';

        if (firstCreate) {
          polygon.setShape({
            points: layout.points
          });
          polygon.style.opacity = 0;
          initProps(polygon, {
            style: {
              opacity: opacity
            }
          }, seriesModel, idx);
        } else {
          updateProps(polygon, {
            style: {
              opacity: opacity
            },
            shape: {
              points: layout.points
            }
          }, seriesModel, idx);
        }

        setStatesStylesFromModel(polygon, itemModel);

        this._updateLabel(data, idx);

        toggleHoverEmphasis(this, emphasisModel.get('focus'), emphasisModel.get('blurScope'), emphasisModel.get('disabled'));
      };

      FunnelPiece.prototype._updateLabel = function (data, idx) {
        var polygon = this;
        var labelLine = this.getTextGuideLine();
        var labelText = polygon.getTextContent();
        var seriesModel = data.hostModel;
        var itemModel = data.getItemModel(idx);
        var layout = data.getItemLayout(idx);
        var labelLayout = layout.label;
        var style = data.getItemVisual(idx, 'style');
        var visualColor = style.fill;
        setLabelStyle( // position will not be used in setLabelStyle
        labelText, getLabelStatesModels(itemModel), {
          labelFetcher: data.hostModel,
          labelDataIndex: idx,
          defaultOpacity: style.opacity,
          defaultText: data.getName(idx)
        }, {
          normal: {
            align: labelLayout.textAlign,
            verticalAlign: labelLayout.verticalAlign
          }
        });
        polygon.setTextConfig({
          local: true,
          inside: !!labelLayout.inside,
          insideStroke: visualColor,
          // insideFill: 'auto',
          outsideFill: visualColor
        });
        var linePoints = labelLayout.linePoints;
        labelLine.setShape({
          points: linePoints
        });
        polygon.textGuideLineConfig = {
          anchor: linePoints ? new Point(linePoints[0][0], linePoints[0][1]) : null
        }; // Make sure update style on labelText after setLabelStyle.
        // Because setLabelStyle will replace a new style on it.

        updateProps(labelText, {
          style: {
            x: labelLayout.x,
            y: labelLayout.y
          }
        }, seriesModel, idx);
        labelText.attr({
          rotation: labelLayout.rotation,
          originX: labelLayout.x,
          originY: labelLayout.y,
          z2: 10
        });
        setLabelLineStyle(polygon, getLabelLineStatesModels(itemModel), {
          // Default use item visual color
          stroke: visualColor
        });
      };

      return FunnelPiece;
    }(Polygon);

    var FunnelView =
    /** @class */
    function (_super) {
      __extends(FunnelView, _super);

      function FunnelView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = FunnelView.type;
        _this.ignoreLabelLineUpdate = true;
        return _this;
      }

      FunnelView.prototype.render = function (seriesModel, ecModel, api) {
        var data = seriesModel.getData();
        var oldData = this._data;
        var group = this.group;
        data.diff(oldData).add(function (idx) {
          var funnelPiece = new FunnelPiece(data, idx);
          data.setItemGraphicEl(idx, funnelPiece);
          group.add(funnelPiece);
        }).update(function (newIdx, oldIdx) {
          var piece = oldData.getItemGraphicEl(oldIdx);
          piece.updateData(data, newIdx);
          group.add(piece);
          data.setItemGraphicEl(newIdx, piece);
        }).remove(function (idx) {
          var piece = oldData.getItemGraphicEl(idx);
          removeElementWithFadeOut(piece, seriesModel, idx);
        }).execute();
        this._data = data;
      };

      FunnelView.prototype.remove = function () {
        this.group.removeAll();
        this._data = null;
      };

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

      FunnelView.type = 'funnel';
      return FunnelView;
    }(ChartView);

    var FunnelSeriesModel =
    /** @class */
    function (_super) {
      __extends(FunnelSeriesModel, _super);

      function FunnelSeriesModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = FunnelSeriesModel.type;
        return _this;
      }

      FunnelSeriesModel.prototype.init = function (option) {
        _super.prototype.init.apply(this, 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)); // Extend labelLine emphasis

        this._defaultLabelLine(option);
      };

      FunnelSeriesModel.prototype.getInitialData = function (option, ecModel) {
        return createSeriesDataSimply(this, {
          coordDimensions: ['value'],
          encodeDefaulter: curry(makeSeriesEncodeForNameBased, this)
        });
      };

      FunnelSeriesModel.prototype._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;
      }; // Overwrite


      FunnelSeriesModel.prototype.getDataParams = function (dataIndex) {
        var data = this.getData();

        var params = _super.prototype.getDataParams.call(this, dataIndex);

        var valueDim = data.mapDimension('value');
        var sum = data.getSum(valueDim); // Percent is 0 if sum is 0

        params.percent = !sum ? 0 : +(data.get(valueDim, dataIndex) / sum * 100).toFixed(2);
        params.$vars.push('percent');
        return params;
      };

      FunnelSeriesModel.type = 'series.funnel';
      FunnelSeriesModel.defaultOption = {
        // zlevel: 0,                  // 一级层叠
        z: 2,
        legendHoverLink: true,
        colorBy: 'data',
        left: 80,
        top: 60,
        right: 80,
        bottom: 60,
        // width: {totalWidth} - left - right,
        // height: {totalHeight} - top - bottom,
        // 默认取数据最小最大值
        // min: 0,
        // max: 100,
        minSize: '0%',
        maxSize: '100%',
        sort: 'descending',
        orient: 'vertical',
        gap: 0,
        funnelAlign: 'center',
        label: {
          show: true,
          position: 'outer' // formatter: 标签文本格式器，同Tooltip.formatter，不支持异步回调

        },
        labelLine: {
          show: true,
          length: 20,
          lineStyle: {
            // color: 各异,
            width: 1
          }
        },
        itemStyle: {
          // color: 各异,
          borderColor: '#fff',
          borderWidth: 1
        },
        emphasis: {
          label: {
            show: true
          }
        },
        select: {
          itemStyle: {
            borderColor: '#212121'
          }
        }
      };
      return FunnelSeriesModel;
    }(SeriesModel);

    function getViewRect$3(seriesModel, api) {
      return getLayoutRect(seriesModel.getBoxLayoutParams(), {
        width: api.getWidth(),
        height: api.getHeight()
      });
    }

    function getSortedIndices(data, sort) {
      var valueDim = data.mapDimension('value');
      var valueArr = data.mapArray(valueDim, function (val) {
        return val;
      });
      var indices = [];
      var isAscending = sort === 'ascending';

      for (var i = 0, len = data.count(); i < len; i++) {
        indices[i] = i;
      } // Add custom sortable function & none sortable opetion by "options.sort"


      if (isFunction(sort)) {
        indices.sort(sort);
      } else if (sort !== 'none') {
        indices.sort(function (a, b) {
          return isAscending ? valueArr[a] - valueArr[b] : valueArr[b] - valueArr[a];
        });
      }

      return indices;
    }

    function labelLayout(data) {
      var seriesModel = data.hostModel;
      var orient = seriesModel.get('orient');
      data.each(function (idx) {
        var itemModel = data.getItemModel(idx);
        var labelModel = itemModel.getModel('label');
        var labelPosition = labelModel.get('position');
        var labelLineModel = itemModel.getModel('labelLine');
        var layout = data.getItemLayout(idx);
        var points = layout.points;
        var isLabelInside = labelPosition === 'inner' || labelPosition === 'inside' || labelPosition === 'center' || labelPosition === 'insideLeft' || labelPosition === 'insideRight';
        var textAlign;
        var textX;
        var textY;
        var linePoints;

        if (isLabelInside) {
          if (labelPosition === 'insideLeft') {
            textX = (points[0][0] + points[3][0]) / 2 + 5;
            textY = (points[0][1] + points[3][1]) / 2;
            textAlign = 'left';
          } else if (labelPosition === 'insideRight') {
            textX = (points[1][0] + points[2][0]) / 2 - 5;
            textY = (points[1][1] + points[2][1]) / 2;
            textAlign = 'right';
          } else {
            textX = (points[0][0] + points[1][0] + points[2][0] + points[3][0]) / 4;
            textY = (points[0][1] + points[1][1] + points[2][1] + points[3][1]) / 4;
            textAlign = 'center';
          }

          linePoints = [[textX, textY], [textX, textY]];
        } else {
          var x1 = void 0;
          var y1 = void 0;
          var x2 = void 0;
          var y2 = void 0;
          var labelLineLen = labelLineModel.get('length');

          if ("development" !== 'production') {
            if (orient === 'vertical' && ['top', 'bottom'].indexOf(labelPosition) > -1) {
              labelPosition = 'left';
              console.warn('Position error: Funnel chart on vertical orient dose not support top and bottom.');
            }

            if (orient === 'horizontal' && ['left', 'right'].indexOf(labelPosition) > -1) {
              labelPosition = 'bottom';
              console.warn('Position error: Funnel chart on horizontal orient dose not support left and right.');
            }
          }

          if (labelPosition === 'left') {
            // Left side
            x1 = (points[3][0] + points[0][0]) / 2;
            y1 = (points[3][1] + points[0][1]) / 2;
            x2 = x1 - labelLineLen;
            textX = x2 - 5;
            textAlign = 'right';
          } else if (labelPosition === 'right') {
            // Right side
            x1 = (points[1][0] + points[2][0]) / 2;
            y1 = (points[1][1] + points[2][1]) / 2;
            x2 = x1 + labelLineLen;
            textX = x2 + 5;
            textAlign = 'left';
          } else if (labelPosition === 'top') {
            // Top side
            x1 = (points[3][0] + points[0][0]) / 2;
            y1 = (points[3][1] + points[0][1]) / 2;
            y2 = y1 - labelLineLen;
            textY = y2 - 5;
            textAlign = 'center';
          } else if (labelPosition === 'bottom') {
            // Bottom side
            x1 = (points[1][0] + points[2][0]) / 2;
            y1 = (points[1][1] + points[2][1]) / 2;
            y2 = y1 + labelLineLen;
            textY = y2 + 5;
            textAlign = 'center';
          } else if (labelPosition === 'rightTop') {
            // RightTop side
            x1 = orient === 'horizontal' ? points[3][0] : points[1][0];
            y1 = orient === 'horizontal' ? points[3][1] : points[1][1];

            if (orient === 'horizontal') {
              y2 = y1 - labelLineLen;
              textY = y2 - 5;
              textAlign = 'center';
            } else {
              x2 = x1 + labelLineLen;
              textX = x2 + 5;
              textAlign = 'top';
            }
          } else if (labelPosition === 'rightBottom') {
            // RightBottom side
            x1 = points[2][0];
            y1 = points[2][1];

            if (orient === 'horizontal') {
              y2 = y1 + labelLineLen;
              textY = y2 + 5;
              textAlign = 'center';
            } else {
              x2 = x1 + labelLineLen;
              textX = x2 + 5;
              textAlign = 'bottom';
            }
          } else if (labelPosition === 'leftTop') {
            // LeftTop side
            x1 = points[0][0];
            y1 = orient === 'horizontal' ? points[0][1] : points[1][1];

            if (orient === 'horizontal') {
              y2 = y1 - labelLineLen;
              textY = y2 - 5;
              textAlign = 'center';
            } else {
              x2 = x1 - labelLineLen;
              textX = x2 - 5;
              textAlign = 'right';
            }
          } else if (labelPosition === 'leftBottom') {
            // LeftBottom side
            x1 = orient === 'horizontal' ? points[1][0] : points[3][0];
            y1 = orient === 'horizontal' ? points[1][1] : points[2][1];

            if (orient === 'horizontal') {
              y2 = y1 + labelLineLen;
              textY = y2 + 5;
              textAlign = 'center';
            } else {
              x2 = x1 - labelLineLen;
              textX = x2 - 5;
              textAlign = 'right';
            }
          } else {
            // Right side or Bottom side
            x1 = (points[1][0] + points[2][0]) / 2;
            y1 = (points[1][1] + points[2][1]) / 2;

            if (orient === 'horizontal') {
              y2 = y1 + labelLineLen;
              textY = y2 + 5;
              textAlign = 'center';
            } else {
              x2 = x1 + labelLineLen;
              textX = x2 + 5;
              textAlign = 'left';
            }
          }

          if (orient === 'horizontal') {
            x2 = x1;
            textX = x2;
          } else {
            y2 = y1;
            textY = y2;
          }

          linePoints = [[x1, y1], [x2, y2]];
        }

        layout.label = {
          linePoints: linePoints,
          x: textX,
          y: textY,
          verticalAlign: 'middle',
          textAlign: textAlign,
          inside: isLabelInside
        };
      });
    }

    function funnelLayout(ecModel, api) {
      ecModel.eachSeriesByType('funnel', function (seriesModel) {
        var data = seriesModel.getData();
        var valueDim = data.mapDimension('value');
        var sort = seriesModel.get('sort');
        var viewRect = getViewRect$3(seriesModel, api);
        var orient = seriesModel.get('orient');
        var viewWidth = viewRect.width;
        var viewHeight = viewRect.height;
        var indices = getSortedIndices(data, sort);
        var x = viewRect.x;
        var y = viewRect.y;
        var sizeExtent = orient === 'horizontal' ? [parsePercent$1(seriesModel.get('minSize'), viewHeight), parsePercent$1(seriesModel.get('maxSize'), viewHeight)] : [parsePercent$1(seriesModel.get('minSize'), viewWidth), parsePercent$1(seriesModel.get('maxSize'), viewWidth)];
        var dataExtent = data.getDataExtent(valueDim);
        var min = seriesModel.get('min');
        var max = seriesModel.get('max');

        if (min == null) {
          min = Math.min(dataExtent[0], 0);
        }

        if (max == null) {
          max = dataExtent[1];
        }

        var funnelAlign = seriesModel.get('funnelAlign');
        var gap = seriesModel.get('gap');
        var viewSize = orient === 'horizontal' ? viewWidth : viewHeight;
        var itemSize = (viewSize - gap * (data.count() - 1)) / data.count();

        var getLinePoints = function (idx, offset) {
          // End point index is data.count() and we assign it 0
          if (orient === 'horizontal') {
            var val_1 = data.get(valueDim, idx) || 0;
            var itemHeight = linearMap(val_1, [min, max], sizeExtent, true);
            var y0 = void 0;

            switch (funnelAlign) {
              case 'top':
                y0 = y;
                break;

              case 'center':
                y0 = y + (viewHeight - itemHeight) / 2;
                break;

              case 'bottom':
                y0 = y + (viewHeight - itemHeight);
                break;
            }

            return [[offset, y0], [offset, y0 + itemHeight]];
          }

          var val = data.get(valueDim, idx) || 0;
          var itemWidth = linearMap(val, [min, max], sizeExtent, true);
          var x0;

          switch (funnelAlign) {
            case 'left':
              x0 = x;
              break;

            case 'center':
              x0 = x + (viewWidth - itemWidth) / 2;
              break;

            case 'right':
              x0 = x + viewWidth - itemWidth;
              break;
          }

          return [[x0, offset], [x0 + itemWidth, offset]];
        };

        if (sort === 'ascending') {
          // From bottom to top
          itemSize = -itemSize;
          gap = -gap;

          if (orient === 'horizontal') {
            x += viewWidth;
          } else {
            y += viewHeight;
          }

          indices = indices.reverse();
        }

        for (var i = 0; i < indices.length; i++) {
          var idx = indices[i];
          var nextIdx = indices[i + 1];
          var itemModel = data.getItemModel(idx);

          if (orient === 'horizontal') {
            var width = itemModel.get(['itemStyle', 'width']);

            if (width == null) {
              width = itemSize;
            } else {
              width = parsePercent$1(width, viewWidth);

              if (sort === 'ascending') {
                width = -width;
              }
            }

            var start = getLinePoints(idx, x);
            var end = getLinePoints(nextIdx, x + width);
            x += width + gap;
            data.setItemLayout(idx, {
              points: start.concat(end.slice().reverse())
            });
          } else {
            var height = itemModel.get(['itemStyle', 'height']);

            if (height == null) {
              height = itemSize;
            } else {
              height = parsePercent$1(height, viewHeight);

              if (sort === 'ascending') {
                height = -height;
              }
            }

            var start = getLinePoints(idx, y);
            var end = getLinePoints(nextIdx, y + height);
            y += height + gap;
            data.setItemLayout(idx, {
              points: start.concat(end.slice().reverse())
            });
          }
        }

        labelLayout(data);
      });
    }

    function install$f(registers) {
      registers.registerChartView(FunnelView);
      registers.registerSeriesModel(FunnelSeriesModel);
      registers.registerLayout(funnelLayout);
      registers.registerProcessor(dataFilter('funnel'));
    }

    var DEFAULT_SMOOTH = 0.3;

    var ParallelView =
    /** @class */
    function (_super) {
      __extends(ParallelView, _super);

      function ParallelView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = ParallelView.type;
        _this._dataGroup = new Group();
        _this._initialized = false;
        return _this;
      }

      ParallelView.prototype.init = function () {
        this.group.add(this._dataGroup);
      };
      /**
       * @override
       */


      ParallelView.prototype.render = function (seriesModel, ecModel, api, payload) {
        // Clear previously rendered progressive elements.
        this._progressiveEls = null;
        var dataGroup = this._dataGroup;
        var data = seriesModel.getData();
        var oldData = this._data;
        var coordSys = seriesModel.coordinateSystem;
        var dimensions = coordSys.dimensions;
        var seriesScope = makeSeriesScope$2(seriesModel);
        data.diff(oldData).add(add).update(update).remove(remove).execute();

        function add(newDataIndex) {
          var line = addEl(data, dataGroup, newDataIndex, dimensions, coordSys);
          updateElCommon(line, data, newDataIndex, seriesScope);
        }

        function update(newDataIndex, oldDataIndex) {
          var line = oldData.getItemGraphicEl(oldDataIndex);
          var points = createLinePoints(data, newDataIndex, dimensions, coordSys);
          data.setItemGraphicEl(newDataIndex, line);
          updateProps(line, {
            shape: {
              points: points
            }
          }, seriesModel, newDataIndex);
          saveOldStyle(line);
          updateElCommon(line, data, newDataIndex, seriesScope);
        }

        function remove(oldDataIndex) {
          var line = oldData.getItemGraphicEl(oldDataIndex);
          dataGroup.remove(line);
        } // First create


        if (!this._initialized) {
          this._initialized = true;
          var clipPath = createGridClipShape(coordSys, seriesModel, function () {
            // Callback will be invoked immediately if there is no animation
            setTimeout(function () {
              dataGroup.removeClipPath();
            });
          });
          dataGroup.setClipPath(clipPath);
        }

        this._data = data;
      };

      ParallelView.prototype.incrementalPrepareRender = function (seriesModel, ecModel, api) {
        this._initialized = true;
        this._data = null;

        this._dataGroup.removeAll();
      };

      ParallelView.prototype.incrementalRender = function (taskParams, seriesModel, ecModel) {
        var data = seriesModel.getData();
        var coordSys = seriesModel.coordinateSystem;
        var dimensions = coordSys.dimensions;
        var seriesScope = makeSeriesScope$2(seriesModel);
        var progressiveEls = this._progressiveEls = [];

        for (var dataIndex = taskParams.start; dataIndex < taskParams.end; dataIndex++) {
          var line = addEl(data, this._dataGroup, dataIndex, dimensions, coordSys);
          line.incremental = true;
          updateElCommon(line, data, dataIndex, seriesScope);
          progressiveEls.push(line);
        }
      };

      ParallelView.prototype.remove = function () {
        this._dataGroup && this._dataGroup.removeAll();
        this._data = null;
      };

      ParallelView.type = 'parallel';
      return ParallelView;
    }(ChartView);

    function createGridClipShape(coordSys, seriesModel, cb) {
      var parallelModel = coordSys.model;
      var rect = coordSys.getRect();
      var rectEl = new Rect({
        shape: {
          x: rect.x,
          y: rect.y,
          width: rect.width,
          height: rect.height
        }
      });
      var dim = parallelModel.get('layout') === 'horizontal' ? 'width' : 'height';
      rectEl.setShape(dim, 0);
      initProps(rectEl, {
        shape: {
          width: rect.width,
          height: rect.height
        }
      }, seriesModel, cb);
      return rectEl;
    }

    function createLinePoints(data, dataIndex, dimensions, coordSys) {
      var points = [];

      for (var i = 0; i < dimensions.length; i++) {
        var dimName = dimensions[i];
        var value = data.get(data.mapDimension(dimName), dataIndex);

        if (!isEmptyValue(value, coordSys.getAxis(dimName).type)) {
          points.push(coordSys.dataToPoint(value, dimName));
        }
      }

      return points;
    }

    function addEl(data, dataGroup, dataIndex, dimensions, coordSys) {
      var points = createLinePoints(data, dataIndex, dimensions, coordSys);
      var line = new Polyline({
        shape: {
          points: points
        },
        // silent: true,
        z2: 10
      });
      dataGroup.add(line);
      data.setItemGraphicEl(dataIndex, line);
      return line;
    }

    function makeSeriesScope$2(seriesModel) {
      var smooth = seriesModel.get('smooth', true);
      smooth === true && (smooth = DEFAULT_SMOOTH);
      smooth = numericToNumber(smooth);
      eqNaN(smooth) && (smooth = 0);
      return {
        smooth: smooth
      };
    }

    function updateElCommon(el, data, dataIndex, seriesScope) {
      el.useStyle(data.getItemVisual(dataIndex, 'style'));
      el.style.fill = null;
      el.setShape('smooth', seriesScope.smooth);
      var itemModel = data.getItemModel(dataIndex);
      var emphasisModel = itemModel.getModel('emphasis');
      setStatesStylesFromModel(el, itemModel, 'lineStyle');
      toggleHoverEmphasis(el, emphasisModel.get('focus'), emphasisModel.get('blurScope'), emphasisModel.get('disabled'));
    } // function simpleDiff(oldData, newData, dimensions) {
    //     let oldLen;
    //     if (!oldData
    //         || !oldData.__plProgressive
    //         || (oldLen = oldData.count()) !== newData.count()
    //     ) {
    //         return true;
    //     }
    //     let dimLen = dimensions.length;
    //     for (let i = 0; i < oldLen; i++) {
    //         for (let j = 0; j < dimLen; j++) {
    //             if (oldData.get(dimensions[j], i) !== newData.get(dimensions[j], i)) {
    //                 return true;
    //             }
    //         }
    //     }
    //     return false;
    // }
    // FIXME put in common util?


    function isEmptyValue(val, axisType) {
      return axisType === 'category' ? val == null : val == null || isNaN(val); // axisType === 'value'
    }

    var ParallelSeriesModel =
    /** @class */
    function (_super) {
      __extends(ParallelSeriesModel, _super);

      function ParallelSeriesModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = ParallelSeriesModel.type;
        _this.visualStyleAccessPath = 'lineStyle';
        _this.visualDrawType = 'stroke';
        return _this;
      }

      ParallelSeriesModel.prototype.getInitialData = function (option, ecModel) {
        return createSeriesData(null, this, {
          useEncodeDefaulter: bind(makeDefaultEncode, null, this)
        });
      };
      /**
       * User can get data raw indices on 'axisAreaSelected' event received.
       *
       * @return Raw indices
       */


      ParallelSeriesModel.prototype.getRawIndicesByActiveState = function (activeState) {
        var coordSys = this.coordinateSystem;
        var data = this.getData();
        var indices = [];
        coordSys.eachActiveState(data, function (theActiveState, dataIndex) {
          if (activeState === theActiveState) {
            indices.push(data.getRawIndex(dataIndex));
          }
        });
        return indices;
      };

      ParallelSeriesModel.type = 'series.parallel';
      ParallelSeriesModel.dependencies = ['parallel'];
      ParallelSeriesModel.defaultOption = {
        // zlevel: 0,
        z: 2,
        coordinateSystem: 'parallel',
        parallelIndex: 0,
        label: {
          show: false
        },
        inactiveOpacity: 0.05,
        activeOpacity: 1,
        lineStyle: {
          width: 1,
          opacity: 0.45,
          type: 'solid'
        },
        emphasis: {
          label: {
            show: false
          }
        },
        progressive: 500,
        smooth: false,
        animationEasing: 'linear'
      };
      return ParallelSeriesModel;
    }(SeriesModel);

    function makeDefaultEncode(seriesModel) {
      // The mapping of parallelAxis dimension to data dimension can
      // be specified in parallelAxis.option.dim. For example, if
      // parallelAxis.option.dim is 'dim3', it mapping to the third
      // dimension of data. But `data.encode` has higher priority.
      // Moreover, parallelModel.dimension should not be regarded as data
      // dimensions. Consider dimensions = ['dim4', 'dim2', 'dim6'];
      var parallelModel = seriesModel.ecModel.getComponent('parallel', seriesModel.get('parallelIndex'));

      if (!parallelModel) {
        return;
      }

      var encodeDefine = {};
      each(parallelModel.dimensions, function (axisDim) {
        var dataDimIndex = convertDimNameToNumber(axisDim);
        encodeDefine[axisDim] = dataDimIndex;
      });
      return encodeDefine;
    }

    function convertDimNameToNumber(dimName) {
      return +dimName.replace('dim', '');
    }

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


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * 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 opacityAccessPath$1 = ['lineStyle', 'opacity'];
    var parallelVisual = {
      seriesType: 'parallel',
      reset: function (seriesModel, ecModel) {
        var coordSys = seriesModel.coordinateSystem;
        var opacityMap = {
          normal: seriesModel.get(['lineStyle', 'opacity']),
          active: seriesModel.get('activeOpacity'),
          inactive: seriesModel.get('inactiveOpacity')
        };
        return {
          progress: function (params, data) {
            coordSys.eachActiveState(data, function (activeState, dataIndex) {
              var opacity = opacityMap[activeState];

              if (activeState === 'normal' && data.hasItemOption) {
                var itemOpacity = data.getItemModel(dataIndex).get(opacityAccessPath$1, true);
                itemOpacity != null && (opacity = itemOpacity);
              }

              var existsStyle = data.ensureUniqueItemVisual(dataIndex, 'style');
              existsStyle.opacity = opacity;
            }, params.start, params.end);
          }
        };
      }
    };

    function parallelPreprocessor(option) {
      createParallelIfNeeded(option);
      mergeAxisOptionFromParallel(option);
    }
    /**
     * Create a parallel coordinate if not exists.
     * @inner
     */

    function createParallelIfNeeded(option) {
      if (option.parallel) {
        return;
      }

      var hasParallelSeries = false;
      each(option.series, function (seriesOpt) {
        if (seriesOpt && seriesOpt.type === 'parallel') {
          hasParallelSeries = true;
        }
      });

      if (hasParallelSeries) {
        option.parallel = [{}];
      }
    }
    /**
     * Merge aixs definition from parallel option (if exists) to axis option.
     * @inner
     */


    function mergeAxisOptionFromParallel(option) {
      var axes = normalizeToArray(option.parallelAxis);
      each(axes, function (axisOption) {
        if (!isObject(axisOption)) {
          return;
        }

        var parallelIndex = axisOption.parallelIndex || 0;
        var parallelOption = normalizeToArray(option.parallel)[parallelIndex];

        if (parallelOption && parallelOption.parallelAxisDefault) {
          merge(axisOption, parallelOption.parallelAxisDefault, false);
        }
      });
    }

    var CLICK_THRESHOLD = 5; // > 4

    var ParallelView$1 =
    /** @class */
    function (_super) {
      __extends(ParallelView, _super);

      function ParallelView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = ParallelView.type;
        return _this;
      }

      ParallelView.prototype.render = function (parallelModel, ecModel, api) {
        this._model = parallelModel;
        this._api = api;

        if (!this._handlers) {
          this._handlers = {};
          each(handlers, function (handler, eventName) {
            api.getZr().on(eventName, this._handlers[eventName] = bind(handler, this));
          }, this);
        }

        createOrUpdate(this, '_throttledDispatchExpand', parallelModel.get('axisExpandRate'), 'fixRate');
      };

      ParallelView.prototype.dispose = function (ecModel, api) {
        clear(this, '_throttledDispatchExpand');
        each(this._handlers, function (handler, eventName) {
          api.getZr().off(eventName, handler);
        });
        this._handlers = null;
      };
      /**
       * @internal
       * @param {Object} [opt] If null, cancel the last action triggering for debounce.
       */


      ParallelView.prototype._throttledDispatchExpand = function (opt) {
        this._dispatchExpand(opt);
      };
      /**
       * @internal
       */


      ParallelView.prototype._dispatchExpand = function (opt) {
        opt && this._api.dispatchAction(extend({
          type: 'parallelAxisExpand'
        }, opt));
      };

      ParallelView.type = 'parallel';
      return ParallelView;
    }(ComponentView);

    var handlers = {
      mousedown: function (e) {
        if (checkTrigger(this, 'click')) {
          this._mouseDownPoint = [e.offsetX, e.offsetY];
        }
      },
      mouseup: function (e) {
        var mouseDownPoint = this._mouseDownPoint;

        if (checkTrigger(this, 'click') && mouseDownPoint) {
          var point = [e.offsetX, e.offsetY];
          var dist = Math.pow(mouseDownPoint[0] - point[0], 2) + Math.pow(mouseDownPoint[1] - point[1], 2);

          if (dist > CLICK_THRESHOLD) {
            return;
          }

          var result = this._model.coordinateSystem.getSlidedAxisExpandWindow([e.offsetX, e.offsetY]);

          result.behavior !== 'none' && this._dispatchExpand({
            axisExpandWindow: result.axisExpandWindow
          });
        }

        this._mouseDownPoint = null;
      },
      mousemove: function (e) {
        // Should do nothing when brushing.
        if (this._mouseDownPoint || !checkTrigger(this, 'mousemove')) {
          return;
        }

        var model = this._model;
        var result = model.coordinateSystem.getSlidedAxisExpandWindow([e.offsetX, e.offsetY]);
        var behavior = result.behavior;
        behavior === 'jump' && this._throttledDispatchExpand.debounceNextCall(model.get('axisExpandDebounce'));

        this._throttledDispatchExpand(behavior === 'none' ? null // Cancel the last trigger, in case that mouse slide out of the area quickly.
        : {
          axisExpandWindow: result.axisExpandWindow,
          // Jumping uses animation, and sliding suppresses animation.
          animation: behavior === 'jump' ? null : {
            duration: 0 // Disable animation.

          }
        });
      }
    };

    function checkTrigger(view, triggerOn) {
      var model = view._model;
      return model.get('axisExpandable') && model.get('axisExpandTriggerOn') === triggerOn;
    }

    var ParallelModel =
    /** @class */
    function (_super) {
      __extends(ParallelModel, _super);

      function ParallelModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = ParallelModel.type;
        return _this;
      }

      ParallelModel.prototype.init = function () {
        _super.prototype.init.apply(this, arguments);

        this.mergeOption({});
      };

      ParallelModel.prototype.mergeOption = function (newOption) {
        var thisOption = this.option;
        newOption && merge(thisOption, newOption, true);

        this._initDimensions();
      };
      /**
       * Whether series or axis is in this coordinate system.
       */


      ParallelModel.prototype.contains = function (model, ecModel) {
        var parallelIndex = model.get('parallelIndex');
        return parallelIndex != null && ecModel.getComponent('parallel', parallelIndex) === this;
      };

      ParallelModel.prototype.setAxisExpand = function (opt) {
        each(['axisExpandable', 'axisExpandCenter', 'axisExpandCount', 'axisExpandWidth', 'axisExpandWindow'], function (name) {
          if (opt.hasOwnProperty(name)) {
            // @ts-ignore FIXME: why "never" inferred in this.option[name]?
            this.option[name] = opt[name];
          }
        }, this);
      };

      ParallelModel.prototype._initDimensions = function () {
        var dimensions = this.dimensions = [];
        var parallelAxisIndex = this.parallelAxisIndex = [];
        var axisModels = filter(this.ecModel.queryComponents({
          mainType: 'parallelAxis'
        }), function (axisModel) {
          // Can not use this.contains here, because
          // initialization has not been completed yet.
          return (axisModel.get('parallelIndex') || 0) === this.componentIndex;
        }, this);
        each(axisModels, function (axisModel) {
          dimensions.push('dim' + axisModel.get('dim'));
          parallelAxisIndex.push(axisModel.componentIndex);
        });
      };

      ParallelModel.type = 'parallel';
      ParallelModel.dependencies = ['parallelAxis'];
      ParallelModel.layoutMode = 'box';
      ParallelModel.defaultOption = {
        // zlevel: 0,
        z: 0,
        left: 80,
        top: 60,
        right: 80,
        bottom: 60,
        // width: {totalWidth} - left - right,
        // height: {totalHeight} - top - bottom,
        layout: 'horizontal',
        // FIXME
        // naming?
        axisExpandable: false,
        axisExpandCenter: null,
        axisExpandCount: 0,
        axisExpandWidth: 50,
        axisExpandRate: 17,
        axisExpandDebounce: 50,
        // [out, in, jumpTarget]. In percentage. If use [null, 0.05], null means full.
        // Do not doc to user until necessary.
        axisExpandSlideTriggerArea: [-0.15, 0.05, 0.4],
        axisExpandTriggerOn: 'click',
        parallelAxisDefault: null
      };
      return ParallelModel;
    }(ComponentModel);

    var ParallelAxis =
    /** @class */
    function (_super) {
      __extends(ParallelAxis, _super);

      function ParallelAxis(dim, scale, coordExtent, axisType, axisIndex) {
        var _this = _super.call(this, dim, scale, coordExtent) || this;

        _this.type = axisType || 'value';
        _this.axisIndex = axisIndex;
        return _this;
      }

      ParallelAxis.prototype.isHorizontal = function () {
        return this.coordinateSystem.getModel().get('layout') !== 'horizontal';
      };

      return ParallelAxis;
    }(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.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * 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 delta Move length.
     * @param handleEnds handleEnds[0] can be bigger then handleEnds[1].
     *              handleEnds will be modified in this method.
     * @param extent handleEnds is restricted by extent.
     *              extent[0] should less or equals than extent[1].
     * @param handleIndex Can be 'all', means that both move the two handleEnds.
     * @param 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 maxSpan The range of dataZoom can not be larger than that.
     * @return The input handleEnds.
     */
    function sliderMove(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;
      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.


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

    var each$5 = each;
    var mathMin$8 = Math.min;
    var mathMax$8 = Math.max;
    var mathFloor$1 = Math.floor;
    var mathCeil$1 = Math.ceil;
    var round$3 = round;
    var PI$7 = Math.PI;

    var Parallel =
    /** @class */
    function () {
      function Parallel(parallelModel, ecModel, api) {
        this.type = 'parallel';
        /**
         * key: dimension
         */

        this._axesMap = createHashMap();
        /**
         * key: dimension
         * value: {position: [], rotation, }
         */

        this._axesLayout = {};
        this.dimensions = parallelModel.dimensions;
        this._model = parallelModel;

        this._init(parallelModel, ecModel, api);
      }

      Parallel.prototype._init = function (parallelModel, ecModel, api) {
        var dimensions = parallelModel.dimensions;
        var parallelAxisIndex = parallelModel.parallelAxisIndex;
        each$5(dimensions, function (dim, idx) {
          var axisIndex = parallelAxisIndex[idx];
          var axisModel = ecModel.getComponent('parallelAxis', axisIndex);

          var axis = this._axesMap.set(dim, new ParallelAxis(dim, createScaleByModel(axisModel), [0, 0], axisModel.get('type'), axisIndex));

          var isCategory = axis.type === 'category';
          axis.onBand = isCategory && axisModel.get('boundaryGap');
          axis.inverse = axisModel.get('inverse'); // Injection

          axisModel.axis = axis;
          axis.model = axisModel;
          axis.coordinateSystem = axisModel.coordinateSystem = this;
        }, this);
      };
      /**
       * Update axis scale after data processed
       */


      Parallel.prototype.update = function (ecModel, api) {
        this._updateAxesFromSeries(this._model, ecModel);
      };

      Parallel.prototype.containPoint = function (point) {
        var layoutInfo = this._makeLayoutInfo();

        var axisBase = layoutInfo.axisBase;
        var layoutBase = layoutInfo.layoutBase;
        var pixelDimIndex = layoutInfo.pixelDimIndex;
        var pAxis = point[1 - pixelDimIndex];
        var pLayout = point[pixelDimIndex];
        return pAxis >= axisBase && pAxis <= axisBase + layoutInfo.axisLength && pLayout >= layoutBase && pLayout <= layoutBase + layoutInfo.layoutLength;
      };

      Parallel.prototype.getModel = function () {
        return this._model;
      };
      /**
       * Update properties from series
       */


      Parallel.prototype._updateAxesFromSeries = function (parallelModel, ecModel) {
        ecModel.eachSeries(function (seriesModel) {
          if (!parallelModel.contains(seriesModel, ecModel)) {
            return;
          }

          var data = seriesModel.getData();
          each$5(this.dimensions, function (dim) {
            var axis = this._axesMap.get(dim);

            axis.scale.unionExtentFromData(data, data.mapDimension(dim));
            niceScaleExtent(axis.scale, axis.model);
          }, this);
        }, this);
      };
      /**
       * Resize the parallel coordinate system.
       */


      Parallel.prototype.resize = function (parallelModel, api) {
        this._rect = getLayoutRect(parallelModel.getBoxLayoutParams(), {
          width: api.getWidth(),
          height: api.getHeight()
        });

        this._layoutAxes();
      };

      Parallel.prototype.getRect = function () {
        return this._rect;
      };

      Parallel.prototype._makeLayoutInfo = function () {
        var parallelModel = this._model;
        var rect = this._rect;
        var xy = ['x', 'y'];
        var wh = ['width', 'height'];
        var layout = parallelModel.get('layout');
        var pixelDimIndex = layout === 'horizontal' ? 0 : 1;
        var layoutLength = rect[wh[pixelDimIndex]];
        var layoutExtent = [0, layoutLength];
        var axisCount = this.dimensions.length;
        var axisExpandWidth = restrict$1(parallelModel.get('axisExpandWidth'), layoutExtent);
        var axisExpandCount = restrict$1(parallelModel.get('axisExpandCount') || 0, [0, axisCount]);
        var axisExpandable = parallelModel.get('axisExpandable') && axisCount > 3 && axisCount > axisExpandCount && axisExpandCount > 1 && axisExpandWidth > 0 && layoutLength > 0; // `axisExpandWindow` is According to the coordinates of [0, axisExpandLength],
        // for sake of consider the case that axisCollapseWidth is 0 (when screen is narrow),
        // where collapsed axes should be overlapped.

        var axisExpandWindow = parallelModel.get('axisExpandWindow');
        var winSize;

        if (!axisExpandWindow) {
          winSize = restrict$1(axisExpandWidth * (axisExpandCount - 1), layoutExtent);
          var axisExpandCenter = parallelModel.get('axisExpandCenter') || mathFloor$1(axisCount / 2);
          axisExpandWindow = [axisExpandWidth * axisExpandCenter - winSize / 2];
          axisExpandWindow[1] = axisExpandWindow[0] + winSize;
        } else {
          winSize = restrict$1(axisExpandWindow[1] - axisExpandWindow[0], layoutExtent);
          axisExpandWindow[1] = axisExpandWindow[0] + winSize;
        }

        var axisCollapseWidth = (layoutLength - winSize) / (axisCount - axisExpandCount); // Avoid axisCollapseWidth is too small.

        axisCollapseWidth < 3 && (axisCollapseWidth = 0); // Find the first and last indices > ewin[0] and < ewin[1].

        var winInnerIndices = [mathFloor$1(round$3(axisExpandWindow[0] / axisExpandWidth, 1)) + 1, mathCeil$1(round$3(axisExpandWindow[1] / axisExpandWidth, 1)) - 1]; // Pos in ec coordinates.

        var axisExpandWindow0Pos = axisCollapseWidth / axisExpandWidth * axisExpandWindow[0];
        return {
          layout: layout,
          pixelDimIndex: pixelDimIndex,
          layoutBase: rect[xy[pixelDimIndex]],
          layoutLength: layoutLength,
          axisBase: rect[xy[1 - pixelDimIndex]],
          axisLength: rect[wh[1 - pixelDimIndex]],
          axisExpandable: axisExpandable,
          axisExpandWidth: axisExpandWidth,
          axisCollapseWidth: axisCollapseWidth,
          axisExpandWindow: axisExpandWindow,
          axisCount: axisCount,
          winInnerIndices: winInnerIndices,
          axisExpandWindow0Pos: axisExpandWindow0Pos
        };
      };

      Parallel.prototype._layoutAxes = function () {
        var rect = this._rect;
        var axes = this._axesMap;
        var dimensions = this.dimensions;

        var layoutInfo = this._makeLayoutInfo();

        var layout = layoutInfo.layout;
        axes.each(function (axis) {
          var axisExtent = [0, layoutInfo.axisLength];
          var idx = axis.inverse ? 1 : 0;
          axis.setExtent(axisExtent[idx], axisExtent[1 - idx]);
        });
        each$5(dimensions, function (dim, idx) {
          var posInfo = (layoutInfo.axisExpandable ? layoutAxisWithExpand : layoutAxisWithoutExpand)(idx, layoutInfo);
          var positionTable = {
            horizontal: {
              x: posInfo.position,
              y: layoutInfo.axisLength
            },
            vertical: {
              x: 0,
              y: posInfo.position
            }
          };
          var rotationTable = {
            horizontal: PI$7 / 2,
            vertical: 0
          };
          var position = [positionTable[layout].x + rect.x, positionTable[layout].y + rect.y];
          var rotation = rotationTable[layout];
          var transform = create$1();
          rotate(transform, transform, rotation);
          translate(transform, transform, position); // TODO
          // tick layout info
          // TODO
          // update dimensions info based on axis order.

          this._axesLayout[dim] = {
            position: position,
            rotation: rotation,
            transform: transform,
            axisNameAvailableWidth: posInfo.axisNameAvailableWidth,
            axisLabelShow: posInfo.axisLabelShow,
            nameTruncateMaxWidth: posInfo.nameTruncateMaxWidth,
            tickDirection: 1,
            labelDirection: 1
          };
        }, this);
      };
      /**
       * Get axis by dim.
       */


      Parallel.prototype.getAxis = function (dim) {
        return this._axesMap.get(dim);
      };
      /**
       * Convert a dim value of a single item of series data to Point.
       */


      Parallel.prototype.dataToPoint = function (value, dim) {
        return this.axisCoordToPoint(this._axesMap.get(dim).dataToCoord(value), dim);
      };
      /**
       * Travel data for one time, get activeState of each data item.
       * @param start the start dataIndex that travel from.
       * @param end the next dataIndex of the last dataIndex will be travel.
       */


      Parallel.prototype.eachActiveState = function (data, callback, start, end) {
        start == null && (start = 0);
        end == null && (end = data.count());
        var axesMap = this._axesMap;
        var dimensions = this.dimensions;
        var dataDimensions = [];
        var axisModels = [];
        each(dimensions, function (axisDim) {
          dataDimensions.push(data.mapDimension(axisDim));
          axisModels.push(axesMap.get(axisDim).model);
        });
        var hasActiveSet = this.hasAxisBrushed();

        for (var dataIndex = start; dataIndex < end; dataIndex++) {
          var activeState = void 0;

          if (!hasActiveSet) {
            activeState = 'normal';
          } else {
            activeState = 'active';
            var values = data.getValues(dataDimensions, dataIndex);

            for (var j = 0, lenj = dimensions.length; j < lenj; j++) {
              var state = axisModels[j].getActiveState(values[j]);

              if (state === 'inactive') {
                activeState = 'inactive';
                break;
              }
            }
          }

          callback(activeState, dataIndex);
        }
      };
      /**
       * Whether has any activeSet.
       */


      Parallel.prototype.hasAxisBrushed = function () {
        var dimensions = this.dimensions;
        var axesMap = this._axesMap;
        var hasActiveSet = false;

        for (var j = 0, lenj = dimensions.length; j < lenj; j++) {
          if (axesMap.get(dimensions[j]).model.getActiveState() !== 'normal') {
            hasActiveSet = true;
          }
        }

        return hasActiveSet;
      };
      /**
       * Convert coords of each axis to Point.
       *  Return point. For example: [10, 20]
       */


      Parallel.prototype.axisCoordToPoint = function (coord, dim) {
        var axisLayout = this._axesLayout[dim];
        return applyTransform$1([coord, 0], axisLayout.transform);
      };
      /**
       * Get axis layout.
       */


      Parallel.prototype.getAxisLayout = function (dim) {
        return clone(this._axesLayout[dim]);
      };
      /**
       * @return {Object} {axisExpandWindow, delta, behavior: 'jump' | 'slide' | 'none'}.
       */


      Parallel.prototype.getSlidedAxisExpandWindow = function (point) {
        var layoutInfo = this._makeLayoutInfo();

        var pixelDimIndex = layoutInfo.pixelDimIndex;
        var axisExpandWindow = layoutInfo.axisExpandWindow.slice();
        var winSize = axisExpandWindow[1] - axisExpandWindow[0];
        var extent = [0, layoutInfo.axisExpandWidth * (layoutInfo.axisCount - 1)]; // Out of the area of coordinate system.

        if (!this.containPoint(point)) {
          return {
            behavior: 'none',
            axisExpandWindow: axisExpandWindow
          };
        } // Convert the point from global to expand coordinates.


        var pointCoord = point[pixelDimIndex] - layoutInfo.layoutBase - layoutInfo.axisExpandWindow0Pos; // For dragging operation convenience, the window should not be
        // slided when mouse is the center area of the window.

        var delta;
        var behavior = 'slide';
        var axisCollapseWidth = layoutInfo.axisCollapseWidth;

        var triggerArea = this._model.get('axisExpandSlideTriggerArea'); // But consider touch device, jump is necessary.


        var useJump = triggerArea[0] != null;

        if (axisCollapseWidth) {
          if (useJump && axisCollapseWidth && pointCoord < winSize * triggerArea[0]) {
            behavior = 'jump';
            delta = pointCoord - winSize * triggerArea[2];
          } else if (useJump && axisCollapseWidth && pointCoord > winSize * (1 - triggerArea[0])) {
            behavior = 'jump';
            delta = pointCoord - winSize * (1 - triggerArea[2]);
          } else {
            (delta = pointCoord - winSize * triggerArea[1]) >= 0 && (delta = pointCoord - winSize * (1 - triggerArea[1])) <= 0 && (delta = 0);
          }

          delta *= layoutInfo.axisExpandWidth / axisCollapseWidth;
          delta ? sliderMove(delta, axisExpandWindow, extent, 'all') // Avoid nonsense triger on mousemove.
          : behavior = 'none';
        } // When screen is too narrow, make it visible and slidable, although it is hard to interact.
        else {
            var winSize2 = axisExpandWindow[1] - axisExpandWindow[0];
            var pos = extent[1] * pointCoord / winSize2;
            axisExpandWindow = [mathMax$8(0, pos - winSize2 / 2)];
            axisExpandWindow[1] = mathMin$8(extent[1], axisExpandWindow[0] + winSize2);
            axisExpandWindow[0] = axisExpandWindow[1] - winSize2;
          }

        return {
          axisExpandWindow: axisExpandWindow,
          behavior: behavior
        };
      };

      return Parallel;
    }();

    function restrict$1(len, extent) {
      return mathMin$8(mathMax$8(len, extent[0]), extent[1]);
    }

    function layoutAxisWithoutExpand(axisIndex, layoutInfo) {
      var step = layoutInfo.layoutLength / (layoutInfo.axisCount - 1);
      return {
        position: step * axisIndex,
        axisNameAvailableWidth: step,
        axisLabelShow: true
      };
    }

    function layoutAxisWithExpand(axisIndex, layoutInfo) {
      var layoutLength = layoutInfo.layoutLength;
      var axisExpandWidth = layoutInfo.axisExpandWidth;
      var axisCount = layoutInfo.axisCount;
      var axisCollapseWidth = layoutInfo.axisCollapseWidth;
      var winInnerIndices = layoutInfo.winInnerIndices;
      var position;
      var axisNameAvailableWidth = axisCollapseWidth;
      var axisLabelShow = false;
      var nameTruncateMaxWidth;

      if (axisIndex < winInnerIndices[0]) {
        position = axisIndex * axisCollapseWidth;
        nameTruncateMaxWidth = axisCollapseWidth;
      } else if (axisIndex <= winInnerIndices[1]) {
        position = layoutInfo.axisExpandWindow0Pos + axisIndex * axisExpandWidth - layoutInfo.axisExpandWindow[0];
        axisNameAvailableWidth = axisExpandWidth;
        axisLabelShow = true;
      } else {
        position = layoutLength - (axisCount - 1 - axisIndex) * axisCollapseWidth;
        nameTruncateMaxWidth = axisCollapseWidth;
      }

      return {
        position: position,
        axisNameAvailableWidth: axisNameAvailableWidth,
        axisLabelShow: axisLabelShow,
        nameTruncateMaxWidth: nameTruncateMaxWidth
      };
    }

    function createParallelCoordSys(ecModel, api) {
      var coordSysList = [];
      ecModel.eachComponent('parallel', function (parallelModel, idx) {
        var coordSys = new Parallel(parallelModel, ecModel, api);
        coordSys.name = 'parallel_' + idx;
        coordSys.resize(parallelModel, api);
        parallelModel.coordinateSystem = coordSys;
        coordSys.model = parallelModel;
        coordSysList.push(coordSys);
      }); // Inject the coordinateSystems into seriesModel

      ecModel.eachSeries(function (seriesModel) {
        if (seriesModel.get('coordinateSystem') === 'parallel') {
          var parallelModel = seriesModel.getReferringComponents('parallel', SINGLE_REFERRING).models[0];
          seriesModel.coordinateSystem = parallelModel.coordinateSystem;
        }
      });
      return coordSysList;
    }

    var parallelCoordSysCreator = {
      create: createParallelCoordSys
    };

    var ParallelAxisModel =
    /** @class */
    function (_super) {
      __extends(ParallelAxisModel, _super);

      function ParallelAxisModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = ParallelAxisModel.type;
        /**
         * @readOnly
         */

        _this.activeIntervals = [];
        return _this;
      }

      ParallelAxisModel.prototype.getAreaSelectStyle = function () {
        return makeStyleMapper([['fill', 'color'], ['lineWidth', 'borderWidth'], ['stroke', 'borderColor'], ['width', 'width'], ['opacity', 'opacity'] // Option decal is in `DecalObject` but style.decal is in `PatternObject`.
        // So do not transfer decal directly.
        ])(this.getModel('areaSelectStyle'));
      };
      /**
       * The code of this feature is put on AxisModel but not ParallelAxis,
       * because axisModel can be alive after echarts updating but instance of
       * ParallelAxis having been disposed. this._activeInterval should be kept
       * when action dispatched (i.e. legend click).
       *
       * @param intervals `interval.length === 0` means set all active.
       */


      ParallelAxisModel.prototype.setActiveIntervals = function (intervals) {
        var activeIntervals = this.activeIntervals = clone(intervals); // Normalize

        if (activeIntervals) {
          for (var i = activeIntervals.length - 1; i >= 0; i--) {
            asc(activeIntervals[i]);
          }
        }
      };
      /**
       * @param value When only attempting detect whether 'no activeIntervals set',
       *        `value` is not needed to be input.
       */


      ParallelAxisModel.prototype.getActiveState = function (value) {
        var activeIntervals = this.activeIntervals;

        if (!activeIntervals.length) {
          return 'normal';
        }

        if (value == null || isNaN(+value)) {
          return 'inactive';
        } // Simple optimization


        if (activeIntervals.length === 1) {
          var interval = activeIntervals[0];

          if (interval[0] <= value && value <= interval[1]) {
            return 'active';
          }
        } else {
          for (var i = 0, len = activeIntervals.length; i < len; i++) {
            if (activeIntervals[i][0] <= value && value <= activeIntervals[i][1]) {
              return 'active';
            }
          }
        }

        return 'inactive';
      };

      return ParallelAxisModel;
    }(ComponentModel);

    mixin(ParallelAxisModel, AxisModelCommonMixin);

    var BRUSH_PANEL_GLOBAL = true;
    var mathMin$9 = Math.min;
    var mathMax$9 = 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(210,219,238,0.3)',
        fill: '#D2DBEE'
      },
      transformable: true,
      brushMode: 'single',
      removeOnClick: false
    };
    var baseUID = 0;
    /**
     * params:
     *     areas: Array.<Array>, coord relates to container group,
     *                             If no container specified, to global.
     *     opt {
     *         isEnd: boolean,
     *         removeOnClick: boolean
     *     }
     */

    var BrushController =
    /** @class */
    function (_super) {
      __extends(BrushController, _super);

      function BrushController(zr) {
        var _this = _super.call(this) || this;
        /**
         * @internal
         */


        _this._track = [];
        /**
         * @internal
         */

        _this._covers = [];
        _this._handlers = {};

        if ("development" !== 'production') {
          assert(zr);
        }

        _this._zr = zr;
        _this.group = new Group();
        _this._uid = 'brushController_' + baseUID++;
        each(pointerHandlers, function (handler, eventName) {
          this._handlers[eventName] = bind(handler, this);
        }, _this);
        return _this;
      }
      /**
       * If set to `false`, select disabled.
       */


      BrushController.prototype.enableBrush = function (brushOption) {
        if ("development" !== 'production') {
          assert(this._mounted);
        }

        this._brushType && this._doDisableBrush();
        brushOption.brushType && this._doEnableBrush(brushOption);
        return this;
      };

      BrushController.prototype._doEnableBrush = function (brushOption) {
        var zr = this._zr; // Consider roam, which takes globalPan too.

        if (!this._enableGlobalPan) {
          take(zr, MUTEX_RESOURCE_KEY, this._uid);
        }

        each(this._handlers, function (handler, eventName) {
          zr.on(eventName, handler);
        });
        this._brushType = brushOption.brushType;
        this._brushOption = merge(clone(DEFAULT_BRUSH_OPT), brushOption, true);
      };

      BrushController.prototype._doDisableBrush = function () {
        var zr = this._zr;
        release(zr, MUTEX_RESOURCE_KEY, this._uid);
        each(this._handlers, function (handler, eventName) {
          zr.off(eventName, handler);
        });
        this._brushType = this._brushOption = null;
      };
      /**
       * @param panelOpts If not pass, it is global brush.
       */


      BrushController.prototype.setPanels = function (panelOpts) {
        if (panelOpts && panelOpts.length) {
          var panels_1 = this._panels = {};
          each(panelOpts, function (panelOpts) {
            panels_1[panelOpts.panelId] = clone(panelOpts);
          });
        } else {
          this._panels = null;
        }

        return this;
      };

      BrushController.prototype.mount = function (opt) {
        opt = opt || {};

        if ("development" !== 'production') {
          this._mounted = true; // should be at first.
        }

        this._enableGlobalPan = opt.enableGlobalPan;
        var thisGroup = this.group;

        this._zr.add(thisGroup);

        thisGroup.attr({
          x: opt.x || 0,
          y: opt.y || 0,
          rotation: opt.rotation || 0,
          scaleX: opt.scaleX || 1,
          scaleY: opt.scaleY || 1
        });
        this._transform = thisGroup.getLocalTransform();
        return this;
      }; // eachCover(cb, context): void {
      //     each(this._covers, cb, context);
      // }

      /**
       * Update covers.
       * @param coverConfigList
       *        If coverConfigList is null/undefined, all covers removed.
       */


      BrushController.prototype.updateCovers = function (coverConfigList) {
        if ("development" !== 'production') {
          assert(this._mounted);
        }

        coverConfigList = map(coverConfigList, function (coverConfig) {
          return merge(clone(DEFAULT_BRUSH_OPT), coverConfig, true);
        });
        var tmpIdPrefix = '\0-brush-index-';
        var oldCovers = this._covers;
        var newCovers = this._covers = [];
        var controller = this;
        var creatingCover = this._creatingCover;
        new DataDiffer(oldCovers, coverConfigList, 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 newBrushInternal = coverConfigList[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 = newBrushInternal, oldCovers[oldIndex]) : endCreating(controller, createCover(controller, newBrushInternal));
            updateCoverAfterCreation(controller, cover);
          }
        }

        function remove(oldIndex) {
          if (oldCovers[oldIndex] !== creatingCover) {
            controller.group.remove(oldCovers[oldIndex]);
          }
        }
      };

      BrushController.prototype.unmount = function () {
        if ("development" !== 'production') {
          if (!this._mounted) {
            return;
          }
        }

        this.enableBrush(false); // container may 'removeAll' outside.

        clearCovers(this);

        this._zr.remove(this.group);

        if ("development" !== 'production') {
          this._mounted = false; // should be at last.
        }

        return this;
      };

      BrushController.prototype.dispose = function () {
        this.unmount();
        this.off();
      };

      return BrushController;
    }(Eventful);

    function createCover(controller, brushOption) {
      var cover = coverRenderers[brushOption.brushType].createCover(controller, brushOption);
      cover.__brushOption = brushOption;
      updateZ(cover, brushOption);
      controller.group.add(cover);
      return cover;
    }

    function endCreating(controller, creatingCover) {
      var coverRenderer = getCoverRenderer(creatingCover);

      if (coverRenderer.endCreating) {
        coverRenderer.endCreating(controller, creatingCover);
        updateZ(creatingCover, creatingCover.__brushOption);
      }

      return creatingCover;
    }

    function updateCoverShape(controller, cover) {
      var brushOption = cover.__brushOption;
      getCoverRenderer(cover).updateCoverShape(controller, cover, brushOption.range, brushOption);
    }

    function updateZ(cover, brushOption) {
      var z = brushOption.z;
      z == null && (z = COVER_Z);
      cover.traverse(function (el) {
        el.z = z;
        el.z2 = z; // Consider in given container.
      });
    }

    function updateCoverAfterCreation(controller, cover) {
      getCoverRenderer(cover).updateCommon(controller, cover);
      updateCoverShape(controller, cover);
    }

    function getCoverRenderer(cover) {
      return coverRenderers[cover.__brushOption.brushType];
    } // return target panel or `true` (means global panel)


    function getPanelByPoint(controller, e, localCursorPoint) {
      var panels = controller._panels;

      if (!panels) {
        return BRUSH_PANEL_GLOBAL; // Global panel
      }

      var panel;
      var transform = controller._transform;
      each(panels, function (pn) {
        pn.isTargetByCursor(e, localCursorPoint, transform) && (panel = pn);
      });
      return panel;
    } // Return a panel or true


    function getPanelByCover(controller, cover) {
      var panels = controller._panels;

      if (!panels) {
        return BRUSH_PANEL_GLOBAL; // 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] : BRUSH_PANEL_GLOBAL;
    }

    function clearCovers(controller) {
      var covers = controller._covers;
      var originalLength = covers.length;
      each(covers, function (cover) {
        controller.group.remove(cover);
      }, controller);
      covers.length = 0;
      return !!originalLength;
    }

    function trigger$1(controller, opt) {
      var areas = map(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: 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(rectRangeConverter, controller, brushOption, edgeNameSequences) {
      var cover = new Group();
      cover.add(new Rect({
        name: 'main',
        style: makeStyle(brushOption),
        silent: true,
        draggable: true,
        cursor: 'move',
        drift: curry(driftRect, rectRangeConverter, controller, cover, ['n', 's', 'w', 'e']),
        ondragend: curry(trigger$1, controller, {
          isEnd: true
        })
      }));
      each(edgeNameSequences, function (nameSequence) {
        cover.add(new Rect({
          name: nameSequence.join(''),
          style: {
            opacity: 0
          },
          draggable: true,
          silent: true,
          invisible: true,
          drift: curry(driftRect, rectRangeConverter, controller, cover, nameSequence),
          ondragend: curry(trigger$1, controller, {
            isEnd: true
          })
        }));
      });
      return cover;
    }

    function updateBaseRect(controller, cover, localRange, brushOption) {
      var lineWidth = brushOption.brushStyle.lineWidth || 0;
      var handleSize = mathMax$9(lineWidth, MIN_RESIZE_LINE_WIDTH);
      var x = localRange[0][0];
      var y = localRange[1][0];
      var xa = x - lineWidth / 2;
      var ya = y - lineWidth / 2;
      var x2 = localRange[0][1];
      var y2 = localRange[1][1];
      var x2a = x2 - handleSize + lineWidth / 2;
      var y2a = y2 - handleSize + lineWidth / 2;
      var width = x2 - x;
      var height = y2 - y;
      var widtha = width + lineWidth;
      var heighta = height + lineWidth;
      updateRectShape(controller, cover, 'main', x, y, width, height);

      if (brushOption.transformable) {
        updateRectShape(controller, cover, 'w', xa, ya, handleSize, heighta);
        updateRectShape(controller, cover, 'e', x2a, ya, handleSize, heighta);
        updateRectShape(controller, cover, 'n', xa, ya, widtha, handleSize);
        updateRectShape(controller, cover, 's', xa, y2a, widtha, handleSize);
        updateRectShape(controller, cover, 'nw', xa, ya, handleSize, handleSize);
        updateRectShape(controller, cover, 'ne', x2a, ya, handleSize, handleSize);
        updateRectShape(controller, cover, 'sw', xa, y2a, handleSize, handleSize);
        updateRectShape(controller, cover, 'se', x2a, y2a, handleSize, handleSize);
      }
    }

    function updateCommon(controller, cover) {
      var brushOption = cover.__brushOption;
      var transformable = brushOption.transformable;
      var mainEl = cover.childAt(0);
      mainEl.useStyle(makeStyle(brushOption));
      mainEl.attr({
        silent: !transformable,
        cursor: transformable ? 'move' : 'default'
      });
      each([['w'], ['e'], ['n'], ['s'], ['s', 'e'], ['s', 'w'], ['n', 'e'], ['n', 'w']], function (nameSequence) {
        var el = cover.childOfName(nameSequence.join(''));
        var globalDir = nameSequence.length === 1 ? getGlobalDirection1(controller, nameSequence[0]) : getGlobalDirection2(controller, nameSequence);
        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$9(x, x2), mathMin$9(y, y2)];
      var max = [mathMax$9(x, x2), mathMax$9(y, y2)];
      return [[min[0], max[0]], [min[1], max[1]] // y range
      ];
    }

    function getTransform$1(controller) {
      return getTransform(controller.group);
    }

    function getGlobalDirection1(controller, localDirName) {
      var map = {
        w: 'left',
        e: 'right',
        n: 'top',
        s: 'bottom'
      };
      var inverseMap = {
        left: 'w',
        right: 'e',
        top: 'n',
        bottom: 's'
      };
      var dir = transformDirection(map[localDirName], getTransform$1(controller));
      return inverseMap[dir];
    }

    function getGlobalDirection2(controller, localDirNameSeq) {
      var globalDir = [getGlobalDirection1(controller, localDirNameSeq[0]), getGlobalDirection1(controller, localDirNameSeq[1])];
      (globalDir[0] === 'e' || globalDir[0] === 'w') && globalDir.reverse();
      return globalDir.join('');
    }

    function driftRect(rectRangeConverter, controller, cover, dirNameSequence, dx, dy) {
      var brushOption = cover.__brushOption;
      var rectRange = rectRangeConverter.toRectRange(brushOption.range);
      var localDelta = toLocalDelta(controller, dx, dy);
      each(dirNameSequence, function (dirName) {
        var ind = DIRECTION_MAP[dirName];
        rectRange[ind[0]][ind[1]] += localDelta[ind[0]];
      });
      brushOption.range = rectRangeConverter.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) {
      var range = cover.__brushOption.range;
      var localDelta = toLocalDelta(controller, dx, dy);
      each(range, function (point) {
        point[0] += localDelta[0];
        point[1] += localDelta[1];
      });
      updateCoverAfterCreation(controller, cover);
      trigger$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 !== BRUSH_PANEL_GLOBAL ? panel.clipPath(data, controller._transform) : clone(data);
    }

    function pointsToRect(points) {
      var xmin = mathMin$9(points[0][0], points[1][0]);
      var ymin = mathMin$9(points[0][1], points[1][1]);
      var xmax = mathMax$9(points[0][0], points[1][0]);
      var ymax = mathMax$9(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.offsetX, e.offsetY)) {
        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 === BRUSH_PANEL_GLOBAL || 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 === BRUSH_PANEL_GLOBAL ? 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 ("development" !== 'production') {
          assert(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 mouse 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
     */


    var coverRenderers = {
      lineX: getLineRenderer(0),
      lineY: getLineRenderer(1),
      rect: {
        createCover: function (controller, brushOption) {
          function returnInput(range) {
            return range;
          }

          return createBaseRectCover({
            toRectRange: returnInput,
            fromRectRange: returnInput
          }, controller, brushOption, [['w'], ['e'], ['n'], ['s'], ['s', 'e'], ['s', 'w'], ['n', 'e'], ['n', 'w']]);
        },
        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(driftPolygon, controller, cover),
            ondragend: curry(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({
            toRectRange: function (range) {
              var rectRange = [range, [0, 100]];
              xyIndex && rectRange.reverse();
              return rectRange;
            },
            fromRectRange: function (rectRange) {
              return rectRange[xyIndex];
            }
          }, controller, brushOption, [[['w'], ['e']], [['n'], ['s']]][xyIndex]);
        },
        getCreatingRange: function (localTrack) {
          var ends = getTrackEnds(localTrack);
          var min = mathMin$9(ends[0][xyIndex], ends[1][xyIndex]);
          var max = mathMax$9(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 !== BRUSH_PANEL_GLOBAL && panel.getLinearBrushOtherExtent) {
            otherExtent = panel.getLinearBrushOtherExtent(xyIndex);
          } 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
      };
    }

    function makeRectPanelClipPath(rect) {
      rect = normalizeRect(rect);
      return function (localPoints) {
        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) {
      var boundingRect = normalizeRect(rect);
      return function (e, localCursorPoint) {
        return boundingRect.contain(localCursorPoint[0], localCursorPoint[1]) && !onIrrelevantElement(e, api, targetModel);
      };
    } // Consider width/height is negative.

    function normalizeRect(rect) {
      return BoundingRect.create(rect);
    }

    var elementList = ['axisLine', 'axisTickLabel', 'axisName'];

    var ParallelAxisView =
    /** @class */
    function (_super) {
      __extends(ParallelAxisView, _super);

      function ParallelAxisView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = ParallelAxisView.type;
        return _this;
      }

      ParallelAxisView.prototype.init = function (ecModel, api) {
        _super.prototype.init.apply(this, arguments);

        (this._brushController = new BrushController(api.getZr())).on('brush', bind(this._onBrush, this));
      };

      ParallelAxisView.prototype.render = function (axisModel, ecModel, api, payload) {
        if (fromAxisAreaSelect(axisModel, ecModel, payload)) {
          return;
        }

        this.axisModel = axisModel;
        this.api = api;
        this.group.removeAll();
        var oldAxisGroup = this._axisGroup;
        this._axisGroup = new Group();
        this.group.add(this._axisGroup);

        if (!axisModel.get('show')) {
          return;
        }

        var coordSysModel = getCoordSysModel(axisModel, ecModel);
        var coordSys = coordSysModel.coordinateSystem;
        var areaSelectStyle = axisModel.getAreaSelectStyle();
        var areaWidth = areaSelectStyle.width;
        var dim = axisModel.axis.dim;
        var axisLayout = coordSys.getAxisLayout(dim);
        var builderOpt = extend({
          strokeContainThreshold: areaWidth
        }, axisLayout);
        var axisBuilder = new AxisBuilder(axisModel, builderOpt);
        each(elementList, axisBuilder.add, axisBuilder);

        this._axisGroup.add(axisBuilder.getGroup());

        this._refreshBrushController(builderOpt, areaSelectStyle, axisModel, coordSysModel, areaWidth, api);

        groupTransition(oldAxisGroup, this._axisGroup, axisModel);
      }; // /**
      //  * @override
      //  */
      // updateVisual(axisModel, ecModel, api, payload) {
      //     this._brushController && this._brushController
      //         .updateCovers(getCoverInfoList(axisModel));
      // }


      ParallelAxisView.prototype._refreshBrushController = function (builderOpt, areaSelectStyle, axisModel, coordSysModel, areaWidth, api) {
        // After filtering, axis may change, select area needs to be update.
        var extent = axisModel.axis.getExtent();
        var extentLen = extent[1] - extent[0];
        var extra = Math.min(30, Math.abs(extentLen) * 0.1); // Arbitrary value.
        // width/height might be negative, which will be
        // normalized in BoundingRect.

        var rect = BoundingRect.create({
          x: extent[0],
          y: -areaWidth / 2,
          width: extentLen,
          height: areaWidth
        });
        rect.x -= extra;
        rect.width += 2 * extra;

        this._brushController.mount({
          enableGlobalPan: true,
          rotation: builderOpt.rotation,
          x: builderOpt.position[0],
          y: builderOpt.position[1]
        }).setPanels([{
          panelId: 'pl',
          clipPath: makeRectPanelClipPath(rect),
          isTargetByCursor: makeRectIsTargetByCursor(rect, api, coordSysModel),
          getLinearBrushOtherExtent: makeLinearBrushOtherExtent(rect, 0)
        }]).enableBrush({
          brushType: 'lineX',
          brushStyle: areaSelectStyle,
          removeOnClick: true
        }).updateCovers(getCoverInfoList(axisModel));
      };

      ParallelAxisView.prototype._onBrush = function (eventParam) {
        var coverInfoList = eventParam.areas; // Do not cache these object, because the mey be changed.

        var axisModel = this.axisModel;
        var axis = axisModel.axis;
        var intervals = map(coverInfoList, function (coverInfo) {
          return [axis.coordToData(coverInfo.range[0], true), axis.coordToData(coverInfo.range[1], true)];
        }); // If realtime is true, action is not dispatched on drag end, because
        // the drag end emits the same params with the last drag move event,
        // and may have some delay when using touch pad.

        if (!axisModel.option.realtime === eventParam.isEnd || eventParam.removeOnClick) {
          // jshint ignore:line
          this.api.dispatchAction({
            type: 'axisAreaSelect',
            parallelAxisId: axisModel.id,
            intervals: intervals
          });
        }
      };

      ParallelAxisView.prototype.dispose = function () {
        this._brushController.dispose();
      };

      ParallelAxisView.type = 'parallelAxis';
      return ParallelAxisView;
    }(ComponentView);

    function fromAxisAreaSelect(axisModel, ecModel, payload) {
      return payload && payload.type === 'axisAreaSelect' && ecModel.findComponents({
        mainType: 'parallelAxis',
        query: payload
      })[0] === axisModel;
    }

    function getCoverInfoList(axisModel) {
      var axis = axisModel.axis;
      return map(axisModel.activeIntervals, function (interval) {
        return {
          brushType: 'lineX',
          panelId: 'pl',
          range: [axis.dataToCoord(interval[0], true), axis.dataToCoord(interval[1], true)]
        };
      });
    }

    function getCoordSysModel(axisModel, ecModel) {
      return ecModel.getComponent('parallel', axisModel.get('parallelIndex'));
    }

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


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * 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 actionInfo$1 = {
      type: 'axisAreaSelect',
      event: 'axisAreaSelected' // update: 'updateVisual'

    };
    function installParallelActions(registers) {
      registers.registerAction(actionInfo$1, function (payload, ecModel) {
        ecModel.eachComponent({
          mainType: 'parallelAxis',
          query: payload
        }, function (parallelAxisModel) {
          parallelAxisModel.axis.model.setActiveIntervals(payload.intervals);
        });
      });
      /**
       * @payload
       */

      registers.registerAction('parallelAxisExpand', function (payload, ecModel) {
        ecModel.eachComponent({
          mainType: 'parallel',
          query: payload
        }, function (parallelModel) {
          parallelModel.setAxisExpand(payload);
        });
      });
    }

    var defaultAxisOption = {
      type: 'value',
      areaSelectStyle: {
        width: 20,
        borderWidth: 1,
        borderColor: 'rgba(160,197,232)',
        color: 'rgba(160,197,232)',
        opacity: 0.3
      },
      realtime: true,
      z: 10
    };
    function install$g(registers) {
      registers.registerComponentView(ParallelView$1);
      registers.registerComponentModel(ParallelModel);
      registers.registerCoordinateSystem('parallel', parallelCoordSysCreator);
      registers.registerPreprocessor(parallelPreprocessor);
      registers.registerComponentModel(ParallelAxisModel);
      registers.registerComponentView(ParallelAxisView);
      axisModelCreator(registers, 'parallel', ParallelAxisModel, defaultAxisOption);
      installParallelActions(registers);
    }

    function install$h(registers) {
      use(install$g);
      registers.registerChartView(ParallelView);
      registers.registerSeriesModel(ParallelSeriesModel);
      registers.registerVisual(registers.PRIORITY.VISUAL.BRUSH, parallelVisual);
    }

    var SankeyPathShape =
    /** @class */
    function () {
      function SankeyPathShape() {
        this.x1 = 0;
        this.y1 = 0;
        this.x2 = 0;
        this.y2 = 0;
        this.cpx1 = 0;
        this.cpy1 = 0;
        this.cpx2 = 0;
        this.cpy2 = 0;
        this.extent = 0;
      }

      return SankeyPathShape;
    }();

    var SankeyPath =
    /** @class */
    function (_super) {
      __extends(SankeyPath, _super);

      function SankeyPath(opts) {
        return _super.call(this, opts) || this;
      }

      SankeyPath.prototype.getDefaultShape = function () {
        return new SankeyPathShape();
      };

      SankeyPath.prototype.buildPath = function (ctx, shape) {
        var extent = shape.extent;
        ctx.moveTo(shape.x1, shape.y1);
        ctx.bezierCurveTo(shape.cpx1, shape.cpy1, shape.cpx2, shape.cpy2, shape.x2, shape.y2);

        if (shape.orient === 'vertical') {
          ctx.lineTo(shape.x2 + extent, shape.y2);
          ctx.bezierCurveTo(shape.cpx2 + extent, shape.cpy2, shape.cpx1 + extent, shape.cpy1, shape.x1 + extent, shape.y1);
        } else {
          ctx.lineTo(shape.x2, shape.y2 + extent);
          ctx.bezierCurveTo(shape.cpx2, shape.cpy2 + extent, shape.cpx1, shape.cpy1 + extent, shape.x1, shape.y1 + extent);
        }

        ctx.closePath();
      };

      SankeyPath.prototype.highlight = function () {
        enterEmphasis(this);
      };

      SankeyPath.prototype.downplay = function () {
        leaveEmphasis(this);
      };

      return SankeyPath;
    }(Path);

    var SankeyView =
    /** @class */
    function (_super) {
      __extends(SankeyView, _super);

      function SankeyView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = SankeyView.type;
        _this._focusAdjacencyDisabled = false;
        return _this;
      }

      SankeyView.prototype.render = function (seriesModel, ecModel, api) {
        var sankeyView = this;
        var graph = seriesModel.getGraph();
        var group = this.group;
        var layoutInfo = seriesModel.layoutInfo; // view width

        var width = layoutInfo.width; // view height

        var height = layoutInfo.height;
        var nodeData = seriesModel.getData();
        var edgeData = seriesModel.getData('edge');
        var orient = seriesModel.get('orient');
        this._model = seriesModel;
        group.removeAll();
        group.x = layoutInfo.x;
        group.y = layoutInfo.y; // generate a bezire Curve for each edge

        graph.eachEdge(function (edge) {
          var curve = new SankeyPath();
          var ecData = getECData(curve);
          ecData.dataIndex = edge.dataIndex;
          ecData.seriesIndex = seriesModel.seriesIndex;
          ecData.dataType = 'edge';
          var edgeModel = edge.getModel();
          var lineStyleModel = edgeModel.getModel('lineStyle');
          var curvature = lineStyleModel.get('curveness');
          var n1Layout = edge.node1.getLayout();
          var node1Model = edge.node1.getModel();
          var dragX1 = node1Model.get('localX');
          var dragY1 = node1Model.get('localY');
          var n2Layout = edge.node2.getLayout();
          var node2Model = edge.node2.getModel();
          var dragX2 = node2Model.get('localX');
          var dragY2 = node2Model.get('localY');
          var edgeLayout = edge.getLayout();
          var x1;
          var y1;
          var x2;
          var y2;
          var cpx1;
          var cpy1;
          var cpx2;
          var cpy2;
          curve.shape.extent = Math.max(1, edgeLayout.dy);
          curve.shape.orient = orient;

          if (orient === 'vertical') {
            x1 = (dragX1 != null ? dragX1 * width : n1Layout.x) + edgeLayout.sy;
            y1 = (dragY1 != null ? dragY1 * height : n1Layout.y) + n1Layout.dy;
            x2 = (dragX2 != null ? dragX2 * width : n2Layout.x) + edgeLayout.ty;
            y2 = dragY2 != null ? dragY2 * height : n2Layout.y;
            cpx1 = x1;
            cpy1 = y1 * (1 - curvature) + y2 * curvature;
            cpx2 = x2;
            cpy2 = y1 * curvature + y2 * (1 - curvature);
          } else {
            x1 = (dragX1 != null ? dragX1 * width : n1Layout.x) + n1Layout.dx;
            y1 = (dragY1 != null ? dragY1 * height : n1Layout.y) + edgeLayout.sy;
            x2 = dragX2 != null ? dragX2 * width : n2Layout.x;
            y2 = (dragY2 != null ? dragY2 * height : n2Layout.y) + edgeLayout.ty;
            cpx1 = x1 * (1 - curvature) + x2 * curvature;
            cpy1 = y1;
            cpx2 = x1 * curvature + x2 * (1 - curvature);
            cpy2 = y2;
          }

          curve.setShape({
            x1: x1,
            y1: y1,
            x2: x2,
            y2: y2,
            cpx1: cpx1,
            cpy1: cpy1,
            cpx2: cpx2,
            cpy2: cpy2
          });
          curve.useStyle(lineStyleModel.getItemStyle()); // Special color, use source node color or target node color

          switch (curve.style.fill) {
            case 'source':
              curve.style.fill = edge.node1.getVisual('color');
              curve.style.decal = edge.node1.getVisual('style').decal;
              break;

            case 'target':
              curve.style.fill = edge.node2.getVisual('color');
              curve.style.decal = edge.node2.getVisual('style').decal;
              break;

            case 'gradient':
              var sourceColor = edge.node1.getVisual('color');
              var targetColor = edge.node2.getVisual('color');

              if (isString(sourceColor) && isString(targetColor)) {
                curve.style.fill = new LinearGradient(0, 0, +(orient === 'horizontal'), +(orient === 'vertical'), [{
                  color: sourceColor,
                  offset: 0
                }, {
                  color: targetColor,
                  offset: 1
                }]);
              }

          }

          setLabelStyle(curve, getLabelStatesModels(edgeModel, 'edgeLabel'), {
            labelFetcher: seriesModel,
            labelDataIndex: edge.dataIndex,
            defaultText: "" + edgeModel.get('value')
          });
          curve.setTextConfig({
            position: 'inside'
          });
          var emphasisModel = edgeModel.getModel('emphasis');
          setStatesStylesFromModel(curve, edgeModel, 'lineStyle', function (model) {
            return model.getItemStyle();
          });
          group.add(curve);
          edgeData.setItemGraphicEl(edge.dataIndex, curve);
          var focus = emphasisModel.get('focus');
          toggleHoverEmphasis(curve, focus === 'adjacency' ? edge.getAdjacentDataIndices() : focus, emphasisModel.get('blurScope'), emphasisModel.get('disabled'));
          getECData(curve).dataType = 'edge';
        }); // Generate a rect for each node

        graph.eachNode(function (node) {
          var layout = node.getLayout();
          var itemModel = node.getModel();
          var dragX = itemModel.get('localX');
          var dragY = itemModel.get('localY');
          var emphasisModel = itemModel.getModel('emphasis');
          var rect = new Rect({
            shape: {
              x: dragX != null ? dragX * width : layout.x,
              y: dragY != null ? dragY * height : layout.y,
              width: layout.dx,
              height: layout.dy
            },
            style: itemModel.getModel('itemStyle').getItemStyle(),
            z2: 10
          });
          setLabelStyle(rect, getLabelStatesModels(itemModel), {
            labelFetcher: seriesModel,
            labelDataIndex: node.dataIndex,
            defaultText: node.id
          });
          rect.disableLabelAnimation = true;
          rect.setStyle('fill', node.getVisual('color'));
          rect.setStyle('decal', node.getVisual('style').decal);
          setStatesStylesFromModel(rect, itemModel);
          group.add(rect);
          nodeData.setItemGraphicEl(node.dataIndex, rect);
          getECData(rect).dataType = 'node';
          var focus = emphasisModel.get('focus');
          toggleHoverEmphasis(rect, focus === 'adjacency' ? node.getAdjacentDataIndices() : focus, emphasisModel.get('blurScope'), emphasisModel.get('disabled'));
        });
        nodeData.eachItemGraphicEl(function (el, dataIndex) {
          var itemModel = nodeData.getItemModel(dataIndex);

          if (itemModel.get('draggable')) {
            el.drift = function (dx, dy) {
              sankeyView._focusAdjacencyDisabled = true;
              this.shape.x += dx;
              this.shape.y += dy;
              this.dirty();
              api.dispatchAction({
                type: 'dragNode',
                seriesId: seriesModel.id,
                dataIndex: nodeData.getRawIndex(dataIndex),
                localX: this.shape.x / width,
                localY: this.shape.y / height
              });
            };

            el.ondragend = function () {
              sankeyView._focusAdjacencyDisabled = false;
            };

            el.draggable = true;
            el.cursor = 'move';
          }
        });

        if (!this._data && seriesModel.isAnimationEnabled()) {
          group.setClipPath(createGridClipShape$1(group.getBoundingRect(), seriesModel, function () {
            group.removeClipPath();
          }));
        }

        this._data = seriesModel.getData();
      };

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

      SankeyView.type = 'sankey';
      return SankeyView;
    }(ChartView); // Add animation to the view


    function createGridClipShape$1(rect, seriesModel, cb) {
      var rectEl = new Rect({
        shape: {
          x: rect.x - 10,
          y: rect.y - 10,
          width: 0,
          height: rect.height + 20
        }
      });
      initProps(rectEl, {
        shape: {
          width: rect.width + 20
        }
      }, seriesModel, cb);
      return rectEl;
    }

    var SankeySeriesModel =
    /** @class */
    function (_super) {
      __extends(SankeySeriesModel, _super);

      function SankeySeriesModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = SankeySeriesModel.type;
        return _this;
      }
      /**
       * Init a graph data structure from data in option series
       */


      SankeySeriesModel.prototype.getInitialData = function (option, ecModel) {
        var links = option.edges || option.links;
        var nodes = option.data || option.nodes;
        var levels = option.levels;
        this.levelModels = [];
        var levelModels = this.levelModels;

        for (var i = 0; i < levels.length; i++) {
          if (levels[i].depth != null && levels[i].depth >= 0) {
            levelModels[levels[i].depth] = new Model(levels[i], this, ecModel);
          } else {
            if ("development" !== 'production') {
              throw new Error('levels[i].depth is mandatory and should be natural number');
            }
          }
        }

        if (nodes && links) {
          var graph = createGraphFromNodeEdge(nodes, links, this, true, beforeLink);
          return graph.data;
        }

        function beforeLink(nodeData, edgeData) {
          nodeData.wrapMethod('getItemModel', function (model, idx) {
            var seriesModel = model.parentModel;
            var layout = seriesModel.getData().getItemLayout(idx);

            if (layout) {
              var nodeDepth = layout.depth;
              var levelModel = seriesModel.levelModels[nodeDepth];

              if (levelModel) {
                model.parentModel = levelModel;
              }
            }

            return model;
          });
          edgeData.wrapMethod('getItemModel', function (model, idx) {
            var seriesModel = model.parentModel;
            var edge = seriesModel.getGraph().getEdgeByIndex(idx);
            var layout = edge.node1.getLayout();

            if (layout) {
              var depth = layout.depth;
              var levelModel = seriesModel.levelModels[depth];

              if (levelModel) {
                model.parentModel = levelModel;
              }
            }

            return model;
          });
        }
      };

      SankeySeriesModel.prototype.setNodePosition = function (dataIndex, localPosition) {
        var nodes = this.option.data || this.option.nodes;
        var dataItem = nodes[dataIndex];
        dataItem.localX = localPosition[0];
        dataItem.localY = localPosition[1];
      };
      /**
       * Return the graphic data structure
       *
       * @return graphic data structure
       */


      SankeySeriesModel.prototype.getGraph = function () {
        return this.getData().graph;
      };
      /**
       * Get edge data of graphic data structure
       *
       * @return data structure of list
       */


      SankeySeriesModel.prototype.getEdgeData = function () {
        return this.getGraph().edgeData;
      };

      SankeySeriesModel.prototype.formatTooltip = function (dataIndex, multipleSeries, dataType) {
        function noValue(val) {
          return isNaN(val) || val == null;
        } // dataType === 'node' or empty do not show tooltip by default


        if (dataType === 'edge') {
          var params = this.getDataParams(dataIndex, dataType);
          var rawDataOpt = params.data;
          var edgeValue = params.value;
          var edgeName = rawDataOpt.source + ' -- ' + rawDataOpt.target;
          return createTooltipMarkup('nameValue', {
            name: edgeName,
            value: edgeValue,
            noValue: noValue(edgeValue)
          });
        } // dataType === 'node'
        else {
            var node = this.getGraph().getNodeByIndex(dataIndex);
            var value = node.getLayout().value;
            var name_1 = this.getDataParams(dataIndex, dataType).data.name;
            return createTooltipMarkup('nameValue', {
              name: name_1 != null ? name_1 + '' : null,
              value: value,
              noValue: noValue(value)
            });
          }
      };

      SankeySeriesModel.prototype.optionUpdated = function () {}; // Override Series.getDataParams()


      SankeySeriesModel.prototype.getDataParams = function (dataIndex, dataType) {
        var params = _super.prototype.getDataParams.call(this, dataIndex, dataType);

        if (params.value == null && dataType === 'node') {
          var node = this.getGraph().getNodeByIndex(dataIndex);
          var nodeValue = node.getLayout().value;
          params.value = nodeValue;
        }

        return params;
      };

      SankeySeriesModel.type = 'series.sankey';
      SankeySeriesModel.defaultOption = {
        // zlevel: 0,
        z: 2,
        coordinateSystem: 'view',
        left: '5%',
        top: '5%',
        right: '20%',
        bottom: '5%',
        orient: 'horizontal',
        nodeWidth: 20,
        nodeGap: 8,
        draggable: true,
        layoutIterations: 32,
        label: {
          show: true,
          position: 'right',
          fontSize: 12
        },
        edgeLabel: {
          show: false,
          fontSize: 12
        },
        levels: [],
        nodeAlign: 'justify',
        lineStyle: {
          color: '#314656',
          opacity: 0.2,
          curveness: 0.5
        },
        emphasis: {
          label: {
            show: true
          },
          lineStyle: {
            opacity: 0.5
          }
        },
        select: {
          itemStyle: {
            borderColor: '#212121'
          }
        },
        animationEasing: 'linear',
        animationDuration: 1000
      };
      return SankeySeriesModel;
    }(SeriesModel);

    function sankeyLayout(ecModel, api) {
      ecModel.eachSeriesByType('sankey', function (seriesModel) {
        var nodeWidth = seriesModel.get('nodeWidth');
        var nodeGap = seriesModel.get('nodeGap');
        var layoutInfo = getViewRect$4(seriesModel, api);
        seriesModel.layoutInfo = layoutInfo;
        var width = layoutInfo.width;
        var height = layoutInfo.height;
        var graph = seriesModel.getGraph();
        var nodes = graph.nodes;
        var edges = graph.edges;
        computeNodeValues(nodes);
        var filteredNodes = filter(nodes, function (node) {
          return node.getLayout().value === 0;
        });
        var iterations = filteredNodes.length !== 0 ? 0 : seriesModel.get('layoutIterations');
        var orient = seriesModel.get('orient');
        var nodeAlign = seriesModel.get('nodeAlign');
        layoutSankey(nodes, edges, nodeWidth, nodeGap, width, height, iterations, orient, nodeAlign);
      });
    }
    /**
     * Get the layout position of the whole view
     */

    function getViewRect$4(seriesModel, api) {
      return getLayoutRect(seriesModel.getBoxLayoutParams(), {
        width: api.getWidth(),
        height: api.getHeight()
      });
    }

    function layoutSankey(nodes, edges, nodeWidth, nodeGap, width, height, iterations, orient, nodeAlign) {
      computeNodeBreadths(nodes, edges, nodeWidth, width, height, orient, nodeAlign);
      computeNodeDepths(nodes, edges, height, width, nodeGap, iterations, orient);
      computeEdgeDepths(nodes, orient);
    }
    /**
     * Compute the value of each node by summing the associated edge's value
     */


    function computeNodeValues(nodes) {
      each(nodes, function (node) {
        var value1 = sum(node.outEdges, getEdgeValue);
        var value2 = sum(node.inEdges, getEdgeValue);
        var nodeRawValue = node.getValue() || 0;
        var value = Math.max(value1, value2, nodeRawValue);
        node.setLayout({
          value: value
        }, true);
      });
    }
    /**
     * Compute the x-position for each node.
     *
     * Here we use Kahn algorithm to detect cycle when we traverse
     * the node to computer the initial x position.
     */


    function computeNodeBreadths(nodes, edges, nodeWidth, width, height, orient, nodeAlign) {
      // Used to mark whether the edge is deleted. if it is deleted,
      // the value is 0, otherwise it is 1.
      var remainEdges = []; // Storage each node's indegree.

      var indegreeArr = []; // Used to storage the node with indegree is equal to 0.

      var zeroIndegrees = [];
      var nextTargetNode = [];
      var x = 0; // let kx = 0;

      for (var i = 0; i < edges.length; i++) {
        remainEdges[i] = 1;
      }

      for (var i = 0; i < nodes.length; i++) {
        indegreeArr[i] = nodes[i].inEdges.length;

        if (indegreeArr[i] === 0) {
          zeroIndegrees.push(nodes[i]);
        }
      }

      var maxNodeDepth = -1; // Traversing nodes using topological sorting to calculate the
      // horizontal(if orient === 'horizontal') or vertical(if orient === 'vertical')
      // position of the nodes.

      while (zeroIndegrees.length) {
        for (var idx = 0; idx < zeroIndegrees.length; idx++) {
          var node = zeroIndegrees[idx];
          var item = node.hostGraph.data.getRawDataItem(node.dataIndex);
          var isItemDepth = item.depth != null && item.depth >= 0;

          if (isItemDepth && item.depth > maxNodeDepth) {
            maxNodeDepth = item.depth;
          }

          node.setLayout({
            depth: isItemDepth ? item.depth : x
          }, true);
          orient === 'vertical' ? node.setLayout({
            dy: nodeWidth
          }, true) : node.setLayout({
            dx: nodeWidth
          }, true);

          for (var edgeIdx = 0; edgeIdx < node.outEdges.length; edgeIdx++) {
            var edge = node.outEdges[edgeIdx];
            var indexEdge = edges.indexOf(edge);
            remainEdges[indexEdge] = 0;
            var targetNode = edge.node2;
            var nodeIndex = nodes.indexOf(targetNode);

            if (--indegreeArr[nodeIndex] === 0 && nextTargetNode.indexOf(targetNode) < 0) {
              nextTargetNode.push(targetNode);
            }
          }
        }

        ++x;
        zeroIndegrees = nextTargetNode;
        nextTargetNode = [];
      }

      for (var i = 0; i < remainEdges.length; i++) {
        if (remainEdges[i] === 1) {
          throw new Error('Sankey is a DAG, the original data has cycle!');
        }
      }

      var maxDepth = maxNodeDepth > x - 1 ? maxNodeDepth : x - 1;

      if (nodeAlign && nodeAlign !== 'left') {
        adjustNodeWithNodeAlign(nodes, nodeAlign, orient, maxDepth);
      }

      var kx = orient === 'vertical' ? (height - nodeWidth) / maxDepth : (width - nodeWidth) / maxDepth;
      scaleNodeBreadths(nodes, kx, orient);
    }

    function isNodeDepth(node) {
      var item = node.hostGraph.data.getRawDataItem(node.dataIndex);
      return item.depth != null && item.depth >= 0;
    }

    function adjustNodeWithNodeAlign(nodes, nodeAlign, orient, maxDepth) {
      if (nodeAlign === 'right') {
        var nextSourceNode = [];
        var remainNodes = nodes;
        var nodeHeight = 0;

        while (remainNodes.length) {
          for (var i = 0; i < remainNodes.length; i++) {
            var node = remainNodes[i];
            node.setLayout({
              skNodeHeight: nodeHeight
            }, true);

            for (var j = 0; j < node.inEdges.length; j++) {
              var edge = node.inEdges[j];

              if (nextSourceNode.indexOf(edge.node1) < 0) {
                nextSourceNode.push(edge.node1);
              }
            }
          }

          remainNodes = nextSourceNode;
          nextSourceNode = [];
          ++nodeHeight;
        }

        each(nodes, function (node) {
          if (!isNodeDepth(node)) {
            node.setLayout({
              depth: Math.max(0, maxDepth - node.getLayout().skNodeHeight)
            }, true);
          }
        });
      } else if (nodeAlign === 'justify') {
        moveSinksRight(nodes, maxDepth);
      }
    }
    /**
     * All the node without outEgdes are assigned maximum x-position and
     *     be aligned in the last column.
     *
     * @param nodes.  node of sankey view.
     * @param maxDepth.  use to assign to node without outEdges as x-position.
     */


    function moveSinksRight(nodes, maxDepth) {
      each(nodes, function (node) {
        if (!isNodeDepth(node) && !node.outEdges.length) {
          node.setLayout({
            depth: maxDepth
          }, true);
        }
      });
    }
    /**
     * Scale node x-position to the width
     *
     * @param nodes  node of sankey view
     * @param kx   multiple used to scale nodes
     */


    function scaleNodeBreadths(nodes, kx, orient) {
      each(nodes, function (node) {
        var nodeDepth = node.getLayout().depth * kx;
        orient === 'vertical' ? node.setLayout({
          y: nodeDepth
        }, true) : node.setLayout({
          x: nodeDepth
        }, true);
      });
    }
    /**
     * Using Gauss-Seidel iterations method to compute the node depth(y-position)
     *
     * @param nodes  node of sankey view
     * @param edges  edge of sankey view
     * @param height  the whole height of the area to draw the view
     * @param nodeGap  the vertical distance between two nodes
     *     in the same column.
     * @param iterations  the number of iterations for the algorithm
     */


    function computeNodeDepths(nodes, edges, height, width, nodeGap, iterations, orient) {
      var nodesByBreadth = prepareNodesByBreadth(nodes, orient);
      initializeNodeDepth(nodesByBreadth, edges, height, width, nodeGap, orient);
      resolveCollisions(nodesByBreadth, nodeGap, height, width, orient);

      for (var alpha = 1; iterations > 0; iterations--) {
        // 0.99 is a experience parameter, ensure that each iterations of
        // changes as small as possible.
        alpha *= 0.99;
        relaxRightToLeft(nodesByBreadth, alpha, orient);
        resolveCollisions(nodesByBreadth, nodeGap, height, width, orient);
        relaxLeftToRight(nodesByBreadth, alpha, orient);
        resolveCollisions(nodesByBreadth, nodeGap, height, width, orient);
      }
    }

    function prepareNodesByBreadth(nodes, orient) {
      var nodesByBreadth = [];
      var keyAttr = orient === 'vertical' ? 'y' : 'x';
      var groupResult = groupData(nodes, function (node) {
        return node.getLayout()[keyAttr];
      });
      groupResult.keys.sort(function (a, b) {
        return a - b;
      });
      each(groupResult.keys, function (key) {
        nodesByBreadth.push(groupResult.buckets.get(key));
      });
      return nodesByBreadth;
    }
    /**
     * Compute the original y-position for each node
     */


    function initializeNodeDepth(nodesByBreadth, edges, height, width, nodeGap, orient) {
      var minKy = Infinity;
      each(nodesByBreadth, function (nodes) {
        var n = nodes.length;
        var sum = 0;
        each(nodes, function (node) {
          sum += node.getLayout().value;
        });
        var ky = orient === 'vertical' ? (width - (n - 1) * nodeGap) / sum : (height - (n - 1) * nodeGap) / sum;

        if (ky < minKy) {
          minKy = ky;
        }
      });
      each(nodesByBreadth, function (nodes) {
        each(nodes, function (node, i) {
          var nodeDy = node.getLayout().value * minKy;

          if (orient === 'vertical') {
            node.setLayout({
              x: i
            }, true);
            node.setLayout({
              dx: nodeDy
            }, true);
          } else {
            node.setLayout({
              y: i
            }, true);
            node.setLayout({
              dy: nodeDy
            }, true);
          }
        });
      });
      each(edges, function (edge) {
        var edgeDy = +edge.getValue() * minKy;
        edge.setLayout({
          dy: edgeDy
        }, true);
      });
    }
    /**
     * Resolve the collision of initialized depth (y-position)
     */


    function resolveCollisions(nodesByBreadth, nodeGap, height, width, orient) {
      var keyAttr = orient === 'vertical' ? 'x' : 'y';
      each(nodesByBreadth, function (nodes) {
        nodes.sort(function (a, b) {
          return a.getLayout()[keyAttr] - b.getLayout()[keyAttr];
        });
        var nodeX;
        var node;
        var dy;
        var y0 = 0;
        var n = nodes.length;
        var nodeDyAttr = orient === 'vertical' ? 'dx' : 'dy';

        for (var i = 0; i < n; i++) {
          node = nodes[i];
          dy = y0 - node.getLayout()[keyAttr];

          if (dy > 0) {
            nodeX = node.getLayout()[keyAttr] + dy;
            orient === 'vertical' ? node.setLayout({
              x: nodeX
            }, true) : node.setLayout({
              y: nodeX
            }, true);
          }

          y0 = node.getLayout()[keyAttr] + node.getLayout()[nodeDyAttr] + nodeGap;
        }

        var viewWidth = orient === 'vertical' ? width : height; // If the bottommost node goes outside the bounds, push it back up

        dy = y0 - nodeGap - viewWidth;

        if (dy > 0) {
          nodeX = node.getLayout()[keyAttr] - dy;
          orient === 'vertical' ? node.setLayout({
            x: nodeX
          }, true) : node.setLayout({
            y: nodeX
          }, true);
          y0 = nodeX;

          for (var i = n - 2; i >= 0; --i) {
            node = nodes[i];
            dy = node.getLayout()[keyAttr] + node.getLayout()[nodeDyAttr] + nodeGap - y0;

            if (dy > 0) {
              nodeX = node.getLayout()[keyAttr] - dy;
              orient === 'vertical' ? node.setLayout({
                x: nodeX
              }, true) : node.setLayout({
                y: nodeX
              }, true);
            }

            y0 = node.getLayout()[keyAttr];
          }
        }
      });
    }
    /**
     * Change the y-position of the nodes, except most the right side nodes
     * @param nodesByBreadth
     * @param alpha  parameter used to adjust the nodes y-position
     */


    function relaxRightToLeft(nodesByBreadth, alpha, orient) {
      each(nodesByBreadth.slice().reverse(), function (nodes) {
        each(nodes, function (node) {
          if (node.outEdges.length) {
            var y = sum(node.outEdges, weightedTarget, orient) / sum(node.outEdges, getEdgeValue);

            if (isNaN(y)) {
              var len = node.outEdges.length;
              y = len ? sum(node.outEdges, centerTarget, orient) / len : 0;
            }

            if (orient === 'vertical') {
              var nodeX = node.getLayout().x + (y - center$1(node, orient)) * alpha;
              node.setLayout({
                x: nodeX
              }, true);
            } else {
              var nodeY = node.getLayout().y + (y - center$1(node, orient)) * alpha;
              node.setLayout({
                y: nodeY
              }, true);
            }
          }
        });
      });
    }

    function weightedTarget(edge, orient) {
      return center$1(edge.node2, orient) * edge.getValue();
    }

    function centerTarget(edge, orient) {
      return center$1(edge.node2, orient);
    }

    function weightedSource(edge, orient) {
      return center$1(edge.node1, orient) * edge.getValue();
    }

    function centerSource(edge, orient) {
      return center$1(edge.node1, orient);
    }

    function center$1(node, orient) {
      return orient === 'vertical' ? node.getLayout().x + node.getLayout().dx / 2 : node.getLayout().y + node.getLayout().dy / 2;
    }

    function getEdgeValue(edge) {
      return edge.getValue();
    }

    function sum(array, cb, orient) {
      var sum = 0;
      var len = array.length;
      var i = -1;

      while (++i < len) {
        var value = +cb(array[i], orient);

        if (!isNaN(value)) {
          sum += value;
        }
      }

      return sum;
    }
    /**
     * Change the y-position of the nodes, except most the left side nodes
     */


    function relaxLeftToRight(nodesByBreadth, alpha, orient) {
      each(nodesByBreadth, function (nodes) {
        each(nodes, function (node) {
          if (node.inEdges.length) {
            var y = sum(node.inEdges, weightedSource, orient) / sum(node.inEdges, getEdgeValue);

            if (isNaN(y)) {
              var len = node.inEdges.length;
              y = len ? sum(node.inEdges, centerSource, orient) / len : 0;
            }

            if (orient === 'vertical') {
              var nodeX = node.getLayout().x + (y - center$1(node, orient)) * alpha;
              node.setLayout({
                x: nodeX
              }, true);
            } else {
              var nodeY = node.getLayout().y + (y - center$1(node, orient)) * alpha;
              node.setLayout({
                y: nodeY
              }, true);
            }
          }
        });
      });
    }
    /**
     * Compute the depth(y-position) of each edge
     */


    function computeEdgeDepths(nodes, orient) {
      var keyAttr = orient === 'vertical' ? 'x' : 'y';
      each(nodes, function (node) {
        node.outEdges.sort(function (a, b) {
          return a.node2.getLayout()[keyAttr] - b.node2.getLayout()[keyAttr];
        });
        node.inEdges.sort(function (a, b) {
          return a.node1.getLayout()[keyAttr] - b.node1.getLayout()[keyAttr];
        });
      });
      each(nodes, function (node) {
        var sy = 0;
        var ty = 0;
        each(node.outEdges, function (edge) {
          edge.setLayout({
            sy: sy
          }, true);
          sy += edge.getLayout().dy;
        });
        each(node.inEdges, function (edge) {
          edge.setLayout({
            ty: ty
          }, true);
          ty += edge.getLayout().dy;
        });
      });
    }

    function sankeyVisual(ecModel) {
      ecModel.eachSeriesByType('sankey', function (seriesModel) {
        var graph = seriesModel.getGraph();
        var nodes = graph.nodes;
        var edges = graph.edges;

        if (nodes.length) {
          var minValue_1 = Infinity;
          var maxValue_1 = -Infinity;
          each(nodes, function (node) {
            var nodeValue = node.getLayout().value;

            if (nodeValue < minValue_1) {
              minValue_1 = nodeValue;
            }

            if (nodeValue > maxValue_1) {
              maxValue_1 = nodeValue;
            }
          });
          each(nodes, function (node) {
            var mapping = new VisualMapping({
              type: 'color',
              mappingMethod: 'linear',
              dataExtent: [minValue_1, maxValue_1],
              visual: seriesModel.get('color')
            });
            var mapValueToColor = mapping.mapValueToVisual(node.getLayout().value);
            var customColor = node.getModel().get(['itemStyle', 'color']);

            if (customColor != null) {
              node.setVisual('color', customColor);
              node.setVisual('style', {
                fill: customColor
              });
            } else {
              node.setVisual('color', mapValueToColor);
              node.setVisual('style', {
                fill: mapValueToColor
              });
            }
          });
        }

        if (edges.length) {
          each(edges, function (edge) {
            var edgeStyle = edge.getModel().get('lineStyle');
            edge.setVisual('style', edgeStyle);
          });
        }
      });
    }

    function install$i(registers) {
      registers.registerChartView(SankeyView);
      registers.registerSeriesModel(SankeySeriesModel);
      registers.registerLayout(sankeyLayout);
      registers.registerVisual(sankeyVisual);
      registers.registerAction({
        type: 'dragNode',
        event: 'dragnode',
        // here can only use 'update' now, other value is not support in echarts.
        update: 'update'
      }, function (payload, ecModel) {
        ecModel.eachComponent({
          mainType: 'series',
          subType: 'sankey',
          query: payload
        }, function (seriesModel) {
          seriesModel.setNodePosition(payload.dataIndex, [payload.localX, payload.localY]);
        });
      });
    }

    var WhiskerBoxCommonMixin =
    /** @class */
    function () {
      function WhiskerBoxCommonMixin() {}
      /**
       * @override
       */


      WhiskerBoxCommonMixin.prototype.getInitialData = function (option, ecModel) {
        // When both types of xAxis and yAxis are 'value', layout is
        // needed to be specified by user. Otherwise, layout can be
        // judged by which axis is category.
        var ordinalMeta;
        var xAxisModel = ecModel.getComponent('xAxis', this.get('xAxisIndex'));
        var yAxisModel = ecModel.getComponent('yAxis', this.get('yAxisIndex'));
        var xAxisType = xAxisModel.get('type');
        var yAxisType = yAxisModel.get('type');
        var addOrdinal; // FIXME
        // Consider time axis.

        if (xAxisType === 'category') {
          option.layout = 'horizontal';
          ordinalMeta = xAxisModel.getOrdinalMeta();
          addOrdinal = true;
        } else if (yAxisType === 'category') {
          option.layout = 'vertical';
          ordinalMeta = yAxisModel.getOrdinalMeta();
          addOrdinal = true;
        } else {
          option.layout = option.layout || 'horizontal';
        }

        var coordDims = ['x', 'y'];
        var baseAxisDimIndex = option.layout === 'horizontal' ? 0 : 1;
        var baseAxisDim = this._baseAxisDim = coordDims[baseAxisDimIndex];
        var otherAxisDim = coordDims[1 - baseAxisDimIndex];
        var axisModels = [xAxisModel, yAxisModel];
        var baseAxisType = axisModels[baseAxisDimIndex].get('type');
        var otherAxisType = axisModels[1 - baseAxisDimIndex].get('type');
        var data = option.data; // Clone a new data for next setOption({}) usage.
        // Avoid modifying current data will affect further update.

        if (data && addOrdinal) {
          var newOptionData_1 = [];
          each(data, function (item, index) {
            var newItem;

            if (isArray(item)) {
              newItem = item.slice(); // Modify current using data.

              item.unshift(index);
            } else if (isArray(item.value)) {
              newItem = extend({}, item);
              newItem.value = newItem.value.slice(); // Modify current using data.

              item.value.unshift(index);
            } else {
              newItem = item;
            }

            newOptionData_1.push(newItem);
          });
          option.data = newOptionData_1;
        }

        var defaultValueDimensions = this.defaultValueDimensions;
        var coordDimensions = [{
          name: baseAxisDim,
          type: getDimensionTypeByAxis(baseAxisType),
          ordinalMeta: ordinalMeta,
          otherDims: {
            tooltip: false,
            itemName: 0
          },
          dimsDef: ['base']
        }, {
          name: otherAxisDim,
          type: getDimensionTypeByAxis(otherAxisType),
          dimsDef: defaultValueDimensions.slice()
        }];
        return createSeriesDataSimply(this, {
          coordDimensions: coordDimensions,
          dimensionsCount: defaultValueDimensions.length + 1,
          encodeDefaulter: curry(makeSeriesEncodeForAxisCoordSys, coordDimensions, this)
        });
      };
      /**
       * If horizontal, base axis is x, otherwise y.
       * @override
       */


      WhiskerBoxCommonMixin.prototype.getBaseAxis = function () {
        var dim = this._baseAxisDim;
        return this.ecModel.getComponent(dim + 'Axis', this.get(dim + 'AxisIndex')).axis;
      };

      return WhiskerBoxCommonMixin;
    }();

    var BoxplotSeriesModel =
    /** @class */
    function (_super) {
      __extends(BoxplotSeriesModel, _super);

      function BoxplotSeriesModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = BoxplotSeriesModel.type; // TODO
        // box width represents group size, so dimension should have 'size'.

        /**
         * @see <https://en.wikipedia.org/wiki/Box_plot>
         * The meanings of 'min' and 'max' depend on user,
         * and echarts do not need to know it.
         * @readOnly
         */

        _this.defaultValueDimensions = [{
          name: 'min',
          defaultTooltip: true
        }, {
          name: 'Q1',
          defaultTooltip: true
        }, {
          name: 'median',
          defaultTooltip: true
        }, {
          name: 'Q3',
          defaultTooltip: true
        }, {
          name: 'max',
          defaultTooltip: true
        }];
        _this.visualDrawType = 'stroke';
        return _this;
      }

      BoxplotSeriesModel.type = 'series.boxplot';
      BoxplotSeriesModel.dependencies = ['xAxis', 'yAxis', 'grid'];
      BoxplotSeriesModel.defaultOption = {
        // zlevel: 0,
        z: 2,
        coordinateSystem: 'cartesian2d',
        legendHoverLink: true,
        layout: null,
        boxWidth: [7, 50],
        itemStyle: {
          color: '#fff',
          borderWidth: 1
        },
        emphasis: {
          scale: true,
          itemStyle: {
            borderWidth: 2,
            shadowBlur: 5,
            shadowOffsetX: 1,
            shadowOffsetY: 1,
            shadowColor: 'rgba(0,0,0,0.2)'
          }
        },
        animationDuration: 800
      };
      return BoxplotSeriesModel;
    }(SeriesModel);

    mixin(BoxplotSeriesModel, WhiskerBoxCommonMixin, true);

    var BoxplotView =
    /** @class */
    function (_super) {
      __extends(BoxplotView, _super);

      function BoxplotView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = BoxplotView.type;
        return _this;
      }

      BoxplotView.prototype.render = function (seriesModel, ecModel, api) {
        var data = seriesModel.getData();
        var group = this.group;
        var oldData = this._data; // There is no old data only when first rendering or switching from
        // stream mode to normal mode, where previous elements should be removed.

        if (!this._data) {
          group.removeAll();
        }

        var constDim = seriesModel.get('layout') === 'horizontal' ? 1 : 0;
        data.diff(oldData).add(function (newIdx) {
          if (data.hasValue(newIdx)) {
            var itemLayout = data.getItemLayout(newIdx);
            var symbolEl = createNormalBox(itemLayout, data, newIdx, constDim, true);
            data.setItemGraphicEl(newIdx, symbolEl);
            group.add(symbolEl);
          }
        }).update(function (newIdx, oldIdx) {
          var symbolEl = oldData.getItemGraphicEl(oldIdx); // Empty data

          if (!data.hasValue(newIdx)) {
            group.remove(symbolEl);
            return;
          }

          var itemLayout = data.getItemLayout(newIdx);

          if (!symbolEl) {
            symbolEl = createNormalBox(itemLayout, data, newIdx, constDim);
          } else {
            saveOldStyle(symbolEl);
            updateNormalBoxData(itemLayout, symbolEl, data, newIdx);
          }

          group.add(symbolEl);
          data.setItemGraphicEl(newIdx, symbolEl);
        }).remove(function (oldIdx) {
          var el = oldData.getItemGraphicEl(oldIdx);
          el && group.remove(el);
        }).execute();
        this._data = data;
      };

      BoxplotView.prototype.remove = function (ecModel) {
        var group = this.group;
        var data = this._data;
        this._data = null;
        data && data.eachItemGraphicEl(function (el) {
          el && group.remove(el);
        });
      };

      BoxplotView.type = 'boxplot';
      return BoxplotView;
    }(ChartView);

    var BoxPathShape =
    /** @class */
    function () {
      function BoxPathShape() {}

      return BoxPathShape;
    }();

    var BoxPath =
    /** @class */
    function (_super) {
      __extends(BoxPath, _super);

      function BoxPath(opts) {
        var _this = _super.call(this, opts) || this;

        _this.type = 'boxplotBoxPath';
        return _this;
      }

      BoxPath.prototype.getDefaultShape = function () {
        return new BoxPathShape();
      };

      BoxPath.prototype.buildPath = function (ctx, shape) {
        var ends = shape.points;
        var i = 0;
        ctx.moveTo(ends[i][0], ends[i][1]);
        i++;

        for (; i < 4; i++) {
          ctx.lineTo(ends[i][0], ends[i][1]);
        }

        ctx.closePath();

        for (; i < ends.length; i++) {
          ctx.moveTo(ends[i][0], ends[i][1]);
          i++;
          ctx.lineTo(ends[i][0], ends[i][1]);
        }
      };

      return BoxPath;
    }(Path);

    function createNormalBox(itemLayout, data, dataIndex, constDim, isInit) {
      var ends = itemLayout.ends;
      var el = new BoxPath({
        shape: {
          points: isInit ? transInit(ends, constDim, itemLayout) : ends
        }
      });
      updateNormalBoxData(itemLayout, el, data, dataIndex, isInit);
      return el;
    }

    function updateNormalBoxData(itemLayout, el, data, dataIndex, isInit) {
      var seriesModel = data.hostModel;
      var updateMethod = graphic[isInit ? 'initProps' : 'updateProps'];
      updateMethod(el, {
        shape: {
          points: itemLayout.ends
        }
      }, seriesModel, dataIndex);
      el.useStyle(data.getItemVisual(dataIndex, 'style'));
      el.style.strokeNoScale = true;
      el.z2 = 100;
      var itemModel = data.getItemModel(dataIndex);
      var emphasisModel = itemModel.getModel('emphasis');
      setStatesStylesFromModel(el, itemModel);
      toggleHoverEmphasis(el, emphasisModel.get('focus'), emphasisModel.get('blurScope'), emphasisModel.get('disabled'));
    }

    function transInit(points, dim, itemLayout) {
      return map(points, function (point) {
        point = point.slice();
        point[dim] = itemLayout.initBaseline;
        return point;
      });
    }

    var each$6 = each;
    function boxplotLayout(ecModel) {
      var groupResult = groupSeriesByAxis(ecModel);
      each$6(groupResult, function (groupItem) {
        var seriesModels = groupItem.seriesModels;

        if (!seriesModels.length) {
          return;
        }

        calculateBase(groupItem);
        each$6(seriesModels, function (seriesModel, idx) {
          layoutSingleSeries(seriesModel, groupItem.boxOffsetList[idx], groupItem.boxWidthList[idx]);
        });
      });
    }
    /**
     * Group series by axis.
     */

    function groupSeriesByAxis(ecModel) {
      var result = [];
      var axisList = [];
      ecModel.eachSeriesByType('boxplot', function (seriesModel) {
        var baseAxis = seriesModel.getBaseAxis();
        var idx = indexOf(axisList, baseAxis);

        if (idx < 0) {
          idx = axisList.length;
          axisList[idx] = baseAxis;
          result[idx] = {
            axis: baseAxis,
            seriesModels: []
          };
        }

        result[idx].seriesModels.push(seriesModel);
      });
      return result;
    }
    /**
     * Calculate offset and box width for each series.
     */


    function calculateBase(groupItem) {
      var baseAxis = groupItem.axis;
      var seriesModels = groupItem.seriesModels;
      var seriesCount = seriesModels.length;
      var boxWidthList = groupItem.boxWidthList = [];
      var boxOffsetList = groupItem.boxOffsetList = [];
      var boundList = [];
      var bandWidth;

      if (baseAxis.type === 'category') {
        bandWidth = baseAxis.getBandWidth();
      } else {
        var maxDataCount_1 = 0;
        each$6(seriesModels, function (seriesModel) {
          maxDataCount_1 = Math.max(maxDataCount_1, seriesModel.getData().count());
        });
        var extent = baseAxis.getExtent();
        bandWidth = Math.abs(extent[1] - extent[0]) / maxDataCount_1;
      }

      each$6(seriesModels, function (seriesModel) {
        var boxWidthBound = seriesModel.get('boxWidth');

        if (!isArray(boxWidthBound)) {
          boxWidthBound = [boxWidthBound, boxWidthBound];
        }

        boundList.push([parsePercent$1(boxWidthBound[0], bandWidth) || 0, parsePercent$1(boxWidthBound[1], bandWidth) || 0]);
      });
      var availableWidth = bandWidth * 0.8 - 2;
      var boxGap = availableWidth / seriesCount * 0.3;
      var boxWidth = (availableWidth - boxGap * (seriesCount - 1)) / seriesCount;
      var base = boxWidth / 2 - availableWidth / 2;
      each$6(seriesModels, function (seriesModel, idx) {
        boxOffsetList.push(base);
        base += boxGap + boxWidth;
        boxWidthList.push(Math.min(Math.max(boxWidth, boundList[idx][0]), boundList[idx][1]));
      });
    }
    /**
     * Calculate points location for each series.
     */


    function layoutSingleSeries(seriesModel, offset, boxWidth) {
      var coordSys = seriesModel.coordinateSystem;
      var data = seriesModel.getData();
      var halfWidth = boxWidth / 2;
      var cDimIdx = seriesModel.get('layout') === 'horizontal' ? 0 : 1;
      var vDimIdx = 1 - cDimIdx;
      var coordDims = ['x', 'y'];
      var cDim = data.mapDimension(coordDims[cDimIdx]);
      var vDims = data.mapDimensionsAll(coordDims[vDimIdx]);

      if (cDim == null || vDims.length < 5) {
        return;
      }

      for (var dataIndex = 0; dataIndex < data.count(); dataIndex++) {
        var axisDimVal = data.get(cDim, dataIndex);
        var median = getPoint(axisDimVal, vDims[2], dataIndex);
        var end1 = getPoint(axisDimVal, vDims[0], dataIndex);
        var end2 = getPoint(axisDimVal, vDims[1], dataIndex);
        var end4 = getPoint(axisDimVal, vDims[3], dataIndex);
        var end5 = getPoint(axisDimVal, vDims[4], dataIndex);
        var ends = [];
        addBodyEnd(ends, end2, false);
        addBodyEnd(ends, end4, true);
        ends.push(end1, end2, end5, end4);
        layEndLine(ends, end1);
        layEndLine(ends, end5);
        layEndLine(ends, median);
        data.setItemLayout(dataIndex, {
          initBaseline: median[vDimIdx],
          ends: ends
        });
      }

      function getPoint(axisDimVal, dim, dataIndex) {
        var val = data.get(dim, dataIndex);
        var p = [];
        p[cDimIdx] = axisDimVal;
        p[vDimIdx] = val;
        var point;

        if (isNaN(axisDimVal) || isNaN(val)) {
          point = [NaN, NaN];
        } else {
          point = coordSys.dataToPoint(p);
          point[cDimIdx] += offset;
        }

        return point;
      }

      function addBodyEnd(ends, point, start) {
        var point1 = point.slice();
        var point2 = point.slice();
        point1[cDimIdx] += halfWidth;
        point2[cDimIdx] -= halfWidth;
        start ? ends.push(point1, point2) : ends.push(point2, point1);
      }

      function layEndLine(ends, endCenter) {
        var from = endCenter.slice();
        var to = endCenter.slice();
        from[cDimIdx] -= halfWidth;
        to[cDimIdx] += halfWidth;
        ends.push(from, to);
      }
    }

    /**
     * See:
     *  <https://en.wikipedia.org/wiki/Box_plot#cite_note-frigge_hoaglin_iglewicz-2>
     *  <http://stat.ethz.ch/R-manual/R-devel/library/grDevices/html/boxplot.stats.html>
     *
     * Helper method for preparing data.
     *
     * @param rawData like
     *        [
     *            [12,232,443], (raw data set for the first box)
     *            [3843,5545,1232], (raw data set for the second box)
     *            ...
     *        ]
     * @param opt.boundIQR=1.5 Data less than min bound is outlier.
     *      default 1.5, means Q1 - 1.5 * (Q3 - Q1).
     *      If 'none'/0 passed, min bound will not be used.
     */

    function prepareBoxplotData(rawData, opt) {
      opt = opt || {};
      var boxData = [];
      var outliers = [];
      var boundIQR = opt.boundIQR;
      var useExtreme = boundIQR === 'none' || boundIQR === 0;

      for (var i = 0; i < rawData.length; i++) {
        var ascList = asc(rawData[i].slice());
        var Q1 = quantile(ascList, 0.25);
        var Q2 = quantile(ascList, 0.5);
        var Q3 = quantile(ascList, 0.75);
        var min = ascList[0];
        var max = ascList[ascList.length - 1];
        var bound = (boundIQR == null ? 1.5 : boundIQR) * (Q3 - Q1);
        var low = useExtreme ? min : Math.max(min, Q1 - bound);
        var high = useExtreme ? max : Math.min(max, Q3 + bound);
        var itemNameFormatter = opt.itemNameFormatter;
        var itemName = isFunction(itemNameFormatter) ? itemNameFormatter({
          value: i
        }) : isString(itemNameFormatter) ? itemNameFormatter.replace('{value}', i + '') : i + '';
        boxData.push([itemName, low, Q1, Q2, Q3, high]);

        for (var j = 0; j < ascList.length; j++) {
          var dataItem = ascList[j];

          if (dataItem < low || dataItem > high) {
            var outlier = [itemName, dataItem];
            outliers.push(outlier);
          }
        }
      }

      return {
        boxData: boxData,
        outliers: outliers
      };
    }

    var boxplotTransform = {
      type: 'echarts:boxplot',
      transform: function transform(params) {
        var upstream = params.upstream;

        if (upstream.sourceFormat !== SOURCE_FORMAT_ARRAY_ROWS) {
          var errMsg = '';

          if ("development" !== 'production') {
            errMsg = makePrintable('source data is not applicable for this boxplot transform. Expect number[][].');
          }

          throwError(errMsg);
        }

        var result = prepareBoxplotData(upstream.getRawData(), params.config);
        return [{
          dimensions: ['ItemName', 'Low', 'Q1', 'Q2', 'Q3', 'High'],
          data: result.boxData
        }, {
          data: result.outliers
        }];
      }
    };

    function install$j(registers) {
      registers.registerSeriesModel(BoxplotSeriesModel);
      registers.registerChartView(BoxplotView);
      registers.registerLayout(boxplotLayout);
      registers.registerTransform(boxplotTransform);
    }

    var SKIP_PROPS = ['color', 'borderColor'];

    var CandlestickView =
    /** @class */
    function (_super) {
      __extends(CandlestickView, _super);

      function CandlestickView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = CandlestickView.type;
        return _this;
      }

      CandlestickView.prototype.render = function (seriesModel, ecModel, api) {
        // If there is clipPath created in large mode. Remove it.
        this.group.removeClipPath(); // Clear previously rendered progressive elements.

        this._progressiveEls = null;

        this._updateDrawMode(seriesModel);

        this._isLargeDraw ? this._renderLarge(seriesModel) : this._renderNormal(seriesModel);
      };

      CandlestickView.prototype.incrementalPrepareRender = function (seriesModel, ecModel, api) {
        this._clear();

        this._updateDrawMode(seriesModel);
      };

      CandlestickView.prototype.incrementalRender = function (params, seriesModel, ecModel, api) {
        this._progressiveEls = [];
        this._isLargeDraw ? this._incrementalRenderLarge(params, seriesModel) : this._incrementalRenderNormal(params, seriesModel);
      };

      CandlestickView.prototype.eachRendered = function (cb) {
        traverseElements(this._progressiveEls || this.group, cb);
      };

      CandlestickView.prototype._updateDrawMode = function (seriesModel) {
        var isLargeDraw = seriesModel.pipelineContext.large;

        if (this._isLargeDraw == null || isLargeDraw !== this._isLargeDraw) {
          this._isLargeDraw = isLargeDraw;

          this._clear();
        }
      };

      CandlestickView.prototype._renderNormal = function (seriesModel) {
        var data = seriesModel.getData();
        var oldData = this._data;
        var group = this.group;
        var isSimpleBox = data.getLayout('isSimpleBox');
        var needsClip = seriesModel.get('clip', true);
        var coord = seriesModel.coordinateSystem;
        var clipArea = coord.getArea && coord.getArea(); // There is no old data only when first rendering or switching from
        // stream mode to normal mode, where previous elements should be removed.

        if (!this._data) {
          group.removeAll();
        }

        data.diff(oldData).add(function (newIdx) {
          if (data.hasValue(newIdx)) {
            var itemLayout = data.getItemLayout(newIdx);

            if (needsClip && isNormalBoxClipped(clipArea, itemLayout)) {
              return;
            }

            var el = createNormalBox$1(itemLayout, newIdx, true);
            initProps(el, {
              shape: {
                points: itemLayout.ends
              }
            }, seriesModel, newIdx);
            setBoxCommon(el, data, newIdx, isSimpleBox);
            group.add(el);
            data.setItemGraphicEl(newIdx, el);
          }
        }).update(function (newIdx, oldIdx) {
          var el = oldData.getItemGraphicEl(oldIdx); // Empty data

          if (!data.hasValue(newIdx)) {
            group.remove(el);
            return;
          }

          var itemLayout = data.getItemLayout(newIdx);

          if (needsClip && isNormalBoxClipped(clipArea, itemLayout)) {
            group.remove(el);
            return;
          }

          if (!el) {
            el = createNormalBox$1(itemLayout);
          } else {
            updateProps(el, {
              shape: {
                points: itemLayout.ends
              }
            }, seriesModel, newIdx);
            saveOldStyle(el);
          }

          setBoxCommon(el, data, newIdx, isSimpleBox);
          group.add(el);
          data.setItemGraphicEl(newIdx, el);
        }).remove(function (oldIdx) {
          var el = oldData.getItemGraphicEl(oldIdx);
          el && group.remove(el);
        }).execute();
        this._data = data;
      };

      CandlestickView.prototype._renderLarge = function (seriesModel) {
        this._clear();

        createLarge$1(seriesModel, this.group);
        var clipPath = seriesModel.get('clip', true) ? createClipPath(seriesModel.coordinateSystem, false, seriesModel) : null;

        if (clipPath) {
          this.group.setClipPath(clipPath);
        } else {
          this.group.removeClipPath();
        }
      };

      CandlestickView.prototype._incrementalRenderNormal = function (params, seriesModel) {
        var data = seriesModel.getData();
        var isSimpleBox = data.getLayout('isSimpleBox');
        var dataIndex;

        while ((dataIndex = params.next()) != null) {
          var itemLayout = data.getItemLayout(dataIndex);
          var el = createNormalBox$1(itemLayout);
          setBoxCommon(el, data, dataIndex, isSimpleBox);
          el.incremental = true;
          this.group.add(el);

          this._progressiveEls.push(el);
        }
      };

      CandlestickView.prototype._incrementalRenderLarge = function (params, seriesModel) {
        createLarge$1(seriesModel, this.group, this._progressiveEls, true);
      };

      CandlestickView.prototype.remove = function (ecModel) {
        this._clear();
      };

      CandlestickView.prototype._clear = function () {
        this.group.removeAll();
        this._data = null;
      };

      CandlestickView.type = 'candlestick';
      return CandlestickView;
    }(ChartView);

    var NormalBoxPathShape =
    /** @class */
    function () {
      function NormalBoxPathShape() {}

      return NormalBoxPathShape;
    }();

    var NormalBoxPath =
    /** @class */
    function (_super) {
      __extends(NormalBoxPath, _super);

      function NormalBoxPath(opts) {
        var _this = _super.call(this, opts) || this;

        _this.type = 'normalCandlestickBox';
        return _this;
      }

      NormalBoxPath.prototype.getDefaultShape = function () {
        return new NormalBoxPathShape();
      };

      NormalBoxPath.prototype.buildPath = function (ctx, shape) {
        var ends = shape.points;

        if (this.__simpleBox) {
          ctx.moveTo(ends[4][0], ends[4][1]);
          ctx.lineTo(ends[6][0], ends[6][1]);
        } else {
          ctx.moveTo(ends[0][0], ends[0][1]);
          ctx.lineTo(ends[1][0], ends[1][1]);
          ctx.lineTo(ends[2][0], ends[2][1]);
          ctx.lineTo(ends[3][0], ends[3][1]);
          ctx.closePath();
          ctx.moveTo(ends[4][0], ends[4][1]);
          ctx.lineTo(ends[5][0], ends[5][1]);
          ctx.moveTo(ends[6][0], ends[6][1]);
          ctx.lineTo(ends[7][0], ends[7][1]);
        }
      };

      return NormalBoxPath;
    }(Path);

    function createNormalBox$1(itemLayout, dataIndex, isInit) {
      var ends = itemLayout.ends;
      return new NormalBoxPath({
        shape: {
          points: isInit ? transInit$1(ends, itemLayout) : ends
        },
        z2: 100
      });
    }

    function isNormalBoxClipped(clipArea, itemLayout) {
      var clipped = true;

      for (var i = 0; i < itemLayout.ends.length; i++) {
        // If any point are in the region.
        if (clipArea.contain(itemLayout.ends[i][0], itemLayout.ends[i][1])) {
          clipped = false;
          break;
        }
      }

      return clipped;
    }

    function setBoxCommon(el, data, dataIndex, isSimpleBox) {
      var itemModel = data.getItemModel(dataIndex);
      el.useStyle(data.getItemVisual(dataIndex, 'style'));
      el.style.strokeNoScale = true;
      el.__simpleBox = isSimpleBox;
      setStatesStylesFromModel(el, itemModel);
    }

    function transInit$1(points, itemLayout) {
      return map(points, function (point) {
        point = point.slice();
        point[1] = itemLayout.initBaseline;
        return point;
      });
    }

    var LargeBoxPathShape =
    /** @class */
    function () {
      function LargeBoxPathShape() {}

      return LargeBoxPathShape;
    }();

    var LargeBoxPath =
    /** @class */
    function (_super) {
      __extends(LargeBoxPath, _super);

      function LargeBoxPath(opts) {
        var _this = _super.call(this, opts) || this;

        _this.type = 'largeCandlestickBox';
        return _this;
      }

      LargeBoxPath.prototype.getDefaultShape = function () {
        return new LargeBoxPathShape();
      };

      LargeBoxPath.prototype.buildPath = function (ctx, shape) {
        // Drawing lines is more efficient than drawing
        // a whole line or drawing rects.
        var points = shape.points;

        for (var i = 0; i < points.length;) {
          if (this.__sign === points[i++]) {
            var x = points[i++];
            ctx.moveTo(x, points[i++]);
            ctx.lineTo(x, points[i++]);
          } else {
            i += 3;
          }
        }
      };

      return LargeBoxPath;
    }(Path);

    function createLarge$1(seriesModel, group, progressiveEls, incremental) {
      var data = seriesModel.getData();
      var largePoints = data.getLayout('largePoints');
      var elP = new LargeBoxPath({
        shape: {
          points: largePoints
        },
        __sign: 1,
        ignoreCoarsePointer: true
      });
      group.add(elP);
      var elN = new LargeBoxPath({
        shape: {
          points: largePoints
        },
        __sign: -1,
        ignoreCoarsePointer: true
      });
      group.add(elN);
      var elDoji = new LargeBoxPath({
        shape: {
          points: largePoints
        },
        __sign: 0,
        ignoreCoarsePointer: true
      });
      group.add(elDoji);
      setLargeStyle(1, elP, seriesModel);
      setLargeStyle(-1, elN, seriesModel);
      setLargeStyle(0, elDoji, seriesModel);

      if (incremental) {
        elP.incremental = true;
        elN.incremental = true;
      }

      if (progressiveEls) {
        progressiveEls.push(elP, elN);
      }
    }

    function setLargeStyle(sign, el, seriesModel, data) {
      // TODO put in visual?
      var borderColor = seriesModel.get(['itemStyle', sign > 0 ? 'borderColor' : 'borderColor0']) // Use color for border color by default.
      || seriesModel.get(['itemStyle', sign > 0 ? 'color' : 'color0']);

      if (sign === 0) {
        borderColor = seriesModel.get(['itemStyle', 'borderColorDoji']);
      } // Color must be excluded.
      // Because symbol provide setColor individually to set fill and stroke


      var itemStyle = seriesModel.getModel('itemStyle').getItemStyle(SKIP_PROPS);
      el.useStyle(itemStyle);
      el.style.fill = null;
      el.style.stroke = borderColor;
    }

    var CandlestickSeriesModel =
    /** @class */
    function (_super) {
      __extends(CandlestickSeriesModel, _super);

      function CandlestickSeriesModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = CandlestickSeriesModel.type;
        _this.defaultValueDimensions = [{
          name: 'open',
          defaultTooltip: true
        }, {
          name: 'close',
          defaultTooltip: true
        }, {
          name: 'lowest',
          defaultTooltip: true
        }, {
          name: 'highest',
          defaultTooltip: true
        }];
        return _this;
      }
      /**
       * Get dimension for shadow in dataZoom
       * @return dimension name
       */


      CandlestickSeriesModel.prototype.getShadowDim = function () {
        return 'open';
      };

      CandlestickSeriesModel.prototype.brushSelector = function (dataIndex, data, selectors) {
        var itemLayout = data.getItemLayout(dataIndex);
        return itemLayout && selectors.rect(itemLayout.brushRect);
      };

      CandlestickSeriesModel.type = 'series.candlestick';
      CandlestickSeriesModel.dependencies = ['xAxis', 'yAxis', 'grid'];
      CandlestickSeriesModel.defaultOption = {
        // zlevel: 0,
        z: 2,
        coordinateSystem: 'cartesian2d',
        legendHoverLink: true,
        // xAxisIndex: 0,
        // yAxisIndex: 0,
        layout: null,
        clip: true,
        itemStyle: {
          color: '#eb5454',
          color0: '#47b262',
          borderColor: '#eb5454',
          borderColor0: '#47b262',
          borderColorDoji: null,
          // borderColor: '#d24040',
          // borderColor0: '#398f4f',
          borderWidth: 1
        },
        emphasis: {
          scale: true,
          itemStyle: {
            borderWidth: 2
          }
        },
        barMaxWidth: null,
        barMinWidth: null,
        barWidth: null,
        large: true,
        largeThreshold: 600,
        progressive: 3e3,
        progressiveThreshold: 1e4,
        progressiveChunkMode: 'mod',
        animationEasing: 'linear',
        animationDuration: 300
      };
      return CandlestickSeriesModel;
    }(SeriesModel);

    mixin(CandlestickSeriesModel, WhiskerBoxCommonMixin, true);

    function candlestickPreprocessor(option) {
      if (!option || !isArray(option.series)) {
        return;
      } // Translate 'k' to 'candlestick'.


      each(option.series, function (seriesItem) {
        if (isObject(seriesItem) && seriesItem.type === 'k') {
          seriesItem.type = 'candlestick';
        }
      });
    }

    var positiveBorderColorQuery = ['itemStyle', 'borderColor'];
    var negativeBorderColorQuery = ['itemStyle', 'borderColor0'];
    var dojiBorderColorQuery = ['itemStyle', 'borderColorDoji'];
    var positiveColorQuery = ['itemStyle', 'color'];
    var negativeColorQuery = ['itemStyle', 'color0'];
    var candlestickVisual = {
      seriesType: 'candlestick',
      plan: createRenderPlanner(),
      // For legend.
      performRawSeries: true,
      reset: function (seriesModel, ecModel) {
        function getColor(sign, model) {
          return model.get(sign > 0 ? positiveColorQuery : negativeColorQuery);
        }

        function getBorderColor(sign, model) {
          return model.get(sign === 0 ? dojiBorderColorQuery : sign > 0 ? positiveBorderColorQuery : negativeBorderColorQuery);
        } // Only visible series has each data be visual encoded


        if (ecModel.isSeriesFiltered(seriesModel)) {
          return;
        }

        var isLargeRender = seriesModel.pipelineContext.large;
        return !isLargeRender && {
          progress: function (params, data) {
            var dataIndex;

            while ((dataIndex = params.next()) != null) {
              var itemModel = data.getItemModel(dataIndex);
              var sign = data.getItemLayout(dataIndex).sign;
              var style = itemModel.getItemStyle();
              style.fill = getColor(sign, itemModel);
              style.stroke = getBorderColor(sign, itemModel) || style.fill;
              var existsStyle = data.ensureUniqueItemVisual(dataIndex, 'style');
              extend(existsStyle, style);
            }
          }
        };
      }
    };

    var candlestickLayout = {
      seriesType: 'candlestick',
      plan: createRenderPlanner(),
      reset: function (seriesModel) {
        var coordSys = seriesModel.coordinateSystem;
        var data = seriesModel.getData();
        var candleWidth = calculateCandleWidth(seriesModel, data);
        var cDimIdx = 0;
        var vDimIdx = 1;
        var coordDims = ['x', 'y'];
        var cDimI = data.getDimensionIndex(data.mapDimension(coordDims[cDimIdx]));
        var vDimsI = map(data.mapDimensionsAll(coordDims[vDimIdx]), data.getDimensionIndex, data);
        var openDimI = vDimsI[0];
        var closeDimI = vDimsI[1];
        var lowestDimI = vDimsI[2];
        var highestDimI = vDimsI[3];
        data.setLayout({
          candleWidth: candleWidth,
          // The value is experimented visually.
          isSimpleBox: candleWidth <= 1.3
        });

        if (cDimI < 0 || vDimsI.length < 4) {
          return;
        }

        return {
          progress: seriesModel.pipelineContext.large ? largeProgress : normalProgress
        };

        function normalProgress(params, data) {
          var dataIndex;
          var store = data.getStore();

          while ((dataIndex = params.next()) != null) {
            var axisDimVal = store.get(cDimI, dataIndex);
            var openVal = store.get(openDimI, dataIndex);
            var closeVal = store.get(closeDimI, dataIndex);
            var lowestVal = store.get(lowestDimI, dataIndex);
            var highestVal = store.get(highestDimI, dataIndex);
            var ocLow = Math.min(openVal, closeVal);
            var ocHigh = Math.max(openVal, closeVal);
            var ocLowPoint = getPoint(ocLow, axisDimVal);
            var ocHighPoint = getPoint(ocHigh, axisDimVal);
            var lowestPoint = getPoint(lowestVal, axisDimVal);
            var highestPoint = getPoint(highestVal, axisDimVal);
            var ends = [];
            addBodyEnd(ends, ocHighPoint, 0);
            addBodyEnd(ends, ocLowPoint, 1);
            ends.push(subPixelOptimizePoint(highestPoint), subPixelOptimizePoint(ocHighPoint), subPixelOptimizePoint(lowestPoint), subPixelOptimizePoint(ocLowPoint));
            var itemModel = data.getItemModel(dataIndex);
            var hasDojiColor = !!itemModel.get(['itemStyle', 'borderColorDoji']);
            data.setItemLayout(dataIndex, {
              sign: getSign(store, dataIndex, openVal, closeVal, closeDimI, hasDojiColor),
              initBaseline: openVal > closeVal ? ocHighPoint[vDimIdx] : ocLowPoint[vDimIdx],
              ends: ends,
              brushRect: makeBrushRect(lowestVal, highestVal, axisDimVal)
            });
          }

          function getPoint(val, axisDimVal) {
            var p = [];
            p[cDimIdx] = axisDimVal;
            p[vDimIdx] = val;
            return isNaN(axisDimVal) || isNaN(val) ? [NaN, NaN] : coordSys.dataToPoint(p);
          }

          function addBodyEnd(ends, point, start) {
            var point1 = point.slice();
            var point2 = point.slice();
            point1[cDimIdx] = subPixelOptimize$1(point1[cDimIdx] + candleWidth / 2, 1, false);
            point2[cDimIdx] = subPixelOptimize$1(point2[cDimIdx] - candleWidth / 2, 1, true);
            start ? ends.push(point1, point2) : ends.push(point2, point1);
          }

          function makeBrushRect(lowestVal, highestVal, axisDimVal) {
            var pmin = getPoint(lowestVal, axisDimVal);
            var pmax = getPoint(highestVal, axisDimVal);
            pmin[cDimIdx] -= candleWidth / 2;
            pmax[cDimIdx] -= candleWidth / 2;
            return {
              x: pmin[0],
              y: pmin[1],
              width:  candleWidth ,
              height:  pmax[1] - pmin[1] 
            };
          }

          function subPixelOptimizePoint(point) {
            point[cDimIdx] = subPixelOptimize$1(point[cDimIdx], 1);
            return point;
          }
        }

        function largeProgress(params, data) {
          // Structure: [sign, x, yhigh, ylow, sign, x, yhigh, ylow, ...]
          var points = createFloat32Array(params.count * 4);
          var offset = 0;
          var point;
          var tmpIn = [];
          var tmpOut = [];
          var dataIndex;
          var store = data.getStore();
          var hasDojiColor = !!seriesModel.get(['itemStyle', 'borderColorDoji']);

          while ((dataIndex = params.next()) != null) {
            var axisDimVal = store.get(cDimI, dataIndex);
            var openVal = store.get(openDimI, dataIndex);
            var closeVal = store.get(closeDimI, dataIndex);
            var lowestVal = store.get(lowestDimI, dataIndex);
            var highestVal = store.get(highestDimI, dataIndex);

            if (isNaN(axisDimVal) || isNaN(lowestVal) || isNaN(highestVal)) {
              points[offset++] = NaN;
              offset += 3;
              continue;
            }

            points[offset++] = getSign(store, dataIndex, openVal, closeVal, closeDimI, hasDojiColor);
            tmpIn[cDimIdx] = axisDimVal;
            tmpIn[vDimIdx] = lowestVal;
            point = coordSys.dataToPoint(tmpIn, null, tmpOut);
            points[offset++] = point ? point[0] : NaN;
            points[offset++] = point ? point[1] : NaN;
            tmpIn[vDimIdx] = highestVal;
            point = coordSys.dataToPoint(tmpIn, null, tmpOut);
            points[offset++] = point ? point[1] : NaN;
          }

          data.setLayout('largePoints', points);
        }
      }
    };
    /**
     * Get the sign of a single data.
     *
     * @returns 0 for doji with hasDojiColor: true,
     *          1 for positive,
     *          -1 for negative.
     */

    function getSign(store, dataIndex, openVal, closeVal, closeDimI, hasDojiColor) {
      var sign;

      if (openVal > closeVal) {
        sign = -1;
      } else if (openVal < closeVal) {
        sign = 1;
      } else {
        sign = hasDojiColor // When doji color is set, use it instead of color/color0.
        ? 0 : dataIndex > 0 // If close === open, compare with close of last record
        ? store.get(closeDimI, dataIndex - 1) <= closeVal ? 1 : -1 : // No record of previous, set to be positive
        1;
      }

      return sign;
    }

    function calculateCandleWidth(seriesModel, data) {
      var baseAxis = seriesModel.getBaseAxis();
      var extent;
      var bandWidth = baseAxis.type === 'category' ? baseAxis.getBandWidth() : (extent = baseAxis.getExtent(), Math.abs(extent[1] - extent[0]) / data.count());
      var barMaxWidth = parsePercent$1(retrieve2(seriesModel.get('barMaxWidth'), bandWidth), bandWidth);
      var barMinWidth = parsePercent$1(retrieve2(seriesModel.get('barMinWidth'), 1), bandWidth);
      var barWidth = seriesModel.get('barWidth');
      return barWidth != null ? parsePercent$1(barWidth, bandWidth) // Put max outer to ensure bar visible in spite of overlap.
      : Math.max(Math.min(bandWidth / 2, barMaxWidth), barMinWidth);
    }

    function install$k(registers) {
      registers.registerChartView(CandlestickView);
      registers.registerSeriesModel(CandlestickSeriesModel);
      registers.registerPreprocessor(candlestickPreprocessor);
      registers.registerVisual(candlestickVisual);
      registers.registerLayout(candlestickLayout);
    }

    function updateRipplePath(rippleGroup, effectCfg) {
      var color = effectCfg.rippleEffectColor || effectCfg.color;
      rippleGroup.eachChild(function (ripplePath) {
        ripplePath.attr({
          z: effectCfg.z,
          zlevel: effectCfg.zlevel,
          style: {
            stroke: effectCfg.brushType === 'stroke' ? color : null,
            fill: effectCfg.brushType === 'fill' ? color : null
          }
        });
      });
    }

    var EffectSymbol =
    /** @class */
    function (_super) {
      __extends(EffectSymbol, _super);

      function EffectSymbol(data, idx) {
        var _this = _super.call(this) || this;

        var symbol = new Symbol(data, idx);
        var rippleGroup = new Group();

        _this.add(symbol);

        _this.add(rippleGroup);

        _this.updateData(data, idx);

        return _this;
      }

      EffectSymbol.prototype.stopEffectAnimation = function () {
        this.childAt(1).removeAll();
      };

      EffectSymbol.prototype.startEffectAnimation = function (effectCfg) {
        var symbolType = effectCfg.symbolType;
        var color = effectCfg.color;
        var rippleNumber = effectCfg.rippleNumber;
        var rippleGroup = this.childAt(1);

        for (var i = 0; i < rippleNumber; i++) {
          // If width/height are set too small (e.g., set to 1) on ios10
          // and macOS Sierra, a circle stroke become a rect, no matter what
          // the scale is set. So we set width/height as 2. See #4136.
          var ripplePath = createSymbol(symbolType, -1, -1, 2, 2, color);
          ripplePath.attr({
            style: {
              strokeNoScale: true
            },
            z2: 99,
            silent: true,
            scaleX: 0.5,
            scaleY: 0.5
          });
          var delay = -i / rippleNumber * effectCfg.period + effectCfg.effectOffset;
          ripplePath.animate('', true).when(effectCfg.period, {
            scaleX: effectCfg.rippleScale / 2,
            scaleY: effectCfg.rippleScale / 2
          }).delay(delay).start();
          ripplePath.animateStyle(true).when(effectCfg.period, {
            opacity: 0
          }).delay(delay).start();
          rippleGroup.add(ripplePath);
        }

        updateRipplePath(rippleGroup, effectCfg);
      };
      /**
       * Update effect symbol
       */


      EffectSymbol.prototype.updateEffectAnimation = function (effectCfg) {
        var oldEffectCfg = this._effectCfg;
        var rippleGroup = this.childAt(1); // Must reinitialize effect if following configuration changed

        var DIFFICULT_PROPS = ['symbolType', 'period', 'rippleScale', 'rippleNumber'];

        for (var i = 0; i < DIFFICULT_PROPS.length; i++) {
          var propName = DIFFICULT_PROPS[i];

          if (oldEffectCfg[propName] !== effectCfg[propName]) {
            this.stopEffectAnimation();
            this.startEffectAnimation(effectCfg);
            return;
          }
        }

        updateRipplePath(rippleGroup, effectCfg);
      };
      /**
       * Highlight symbol
       */


      EffectSymbol.prototype.highlight = function () {
        enterEmphasis(this);
      };
      /**
       * Downplay symbol
       */


      EffectSymbol.prototype.downplay = function () {
        leaveEmphasis(this);
      };

      EffectSymbol.prototype.getSymbolType = function () {
        var symbol = this.childAt(0);
        return symbol && symbol.getSymbolType();
      };
      /**
       * Update symbol properties
       */


      EffectSymbol.prototype.updateData = function (data, idx) {
        var _this = this;

        var seriesModel = data.hostModel;
        this.childAt(0).updateData(data, idx);
        var rippleGroup = this.childAt(1);
        var itemModel = data.getItemModel(idx);
        var symbolType = data.getItemVisual(idx, 'symbol');
        var symbolSize = normalizeSymbolSize(data.getItemVisual(idx, 'symbolSize'));
        var symbolStyle = data.getItemVisual(idx, 'style');
        var color = symbolStyle && symbolStyle.fill;
        var emphasisModel = itemModel.getModel('emphasis');
        rippleGroup.setScale(symbolSize);
        rippleGroup.traverse(function (ripplePath) {
          ripplePath.setStyle('fill', color);
        });
        var symbolOffset = normalizeSymbolOffset(data.getItemVisual(idx, 'symbolOffset'), symbolSize);

        if (symbolOffset) {
          rippleGroup.x = symbolOffset[0];
          rippleGroup.y = symbolOffset[1];
        }

        var symbolRotate = data.getItemVisual(idx, 'symbolRotate');
        rippleGroup.rotation = (symbolRotate || 0) * Math.PI / 180 || 0;
        var effectCfg = {};
        effectCfg.showEffectOn = seriesModel.get('showEffectOn');
        effectCfg.rippleScale = itemModel.get(['rippleEffect', 'scale']);
        effectCfg.brushType = itemModel.get(['rippleEffect', 'brushType']);
        effectCfg.period = itemModel.get(['rippleEffect', 'period']) * 1000;
        effectCfg.effectOffset = idx / data.count();
        effectCfg.z = seriesModel.getShallow('z') || 0;
        effectCfg.zlevel = seriesModel.getShallow('zlevel') || 0;
        effectCfg.symbolType = symbolType;
        effectCfg.color = color;
        effectCfg.rippleEffectColor = itemModel.get(['rippleEffect', 'color']);
        effectCfg.rippleNumber = itemModel.get(['rippleEffect', 'number']);

        if (effectCfg.showEffectOn === 'render') {
          this._effectCfg ? this.updateEffectAnimation(effectCfg) : this.startEffectAnimation(effectCfg);
          this._effectCfg = effectCfg;
        } else {
          // Not keep old effect config
          this._effectCfg = null;
          this.stopEffectAnimation();

          this.onHoverStateChange = function (toState) {
            if (toState === 'emphasis') {
              if (effectCfg.showEffectOn !== 'render') {
                _this.startEffectAnimation(effectCfg);
              }
            } else if (toState === 'normal') {
              if (effectCfg.showEffectOn !== 'render') {
                _this.stopEffectAnimation();
              }
            }
          };
        }

        this._effectCfg = effectCfg;
        toggleHoverEmphasis(this, emphasisModel.get('focus'), emphasisModel.get('blurScope'), emphasisModel.get('disabled'));
      };

      EffectSymbol.prototype.fadeOut = function (cb) {
        cb && cb();
      };
      return EffectSymbol;
    }(Group);

    var EffectScatterView =
    /** @class */
    function (_super) {
      __extends(EffectScatterView, _super);

      function EffectScatterView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = EffectScatterView.type;
        return _this;
      }

      EffectScatterView.prototype.init = function () {
        this._symbolDraw = new SymbolDraw(EffectSymbol);
      };

      EffectScatterView.prototype.render = function (seriesModel, ecModel, api) {
        var data = seriesModel.getData();
        var effectSymbolDraw = this._symbolDraw;
        effectSymbolDraw.updateData(data, {
          clipShape: this._getClipShape(seriesModel)
        });
        this.group.add(effectSymbolDraw.group);
      };

      EffectScatterView.prototype._getClipShape = function (seriesModel) {
        var coordSys = seriesModel.coordinateSystem;
        var clipArea = coordSys && coordSys.getArea && coordSys.getArea();
        return seriesModel.get('clip', true) ? clipArea : null;
      };

      EffectScatterView.prototype.updateTransform = function (seriesModel, ecModel, api) {
        var data = seriesModel.getData();
        this.group.dirty();
        var res = pointsLayout('').reset(seriesModel, ecModel, api);

        if (res.progress) {
          res.progress({
            start: 0,
            end: data.count(),
            count: data.count()
          }, data);
        }

        this._symbolDraw.updateLayout();
      };

      EffectScatterView.prototype._updateGroupTransform = function (seriesModel) {
        var coordSys = seriesModel.coordinateSystem;

        if (coordSys && coordSys.getRoamTransform) {
          this.group.transform = clone$2(coordSys.getRoamTransform());
          this.group.decomposeTransform();
        }
      };

      EffectScatterView.prototype.remove = function (ecModel, api) {
        this._symbolDraw && this._symbolDraw.remove(true);
      };

      EffectScatterView.type = 'effectScatter';
      return EffectScatterView;
    }(ChartView);

    var EffectScatterSeriesModel =
    /** @class */
    function (_super) {
      __extends(EffectScatterSeriesModel, _super);

      function EffectScatterSeriesModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = EffectScatterSeriesModel.type;
        _this.hasSymbolVisual = true;
        return _this;
      }

      EffectScatterSeriesModel.prototype.getInitialData = function (option, ecModel) {
        return createSeriesData(null, this, {
          useEncodeDefaulter: true
        });
      };

      EffectScatterSeriesModel.prototype.brushSelector = function (dataIndex, data, selectors) {
        return selectors.point(data.getItemLayout(dataIndex));
      };

      EffectScatterSeriesModel.type = 'series.effectScatter';
      EffectScatterSeriesModel.dependencies = ['grid', 'polar'];
      EffectScatterSeriesModel.defaultOption = {
        coordinateSystem: 'cartesian2d',
        // zlevel: 0,
        z: 2,
        legendHoverLink: true,
        effectType: 'ripple',
        progressive: 0,
        // When to show the effect, option: 'render'|'emphasis'
        showEffectOn: 'render',
        clip: true,
        // Ripple effect config
        rippleEffect: {
          period: 4,
          // Scale of ripple
          scale: 2.5,
          // Brush type can be fill or stroke
          brushType: 'fill',
          // Ripple number
          number: 3
        },
        universalTransition: {
          divideShape: 'clone'
        },
        // 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,  // 图形旋转控制
        // itemStyle: {
        //     opacity: 1
        // }

      };
      return EffectScatterSeriesModel;
    }(SeriesModel);

    function install$l(registers) {
      registers.registerChartView(EffectScatterView);
      registers.registerSeriesModel(EffectScatterSeriesModel);
      registers.registerLayout(pointsLayout('effectScatter'));
    }

    var EffectLine =
    /** @class */
    function (_super) {
      __extends(EffectLine, _super);

      function EffectLine(lineData, idx, seriesScope) {
        var _this = _super.call(this) || this;

        _this.add(_this.createLine(lineData, idx, seriesScope));

        _this._updateEffectSymbol(lineData, idx);

        return _this;
      }

      EffectLine.prototype.createLine = function (lineData, idx, seriesScope) {
        return new Line$1(lineData, idx, seriesScope);
      };

      EffectLine.prototype._updateEffectSymbol = function (lineData, idx) {
        var itemModel = lineData.getItemModel(idx);
        var effectModel = itemModel.getModel('effect');
        var size = effectModel.get('symbolSize');
        var symbolType = effectModel.get('symbol');

        if (!isArray(size)) {
          size = [size, size];
        }

        var lineStyle = lineData.getItemVisual(idx, 'style');
        var color = effectModel.get('color') || lineStyle && lineStyle.stroke;
        var symbol = this.childAt(1);

        if (this._symbolType !== symbolType) {
          // Remove previous
          this.remove(symbol);
          symbol = createSymbol(symbolType, -0.5, -0.5, 1, 1, color);
          symbol.z2 = 100;
          symbol.culling = true;
          this.add(symbol);
        } // Symbol may be removed if loop is false


        if (!symbol) {
          return;
        } // Shadow color is same with color in default


        symbol.setStyle('shadowColor', color);
        symbol.setStyle(effectModel.getItemStyle(['color']));
        symbol.scaleX = size[0];
        symbol.scaleY = size[1];
        symbol.setColor(color);
        this._symbolType = symbolType;
        this._symbolScale = size;

        this._updateEffectAnimation(lineData, effectModel, idx);
      };

      EffectLine.prototype._updateEffectAnimation = function (lineData, effectModel, idx) {
        var symbol = this.childAt(1);

        if (!symbol) {
          return;
        }

        var points = lineData.getItemLayout(idx);
        var period = effectModel.get('period') * 1000;
        var loop = effectModel.get('loop');
        var roundTrip = effectModel.get('roundTrip');
        var constantSpeed = effectModel.get('constantSpeed');
        var delayExpr = retrieve(effectModel.get('delay'), function (idx) {
          return idx / lineData.count() * period / 3;
        }); // Ignore when updating

        symbol.ignore = true;

        this._updateAnimationPoints(symbol, points);

        if (constantSpeed > 0) {
          period = this._getLineLength(symbol) / constantSpeed * 1000;
        }

        if (period !== this._period || loop !== this._loop || roundTrip !== this._roundTrip) {
          symbol.stopAnimation();
          var delayNum = void 0;

          if (isFunction(delayExpr)) {
            delayNum = delayExpr(idx);
          } else {
            delayNum = delayExpr;
          }

          if (symbol.__t > 0) {
            delayNum = -period * symbol.__t;
          }

          this._animateSymbol(symbol, period, delayNum, loop, roundTrip);
        }

        this._period = period;
        this._loop = loop;
        this._roundTrip = roundTrip;
      };

      EffectLine.prototype._animateSymbol = function (symbol, period, delayNum, loop, roundTrip) {
        if (period > 0) {
          symbol.__t = 0;
          var self_1 = this;
          var animator = symbol.animate('', loop).when(roundTrip ? period * 2 : period, {
            __t: roundTrip ? 2 : 1
          }).delay(delayNum).during(function () {
            self_1._updateSymbolPosition(symbol);
          });

          if (!loop) {
            animator.done(function () {
              self_1.remove(symbol);
            });
          }

          animator.start();
        }
      };

      EffectLine.prototype._getLineLength = function (symbol) {
        // Not so accurate
        return dist(symbol.__p1, symbol.__cp1) + dist(symbol.__cp1, symbol.__p2);
      };

      EffectLine.prototype._updateAnimationPoints = function (symbol, points) {
        symbol.__p1 = points[0];
        symbol.__p2 = points[1];
        symbol.__cp1 = points[2] || [(points[0][0] + points[1][0]) / 2, (points[0][1] + points[1][1]) / 2];
      };

      EffectLine.prototype.updateData = function (lineData, idx, seriesScope) {
        this.childAt(0).updateData(lineData, idx, seriesScope);

        this._updateEffectSymbol(lineData, idx);
      };

      EffectLine.prototype._updateSymbolPosition = function (symbol) {
        var p1 = symbol.__p1;
        var p2 = symbol.__p2;
        var cp1 = symbol.__cp1;
        var t = symbol.__t < 1 ? symbol.__t : 2 - symbol.__t;
        var pos = [symbol.x, symbol.y];
        var lastPos = pos.slice();
        var quadraticAt$1 = quadraticAt;
        var quadraticDerivativeAt$1 = quadraticDerivativeAt;
        pos[0] = quadraticAt$1(p1[0], cp1[0], p2[0], t);
        pos[1] = quadraticAt$1(p1[1], cp1[1], p2[1], t); // Tangent

        var tx = symbol.__t < 1 ? quadraticDerivativeAt$1(p1[0], cp1[0], p2[0], t) : quadraticDerivativeAt$1(p2[0], cp1[0], p1[0], 1 - t);
        var ty = symbol.__t < 1 ? quadraticDerivativeAt$1(p1[1], cp1[1], p2[1], t) : quadraticDerivativeAt$1(p2[1], cp1[1], p1[1], 1 - t);
        symbol.rotation = -Math.atan2(ty, tx) - Math.PI / 2; // enable continuity trail for 'line', 'rect', 'roundRect' symbolType

        if (this._symbolType === 'line' || this._symbolType === 'rect' || this._symbolType === 'roundRect') {
          if (symbol.__lastT !== undefined && symbol.__lastT < symbol.__t) {
            symbol.scaleY = dist(lastPos, pos) * 1.05; // make sure the last segment render within endPoint

            if (t === 1) {
              pos[0] = lastPos[0] + (pos[0] - lastPos[0]) / 2;
              pos[1] = lastPos[1] + (pos[1] - lastPos[1]) / 2;
            }
          } else if (symbol.__lastT === 1) {
            // After first loop, symbol.__t does NOT start with 0, so connect p1 to pos directly.
            symbol.scaleY = 2 * dist(p1, pos);
          } else {
            symbol.scaleY = this._symbolScale[1];
          }
        }

        symbol.__lastT = symbol.__t;
        symbol.ignore = false;
        symbol.x = pos[0];
        symbol.y = pos[1];
      };

      EffectLine.prototype.updateLayout = function (lineData, idx) {
        this.childAt(0).updateLayout(lineData, idx);
        var effectModel = lineData.getItemModel(idx).getModel('effect');

        this._updateEffectAnimation(lineData, effectModel, idx);
      };

      return EffectLine;
    }(Group);

    var Polyline$1 =
    /** @class */
    function (_super) {
      __extends(Polyline$1, _super);

      function Polyline$1(lineData, idx, seriesScope) {
        var _this = _super.call(this) || this;

        _this._createPolyline(lineData, idx, seriesScope);

        return _this;
      }

      Polyline$1.prototype._createPolyline = function (lineData, idx, seriesScope) {
        // let seriesModel = lineData.hostModel;
        var points = lineData.getItemLayout(idx);
        var line = new Polyline({
          shape: {
            points: points
          }
        });
        this.add(line);

        this._updateCommonStl(lineData, idx, seriesScope);
      };

      Polyline$1.prototype.updateData = function (lineData, idx, seriesScope) {
        var seriesModel = lineData.hostModel;
        var line = this.childAt(0);
        var target = {
          shape: {
            points: lineData.getItemLayout(idx)
          }
        };
        updateProps(line, target, seriesModel, idx);

        this._updateCommonStl(lineData, idx, seriesScope);
      };

      Polyline$1.prototype._updateCommonStl = function (lineData, idx, seriesScope) {
        var line = this.childAt(0);
        var itemModel = lineData.getItemModel(idx);
        var emphasisLineStyle = seriesScope && seriesScope.emphasisLineStyle;
        var focus = seriesScope && seriesScope.focus;
        var blurScope = seriesScope && seriesScope.blurScope;
        var emphasisDisabled = seriesScope && seriesScope.emphasisDisabled;

        if (!seriesScope || lineData.hasItemOption) {
          var emphasisModel = itemModel.getModel('emphasis');
          emphasisLineStyle = emphasisModel.getModel('lineStyle').getLineStyle();
          emphasisDisabled = emphasisModel.get('disabled');
          focus = emphasisModel.get('focus');
          blurScope = emphasisModel.get('blurScope');
        }

        line.useStyle(lineData.getItemVisual(idx, 'style'));
        line.style.fill = null;
        line.style.strokeNoScale = true;
        var lineEmphasisState = line.ensureState('emphasis');
        lineEmphasisState.style = emphasisLineStyle;
        toggleHoverEmphasis(this, focus, blurScope, emphasisDisabled);
      };

      Polyline$1.prototype.updateLayout = function (lineData, idx) {
        var polyline = this.childAt(0);
        polyline.setShape('points', lineData.getItemLayout(idx));
      };
      return Polyline$1;
    }(Group);

    var EffectPolyline =
    /** @class */
    function (_super) {
      __extends(EffectPolyline, _super);

      function EffectPolyline() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this._lastFrame = 0;
        _this._lastFramePercent = 0;
        return _this;
      } // Override


      EffectPolyline.prototype.createLine = function (lineData, idx, seriesScope) {
        return new Polyline$1(lineData, idx, seriesScope);
      };

      EffectPolyline.prototype._updateAnimationPoints = function (symbol, points) {
        this._points = points;
        var accLenArr = [0];
        var len = 0;

        for (var i = 1; i < points.length; i++) {
          var p1 = points[i - 1];
          var p2 = points[i];
          len += dist(p1, p2);
          accLenArr.push(len);
        }

        if (len === 0) {
          this._length = 0;
          return;
        }

        for (var i = 0; i < accLenArr.length; i++) {
          accLenArr[i] /= len;
        }

        this._offsets = accLenArr;
        this._length = len;
      };

      EffectPolyline.prototype._getLineLength = function () {
        return this._length;
      };

      EffectPolyline.prototype._updateSymbolPosition = function (symbol) {
        var t = symbol.__t < 1 ? symbol.__t : 2 - symbol.__t;
        var points = this._points;
        var offsets = this._offsets;
        var len = points.length;

        if (!offsets) {
          // Has length 0
          return;
        }

        var lastFrame = this._lastFrame;
        var frame;

        if (t < this._lastFramePercent) {
          // Start from the next frame
          // PENDING start from lastFrame ?
          var start = Math.min(lastFrame + 1, len - 1);

          for (frame = start; frame >= 0; frame--) {
            if (offsets[frame] <= t) {
              break;
            }
          } // PENDING really need to do this ?


          frame = Math.min(frame, len - 2);
        } else {
          for (frame = lastFrame; frame < len; frame++) {
            if (offsets[frame] > t) {
              break;
            }
          }

          frame = Math.min(frame - 1, len - 2);
        }

        var p = (t - offsets[frame]) / (offsets[frame + 1] - offsets[frame]);
        var p0 = points[frame];
        var p1 = points[frame + 1];
        symbol.x = p0[0] * (1 - p) + p * p1[0];
        symbol.y = p0[1] * (1 - p) + p * p1[1];
        var tx = symbol.__t < 1 ? p1[0] - p0[0] : p0[0] - p1[0];
        var ty = symbol.__t < 1 ? p1[1] - p0[1] : p0[1] - p1[1];
        symbol.rotation = -Math.atan2(ty, tx) - Math.PI / 2;
        this._lastFrame = frame;
        this._lastFramePercent = t;
        symbol.ignore = false;
      };
      return EffectPolyline;
    }(EffectLine);

    var LargeLinesPathShape =
    /** @class */
    function () {
      function LargeLinesPathShape() {
        this.polyline = false;
        this.curveness = 0;
        this.segs = [];
      }

      return LargeLinesPathShape;
    }();

    var LargeLinesPath =
    /** @class */
    function (_super) {
      __extends(LargeLinesPath, _super);

      function LargeLinesPath(opts) {
        var _this = _super.call(this, opts) || this;

        _this._off = 0;
        _this.hoverDataIdx = -1;
        return _this;
      }

      LargeLinesPath.prototype.reset = function () {
        this.notClear = false;
        this._off = 0;
      };

      LargeLinesPath.prototype.getDefaultStyle = function () {
        return {
          stroke: '#000',
          fill: null
        };
      };

      LargeLinesPath.prototype.getDefaultShape = function () {
        return new LargeLinesPathShape();
      };

      LargeLinesPath.prototype.buildPath = function (ctx, shape) {
        var segs = shape.segs;
        var curveness = shape.curveness;
        var i;

        if (shape.polyline) {
          for (i = this._off; i < segs.length;) {
            var count = segs[i++];

            if (count > 0) {
              ctx.moveTo(segs[i++], segs[i++]);

              for (var k = 1; k < count; k++) {
                ctx.lineTo(segs[i++], segs[i++]);
              }
            }
          }
        } else {
          for (i = this._off; i < segs.length;) {
            var x0 = segs[i++];
            var y0 = segs[i++];
            var x1 = segs[i++];
            var y1 = segs[i++];
            ctx.moveTo(x0, y0);

            if (curveness > 0) {
              var x2 = (x0 + x1) / 2 - (y0 - y1) * curveness;
              var y2 = (y0 + y1) / 2 - (x1 - x0) * curveness;
              ctx.quadraticCurveTo(x2, y2, x1, y1);
            } else {
              ctx.lineTo(x1, y1);
            }
          }
        }

        if (this.incremental) {
          this._off = i;
          this.notClear = true;
        }
      };

      LargeLinesPath.prototype.findDataIndex = function (x, y) {
        var shape = this.shape;
        var segs = shape.segs;
        var curveness = shape.curveness;
        var lineWidth = this.style.lineWidth;

        if (shape.polyline) {
          var dataIndex = 0;

          for (var i = 0; i < segs.length;) {
            var count = segs[i++];

            if (count > 0) {
              var x0 = segs[i++];
              var y0 = segs[i++];

              for (var k = 1; k < count; k++) {
                var x1 = segs[i++];
                var y1 = segs[i++];

                if (containStroke(x0, y0, x1, y1, lineWidth, x, y)) {
                  return dataIndex;
                }
              }
            }

            dataIndex++;
          }
        } else {
          var dataIndex = 0;

          for (var i = 0; i < segs.length;) {
            var x0 = segs[i++];
            var y0 = segs[i++];
            var x1 = segs[i++];
            var y1 = segs[i++];

            if (curveness > 0) {
              var x2 = (x0 + x1) / 2 - (y0 - y1) * curveness;
              var y2 = (y0 + y1) / 2 - (x1 - x0) * curveness;

              if (containStroke$2(x0, y0, x2, y2, x1, y1, lineWidth, x, y)) {
                return dataIndex;
              }
            } else {
              if (containStroke(x0, y0, x1, y1, lineWidth, x, y)) {
                return dataIndex;
              }
            }

            dataIndex++;
          }
        }

        return -1;
      };

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

        if (rect.contain(x, y)) {
          // Cache found data index.
          var dataIdx = this.hoverDataIdx = this.findDataIndex(x, y);
          return dataIdx >= 0;
        }

        this.hoverDataIdx = -1;
        return false;
      };

      LargeLinesPath.prototype.getBoundingRect = function () {
        // Ignore stroke for large symbol draw.
        var rect = this._rect;

        if (!rect) {
          var shape = this.shape;
          var points = shape.segs;
          var minX = Infinity;
          var minY = Infinity;
          var maxX = -Infinity;
          var maxY = -Infinity;

          for (var i = 0; i < points.length;) {
            var x = points[i++];
            var y = points[i++];
            minX = Math.min(x, minX);
            maxX = Math.max(x, maxX);
            minY = Math.min(y, minY);
            maxY = Math.max(y, maxY);
          }

          rect = this._rect = new BoundingRect(minX, minY, maxX, maxY);
        }

        return rect;
      };

      return LargeLinesPath;
    }(Path);

    var LargeLineDraw =
    /** @class */
    function () {
      function LargeLineDraw() {
        this.group = new Group();
      }
      /**
       * Update symbols draw by new data
       */


      LargeLineDraw.prototype.updateData = function (data) {
        this._clear();

        var lineEl = this._create();

        lineEl.setShape({
          segs: data.getLayout('linesPoints')
        });

        this._setCommon(lineEl, data);
      };
      /**
       * @override
       */

      LargeLineDraw.prototype.incrementalPrepareUpdate = function (data) {
        this.group.removeAll();

        this._clear();
      };
      /**
       * @override
       */

      LargeLineDraw.prototype.incrementalUpdate = function (taskParams, data) {
        var lastAdded = this._newAdded[0];
        var linePoints = data.getLayout('linesPoints');
        var oldSegs = lastAdded && lastAdded.shape.segs; // Merging the exists. Each element has 1e4 points.
        // Consider the performance balance between too much elements and too much points in one shape(may affect hover optimization)

        if (oldSegs && oldSegs.length < 2e4) {
          var oldLen = oldSegs.length;
          var newSegs = new Float32Array(oldLen + linePoints.length); // Concat two array

          newSegs.set(oldSegs);
          newSegs.set(linePoints, oldLen);
          lastAdded.setShape({
            segs: newSegs
          });
        } else {
          // Clear
          this._newAdded = [];

          var lineEl = this._create();

          lineEl.incremental = true;
          lineEl.setShape({
            segs: linePoints
          });

          this._setCommon(lineEl, data);

          lineEl.__startIndex = taskParams.start;
        }
      };
      /**
       * @override
       */


      LargeLineDraw.prototype.remove = function () {
        this._clear();
      };

      LargeLineDraw.prototype.eachRendered = function (cb) {
        this._newAdded[0] && cb(this._newAdded[0]);
      };

      LargeLineDraw.prototype._create = function () {
        var lineEl = new LargeLinesPath({
          cursor: 'default',
          ignoreCoarsePointer: true
        });

        this._newAdded.push(lineEl);

        this.group.add(lineEl);
        return lineEl;
      };

      LargeLineDraw.prototype._setCommon = function (lineEl, data, isIncremental) {
        var hostModel = data.hostModel;
        lineEl.setShape({
          polyline: hostModel.get('polyline'),
          curveness: hostModel.get(['lineStyle', 'curveness'])
        });
        lineEl.useStyle(hostModel.getModel('lineStyle').getLineStyle());
        lineEl.style.strokeNoScale = true;
        var style = data.getVisual('style');

        if (style && style.stroke) {
          lineEl.setStyle('stroke', style.stroke);
        }

        lineEl.setStyle('fill', null);
        var ecData = getECData(lineEl); // Enable tooltip
        // PENDING May have performance issue when path is extremely large

        ecData.seriesIndex = hostModel.seriesIndex;
        lineEl.on('mousemove', function (e) {
          ecData.dataIndex = null;
          var dataIndex = lineEl.hoverDataIdx;

          if (dataIndex > 0) {
            // Provide dataIndex for tooltip
            ecData.dataIndex = dataIndex + lineEl.__startIndex;
          }
        });
      };

      LargeLineDraw.prototype._clear = function () {
        this._newAdded = [];
        this.group.removeAll();
      };
      return LargeLineDraw;
    }();

    var linesLayout = {
      seriesType: 'lines',
      plan: createRenderPlanner(),
      reset: function (seriesModel) {
        var coordSys = seriesModel.coordinateSystem;

        if (!coordSys) {
          if ("development" !== 'production') {
            error('The lines series must have a coordinate system.');
          }

          return;
        }

        var isPolyline = seriesModel.get('polyline');
        var isLarge = seriesModel.pipelineContext.large;
        return {
          progress: function (params, lineData) {
            var lineCoords = [];

            if (isLarge) {
              var points = void 0;
              var segCount = params.end - params.start;

              if (isPolyline) {
                var totalCoordsCount = 0;

                for (var i = params.start; i < params.end; i++) {
                  totalCoordsCount += seriesModel.getLineCoordsCount(i);
                }

                points = new Float32Array(segCount + totalCoordsCount * 2);
              } else {
                points = new Float32Array(segCount * 4);
              }

              var offset = 0;
              var pt = [];

              for (var i = params.start; i < params.end; i++) {
                var len = seriesModel.getLineCoords(i, lineCoords);

                if (isPolyline) {
                  points[offset++] = len;
                }

                for (var k = 0; k < len; k++) {
                  pt = coordSys.dataToPoint(lineCoords[k], false, pt);
                  points[offset++] = pt[0];
                  points[offset++] = pt[1];
                }
              }

              lineData.setLayout('linesPoints', points);
            } else {
              for (var i = params.start; i < params.end; i++) {
                var itemModel = lineData.getItemModel(i);
                var len = seriesModel.getLineCoords(i, lineCoords);
                var pts = [];

                if (isPolyline) {
                  for (var j = 0; j < len; j++) {
                    pts.push(coordSys.dataToPoint(lineCoords[j]));
                  }
                } else {
                  pts[0] = coordSys.dataToPoint(lineCoords[0]);
                  pts[1] = coordSys.dataToPoint(lineCoords[1]);
                  var curveness = itemModel.get(['lineStyle', 'curveness']);

                  if (+curveness) {
                    pts[2] = [(pts[0][0] + pts[1][0]) / 2 - (pts[0][1] - pts[1][1]) * curveness, (pts[0][1] + pts[1][1]) / 2 - (pts[1][0] - pts[0][0]) * curveness];
                  }
                }

                lineData.setItemLayout(i, pts);
              }
            }
          }
        };
      }
    };

    var LinesView =
    /** @class */
    function (_super) {
      __extends(LinesView, _super);

      function LinesView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = LinesView.type;
        return _this;
      }

      LinesView.prototype.render = function (seriesModel, ecModel, api) {
        var data = seriesModel.getData();

        var lineDraw = this._updateLineDraw(data, seriesModel);

        var zlevel = seriesModel.get('zlevel');
        var trailLength = seriesModel.get(['effect', 'trailLength']);
        var zr = api.getZr(); // Avoid the drag cause ghost shadow
        // FIXME Better way ?
        // SVG doesn't support

        var isSvg = zr.painter.getType() === 'svg';

        if (!isSvg) {
          zr.painter.getLayer(zlevel).clear(true);
        } // Config layer with motion blur


        if (this._lastZlevel != null && !isSvg) {
          zr.configLayer(this._lastZlevel, {
            motionBlur: false
          });
        }

        if (this._showEffect(seriesModel) && trailLength > 0) {
          if (!isSvg) {
            zr.configLayer(zlevel, {
              motionBlur: true,
              lastFrameAlpha: Math.max(Math.min(trailLength / 10 + 0.9, 1), 0)
            });
          } else if ("development" !== 'production') {
            console.warn('SVG render mode doesn\'t support lines with trail effect');
          }
        }

        lineDraw.updateData(data);
        var clipPath = seriesModel.get('clip', true) && createClipPath(seriesModel.coordinateSystem, false, seriesModel);

        if (clipPath) {
          this.group.setClipPath(clipPath);
        } else {
          this.group.removeClipPath();
        }

        this._lastZlevel = zlevel;
        this._finished = true;
      };

      LinesView.prototype.incrementalPrepareRender = function (seriesModel, ecModel, api) {
        var data = seriesModel.getData();

        var lineDraw = this._updateLineDraw(data, seriesModel);

        lineDraw.incrementalPrepareUpdate(data);

        this._clearLayer(api);

        this._finished = false;
      };

      LinesView.prototype.incrementalRender = function (taskParams, seriesModel, ecModel) {
        this._lineDraw.incrementalUpdate(taskParams, seriesModel.getData());

        this._finished = taskParams.end === seriesModel.getData().count();
      };

      LinesView.prototype.eachRendered = function (cb) {
        this._lineDraw && this._lineDraw.eachRendered(cb);
      };

      LinesView.prototype.updateTransform = function (seriesModel, ecModel, api) {
        var data = seriesModel.getData();
        var pipelineContext = seriesModel.pipelineContext;

        if (!this._finished || pipelineContext.large || pipelineContext.progressiveRender) {
          // TODO Don't have to do update in large mode. Only do it when there are millions of data.
          return {
            update: true
          };
        } else {
          // TODO Use same logic with ScatterView.
          // Manually update layout
          var res = linesLayout.reset(seriesModel, ecModel, api);

          if (res.progress) {
            res.progress({
              start: 0,
              end: data.count(),
              count: data.count()
            }, data);
          } // Not in large mode


          this._lineDraw.updateLayout();

          this._clearLayer(api);
        }
      };

      LinesView.prototype._updateLineDraw = function (data, seriesModel) {
        var lineDraw = this._lineDraw;

        var hasEffect = this._showEffect(seriesModel);

        var isPolyline = !!seriesModel.get('polyline');
        var pipelineContext = seriesModel.pipelineContext;
        var isLargeDraw = pipelineContext.large;

        if ("development" !== 'production') {
          if (hasEffect && isLargeDraw) {
            console.warn('Large lines not support effect');
          }
        }

        if (!lineDraw || hasEffect !== this._hasEffet || isPolyline !== this._isPolyline || isLargeDraw !== this._isLargeDraw) {
          if (lineDraw) {
            lineDraw.remove();
          }

          lineDraw = this._lineDraw = isLargeDraw ? new LargeLineDraw() : new LineDraw(isPolyline ? hasEffect ? EffectPolyline : Polyline$1 : hasEffect ? EffectLine : Line$1);
          this._hasEffet = hasEffect;
          this._isPolyline = isPolyline;
          this._isLargeDraw = isLargeDraw;
        }

        this.group.add(lineDraw.group);
        return lineDraw;
      };

      LinesView.prototype._showEffect = function (seriesModel) {
        return !!seriesModel.get(['effect', 'show']);
      };

      LinesView.prototype._clearLayer = function (api) {
        // Not use motion when dragging or zooming
        var zr = api.getZr();
        var isSvg = zr.painter.getType() === 'svg';

        if (!isSvg && this._lastZlevel != null) {
          zr.painter.getLayer(this._lastZlevel).clear(true);
        }
      };

      LinesView.prototype.remove = function (ecModel, api) {
        this._lineDraw && this._lineDraw.remove();
        this._lineDraw = null; // Clear motion when lineDraw is removed

        this._clearLayer(api);
      };

      LinesView.prototype.dispose = function (ecModel, api) {
        this.remove(ecModel, api);
      };

      LinesView.type = 'lines';
      return LinesView;
    }(ChartView);

    var Uint32Arr = typeof Uint32Array === 'undefined' ? Array : Uint32Array;
    var Float64Arr = typeof Float64Array === 'undefined' ? Array : Float64Array;

    function compatEc2(seriesOpt) {
      var data = seriesOpt.data;

      if (data && data[0] && data[0][0] && data[0][0].coord) {
        if ("development" !== 'production') {
          console.warn('Lines data configuration has been changed to' + ' { coords:[[1,2],[2,3]] }');
        }

        seriesOpt.data = map(data, function (itemOpt) {
          var coords = [itemOpt[0].coord, itemOpt[1].coord];
          var target = {
            coords: coords
          };

          if (itemOpt[0].name) {
            target.fromName = itemOpt[0].name;
          }

          if (itemOpt[1].name) {
            target.toName = itemOpt[1].name;
          }

          return mergeAll([target, itemOpt[0], itemOpt[1]]);
        });
      }
    }

    var LinesSeriesModel =
    /** @class */
    function (_super) {
      __extends(LinesSeriesModel, _super);

      function LinesSeriesModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = LinesSeriesModel.type;
        _this.visualStyleAccessPath = 'lineStyle';
        _this.visualDrawType = 'stroke';
        return _this;
      }

      LinesSeriesModel.prototype.init = function (option) {
        // The input data may be null/undefined.
        option.data = option.data || []; // Not using preprocessor because mergeOption may not have series.type

        compatEc2(option);

        var result = this._processFlatCoordsArray(option.data);

        this._flatCoords = result.flatCoords;
        this._flatCoordsOffset = result.flatCoordsOffset;

        if (result.flatCoords) {
          option.data = new Float32Array(result.count);
        }

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

      LinesSeriesModel.prototype.mergeOption = function (option) {
        compatEc2(option);

        if (option.data) {
          // Only update when have option data to merge.
          var result = this._processFlatCoordsArray(option.data);

          this._flatCoords = result.flatCoords;
          this._flatCoordsOffset = result.flatCoordsOffset;

          if (result.flatCoords) {
            option.data = new Float32Array(result.count);
          }
        }

        _super.prototype.mergeOption.apply(this, arguments);
      };

      LinesSeriesModel.prototype.appendData = function (params) {
        var result = this._processFlatCoordsArray(params.data);

        if (result.flatCoords) {
          if (!this._flatCoords) {
            this._flatCoords = result.flatCoords;
            this._flatCoordsOffset = result.flatCoordsOffset;
          } else {
            this._flatCoords = concatArray(this._flatCoords, result.flatCoords);
            this._flatCoordsOffset = concatArray(this._flatCoordsOffset, result.flatCoordsOffset);
          }

          params.data = new Float32Array(result.count);
        }

        this.getRawData().appendData(params.data);
      };

      LinesSeriesModel.prototype._getCoordsFromItemModel = function (idx) {
        var itemModel = this.getData().getItemModel(idx);
        var coords = itemModel.option instanceof Array ? itemModel.option : itemModel.getShallow('coords');

        if ("development" !== 'production') {
          if (!(coords instanceof Array && coords.length > 0 && coords[0] instanceof Array)) {
            throw new Error('Invalid coords ' + JSON.stringify(coords) + '. Lines must have 2d coords array in data item.');
          }
        }

        return coords;
      };

      LinesSeriesModel.prototype.getLineCoordsCount = function (idx) {
        if (this._flatCoordsOffset) {
          return this._flatCoordsOffset[idx * 2 + 1];
        } else {
          return this._getCoordsFromItemModel(idx).length;
        }
      };

      LinesSeriesModel.prototype.getLineCoords = function (idx, out) {
        if (this._flatCoordsOffset) {
          var offset = this._flatCoordsOffset[idx * 2];
          var len = this._flatCoordsOffset[idx * 2 + 1];

          for (var i = 0; i < len; i++) {
            out[i] = out[i] || [];
            out[i][0] = this._flatCoords[offset + i * 2];
            out[i][1] = this._flatCoords[offset + i * 2 + 1];
          }

          return len;
        } else {
          var coords = this._getCoordsFromItemModel(idx);

          for (var i = 0; i < coords.length; i++) {
            out[i] = out[i] || [];
            out[i][0] = coords[i][0];
            out[i][1] = coords[i][1];
          }

          return coords.length;
        }
      };

      LinesSeriesModel.prototype._processFlatCoordsArray = function (data) {
        var startOffset = 0;

        if (this._flatCoords) {
          startOffset = this._flatCoords.length;
        } // Stored as a typed array. In format
        // Points Count(2) | x | y | x | y | Points Count(3) | x |  y | x | y | x | y |


        if (isNumber(data[0])) {
          var len = data.length; // Store offset and len of each segment

          var coordsOffsetAndLenStorage = new Uint32Arr(len);
          var coordsStorage = new Float64Arr(len);
          var coordsCursor = 0;
          var offsetCursor = 0;
          var dataCount = 0;

          for (var i = 0; i < len;) {
            dataCount++;
            var count = data[i++]; // Offset

            coordsOffsetAndLenStorage[offsetCursor++] = coordsCursor + startOffset; // Len

            coordsOffsetAndLenStorage[offsetCursor++] = count;

            for (var k = 0; k < count; k++) {
              var x = data[i++];
              var y = data[i++];
              coordsStorage[coordsCursor++] = x;
              coordsStorage[coordsCursor++] = y;

              if (i > len) {
                if ("development" !== 'production') {
                  throw new Error('Invalid data format.');
                }
              }
            }
          }

          return {
            flatCoordsOffset: new Uint32Array(coordsOffsetAndLenStorage.buffer, 0, offsetCursor),
            flatCoords: coordsStorage,
            count: dataCount
          };
        }

        return {
          flatCoordsOffset: null,
          flatCoords: null,
          count: data.length
        };
      };

      LinesSeriesModel.prototype.getInitialData = function (option, ecModel) {
        if ("development" !== 'production') {
          var CoordSys = CoordinateSystemManager.get(option.coordinateSystem);

          if (!CoordSys) {
            throw new Error('Unknown coordinate system ' + option.coordinateSystem);
          }
        }

        var lineData = new SeriesData(['value'], this);
        lineData.hasItemOption = false;
        lineData.initData(option.data, [], function (dataItem, dimName, dataIndex, dimIndex) {
          // dataItem is simply coords
          if (dataItem instanceof Array) {
            return NaN;
          } else {
            lineData.hasItemOption = true;
            var value = dataItem.value;

            if (value != null) {
              return value instanceof Array ? value[dimIndex] : value;
            }
          }
        });
        return lineData;
      };

      LinesSeriesModel.prototype.formatTooltip = function (dataIndex, multipleSeries, dataType) {
        var data = this.getData();
        var itemModel = data.getItemModel(dataIndex);
        var name = itemModel.get('name');

        if (name) {
          return name;
        }

        var fromName = itemModel.get('fromName');
        var toName = itemModel.get('toName');
        var nameArr = [];
        fromName != null && nameArr.push(fromName);
        toName != null && nameArr.push(toName);
        return createTooltipMarkup('nameValue', {
          name: nameArr.join(' > ')
        });
      };

      LinesSeriesModel.prototype.preventIncremental = function () {
        return !!this.get(['effect', 'show']);
      };

      LinesSeriesModel.prototype.getProgressive = function () {
        var progressive = this.option.progressive;

        if (progressive == null) {
          return this.option.large ? 1e4 : this.get('progressive');
        }

        return progressive;
      };

      LinesSeriesModel.prototype.getProgressiveThreshold = function () {
        var progressiveThreshold = this.option.progressiveThreshold;

        if (progressiveThreshold == null) {
          return this.option.large ? 2e4 : this.get('progressiveThreshold');
        }

        return progressiveThreshold;
      };

      LinesSeriesModel.prototype.getZLevelKey = function () {
        var effectModel = this.getModel('effect');
        var trailLength = effectModel.get('trailLength');
        return this.getData().count() > this.getProgressiveThreshold() // Each progressive series has individual key.
        ? this.id : effectModel.get('show') && trailLength > 0 ? trailLength + '' : '';
      };

      LinesSeriesModel.type = 'series.lines';
      LinesSeriesModel.dependencies = ['grid', 'polar', 'geo', 'calendar'];
      LinesSeriesModel.defaultOption = {
        coordinateSystem: 'geo',
        // zlevel: 0,
        z: 2,
        legendHoverLink: true,
        // Cartesian coordinate system
        xAxisIndex: 0,
        yAxisIndex: 0,
        symbol: ['none', 'none'],
        symbolSize: [10, 10],
        // Geo coordinate system
        geoIndex: 0,
        effect: {
          show: false,
          period: 4,
          constantSpeed: 0,
          symbol: 'circle',
          symbolSize: 3,
          loop: true,
          trailLength: 0.2
        },
        large: false,
        // Available when large is true
        largeThreshold: 2000,
        polyline: false,
        clip: true,
        label: {
          show: false,
          position: 'end' // distance: 5,
          // formatter: 标签文本格式器，同Tooltip.formatter，不支持异步回调

        },
        lineStyle: {
          opacity: 0.5
        }
      };
      return LinesSeriesModel;
    }(SeriesModel);

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


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * 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 normalize$3(a) {
      if (!(a instanceof Array)) {
        a = [a, a];
      }

      return a;
    }

    var linesVisual = {
      seriesType: 'lines',
      reset: function (seriesModel) {
        var symbolType = normalize$3(seriesModel.get('symbol'));
        var symbolSize = normalize$3(seriesModel.get('symbolSize'));
        var data = seriesModel.getData();
        data.setVisual('fromSymbol', symbolType && symbolType[0]);
        data.setVisual('toSymbol', symbolType && symbolType[1]);
        data.setVisual('fromSymbolSize', symbolSize && symbolSize[0]);
        data.setVisual('toSymbolSize', symbolSize && symbolSize[1]);

        function dataEach(data, idx) {
          var itemModel = data.getItemModel(idx);
          var symbolType = normalize$3(itemModel.getShallow('symbol', true));
          var symbolSize = normalize$3(itemModel.getShallow('symbolSize', true));
          symbolType[0] && data.setItemVisual(idx, 'fromSymbol', symbolType[0]);
          symbolType[1] && data.setItemVisual(idx, 'toSymbol', symbolType[1]);
          symbolSize[0] && data.setItemVisual(idx, 'fromSymbolSize', symbolSize[0]);
          symbolSize[1] && data.setItemVisual(idx, 'toSymbolSize', symbolSize[1]);
        }

        return {
          dataEach: data.hasItemOption ? dataEach : null
        };
      }
    };

    function install$m(registers) {
      registers.registerChartView(LinesView);
      registers.registerSeriesModel(LinesSeriesModel);
      registers.registerLayout(linesLayout);
      registers.registerVisual(linesVisual);
    }

    var GRADIENT_LEVELS = 256;

    var HeatmapLayer =
    /** @class */
    function () {
      function HeatmapLayer() {
        this.blurSize = 30;
        this.pointSize = 20;
        this.maxOpacity = 1;
        this.minOpacity = 0;
        this._gradientPixels = {
          inRange: null,
          outOfRange: null
        };
        var canvas = platformApi.createCanvas();
        this.canvas = canvas;
      }
      /**
       * Renders Heatmap and returns the rendered canvas
       * @param data array of data, each has x, y, value
       * @param width canvas width
       * @param height canvas height
       */


      HeatmapLayer.prototype.update = function (data, width, height, normalize, colorFunc, isInRange) {
        var brush = this._getBrush();

        var gradientInRange = this._getGradient(colorFunc, 'inRange');

        var gradientOutOfRange = this._getGradient(colorFunc, 'outOfRange');

        var r = this.pointSize + this.blurSize;
        var canvas = this.canvas;
        var ctx = canvas.getContext('2d');
        var len = data.length;
        canvas.width = width;
        canvas.height = height;

        for (var i = 0; i < len; ++i) {
          var p = data[i];
          var x = p[0];
          var y = p[1];
          var value = p[2]; // calculate alpha using value

          var alpha = normalize(value); // draw with the circle brush with alpha

          ctx.globalAlpha = alpha;
          ctx.drawImage(brush, x - r, y - r);
        }

        if (!canvas.width || !canvas.height) {
          // Avoid "Uncaught DOMException: Failed to execute 'getImageData' on
          // 'CanvasRenderingContext2D': The source height is 0."
          return canvas;
        } // colorize the canvas using alpha value and set with gradient


        var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
        var pixels = imageData.data;
        var offset = 0;
        var pixelLen = pixels.length;
        var minOpacity = this.minOpacity;
        var maxOpacity = this.maxOpacity;
        var diffOpacity = maxOpacity - minOpacity;

        while (offset < pixelLen) {
          var alpha = pixels[offset + 3] / 256;
          var gradientOffset = Math.floor(alpha * (GRADIENT_LEVELS - 1)) * 4; // Simple optimize to ignore the empty data

          if (alpha > 0) {
            var gradient = isInRange(alpha) ? gradientInRange : gradientOutOfRange; // Any alpha > 0 will be mapped to [minOpacity, maxOpacity]

            alpha > 0 && (alpha = alpha * diffOpacity + minOpacity);
            pixels[offset++] = gradient[gradientOffset];
            pixels[offset++] = gradient[gradientOffset + 1];
            pixels[offset++] = gradient[gradientOffset + 2];
            pixels[offset++] = gradient[gradientOffset + 3] * alpha * 256;
          } else {
            offset += 4;
          }
        }

        ctx.putImageData(imageData, 0, 0);
        return canvas;
      };
      /**
       * get canvas of a black circle brush used for canvas to draw later
       */


      HeatmapLayer.prototype._getBrush = function () {
        var brushCanvas = this._brushCanvas || (this._brushCanvas = platformApi.createCanvas()); // set brush size

        var r = this.pointSize + this.blurSize;
        var d = r * 2;
        brushCanvas.width = d;
        brushCanvas.height = d;
        var ctx = brushCanvas.getContext('2d');
        ctx.clearRect(0, 0, d, d); // in order to render shadow without the distinct circle,
        // draw the distinct circle in an invisible place,
        // and use shadowOffset to draw shadow in the center of the canvas

        ctx.shadowOffsetX = d;
        ctx.shadowBlur = this.blurSize; // draw the shadow in black, and use alpha and shadow blur to generate
        // color in color map

        ctx.shadowColor = '#000'; // draw circle in the left to the canvas

        ctx.beginPath();
        ctx.arc(-r, r, this.pointSize, 0, Math.PI * 2, true);
        ctx.closePath();
        ctx.fill();
        return brushCanvas;
      };
      /**
       * get gradient color map
       * @private
       */


      HeatmapLayer.prototype._getGradient = function (colorFunc, state) {
        var gradientPixels = this._gradientPixels;
        var pixelsSingleState = gradientPixels[state] || (gradientPixels[state] = new Uint8ClampedArray(256 * 4));
        var color = [0, 0, 0, 0];
        var off = 0;

        for (var i = 0; i < 256; i++) {
          colorFunc[state](i / 255, true, color);
          pixelsSingleState[off++] = color[0];
          pixelsSingleState[off++] = color[1];
          pixelsSingleState[off++] = color[2];
          pixelsSingleState[off++] = color[3];
        }

        return pixelsSingleState;
      };

      return HeatmapLayer;
    }();

    function getIsInPiecewiseRange(dataExtent, pieceList, selected) {
      var dataSpan = dataExtent[1] - dataExtent[0];
      pieceList = map(pieceList, function (piece) {
        return {
          interval: [(piece.interval[0] - dataExtent[0]) / dataSpan, (piece.interval[1] - dataExtent[0]) / dataSpan]
        };
      });
      var len = pieceList.length;
      var lastIndex = 0;
      return function (val) {
        var i; // Try to find in the location of the last found

        for (i = lastIndex; i < len; i++) {
          var interval = pieceList[i].interval;

          if (interval[0] <= val && val <= interval[1]) {
            lastIndex = i;
            break;
          }
        }

        if (i === len) {
          // Not found, back interation
          for (i = lastIndex - 1; i >= 0; i--) {
            var interval = pieceList[i].interval;

            if (interval[0] <= val && val <= interval[1]) {
              lastIndex = i;
              break;
            }
          }
        }

        return i >= 0 && i < len && selected[i];
      };
    }

    function getIsInContinuousRange(dataExtent, range) {
      var dataSpan = dataExtent[1] - dataExtent[0];
      range = [(range[0] - dataExtent[0]) / dataSpan, (range[1] - dataExtent[0]) / dataSpan];
      return function (val) {
        return val >= range[0] && val <= range[1];
      };
    }

    function isGeoCoordSys(coordSys) {
      var dimensions = coordSys.dimensions; // Not use coordSys.type === 'geo' because coordSys maybe extended

      return dimensions[0] === 'lng' && dimensions[1] === 'lat';
    }

    var HeatmapView =
    /** @class */
    function (_super) {
      __extends(HeatmapView, _super);

      function HeatmapView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = HeatmapView.type;
        return _this;
      }

      HeatmapView.prototype.render = function (seriesModel, ecModel, api) {
        var visualMapOfThisSeries;
        ecModel.eachComponent('visualMap', function (visualMap) {
          visualMap.eachTargetSeries(function (targetSeries) {
            if (targetSeries === seriesModel) {
              visualMapOfThisSeries = visualMap;
            }
          });
        });

        if ("development" !== 'production') {
          if (!visualMapOfThisSeries) {
            throw new Error('Heatmap must use with visualMap');
          }
        } // Clear previously rendered progressive elements.


        this._progressiveEls = null;
        this.group.removeAll();
        var coordSys = seriesModel.coordinateSystem;

        if (coordSys.type === 'cartesian2d' || coordSys.type === 'calendar') {
          this._renderOnCartesianAndCalendar(seriesModel, api, 0, seriesModel.getData().count());
        } else if (isGeoCoordSys(coordSys)) {
          this._renderOnGeo(coordSys, seriesModel, visualMapOfThisSeries, api);
        }
      };

      HeatmapView.prototype.incrementalPrepareRender = function (seriesModel, ecModel, api) {
        this.group.removeAll();
      };

      HeatmapView.prototype.incrementalRender = function (params, seriesModel, ecModel, api) {
        var coordSys = seriesModel.coordinateSystem;

        if (coordSys) {
          // geo does not support incremental rendering?
          if (isGeoCoordSys(coordSys)) {
            this.render(seriesModel, ecModel, api);
          } else {
            this._progressiveEls = [];

            this._renderOnCartesianAndCalendar(seriesModel, api, params.start, params.end, true);
          }
        }
      };

      HeatmapView.prototype.eachRendered = function (cb) {
        traverseElements(this._progressiveEls || this.group, cb);
      };

      HeatmapView.prototype._renderOnCartesianAndCalendar = function (seriesModel, api, start, end, incremental) {
        var coordSys = seriesModel.coordinateSystem;
        var isCartesian2d = isCoordinateSystemType(coordSys, 'cartesian2d');
        var width;
        var height;
        var xAxisExtent;
        var yAxisExtent;

        if (isCartesian2d) {
          var xAxis = coordSys.getAxis('x');
          var yAxis = coordSys.getAxis('y');

          if ("development" !== 'production') {
            if (!(xAxis.type === 'category' && yAxis.type === 'category')) {
              throw new Error('Heatmap on cartesian must have two category axes');
            }

            if (!(xAxis.onBand && yAxis.onBand)) {
              throw new Error('Heatmap on cartesian must have two axes with boundaryGap true');
            }
          } // add 0.5px to avoid the gaps


          width = xAxis.getBandWidth() + .5;
          height = yAxis.getBandWidth() + .5;
          xAxisExtent = xAxis.scale.getExtent();
          yAxisExtent = yAxis.scale.getExtent();
        }

        var group = this.group;
        var data = seriesModel.getData();
        var emphasisStyle = seriesModel.getModel(['emphasis', 'itemStyle']).getItemStyle();
        var blurStyle = seriesModel.getModel(['blur', 'itemStyle']).getItemStyle();
        var selectStyle = seriesModel.getModel(['select', 'itemStyle']).getItemStyle();
        var borderRadius = seriesModel.get(['itemStyle', 'borderRadius']);
        var labelStatesModels = getLabelStatesModels(seriesModel);
        var emphasisModel = seriesModel.getModel('emphasis');
        var focus = emphasisModel.get('focus');
        var blurScope = emphasisModel.get('blurScope');
        var emphasisDisabled = emphasisModel.get('disabled');
        var dataDims = isCartesian2d ? [data.mapDimension('x'), data.mapDimension('y'), data.mapDimension('value')] : [data.mapDimension('time'), data.mapDimension('value')];

        for (var idx = start; idx < end; idx++) {
          var rect = void 0;
          var style = data.getItemVisual(idx, 'style');

          if (isCartesian2d) {
            var dataDimX = data.get(dataDims[0], idx);
            var dataDimY = data.get(dataDims[1], idx); // Ignore empty data and out of extent data

            if (isNaN(data.get(dataDims[2], idx)) || isNaN(dataDimX) || isNaN(dataDimY) || dataDimX < xAxisExtent[0] || dataDimX > xAxisExtent[1] || dataDimY < yAxisExtent[0] || dataDimY > yAxisExtent[1]) {
              continue;
            }

            var point = coordSys.dataToPoint([dataDimX, dataDimY]);
            rect = new Rect({
              shape: {
                x: point[0] - width / 2,
                y: point[1] - height / 2,
                width: width,
                height: height
              },
              style: style
            });
          } else {
            // Ignore empty data
            if (isNaN(data.get(dataDims[1], idx))) {
              continue;
            }

            rect = new Rect({
              z2: 1,
              shape: coordSys.dataToRect([data.get(dataDims[0], idx)]).contentShape,
              style: style
            });
          } // Optimization for large dataset


          if (data.hasItemOption) {
            var itemModel = data.getItemModel(idx);
            var emphasisModel_1 = itemModel.getModel('emphasis');
            emphasisStyle = emphasisModel_1.getModel('itemStyle').getItemStyle();
            blurStyle = itemModel.getModel(['blur', 'itemStyle']).getItemStyle();
            selectStyle = itemModel.getModel(['select', 'itemStyle']).getItemStyle(); // Each item value struct in the data would be firstly
            // {
            //     itemStyle: { borderRadius: [30, 30] },
            //     value: [2022, 02, 22]
            // }

            borderRadius = itemModel.get(['itemStyle', 'borderRadius']);
            focus = emphasisModel_1.get('focus');
            blurScope = emphasisModel_1.get('blurScope');
            emphasisDisabled = emphasisModel_1.get('disabled');
            labelStatesModels = getLabelStatesModels(itemModel);
          }

          rect.shape.r = borderRadius;
          var rawValue = seriesModel.getRawValue(idx);
          var defaultText = '-';

          if (rawValue && rawValue[2] != null) {
            defaultText = rawValue[2] + '';
          }

          setLabelStyle(rect, labelStatesModels, {
            labelFetcher: seriesModel,
            labelDataIndex: idx,
            defaultOpacity: style.opacity,
            defaultText: defaultText
          });
          rect.ensureState('emphasis').style = emphasisStyle;
          rect.ensureState('blur').style = blurStyle;
          rect.ensureState('select').style = selectStyle;
          toggleHoverEmphasis(rect, focus, blurScope, emphasisDisabled);
          rect.incremental = incremental; // PENDING

          if (incremental) {
            // Rect must use hover layer if it's incremental.
            rect.states.emphasis.hoverLayer = true;
          }

          group.add(rect);
          data.setItemGraphicEl(idx, rect);

          if (this._progressiveEls) {
            this._progressiveEls.push(rect);
          }
        }
      };

      HeatmapView.prototype._renderOnGeo = function (geo, seriesModel, visualMapModel, api) {
        var inRangeVisuals = visualMapModel.targetVisuals.inRange;
        var outOfRangeVisuals = visualMapModel.targetVisuals.outOfRange; // if (!visualMapping) {
        //     throw new Error('Data range must have color visuals');
        // }

        var data = seriesModel.getData();
        var hmLayer = this._hmLayer || this._hmLayer || new HeatmapLayer();
        hmLayer.blurSize = seriesModel.get('blurSize');
        hmLayer.pointSize = seriesModel.get('pointSize');
        hmLayer.minOpacity = seriesModel.get('minOpacity');
        hmLayer.maxOpacity = seriesModel.get('maxOpacity');
        var rect = geo.getViewRect().clone();
        var roamTransform = geo.getRoamTransform();
        rect.applyTransform(roamTransform); // Clamp on viewport

        var x = Math.max(rect.x, 0);
        var y = Math.max(rect.y, 0);
        var x2 = Math.min(rect.width + rect.x, api.getWidth());
        var y2 = Math.min(rect.height + rect.y, api.getHeight());
        var width = x2 - x;
        var height = y2 - y;
        var dims = [data.mapDimension('lng'), data.mapDimension('lat'), data.mapDimension('value')];
        var points = data.mapArray(dims, function (lng, lat, value) {
          var pt = geo.dataToPoint([lng, lat]);
          pt[0] -= x;
          pt[1] -= y;
          pt.push(value);
          return pt;
        });
        var dataExtent = visualMapModel.getExtent();
        var isInRange = visualMapModel.type === 'visualMap.continuous' ? getIsInContinuousRange(dataExtent, visualMapModel.option.range) : getIsInPiecewiseRange(dataExtent, visualMapModel.getPieceList(), visualMapModel.option.selected);
        hmLayer.update(points, width, height, inRangeVisuals.color.getNormalizer(), {
          inRange: inRangeVisuals.color.getColorMapper(),
          outOfRange: outOfRangeVisuals.color.getColorMapper()
        }, isInRange);
        var img = new ZRImage({
          style: {
            width: width,
            height: height,
            x: x,
            y: y,
            image: hmLayer.canvas
          },
          silent: true
        });
        this.group.add(img);
      };

      HeatmapView.type = 'heatmap';
      return HeatmapView;
    }(ChartView);

    var HeatmapSeriesModel =
    /** @class */
    function (_super) {
      __extends(HeatmapSeriesModel, _super);

      function HeatmapSeriesModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = HeatmapSeriesModel.type;
        return _this;
      }

      HeatmapSeriesModel.prototype.getInitialData = function (option, ecModel) {
        return createSeriesData(null, this, {
          generateCoord: 'value'
        });
      };

      HeatmapSeriesModel.prototype.preventIncremental = function () {
        var coordSysCreator = CoordinateSystemManager.get(this.get('coordinateSystem'));

        if (coordSysCreator && coordSysCreator.dimensions) {
          return coordSysCreator.dimensions[0] === 'lng' && coordSysCreator.dimensions[1] === 'lat';
        }
      };

      HeatmapSeriesModel.type = 'series.heatmap';
      HeatmapSeriesModel.dependencies = ['grid', 'geo', 'calendar'];
      HeatmapSeriesModel.defaultOption = {
        coordinateSystem: 'cartesian2d',
        // zlevel: 0,
        z: 2,
        // Cartesian coordinate system
        // xAxisIndex: 0,
        // yAxisIndex: 0,
        // Geo coordinate system
        geoIndex: 0,
        blurSize: 30,
        pointSize: 20,
        maxOpacity: 1,
        minOpacity: 0,
        select: {
          itemStyle: {
            borderColor: '#212121'
          }
        }
      };
      return HeatmapSeriesModel;
    }(SeriesModel);

    function install$n(registers) {
      registers.registerChartView(HeatmapView);
      registers.registerSeriesModel(HeatmapSeriesModel);
    }

    var BAR_BORDER_WIDTH_QUERY = ['itemStyle', 'borderWidth']; // index: +isHorizontal

    var LAYOUT_ATTRS = [{
      xy: 'x',
      wh: 'width',
      index: 0,
      posDesc: ['left', 'right']
    }, {
      xy: 'y',
      wh: 'height',
      index: 1,
      posDesc: ['top', 'bottom']
    }];
    var pathForLineWidth = new Circle();

    var PictorialBarView =
    /** @class */
    function (_super) {
      __extends(PictorialBarView, _super);

      function PictorialBarView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = PictorialBarView.type;
        return _this;
      }

      PictorialBarView.prototype.render = function (seriesModel, ecModel, api) {
        var group = this.group;
        var data = seriesModel.getData();
        var oldData = this._data;
        var cartesian = seriesModel.coordinateSystem;
        var baseAxis = cartesian.getBaseAxis();
        var isHorizontal = baseAxis.isHorizontal();
        var coordSysRect = cartesian.master.getRect();
        var opt = {
          ecSize: {
            width: api.getWidth(),
            height: api.getHeight()
          },
          seriesModel: seriesModel,
          coordSys: cartesian,
          coordSysExtent: [[coordSysRect.x, coordSysRect.x + coordSysRect.width], [coordSysRect.y, coordSysRect.y + coordSysRect.height]],
          isHorizontal: isHorizontal,
          valueDim: LAYOUT_ATTRS[+isHorizontal],
          categoryDim: LAYOUT_ATTRS[1 - +isHorizontal]
        };
        data.diff(oldData).add(function (dataIndex) {
          if (!data.hasValue(dataIndex)) {
            return;
          }

          var itemModel = getItemModel(data, dataIndex);
          var symbolMeta = getSymbolMeta(data, dataIndex, itemModel, opt);
          var bar = createBar(data, opt, symbolMeta);
          data.setItemGraphicEl(dataIndex, bar);
          group.add(bar);
          updateCommon$1(bar, opt, symbolMeta);
        }).update(function (newIndex, oldIndex) {
          var bar = oldData.getItemGraphicEl(oldIndex);

          if (!data.hasValue(newIndex)) {
            group.remove(bar);
            return;
          }

          var itemModel = getItemModel(data, newIndex);
          var symbolMeta = getSymbolMeta(data, newIndex, itemModel, opt);
          var pictorialShapeStr = getShapeStr(data, symbolMeta);

          if (bar && pictorialShapeStr !== bar.__pictorialShapeStr) {
            group.remove(bar);
            data.setItemGraphicEl(newIndex, null);
            bar = null;
          }

          if (bar) {
            updateBar(bar, opt, symbolMeta);
          } else {
            bar = createBar(data, opt, symbolMeta, true);
          }

          data.setItemGraphicEl(newIndex, bar);
          bar.__pictorialSymbolMeta = symbolMeta; // Add back

          group.add(bar);
          updateCommon$1(bar, opt, symbolMeta);
        }).remove(function (dataIndex) {
          var bar = oldData.getItemGraphicEl(dataIndex);
          bar && removeBar(oldData, dataIndex, bar.__pictorialSymbolMeta.animationModel, bar);
        }).execute();
        this._data = data;
        return this.group;
      };

      PictorialBarView.prototype.remove = function (ecModel, api) {
        var group = this.group;
        var data = this._data;

        if (ecModel.get('animation')) {
          if (data) {
            data.eachItemGraphicEl(function (bar) {
              removeBar(data, getECData(bar).dataIndex, ecModel, bar);
            });
          }
        } else {
          group.removeAll();
        }
      };

      PictorialBarView.type = 'pictorialBar';
      return PictorialBarView;
    }(ChartView); // Set or calculate default value about symbol, and calculate layout info.


    function getSymbolMeta(data, dataIndex, itemModel, opt) {
      var layout = data.getItemLayout(dataIndex);
      var symbolRepeat = itemModel.get('symbolRepeat');
      var symbolClip = itemModel.get('symbolClip');
      var symbolPosition = itemModel.get('symbolPosition') || 'start';
      var symbolRotate = itemModel.get('symbolRotate');
      var rotation = (symbolRotate || 0) * Math.PI / 180 || 0;
      var symbolPatternSize = itemModel.get('symbolPatternSize') || 2;
      var isAnimationEnabled = itemModel.isAnimationEnabled();
      var symbolMeta = {
        dataIndex: dataIndex,
        layout: layout,
        itemModel: itemModel,
        symbolType: data.getItemVisual(dataIndex, 'symbol') || 'circle',
        style: data.getItemVisual(dataIndex, 'style'),
        symbolClip: symbolClip,
        symbolRepeat: symbolRepeat,
        symbolRepeatDirection: itemModel.get('symbolRepeatDirection'),
        symbolPatternSize: symbolPatternSize,
        rotation: rotation,
        animationModel: isAnimationEnabled ? itemModel : null,
        hoverScale: isAnimationEnabled && itemModel.get(['emphasis', 'scale']),
        z2: itemModel.getShallow('z', true) || 0
      };
      prepareBarLength(itemModel, symbolRepeat, layout, opt, symbolMeta);
      prepareSymbolSize(data, dataIndex, layout, symbolRepeat, symbolClip, symbolMeta.boundingLength, symbolMeta.pxSign, symbolPatternSize, opt, symbolMeta);
      prepareLineWidth(itemModel, symbolMeta.symbolScale, rotation, opt, symbolMeta);
      var symbolSize = symbolMeta.symbolSize;
      var symbolOffset = normalizeSymbolOffset(itemModel.get('symbolOffset'), symbolSize);
      prepareLayoutInfo(itemModel, symbolSize, layout, symbolRepeat, symbolClip, symbolOffset, symbolPosition, symbolMeta.valueLineWidth, symbolMeta.boundingLength, symbolMeta.repeatCutLength, opt, symbolMeta);
      return symbolMeta;
    } // bar length can be negative.


    function prepareBarLength(itemModel, symbolRepeat, layout, opt, outputSymbolMeta) {
      var valueDim = opt.valueDim;
      var symbolBoundingData = itemModel.get('symbolBoundingData');
      var valueAxis = opt.coordSys.getOtherAxis(opt.coordSys.getBaseAxis());
      var zeroPx = valueAxis.toGlobalCoord(valueAxis.dataToCoord(0));
      var pxSignIdx = 1 - +(layout[valueDim.wh] <= 0);
      var boundingLength;

      if (isArray(symbolBoundingData)) {
        var symbolBoundingExtent = [convertToCoordOnAxis(valueAxis, symbolBoundingData[0]) - zeroPx, convertToCoordOnAxis(valueAxis, symbolBoundingData[1]) - zeroPx];
        symbolBoundingExtent[1] < symbolBoundingExtent[0] && symbolBoundingExtent.reverse();
        boundingLength = symbolBoundingExtent[pxSignIdx];
      } else if (symbolBoundingData != null) {
        boundingLength = convertToCoordOnAxis(valueAxis, symbolBoundingData) - zeroPx;
      } else if (symbolRepeat) {
        boundingLength = opt.coordSysExtent[valueDim.index][pxSignIdx] - zeroPx;
      } else {
        boundingLength = layout[valueDim.wh];
      }

      outputSymbolMeta.boundingLength = boundingLength;

      if (symbolRepeat) {
        outputSymbolMeta.repeatCutLength = layout[valueDim.wh];
      } // if 'pxSign' means sign of pixel,  it can't be zero, or symbolScale will be zero
      // and when borderWidth be settled, the actual linewidth will be NaN


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

    function convertToCoordOnAxis(axis, value) {
      return axis.toGlobalCoord(axis.dataToCoord(axis.scale.parse(value)));
    } // Support ['100%', '100%']


    function prepareSymbolSize(data, dataIndex, layout, symbolRepeat, symbolClip, boundingLength, pxSign, symbolPatternSize, opt, outputSymbolMeta) {
      var valueDim = opt.valueDim;
      var categoryDim = opt.categoryDim;
      var categorySize = Math.abs(layout[categoryDim.wh]);
      var symbolSize = data.getItemVisual(dataIndex, 'symbolSize');
      var parsedSymbolSize;

      if (isArray(symbolSize)) {
        parsedSymbolSize = symbolSize.slice();
      } else {
        if (symbolSize == null) {
          // will parse to number below
          parsedSymbolSize = ['100%', '100%'];
        } else {
          parsedSymbolSize = [symbolSize, symbolSize];
        }
      } // Note: percentage symbolSize (like '100%') do not consider lineWidth, because it is
      // to complicated to calculate real percent value if considering scaled lineWidth.
      // So the actual size will bigger than layout size if lineWidth is bigger than zero,
      // which can be tolerated in pictorial chart.


      parsedSymbolSize[categoryDim.index] = parsePercent$1(parsedSymbolSize[categoryDim.index], categorySize);
      parsedSymbolSize[valueDim.index] = parsePercent$1(parsedSymbolSize[valueDim.index], symbolRepeat ? categorySize : Math.abs(boundingLength));
      outputSymbolMeta.symbolSize = parsedSymbolSize; // If x or y is less than zero, show reversed shape.

      var symbolScale = outputSymbolMeta.symbolScale = [parsedSymbolSize[0] / symbolPatternSize, parsedSymbolSize[1] / symbolPatternSize]; // Follow convention, 'right' and 'top' is the normal scale.

      symbolScale[valueDim.index] *= (opt.isHorizontal ? -1 : 1) * pxSign;
    }

    function prepareLineWidth(itemModel, symbolScale, rotation, opt, outputSymbolMeta) {
      // In symbols are drawn with scale, so do not need to care about the case that width
      // or height are too small. But symbol use strokeNoScale, where acture lineWidth should
      // be calculated.
      var valueLineWidth = itemModel.get(BAR_BORDER_WIDTH_QUERY) || 0;

      if (valueLineWidth) {
        pathForLineWidth.attr({
          scaleX: symbolScale[0],
          scaleY: symbolScale[1],
          rotation: rotation
        });
        pathForLineWidth.updateTransform();
        valueLineWidth /= pathForLineWidth.getLineScale();
        valueLineWidth *= symbolScale[opt.valueDim.index];
      }

      outputSymbolMeta.valueLineWidth = valueLineWidth || 0;
    }

    function prepareLayoutInfo(itemModel, symbolSize, layout, symbolRepeat, symbolClip, symbolOffset, symbolPosition, valueLineWidth, boundingLength, repeatCutLength, opt, outputSymbolMeta) {
      var categoryDim = opt.categoryDim;
      var valueDim = opt.valueDim;
      var pxSign = outputSymbolMeta.pxSign;
      var unitLength = Math.max(symbolSize[valueDim.index] + valueLineWidth, 0);
      var pathLen = unitLength; // Note: rotation will not effect the layout of symbols, because user may
      // want symbols to rotate on its center, which should not be translated
      // when rotating.

      if (symbolRepeat) {
        var absBoundingLength = Math.abs(boundingLength);
        var symbolMargin = retrieve(itemModel.get('symbolMargin'), '15%') + '';
        var hasEndGap = false;

        if (symbolMargin.lastIndexOf('!') === symbolMargin.length - 1) {
          hasEndGap = true;
          symbolMargin = symbolMargin.slice(0, symbolMargin.length - 1);
        }

        var symbolMarginNumeric = parsePercent$1(symbolMargin, symbolSize[valueDim.index]);
        var uLenWithMargin = Math.max(unitLength + symbolMarginNumeric * 2, 0); // When symbol margin is less than 0, margin at both ends will be subtracted
        // to ensure that all of the symbols will not be overflow the given area.

        var endFix = hasEndGap ? 0 : symbolMarginNumeric * 2; // Both final repeatTimes and final symbolMarginNumeric area calculated based on
        // boundingLength.

        var repeatSpecified = isNumeric(symbolRepeat);
        var repeatTimes = repeatSpecified ? symbolRepeat : toIntTimes((absBoundingLength + endFix) / uLenWithMargin); // Adjust calculate margin, to ensure each symbol is displayed
        // entirely in the given layout area.

        var mDiff = absBoundingLength - repeatTimes * unitLength;
        symbolMarginNumeric = mDiff / 2 / (hasEndGap ? repeatTimes : Math.max(repeatTimes - 1, 1));
        uLenWithMargin = unitLength + symbolMarginNumeric * 2;
        endFix = hasEndGap ? 0 : symbolMarginNumeric * 2; // Update repeatTimes when not all symbol will be shown.

        if (!repeatSpecified && symbolRepeat !== 'fixed') {
          repeatTimes = repeatCutLength ? toIntTimes((Math.abs(repeatCutLength) + endFix) / uLenWithMargin) : 0;
        }

        pathLen = repeatTimes * uLenWithMargin - endFix;
        outputSymbolMeta.repeatTimes = repeatTimes;
        outputSymbolMeta.symbolMargin = symbolMarginNumeric;
      }

      var sizeFix = pxSign * (pathLen / 2);
      var pathPosition = outputSymbolMeta.pathPosition = [];
      pathPosition[categoryDim.index] = layout[categoryDim.wh] / 2;
      pathPosition[valueDim.index] = symbolPosition === 'start' ? sizeFix : symbolPosition === 'end' ? boundingLength - sizeFix : boundingLength / 2; // 'center'

      if (symbolOffset) {
        pathPosition[0] += symbolOffset[0];
        pathPosition[1] += symbolOffset[1];
      }

      var bundlePosition = outputSymbolMeta.bundlePosition = [];
      bundlePosition[categoryDim.index] = layout[categoryDim.xy];
      bundlePosition[valueDim.index] = layout[valueDim.xy];
      var barRectShape = outputSymbolMeta.barRectShape = extend({}, layout);
      barRectShape[valueDim.wh] = pxSign * Math.max(Math.abs(layout[valueDim.wh]), Math.abs(pathPosition[valueDim.index] + sizeFix));
      barRectShape[categoryDim.wh] = layout[categoryDim.wh];
      var clipShape = outputSymbolMeta.clipShape = {}; // Consider that symbol may be overflow layout rect.

      clipShape[categoryDim.xy] = -layout[categoryDim.xy];
      clipShape[categoryDim.wh] = opt.ecSize[categoryDim.wh];
      clipShape[valueDim.xy] = 0;
      clipShape[valueDim.wh] = layout[valueDim.wh];
    }

    function createPath(symbolMeta) {
      var symbolPatternSize = symbolMeta.symbolPatternSize;
      var path = createSymbol( // Consider texture img, make a big size.
      symbolMeta.symbolType, -symbolPatternSize / 2, -symbolPatternSize / 2, symbolPatternSize, symbolPatternSize);
      path.attr({
        culling: true
      });
      path.type !== 'image' && path.setStyle({
        strokeNoScale: true
      });
      return path;
    }

    function createOrUpdateRepeatSymbols(bar, opt, symbolMeta, isUpdate) {
      var bundle = bar.__pictorialBundle;
      var symbolSize = symbolMeta.symbolSize;
      var valueLineWidth = symbolMeta.valueLineWidth;
      var pathPosition = symbolMeta.pathPosition;
      var valueDim = opt.valueDim;
      var repeatTimes = symbolMeta.repeatTimes || 0;
      var index = 0;
      var unit = symbolSize[opt.valueDim.index] + valueLineWidth + symbolMeta.symbolMargin * 2;
      eachPath(bar, function (path) {
        path.__pictorialAnimationIndex = index;
        path.__pictorialRepeatTimes = repeatTimes;

        if (index < repeatTimes) {
          updateAttr(path, null, makeTarget(index), symbolMeta, isUpdate);
        } else {
          updateAttr(path, null, {
            scaleX: 0,
            scaleY: 0
          }, symbolMeta, isUpdate, function () {
            bundle.remove(path);
          });
        } // updateHoverAnimation(path, symbolMeta);


        index++;
      });

      for (; index < repeatTimes; index++) {
        var path = createPath(symbolMeta);
        path.__pictorialAnimationIndex = index;
        path.__pictorialRepeatTimes = repeatTimes;
        bundle.add(path);
        var target = makeTarget(index);
        updateAttr(path, {
          x: target.x,
          y: target.y,
          scaleX: 0,
          scaleY: 0
        }, {
          scaleX: target.scaleX,
          scaleY: target.scaleY,
          rotation: target.rotation
        }, symbolMeta, isUpdate);
      }

      function makeTarget(index) {
        var position = pathPosition.slice(); // (start && pxSign > 0) || (end && pxSign < 0): i = repeatTimes - index
        // Otherwise: i = index;

        var pxSign = symbolMeta.pxSign;
        var i = index;

        if (symbolMeta.symbolRepeatDirection === 'start' ? pxSign > 0 : pxSign < 0) {
          i = repeatTimes - 1 - index;
        }

        position[valueDim.index] = unit * (i - repeatTimes / 2 + 0.5) + pathPosition[valueDim.index];
        return {
          x: position[0],
          y: position[1],
          scaleX: symbolMeta.symbolScale[0],
          scaleY: symbolMeta.symbolScale[1],
          rotation: symbolMeta.rotation
        };
      }
    }

    function createOrUpdateSingleSymbol(bar, opt, symbolMeta, isUpdate) {
      var bundle = bar.__pictorialBundle;
      var mainPath = bar.__pictorialMainPath;

      if (!mainPath) {
        mainPath = bar.__pictorialMainPath = createPath(symbolMeta);
        bundle.add(mainPath);
        updateAttr(mainPath, {
          x: symbolMeta.pathPosition[0],
          y: symbolMeta.pathPosition[1],
          scaleX: 0,
          scaleY: 0,
          rotation: symbolMeta.rotation
        }, {
          scaleX: symbolMeta.symbolScale[0],
          scaleY: symbolMeta.symbolScale[1]
        }, symbolMeta, isUpdate);
      } else {
        updateAttr(mainPath, null, {
          x: symbolMeta.pathPosition[0],
          y: symbolMeta.pathPosition[1],
          scaleX: symbolMeta.symbolScale[0],
          scaleY: symbolMeta.symbolScale[1],
          rotation: symbolMeta.rotation
        }, symbolMeta, isUpdate);
      }
    } // bar rect is used for label.


    function createOrUpdateBarRect(bar, symbolMeta, isUpdate) {
      var rectShape = extend({}, symbolMeta.barRectShape);
      var barRect = bar.__pictorialBarRect;

      if (!barRect) {
        barRect = bar.__pictorialBarRect = new Rect({
          z2: 2,
          shape: rectShape,
          silent: true,
          style: {
            stroke: 'transparent',
            fill: 'transparent',
            lineWidth: 0
          }
        });
        barRect.disableMorphing = true;
        bar.add(barRect);
      } else {
        updateAttr(barRect, null, {
          shape: rectShape
        }, symbolMeta, isUpdate);
      }
    }

    function createOrUpdateClip(bar, opt, symbolMeta, isUpdate) {
      // If not clip, symbol will be remove and rebuilt.
      if (symbolMeta.symbolClip) {
        var clipPath = bar.__pictorialClipPath;
        var clipShape = extend({}, symbolMeta.clipShape);
        var valueDim = opt.valueDim;
        var animationModel = symbolMeta.animationModel;
        var dataIndex = symbolMeta.dataIndex;

        if (clipPath) {
          updateProps(clipPath, {
            shape: clipShape
          }, animationModel, dataIndex);
        } else {
          clipShape[valueDim.wh] = 0;
          clipPath = new Rect({
            shape: clipShape
          });

          bar.__pictorialBundle.setClipPath(clipPath);

          bar.__pictorialClipPath = clipPath;
          var target = {};
          target[valueDim.wh] = symbolMeta.clipShape[valueDim.wh];
          graphic[isUpdate ? 'updateProps' : 'initProps'](clipPath, {
            shape: target
          }, animationModel, dataIndex);
        }
      }
    }

    function getItemModel(data, dataIndex) {
      var itemModel = data.getItemModel(dataIndex);
      itemModel.getAnimationDelayParams = getAnimationDelayParams;
      itemModel.isAnimationEnabled = isAnimationEnabled;
      return itemModel;
    }

    function getAnimationDelayParams(path) {
      // The order is the same as the z-order, see `symbolRepeatDiretion`.
      return {
        index: path.__pictorialAnimationIndex,
        count: path.__pictorialRepeatTimes
      };
    }

    function isAnimationEnabled() {
      // `animation` prop can be set on itemModel in pictorial bar chart.
      return this.parentModel.isAnimationEnabled() && !!this.getShallow('animation');
    }

    function createBar(data, opt, symbolMeta, isUpdate) {
      // bar is the main element for each data.
      var bar = new Group(); // bundle is used for location and clip.

      var bundle = new Group();
      bar.add(bundle);
      bar.__pictorialBundle = bundle;
      bundle.x = symbolMeta.bundlePosition[0];
      bundle.y = symbolMeta.bundlePosition[1];

      if (symbolMeta.symbolRepeat) {
        createOrUpdateRepeatSymbols(bar, opt, symbolMeta);
      } else {
        createOrUpdateSingleSymbol(bar, opt, symbolMeta);
      }

      createOrUpdateBarRect(bar, symbolMeta, isUpdate);
      createOrUpdateClip(bar, opt, symbolMeta, isUpdate);
      bar.__pictorialShapeStr = getShapeStr(data, symbolMeta);
      bar.__pictorialSymbolMeta = symbolMeta;
      return bar;
    }

    function updateBar(bar, opt, symbolMeta) {
      var animationModel = symbolMeta.animationModel;
      var dataIndex = symbolMeta.dataIndex;
      var bundle = bar.__pictorialBundle;
      updateProps(bundle, {
        x: symbolMeta.bundlePosition[0],
        y: symbolMeta.bundlePosition[1]
      }, animationModel, dataIndex);

      if (symbolMeta.symbolRepeat) {
        createOrUpdateRepeatSymbols(bar, opt, symbolMeta, true);
      } else {
        createOrUpdateSingleSymbol(bar, opt, symbolMeta, true);
      }

      createOrUpdateBarRect(bar, symbolMeta, true);
      createOrUpdateClip(bar, opt, symbolMeta, true);
    }

    function removeBar(data, dataIndex, animationModel, bar) {
      // Not show text when animating
      var labelRect = bar.__pictorialBarRect;
      labelRect && labelRect.removeTextContent();
      var paths = [];
      eachPath(bar, function (path) {
        paths.push(path);
      });
      bar.__pictorialMainPath && paths.push(bar.__pictorialMainPath); // I do not find proper remove animation for clip yet.

      bar.__pictorialClipPath && (animationModel = null);
      each(paths, function (path) {
        removeElement(path, {
          scaleX: 0,
          scaleY: 0
        }, animationModel, dataIndex, function () {
          bar.parent && bar.parent.remove(bar);
        });
      });
      data.setItemGraphicEl(dataIndex, null);
    }

    function getShapeStr(data, symbolMeta) {
      return [data.getItemVisual(symbolMeta.dataIndex, 'symbol') || 'none', !!symbolMeta.symbolRepeat, !!symbolMeta.symbolClip].join(':');
    }

    function eachPath(bar, cb, context) {
      // Do not use Group#eachChild, because it do not support remove.
      each(bar.__pictorialBundle.children(), function (el) {
        el !== bar.__pictorialBarRect && cb.call(context, el);
      });
    }

    function updateAttr(el, immediateAttrs, animationAttrs, symbolMeta, isUpdate, cb) {
      immediateAttrs && el.attr(immediateAttrs); // when symbolCip used, only clip path has init animation, otherwise it would be weird effect.

      if (symbolMeta.symbolClip && !isUpdate) {
        animationAttrs && el.attr(animationAttrs);
      } else {
        animationAttrs && graphic[isUpdate ? 'updateProps' : 'initProps'](el, animationAttrs, symbolMeta.animationModel, symbolMeta.dataIndex, cb);
      }
    }

    function updateCommon$1(bar, opt, symbolMeta) {
      var dataIndex = symbolMeta.dataIndex;
      var itemModel = symbolMeta.itemModel; // Color must be excluded.
      // Because symbol provide setColor individually to set fill and stroke

      var emphasisModel = itemModel.getModel('emphasis');
      var emphasisStyle = emphasisModel.getModel('itemStyle').getItemStyle();
      var blurStyle = itemModel.getModel(['blur', 'itemStyle']).getItemStyle();
      var selectStyle = itemModel.getModel(['select', 'itemStyle']).getItemStyle();
      var cursorStyle = itemModel.getShallow('cursor');
      var focus = emphasisModel.get('focus');
      var blurScope = emphasisModel.get('blurScope');
      var hoverScale = emphasisModel.get('scale');
      eachPath(bar, function (path) {
        if (path instanceof ZRImage) {
          var pathStyle = path.style;
          path.useStyle(extend({
            // TODO other properties like dx, dy ?
            image: pathStyle.image,
            x: pathStyle.x,
            y: pathStyle.y,
            width: pathStyle.width,
            height: pathStyle.height
          }, symbolMeta.style));
        } else {
          path.useStyle(symbolMeta.style);
        }

        var emphasisState = path.ensureState('emphasis');
        emphasisState.style = emphasisStyle;

        if (hoverScale) {
          // NOTE: Must after scale is set after updateAttr
          emphasisState.scaleX = path.scaleX * 1.1;
          emphasisState.scaleY = path.scaleY * 1.1;
        }

        path.ensureState('blur').style = blurStyle;
        path.ensureState('select').style = selectStyle;
        cursorStyle && (path.cursor = cursorStyle);
        path.z2 = symbolMeta.z2;
      });
      var barPositionOutside = opt.valueDim.posDesc[+(symbolMeta.boundingLength > 0)];
      var barRect = bar.__pictorialBarRect;
      setLabelStyle(barRect, getLabelStatesModels(itemModel), {
        labelFetcher: opt.seriesModel,
        labelDataIndex: dataIndex,
        defaultText: getDefaultLabel(opt.seriesModel.getData(), dataIndex),
        inheritColor: symbolMeta.style.fill,
        defaultOpacity: symbolMeta.style.opacity,
        defaultOutsidePosition: barPositionOutside
      });
      toggleHoverEmphasis(bar, focus, blurScope, emphasisModel.get('disabled'));
    }

    function toIntTimes(times) {
      var roundedTimes = Math.round(times); // Escapse accurate error

      return Math.abs(times - roundedTimes) < 1e-4 ? roundedTimes : Math.ceil(times);
    }

    var PictorialBarSeriesModel =
    /** @class */
    function (_super) {
      __extends(PictorialBarSeriesModel, _super);

      function PictorialBarSeriesModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = PictorialBarSeriesModel.type;
        _this.hasSymbolVisual = true;
        _this.defaultSymbol = 'roundRect';
        return _this;
      }

      PictorialBarSeriesModel.prototype.getInitialData = function (option) {
        // Disable stack.
        option.stack = null;
        return _super.prototype.getInitialData.apply(this, arguments);
      };

      PictorialBarSeriesModel.type = 'series.pictorialBar';
      PictorialBarSeriesModel.dependencies = ['grid'];
      PictorialBarSeriesModel.defaultOption = inheritDefaultOption(BaseBarSeriesModel.defaultOption, {
        symbol: 'circle',
        symbolSize: null,
        symbolRotate: null,
        symbolPosition: null,
        symbolOffset: null,
        symbolMargin: null,
        symbolRepeat: false,
        symbolRepeatDirection: 'end',
        symbolClip: false,
        symbolBoundingData: null,
        symbolPatternSize: 400,
        barGap: '-100%',
        // z can be set in data item, which is z2 actually.
        // Disable progressive
        progressive: 0,
        emphasis: {
          // By default pictorialBar do not hover scale. Hover scale is not suitable
          // for the case that both has foreground and background.
          scale: false
        },
        select: {
          itemStyle: {
            borderColor: '#212121'
          }
        }
      });
      return PictorialBarSeriesModel;
    }(BaseBarSeriesModel);

    function install$o(registers) {
      registers.registerChartView(PictorialBarView);
      registers.registerSeriesModel(PictorialBarSeriesModel);
      registers.registerLayout(registers.PRIORITY.VISUAL.LAYOUT, curry(layout, 'pictorialBar')); // Do layout after other overall layout, which can prepare some information.

      registers.registerLayout(registers.PRIORITY.VISUAL.PROGRESSIVE_LAYOUT, createProgressiveLayout('pictorialBar'));
    }

    var ThemeRiverView =
    /** @class */
    function (_super) {
      __extends(ThemeRiverView, _super);

      function ThemeRiverView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = ThemeRiverView.type;
        _this._layers = [];
        return _this;
      }

      ThemeRiverView.prototype.render = function (seriesModel, ecModel, api) {
        var data = seriesModel.getData();
        var self = this;
        var group = this.group;
        var layersSeries = seriesModel.getLayerSeries();
        var layoutInfo = data.getLayout('layoutInfo');
        var rect = layoutInfo.rect;
        var boundaryGap = layoutInfo.boundaryGap;
        group.x = 0;
        group.y = rect.y + boundaryGap[0];

        function keyGetter(item) {
          return item.name;
        }

        var dataDiffer = new DataDiffer(this._layersSeries || [], layersSeries, keyGetter, keyGetter);
        var newLayersGroups = [];
        dataDiffer.add(bind(process, this, 'add')).update(bind(process, this, 'update')).remove(bind(process, this, 'remove')).execute();

        function process(status, idx, oldIdx) {
          var oldLayersGroups = self._layers;

          if (status === 'remove') {
            group.remove(oldLayersGroups[idx]);
            return;
          }

          var points0 = [];
          var points1 = [];
          var style;
          var indices = layersSeries[idx].indices;
          var j = 0;

          for (; j < indices.length; j++) {
            var layout = data.getItemLayout(indices[j]);
            var x = layout.x;
            var y0 = layout.y0;
            var y = layout.y;
            points0.push(x, y0);
            points1.push(x, y0 + y);
            style = data.getItemVisual(indices[j], 'style');
          }

          var polygon;
          var textLayout = data.getItemLayout(indices[0]);
          var labelModel = seriesModel.getModel('label');
          var margin = labelModel.get('margin');
          var emphasisModel = seriesModel.getModel('emphasis');

          if (status === 'add') {
            var layerGroup = newLayersGroups[idx] = new Group();
            polygon = new ECPolygon({
              shape: {
                points: points0,
                stackedOnPoints: points1,
                smooth: 0.4,
                stackedOnSmooth: 0.4,
                smoothConstraint: false
              },
              z2: 0
            });
            layerGroup.add(polygon);
            group.add(layerGroup);

            if (seriesModel.isAnimationEnabled()) {
              polygon.setClipPath(createGridClipShape$2(polygon.getBoundingRect(), seriesModel, function () {
                polygon.removeClipPath();
              }));
            }
          } else {
            var layerGroup = oldLayersGroups[oldIdx];
            polygon = layerGroup.childAt(0);
            group.add(layerGroup);
            newLayersGroups[idx] = layerGroup;
            updateProps(polygon, {
              shape: {
                points: points0,
                stackedOnPoints: points1
              }
            }, seriesModel);
            saveOldStyle(polygon);
          }

          setLabelStyle(polygon, getLabelStatesModels(seriesModel), {
            labelDataIndex: indices[j - 1],
            defaultText: data.getName(indices[j - 1]),
            inheritColor: style.fill
          }, {
            normal: {
              verticalAlign: 'middle' // align: 'right'

            }
          });
          polygon.setTextConfig({
            position: null,
            local: true
          });
          var labelEl = polygon.getTextContent(); // TODO More label position options.

          if (labelEl) {
            labelEl.x = textLayout.x - margin;
            labelEl.y = textLayout.y0 + textLayout.y / 2;
          }

          polygon.useStyle(style);
          data.setItemGraphicEl(idx, polygon);
          setStatesStylesFromModel(polygon, seriesModel);
          toggleHoverEmphasis(polygon, emphasisModel.get('focus'), emphasisModel.get('blurScope'), emphasisModel.get('disabled'));
        }

        this._layersSeries = layersSeries;
        this._layers = newLayersGroups;
      };

      ThemeRiverView.type = 'themeRiver';
      return ThemeRiverView;
    }(ChartView);

    function createGridClipShape$2(rect, seriesModel, cb) {
      var rectEl = new Rect({
        shape: {
          x: rect.x - 10,
          y: rect.y - 10,
          width: 0,
          height: rect.height + 20
        }
      });
      initProps(rectEl, {
        shape: {
          x: rect.x - 50,
          width: rect.width + 100,
          height: rect.height + 20
        }
      }, seriesModel, cb);
      return rectEl;
    }

    var DATA_NAME_INDEX = 2;

    var ThemeRiverSeriesModel =
    /** @class */
    function (_super) {
      __extends(ThemeRiverSeriesModel, _super);

      function ThemeRiverSeriesModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = ThemeRiverSeriesModel.type;
        return _this;
      }
      /**
       * @override
       */


      ThemeRiverSeriesModel.prototype.init = function (option) {
        // eslint-disable-next-line
        _super.prototype.init.apply(this, arguments); // Put this function here is for the sake of consistency of code style.
        // 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));
      };
      /**
       * If there is no value of a certain point in the time for some event,set it value to 0.
       *
       * @param {Array} data  initial data in the option
       * @return {Array}
       */


      ThemeRiverSeriesModel.prototype.fixData = function (data) {
        var rawDataLength = data.length;
        /**
         * Make sure every layer data get the same keys.
         * The value index tells which layer has visited.
         * {
         *  2014/01/01: -1
         * }
         */

        var timeValueKeys = {}; // grouped data by name

        var groupResult = groupData(data, function (item) {
          if (!timeValueKeys.hasOwnProperty(item[0] + '')) {
            timeValueKeys[item[0] + ''] = -1;
          }

          return item[2];
        });
        var layerData = [];
        groupResult.buckets.each(function (items, key) {
          layerData.push({
            name: key,
            dataList: items
          });
        });
        var layerNum = layerData.length;

        for (var k = 0; k < layerNum; ++k) {
          var name_1 = layerData[k].name;

          for (var j = 0; j < layerData[k].dataList.length; ++j) {
            var timeValue = layerData[k].dataList[j][0] + '';
            timeValueKeys[timeValue] = k;
          }

          for (var timeValue in timeValueKeys) {
            if (timeValueKeys.hasOwnProperty(timeValue) && timeValueKeys[timeValue] !== k) {
              timeValueKeys[timeValue] = k;
              data[rawDataLength] = [timeValue, 0, name_1];
              rawDataLength++;
            }
          }
        }

        return data;
      };
      /**
       * @override
       * @param  option  the initial option that user gave
       * @param  ecModel  the model object for themeRiver option
       */


      ThemeRiverSeriesModel.prototype.getInitialData = function (option, ecModel) {
        var singleAxisModel = this.getReferringComponents('singleAxis', SINGLE_REFERRING).models[0];
        var axisType = singleAxisModel.get('type'); // filter the data item with the value of label is undefined

        var filterData = filter(option.data, function (dataItem) {
          return dataItem[2] !== undefined;
        }); // ??? TODO design a stage to transfer data for themeRiver and lines?

        var data = this.fixData(filterData || []);
        var nameList = [];
        var nameMap = this.nameMap = createHashMap();
        var count = 0;

        for (var i = 0; i < data.length; ++i) {
          nameList.push(data[i][DATA_NAME_INDEX]);

          if (!nameMap.get(data[i][DATA_NAME_INDEX])) {
            nameMap.set(data[i][DATA_NAME_INDEX], count);
            count++;
          }
        }

        var dimensions = prepareSeriesDataSchema(data, {
          coordDimensions: ['single'],
          dimensionsDefine: [{
            name: 'time',
            type: getDimensionTypeByAxis(axisType)
          }, {
            name: 'value',
            type: 'float'
          }, {
            name: 'name',
            type: 'ordinal'
          }],
          encodeDefine: {
            single: 0,
            value: 1,
            itemName: 2
          }
        }).dimensions;
        var list = new SeriesData(dimensions, this);
        list.initData(data);
        return list;
      };
      /**
       * The raw data is divided into multiple layers and each layer
       *     has same name.
       */


      ThemeRiverSeriesModel.prototype.getLayerSeries = function () {
        var data = this.getData();
        var lenCount = data.count();
        var indexArr = [];

        for (var i = 0; i < lenCount; ++i) {
          indexArr[i] = i;
        }

        var timeDim = data.mapDimension('single'); // data group by name

        var groupResult = groupData(indexArr, function (index) {
          return data.get('name', index);
        });
        var layerSeries = [];
        groupResult.buckets.each(function (items, key) {
          items.sort(function (index1, index2) {
            return data.get(timeDim, index1) - data.get(timeDim, index2);
          });
          layerSeries.push({
            name: key,
            indices: items
          });
        });
        return layerSeries;
      };
      /**
       * Get data indices for show tooltip content
       */


      ThemeRiverSeriesModel.prototype.getAxisTooltipData = function (dim, value, baseAxis) {
        if (!isArray(dim)) {
          dim = dim ? [dim] : [];
        }

        var data = this.getData();
        var layerSeries = this.getLayerSeries();
        var indices = [];
        var layerNum = layerSeries.length;
        var nestestValue;

        for (var i = 0; i < layerNum; ++i) {
          var minDist = Number.MAX_VALUE;
          var nearestIdx = -1;
          var pointNum = layerSeries[i].indices.length;

          for (var j = 0; j < pointNum; ++j) {
            var theValue = data.get(dim[0], layerSeries[i].indices[j]);
            var dist = Math.abs(theValue - value);

            if (dist <= minDist) {
              nestestValue = theValue;
              minDist = dist;
              nearestIdx = layerSeries[i].indices[j];
            }
          }

          indices.push(nearestIdx);
        }

        return {
          dataIndices: indices,
          nestestValue: nestestValue
        };
      };

      ThemeRiverSeriesModel.prototype.formatTooltip = function (dataIndex, multipleSeries, dataType) {
        var data = this.getData();
        var name = data.getName(dataIndex);
        var value = data.get(data.mapDimension('value'), dataIndex);
        return createTooltipMarkup('nameValue', {
          name: name,
          value: value
        });
      };

      ThemeRiverSeriesModel.type = 'series.themeRiver';
      ThemeRiverSeriesModel.dependencies = ['singleAxis'];
      ThemeRiverSeriesModel.defaultOption = {
        // zlevel: 0,
        z: 2,
        colorBy: 'data',
        coordinateSystem: 'singleAxis',
        // gap in axis's orthogonal orientation
        boundaryGap: ['10%', '10%'],
        // legendHoverLink: true,
        singleAxisIndex: 0,
        animationEasing: 'linear',
        label: {
          margin: 4,
          show: true,
          position: 'left',
          fontSize: 11
        },
        emphasis: {
          label: {
            show: true
          }
        }
      };
      return ThemeRiverSeriesModel;
    }(SeriesModel);

    function themeRiverLayout(ecModel, api) {
      ecModel.eachSeriesByType('themeRiver', function (seriesModel) {
        var data = seriesModel.getData();
        var single = seriesModel.coordinateSystem;
        var layoutInfo = {}; // use the axis boundingRect for view

        var rect = single.getRect();
        layoutInfo.rect = rect;
        var boundaryGap = seriesModel.get('boundaryGap');
        var axis = single.getAxis();
        layoutInfo.boundaryGap = boundaryGap;

        if (axis.orient === 'horizontal') {
          boundaryGap[0] = parsePercent$1(boundaryGap[0], rect.height);
          boundaryGap[1] = parsePercent$1(boundaryGap[1], rect.height);
          var height = rect.height - boundaryGap[0] - boundaryGap[1];
          doThemeRiverLayout(data, seriesModel, height);
        } else {
          boundaryGap[0] = parsePercent$1(boundaryGap[0], rect.width);
          boundaryGap[1] = parsePercent$1(boundaryGap[1], rect.width);
          var width = rect.width - boundaryGap[0] - boundaryGap[1];
          doThemeRiverLayout(data, seriesModel, width);
        }

        data.setLayout('layoutInfo', layoutInfo);
      });
    }
    /**
     * The layout information about themeriver
     *
     * @param data  data in the series
     * @param seriesModel  the model object of themeRiver series
     * @param height  value used to compute every series height
     */

    function doThemeRiverLayout(data, seriesModel, height) {
      if (!data.count()) {
        return;
      }

      var coordSys = seriesModel.coordinateSystem; // the data in each layer are organized into a series.

      var layerSeries = seriesModel.getLayerSeries(); // the points in each layer.

      var timeDim = data.mapDimension('single');
      var valueDim = data.mapDimension('value');
      var layerPoints = map(layerSeries, function (singleLayer) {
        return map(singleLayer.indices, function (idx) {
          var pt = coordSys.dataToPoint(data.get(timeDim, idx));
          pt[1] = data.get(valueDim, idx);
          return pt;
        });
      });
      var base = computeBaseline(layerPoints);
      var baseLine = base.y0;
      var ky = height / base.max; // set layout information for each item.

      var n = layerSeries.length;
      var m = layerSeries[0].indices.length;
      var baseY0;

      for (var j = 0; j < m; ++j) {
        baseY0 = baseLine[j] * ky;
        data.setItemLayout(layerSeries[0].indices[j], {
          layerIndex: 0,
          x: layerPoints[0][j][0],
          y0: baseY0,
          y: layerPoints[0][j][1] * ky
        });

        for (var i = 1; i < n; ++i) {
          baseY0 += layerPoints[i - 1][j][1] * ky;
          data.setItemLayout(layerSeries[i].indices[j], {
            layerIndex: i,
            x: layerPoints[i][j][0],
            y0: baseY0,
            y: layerPoints[i][j][1] * ky
          });
        }
      }
    }
    /**
     * Compute the baseLine of the rawdata
     * Inspired by Lee Byron's paper Stacked Graphs - Geometry & Aesthetics
     *
     * @param  data  the points in each layer
     */


    function computeBaseline(data) {
      var layerNum = data.length;
      var pointNum = data[0].length;
      var sums = [];
      var y0 = [];
      var max = 0;

      for (var i = 0; i < pointNum; ++i) {
        var temp = 0;

        for (var j = 0; j < layerNum; ++j) {
          temp += data[j][i][1];
        }

        if (temp > max) {
          max = temp;
        }

        sums.push(temp);
      }

      for (var k = 0; k < pointNum; ++k) {
        y0[k] = (max - sums[k]) / 2;
      }

      max = 0;

      for (var l = 0; l < pointNum; ++l) {
        var sum = sums[l] + y0[l];

        if (sum > max) {
          max = sum;
        }
      }

      return {
        y0: y0,
        max: max
      };
    }

    function install$p(registers) {
      registers.registerChartView(ThemeRiverView);
      registers.registerSeriesModel(ThemeRiverSeriesModel);
      registers.registerLayout(themeRiverLayout);
      registers.registerProcessor(dataFilter('themeRiver'));
    }

    var DEFAULT_SECTOR_Z = 2;
    var DEFAULT_TEXT_Z = 4;
    /**
     * Sunburstce of Sunburst including Sector, Label, LabelLine
     */

    var SunburstPiece =
    /** @class */
    function (_super) {
      __extends(SunburstPiece, _super);

      function SunburstPiece(node, seriesModel, ecModel, api) {
        var _this = _super.call(this) || this;

        _this.z2 = DEFAULT_SECTOR_Z;
        _this.textConfig = {
          inside: true
        };
        getECData(_this).seriesIndex = seriesModel.seriesIndex;
        var text = new ZRText({
          z2: DEFAULT_TEXT_Z,
          silent: node.getModel().get(['label', 'silent'])
        });

        _this.setTextContent(text);

        _this.updateData(true, node, seriesModel, ecModel, api);

        return _this;
      }

      SunburstPiece.prototype.updateData = function (firstCreate, node, // state: 'emphasis' | 'normal' | 'highlight' | 'downplay',
      seriesModel, ecModel, api) {
        this.node = node;
        node.piece = this;
        seriesModel = seriesModel || this._seriesModel;
        ecModel = ecModel || this._ecModel;
        var sector = this;
        getECData(sector).dataIndex = node.dataIndex;
        var itemModel = node.getModel();
        var emphasisModel = itemModel.getModel('emphasis');
        var layout = node.getLayout();
        var sectorShape = extend({}, layout);
        sectorShape.label = null;
        var normalStyle = node.getVisual('style');
        normalStyle.lineJoin = 'bevel';
        var decal = node.getVisual('decal');

        if (decal) {
          normalStyle.decal = createOrUpdatePatternFromDecal(decal, api);
        }

        var cornerRadius = getSectorCornerRadius(itemModel.getModel('itemStyle'), sectorShape, true);
        extend(sectorShape, cornerRadius);
        each(SPECIAL_STATES, function (stateName) {
          var state = sector.ensureState(stateName);
          var itemStyleModel = itemModel.getModel([stateName, 'itemStyle']);
          state.style = itemStyleModel.getItemStyle(); // border radius

          var cornerRadius = getSectorCornerRadius(itemStyleModel, sectorShape);

          if (cornerRadius) {
            state.shape = cornerRadius;
          }
        });

        if (firstCreate) {
          sector.setShape(sectorShape);
          sector.shape.r = layout.r0;
          updateProps(sector, {
            shape: {
              r: layout.r
            }
          }, seriesModel, node.dataIndex);
        } else {
          // Disable animation for gradient since no interpolation method
          // is supported for gradient
          updateProps(sector, {
            shape: sectorShape
          }, seriesModel);
          saveOldStyle(sector);
        }

        sector.useStyle(normalStyle);

        this._updateLabel(seriesModel);

        var cursorStyle = itemModel.getShallow('cursor');
        cursorStyle && sector.attr('cursor', cursorStyle);
        this._seriesModel = seriesModel || this._seriesModel;
        this._ecModel = ecModel || this._ecModel;
        var focus = emphasisModel.get('focus');
        var focusOrIndices = focus === 'ancestor' ? node.getAncestorsIndices() : focus === 'descendant' ? node.getDescendantIndices() : focus;
        toggleHoverEmphasis(this, focusOrIndices, emphasisModel.get('blurScope'), emphasisModel.get('disabled'));
      };

      SunburstPiece.prototype._updateLabel = function (seriesModel) {
        var _this = this;

        var itemModel = this.node.getModel();
        var normalLabelModel = itemModel.getModel('label');
        var layout = this.node.getLayout();
        var angle = layout.endAngle - layout.startAngle;
        var midAngle = (layout.startAngle + layout.endAngle) / 2;
        var dx = Math.cos(midAngle);
        var dy = Math.sin(midAngle);
        var sector = this;
        var label = sector.getTextContent();
        var dataIndex = this.node.dataIndex;
        var labelMinAngle = normalLabelModel.get('minAngle') / 180 * Math.PI;
        var isNormalShown = normalLabelModel.get('show') && !(labelMinAngle != null && Math.abs(angle) < labelMinAngle);
        label.ignore = !isNormalShown; // TODO use setLabelStyle

        each(DISPLAY_STATES, function (stateName) {
          var labelStateModel = stateName === 'normal' ? itemModel.getModel('label') : itemModel.getModel([stateName, 'label']);
          var isNormal = stateName === 'normal';
          var state = isNormal ? label : label.ensureState(stateName);
          var text = seriesModel.getFormattedLabel(dataIndex, stateName);

          if (isNormal) {
            text = text || _this.node.name;
          }

          state.style = createTextStyle(labelStateModel, {}, null, stateName !== 'normal', true);

          if (text) {
            state.style.text = text;
          } // Not displaying text when angle is too small


          var isShown = labelStateModel.get('show');

          if (isShown != null && !isNormal) {
            state.ignore = !isShown;
          }

          var labelPosition = getLabelAttr(labelStateModel, 'position');
          var sectorState = isNormal ? sector : sector.states[stateName];
          var labelColor = sectorState.style.fill;
          sectorState.textConfig = {
            outsideFill: labelStateModel.get('color') === 'inherit' ? labelColor : null,
            inside: labelPosition !== 'outside'
          };
          var r;
          var labelPadding = getLabelAttr(labelStateModel, 'distance') || 0;
          var textAlign = getLabelAttr(labelStateModel, 'align');

          if (labelPosition === 'outside') {
            r = layout.r + labelPadding;
            textAlign = midAngle > Math.PI / 2 ? 'right' : 'left';
          } else {
            if (!textAlign || textAlign === 'center') {
              // Put label in the center if it's a circle
              if (angle === 2 * Math.PI && layout.r0 === 0) {
                r = 0;
              } else {
                r = (layout.r + layout.r0) / 2;
              }

              textAlign = 'center';
            } else if (textAlign === 'left') {
              r = layout.r0 + labelPadding;

              if (midAngle > Math.PI / 2) {
                textAlign = 'right';
              }
            } else if (textAlign === 'right') {
              r = layout.r - labelPadding;

              if (midAngle > Math.PI / 2) {
                textAlign = 'left';
              }
            }
          }

          state.style.align = textAlign;
          state.style.verticalAlign = getLabelAttr(labelStateModel, 'verticalAlign') || 'middle';
          state.x = r * dx + layout.cx;
          state.y = r * dy + layout.cy;
          var rotateType = getLabelAttr(labelStateModel, 'rotate');
          var rotate = 0;

          if (rotateType === 'radial') {
            rotate = -midAngle;

            if (rotate < -Math.PI / 2) {
              rotate += Math.PI;
            }
          } else if (rotateType === 'tangential') {
            rotate = Math.PI / 2 - midAngle;

            if (rotate > Math.PI / 2) {
              rotate -= Math.PI;
            } else if (rotate < -Math.PI / 2) {
              rotate += Math.PI;
            }
          } else if (isNumber(rotateType)) {
            rotate = rotateType * Math.PI / 180;
          }

          state.rotation = rotate;
        });

        function getLabelAttr(model, name) {
          var stateAttr = model.get(name);

          if (stateAttr == null) {
            return normalLabelModel.get(name);
          }

          return stateAttr;
        }

        label.dirtyStyle();
      };

      return SunburstPiece;
    }(Sector);

    var ROOT_TO_NODE_ACTION = 'sunburstRootToNode';
    var HIGHLIGHT_ACTION = 'sunburstHighlight';
    var UNHIGHLIGHT_ACTION = 'sunburstUnhighlight';
    function installSunburstAction(registers) {
      registers.registerAction({
        type: ROOT_TO_NODE_ACTION,
        update: 'updateView'
      }, function (payload, ecModel) {
        ecModel.eachComponent({
          mainType: 'series',
          subType: 'sunburst',
          query: payload
        }, handleRootToNode);

        function handleRootToNode(model, index) {
          var targetInfo = retrieveTargetInfo(payload, [ROOT_TO_NODE_ACTION], model);

          if (targetInfo) {
            var originViewRoot = model.getViewRoot();

            if (originViewRoot) {
              payload.direction = aboveViewRoot(originViewRoot, targetInfo.node) ? 'rollUp' : 'drillDown';
            }

            model.resetViewRoot(targetInfo.node);
          }
        }
      });
      registers.registerAction({
        type: HIGHLIGHT_ACTION,
        update: 'none'
      }, function (payload, ecModel, api) {
        // Clone
        payload = extend({}, payload);
        ecModel.eachComponent({
          mainType: 'series',
          subType: 'sunburst',
          query: payload
        }, handleHighlight);

        function handleHighlight(model) {
          var targetInfo = retrieveTargetInfo(payload, [HIGHLIGHT_ACTION], model);

          if (targetInfo) {
            payload.dataIndex = targetInfo.node.dataIndex;
          }
        }

        if ("development" !== 'production') {
          deprecateReplaceLog('sunburstHighlight', 'highlight');
        } // Fast forward action


        api.dispatchAction(extend(payload, {
          type: 'highlight'
        }));
      });
      registers.registerAction({
        type: UNHIGHLIGHT_ACTION,
        update: 'updateView'
      }, function (payload, ecModel, api) {
        payload = extend({}, payload);

        if ("development" !== 'production') {
          deprecateReplaceLog('sunburstUnhighlight', 'downplay');
        }

        api.dispatchAction(extend(payload, {
          type: 'downplay'
        }));
      });
    }

    var SunburstView =
    /** @class */
    function (_super) {
      __extends(SunburstView, _super);

      function SunburstView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = SunburstView.type;
        return _this;
      }

      SunburstView.prototype.render = function (seriesModel, ecModel, api, // @ts-ignore
      payload) {
        var self = this;
        this.seriesModel = seriesModel;
        this.api = api;
        this.ecModel = ecModel;
        var data = seriesModel.getData();
        var virtualRoot = data.tree.root;
        var newRoot = seriesModel.getViewRoot();
        var group = this.group;
        var renderLabelForZeroData = seriesModel.get('renderLabelForZeroData');
        var newChildren = [];
        newRoot.eachNode(function (node) {
          newChildren.push(node);
        });
        var oldChildren = this._oldChildren || [];
        dualTravel(newChildren, oldChildren);
        renderRollUp(virtualRoot, newRoot);

        this._initEvents();

        this._oldChildren = newChildren;

        function dualTravel(newChildren, oldChildren) {
          if (newChildren.length === 0 && oldChildren.length === 0) {
            return;
          }

          new DataDiffer(oldChildren, newChildren, getKey, getKey).add(processNode).update(processNode).remove(curry(processNode, null)).execute();

          function getKey(node) {
            return node.getId();
          }

          function processNode(newIdx, oldIdx) {
            var newNode = newIdx == null ? null : newChildren[newIdx];
            var oldNode = oldIdx == null ? null : oldChildren[oldIdx];
            doRenderNode(newNode, oldNode);
          }
        }

        function doRenderNode(newNode, oldNode) {
          if (!renderLabelForZeroData && newNode && !newNode.getValue()) {
            // Not render data with value 0
            newNode = null;
          }

          if (newNode !== virtualRoot && oldNode !== virtualRoot) {
            if (oldNode && oldNode.piece) {
              if (newNode) {
                // Update
                oldNode.piece.updateData(false, newNode, seriesModel, ecModel, api); // For tooltip

                data.setItemGraphicEl(newNode.dataIndex, oldNode.piece);
              } else {
                // Remove
                removeNode(oldNode);
              }
            } else if (newNode) {
              // Add
              var piece = new SunburstPiece(newNode, seriesModel, ecModel, api);
              group.add(piece); // For tooltip

              data.setItemGraphicEl(newNode.dataIndex, piece);
            }
          }
        }

        function removeNode(node) {
          if (!node) {
            return;
          }

          if (node.piece) {
            group.remove(node.piece);
            node.piece = null;
          }
        }

        function renderRollUp(virtualRoot, viewRoot) {
          if (viewRoot.depth > 0) {
            // Render
            if (self.virtualPiece) {
              // Update
              self.virtualPiece.updateData(false, virtualRoot, seriesModel, ecModel, api);
            } else {
              // Add
              self.virtualPiece = new SunburstPiece(virtualRoot, seriesModel, ecModel, api);
              group.add(self.virtualPiece);
            } // TODO event scope


            viewRoot.piece.off('click');
            self.virtualPiece.on('click', function (e) {
              self._rootToNode(viewRoot.parentNode);
            });
          } else if (self.virtualPiece) {
            // Remove
            group.remove(self.virtualPiece);
            self.virtualPiece = null;
          }
        }
      };
      /**
       * @private
       */


      SunburstView.prototype._initEvents = function () {
        var _this = this;

        this.group.off('click');
        this.group.on('click', function (e) {
          var targetFound = false;

          var viewRoot = _this.seriesModel.getViewRoot();

          viewRoot.eachNode(function (node) {
            if (!targetFound && node.piece && node.piece === e.target) {
              var nodeClick = node.getModel().get('nodeClick');

              if (nodeClick === 'rootToNode') {
                _this._rootToNode(node);
              } else if (nodeClick === 'link') {
                var itemModel = node.getModel();
                var link = itemModel.get('link');

                if (link) {
                  var linkTarget = itemModel.get('target', true) || '_blank';
                  windowOpen(link, linkTarget);
                }
              }

              targetFound = true;
            }
          });
        });
      };
      /**
       * @private
       */


      SunburstView.prototype._rootToNode = function (node) {
        if (node !== this.seriesModel.getViewRoot()) {
          this.api.dispatchAction({
            type: ROOT_TO_NODE_ACTION,
            from: this.uid,
            seriesId: this.seriesModel.id,
            targetNode: node
          });
        }
      };
      /**
       * @implement
       */


      SunburstView.prototype.containPoint = function (point, seriesModel) {
        var treeRoot = seriesModel.getData();
        var itemLayout = treeRoot.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;
        }
      };

      SunburstView.type = 'sunburst';
      return SunburstView;
    }(ChartView);

    var SunburstSeriesModel =
    /** @class */
    function (_super) {
      __extends(SunburstSeriesModel, _super);

      function SunburstSeriesModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = SunburstSeriesModel.type;
        _this.ignoreStyleOnData = true;
        return _this;
      }

      SunburstSeriesModel.prototype.getInitialData = function (option, ecModel) {
        // Create a virtual root.
        var root = {
          name: option.name,
          children: option.data
        };
        completeTreeValue$1(root);
        var levelModels = this._levelModels = map(option.levels || [], function (levelDefine) {
          return new Model(levelDefine, this, ecModel);
        }, this); // Make sure always a new tree is created when setOption,
        // in TreemapView, we check whether oldTree === newTree
        // to choose mappings approach among old shapes and new shapes.

        var tree = Tree.createTree(root, this, beforeLink);

        function beforeLink(nodeData) {
          nodeData.wrapMethod('getItemModel', function (model, idx) {
            var node = tree.getNodeByDataIndex(idx);
            var levelModel = levelModels[node.depth];
            levelModel && (model.parentModel = levelModel);
            return model;
          });
        }

        return tree.data;
      };

      SunburstSeriesModel.prototype.optionUpdated = function () {
        this.resetViewRoot();
      };
      /*
       * @override
       */


      SunburstSeriesModel.prototype.getDataParams = function (dataIndex) {
        var params = _super.prototype.getDataParams.apply(this, arguments);

        var node = this.getData().tree.getNodeByDataIndex(dataIndex);
        params.treePathInfo = wrapTreePathInfo(node, this);
        return params;
      };

      SunburstSeriesModel.prototype.getLevelModel = function (node) {
        return this._levelModels && this._levelModels[node.depth];
      };

      SunburstSeriesModel.prototype.getViewRoot = function () {
        return this._viewRoot;
      };

      SunburstSeriesModel.prototype.resetViewRoot = function (viewRoot) {
        viewRoot ? this._viewRoot = viewRoot : viewRoot = this._viewRoot;
        var root = this.getRawData().tree.root;

        if (!viewRoot || viewRoot !== root && !root.contains(viewRoot)) {
          this._viewRoot = root;
        }
      };

      SunburstSeriesModel.prototype.enableAriaDecal = function () {
        enableAriaDecalForTree(this);
      };

      SunburstSeriesModel.type = 'series.sunburst';
      SunburstSeriesModel.defaultOption = {
        // zlevel: 0,
        z: 2,
        // 默认全局居中
        center: ['50%', '50%'],
        radius: [0, '75%'],
        // 默认顺时针
        clockwise: true,
        startAngle: 90,
        // 最小角度改为0
        minAngle: 0,
        // If still show when all data zero.
        stillShowZeroSum: true,
        // 'rootToNode', 'link', or false
        nodeClick: 'rootToNode',
        renderLabelForZeroData: false,
        label: {
          // could be: 'radial', 'tangential', or 'none'
          rotate: 'radial',
          show: true,
          opacity: 1,
          // 'left' is for inner side of inside, and 'right' is for outer
          // side for inside
          align: 'center',
          position: 'inside',
          distance: 5,
          silent: true
        },
        itemStyle: {
          borderWidth: 1,
          borderColor: 'white',
          borderType: 'solid',
          shadowBlur: 0,
          shadowColor: 'rgba(0, 0, 0, 0.2)',
          shadowOffsetX: 0,
          shadowOffsetY: 0,
          opacity: 1
        },
        emphasis: {
          focus: 'descendant'
        },
        blur: {
          itemStyle: {
            opacity: 0.2
          },
          label: {
            opacity: 0.1
          }
        },
        // Animation type can be expansion, scale.
        animationType: 'expansion',
        animationDuration: 1000,
        animationDurationUpdate: 500,
        data: [],

        /**
         * Sort order.
         *
         * Valid values: 'desc', 'asc', null, or callback function.
         * 'desc' and 'asc' for descend and ascendant order;
         * null for not sorting;
         * example of callback function:
         * function(nodeA, nodeB) {
         *     return nodeA.getValue() - nodeB.getValue();
         * }
         */
        sort: 'desc'
      };
      return SunburstSeriesModel;
    }(SeriesModel);

    function completeTreeValue$1(dataNode) {
      // Postorder travel tree.
      // If value of none-leaf node is not set,
      // calculate it by suming up the value of all children.
      var sum = 0;
      each(dataNode.children, function (child) {
        completeTreeValue$1(child);
        var childValue = child.value; // TODO First value of array must be a number

        isArray(childValue) && (childValue = childValue[0]);
        sum += childValue;
      });
      var thisValue = dataNode.value;

      if (isArray(thisValue)) {
        thisValue = thisValue[0];
      }

      if (thisValue == null || isNaN(thisValue)) {
        thisValue = sum;
      } // Value should not less than 0.


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

      isArray(dataNode.value) ? dataNode.value[0] = thisValue : dataNode.value = thisValue;
    }

    var RADIAN$2 = Math.PI / 180;
    function sunburstLayout(seriesType, ecModel, api) {
      ecModel.eachSeriesByType(seriesType, function (seriesModel) {
        var center = seriesModel.get('center');
        var radius = seriesModel.get('radius');

        if (!isArray(radius)) {
          radius = [0, radius];
        }

        if (!isArray(center)) {
          center = [center, center];
        }

        var width = api.getWidth();
        var height = api.getHeight();
        var size = Math.min(width, height);
        var cx = parsePercent$1(center[0], width);
        var cy = parsePercent$1(center[1], height);
        var r0 = parsePercent$1(radius[0], size / 2);
        var r = parsePercent$1(radius[1], size / 2);
        var startAngle = -seriesModel.get('startAngle') * RADIAN$2;
        var minAngle = seriesModel.get('minAngle') * RADIAN$2;
        var virtualRoot = seriesModel.getData().tree.root;
        var treeRoot = seriesModel.getViewRoot();
        var rootDepth = treeRoot.depth;
        var sort = seriesModel.get('sort');

        if (sort != null) {
          initChildren$1(treeRoot, sort);
        }

        var validDataCount = 0;
        each(treeRoot.children, function (child) {
          !isNaN(child.getValue()) && validDataCount++;
        });
        var sum = treeRoot.getValue(); // Sum may be 0

        var unitRadian = Math.PI / (sum || validDataCount) * 2;
        var renderRollupNode = treeRoot.depth > 0;
        var levels = treeRoot.height - (renderRollupNode ? -1 : 1);
        var rPerLevel = (r - r0) / (levels || 1);
        var clockwise = seriesModel.get('clockwise');
        var stillShowZeroSum = seriesModel.get('stillShowZeroSum'); // In the case some sector angle is smaller than minAngle
        // let restAngle = PI2;
        // let valueSumLargerThanMinAngle = 0;

        var dir = clockwise ? 1 : -1;
        /**
         * Render a tree
         * @return increased angle
         */

        var renderNode = function (node, startAngle) {
          if (!node) {
            return;
          }

          var endAngle = startAngle; // Render self

          if (node !== virtualRoot) {
            // Tree node is virtual, so it doesn't need to be drawn
            var value = node.getValue();
            var angle = sum === 0 && stillShowZeroSum ? unitRadian : value * unitRadian;

            if (angle < minAngle) {
              angle = minAngle; // restAngle -= minAngle;
            } // else {
            //     valueSumLargerThanMinAngle += value;
            // }


            endAngle = startAngle + dir * angle;
            var depth = node.depth - rootDepth - (renderRollupNode ? -1 : 1);
            var rStart = r0 + rPerLevel * depth;
            var rEnd = r0 + rPerLevel * (depth + 1);
            var levelModel = seriesModel.getLevelModel(node);

            if (levelModel) {
              var r0_1 = levelModel.get('r0', true);
              var r_1 = levelModel.get('r', true);
              var radius_1 = levelModel.get('radius', true);

              if (radius_1 != null) {
                r0_1 = radius_1[0];
                r_1 = radius_1[1];
              }

              r0_1 != null && (rStart = parsePercent$1(r0_1, size / 2));
              r_1 != null && (rEnd = parsePercent$1(r_1, size / 2));
            }

            node.setLayout({
              angle: angle,
              startAngle: startAngle,
              endAngle: endAngle,
              clockwise: clockwise,
              cx: cx,
              cy: cy,
              r0: rStart,
              r: rEnd
            });
          } // Render children


          if (node.children && node.children.length) {
            // currentAngle = startAngle;
            var siblingAngle_1 = 0;
            each(node.children, function (node) {
              siblingAngle_1 += renderNode(node, startAngle + siblingAngle_1);
            });
          }

          return endAngle - startAngle;
        }; // Virtual root node for roll up


        if (renderRollupNode) {
          var rStart = r0;
          var rEnd = r0 + rPerLevel;
          var angle = Math.PI * 2;
          virtualRoot.setLayout({
            angle: angle,
            startAngle: startAngle,
            endAngle: startAngle + angle,
            clockwise: clockwise,
            cx: cx,
            cy: cy,
            r0: rStart,
            r: rEnd
          });
        }

        renderNode(treeRoot, startAngle);
      });
    }
    /**
     * Init node children by order and update visual
     */

    function initChildren$1(node, sortOrder) {
      var children = node.children || [];
      node.children = sort$2(children, sortOrder); // Init children recursively

      if (children.length) {
        each(node.children, function (child) {
          initChildren$1(child, sortOrder);
        });
      }
    }
    /**
     * Sort children nodes
     *
     * @param {TreeNode[]}               children children of node to be sorted
     * @param {string | function | null} sort sort method
     *                                   See SunburstSeries.js for details.
     */


    function sort$2(children, sortOrder) {
      if (isFunction(sortOrder)) {
        var sortTargets = map(children, function (child, idx) {
          var value = child.getValue();
          return {
            params: {
              depth: child.depth,
              height: child.height,
              dataIndex: child.dataIndex,
              getValue: function () {
                return value;
              }
            },
            index: idx
          };
        });
        sortTargets.sort(function (a, b) {
          return sortOrder(a.params, b.params);
        });
        return map(sortTargets, function (target) {
          return children[target.index];
        });
      } else {
        var isAsc_1 = sortOrder === 'asc';
        return children.sort(function (a, b) {
          var diff = (a.getValue() - b.getValue()) * (isAsc_1 ? 1 : -1);
          return diff === 0 ? (a.dataIndex - b.dataIndex) * (isAsc_1 ? -1 : 1) : diff;
        });
      }
    }

    function sunburstVisual(ecModel) {
      var paletteScope = {}; // Default color strategy

      function pickColor(node, seriesModel, treeHeight) {
        // Choose color from palette based on the first level.
        var current = node;

        while (current && current.depth > 1) {
          current = current.parentNode;
        }

        var color = seriesModel.getColorFromPalette(current.name || current.dataIndex + '', paletteScope);

        if (node.depth > 1 && isString(color)) {
          // Lighter on the deeper level.
          color = lift(color, (node.depth - 1) / (treeHeight - 1) * 0.5);
        }

        return color;
      }

      ecModel.eachSeriesByType('sunburst', function (seriesModel) {
        var data = seriesModel.getData();
        var tree = data.tree;
        tree.eachNode(function (node) {
          var model = node.getModel();
          var style = model.getModel('itemStyle').getItemStyle();

          if (!style.fill) {
            style.fill = pickColor(node, seriesModel, tree.root.height);
          }

          var existsStyle = data.ensureUniqueItemVisual(node.dataIndex, 'style');
          extend(existsStyle, style);
        });
      });
    }

    function install$q(registers) {
      registers.registerChartView(SunburstView);
      registers.registerSeriesModel(SunburstSeriesModel);
      registers.registerLayout(curry(sunburstLayout, 'sunburst'));
      registers.registerProcessor(curry(dataFilter, 'sunburst'));
      registers.registerVisual(sunburstVisual);
      installSunburstAction(registers);
    }

    // `visual('color') visual('borderColor')` is supported.

    var STYLE_VISUAL_TYPE = {
      color: 'fill',
      borderColor: 'stroke'
    };
    var NON_STYLE_VISUAL_PROPS = {
      symbol: 1,
      symbolSize: 1,
      symbolKeepAspect: 1,
      legendIcon: 1,
      visualMeta: 1,
      liftZ: 1,
      decal: 1
    };
    var customInnerStore = makeInner();

    var CustomSeriesModel =
    /** @class */
    function (_super) {
      __extends(CustomSeriesModel, _super);

      function CustomSeriesModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = CustomSeriesModel.type;
        return _this;
      }

      CustomSeriesModel.prototype.optionUpdated = function () {
        this.currentZLevel = this.get('zlevel', true);
        this.currentZ = this.get('z', true);
      };

      CustomSeriesModel.prototype.getInitialData = function (option, ecModel) {
        return createSeriesData(null, this);
      };

      CustomSeriesModel.prototype.getDataParams = function (dataIndex, dataType, el) {
        var params = _super.prototype.getDataParams.call(this, dataIndex, dataType);

        el && (params.info = customInnerStore(el).info);
        return params;
      };

      CustomSeriesModel.type = 'series.custom';
      CustomSeriesModel.dependencies = ['grid', 'polar', 'geo', 'singleAxis', 'calendar'];
      CustomSeriesModel.defaultOption = {
        coordinateSystem: 'cartesian2d',
        // zlevel: 0,
        z: 2,
        legendHoverLink: true,
        // Custom series will not clip by default.
        // Some case will use custom series to draw label
        // For example https://echarts.apache.org/examples/en/editor.html?c=custom-gantt-flight
        clip: false // Cartesian coordinate system
        // xAxisIndex: 0,
        // yAxisIndex: 0,
        // Polar coordinate system
        // polarIndex: 0,
        // Geo coordinate system
        // geoIndex: 0,

      };
      return CustomSeriesModel;
    }(SeriesModel);

    function dataToCoordSize(dataSize, dataItem) {
      // dataItem is necessary in log axis.
      dataItem = dataItem || [0, 0];
      return map(['x', 'y'], function (dim, dimIdx) {
        var axis = this.getAxis(dim);
        var val = dataItem[dimIdx];
        var halfSize = dataSize[dimIdx] / 2;
        return axis.type === 'category' ? axis.getBandWidth() : Math.abs(axis.dataToCoord(val - halfSize) - axis.dataToCoord(val + halfSize));
      }, this);
    }

    function cartesianPrepareCustom(coordSys) {
      var rect = coordSys.master.getRect();
      return {
        coordSys: {
          // The name exposed to user is always 'cartesian2d' but not 'grid'.
          type: 'cartesian2d',
          x: rect.x,
          y: rect.y,
          width: rect.width,
          height: rect.height
        },
        api: {
          coord: function (data) {
            // do not provide "out" param
            return coordSys.dataToPoint(data);
          },
          size: bind(dataToCoordSize, coordSys)
        }
      };
    }

    function dataToCoordSize$1(dataSize, dataItem) {
      dataItem = dataItem || [0, 0];
      return map([0, 1], function (dimIdx) {
        var val = dataItem[dimIdx];
        var halfSize = dataSize[dimIdx] / 2;
        var p1 = [];
        var p2 = [];
        p1[dimIdx] = val - halfSize;
        p2[dimIdx] = val + halfSize;
        p1[1 - dimIdx] = p2[1 - dimIdx] = dataItem[1 - dimIdx];
        return Math.abs(this.dataToPoint(p1)[dimIdx] - this.dataToPoint(p2)[dimIdx]);
      }, this);
    }

    function geoPrepareCustom(coordSys) {
      var rect = coordSys.getBoundingRect();
      return {
        coordSys: {
          type: 'geo',
          x: rect.x,
          y: rect.y,
          width: rect.width,
          height: rect.height,
          zoom: coordSys.getZoom()
        },
        api: {
          coord: function (data) {
            // do not provide "out" and noRoam param,
            // Compatible with this usage:
            // echarts.util.map(item.points, api.coord)
            return coordSys.dataToPoint(data);
          },
          size: bind(dataToCoordSize$1, coordSys)
        }
      };
    }

    function dataToCoordSize$2(dataSize, dataItem) {
      // dataItem is necessary in log axis.
      var axis = this.getAxis();
      var val = dataItem instanceof Array ? dataItem[0] : dataItem;
      var halfSize = (dataSize instanceof Array ? dataSize[0] : dataSize) / 2;
      return axis.type === 'category' ? axis.getBandWidth() : Math.abs(axis.dataToCoord(val - halfSize) - axis.dataToCoord(val + halfSize));
    }

    function singlePrepareCustom(coordSys) {
      var rect = coordSys.getRect();
      return {
        coordSys: {
          type: 'singleAxis',
          x: rect.x,
          y: rect.y,
          width: rect.width,
          height: rect.height
        },
        api: {
          coord: function (val) {
            // do not provide "out" param
            return coordSys.dataToPoint(val);
          },
          size: bind(dataToCoordSize$2, coordSys)
        }
      };
    }

    function dataToCoordSize$3(dataSize, dataItem) {
      // dataItem is necessary in log axis.
      dataItem = dataItem || [0, 0];
      return map(['Radius', 'Angle'], function (dim, dimIdx) {
        var getterName = 'get' + dim + 'Axis'; // TODO: TYPE Check Angle Axis

        var axis = this[getterName]();
        var val = dataItem[dimIdx];
        var halfSize = dataSize[dimIdx] / 2;
        var result = axis.type === 'category' ? axis.getBandWidth() : Math.abs(axis.dataToCoord(val - halfSize) - axis.dataToCoord(val + halfSize));

        if (dim === 'Angle') {
          result = result * Math.PI / 180;
        }

        return result;
      }, this);
    }

    function polarPrepareCustom(coordSys) {
      var radiusAxis = coordSys.getRadiusAxis();
      var angleAxis = coordSys.getAngleAxis();
      var radius = radiusAxis.getExtent();
      radius[0] > radius[1] && radius.reverse();
      return {
        coordSys: {
          type: 'polar',
          cx: coordSys.cx,
          cy: coordSys.cy,
          r: radius[1],
          r0: radius[0]
        },
        api: {
          coord: function (data) {
            var radius = radiusAxis.dataToRadius(data[0]);
            var angle = angleAxis.dataToAngle(data[1]);
            var coord = coordSys.coordToPoint([radius, angle]);
            coord.push(radius, angle * Math.PI / 180);
            return coord;
          },
          size: bind(dataToCoordSize$3, coordSys)
        }
      };
    }

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


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * 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 calendarPrepareCustom(coordSys) {
      var rect = coordSys.getRect();
      var rangeInfo = coordSys.getRangeInfo();
      return {
        coordSys: {
          type: 'calendar',
          x: rect.x,
          y: rect.y,
          width: rect.width,
          height: rect.height,
          cellWidth: coordSys.getCellWidth(),
          cellHeight: coordSys.getCellHeight(),
          rangeInfo: {
            start: rangeInfo.start,
            end: rangeInfo.end,
            weeks: rangeInfo.weeks,
            dayCount: rangeInfo.allDay
          }
        },
        api: {
          coord: function (data, clamp) {
            return coordSys.dataToPoint(data, clamp);
          }
        }
      };
    }

    var deprecatedLogs = {};
    /**
     * Whether need to call `convertEC4CompatibleStyle`.
     */

    function isEC4CompatibleStyle(style, elType, hasOwnTextContentOption, hasOwnTextConfig) {
      // Since echarts5, `RectText` is separated from its host element and style.text
      // does not exist any more. The compat work brings some extra burden on performance.
      // So we provide:
      // `legacy: true` force make compat.
      // `legacy: false`, force do not compat.
      // `legacy` not set: auto detect whether legacy.
      //     But in this case we do not compat (difficult to detect and rare case):
      //     Becuse custom series and graphic component support "merge", users may firstly
      //     only set `textStrokeWidth` style or secondly only set `text`.
      return style && (style.legacy || style.legacy !== false && !hasOwnTextContentOption && !hasOwnTextConfig && elType !== 'tspan' // Difficult to detect whether legacy for a "text" el.
      && (elType === 'text' || hasOwn(style, 'text')));
    }
    /**
     * `EC4CompatibleStyle` is style that might be in echarts4 format or echarts5 format.
     * @param hostStyle The properties might be modified.
     * @return If be text el, `textContentStyle` and `textConfig` will not be returned.
     *         Otherwise a `textContentStyle` and `textConfig` will be created, whose props area
     *         retried from the `hostStyle`.
     */

    function convertFromEC4CompatibleStyle(hostStyle, elType, isNormal) {
      var srcStyle = hostStyle;
      var textConfig;
      var textContent;
      var textContentStyle;

      if (elType === 'text') {
        textContentStyle = srcStyle;
      } else {
        textContentStyle = {};
        hasOwn(srcStyle, 'text') && (textContentStyle.text = srcStyle.text);
        hasOwn(srcStyle, 'rich') && (textContentStyle.rich = srcStyle.rich);
        hasOwn(srcStyle, 'textFill') && (textContentStyle.fill = srcStyle.textFill);
        hasOwn(srcStyle, 'textStroke') && (textContentStyle.stroke = srcStyle.textStroke);
        hasOwn(srcStyle, 'fontFamily') && (textContentStyle.fontFamily = srcStyle.fontFamily);
        hasOwn(srcStyle, 'fontSize') && (textContentStyle.fontSize = srcStyle.fontSize);
        hasOwn(srcStyle, 'fontStyle') && (textContentStyle.fontStyle = srcStyle.fontStyle);
        hasOwn(srcStyle, 'fontWeight') && (textContentStyle.fontWeight = srcStyle.fontWeight);
        textContent = {
          type: 'text',
          style: textContentStyle,
          // ec4 does not support rectText trigger.
          // And when text position is different in normal and emphasis
          // => hover text trigger emphasis;
          // => text position changed, leave mouse pointer immediately;
          // That might cause incorrect state.
          silent: true
        };
        textConfig = {};
        var hasOwnPos = hasOwn(srcStyle, 'textPosition');

        if (isNormal) {
          textConfig.position = hasOwnPos ? srcStyle.textPosition : 'inside';
        } else {
          hasOwnPos && (textConfig.position = srcStyle.textPosition);
        }

        hasOwn(srcStyle, 'textPosition') && (textConfig.position = srcStyle.textPosition);
        hasOwn(srcStyle, 'textOffset') && (textConfig.offset = srcStyle.textOffset);
        hasOwn(srcStyle, 'textRotation') && (textConfig.rotation = srcStyle.textRotation);
        hasOwn(srcStyle, 'textDistance') && (textConfig.distance = srcStyle.textDistance);
      }

      convertEC4CompatibleRichItem(textContentStyle, hostStyle);
      each(textContentStyle.rich, function (richItem) {
        convertEC4CompatibleRichItem(richItem, richItem);
      });
      return {
        textConfig: textConfig,
        textContent: textContent
      };
    }
    /**
     * The result will be set to `out`.
     */

    function convertEC4CompatibleRichItem(out, richItem) {
      if (!richItem) {
        return;
      } // (1) For simplicity, make textXXX properties (deprecated since ec5) has
      // higher priority. For example, consider in ec4 `borderColor: 5, textBorderColor: 10`
      // on a rect means `borderColor: 4` on the rect and `borderColor: 10` on an attached
      // richText in ec5.
      // (2) `out === richItem` if and only if `out` is text el or rich item.
      // So we can overwrite existing props in `out` since textXXX has higher priority.


      richItem.font = richItem.textFont || richItem.font;
      hasOwn(richItem, 'textStrokeWidth') && (out.lineWidth = richItem.textStrokeWidth);
      hasOwn(richItem, 'textAlign') && (out.align = richItem.textAlign);
      hasOwn(richItem, 'textVerticalAlign') && (out.verticalAlign = richItem.textVerticalAlign);
      hasOwn(richItem, 'textLineHeight') && (out.lineHeight = richItem.textLineHeight);
      hasOwn(richItem, 'textWidth') && (out.width = richItem.textWidth);
      hasOwn(richItem, 'textHeight') && (out.height = richItem.textHeight);
      hasOwn(richItem, 'textBackgroundColor') && (out.backgroundColor = richItem.textBackgroundColor);
      hasOwn(richItem, 'textPadding') && (out.padding = richItem.textPadding);
      hasOwn(richItem, 'textBorderColor') && (out.borderColor = richItem.textBorderColor);
      hasOwn(richItem, 'textBorderWidth') && (out.borderWidth = richItem.textBorderWidth);
      hasOwn(richItem, 'textBorderRadius') && (out.borderRadius = richItem.textBorderRadius);
      hasOwn(richItem, 'textBoxShadowColor') && (out.shadowColor = richItem.textBoxShadowColor);
      hasOwn(richItem, 'textBoxShadowBlur') && (out.shadowBlur = richItem.textBoxShadowBlur);
      hasOwn(richItem, 'textBoxShadowOffsetX') && (out.shadowOffsetX = richItem.textBoxShadowOffsetX);
      hasOwn(richItem, 'textBoxShadowOffsetY') && (out.shadowOffsetY = richItem.textBoxShadowOffsetY);
    }
    /**
     * Convert to pure echarts4 format style.
     * `itemStyle` will be modified, added with ec4 style properties from
     * `textStyle` and `textConfig`.
     *
     * [Caveat]: For simplicity, `insideRollback` in ec4 does not compat, where
     * `styleEmphasis: {textFill: 'red'}` will remove the normal auto added stroke.
     */


    function convertToEC4StyleForCustomSerise(itemStl, txStl, txCfg) {
      var out = itemStl; // See `custom.ts`, a trick to set extra `textPosition` firstly.

      out.textPosition = out.textPosition || txCfg.position || 'inside';
      txCfg.offset != null && (out.textOffset = txCfg.offset);
      txCfg.rotation != null && (out.textRotation = txCfg.rotation);
      txCfg.distance != null && (out.textDistance = txCfg.distance);
      var isInside = out.textPosition.indexOf('inside') >= 0;
      var hostFill = itemStl.fill || '#000';
      convertToEC4RichItem(out, txStl);
      var textFillNotSet = out.textFill == null;

      if (isInside) {
        if (textFillNotSet) {
          out.textFill = txCfg.insideFill || '#fff';
          !out.textStroke && txCfg.insideStroke && (out.textStroke = txCfg.insideStroke);
          !out.textStroke && (out.textStroke = hostFill);
          out.textStrokeWidth == null && (out.textStrokeWidth = 2);
        }
      } else {
        if (textFillNotSet) {
          out.textFill = itemStl.fill || txCfg.outsideFill || '#000';
        }

        !out.textStroke && txCfg.outsideStroke && (out.textStroke = txCfg.outsideStroke);
      }

      out.text = txStl.text;
      out.rich = txStl.rich;
      each(txStl.rich, function (richItem) {
        convertToEC4RichItem(richItem, richItem);
      });
      return out;
    }

    function convertToEC4RichItem(out, richItem) {
      if (!richItem) {
        return;
      }

      hasOwn(richItem, 'fill') && (out.textFill = richItem.fill);
      hasOwn(richItem, 'stroke') && (out.textStroke = richItem.fill);
      hasOwn(richItem, 'lineWidth') && (out.textStrokeWidth = richItem.lineWidth);
      hasOwn(richItem, 'font') && (out.font = richItem.font);
      hasOwn(richItem, 'fontStyle') && (out.fontStyle = richItem.fontStyle);
      hasOwn(richItem, 'fontWeight') && (out.fontWeight = richItem.fontWeight);
      hasOwn(richItem, 'fontSize') && (out.fontSize = richItem.fontSize);
      hasOwn(richItem, 'fontFamily') && (out.fontFamily = richItem.fontFamily);
      hasOwn(richItem, 'align') && (out.textAlign = richItem.align);
      hasOwn(richItem, 'verticalAlign') && (out.textVerticalAlign = richItem.verticalAlign);
      hasOwn(richItem, 'lineHeight') && (out.textLineHeight = richItem.lineHeight);
      hasOwn(richItem, 'width') && (out.textWidth = richItem.width);
      hasOwn(richItem, 'height') && (out.textHeight = richItem.height);
      hasOwn(richItem, 'backgroundColor') && (out.textBackgroundColor = richItem.backgroundColor);
      hasOwn(richItem, 'padding') && (out.textPadding = richItem.padding);
      hasOwn(richItem, 'borderColor') && (out.textBorderColor = richItem.borderColor);
      hasOwn(richItem, 'borderWidth') && (out.textBorderWidth = richItem.borderWidth);
      hasOwn(richItem, 'borderRadius') && (out.textBorderRadius = richItem.borderRadius);
      hasOwn(richItem, 'shadowColor') && (out.textBoxShadowColor = richItem.shadowColor);
      hasOwn(richItem, 'shadowBlur') && (out.textBoxShadowBlur = richItem.shadowBlur);
      hasOwn(richItem, 'shadowOffsetX') && (out.textBoxShadowOffsetX = richItem.shadowOffsetX);
      hasOwn(richItem, 'shadowOffsetY') && (out.textBoxShadowOffsetY = richItem.shadowOffsetY);
      hasOwn(richItem, 'textShadowColor') && (out.textShadowColor = richItem.textShadowColor);
      hasOwn(richItem, 'textShadowBlur') && (out.textShadowBlur = richItem.textShadowBlur);
      hasOwn(richItem, 'textShadowOffsetX') && (out.textShadowOffsetX = richItem.textShadowOffsetX);
      hasOwn(richItem, 'textShadowOffsetY') && (out.textShadowOffsetY = richItem.textShadowOffsetY);
    }

    function warnDeprecated(deprecated, insteadApproach) {
      if ("development" !== 'production') {
        var key = deprecated + '^_^' + insteadApproach;

        if (!deprecatedLogs[key]) {
          console.warn("[ECharts] DEPRECATED: \"" + deprecated + "\" has been deprecated. " + insteadApproach);
          deprecatedLogs[key] = true;
        }
      }
    }

    var LEGACY_TRANSFORM_PROPS_MAP = {
      position: ['x', 'y'],
      scale: ['scaleX', 'scaleY'],
      origin: ['originX', 'originY']
    };
    var LEGACY_TRANSFORM_PROPS = keys(LEGACY_TRANSFORM_PROPS_MAP);
    var TRANSFORM_PROPS_MAP = reduce(TRANSFORMABLE_PROPS, function (obj, key) {
      obj[key] = 1;
      return obj;
    }, {});
    var transformPropNamesStr = TRANSFORMABLE_PROPS.join(', '); // '' means root

    var ELEMENT_ANIMATABLE_PROPS = ['', 'style', 'shape', 'extra'];
    var transitionInnerStore = makeInner();

    function getElementAnimationConfig(animationType, el, elOption, parentModel, dataIndex) {
      var animationProp = animationType + "Animation";
      var config = getAnimationConfig(animationType, parentModel, dataIndex) || {};
      var userDuring = transitionInnerStore(el).userDuring; // Only set when duration is > 0 and it's need to be animated.

      if (config.duration > 0) {
        // For simplicity, if during not specified, the previous during will not work any more.
        config.during = userDuring ? bind(duringCall, {
          el: el,
          userDuring: userDuring
        }) : null;
        config.setToFinal = true;
        config.scope = animationType;
      }

      extend(config, elOption[animationProp]);
      return config;
    }

    function applyUpdateTransition(el, elOption, animatableModel, opts) {
      opts = opts || {};
      var dataIndex = opts.dataIndex,
          isInit = opts.isInit,
          clearStyle = opts.clearStyle;
      var hasAnimation = animatableModel.isAnimationEnabled(); // Save the meta info for further morphing. Like apply on the sub morphing elements.

      var store = transitionInnerStore(el);
      var styleOpt = elOption.style;
      store.userDuring = elOption.during;
      var transFromProps = {};
      var propsToSet = {};
      prepareTransformAllPropsFinal(el, elOption, propsToSet);
      prepareShapeOrExtraAllPropsFinal('shape', elOption, propsToSet);
      prepareShapeOrExtraAllPropsFinal('extra', elOption, propsToSet);

      if (!isInit && hasAnimation) {
        prepareTransformTransitionFrom(el, elOption, transFromProps);
        prepareShapeOrExtraTransitionFrom('shape', el, elOption, transFromProps);
        prepareShapeOrExtraTransitionFrom('extra', el, elOption, transFromProps);
        prepareStyleTransitionFrom(el, elOption, styleOpt, transFromProps);
      }

      propsToSet.style = styleOpt;
      applyPropsDirectly(el, propsToSet, clearStyle);
      applyMiscProps(el, elOption);

      if (hasAnimation) {
        if (isInit) {
          var enterFromProps_1 = {};
          each(ELEMENT_ANIMATABLE_PROPS, function (propName) {
            var prop = propName ? elOption[propName] : elOption;

            if (prop && prop.enterFrom) {
              if (propName) {
                enterFromProps_1[propName] = enterFromProps_1[propName] || {};
              }

              extend(propName ? enterFromProps_1[propName] : enterFromProps_1, prop.enterFrom);
            }
          });
          var config = getElementAnimationConfig('enter', el, elOption, animatableModel, dataIndex);

          if (config.duration > 0) {
            el.animateFrom(enterFromProps_1, config);
          }
        } else {
          applyPropsTransition(el, elOption, dataIndex || 0, animatableModel, transFromProps);
        }
      } // Store leave to be used in leave transition.


      updateLeaveTo(el, elOption);
      styleOpt ? el.dirty() : el.markRedraw();
    }
    function updateLeaveTo(el, elOption) {
      // Try merge to previous set leaveTo
      var leaveToProps = transitionInnerStore(el).leaveToProps;

      for (var i = 0; i < ELEMENT_ANIMATABLE_PROPS.length; i++) {
        var propName = ELEMENT_ANIMATABLE_PROPS[i];
        var prop = propName ? elOption[propName] : elOption;

        if (prop && prop.leaveTo) {
          if (!leaveToProps) {
            leaveToProps = transitionInnerStore(el).leaveToProps = {};
          }

          if (propName) {
            leaveToProps[propName] = leaveToProps[propName] || {};
          }

          extend(propName ? leaveToProps[propName] : leaveToProps, prop.leaveTo);
        }
      }
    }
    function applyLeaveTransition(el, elOption, animatableModel, onRemove) {
      if (el) {
        var parent_1 = el.parent;
        var leaveToProps = transitionInnerStore(el).leaveToProps;

        if (leaveToProps) {
          // TODO TODO use leave after leaveAnimation in series is introduced
          // TODO Data index?
          var config = getElementAnimationConfig('update', el, elOption, animatableModel, 0);

          config.done = function () {
            parent_1.remove(el);
            onRemove && onRemove();
          };

          el.animateTo(leaveToProps, config);
        } else {
          parent_1.remove(el);
          onRemove && onRemove();
        }
      }
    }
    function isTransitionAll(transition) {
      return transition === 'all';
    }

    function applyPropsDirectly(el, // Can be null/undefined
    allPropsFinal, clearStyle) {
      var styleOpt = allPropsFinal.style;

      if (!el.isGroup && styleOpt) {
        if (clearStyle) {
          el.useStyle({}); // When style object changed, how to trade the existing animation?
          // It is probably complicated and not needed to cover all the cases.
          // But still need consider the case:
          // (1) When using init animation on `style.opacity`, and before the animation
          //     ended users triggers an update by mousewhel. At that time the init
          //     animation should better be continued rather than terminated.
          //     So after `useStyle` called, we should change the animation target manually
          //     to continue the effect of the init animation.
          // (2) PENDING: If the previous animation targeted at a `val1`, and currently we need
          //     to update the value to `val2` and no animation declared, should be terminate
          //     the previous animation or just modify the target of the animation?
          //     Therotically That will happen not only on `style` but also on `shape` and
          //     `transfrom` props. But we haven't handle this case at present yet.
          // (3) PENDING: Is it proper to visit `animators` and `targetName`?

          var animators = el.animators;

          for (var i = 0; i < animators.length; i++) {
            var animator = animators[i]; // targetName is the "topKey".

            if (animator.targetName === 'style') {
              animator.changeTarget(el.style);
            }
          }
        }

        el.setStyle(styleOpt);
      }

      if (allPropsFinal) {
        // Not set style here.
        allPropsFinal.style = null; // Set el to the final state firstly.

        allPropsFinal && el.attr(allPropsFinal);
        allPropsFinal.style = styleOpt;
      }
    }

    function applyPropsTransition(el, elOption, dataIndex, model, // Can be null/undefined
    transFromProps) {
      if (transFromProps) {
        var config = getElementAnimationConfig('update', el, elOption, model, dataIndex);

        if (config.duration > 0) {
          el.animateFrom(transFromProps, config);
        }
      }
    }

    function applyMiscProps(el, elOption) {
      // Merge by default.
      hasOwn(elOption, 'silent') && (el.silent = elOption.silent);
      hasOwn(elOption, 'ignore') && (el.ignore = elOption.ignore);

      if (el instanceof Displayable) {
        hasOwn(elOption, 'invisible') && (el.invisible = elOption.invisible);
      }

      if (el instanceof Path) {
        hasOwn(elOption, 'autoBatch') && (el.autoBatch = elOption.autoBatch);
      }
    } // Use it to avoid it be exposed to user.


    var tmpDuringScope = {};
    var transitionDuringAPI = {
      // Usually other props do not need to be changed in animation during.
      setTransform: function (key, val) {
        if ("development" !== 'production') {
          assert(hasOwn(TRANSFORM_PROPS_MAP, key), 'Only ' + transformPropNamesStr + ' available in `setTransform`.');
        }

        tmpDuringScope.el[key] = val;
        return this;
      },
      getTransform: function (key) {
        if ("development" !== 'production') {
          assert(hasOwn(TRANSFORM_PROPS_MAP, key), 'Only ' + transformPropNamesStr + ' available in `getTransform`.');
        }

        return tmpDuringScope.el[key];
      },
      setShape: function (key, val) {
        if ("development" !== 'production') {
          assertNotReserved(key);
        }

        var el = tmpDuringScope.el;
        var shape = el.shape || (el.shape = {});
        shape[key] = val;
        el.dirtyShape && el.dirtyShape();
        return this;
      },
      getShape: function (key) {
        if ("development" !== 'production') {
          assertNotReserved(key);
        }

        var shape = tmpDuringScope.el.shape;

        if (shape) {
          return shape[key];
        }
      },
      setStyle: function (key, val) {
        if ("development" !== 'production') {
          assertNotReserved(key);
        }

        var el = tmpDuringScope.el;
        var style = el.style;

        if (style) {
          if ("development" !== 'production') {
            if (eqNaN(val)) {
              warn('style.' + key + ' must not be assigned with NaN.');
            }
          }

          style[key] = val;
          el.dirtyStyle && el.dirtyStyle();
        }

        return this;
      },
      getStyle: function (key) {
        if ("development" !== 'production') {
          assertNotReserved(key);
        }

        var style = tmpDuringScope.el.style;

        if (style) {
          return style[key];
        }
      },
      setExtra: function (key, val) {
        if ("development" !== 'production') {
          assertNotReserved(key);
        }

        var extra = tmpDuringScope.el.extra || (tmpDuringScope.el.extra = {});
        extra[key] = val;
        return this;
      },
      getExtra: function (key) {
        if ("development" !== 'production') {
          assertNotReserved(key);
        }

        var extra = tmpDuringScope.el.extra;

        if (extra) {
          return extra[key];
        }
      }
    };

    function assertNotReserved(key) {
      if ("development" !== 'production') {
        if (key === 'transition' || key === 'enterFrom' || key === 'leaveTo') {
          throw new Error('key must not be "' + key + '"');
        }
      }
    }

    function duringCall() {
      // Do not provide "percent" until some requirements come.
      // Because consider thies case:
      // enterFrom: {x: 100, y: 30}, transition: 'x'.
      // And enter duration is different from update duration.
      // Thus it might be confused about the meaning of "percent" in during callback.
      var scope = this;
      var el = scope.el;

      if (!el) {
        return;
      } // If el is remove from zr by reason like legend, during still need to called,
      // because el will be added back to zr and the prop value should not be incorrect.


      var latestUserDuring = transitionInnerStore(el).userDuring;
      var scopeUserDuring = scope.userDuring; // Ensured a during is only called once in each animation frame.
      // If a during is called multiple times in one frame, maybe some users' calculation logic
      // might be wrong (not sure whether this usage exists).
      // The case of a during might be called twice can be: by default there is a animator for
      // 'x', 'y' when init. Before the init animation finished, call `setOption` to start
      // another animators for 'style'/'shape'/'extra'.

      if (latestUserDuring !== scopeUserDuring) {
        // release
        scope.el = scope.userDuring = null;
        return;
      }

      tmpDuringScope.el = el; // Give no `this` to user in "during" calling.

      scopeUserDuring(transitionDuringAPI); // FIXME: if in future meet the case that some prop will be both modified in `during` and `state`,
      // consider the issue that the prop might be incorrect when return to "normal" state.
    }

    function prepareShapeOrExtraTransitionFrom(mainAttr, fromEl, elOption, transFromProps) {
      var attrOpt = elOption[mainAttr];

      if (!attrOpt) {
        return;
      }

      var elPropsInAttr = fromEl[mainAttr];
      var transFromPropsInAttr;

      if (elPropsInAttr) {
        var transition = elOption.transition;
        var attrTransition = attrOpt.transition;

        if (attrTransition) {
          !transFromPropsInAttr && (transFromPropsInAttr = transFromProps[mainAttr] = {});

          if (isTransitionAll(attrTransition)) {
            extend(transFromPropsInAttr, elPropsInAttr);
          } else {
            var transitionKeys = normalizeToArray(attrTransition);

            for (var i = 0; i < transitionKeys.length; i++) {
              var key = transitionKeys[i];
              var elVal = elPropsInAttr[key];
              transFromPropsInAttr[key] = elVal;
            }
          }
        } else if (isTransitionAll(transition) || indexOf(transition, mainAttr) >= 0) {
          !transFromPropsInAttr && (transFromPropsInAttr = transFromProps[mainAttr] = {});
          var elPropsInAttrKeys = keys(elPropsInAttr);

          for (var i = 0; i < elPropsInAttrKeys.length; i++) {
            var key = elPropsInAttrKeys[i];
            var elVal = elPropsInAttr[key];

            if (isNonStyleTransitionEnabled(attrOpt[key], elVal)) {
              transFromPropsInAttr[key] = elVal;
            }
          }
        }
      }
    }

    function prepareShapeOrExtraAllPropsFinal(mainAttr, elOption, allProps) {
      var attrOpt = elOption[mainAttr];

      if (!attrOpt) {
        return;
      }

      var allPropsInAttr = allProps[mainAttr] = {};
      var keysInAttr = keys(attrOpt);

      for (var i = 0; i < keysInAttr.length; i++) {
        var key = keysInAttr[i]; // To avoid share one object with different element, and
        // to avoid user modify the object inexpectedly, have to clone.

        allPropsInAttr[key] = cloneValue(attrOpt[key]);
      }
    }

    function prepareTransformTransitionFrom(el, elOption, transFromProps) {
      var transition = elOption.transition;
      var transitionKeys = isTransitionAll(transition) ? TRANSFORMABLE_PROPS : normalizeToArray(transition || []);

      for (var i = 0; i < transitionKeys.length; i++) {
        var key = transitionKeys[i];

        if (key === 'style' || key === 'shape' || key === 'extra') {
          continue;
        }

        var elVal = el[key];

        if ("development" !== 'production') {
          checkTransformPropRefer(key, 'el.transition');
        } // Do not clone, animator will perform that clone.


        transFromProps[key] = elVal;
      }
    }

    function prepareTransformAllPropsFinal(el, elOption, allProps) {
      for (var i = 0; i < LEGACY_TRANSFORM_PROPS.length; i++) {
        var legacyName = LEGACY_TRANSFORM_PROPS[i];
        var xyName = LEGACY_TRANSFORM_PROPS_MAP[legacyName];
        var legacyArr = elOption[legacyName];

        if (legacyArr) {
          allProps[xyName[0]] = legacyArr[0];
          allProps[xyName[1]] = legacyArr[1];
        }
      }

      for (var i = 0; i < TRANSFORMABLE_PROPS.length; i++) {
        var key = TRANSFORMABLE_PROPS[i];

        if (elOption[key] != null) {
          allProps[key] = elOption[key];
        }
      }
    }

    function prepareStyleTransitionFrom(fromEl, elOption, styleOpt, transFromProps) {
      if (!styleOpt) {
        return;
      }

      var fromElStyle = fromEl.style;
      var transFromStyleProps;

      if (fromElStyle) {
        var styleTransition = styleOpt.transition;
        var elTransition = elOption.transition;

        if (styleTransition && !isTransitionAll(styleTransition)) {
          var transitionKeys = normalizeToArray(styleTransition);
          !transFromStyleProps && (transFromStyleProps = transFromProps.style = {});

          for (var i = 0; i < transitionKeys.length; i++) {
            var key = transitionKeys[i];
            var elVal = fromElStyle[key]; // Do not clone, see `checkNonStyleTansitionRefer`.

            transFromStyleProps[key] = elVal;
          }
        } else if (fromEl.getAnimationStyleProps && (isTransitionAll(elTransition) || isTransitionAll(styleTransition) || indexOf(elTransition, 'style') >= 0)) {
          var animationProps = fromEl.getAnimationStyleProps();
          var animationStyleProps = animationProps ? animationProps.style : null;

          if (animationStyleProps) {
            !transFromStyleProps && (transFromStyleProps = transFromProps.style = {});
            var styleKeys = keys(styleOpt);

            for (var i = 0; i < styleKeys.length; i++) {
              var key = styleKeys[i];

              if (animationStyleProps[key]) {
                var elVal = fromElStyle[key];
                transFromStyleProps[key] = elVal;
              }
            }
          }
        }
      }
    }

    function isNonStyleTransitionEnabled(optVal, elVal) {
      // The same as `checkNonStyleTansitionRefer`.
      return !isArrayLike(optVal) ? optVal != null && isFinite(optVal) : optVal !== elVal;
    }

    var checkTransformPropRefer;

    if ("development" !== 'production') {
      checkTransformPropRefer = function (key, usedIn) {
        if (!hasOwn(TRANSFORM_PROPS_MAP, key)) {
          warn('Prop `' + key + '` is not a permitted in `' + usedIn + '`. ' + 'Only `' + keys(TRANSFORM_PROPS_MAP).join('`, `') + '` are permitted.');
        }
      };
    }

    var getStateToRestore = makeInner();
    var KEYFRAME_EXCLUDE_KEYS = ['percent', 'easing', 'shape', 'style', 'extra'];
    /**
     * Stop previous keyframe animation and restore the attributes.
     * Avoid new keyframe animation starts with wrong internal state when the percent: 0 is not set.
     */

    function stopPreviousKeyframeAnimationAndRestore(el) {
      // Stop previous keyframe animation.
      el.stopAnimation('keyframe'); // Restore

      el.attr(getStateToRestore(el));
    }
    function applyKeyframeAnimation(el, animationOpts, animatableModel) {
      if (!animatableModel.isAnimationEnabled() || !animationOpts) {
        return;
      }

      if (isArray(animationOpts)) {
        each(animationOpts, function (singleAnimationOpts) {
          applyKeyframeAnimation(el, singleAnimationOpts, animatableModel);
        });
        return;
      }

      var keyframes = animationOpts.keyframes;
      var duration = animationOpts.duration;

      if (animatableModel && duration == null) {
        // Default to use duration of config.
        // NOTE: animation config from payload will be ignored because they are mainly for transitions.
        var config = getAnimationConfig('enter', animatableModel, 0);
        duration = config && config.duration;
      }

      if (!keyframes || !duration) {
        return;
      }

      var stateToRestore = getStateToRestore(el);
      each(ELEMENT_ANIMATABLE_PROPS, function (targetPropName) {
        if (targetPropName && !el[targetPropName]) {
          return;
        }

        var animator;
        var endFrameIsSet = false; // Sort keyframes by percent.

        keyframes.sort(function (a, b) {
          return a.percent - b.percent;
        });
        each(keyframes, function (kf) {
          // Stop current animation.
          var animators = el.animators;
          var kfValues = targetPropName ? kf[targetPropName] : kf;

          if ("development" !== 'production') {
            if (kf.percent >= 1) {
              endFrameIsSet = true;
            }
          }

          if (!kfValues) {
            return;
          }

          var propKeys = keys(kfValues);

          if (!targetPropName) {
            // PENDING performance?
            propKeys = filter(propKeys, function (key) {
              return indexOf(KEYFRAME_EXCLUDE_KEYS, key) < 0;
            });
          }

          if (!propKeys.length) {
            return;
          }

          if (!animator) {
            animator = el.animate(targetPropName, animationOpts.loop, true);
            animator.scope = 'keyframe';
          }

          for (var i = 0; i < animators.length; i++) {
            // Stop all other animation that is not keyframe.
            if (animators[i] !== animator && animators[i].targetName === animator.targetName) {
              animators[i].stopTracks(propKeys);
            }
          }

          targetPropName && (stateToRestore[targetPropName] = stateToRestore[targetPropName] || {});
          var savedTarget = targetPropName ? stateToRestore[targetPropName] : stateToRestore;
          each(propKeys, function (key) {
            // Save original value.
            savedTarget[key] = ((targetPropName ? el[targetPropName] : el) || {})[key];
          });
          animator.whenWithKeys(duration * kf.percent, kfValues, propKeys, kf.easing);
        });

        if (!animator) {
          return;
        }

        if ("development" !== 'production') {
          if (!endFrameIsSet) {
            warn('End frame with percent: 1 is missing in the keyframeAnimation.', true);
          }
        }

        animator.delay(animationOpts.delay || 0).duration(duration).start(animationOpts.easing);
      });
    }

    var EMPHASIS = 'emphasis';
    var NORMAL = 'normal';
    var BLUR = 'blur';
    var SELECT = 'select';
    var STATES = [NORMAL, EMPHASIS, BLUR, SELECT];
    var PATH_ITEM_STYLE = {
      normal: ['itemStyle'],
      emphasis: [EMPHASIS, 'itemStyle'],
      blur: [BLUR, 'itemStyle'],
      select: [SELECT, 'itemStyle']
    };
    var PATH_LABEL = {
      normal: ['label'],
      emphasis: [EMPHASIS, 'label'],
      blur: [BLUR, 'label'],
      select: [SELECT, 'label']
    };
    var DEFAULT_TRANSITION = ['x', 'y']; // Use prefix to avoid index to be the same as el.name,
    // which will cause weird update animation.

    var GROUP_DIFF_PREFIX = 'e\0\0';
    var attachedTxInfoTmp = {
      normal: {},
      emphasis: {},
      blur: {},
      select: {}
    };
    /**
     * To reduce total package size of each coordinate systems, the modules `prepareCustom`
     * of each coordinate systems are not required by each coordinate systems directly, but
     * required by the module `custom`.
     *
     * prepareInfoForCustomSeries {Function}: optional
     *     @return {Object} {coordSys: {...}, api: {
     *         coord: function (data, clamp) {}, // return point in global.
     *         size: function (dataSize, dataItem) {} // return size of each axis in coordSys.
     *     }}
     */

    var prepareCustoms = {
      cartesian2d: cartesianPrepareCustom,
      geo: geoPrepareCustom,
      single: singlePrepareCustom,
      polar: polarPrepareCustom,
      calendar: calendarPrepareCustom
    };

    function isPath$1(el) {
      return el instanceof Path;
    }

    function isDisplayable(el) {
      return el instanceof Displayable;
    }

    function copyElement(sourceEl, targetEl) {
      targetEl.copyTransform(sourceEl);

      if (isDisplayable(targetEl) && isDisplayable(sourceEl)) {
        targetEl.setStyle(sourceEl.style);
        targetEl.z = sourceEl.z;
        targetEl.z2 = sourceEl.z2;
        targetEl.zlevel = sourceEl.zlevel;
        targetEl.invisible = sourceEl.invisible;
        targetEl.ignore = sourceEl.ignore;

        if (isPath$1(targetEl) && isPath$1(sourceEl)) {
          targetEl.setShape(sourceEl.shape);
        }
      }
    }

    var CustomChartView =
    /** @class */
    function (_super) {
      __extends(CustomChartView, _super);

      function CustomChartView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = CustomChartView.type;
        return _this;
      }

      CustomChartView.prototype.render = function (customSeries, ecModel, api, payload) {
        // Clear previously rendered progressive elements.
        this._progressiveEls = null;
        var oldData = this._data;
        var data = customSeries.getData();
        var group = this.group;
        var renderItem = makeRenderItem(customSeries, data, ecModel, api);

        if (!oldData) {
          // Previous render is incremental render or first render.
          // Needs remove the incremental rendered elements.
          group.removeAll();
        }

        data.diff(oldData).add(function (newIdx) {
          createOrUpdateItem(api, null, newIdx, renderItem(newIdx, payload), customSeries, group, data);
        }).remove(function (oldIdx) {
          var el = oldData.getItemGraphicEl(oldIdx);
          el && applyLeaveTransition(el, customInnerStore(el).option, customSeries);
        }).update(function (newIdx, oldIdx) {
          var oldEl = oldData.getItemGraphicEl(oldIdx);
          createOrUpdateItem(api, oldEl, newIdx, renderItem(newIdx, payload), customSeries, group, data);
        }).execute(); // Do clipping

        var clipPath = customSeries.get('clip', true) ? createClipPath(customSeries.coordinateSystem, false, customSeries) : null;

        if (clipPath) {
          group.setClipPath(clipPath);
        } else {
          group.removeClipPath();
        }

        this._data = data;
      };

      CustomChartView.prototype.incrementalPrepareRender = function (customSeries, ecModel, api) {
        this.group.removeAll();
        this._data = null;
      };

      CustomChartView.prototype.incrementalRender = function (params, customSeries, ecModel, api, payload) {
        var data = customSeries.getData();
        var renderItem = makeRenderItem(customSeries, data, ecModel, api);
        var progressiveEls = this._progressiveEls = [];

        function setIncrementalAndHoverLayer(el) {
          if (!el.isGroup) {
            el.incremental = true;
            el.ensureState('emphasis').hoverLayer = true;
          }
        }

        for (var idx = params.start; idx < params.end; idx++) {
          var el = createOrUpdateItem(null, null, idx, renderItem(idx, payload), customSeries, this.group, data);

          if (el) {
            el.traverse(setIncrementalAndHoverLayer);
            progressiveEls.push(el);
          }
        }
      };

      CustomChartView.prototype.eachRendered = function (cb) {
        traverseElements(this._progressiveEls || this.group, cb);
      };

      CustomChartView.prototype.filterForExposedEvent = function (eventType, query, targetEl, packedEvent) {
        var elementName = query.element;

        if (elementName == null || targetEl.name === elementName) {
          return true;
        } // Enable to give a name on a group made by `renderItem`, and listen
        // events that are triggered by its descendents.


        while ((targetEl = targetEl.__hostTarget || targetEl.parent) && targetEl !== this.group) {
          if (targetEl.name === elementName) {
            return true;
          }
        }

        return false;
      };

      CustomChartView.type = 'custom';
      return CustomChartView;
    }(ChartView);

    function createEl(elOption) {
      var graphicType = elOption.type;
      var el; // Those graphic elements are not shapes. They should not be
      // overwritten by users, so do them first.

      if (graphicType === 'path') {
        var shape = elOption.shape; // Using pathRect brings convenience to users sacle svg path.

        var pathRect = shape.width != null && shape.height != null ? {
          x: shape.x || 0,
          y: shape.y || 0,
          width: shape.width,
          height: shape.height
        } : null;
        var pathData = getPathData(shape); // Path is also used for icon, so layout 'center' by default.

        el = makePath(pathData, null, pathRect, shape.layout || 'center');
        customInnerStore(el).customPathData = pathData;
      } else if (graphicType === 'image') {
        el = new ZRImage({});
        customInnerStore(el).customImagePath = elOption.style.image;
      } else if (graphicType === 'text') {
        el = new ZRText({}); // customInnerStore(el).customText = (elOption.style as TextStyleProps).text;
      } else if (graphicType === 'group') {
        el = new Group();
      } else if (graphicType === 'compoundPath') {
        throw new Error('"compoundPath" is not supported yet.');
      } else {
        var Clz = getShapeClass(graphicType);

        if (!Clz) {
          var errMsg = '';

          if ("development" !== 'production') {
            errMsg = 'graphic type "' + graphicType + '" can not be found.';
          }

          throwError(errMsg);
        }

        el = new Clz();
      }

      customInnerStore(el).customGraphicType = graphicType;
      el.name = elOption.name; // Compat ec4: the default z2 lift is 1. If changing the number,
      // some cases probably be broken: hierarchy layout along z, like circle packing,
      // where emphasis only intending to modify color/border rather than lift z2.

      el.z2EmphasisLift = 1;
      el.z2SelectLift = 1;
      return el;
    }

    function updateElNormal( // Can be null/undefined
    api, el, dataIndex, elOption, attachedTxInfo, seriesModel, isInit) {
      // Stop and restore before update any other attributes.
      stopPreviousKeyframeAnimationAndRestore(el);
      var txCfgOpt = attachedTxInfo && attachedTxInfo.normal.cfg;

      if (txCfgOpt) {
        // PENDING: whether use user object directly rather than clone?
        // TODO:5.0 textConfig transition animation?
        el.setTextConfig(txCfgOpt);
      } // Default transition ['x', 'y']


      if (elOption && elOption.transition == null) {
        elOption.transition = DEFAULT_TRANSITION;
      } // Do some normalization on style.


      var styleOpt = elOption && elOption.style;

      if (styleOpt) {
        if (el.type === 'text') {
          var textOptionStyle = styleOpt; // Compatible with ec4: if `textFill` or `textStroke` exists use them.

          hasOwn(textOptionStyle, 'textFill') && (textOptionStyle.fill = textOptionStyle.textFill);
          hasOwn(textOptionStyle, 'textStroke') && (textOptionStyle.stroke = textOptionStyle.textStroke);
        }

        var decalPattern = void 0;
        var decalObj = isPath$1(el) ? styleOpt.decal : null;

        if (api && decalObj) {
          decalObj.dirty = true;
          decalPattern = createOrUpdatePatternFromDecal(decalObj, api);
        } // Always overwrite in case user specify this prop.


        styleOpt.__decalPattern = decalPattern;
      }

      if (isDisplayable(el)) {
        if (styleOpt) {
          var decalPattern = styleOpt.__decalPattern;

          if (decalPattern) {
            styleOpt.decal = decalPattern;
          }
        }
      }

      applyUpdateTransition(el, elOption, seriesModel, {
        dataIndex: dataIndex,
        isInit: isInit,
        clearStyle: true
      });
      applyKeyframeAnimation(el, elOption.keyframeAnimation, seriesModel);
    }

    function updateElOnState(state, el, elStateOpt, styleOpt, attachedTxInfo) {
      var elDisplayable = el.isGroup ? null : el;
      var txCfgOpt = attachedTxInfo && attachedTxInfo[state].cfg; // PENDING:5.0 support customize scale change and transition animation?

      if (elDisplayable) {
        // By default support auto lift color when hover whether `emphasis` specified.
        var stateObj = elDisplayable.ensureState(state);

        if (styleOpt === false) {
          var existingEmphasisState = elDisplayable.getState(state);

          if (existingEmphasisState) {
            existingEmphasisState.style = null;
          }
        } else {
          // style is needed to enable default emphasis.
          stateObj.style = styleOpt || null;
        } // If `elOption.styleEmphasis` or `elOption.emphasis.style` is `false`,
        // remove hover style.
        // If `elOption.textConfig` or `elOption.emphasis.textConfig` is null/undefined, it does not
        // make sense. So for simplicity, we do not ditinguish `hasOwnProperty` and null/undefined.


        if (txCfgOpt) {
          stateObj.textConfig = txCfgOpt;
        }

        setDefaultStateProxy(elDisplayable);
      }
    }

    function updateZ$1(el, elOption, seriesModel) {
      // Group not support textContent and not support z yet.
      if (el.isGroup) {
        return;
      }

      var elDisplayable = el;
      var currentZ = seriesModel.currentZ;
      var currentZLevel = seriesModel.currentZLevel; // Always erase.

      elDisplayable.z = currentZ;
      elDisplayable.zlevel = currentZLevel; // z2 must not be null/undefined, otherwise sort error may occur.

      var optZ2 = elOption.z2;
      optZ2 != null && (elDisplayable.z2 = optZ2 || 0);

      for (var i = 0; i < STATES.length; i++) {
        updateZForEachState(elDisplayable, elOption, STATES[i]);
      }
    }

    function updateZForEachState(elDisplayable, elOption, state) {
      var isNormal = state === NORMAL;
      var elStateOpt = isNormal ? elOption : retrieveStateOption(elOption, state);
      var optZ2 = elStateOpt ? elStateOpt.z2 : null;
      var stateObj;

      if (optZ2 != null) {
        // Do not `ensureState` until required.
        stateObj = isNormal ? elDisplayable : elDisplayable.ensureState(state);
        stateObj.z2 = optZ2 || 0;
      }
    }

    function makeRenderItem(customSeries, data, ecModel, api) {
      var renderItem = customSeries.get('renderItem');
      var coordSys = customSeries.coordinateSystem;
      var prepareResult = {};

      if (coordSys) {
        if ("development" !== 'production') {
          assert(renderItem, 'series.render is required.');
          assert(coordSys.prepareCustoms || prepareCustoms[coordSys.type], 'This coordSys does not support custom series.');
        } // `coordSys.prepareCustoms` is used for external coord sys like bmap.


        prepareResult = coordSys.prepareCustoms ? coordSys.prepareCustoms(coordSys) : prepareCustoms[coordSys.type](coordSys);
      }

      var userAPI = defaults({
        getWidth: api.getWidth,
        getHeight: api.getHeight,
        getZr: api.getZr,
        getDevicePixelRatio: api.getDevicePixelRatio,
        value: value,
        style: style,
        ordinalRawValue: ordinalRawValue,
        styleEmphasis: styleEmphasis,
        visual: visual,
        barLayout: barLayout,
        currentSeriesIndices: currentSeriesIndices,
        font: font
      }, prepareResult.api || {});
      var userParams = {
        // The life cycle of context: current round of rendering.
        // The global life cycle is probably not necessary, because
        // user can store global status by themselves.
        context: {},
        seriesId: customSeries.id,
        seriesName: customSeries.name,
        seriesIndex: customSeries.seriesIndex,
        coordSys: prepareResult.coordSys,
        dataInsideLength: data.count(),
        encode: wrapEncodeDef(customSeries.getData())
      }; // If someday intending to refactor them to a class, should consider do not
      // break change: currently these attribute member are encapsulated in a closure
      // so that do not need to force user to call these method with a scope.
      // Do not support call `api` asynchronously without dataIndexInside input.

      var currDataIndexInside;
      var currItemModel;
      var currItemStyleModels = {};
      var currLabelModels = {};
      var seriesItemStyleModels = {};
      var seriesLabelModels = {};

      for (var i = 0; i < STATES.length; i++) {
        var stateName = STATES[i];
        seriesItemStyleModels[stateName] = customSeries.getModel(PATH_ITEM_STYLE[stateName]);
        seriesLabelModels[stateName] = customSeries.getModel(PATH_LABEL[stateName]);
      }

      function getItemModel(dataIndexInside) {
        return dataIndexInside === currDataIndexInside ? currItemModel || (currItemModel = data.getItemModel(dataIndexInside)) : data.getItemModel(dataIndexInside);
      }

      function getItemStyleModel(dataIndexInside, state) {
        return !data.hasItemOption ? seriesItemStyleModels[state] : dataIndexInside === currDataIndexInside ? currItemStyleModels[state] || (currItemStyleModels[state] = getItemModel(dataIndexInside).getModel(PATH_ITEM_STYLE[state])) : getItemModel(dataIndexInside).getModel(PATH_ITEM_STYLE[state]);
      }

      function getLabelModel(dataIndexInside, state) {
        return !data.hasItemOption ? seriesLabelModels[state] : dataIndexInside === currDataIndexInside ? currLabelModels[state] || (currLabelModels[state] = getItemModel(dataIndexInside).getModel(PATH_LABEL[state])) : getItemModel(dataIndexInside).getModel(PATH_LABEL[state]);
      }

      return function (dataIndexInside, payload) {
        currDataIndexInside = dataIndexInside;
        currItemModel = null;
        currItemStyleModels = {};
        currLabelModels = {};
        return renderItem && renderItem(defaults({
          dataIndexInside: dataIndexInside,
          dataIndex: data.getRawIndex(dataIndexInside),
          // Can be used for optimization when zoom or roam.
          actionType: payload ? payload.type : null
        }, userParams), userAPI);
      };
      /**
       * @public
       * @param dim by default 0.
       * @param dataIndexInside by default `currDataIndexInside`.
       */

      function value(dim, dataIndexInside) {
        dataIndexInside == null && (dataIndexInside = currDataIndexInside);
        return data.getStore().get(data.getDimensionIndex(dim || 0), dataIndexInside);
      }
      /**
       * @public
       * @param dim by default 0.
       * @param dataIndexInside by default `currDataIndexInside`.
       */


      function ordinalRawValue(dim, dataIndexInside) {
        dataIndexInside == null && (dataIndexInside = currDataIndexInside);
        dim = dim || 0;
        var dimInfo = data.getDimensionInfo(dim);

        if (!dimInfo) {
          var dimIndex = data.getDimensionIndex(dim);
          return dimIndex >= 0 ? data.getStore().get(dimIndex, dataIndexInside) : undefined;
        }

        var val = data.get(dimInfo.name, dataIndexInside);
        var ordinalMeta = dimInfo && dimInfo.ordinalMeta;
        return ordinalMeta ? ordinalMeta.categories[val] : val;
      }
      /**
       * @deprecated The original intention of `api.style` is enable to set itemStyle
       * like other series. But it is not necessary and not easy to give a strict definition
       * of what it returns. And since echarts5 it needs to be make compat work. So
       * deprecates it since echarts5.
       *
       * By default, `visual` is applied to style (to support visualMap).
       * `visual.color` is applied at `fill`. If user want apply visual.color on `stroke`,
       * it can be implemented as:
       * `api.style({stroke: api.visual('color'), fill: null})`;
       *
       * [Compat]: since ec5, RectText has been separated from its hosts el.
       * so `api.style()` will only return the style from `itemStyle` but not handle `label`
       * any more. But `series.label` config is never published in doc.
       * We still compat it in `api.style()`. But not encourage to use it and will still not
       * to pulish it to doc.
       * @public
       * @param dataIndexInside by default `currDataIndexInside`.
       */


      function style(userProps, dataIndexInside) {
        if ("development" !== 'production') {
          warnDeprecated('api.style', 'Please write literal style directly instead.');
        }

        dataIndexInside == null && (dataIndexInside = currDataIndexInside);
        var style = data.getItemVisual(dataIndexInside, 'style');
        var visualColor = style && style.fill;
        var opacity = style && style.opacity;
        var itemStyle = getItemStyleModel(dataIndexInside, NORMAL).getItemStyle();
        visualColor != null && (itemStyle.fill = visualColor);
        opacity != null && (itemStyle.opacity = opacity);
        var opt = {
          inheritColor: isString(visualColor) ? visualColor : '#000'
        };
        var labelModel = getLabelModel(dataIndexInside, NORMAL); // Now that the feature of "auto adjust text fill/stroke" has been migrated to zrender
        // since ec5, we should set `isAttached` as `false` here and make compat in
        // `convertToEC4StyleForCustomSerise`.

        var textStyle = createTextStyle(labelModel, null, opt, false, true);
        textStyle.text = labelModel.getShallow('show') ? retrieve2(customSeries.getFormattedLabel(dataIndexInside, NORMAL), getDefaultLabel(data, dataIndexInside)) : null;
        var textConfig = createTextConfig(labelModel, opt, false);
        preFetchFromExtra(userProps, itemStyle);
        itemStyle = convertToEC4StyleForCustomSerise(itemStyle, textStyle, textConfig);
        userProps && applyUserPropsAfter(itemStyle, userProps);
        itemStyle.legacy = true;
        return itemStyle;
      }
      /**
       * @deprecated The reason see `api.style()`
       * @public
       * @param dataIndexInside by default `currDataIndexInside`.
       */


      function styleEmphasis(userProps, dataIndexInside) {
        if ("development" !== 'production') {
          warnDeprecated('api.styleEmphasis', 'Please write literal style directly instead.');
        }

        dataIndexInside == null && (dataIndexInside = currDataIndexInside);
        var itemStyle = getItemStyleModel(dataIndexInside, EMPHASIS).getItemStyle();
        var labelModel = getLabelModel(dataIndexInside, EMPHASIS);
        var textStyle = createTextStyle(labelModel, null, null, true, true);
        textStyle.text = labelModel.getShallow('show') ? retrieve3(customSeries.getFormattedLabel(dataIndexInside, EMPHASIS), customSeries.getFormattedLabel(dataIndexInside, NORMAL), getDefaultLabel(data, dataIndexInside)) : null;
        var textConfig = createTextConfig(labelModel, null, true);
        preFetchFromExtra(userProps, itemStyle);
        itemStyle = convertToEC4StyleForCustomSerise(itemStyle, textStyle, textConfig);
        userProps && applyUserPropsAfter(itemStyle, userProps);
        itemStyle.legacy = true;
        return itemStyle;
      }

      function applyUserPropsAfter(itemStyle, extra) {
        for (var key in extra) {
          if (hasOwn(extra, key)) {
            itemStyle[key] = extra[key];
          }
        }
      }

      function preFetchFromExtra(extra, itemStyle) {
        // A trick to retrieve those props firstly, which are used to
        // apply auto inside fill/stroke in `convertToEC4StyleForCustomSerise`.
        // (It's not reasonable but only for a degree of compat)
        if (extra) {
          extra.textFill && (itemStyle.textFill = extra.textFill);
          extra.textPosition && (itemStyle.textPosition = extra.textPosition);
        }
      }
      /**
       * @public
       * @param dataIndexInside by default `currDataIndexInside`.
       */


      function visual(visualType, dataIndexInside) {
        dataIndexInside == null && (dataIndexInside = currDataIndexInside);

        if (hasOwn(STYLE_VISUAL_TYPE, visualType)) {
          var style_1 = data.getItemVisual(dataIndexInside, 'style');
          return style_1 ? style_1[STYLE_VISUAL_TYPE[visualType]] : null;
        } // Only support these visuals. Other visual might be inner tricky
        // for performance (like `style`), do not expose to users.


        if (hasOwn(NON_STYLE_VISUAL_PROPS, visualType)) {
          return data.getItemVisual(dataIndexInside, visualType);
        }
      }
      /**
       * @public
       * @return If not support, return undefined.
       */


      function barLayout(opt) {
        if (coordSys.type === 'cartesian2d') {
          var baseAxis = coordSys.getBaseAxis();
          return getLayoutOnAxis(defaults({
            axis: baseAxis
          }, opt));
        }
      }
      /**
       * @public
       */


      function currentSeriesIndices() {
        return ecModel.getCurrentSeriesIndices();
      }
      /**
       * @public
       * @return font string
       */


      function font(opt) {
        return getFont(opt, ecModel);
      }
    }

    function wrapEncodeDef(data) {
      var encodeDef = {};
      each(data.dimensions, function (dimName) {
        var dimInfo = data.getDimensionInfo(dimName);

        if (!dimInfo.isExtraCoord) {
          var coordDim = dimInfo.coordDim;
          var dataDims = encodeDef[coordDim] = encodeDef[coordDim] || [];
          dataDims[dimInfo.coordDimIndex] = data.getDimensionIndex(dimName);
        }
      });
      return encodeDef;
    }

    function createOrUpdateItem(api, existsEl, dataIndex, elOption, seriesModel, group, data) {
      // [Rule]
      // If `renderItem` returns `null`/`undefined`/`false`, remove the previous el if existing.
      //     (It seems that violate the "merge" principle, but most of users probably intuitively
      //     regard "return;" as "show nothing element whatever", so make a exception to meet the
      //     most cases.)
      // The rule or "merge" see [STRATEGY_MERGE].
      // If `elOption` is `null`/`undefined`/`false` (when `renderItem` returns nothing).
      if (!elOption) {
        group.remove(existsEl);
        return;
      }

      var el = doCreateOrUpdateEl(api, existsEl, dataIndex, elOption, seriesModel, group);
      el && data.setItemGraphicEl(dataIndex, el);
      el && toggleHoverEmphasis(el, elOption.focus, elOption.blurScope, elOption.emphasisDisabled);
      return el;
    }

    function doCreateOrUpdateEl(api, existsEl, dataIndex, elOption, seriesModel, group) {
      if ("development" !== 'production') {
        assert(elOption, 'should not have an null/undefined element setting');
      }

      var toBeReplacedIdx = -1;
      var oldEl = existsEl;

      if (existsEl && doesElNeedRecreate(existsEl, elOption, seriesModel) // || (
      //     // PENDING: even in one-to-one mapping case, if el is marked as morph,
      //     // do not sure whether the el will be mapped to another el with different
      //     // hierarchy in Group tree. So always recreate el rather than reuse the el.
      //     morphHelper && morphHelper.isOneToOneFrom(el)
      // )
      ) {
        // Should keep at the original index, otherwise "merge by index" will be incorrect.
        toBeReplacedIdx = indexOf(group.childrenRef(), existsEl);
        existsEl = null;
      }

      var isInit = !existsEl;
      var el = existsEl;

      if (!el) {
        el = createEl(elOption);

        if (oldEl) {
          copyElement(oldEl, el);
        }
      } else {
        // FIMXE:NEXT unified clearState?
        // If in some case the performance issue arised, consider
        // do not clearState but update cached normal state directly.
        el.clearStates();
      } // Need to set morph: false explictly to disable automatically morphing.


      if (elOption.morph === false) {
        el.disableMorphing = true;
      } else if (el.disableMorphing) {
        el.disableMorphing = false;
      }

      attachedTxInfoTmp.normal.cfg = attachedTxInfoTmp.normal.conOpt = attachedTxInfoTmp.emphasis.cfg = attachedTxInfoTmp.emphasis.conOpt = attachedTxInfoTmp.blur.cfg = attachedTxInfoTmp.blur.conOpt = attachedTxInfoTmp.select.cfg = attachedTxInfoTmp.select.conOpt = null;
      attachedTxInfoTmp.isLegacy = false;
      doCreateOrUpdateAttachedTx(el, dataIndex, elOption, seriesModel, isInit, attachedTxInfoTmp);
      doCreateOrUpdateClipPath(el, dataIndex, elOption, seriesModel, isInit);
      updateElNormal(api, el, dataIndex, elOption, attachedTxInfoTmp, seriesModel, isInit); // `elOption.info` enables user to mount some info on
      // elements and use them in event handlers.
      // Update them only when user specified, otherwise, remain.

      hasOwn(elOption, 'info') && (customInnerStore(el).info = elOption.info);

      for (var i = 0; i < STATES.length; i++) {
        var stateName = STATES[i];

        if (stateName !== NORMAL) {
          var otherStateOpt = retrieveStateOption(elOption, stateName);
          var otherStyleOpt = retrieveStyleOptionOnState(elOption, otherStateOpt, stateName);
          updateElOnState(stateName, el, otherStateOpt, otherStyleOpt, attachedTxInfoTmp);
        }
      }

      updateZ$1(el, elOption, seriesModel);

      if (elOption.type === 'group') {
        mergeChildren(api, el, dataIndex, elOption, seriesModel);
      }

      if (toBeReplacedIdx >= 0) {
        group.replaceAt(el, toBeReplacedIdx);
      } else {
        group.add(el);
      }

      return el;
    } // `el` must not be null/undefined.


    function doesElNeedRecreate(el, elOption, seriesModel) {
      var elInner = customInnerStore(el);
      var elOptionType = elOption.type;
      var elOptionShape = elOption.shape;
      var elOptionStyle = elOption.style;
      return (// Always create new if universal transition is enabled.
        // Because we do transition after render. It needs to know what old element is. Replacement will loose it.
        seriesModel.isUniversalTransitionEnabled() // If `elOptionType` is `null`, follow the merge principle.
        || elOptionType != null && elOptionType !== elInner.customGraphicType || elOptionType === 'path' && hasOwnPathData(elOptionShape) && getPathData(elOptionShape) !== elInner.customPathData || elOptionType === 'image' && hasOwn(elOptionStyle, 'image') && elOptionStyle.image !== elInner.customImagePath // // FIXME test and remove this restriction?
        // || (elOptionType === 'text'
        //     && hasOwn(elOptionStyle, 'text')
        //     && (elOptionStyle as TextStyleProps).text !== elInner.customText
        // )

      );
    }

    function doCreateOrUpdateClipPath(el, dataIndex, elOption, seriesModel, isInit) {
      // Based on the "merge" principle, if no clipPath provided,
      // do nothing. The exists clip will be totally removed only if
      // `el.clipPath` is `false`. Otherwise it will be merged/replaced.
      var clipPathOpt = elOption.clipPath;

      if (clipPathOpt === false) {
        if (el && el.getClipPath()) {
          el.removeClipPath();
        }
      } else if (clipPathOpt) {
        var clipPath = el.getClipPath();

        if (clipPath && doesElNeedRecreate(clipPath, clipPathOpt, seriesModel)) {
          clipPath = null;
        }

        if (!clipPath) {
          clipPath = createEl(clipPathOpt);

          if ("development" !== 'production') {
            assert(isPath$1(clipPath), 'Only any type of `path` can be used in `clipPath`, rather than ' + clipPath.type + '.');
          }

          el.setClipPath(clipPath);
        }

        updateElNormal(null, clipPath, dataIndex, clipPathOpt, null, seriesModel, isInit);
      } // If not define `clipPath` in option, do nothing unnecessary.

    }

    function doCreateOrUpdateAttachedTx(el, dataIndex, elOption, seriesModel, isInit, attachedTxInfo) {
      // Group does not support textContent temporarily until necessary.
      if (el.isGroup) {
        return;
      } // Normal must be called before emphasis, for `isLegacy` detection.


      processTxInfo(elOption, null, attachedTxInfo);
      processTxInfo(elOption, EMPHASIS, attachedTxInfo); // If `elOption.textConfig` or `elOption.textContent` is null/undefined, it does not make sense.
      // So for simplicity, if "elOption hasOwnProperty of them but be null/undefined", we do not
      // trade them as set to null to el.
      // Especially:
      // `elOption.textContent: false` means remove textContent.
      // `elOption.textContent.emphasis.style: false` means remove the style from emphasis state.

      var txConOptNormal = attachedTxInfo.normal.conOpt;
      var txConOptEmphasis = attachedTxInfo.emphasis.conOpt;
      var txConOptBlur = attachedTxInfo.blur.conOpt;
      var txConOptSelect = attachedTxInfo.select.conOpt;

      if (txConOptNormal != null || txConOptEmphasis != null || txConOptSelect != null || txConOptBlur != null) {
        var textContent = el.getTextContent();

        if (txConOptNormal === false) {
          textContent && el.removeTextContent();
        } else {
          txConOptNormal = attachedTxInfo.normal.conOpt = txConOptNormal || {
            type: 'text'
          };

          if (!textContent) {
            textContent = createEl(txConOptNormal);
            el.setTextContent(textContent);
          } else {
            // If in some case the performance issue arised, consider
            // do not clearState but update cached normal state directly.
            textContent.clearStates();
          }

          updateElNormal(null, textContent, dataIndex, txConOptNormal, null, seriesModel, isInit);
          var txConStlOptNormal = txConOptNormal && txConOptNormal.style;

          for (var i = 0; i < STATES.length; i++) {
            var stateName = STATES[i];

            if (stateName !== NORMAL) {
              var txConOptOtherState = attachedTxInfo[stateName].conOpt;
              updateElOnState(stateName, textContent, txConOptOtherState, retrieveStyleOptionOnState(txConOptNormal, txConOptOtherState, stateName), null);
            }
          }

          txConStlOptNormal ? textContent.dirty() : textContent.markRedraw();
        }
      }
    }

    function processTxInfo(elOption, state, attachedTxInfo) {
      var stateOpt = !state ? elOption : retrieveStateOption(elOption, state);
      var styleOpt = !state ? elOption.style : retrieveStyleOptionOnState(elOption, stateOpt, EMPHASIS);
      var elType = elOption.type;
      var txCfg = stateOpt ? stateOpt.textConfig : null;
      var txConOptNormal = elOption.textContent;
      var txConOpt = !txConOptNormal ? null : !state ? txConOptNormal : retrieveStateOption(txConOptNormal, state);

      if (styleOpt && ( // Because emphasis style has little info to detect legacy,
      // if normal is legacy, emphasis is trade as legacy.
      attachedTxInfo.isLegacy || isEC4CompatibleStyle(styleOpt, elType, !!txCfg, !!txConOpt))) {
        attachedTxInfo.isLegacy = true;
        var convertResult = convertFromEC4CompatibleStyle(styleOpt, elType, !state); // Explicitly specified `textConfig` and `textContent` has higher priority than
        // the ones generated by legacy style. Otherwise if users use them and `api.style`
        // at the same time, they not both work and hardly to known why.

        if (!txCfg && convertResult.textConfig) {
          txCfg = convertResult.textConfig;
        }

        if (!txConOpt && convertResult.textContent) {
          txConOpt = convertResult.textContent;
        }
      }

      if (!state && txConOpt) {
        var txConOptNormal_1 = txConOpt; // `textContent: {type: 'text'}`, the "type" is easy to be missing. So we tolerate it.

        !txConOptNormal_1.type && (txConOptNormal_1.type = 'text');

        if ("development" !== 'production') {
          // Do not tolerate incorrcet type for forward compat.
          assert(txConOptNormal_1.type === 'text', 'textContent.type must be "text"');
        }
      }

      var info = !state ? attachedTxInfo.normal : attachedTxInfo[state];
      info.cfg = txCfg;
      info.conOpt = txConOpt;
    }

    function retrieveStateOption(elOption, state) {
      return !state ? elOption : elOption ? elOption[state] : null;
    }

    function retrieveStyleOptionOnState(stateOptionNormal, stateOption, state) {
      var style = stateOption && stateOption.style;

      if (style == null && state === EMPHASIS && stateOptionNormal) {
        style = stateOptionNormal.styleEmphasis;
      }

      return style;
    } // Usage:
    // (1) By default, `elOption.$mergeChildren` is `'byIndex'`, which indicates
    //     that the existing children will not be removed, and enables the feature
    //     that update some of the props of some of the children simply by construct
    //     the returned children of `renderItem` like:
    //     `var children = group.children = []; children[3] = {opacity: 0.5};`
    // (2) If `elOption.$mergeChildren` is `'byName'`, add/update/remove children
    //     by child.name. But that might be lower performance.
    // (3) If `elOption.$mergeChildren` is `false`, the existing children will be
    //     replaced totally.
    // (4) If `!elOption.children`, following the "merge" principle, nothing will
    //     happen.
    // (5) If `elOption.$mergeChildren` is not `false` neither `'byName'` and the
    //     `el` is a group, and if any of the new child is null, it means to remove
    //     the element at the same index, if exists. On the other hand, if the new
    //     child is and empty object `{}`, it means to keep the element not changed.
    //
    // For implementation simpleness, do not provide a direct way to remove single
    // child (otherwise the total indices of the children array have to be modified).
    // User can remove a single child by setting its `ignore` to `true`.


    function mergeChildren(api, el, dataIndex, elOption, seriesModel) {
      var newChildren = elOption.children;
      var newLen = newChildren ? newChildren.length : 0;
      var mergeChildren = elOption.$mergeChildren; // `diffChildrenByName` has been deprecated.

      var byName = mergeChildren === 'byName' || elOption.diffChildrenByName;
      var notMerge = mergeChildren === false; // For better performance on roam update, only enter if necessary.

      if (!newLen && !byName && !notMerge) {
        return;
      }

      if (byName) {
        diffGroupChildren({
          api: api,
          oldChildren: el.children() || [],
          newChildren: newChildren || [],
          dataIndex: dataIndex,
          seriesModel: seriesModel,
          group: el
        });
        return;
      }

      notMerge && el.removeAll(); // Mapping children of a group simply by index, which
      // might be better performance.

      var index = 0;

      for (; index < newLen; index++) {
        var newChild = newChildren[index];
        var oldChild = el.childAt(index);

        if (newChild) {
          if (newChild.ignore == null) {
            // The old child is set to be ignored if null (see comments
            // below). So we need to set ignore to be false back.
            newChild.ignore = false;
          }

          doCreateOrUpdateEl(api, oldChild, dataIndex, newChild, seriesModel, el);
        } else {
          if ("development" !== 'production') {
            assert(oldChild, 'renderItem should not return a group containing elements' + ' as null/undefined/{} if they do not exist before.');
          } // If the new element option is null, it means to remove the old
          // element. But we cannot really remove the element from the group
          // directly, because the element order may not be stable when this
          // element is added back. So we set the element to be ignored.


          oldChild.ignore = true;
        }
      }

      for (var i = el.childCount() - 1; i >= index; i--) {
        var child = el.childAt(i);
        removeChildFromGroup(el, child, seriesModel);
      }
    }

    function removeChildFromGroup(group, child, seriesModel) {
      // Do not support leave elements that are not mentioned in the latest
      // `renderItem` return. Otherwise users may not have a clear and simple
      // concept that how to control all of the elements.
      child && applyLeaveTransition(child, customInnerStore(group).option, seriesModel);
    }

    function diffGroupChildren(context) {
      new DataDiffer(context.oldChildren, context.newChildren, getKey, getKey, context).add(processAddUpdate).update(processAddUpdate).remove(processRemove).execute();
    }

    function getKey(item, idx) {
      var name = item && item.name;
      return name != null ? name : GROUP_DIFF_PREFIX + idx;
    }

    function processAddUpdate(newIndex, oldIndex) {
      var context = this.context;
      var childOption = newIndex != null ? context.newChildren[newIndex] : null;
      var child = oldIndex != null ? context.oldChildren[oldIndex] : null;
      doCreateOrUpdateEl(context.api, child, context.dataIndex, childOption, context.seriesModel, context.group);
    }

    function processRemove(oldIndex) {
      var context = this.context;
      var child = context.oldChildren[oldIndex];
      child && applyLeaveTransition(child, customInnerStore(child).option, context.seriesModel);
    }
    /**
     * @return SVG Path data.
     */


    function getPathData(shape) {
      // "d" follows the SVG convention.
      return shape && (shape.pathData || shape.d);
    }

    function hasOwnPathData(shape) {
      return shape && (hasOwn(shape, 'pathData') || hasOwn(shape, 'd'));
    }

    function install$r(registers) {
      registers.registerChartView(CustomChartView);
      registers.registerSeriesModel(CustomSeriesModel);
    }

    var inner$a = makeInner();
    var clone$3 = clone;
    var bind$1 = bind;
    /**
     * Base axis pointer class in 2D.
     */

    var BaseAxisPointer =
    /** @class */
    function () {
      function BaseAxisPointer() {
        this._dragging = false;
        /**
         * In px, arbitrary value. Do not set too small,
         * no animation is ok for most cases.
         */

        this.animationThreshold = 15;
      }
      /**
       * @implement
       */


      BaseAxisPointer.prototype.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);
          this.updateLabelEl(group, elOption, doUpdateProps, axisPointerModel);
        }

        updateMandatoryProps(group, axisPointerModel, true);

        this._renderHandle(value);
      };
      /**
       * @implement
       */


      BaseAxisPointer.prototype.remove = function (api) {
        this.clear(api);
      };
      /**
       * @implement
       */


      BaseAxisPointer.prototype.dispose = function (api) {
        this.clear(api);
      };
      /**
       * @protected
       */


      BaseAxisPointer.prototype.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
       */


      BaseAxisPointer.prototype.makeElOption = function (elOption, value, axisModel, axisPointerModel, api) {// Shoule be implemenented by sub-class.
      };
      /**
       * @protected
       */


      BaseAxisPointer.prototype.createPointerEl = function (group, elOption, axisModel, axisPointerModel) {
        var pointerOption = elOption.pointer;

        if (pointerOption) {
          var pointerEl = inner$a(group).pointerEl = new graphic[pointerOption.type](clone$3(elOption.pointer));
          group.add(pointerEl);
        }
      };
      /**
       * @protected
       */


      BaseAxisPointer.prototype.createLabelEl = function (group, elOption, axisModel, axisPointerModel) {
        if (elOption.label) {
          var labelEl = inner$a(group).labelEl = new ZRText(clone$3(elOption.label));
          group.add(labelEl);
          updateLabelShowHide(labelEl, axisPointerModel);
        }
      };
      /**
       * @protected
       */


      BaseAxisPointer.prototype.updatePointerEl = function (group, elOption, updateProps) {
        var pointerEl = inner$a(group).pointerEl;

        if (pointerEl && elOption.pointer) {
          pointerEl.setStyle(elOption.pointer.style);
          updateProps(pointerEl, {
            shape: elOption.pointer.shape
          });
        }
      };
      /**
       * @protected
       */


      BaseAxisPointer.prototype.updateLabelEl = function (group, elOption, updateProps, axisPointerModel) {
        var labelEl = inner$a(group).labelEl;

        if (labelEl) {
          labelEl.setStyle(elOption.label.style);
          updateProps(labelEl, {
            // Consider text length change in vertical axis, animation should
            // be used on shape, otherwise the effect will be weird.
            // TODOTODO
            // shape: elOption.label.shape,
            x: elOption.label.x,
            y: elOption.label.y
          });
          updateLabelShowHide(labelEl, axisPointerModel);
        }
      };
      /**
       * @private
       */


      BaseAxisPointer.prototype._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

        handle.setStyle(handleModel.getItemStyle(null, ['color', 'borderColor', 'borderWidth', 'opacity', 'shadowColor', 'shadowBlur', 'shadowOffsetX', 'shadowOffsetY'])); // update position

        var handleSize = handleModel.get('size');

        if (!isArray(handleSize)) {
          handleSize = [handleSize, handleSize];
        }

        handle.scaleX = handleSize[0] / 2;
        handle.scaleY = handleSize[1] / 2;
        createOrUpdate(this, '_doDispatchAxisPointer', handleModel.get('throttle') || 0, 'fixRate');

        this._moveHandleToValue(value, isInit);
      };

      BaseAxisPointer.prototype._moveHandleToValue = function (value, isInit) {
        updateProps$1(this._axisPointerModel, !isInit && this._moveAnimation, this._handle, getHandleTransProps(this.getHandleTransform(value, this._axisModel, this._axisPointerModel)));
      };

      BaseAxisPointer.prototype._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$a(handle).lastProp = null;

        this._doDispatchAxisPointer();
      };
      /**
       * Throttled method.
       */


      BaseAxisPointer.prototype._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
          }]
        });
      };

      BaseAxisPointer.prototype._onHandleDragEnd = function () {
        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'
        });
      };
      /**
       * @private
       */


      BaseAxisPointer.prototype.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;
        }

        clear(this, '_doDispatchAxisPointer');
      };
      /**
       * @protected
       */


      BaseAxisPointer.prototype.doClear = function () {// Implemented by sub-class if necessary.
      };

      BaseAxisPointer.prototype.buildLabel = function (xy, wh, xDimIndex) {
        xDimIndex = xDimIndex || 0;
        return {
          x: xy[xDimIndex],
          y: xy[1 - xDimIndex],
          width: wh[xDimIndex],
          height: wh[1 - xDimIndex]
        };
      };

      return BaseAxisPointer;
    }();

    function updateProps$1(animationModel, moveAnimation, el, props) {
      // Animation optimize.
      if (!propsEqual(inner$a(el).lastProp, props)) {
        inner$a(el).lastProp = props;
        moveAnimation ? updateProps(el, props, animationModel) : (el.stopAnimation(), el.attr(props));
      }
    }

    function propsEqual(lastProps, newProps) {
      if (isObject(lastProps) && isObject(newProps)) {
        var equals_1 = true;
        each(newProps, function (item, key) {
          equals_1 = equals_1 && propsEqual(lastProps[key], item);
        });
        return !!equals_1;
      } else {
        return lastProps === newProps;
      }
    }

    function updateLabelShowHide(labelEl, axisPointerModel) {
      labelEl[axisPointerModel.get(['label', 'show']) ? 'show' : 'hide']();
    }

    function getHandleTransProps(trans) {
      return {
        x: trans.x || 0,
        y: trans.y || 0,
        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;
        }
      });
    }

    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')},
        x: position[0],
        y: position[1],
        style: createTextStyle(labelModel, {
          text: text,
          font: font,
          fill: labelModel.getTextColor(),
          padding: paddings,
          backgroundColor: bgColor
        }),
        // 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);
    }

    function getValueLabel(value, axis, ecModel, seriesDataIndices, opt) {
      value = axis.scale.parse(value);
      var text = axis.scale.getLabel({
        value: value
      }, {
        // If `precision` is set, width can be fixed (like '12.00500'), which
        // helps to debounce when when moving label.
        precision: opt.precision
      });
      var formatter = opt.formatter;

      if (formatter) {
        var params_1 = {
          value: getAxisRawValue(axis, {
            value: value
          }),
          axisDimension: axis.dim,
          axisIndex: axis.index,
          seriesData: []
        };
        each(seriesDataIndices, function (idxItem) {
          var series = ecModel.getSeriesByIndex(idxItem.seriesIndex);
          var dataIndex = idxItem.dataIndexInside;
          var dataParams = series && series.getDataParams(dataIndex);
          dataParams && params_1.seriesData.push(dataParams);
        });

        if (isString(formatter)) {
          text = formatter.replace('{value}', text);
        } else if (isFunction(formatter)) {
          text = formatter(params_1);
        }
      }

      return text;
    }
    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) {
      // @ts-ignore
      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
      });
    }
    function makeLineShape(p1, p2, xDimIndex) {
      xDimIndex = xDimIndex || 0;
      return {
        x1: p1[xDimIndex],
        y1: p1[1 - xDimIndex],
        x2: p2[xDimIndex],
        y2: p2[1 - xDimIndex]
      };
    }
    function makeRectShape(xy, wh, xDimIndex) {
      xDimIndex = xDimIndex || 0;
      return {
        x: xy[xDimIndex],
        y: xy[1 - xDimIndex],
        width: wh[xDimIndex],
        height: wh[1 - xDimIndex]
      };
    }
    function makeSectorShape(cx, cy, r0, r, startAngle, endAngle) {
      return {
        cx: cx,
        cy: cy,
        r0: r0,
        r: r,
        startAngle: startAngle,
        endAngle: endAngle,
        clockwise: true
      };
    }

    var CartesianAxisPointer =
    /** @class */
    function (_super) {
      __extends(CartesianAxisPointer, _super);

      function CartesianAxisPointer() {
        return _super !== null && _super.apply(this, arguments) || this;
      }
      /**
       * @override
       */


      CartesianAxisPointer.prototype.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( // @ts-ignore
        value, elOption, layoutInfo, axisModel, axisPointerModel, api);
      };
      /**
       * @override
       */


      CartesianAxisPointer.prototype.getHandleTransform = function (value, axisModel, axisPointerModel) {
        var layoutInfo = layout$1(axisModel.axis.grid.model, axisModel, {
          labelInside: false
        }); // @ts-ignore

        layoutInfo.labelMargin = axisPointerModel.get(['handle', 'margin']);
        var pos = getTransformedPosition(axisModel.axis, value, layoutInfo);
        return {
          x: pos[0],
          y: pos[1],
          rotation: layoutInfo.rotation + (layoutInfo.labelDirection < 0 ? Math.PI : 0)
        };
      };
      /**
       * @override
       */


      CartesianAxisPointer.prototype.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.x, transform.y];
        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 {
          x: currPosition[0],
          y: currPosition[1],
          rotation: transform.rotation,
          cursorPoint: cursorPoint,
          tooltipOption: tooltipOptions[dimIndex]
        };
      };

      return CartesianAxisPointer;
    }(BaseAxisPointer);

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

    var AxisPointerModel =
    /** @class */
    function (_super) {
      __extends(AxisPointerModel, _super);

      function AxisPointerModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = AxisPointerModel.type;
        return _this;
      }

      AxisPointerModel.type = 'axisPointer';
      AxisPointerModel.defaultOption = {
        // 'auto' means that show when triggered by tooltip or handle.
        show: 'auto',
        // zlevel: 0,
        z: 50,
        type: 'line',
        // axispointer triggered by tootip determine snap automatically,
        // see `modelHelper`.
        snap: false,
        triggerTooltip: true,
        value: null,
        status: null,
        link: [],
        // Do not set 'auto' here, otherwise global animation: false
        // will not effect at this axispointer.
        animation: null,
        animationDurationUpdate: 200,
        lineStyle: {
          color: '#B9BEC9',
          width: 1,
          type: 'dashed'
        },
        shadowStyle: {
          color: 'rgba(210,219,238,0.2)'
        },
        label: {
          show: true,
          formatter: null,
          precision: 'auto',
          margin: 3,
          color: '#fff',
          padding: [5, 7, 5, 7],
          backgroundColor: 'auto',
          borderColor: null,
          borderWidth: 0,
          borderRadius: 3
        },
        handle: {
          show: false,
          // eslint-disable-next-line
          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',
          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
        }
      };
      return AxisPointerModel;
    }(ComponentModel);

    var inner$b = makeInner();
    var each$7 = each;
    /**
     * @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.node) {
        return;
      }

      var zr = api.getZr();
      inner$b(zr).records || (inner$b(zr).records = {});
      initGlobalListeners(zr, api);
      var record = inner$b(zr).records[key] || (inner$b(zr).records[key] = {});
      record.handler = handler;
    }

    function initGlobalListeners(zr, api) {
      if (inner$b(zr).initialized) {
        return;
      }

      inner$b(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$7(inner$b(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
      };
    }

    function unregister(key, api) {
      if (env.node) {
        return;
      }

      var zr = api.getZr();
      var record = (inner$b(zr).records || {})[key];

      if (record) {
        inner$b(zr).records[key] = null;
      }
    }

    var AxisPointerView =
    /** @class */
    function (_super) {
      __extends(AxisPointerView, _super);

      function AxisPointerView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = AxisPointerView.type;
        return _this;
      }

      AxisPointerView.prototype.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
            });
          }
        });
      };

      AxisPointerView.prototype.remove = function (ecModel, api) {
        unregister('axisPointer', api);
      };

      AxisPointerView.prototype.dispose = function (ecModel, api) {
        unregister('axisPointer', api);
      };

      AxisPointerView.type = 'axisPointer';
      return AxisPointerView;
    }(ComponentView);

    /**
     * @param finder contains {seriesIndex, dataIndex, dataIndexInside}
     * @param ecModel
     * @return  {point: [x, y], el: ...} point Will not be null.
     */

    function findPointFromSeries(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) {
        if (finder.isStacked) {
          var baseAxis = coordSys.getBaseAxis();
          var valueAxis = coordSys.getOtherAxis(baseAxis);
          var valueAxisDim = valueAxis.dim;
          var baseAxisDim = baseAxis.dim;
          var baseDataOffset = valueAxisDim === 'x' || valueAxisDim === 'radius' ? 1 : 0;
          var baseDim = data.mapDimension(baseAxisDim);
          var stackedData = [];
          stackedData[baseDataOffset] = data.get(baseDim, dataIndex);
          stackedData[1 - baseDataOffset] = data.get(data.getCalculationInfo('stackResultDimension'), dataIndex);
          point = coordSys.dataToPoint(stackedData) || [];
        } else {
          point = coordSys.dataToPoint(data.getValues(map(coordSys.dimensions, function (dim) {
            return data.mapDimension(dim);
          }), dataIndex)) || [];
        }
      } 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
      };
    }

    var inner$c = makeInner();
    /**
     * Basic logic: check all axis, if they do not demand show/highlight,
     * then hide/downplay them.
     *
     * @return content of event obj for echarts.connect.
     */

    function axisTrigger(payload, ecModel, api) {
      var currTrigger = payload.currTrigger;
      var point = [payload.x, payload.y];
      var finder = payload;
      var dispatchAction = payload.dispatchAction || 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 outputPayload = {};
      var showValueMap = {};
      var dataByCoordSys = {
        list: [],
        map: {}
      };
      var updaters = {
        showPointer: curry(showPointer, showValueMap),
        showTooltip: curry(showTooltip, dataByCoordSys)
      }; // Process for triggered axes.

      each(coordSysAxesInfo.coordSysMap, function (coordSys, coordSysKey) {
        // If a point given, it must be contained by the coordinate system.
        var coordSysContainsPoint = isIllegalPoint || coordSys.containPoint(point);
        each(coordSysAxesInfo.coordSysAxesInfo[coordSysKey], function (axisInfo, key) {
          var axis = axisInfo.axis;
          var inputAxisInfo = findInputAxisInfo(inputAxesInfo, axisInfo); // If no inputAxesInfo, no axis is restricted.

          if (!shouldHide && coordSysContainsPoint && (!inputAxesInfo || inputAxisInfo)) {
            var val = inputAxisInfo && inputAxisInfo.value;

            if (val == null && !isIllegalPoint) {
              val = axis.pointToData(point);
            }

            val != null && processOnAxis(axisInfo, val, updaters, false, outputPayload);
          }
        });
      }); // Process for linked axes.

      var linkTriggers = {};
      each(axesInfo, function (tarAxisInfo, tarKey) {
        var linkGroup = tarAxisInfo.linkGroup; // If axis has been triggered in the previous stage, it should not be triggered by link.

        if (linkGroup && !showValueMap[tarKey]) {
          each(linkGroup.axesInfo, function (srcAxisInfo, srcKey) {
            var srcValItem = showValueMap[srcKey]; // If srcValItem exist, source axis is triggered, so link to target axis.

            if (srcAxisInfo !== tarAxisInfo && srcValItem) {
              var val = srcValItem.value;
              linkGroup.mapper && (val = tarAxisInfo.axis.scale.parse(linkGroup.mapper(val, makeMapperParam(srcAxisInfo), makeMapperParam(tarAxisInfo))));
              linkTriggers[tarAxisInfo.key] = val;
            }
          });
        }
      });
      each(linkTriggers, function (val, tarKey) {
        processOnAxis(axesInfo[tarKey], val, updaters, true, outputPayload);
      });
      updateModelActually(showValueMap, axesInfo, outputPayload);
      dispatchTooltipActually(dataByCoordSys, point, payload, dispatchAction);
      dispatchHighDownActually(axesInfo, dispatchAction, api);
      return outputPayload;
    }

    function processOnAxis(axisInfo, newValue, updaters, noSnap, 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 (!noSnap && axisInfo.snap) {
        if (axis.containData(snapToValue) && snapToValue != null) {
          newValue = snapToValue;
        }
      }

      updaters.showPointer(axisInfo, newValue, payloadBatch); // Tooltip should always be snapToValue, otherwise there will be
      // incorrect "axis value ~ series value" mapping displayed in tooltip.

      updaters.showTooltip(axisInfo, payloadInfo, snapToValue);
    }

    function buildPayloadsBySeries(value, axisInfo) {
      var axis = axisInfo.axis;
      var dim = axis.dim;
      var snapToValue = value;
      var payloadBatch = [];
      var minDist = Number.MAX_VALUE;
      var minDiff = -1;
      each(axisInfo.seriesModels, function (series, idx) {
        var dataDim = series.getData().mapDimensionsAll(dim);
        var seriesNestestValue;
        var dataIndices;

        if (series.getAxisTooltipData) {
          var result = series.getAxisTooltipData(dataDim, value, axis);
          dataIndices = result.dataIndices;
          seriesNestestValue = result.nestestValue;
        } else {
          dataIndices = series.getData().indicesOfNearest(dataDim[0], value, // Add a threshold to avoid find the wrong dataIndex
          // when data length is not same.
          // false,
          axis.type === 'category' ? 0.5 : null);

          if (!dataIndices.length) {
            return;
          }

          seriesNestestValue = series.getData().get(dataDim[0], dataIndices[0]);
        }

        if (seriesNestestValue == null || !isFinite(seriesNestestValue)) {
          return;
        }

        var diff = value - seriesNestestValue;
        var dist = Math.abs(diff); // Consider category case

        if (dist <= minDist) {
          if (dist < minDist || diff >= 0 && minDiff < 0) {
            minDist = dist;
            minDiff = diff;
            snapToValue = seriesNestestValue;
            payloadBatch.length = 0;
          }

          each(dataIndices, function (dataIndex) {
            payloadBatch.push({
              seriesIndex: series.seriesIndex,
              dataIndexInside: dataIndex,
              dataIndex: series.getData().getRawIndex(dataIndex)
            });
          });
        }
      });
      return {
        payloadBatch: payloadBatch,
        snapToValue: snapToValue
      };
    }

    function showPointer(showValueMap, axisInfo, value, payloadBatch) {
      showValueMap[axisInfo.key] = {
        value: value,
        payloadBatch: payloadBatch
      };
    }

    function showTooltip(dataByCoordSys, axisInfo, payloadInfo, value) {
      var payloadBatch = payloadInfo.payloadBatch;
      var axis = axisInfo.axis;
      var axisModel = axis.model;
      var axisPointerModel = axisInfo.axisPointerModel; // If no data, do not create anything in dataByCoordSys,
      // whose length will be used to judge whether dispatch action.

      if (!axisInfo.triggerTooltip || !payloadBatch.length) {
        return;
      }

      var coordSysModel = axisInfo.coordSys.model;
      var coordSysKey = 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, outputPayload) {
      var outputAxesInfo = outputPayload.axesInfo = []; // Basic logic: If no 'show' required, 'hide' this axisPointer.

      each(axesInfo, function (axisInfo, key) {
        var option = axisInfo.axisPointerModel.option;
        var valItem = showValueMap[key];

        if (valItem) {
          !axisInfo.useHandle && (option.status = 'show');
          option.value = valItem.value; // For label formatter param and highlight.

          option.seriesDataIndices = (valItem.payloadBatch || []).slice();
        } // When always show (e.g., handle used), remain
        // original value and status.
        else {
            // If hide, value still need to be set, consider
            // click legend to toggle axis blank.
            !axisInfo.useHandle && (option.status = 'hide');
          } // If status is 'hide', should be no info in payload.


        option.status === 'show' && outputAxesInfo.push({
          axisDim: axisInfo.axis.dim,
          axisIndex: axisInfo.axis.model.componentIndex,
          value: option.value
        });
      });
    }

    function dispatchTooltipActually(dataByCoordSys, point, payload, dispatchAction) {
      // Basic logic: If no showTip required, hideTip will be dispatched.
      if (illegalPoint(point) || !dataByCoordSys.list.length) {
        dispatchAction({
          type: 'hideTip'
        });
        return;
      } // In most case only one axis (or event one series is used). It is
      // convinient to fetch payload.seriesIndex and payload.dataIndex
      // dirtectly. So put the first seriesIndex and dataIndex of the first
      // axis on the payload.


      var sampleItem = ((dataByCoordSys.list[0].dataByAxis[0] || {}).seriesDataIndices || [])[0] || {};
      dispatchAction({
        type: 'showTip',
        escapeConnect: true,
        x: point[0],
        y: point[1],
        tooltipOption: payload.tooltipOption,
        position: payload.position,
        dataIndexInside: sampleItem.dataIndexInside,
        dataIndex: sampleItem.dataIndex,
        seriesIndex: sampleItem.seriesIndex,
        dataByCoordSys: dataByCoordSys.list
      });
    }

    function dispatchHighDownActually(axesInfo, dispatchAction, api) {
      // FIXME
      // highlight status modification shoule be a stage of main process?
      // (Consider confilct (e.g., legend and axisPointer) and setOption)
      var zr = api.getZr();
      var highDownKey = 'axisPointerLastHighlights';
      var lastHighlights = inner$c(zr)[highDownKey] || {};
      var newHighlights = inner$c(zr)[highDownKey] = {}; // Update highlight/downplay status according to axisPointer model.
      // Build hash map and remove duplicate incidentally.

      each(axesInfo, function (axisInfo, key) {
        var option = axisInfo.axisPointerModel.option;
        option.status === 'show' && each(option.seriesDataIndices, function (batchItem) {
          var key = batchItem.seriesIndex + ' | ' + batchItem.dataIndex;
          newHighlights[key] = batchItem;
        });
      }); // Diff.

      var toHighlight = [];
      var toDownplay = [];
      each(lastHighlights, function (batchItem, key) {
        !newHighlights[key] && toDownplay.push(batchItem);
      });
      each(newHighlights, function (batchItem, key) {
        !lastHighlights[key] && toHighlight.push(batchItem);
      });
      toDownplay.length && api.dispatchAction({
        type: 'downplay',
        escapeConnect: true,
        // Not blur others when highlight in axisPointer.
        notBlur: true,
        batch: toDownplay
      });
      toHighlight.length && api.dispatchAction({
        type: 'highlight',
        escapeConnect: true,
        // Not blur others when highlight in axisPointer.
        notBlur: 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]);
    }

    function install$s(registers) {
      // 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.
      AxisView.registerAxisPointerClass('CartesianAxisPointer', CartesianAxisPointer);
      registers.registerComponentModel(AxisPointerModel);
      registers.registerComponentView(AxisPointerView);
      registers.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.

      registers.registerProcessor(registers.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.

      registers.registerAction({
        type: 'updateAxisPointer',
        event: 'updateAxisPointer',
        update: ':updateAxisPointer'
      }, axisTrigger);
    }

    function install$t(registers) {
      use(install$5);
      use(install$s);
    }

    var PolarAxisPointer =
    /** @class */
    function (_super) {
      __extends(PolarAxisPointer, _super);

      function PolarAxisPointer() {
        return _super !== null && _super.apply(this, arguments) || this;
      }
      /**
       * @override
       */


      PolarAxisPointer.prototype.makeElOption = function (elOption, value, axisModel, axisPointerModel, api) {
        var axis = axisModel.axis;

        if (axis.dim === 'angle') {
          this.animationThreshold = Math.PI / 18;
        }

        var polar = axis.polar;
        var otherAxis = polar.getOtherAxis(axis);
        var otherExtent = otherAxis.getExtent();
        var coordValue = axis.dataToCoord(value);
        var axisPointerType = axisPointerModel.get('type');

        if (axisPointerType && axisPointerType !== 'none') {
          var elStyle = buildElStyle(axisPointerModel);
          var pointerOption = pointerShapeBuilder$1[axisPointerType](axis, polar, coordValue, otherExtent);
          pointerOption.style = elStyle;
          elOption.graphicKey = pointerOption.type;
          elOption.pointer = pointerOption;
        }

        var labelMargin = axisPointerModel.get(['label', 'margin']);
        var labelPos = getLabelPosition(value, axisModel, axisPointerModel, polar, labelMargin);
        buildLabelElOption(elOption, axisModel, axisPointerModel, api, labelPos);
      };

      return PolarAxisPointer;
    }(BaseAxisPointer);

    function getLabelPosition(value, axisModel, axisPointerModel, polar, labelMargin) {
      var axis = axisModel.axis;
      var coord = axis.dataToCoord(value);
      var axisAngle = polar.getAngleAxis().getExtent()[0];
      axisAngle = axisAngle / 180 * Math.PI;
      var radiusExtent = polar.getRadiusAxis().getExtent();
      var position;
      var align;
      var verticalAlign;

      if (axis.dim === 'radius') {
        var transform = create$1();
        rotate(transform, transform, axisAngle);
        translate(transform, transform, [polar.cx, polar.cy]);
        position = applyTransform$1([coord, -labelMargin], transform);
        var labelRotation = axisModel.getModel('axisLabel').get('rotate') || 0; // @ts-ignore

        var labelLayout = AxisBuilder.innerTextLayout(axisAngle, labelRotation * Math.PI / 180, -1);
        align = labelLayout.textAlign;
        verticalAlign = labelLayout.textVerticalAlign;
      } else {
        // angle axis
        var r = radiusExtent[1];
        position = polar.coordToPoint([r + labelMargin, coord]);
        var cx = polar.cx;
        var cy = polar.cy;
        align = Math.abs(position[0] - cx) / r < 0.3 ? 'center' : position[0] > cx ? 'left' : 'right';
        verticalAlign = Math.abs(position[1] - cy) / r < 0.3 ? 'middle' : position[1] > cy ? 'top' : 'bottom';
      }

      return {
        position: position,
        align: align,
        verticalAlign: verticalAlign
      };
    }

    var pointerShapeBuilder$1 = {
      line: function (axis, polar, coordValue, otherExtent) {
        return axis.dim === 'angle' ? {
          type: 'Line',
          shape: makeLineShape(polar.coordToPoint([otherExtent[0], coordValue]), polar.coordToPoint([otherExtent[1], coordValue]))
        } : {
          type: 'Circle',
          shape: {
            cx: polar.cx,
            cy: polar.cy,
            r: coordValue
          }
        };
      },
      shadow: function (axis, polar, coordValue, otherExtent) {
        var bandWidth = Math.max(1, axis.getBandWidth());
        var radian = Math.PI / 180;
        return axis.dim === 'angle' ? {
          type: 'Sector',
          shape: makeSectorShape(polar.cx, polar.cy, otherExtent[0], otherExtent[1], // In ECharts y is negative if angle is positive
          (-coordValue - bandWidth / 2) * radian, (-coordValue + bandWidth / 2) * radian)
        } : {
          type: 'Sector',
          shape: makeSectorShape(polar.cx, polar.cy, coordValue - bandWidth / 2, coordValue + bandWidth / 2, 0, Math.PI * 2)
        };
      }
    };

    var PolarModel =
    /** @class */
    function (_super) {
      __extends(PolarModel, _super);

      function PolarModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = PolarModel.type;
        return _this;
      }

      PolarModel.prototype.findAxisModel = function (axisType) {
        var foundAxisModel;
        var ecModel = this.ecModel;
        ecModel.eachComponent(axisType, function (axisModel) {
          if (axisModel.getCoordSysModel() === this) {
            foundAxisModel = axisModel;
          }
        }, this);
        return foundAxisModel;
      };

      PolarModel.type = 'polar';
      PolarModel.dependencies = ['radiusAxis', 'angleAxis'];
      PolarModel.defaultOption = {
        // zlevel: 0,
        z: 0,
        center: ['50%', '50%'],
        radius: '80%'
      };
      return PolarModel;
    }(ComponentModel);

    var PolarAxisModel =
    /** @class */
    function (_super) {
      __extends(PolarAxisModel, _super);

      function PolarAxisModel() {
        return _super !== null && _super.apply(this, arguments) || this;
      }

      PolarAxisModel.prototype.getCoordSysModel = function () {
        return this.getReferringComponents('polar', SINGLE_REFERRING).models[0];
      };

      PolarAxisModel.type = 'polarAxis';
      return PolarAxisModel;
    }(ComponentModel);

    mixin(PolarAxisModel, AxisModelCommonMixin);

    var AngleAxisModel =
    /** @class */
    function (_super) {
      __extends(AngleAxisModel, _super);

      function AngleAxisModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = AngleAxisModel.type;
        return _this;
      }

      AngleAxisModel.type = 'angleAxis';
      return AngleAxisModel;
    }(PolarAxisModel);

    var RadiusAxisModel =
    /** @class */
    function (_super) {
      __extends(RadiusAxisModel, _super);

      function RadiusAxisModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = RadiusAxisModel.type;
        return _this;
      }

      RadiusAxisModel.type = 'radiusAxis';
      return RadiusAxisModel;
    }(PolarAxisModel);

    var RadiusAxis =
    /** @class */
    function (_super) {
      __extends(RadiusAxis, _super);

      function RadiusAxis(scale, radiusExtent) {
        return _super.call(this, 'radius', scale, radiusExtent) || this;
      }

      RadiusAxis.prototype.pointToData = function (point, clamp) {
        return this.polar.pointToData(point, clamp)[this.dim === 'radius' ? 0 : 1];
      };

      return RadiusAxis;
    }(Axis);

    RadiusAxis.prototype.dataToRadius = Axis.prototype.dataToCoord;
    RadiusAxis.prototype.radiusToData = Axis.prototype.coordToData;

    var inner$d = makeInner();

    var AngleAxis =
    /** @class */
    function (_super) {
      __extends(AngleAxis, _super);

      function AngleAxis(scale, angleExtent) {
        return _super.call(this, 'angle', scale, angleExtent || [0, 360]) || this;
      }

      AngleAxis.prototype.pointToData = function (point, clamp) {
        return this.polar.pointToData(point, clamp)[this.dim === 'radius' ? 0 : 1];
      };
      /**
       * Only be called in category axis.
       * Angle axis uses text height to decide interval
       *
       * @override
       * @return {number} Auto interval for cateogry axis tick and label
       */


      AngleAxis.prototype.calculateCategoryInterval = function () {
        var axis = this;
        var labelModel = axis.getLabelModel();
        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 tickValue = ordinalExtent[0];
        var unitSpan = axis.dataToCoord(tickValue + 1) - axis.dataToCoord(tickValue);
        var unitH = Math.abs(unitSpan); // Not precise, just use height as text width
        // and each distance from axis line yet.

        var rect = getBoundingRect(tickValue == null ? '' : tickValue + '', labelModel.getFont(), 'center', 'top');
        var maxH = Math.max(rect.height, 7);
        var dh = maxH / unitH; // 0/0 is NaN, 1/0 is Infinity.

        isNaN(dh) && (dh = Infinity);
        var interval = Math.max(0, Math.floor(dh));
        var cache = inner$d(axis.model);
        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.

        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) {
          interval = lastAutoInterval;
        } // Only update cache if cache not used, otherwise the
        // changing of interval is too insensitive.
        else {
            cache.lastTickCount = tickCount;
            cache.lastAutoInterval = interval;
          }

        return interval;
      };

      return AngleAxis;
    }(Axis);

    AngleAxis.prototype.dataToAngle = Axis.prototype.dataToCoord;
    AngleAxis.prototype.angleToData = Axis.prototype.coordToData;

    var polarDimensions = ['radius', 'angle'];

    var Polar =
    /** @class */
    function () {
      function Polar(name) {
        this.dimensions = polarDimensions;
        this.type = 'polar';
        /**
         * x of polar center
         */

        this.cx = 0;
        /**
         * y of polar center
         */

        this.cy = 0;
        this._radiusAxis = new RadiusAxis();
        this._angleAxis = new AngleAxis();
        this.axisPointerEnabled = true;
        this.name = name || '';
        this._radiusAxis.polar = this._angleAxis.polar = this;
      }
      /**
       * If contain coord
       */


      Polar.prototype.containPoint = function (point) {
        var coord = this.pointToCoord(point);
        return this._radiusAxis.contain(coord[0]) && this._angleAxis.contain(coord[1]);
      };
      /**
       * If contain data
       */


      Polar.prototype.containData = function (data) {
        return this._radiusAxis.containData(data[0]) && this._angleAxis.containData(data[1]);
      };

      Polar.prototype.getAxis = function (dim) {
        var key = '_' + dim + 'Axis';
        return this[key];
      };

      Polar.prototype.getAxes = function () {
        return [this._radiusAxis, this._angleAxis];
      };
      /**
       * Get axes by type of scale
       */


      Polar.prototype.getAxesByScale = function (scaleType) {
        var axes = [];
        var angleAxis = this._angleAxis;
        var radiusAxis = this._radiusAxis;
        angleAxis.scale.type === scaleType && axes.push(angleAxis);
        radiusAxis.scale.type === scaleType && axes.push(radiusAxis);
        return axes;
      };

      Polar.prototype.getAngleAxis = function () {
        return this._angleAxis;
      };

      Polar.prototype.getRadiusAxis = function () {
        return this._radiusAxis;
      };

      Polar.prototype.getOtherAxis = function (axis) {
        var angleAxis = this._angleAxis;
        return axis === angleAxis ? this._radiusAxis : angleAxis;
      };
      /**
       * Base axis will be used on stacking.
       *
       */


      Polar.prototype.getBaseAxis = function () {
        return this.getAxesByScale('ordinal')[0] || this.getAxesByScale('time')[0] || this.getAngleAxis();
      };

      Polar.prototype.getTooltipAxes = function (dim) {
        var baseAxis = dim != null && dim !== 'auto' ? this.getAxis(dim) : this.getBaseAxis();
        return {
          baseAxes: [baseAxis],
          otherAxes: [this.getOtherAxis(baseAxis)]
        };
      };
      /**
       * Convert a single data item to (x, y) point.
       * Parameter data is an array which the first element is radius and the second is angle
       */


      Polar.prototype.dataToPoint = function (data, clamp) {
        return this.coordToPoint([this._radiusAxis.dataToRadius(data[0], clamp), this._angleAxis.dataToAngle(data[1], clamp)]);
      };
      /**
       * Convert a (x, y) point to data
       */


      Polar.prototype.pointToData = function (point, clamp) {
        var coord = this.pointToCoord(point);
        return [this._radiusAxis.radiusToData(coord[0], clamp), this._angleAxis.angleToData(coord[1], clamp)];
      };
      /**
       * Convert a (x, y) point to (radius, angle) coord
       */


      Polar.prototype.pointToCoord = function (point) {
        var dx = point[0] - this.cx;
        var dy = point[1] - this.cy;
        var angleAxis = this.getAngleAxis();
        var extent = angleAxis.getExtent();
        var minAngle = Math.min(extent[0], extent[1]);
        var maxAngle = Math.max(extent[0], extent[1]); // Fix fixed extent in polarCreator
        // FIXME

        angleAxis.inverse ? minAngle = maxAngle - 360 : maxAngle = minAngle + 360;
        var radius = Math.sqrt(dx * dx + dy * dy);
        dx /= radius;
        dy /= radius;
        var radian = Math.atan2(-dy, dx) / Math.PI * 180; // move to angleExtent

        var dir = radian < minAngle ? 1 : -1;

        while (radian < minAngle || radian > maxAngle) {
          radian += dir * 360;
        }

        return [radius, radian];
      };
      /**
       * Convert a (radius, angle) coord to (x, y) point
       */


      Polar.prototype.coordToPoint = function (coord) {
        var radius = coord[0];
        var radian = coord[1] / 180 * Math.PI;
        var x = Math.cos(radian) * radius + this.cx; // Inverse the y

        var y = -Math.sin(radian) * radius + this.cy;
        return [x, y];
      };
      /**
       * Get ring area of cartesian.
       * Area will have a contain function to determine if a point is in the coordinate system.
       */


      Polar.prototype.getArea = function () {
        var angleAxis = this.getAngleAxis();
        var radiusAxis = this.getRadiusAxis();
        var radiusExtent = radiusAxis.getExtent().slice();
        radiusExtent[0] > radiusExtent[1] && radiusExtent.reverse();
        var angleExtent = angleAxis.getExtent();
        var RADIAN = Math.PI / 180;
        return {
          cx: this.cx,
          cy: this.cy,
          r0: radiusExtent[0],
          r: radiusExtent[1],
          startAngle: -angleExtent[0] * RADIAN,
          endAngle: -angleExtent[1] * RADIAN,
          clockwise: angleAxis.inverse,
          contain: function (x, y) {
            // It's a ring shape.
            // Start angle and end angle don't matter
            var dx = x - this.cx;
            var dy = y - this.cy; // minus a tiny value 1e-4 to avoid being clipped unexpectedly

            var d2 = dx * dx + dy * dy - 1e-4;
            var r = this.r;
            var r0 = this.r0;
            return d2 <= r * r && d2 >= r0 * r0;
          }
        };
      };

      Polar.prototype.convertToPixel = function (ecModel, finder, value) {
        var coordSys = getCoordSys$2(finder);
        return coordSys === this ? this.dataToPoint(value) : null;
      };

      Polar.prototype.convertFromPixel = function (ecModel, finder, pixel) {
        var coordSys = getCoordSys$2(finder);
        return coordSys === this ? this.pointToData(pixel) : null;
      };

      return Polar;
    }();

    function getCoordSys$2(finder) {
      var seriesModel = finder.seriesModel;
      var polarModel = finder.polarModel;
      return polarModel && polarModel.coordinateSystem || seriesModel && seriesModel.coordinateSystem;
    }

    /**
     * Resize method bound to the polar
     */

    function resizePolar(polar, polarModel, api) {
      var center = polarModel.get('center');
      var width = api.getWidth();
      var height = api.getHeight();
      polar.cx = parsePercent$1(center[0], width);
      polar.cy = parsePercent$1(center[1], height);
      var radiusAxis = polar.getRadiusAxis();
      var size = Math.min(width, height) / 2;
      var radius = polarModel.get('radius');

      if (radius == null) {
        radius = [0, '100%'];
      } else if (!isArray(radius)) {
        // r0 = 0
        radius = [0, radius];
      }

      var parsedRadius = [parsePercent$1(radius[0], size), parsePercent$1(radius[1], size)];
      radiusAxis.inverse ? radiusAxis.setExtent(parsedRadius[1], parsedRadius[0]) : radiusAxis.setExtent(parsedRadius[0], parsedRadius[1]);
    }
    /**
     * Update polar
     */


    function updatePolarScale(ecModel, api) {
      var polar = this;
      var angleAxis = polar.getAngleAxis();
      var radiusAxis = polar.getRadiusAxis(); // Reset scale

      angleAxis.scale.setExtent(Infinity, -Infinity);
      radiusAxis.scale.setExtent(Infinity, -Infinity);
      ecModel.eachSeries(function (seriesModel) {
        if (seriesModel.coordinateSystem === polar) {
          var data_1 = seriesModel.getData();
          each(getDataDimensionsOnAxis(data_1, 'radius'), function (dim) {
            radiusAxis.scale.unionExtentFromData(data_1, dim);
          });
          each(getDataDimensionsOnAxis(data_1, 'angle'), function (dim) {
            angleAxis.scale.unionExtentFromData(data_1, dim);
          });
        }
      });
      niceScaleExtent(angleAxis.scale, angleAxis.model);
      niceScaleExtent(radiusAxis.scale, radiusAxis.model); // Fix extent of category angle axis

      if (angleAxis.type === 'category' && !angleAxis.onBand) {
        var extent = angleAxis.getExtent();
        var diff = 360 / angleAxis.scale.count();
        angleAxis.inverse ? extent[1] += diff : extent[1] -= diff;
        angleAxis.setExtent(extent[0], extent[1]);
      }
    }

    function isAngleAxisModel(axisModel) {
      return axisModel.mainType === 'angleAxis';
    }
    /**
     * Set common axis properties
     */


    function setAxis(axis, axisModel) {
      axis.type = axisModel.get('type');
      axis.scale = createScaleByModel(axisModel);
      axis.onBand = axisModel.get('boundaryGap') && axis.type === 'category';
      axis.inverse = axisModel.get('inverse');

      if (isAngleAxisModel(axisModel)) {
        axis.inverse = axis.inverse !== axisModel.get('clockwise');
        var startAngle = axisModel.get('startAngle');
        axis.setExtent(startAngle, startAngle + (axis.inverse ? -360 : 360));
      } // Inject axis instance


      axisModel.axis = axis;
      axis.model = axisModel;
    }

    var polarCreator = {
      dimensions: polarDimensions,
      create: function (ecModel, api) {
        var polarList = [];
        ecModel.eachComponent('polar', function (polarModel, idx) {
          var polar = new Polar(idx + ''); // Inject resize and update method

          polar.update = updatePolarScale;
          var radiusAxis = polar.getRadiusAxis();
          var angleAxis = polar.getAngleAxis();
          var radiusAxisModel = polarModel.findAxisModel('radiusAxis');
          var angleAxisModel = polarModel.findAxisModel('angleAxis');
          setAxis(radiusAxis, radiusAxisModel);
          setAxis(angleAxis, angleAxisModel);
          resizePolar(polar, polarModel, api);
          polarList.push(polar);
          polarModel.coordinateSystem = polar;
          polar.model = polarModel;
        }); // Inject coordinateSystem to series

        ecModel.eachSeries(function (seriesModel) {
          if (seriesModel.get('coordinateSystem') === 'polar') {
            var polarModel = seriesModel.getReferringComponents('polar', SINGLE_REFERRING).models[0];

            if ("development" !== 'production') {
              if (!polarModel) {
                throw new Error('Polar "' + retrieve(seriesModel.get('polarIndex'), seriesModel.get('polarId'), 0) + '" not found');
              }
            }

            seriesModel.coordinateSystem = polarModel.coordinateSystem;
          }
        });
        return polarList;
      }
    };

    var elementList$1 = ['axisLine', 'axisLabel', 'axisTick', 'minorTick', 'splitLine', 'minorSplitLine', 'splitArea'];

    function getAxisLineShape(polar, rExtent, angle) {
      rExtent[1] > rExtent[0] && (rExtent = rExtent.slice().reverse());
      var start = polar.coordToPoint([rExtent[0], angle]);
      var end = polar.coordToPoint([rExtent[1], angle]);
      return {
        x1: start[0],
        y1: start[1],
        x2: end[0],
        y2: end[1]
      };
    }

    function getRadiusIdx(polar) {
      var radiusAxis = polar.getRadiusAxis();
      return radiusAxis.inverse ? 0 : 1;
    } // Remove the last tick which will overlap the first tick


    function fixAngleOverlap(list) {
      var firstItem = list[0];
      var lastItem = list[list.length - 1];

      if (firstItem && lastItem && Math.abs(Math.abs(firstItem.coord - lastItem.coord) - 360) < 1e-4) {
        list.pop();
      }
    }

    var AngleAxisView =
    /** @class */
    function (_super) {
      __extends(AngleAxisView, _super);

      function AngleAxisView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = AngleAxisView.type;
        _this.axisPointerClass = 'PolarAxisPointer';
        return _this;
      }

      AngleAxisView.prototype.render = function (angleAxisModel, ecModel) {
        this.group.removeAll();

        if (!angleAxisModel.get('show')) {
          return;
        }

        var angleAxis = angleAxisModel.axis;
        var polar = angleAxis.polar;
        var radiusExtent = polar.getRadiusAxis().getExtent();
        var ticksAngles = angleAxis.getTicksCoords();
        var minorTickAngles = angleAxis.getMinorTicksCoords();
        var labels = map(angleAxis.getViewLabels(), function (labelItem) {
          labelItem = clone(labelItem);
          var scale = angleAxis.scale;
          var tickValue = scale.type === 'ordinal' ? scale.getRawOrdinalNumber(labelItem.tickValue) : labelItem.tickValue;
          labelItem.coord = angleAxis.dataToCoord(tickValue);
          return labelItem;
        });
        fixAngleOverlap(labels);
        fixAngleOverlap(ticksAngles);
        each(elementList$1, function (name) {
          if (angleAxisModel.get([name, 'show']) && (!angleAxis.scale.isBlank() || name === 'axisLine')) {
            angelAxisElementsBuilders[name](this.group, angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent, labels);
          }
        }, this);
      };

      AngleAxisView.type = 'angleAxis';
      return AngleAxisView;
    }(AxisView);

    var angelAxisElementsBuilders = {
      axisLine: function (group, angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent) {
        var lineStyleModel = angleAxisModel.getModel(['axisLine', 'lineStyle']); // extent id of the axis radius (r0 and r)

        var rId = getRadiusIdx(polar);
        var r0Id = rId ? 0 : 1;
        var shape;

        if (radiusExtent[r0Id] === 0) {
          shape = new Circle({
            shape: {
              cx: polar.cx,
              cy: polar.cy,
              r: radiusExtent[rId]
            },
            style: lineStyleModel.getLineStyle(),
            z2: 1,
            silent: true
          });
        } else {
          shape = new Ring({
            shape: {
              cx: polar.cx,
              cy: polar.cy,
              r: radiusExtent[rId],
              r0: radiusExtent[r0Id]
            },
            style: lineStyleModel.getLineStyle(),
            z2: 1,
            silent: true
          });
        }

        shape.style.fill = null;
        group.add(shape);
      },
      axisTick: function (group, angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent) {
        var tickModel = angleAxisModel.getModel('axisTick');
        var tickLen = (tickModel.get('inside') ? -1 : 1) * tickModel.get('length');
        var radius = radiusExtent[getRadiusIdx(polar)];
        var lines = map(ticksAngles, function (tickAngleItem) {
          return new Line({
            shape: getAxisLineShape(polar, [radius, radius + tickLen], tickAngleItem.coord)
          });
        });
        group.add(mergePath$1(lines, {
          style: defaults(tickModel.getModel('lineStyle').getLineStyle(), {
            stroke: angleAxisModel.get(['axisLine', 'lineStyle', 'color'])
          })
        }));
      },
      minorTick: function (group, angleAxisModel, polar, tickAngles, minorTickAngles, radiusExtent) {
        if (!minorTickAngles.length) {
          return;
        }

        var tickModel = angleAxisModel.getModel('axisTick');
        var minorTickModel = angleAxisModel.getModel('minorTick');
        var tickLen = (tickModel.get('inside') ? -1 : 1) * minorTickModel.get('length');
        var radius = radiusExtent[getRadiusIdx(polar)];
        var lines = [];

        for (var i = 0; i < minorTickAngles.length; i++) {
          for (var k = 0; k < minorTickAngles[i].length; k++) {
            lines.push(new Line({
              shape: getAxisLineShape(polar, [radius, radius + tickLen], minorTickAngles[i][k].coord)
            }));
          }
        }

        group.add(mergePath$1(lines, {
          style: defaults(minorTickModel.getModel('lineStyle').getLineStyle(), defaults(tickModel.getLineStyle(), {
            stroke: angleAxisModel.get(['axisLine', 'lineStyle', 'color'])
          }))
        }));
      },
      axisLabel: function (group, angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent, labels) {
        var rawCategoryData = angleAxisModel.getCategories(true);
        var commonLabelModel = angleAxisModel.getModel('axisLabel');
        var labelMargin = commonLabelModel.get('margin');
        var triggerEvent = angleAxisModel.get('triggerEvent'); // Use length of ticksAngles because it may remove the last tick to avoid overlapping

        each(labels, function (labelItem, idx) {
          var labelModel = commonLabelModel;
          var tickValue = labelItem.tickValue;
          var r = radiusExtent[getRadiusIdx(polar)];
          var p = polar.coordToPoint([r + labelMargin, labelItem.coord]);
          var cx = polar.cx;
          var cy = polar.cy;
          var labelTextAlign = Math.abs(p[0] - cx) / r < 0.3 ? 'center' : p[0] > cx ? 'left' : 'right';
          var labelTextVerticalAlign = Math.abs(p[1] - cy) / r < 0.3 ? 'middle' : p[1] > cy ? 'top' : 'bottom';

          if (rawCategoryData && rawCategoryData[tickValue]) {
            var rawCategoryItem = rawCategoryData[tickValue];

            if (isObject(rawCategoryItem) && rawCategoryItem.textStyle) {
              labelModel = new Model(rawCategoryItem.textStyle, commonLabelModel, commonLabelModel.ecModel);
            }
          }

          var textEl = new ZRText({
            silent: AxisBuilder.isLabelSilent(angleAxisModel),
            style: createTextStyle(labelModel, {
              x: p[0],
              y: p[1],
              fill: labelModel.getTextColor() || angleAxisModel.get(['axisLine', 'lineStyle', 'color']),
              text: labelItem.formattedLabel,
              align: labelTextAlign,
              verticalAlign: labelTextVerticalAlign
            })
          });
          group.add(textEl); // Pack data for mouse event

          if (triggerEvent) {
            var eventData = AxisBuilder.makeAxisEventDataBase(angleAxisModel);
            eventData.targetType = 'axisLabel';
            eventData.value = labelItem.rawLabel;
            getECData(textEl).eventData = eventData;
          }
        }, this);
      },
      splitLine: function (group, angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent) {
        var splitLineModel = angleAxisModel.getModel('splitLine');
        var lineStyleModel = splitLineModel.getModel('lineStyle');
        var lineColors = lineStyleModel.get('color');
        var lineCount = 0;
        lineColors = lineColors instanceof Array ? lineColors : [lineColors];
        var splitLines = [];

        for (var i = 0; i < ticksAngles.length; i++) {
          var colorIndex = lineCount++ % lineColors.length;
          splitLines[colorIndex] = splitLines[colorIndex] || [];
          splitLines[colorIndex].push(new Line({
            shape: getAxisLineShape(polar, radiusExtent, ticksAngles[i].coord)
          }));
        } // Simple optimization
        // Batching the lines if color are the same


        for (var i = 0; i < splitLines.length; i++) {
          group.add(mergePath$1(splitLines[i], {
            style: defaults({
              stroke: lineColors[i % lineColors.length]
            }, lineStyleModel.getLineStyle()),
            silent: true,
            z: angleAxisModel.get('z')
          }));
        }
      },
      minorSplitLine: function (group, angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent) {
        if (!minorTickAngles.length) {
          return;
        }

        var minorSplitLineModel = angleAxisModel.getModel('minorSplitLine');
        var lineStyleModel = minorSplitLineModel.getModel('lineStyle');
        var lines = [];

        for (var i = 0; i < minorTickAngles.length; i++) {
          for (var k = 0; k < minorTickAngles[i].length; k++) {
            lines.push(new Line({
              shape: getAxisLineShape(polar, radiusExtent, minorTickAngles[i][k].coord)
            }));
          }
        }

        group.add(mergePath$1(lines, {
          style: lineStyleModel.getLineStyle(),
          silent: true,
          z: angleAxisModel.get('z')
        }));
      },
      splitArea: function (group, angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent) {
        if (!ticksAngles.length) {
          return;
        }

        var splitAreaModel = angleAxisModel.getModel('splitArea');
        var areaStyleModel = splitAreaModel.getModel('areaStyle');
        var areaColors = areaStyleModel.get('color');
        var lineCount = 0;
        areaColors = areaColors instanceof Array ? areaColors : [areaColors];
        var splitAreas = [];
        var RADIAN = Math.PI / 180;
        var prevAngle = -ticksAngles[0].coord * RADIAN;
        var r0 = Math.min(radiusExtent[0], radiusExtent[1]);
        var r1 = Math.max(radiusExtent[0], radiusExtent[1]);
        var clockwise = angleAxisModel.get('clockwise');

        for (var i = 1, len = ticksAngles.length; i <= len; i++) {
          var coord = i === len ? ticksAngles[0].coord : ticksAngles[i].coord;
          var colorIndex = lineCount++ % areaColors.length;
          splitAreas[colorIndex] = splitAreas[colorIndex] || [];
          splitAreas[colorIndex].push(new Sector({
            shape: {
              cx: polar.cx,
              cy: polar.cy,
              r0: r0,
              r: r1,
              startAngle: prevAngle,
              endAngle: -coord * RADIAN,
              clockwise: clockwise
            },
            silent: true
          }));
          prevAngle = -coord * RADIAN;
        } // Simple optimization
        // Batching the lines if color are the same


        for (var i = 0; i < splitAreas.length; i++) {
          group.add(mergePath$1(splitAreas[i], {
            style: defaults({
              fill: areaColors[i % areaColors.length]
            }, areaStyleModel.getAreaStyle()),
            silent: true
          }));
        }
      }
    };

    var axisBuilderAttrs$2 = ['axisLine', 'axisTickLabel', 'axisName'];
    var selfBuilderAttrs$1 = ['splitLine', 'splitArea', 'minorSplitLine'];

    var RadiusAxisView =
    /** @class */
    function (_super) {
      __extends(RadiusAxisView, _super);

      function RadiusAxisView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = RadiusAxisView.type;
        _this.axisPointerClass = 'PolarAxisPointer';
        return _this;
      }

      RadiusAxisView.prototype.render = function (radiusAxisModel, ecModel) {
        this.group.removeAll();

        if (!radiusAxisModel.get('show')) {
          return;
        }

        var oldAxisGroup = this._axisGroup;
        var newAxisGroup = this._axisGroup = new Group();
        this.group.add(newAxisGroup);
        var radiusAxis = radiusAxisModel.axis;
        var polar = radiusAxis.polar;
        var angleAxis = polar.getAngleAxis();
        var ticksCoords = radiusAxis.getTicksCoords();
        var minorTicksCoords = radiusAxis.getMinorTicksCoords();
        var axisAngle = angleAxis.getExtent()[0];
        var radiusExtent = radiusAxis.getExtent();
        var layout = layoutAxis(polar, radiusAxisModel, axisAngle);
        var axisBuilder = new AxisBuilder(radiusAxisModel, layout);
        each(axisBuilderAttrs$2, axisBuilder.add, axisBuilder);
        newAxisGroup.add(axisBuilder.getGroup());
        groupTransition(oldAxisGroup, newAxisGroup, radiusAxisModel);
        each(selfBuilderAttrs$1, function (name) {
          if (radiusAxisModel.get([name, 'show']) && !radiusAxis.scale.isBlank()) {
            axisElementBuilders$1[name](this.group, radiusAxisModel, polar, axisAngle, radiusExtent, ticksCoords, minorTicksCoords);
          }
        }, this);
      };

      RadiusAxisView.type = 'radiusAxis';
      return RadiusAxisView;
    }(AxisView);

    var axisElementBuilders$1 = {
      splitLine: function (group, radiusAxisModel, polar, axisAngle, radiusExtent, ticksCoords) {
        var splitLineModel = radiusAxisModel.getModel('splitLine');
        var lineStyleModel = splitLineModel.getModel('lineStyle');
        var lineColors = lineStyleModel.get('color');
        var lineCount = 0;
        lineColors = lineColors instanceof Array ? lineColors : [lineColors];
        var splitLines = [];

        for (var i = 0; i < ticksCoords.length; i++) {
          var colorIndex = lineCount++ % lineColors.length;
          splitLines[colorIndex] = splitLines[colorIndex] || [];
          splitLines[colorIndex].push(new Circle({
            shape: {
              cx: polar.cx,
              cy: polar.cy,
              // ensure circle radius >= 0
              r: Math.max(ticksCoords[i].coord, 0)
            }
          }));
        } // Simple optimization
        // Batching the lines if color are the same


        for (var i = 0; i < splitLines.length; i++) {
          group.add(mergePath$1(splitLines[i], {
            style: defaults({
              stroke: lineColors[i % lineColors.length],
              fill: null
            }, lineStyleModel.getLineStyle()),
            silent: true
          }));
        }
      },
      minorSplitLine: function (group, radiusAxisModel, polar, axisAngle, radiusExtent, ticksCoords, minorTicksCoords) {
        if (!minorTicksCoords.length) {
          return;
        }

        var minorSplitLineModel = radiusAxisModel.getModel('minorSplitLine');
        var lineStyleModel = minorSplitLineModel.getModel('lineStyle');
        var lines = [];

        for (var i = 0; i < minorTicksCoords.length; i++) {
          for (var k = 0; k < minorTicksCoords[i].length; k++) {
            lines.push(new Circle({
              shape: {
                cx: polar.cx,
                cy: polar.cy,
                r: minorTicksCoords[i][k].coord
              }
            }));
          }
        }

        group.add(mergePath$1(lines, {
          style: defaults({
            fill: null
          }, lineStyleModel.getLineStyle()),
          silent: true
        }));
      },
      splitArea: function (group, radiusAxisModel, polar, axisAngle, radiusExtent, ticksCoords) {
        if (!ticksCoords.length) {
          return;
        }

        var splitAreaModel = radiusAxisModel.getModel('splitArea');
        var areaStyleModel = splitAreaModel.getModel('areaStyle');
        var areaColors = areaStyleModel.get('color');
        var lineCount = 0;
        areaColors = areaColors instanceof Array ? areaColors : [areaColors];
        var splitAreas = [];
        var prevRadius = ticksCoords[0].coord;

        for (var i = 1; i < ticksCoords.length; i++) {
          var colorIndex = lineCount++ % areaColors.length;
          splitAreas[colorIndex] = splitAreas[colorIndex] || [];
          splitAreas[colorIndex].push(new Sector({
            shape: {
              cx: polar.cx,
              cy: polar.cy,
              r0: prevRadius,
              r: ticksCoords[i].coord,
              startAngle: 0,
              endAngle: Math.PI * 2
            },
            silent: true
          }));
          prevRadius = ticksCoords[i].coord;
        } // Simple optimization
        // Batching the lines if color are the same


        for (var i = 0; i < splitAreas.length; i++) {
          group.add(mergePath$1(splitAreas[i], {
            style: defaults({
              fill: areaColors[i % areaColors.length]
            }, areaStyleModel.getAreaStyle()),
            silent: true
          }));
        }
      }
    };
    /**
     * @inner
     */

    function layoutAxis(polar, radiusAxisModel, axisAngle) {
      return {
        position: [polar.cx, polar.cy],
        rotation: axisAngle / 180 * Math.PI,
        labelDirection: -1,
        tickDirection: -1,
        nameDirection: 1,
        labelRotate: radiusAxisModel.getModel('axisLabel').get('rotate'),
        // Over splitLine and splitArea
        z2: 1
      };
    }

    function getSeriesStackId$1(seriesModel) {
      return seriesModel.get('stack') || '__ec_stack_' + seriesModel.seriesIndex;
    }

    function getAxisKey$1(polar, axis) {
      return axis.dim + polar.model.componentIndex;
    }

    function barLayoutPolar(seriesType, ecModel, api) {
      var lastStackCoords = {};
      var barWidthAndOffset = calRadialBar(filter(ecModel.getSeriesByType(seriesType), function (seriesModel) {
        return !ecModel.isSeriesFiltered(seriesModel) && seriesModel.coordinateSystem && seriesModel.coordinateSystem.type === 'polar';
      }));
      ecModel.eachSeriesByType(seriesType, function (seriesModel) {
        // Check series coordinate, do layout for polar only
        if (seriesModel.coordinateSystem.type !== 'polar') {
          return;
        }

        var data = seriesModel.getData();
        var polar = seriesModel.coordinateSystem;
        var baseAxis = polar.getBaseAxis();
        var axisKey = getAxisKey$1(polar, baseAxis);
        var stackId = getSeriesStackId$1(seriesModel);
        var columnLayoutInfo = barWidthAndOffset[axisKey][stackId];
        var columnOffset = columnLayoutInfo.offset;
        var columnWidth = columnLayoutInfo.width;
        var valueAxis = polar.getOtherAxis(baseAxis);
        var cx = seriesModel.coordinateSystem.cx;
        var cy = seriesModel.coordinateSystem.cy;
        var barMinHeight = seriesModel.get('barMinHeight') || 0;
        var barMinAngle = seriesModel.get('barMinAngle') || 0;
        lastStackCoords[stackId] = lastStackCoords[stackId] || [];
        var valueDim = data.mapDimension(valueAxis.dim);
        var baseDim = data.mapDimension(baseAxis.dim);
        var stacked = isDimensionStacked(data, valueDim
        /* , baseDim */
        );
        var clampLayout = baseAxis.dim !== 'radius' || !seriesModel.get('roundCap', true);
        var valueAxisStart = valueAxis.dataToCoord(0);

        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.
          // Only ordinal axis can be stacked.

          if (stacked) {
            if (!lastStackCoords[stackId][baseValue]) {
              lastStackCoords[stackId][baseValue] = {
                p: valueAxisStart,
                n: valueAxisStart // Negative stack

              };
            } // Should also consider #4243


            baseCoord = lastStackCoords[stackId][baseValue][sign];
          }

          var r0 = void 0;
          var r = void 0;
          var startAngle = void 0;
          var endAngle = void 0; // radial sector

          if (valueAxis.dim === 'radius') {
            var radiusSpan = valueAxis.dataToCoord(value) - valueAxisStart;
            var angle = baseAxis.dataToCoord(baseValue);

            if (Math.abs(radiusSpan) < barMinHeight) {
              radiusSpan = (radiusSpan < 0 ? -1 : 1) * barMinHeight;
            }

            r0 = baseCoord;
            r = baseCoord + radiusSpan;
            startAngle = angle - columnOffset;
            endAngle = startAngle - columnWidth;
            stacked && (lastStackCoords[stackId][baseValue][sign] = r);
          } // tangential sector
          else {
              var angleSpan = valueAxis.dataToCoord(value, clampLayout) - valueAxisStart;
              var radius = baseAxis.dataToCoord(baseValue);

              if (Math.abs(angleSpan) < barMinAngle) {
                angleSpan = (angleSpan < 0 ? -1 : 1) * barMinAngle;
              }

              r0 = radius + columnOffset;
              r = r0 + columnWidth;
              startAngle = baseCoord;
              endAngle = baseCoord + angleSpan; // if the previous stack is at the end of the ring,
              // add a round to differentiate it from origin
              // let extent = angleAxis.getExtent();
              // let stackCoord = angle;
              // if (stackCoord === extent[0] && value > 0) {
              //     stackCoord = extent[1];
              // }
              // else if (stackCoord === extent[1] && value < 0) {
              //     stackCoord = extent[0];
              // }

              stacked && (lastStackCoords[stackId][baseValue][sign] = endAngle);
            }

          data.setItemLayout(idx, {
            cx: cx,
            cy: cy,
            r0: r0,
            r: r,
            // Consider that positive angle is anti-clockwise,
            // while positive radian of sector is clockwise
            startAngle: -startAngle * Math.PI / 180,
            endAngle: -endAngle * Math.PI / 180,

            /**
             * 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.
             */
            clockwise: startAngle >= endAngle
          });
        }
      });
    }
    /**
     * Calculate bar width and offset for radial bar charts
     */


    function calRadialBar(barSeries) {
      // Columns info on each category axis. Key is polar name
      var columnsMap = {};
      each(barSeries, function (seriesModel, idx) {
        var data = seriesModel.getData();
        var polar = seriesModel.coordinateSystem;
        var baseAxis = polar.getBaseAxis();
        var axisKey = getAxisKey$1(polar, baseAxis);
        var axisExtent = baseAxis.getExtent();
        var bandWidth = baseAxis.type === 'category' ? baseAxis.getBandWidth() : Math.abs(axisExtent[1] - axisExtent[0]) / data.count();
        var columnsOnAxis = columnsMap[axisKey] || {
          bandWidth: bandWidth,
          remainedWidth: bandWidth,
          autoWidthCount: 0,
          categoryGap: '20%',
          gap: '30%',
          stacks: {}
        };
        var stacks = columnsOnAxis.stacks;
        columnsMap[axisKey] = columnsOnAxis;
        var stackId = getSeriesStackId$1(seriesModel);

        if (!stacks[stackId]) {
          columnsOnAxis.autoWidthCount++;
        }

        stacks[stackId] = stacks[stackId] || {
          width: 0,
          maxWidth: 0
        };
        var barWidth = parsePercent$1(seriesModel.get('barWidth'), bandWidth);
        var barMaxWidth = parsePercent$1(seriesModel.get('barMaxWidth'), bandWidth);
        var barGap = seriesModel.get('barGap');
        var barCategoryGap = seriesModel.get('barCategoryGap');

        if (barWidth && !stacks[stackId].width) {
          barWidth = Math.min(columnsOnAxis.remainedWidth, barWidth);
          stacks[stackId].width = barWidth;
          columnsOnAxis.remainedWidth -= barWidth;
        }

        barMaxWidth && (stacks[stackId].maxWidth = barMaxWidth);
        barGap != null && (columnsOnAxis.gap = barGap);
        barCategoryGap != null && (columnsOnAxis.categoryGap = barCategoryGap);
      });
      var result = {};
      each(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(stacks, function (column, stack) {
          var maxWidth = column.maxWidth;

          if (maxWidth && maxWidth < autoWidth) {
            maxWidth = Math.min(maxWidth, remainedWidth);

            if (column.width) {
              maxWidth = Math.min(maxWidth, column.width);
            }

            remainedWidth -= maxWidth;
            column.width = maxWidth;
            autoWidthCount--;
          }
        }); // Recalculate width again

        autoWidth = (remainedWidth - categoryGap) / (autoWidthCount + (autoWidthCount - 1) * barGapPercent);
        autoWidth = Math.max(autoWidth, 0);
        var widthSum = 0;
        var lastColumn;
        each(stacks, function (column, idx) {
          if (!column.width) {
            column.width = autoWidth;
          }

          lastColumn = column;
          widthSum += column.width * (1 + barGapPercent);
        });

        if (lastColumn) {
          widthSum -= lastColumn.width * barGapPercent;
        }

        var offset = -widthSum / 2;
        each(stacks, function (column, stackId) {
          result[coordSysName][stackId] = result[coordSysName][stackId] || {
            offset: offset,
            width: column.width
          };
          offset += column.width * (1 + barGapPercent);
        });
      });
      return result;
    }

    var angleAxisExtraOption = {
      startAngle: 90,
      clockwise: true,
      splitNumber: 12,
      axisLabel: {
        rotate: 0
      }
    };
    var radiusAxisExtraOption = {
      splitNumber: 5
    };

    var PolarView =
    /** @class */
    function (_super) {
      __extends(PolarView, _super);

      function PolarView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = PolarView.type;
        return _this;
      }

      PolarView.type = 'polar';
      return PolarView;
    }(ComponentView);

    function install$u(registers) {
      use(install$s);
      AxisView.registerAxisPointerClass('PolarAxisPointer', PolarAxisPointer);
      registers.registerCoordinateSystem('polar', polarCreator);
      registers.registerComponentModel(PolarModel);
      registers.registerComponentView(PolarView); // Model and view for angleAxis and radiusAxis

      axisModelCreator(registers, 'angle', AngleAxisModel, angleAxisExtraOption);
      axisModelCreator(registers, 'radius', RadiusAxisModel, radiusAxisExtraOption);
      registers.registerComponentView(AngleAxisView);
      registers.registerComponentView(RadiusAxisView);
      registers.registerLayout(curry(barLayoutPolar, 'bar'));
    }

    function layout$2(axisModel, opt) {
      opt = opt || {};
      var single = axisModel.coordinateSystem;
      var axis = axisModel.axis;
      var layout = {};
      var axisPosition = axis.position;
      var orient = axis.orient;
      var rect = single.getRect();
      var rectBound = [rect.x, rect.x + rect.width, rect.y, rect.y + rect.height];
      var positionMap = {
        horizontal: {
          top: rectBound[2],
          bottom: rectBound[3]
        },
        vertical: {
          left: rectBound[0],
          right: rectBound[1]
        }
      };
      layout.position = [orient === 'vertical' ? positionMap.vertical[axisPosition] : rectBound[0], orient === 'horizontal' ? positionMap.horizontal[axisPosition] : rectBound[3]];
      var r = {
        horizontal: 0,
        vertical: 1
      };
      layout.rotation = Math.PI / 2 * r[orient];
      var directionMap = {
        top: -1,
        bottom: 1,
        right: 1,
        left: -1
      };
      layout.labelDirection = layout.tickDirection = layout.nameDirection = directionMap[axisPosition];

      if (axisModel.get(['axisTick', 'inside'])) {
        layout.tickDirection = -layout.tickDirection;
      }

      if (retrieve(opt.labelInside, axisModel.get(['axisLabel', 'inside']))) {
        layout.labelDirection = -layout.labelDirection;
      }

      var labelRotation = opt.rotate;
      labelRotation == null && (labelRotation = axisModel.get(['axisLabel', 'rotate']));
      layout.labelRotation = axisPosition === 'top' ? -labelRotation : labelRotation;
      layout.z2 = 1;
      return layout;
    }

    var axisBuilderAttrs$3 = ['axisLine', 'axisTickLabel', 'axisName'];
    var selfBuilderAttrs$2 = ['splitArea', 'splitLine'];

    var SingleAxisView =
    /** @class */
    function (_super) {
      __extends(SingleAxisView, _super);

      function SingleAxisView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = SingleAxisView.type;
        _this.axisPointerClass = 'SingleAxisPointer';
        return _this;
      }

      SingleAxisView.prototype.render = function (axisModel, ecModel, api, payload) {
        var group = this.group;
        group.removeAll();
        var oldAxisGroup = this._axisGroup;
        this._axisGroup = new Group();
        var layout = layout$2(axisModel);
        var axisBuilder = new AxisBuilder(axisModel, layout);
        each(axisBuilderAttrs$3, axisBuilder.add, axisBuilder);
        group.add(this._axisGroup);
        group.add(axisBuilder.getGroup());
        each(selfBuilderAttrs$2, function (name) {
          if (axisModel.get([name, 'show'])) {
            axisElementBuilders$2[name](this, this.group, this._axisGroup, axisModel);
          }
        }, this);
        groupTransition(oldAxisGroup, this._axisGroup, axisModel);

        _super.prototype.render.call(this, axisModel, ecModel, api, payload);
      };

      SingleAxisView.prototype.remove = function () {
        rectCoordAxisHandleRemove(this);
      };

      SingleAxisView.type = 'singleAxis';
      return SingleAxisView;
    }(AxisView);

    var axisElementBuilders$2 = {
      splitLine: function (axisView, group, axisGroup, axisModel) {
        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 = lineColors instanceof Array ? lineColors : [lineColors];
        var lineWidth = lineStyleModel.get('width');
        var gridRect = axisModel.coordinateSystem.getRect();
        var isHorizontal = axis.isHorizontal();
        var splitLines = [];
        var lineCount = 0;
        var ticksCoords = axis.getTicksCoords({
          tickModel: splitLineModel
        });
        var p1 = [];
        var p2 = [];

        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 line = new Line({
            shape: {
              x1: p1[0],
              y1: p1[1],
              x2: p2[0],
              y2: p2[1]
            },
            silent: true
          });
          subPixelOptimizeLine$1(line.shape, lineWidth);
          var colorIndex = lineCount++ % lineColors.length;
          splitLines[colorIndex] = splitLines[colorIndex] || [];
          splitLines[colorIndex].push(line);
        }

        var lineStyle = lineStyleModel.getLineStyle(['color']);

        for (var i = 0; i < splitLines.length; ++i) {
          group.add(mergePath$1(splitLines[i], {
            style: defaults({
              stroke: lineColors[i % lineColors.length]
            }, lineStyle),
            silent: true
          }));
        }
      },
      splitArea: function (axisView, group, axisGroup, axisModel) {
        rectCoordAxisBuildSplitArea(axisView, axisGroup, axisModel, axisModel);
      }
    };

    var SingleAxisModel =
    /** @class */
    function (_super) {
      __extends(SingleAxisModel, _super);

      function SingleAxisModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = SingleAxisModel.type;
        return _this;
      }

      SingleAxisModel.prototype.getCoordSysModel = function () {
        return this;
      };

      SingleAxisModel.type = 'singleAxis';
      SingleAxisModel.layoutMode = 'box';
      SingleAxisModel.defaultOption = {
        left: '5%',
        top: '5%',
        right: '5%',
        bottom: '5%',
        type: 'value',
        position: 'bottom',
        orient: 'horizontal',
        axisLine: {
          show: true,
          lineStyle: {
            width: 1,
            type: 'solid'
          }
        },
        // Single coordinate system and single axis is the,
        // which is used as the parent tooltip model.
        // same model, so we set default tooltip show as true.
        tooltip: {
          show: true
        },
        axisTick: {
          show: true,
          length: 6,
          lineStyle: {
            width: 1
          }
        },
        axisLabel: {
          show: true,
          interval: 'auto'
        },
        splitLine: {
          show: true,
          lineStyle: {
            type: 'dashed',
            opacity: 0.2
          }
        }
      };
      return SingleAxisModel;
    }(ComponentModel);

    mixin(SingleAxisModel, AxisModelCommonMixin.prototype);

    var SingleAxis =
    /** @class */
    function (_super) {
      __extends(SingleAxis, _super);

      function SingleAxis(dim, scale, coordExtent, axisType, position) {
        var _this = _super.call(this, dim, scale, coordExtent) || this;

        _this.type = axisType || 'value';
        _this.position = position || 'bottom';
        return _this;
      }
      /**
       * Judge the orient of the axis.
       */


      SingleAxis.prototype.isHorizontal = function () {
        var position = this.position;
        return position === 'top' || position === 'bottom';
      };

      SingleAxis.prototype.pointToData = function (point, clamp) {
        return this.coordinateSystem.pointToData(point)[0];
      };

      return SingleAxis;
    }(Axis);

    var singleDimensions = ['single'];
    /**
     * Create a single coordinates system.
     */

    var Single =
    /** @class */
    function () {
      function Single(axisModel, ecModel, api) {
        this.type = 'single';
        this.dimension = 'single';
        /**
         * Add it just for draw tooltip.
         */

        this.dimensions = singleDimensions;
        this.axisPointerEnabled = true;
        this.model = axisModel;

        this._init(axisModel, ecModel, api);
      }
      /**
       * Initialize single coordinate system.
       */


      Single.prototype._init = function (axisModel, ecModel, api) {
        var dim = this.dimension;
        var axis = new SingleAxis(dim, createScaleByModel(axisModel), [0, 0], axisModel.get('type'), axisModel.get('position'));
        var isCategory = axis.type === 'category';
        axis.onBand = isCategory && axisModel.get('boundaryGap');
        axis.inverse = axisModel.get('inverse');
        axis.orient = axisModel.get('orient');
        axisModel.axis = axis;
        axis.model = axisModel;
        axis.coordinateSystem = this;
        this._axis = axis;
      };
      /**
       * Update axis scale after data processed
       */


      Single.prototype.update = function (ecModel, api) {
        ecModel.eachSeries(function (seriesModel) {
          if (seriesModel.coordinateSystem === this) {
            var data_1 = seriesModel.getData();
            each(data_1.mapDimensionsAll(this.dimension), function (dim) {
              this._axis.scale.unionExtentFromData(data_1, dim);
            }, this);
            niceScaleExtent(this._axis.scale, this._axis.model);
          }
        }, this);
      };
      /**
       * Resize the single coordinate system.
       */


      Single.prototype.resize = function (axisModel, api) {
        this._rect = getLayoutRect({
          left: axisModel.get('left'),
          top: axisModel.get('top'),
          right: axisModel.get('right'),
          bottom: axisModel.get('bottom'),
          width: axisModel.get('width'),
          height: axisModel.get('height')
        }, {
          width: api.getWidth(),
          height: api.getHeight()
        });

        this._adjustAxis();
      };

      Single.prototype.getRect = function () {
        return this._rect;
      };

      Single.prototype._adjustAxis = function () {
        var rect = this._rect;
        var axis = this._axis;
        var isHorizontal = axis.isHorizontal();
        var extent = isHorizontal ? [0, rect.width] : [0, rect.height];
        var idx = axis.inverse ? 1 : 0;
        axis.setExtent(extent[idx], extent[1 - idx]);

        this._updateAxisTransform(axis, isHorizontal ? rect.x : rect.y);
      };

      Single.prototype._updateAxisTransform = function (axis, coordBase) {
        var axisExtent = axis.getExtent();
        var extentSum = axisExtent[0] + axisExtent[1];
        var isHorizontal = axis.isHorizontal();
        axis.toGlobalCoord = isHorizontal ? function (coord) {
          return coord + coordBase;
        } : function (coord) {
          return extentSum - coord + coordBase;
        };
        axis.toLocalCoord = isHorizontal ? function (coord) {
          return coord - coordBase;
        } : function (coord) {
          return extentSum - coord + coordBase;
        };
      };
      /**
       * Get axis.
       */


      Single.prototype.getAxis = function () {
        return this._axis;
      };
      /**
       * Get axis, add it just for draw tooltip.
       */


      Single.prototype.getBaseAxis = function () {
        return this._axis;
      };

      Single.prototype.getAxes = function () {
        return [this._axis];
      };

      Single.prototype.getTooltipAxes = function () {
        return {
          baseAxes: [this.getAxis()],
          // Empty otherAxes
          otherAxes: []
        };
      };
      /**
       * If contain point.
       */


      Single.prototype.containPoint = function (point) {
        var rect = this.getRect();
        var axis = this.getAxis();
        var orient = axis.orient;

        if (orient === 'horizontal') {
          return axis.contain(axis.toLocalCoord(point[0])) && point[1] >= rect.y && point[1] <= rect.y + rect.height;
        } else {
          return axis.contain(axis.toLocalCoord(point[1])) && point[0] >= rect.y && point[0] <= rect.y + rect.height;
        }
      };

      Single.prototype.pointToData = function (point) {
        var axis = this.getAxis();
        return [axis.coordToData(axis.toLocalCoord(point[axis.orient === 'horizontal' ? 0 : 1]))];
      };
      /**
       * Convert the series data to concrete point.
       * Can be [val] | val
       */


      Single.prototype.dataToPoint = function (val) {
        var axis = this.getAxis();
        var rect = this.getRect();
        var pt = [];
        var idx = axis.orient === 'horizontal' ? 0 : 1;

        if (val instanceof Array) {
          val = val[0];
        }

        pt[idx] = axis.toGlobalCoord(axis.dataToCoord(+val));
        pt[1 - idx] = idx === 0 ? rect.y + rect.height / 2 : rect.x + rect.width / 2;
        return pt;
      };

      Single.prototype.convertToPixel = function (ecModel, finder, value) {
        var coordSys = getCoordSys$3(finder);
        return coordSys === this ? this.dataToPoint(value) : null;
      };

      Single.prototype.convertFromPixel = function (ecModel, finder, pixel) {
        var coordSys = getCoordSys$3(finder);
        return coordSys === this ? this.pointToData(pixel) : null;
      };

      return Single;
    }();

    function getCoordSys$3(finder) {
      var seriesModel = finder.seriesModel;
      var singleModel = finder.singleAxisModel;
      return singleModel && singleModel.coordinateSystem || seriesModel && seriesModel.coordinateSystem;
    }

    /**
     * Create single coordinate system and inject it into seriesModel.
     */

    function create$2(ecModel, api) {
      var singles = [];
      ecModel.eachComponent('singleAxis', function (axisModel, idx) {
        var single = new Single(axisModel, ecModel, api);
        single.name = 'single_' + idx;
        single.resize(axisModel, api);
        axisModel.coordinateSystem = single;
        singles.push(single);
      });
      ecModel.eachSeries(function (seriesModel) {
        if (seriesModel.get('coordinateSystem') === 'singleAxis') {
          var singleAxisModel = seriesModel.getReferringComponents('singleAxis', SINGLE_REFERRING).models[0];
          seriesModel.coordinateSystem = singleAxisModel && singleAxisModel.coordinateSystem;
        }
      });
      return singles;
    }

    var singleCreator = {
      create: create$2,
      dimensions: singleDimensions
    };

    var XY = ['x', 'y'];
    var WH = ['width', 'height'];

    var SingleAxisPointer =
    /** @class */
    function (_super) {
      __extends(SingleAxisPointer, _super);

      function SingleAxisPointer() {
        return _super !== null && _super.apply(this, arguments) || this;
      }
      /**
       * @override
       */


      SingleAxisPointer.prototype.makeElOption = function (elOption, value, axisModel, axisPointerModel, api) {
        var axis = axisModel.axis;
        var coordSys = axis.coordinateSystem;
        var otherExtent = getGlobalExtent(coordSys, 1 - getPointDimIndex(axis));
        var pixelValue = coordSys.dataToPoint(value)[0];
        var axisPointerType = axisPointerModel.get('type');

        if (axisPointerType && axisPointerType !== 'none') {
          var elStyle = buildElStyle(axisPointerModel);
          var pointerOption = pointerShapeBuilder$2[axisPointerType](axis, pixelValue, otherExtent);
          pointerOption.style = elStyle;
          elOption.graphicKey = pointerOption.type;
          elOption.pointer = pointerOption;
        }

        var layoutInfo = layout$2(axisModel);
        buildCartesianSingleLabelElOption( // @ts-ignore
        value, elOption, layoutInfo, axisModel, axisPointerModel, api);
      };
      /**
       * @override
       */


      SingleAxisPointer.prototype.getHandleTransform = function (value, axisModel, axisPointerModel) {
        var layoutInfo = layout$2(axisModel, {
          labelInside: false
        }); // @ts-ignore

        layoutInfo.labelMargin = axisPointerModel.get(['handle', 'margin']);
        var position = getTransformedPosition(axisModel.axis, value, layoutInfo);
        return {
          x: position[0],
          y: position[1],
          rotation: layoutInfo.rotation + (layoutInfo.labelDirection < 0 ? Math.PI : 0)
        };
      };
      /**
       * @override
       */


      SingleAxisPointer.prototype.updateHandleTransform = function (transform, delta, axisModel, axisPointerModel) {
        var axis = axisModel.axis;
        var coordSys = axis.coordinateSystem;
        var dimIndex = getPointDimIndex(axis);
        var axisExtent = getGlobalExtent(coordSys, dimIndex);
        var currPosition = [transform.x, transform.y];
        currPosition[dimIndex] += delta[dimIndex];
        currPosition[dimIndex] = Math.min(axisExtent[1], currPosition[dimIndex]);
        currPosition[dimIndex] = Math.max(axisExtent[0], currPosition[dimIndex]);
        var otherExtent = getGlobalExtent(coordSys, 1 - dimIndex);
        var cursorOtherValue = (otherExtent[1] + otherExtent[0]) / 2;
        var cursorPoint = [cursorOtherValue, cursorOtherValue];
        cursorPoint[dimIndex] = currPosition[dimIndex];
        return {
          x: currPosition[0],
          y: currPosition[1],
          rotation: transform.rotation,
          cursorPoint: cursorPoint,
          tooltipOption: {
            verticalAlign: 'middle'
          }
        };
      };

      return SingleAxisPointer;
    }(BaseAxisPointer);

    var pointerShapeBuilder$2 = {
      line: function (axis, pixelValue, otherExtent) {
        var targetShape = makeLineShape([pixelValue, otherExtent[0]], [pixelValue, otherExtent[1]], getPointDimIndex(axis));
        return {
          type: 'Line',
          subPixelOptimize: true,
          shape: targetShape
        };
      },
      shadow: function (axis, pixelValue, otherExtent) {
        var bandWidth = axis.getBandWidth();
        var span = otherExtent[1] - otherExtent[0];
        return {
          type: 'Rect',
          shape: makeRectShape([pixelValue - bandWidth / 2, otherExtent[0]], [bandWidth, span], getPointDimIndex(axis))
        };
      }
    };

    function getPointDimIndex(axis) {
      return axis.isHorizontal() ? 0 : 1;
    }

    function getGlobalExtent(coordSys, dimIndex) {
      var rect = coordSys.getRect();
      return [rect[XY[dimIndex]], rect[XY[dimIndex]] + rect[WH[dimIndex]]];
    }

    var SingleView =
    /** @class */
    function (_super) {
      __extends(SingleView, _super);

      function SingleView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = SingleView.type;
        return _this;
      }

      SingleView.type = 'single';
      return SingleView;
    }(ComponentView);

    function install$v(registers) {
      use(install$s);
      AxisView.registerAxisPointerClass('SingleAxisPointer', SingleAxisPointer);
      registers.registerComponentView(SingleView); // Axis

      registers.registerComponentView(SingleAxisView);
      registers.registerComponentModel(SingleAxisModel);
      axisModelCreator(registers, 'single', SingleAxisModel, SingleAxisModel.defaultOption);
      registers.registerCoordinateSystem('single', singleCreator);
    }

    var CalendarModel =
    /** @class */
    function (_super) {
      __extends(CalendarModel, _super);

      function CalendarModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = CalendarModel.type;
        return _this;
      }
      /**
       * @override
       */


      CalendarModel.prototype.init = function (option, parentModel, ecModel) {
        var inputPositionParams = getLayoutParams(option);

        _super.prototype.init.apply(this, arguments);

        mergeAndNormalizeLayoutParams(option, inputPositionParams);
      };
      /**
       * @override
       */


      CalendarModel.prototype.mergeOption = function (option) {
        _super.prototype.mergeOption.apply(this, arguments);

        mergeAndNormalizeLayoutParams(this.option, option);
      };

      CalendarModel.prototype.getCellSize = function () {
        // Has been normalized
        return this.option.cellSize;
      };

      CalendarModel.type = 'calendar';
      CalendarModel.defaultOption = {
        // zlevel: 0,
        z: 2,
        left: 80,
        top: 60,
        cellSize: 20,
        // horizontal vertical
        orient: 'horizontal',
        // month separate line style
        splitLine: {
          show: true,
          lineStyle: {
            color: '#000',
            width: 1,
            type: 'solid'
          }
        },
        // rect style  temporarily unused emphasis
        itemStyle: {
          color: '#fff',
          borderWidth: 1,
          borderColor: '#ccc'
        },
        // week text style
        dayLabel: {
          show: true,
          firstDay: 0,
          // start end
          position: 'start',
          margin: '50%',
          color: '#000'
        },
        // month text style
        monthLabel: {
          show: true,
          // start end
          position: 'start',
          margin: 5,
          // center or left
          align: 'center',
          formatter: null,
          color: '#000'
        },
        // year text style
        yearLabel: {
          show: true,
          // top bottom left right
          position: null,
          margin: 30,
          formatter: null,
          color: '#ccc',
          fontFamily: 'sans-serif',
          fontWeight: 'bolder',
          fontSize: 20
        }
      };
      return CalendarModel;
    }(ComponentModel);

    function mergeAndNormalizeLayoutParams(target, raw) {
      // Normalize cellSize
      var cellSize = target.cellSize;
      var cellSizeArr;

      if (!isArray(cellSize)) {
        cellSizeArr = target.cellSize = [cellSize, cellSize];
      } else {
        cellSizeArr = cellSize;
      }

      if (cellSizeArr.length === 1) {
        cellSizeArr[1] = cellSizeArr[0];
      }

      var ignoreSize = map([0, 1], function (hvIdx) {
        // If user have set `width` or both `left` and `right`, cellSizeArr
        // will be automatically set to 'auto', otherwise the default
        // setting of cellSizeArr will make `width` setting not work.
        if (sizeCalculable(raw, hvIdx)) {
          cellSizeArr[hvIdx] = 'auto';
        }

        return cellSizeArr[hvIdx] != null && cellSizeArr[hvIdx] !== 'auto';
      });
      mergeLayoutParam(target, raw, {
        type: 'box',
        ignoreSize: ignoreSize
      });
    }

    var CalendarView =
    /** @class */
    function (_super) {
      __extends(CalendarView, _super);

      function CalendarView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = CalendarView.type;
        return _this;
      }

      CalendarView.prototype.render = function (calendarModel, ecModel, api) {
        var group = this.group;
        group.removeAll();
        var coordSys = calendarModel.coordinateSystem; // range info

        var rangeData = coordSys.getRangeInfo();
        var orient = coordSys.getOrient(); // locale

        var localeModel = ecModel.getLocaleModel();

        this._renderDayRect(calendarModel, rangeData, group); // _renderLines must be called prior to following function


        this._renderLines(calendarModel, rangeData, orient, group);

        this._renderYearText(calendarModel, rangeData, orient, group);

        this._renderMonthText(calendarModel, localeModel, orient, group);

        this._renderWeekText(calendarModel, localeModel, rangeData, orient, group);
      }; // render day rect


      CalendarView.prototype._renderDayRect = function (calendarModel, rangeData, group) {
        var coordSys = calendarModel.coordinateSystem;
        var itemRectStyleModel = calendarModel.getModel('itemStyle').getItemStyle();
        var sw = coordSys.getCellWidth();
        var sh = coordSys.getCellHeight();

        for (var i = rangeData.start.time; i <= rangeData.end.time; i = coordSys.getNextNDay(i, 1).time) {
          var point = coordSys.dataToRect([i], false).tl; // every rect

          var rect = new Rect({
            shape: {
              x: point[0],
              y: point[1],
              width: sw,
              height: sh
            },
            cursor: 'default',
            style: itemRectStyleModel
          });
          group.add(rect);
        }
      }; // render separate line


      CalendarView.prototype._renderLines = function (calendarModel, rangeData, orient, group) {
        var self = this;
        var coordSys = calendarModel.coordinateSystem;
        var lineStyleModel = calendarModel.getModel(['splitLine', 'lineStyle']).getLineStyle();
        var show = calendarModel.get(['splitLine', 'show']);
        var lineWidth = lineStyleModel.lineWidth;
        this._tlpoints = [];
        this._blpoints = [];
        this._firstDayOfMonth = [];
        this._firstDayPoints = [];
        var firstDay = rangeData.start;

        for (var i = 0; firstDay.time <= rangeData.end.time; i++) {
          addPoints(firstDay.formatedDate);

          if (i === 0) {
            firstDay = coordSys.getDateInfo(rangeData.start.y + '-' + rangeData.start.m);
          }

          var date = firstDay.date;
          date.setMonth(date.getMonth() + 1);
          firstDay = coordSys.getDateInfo(date);
        }

        addPoints(coordSys.getNextNDay(rangeData.end.time, 1).formatedDate);

        function addPoints(date) {
          self._firstDayOfMonth.push(coordSys.getDateInfo(date));

          self._firstDayPoints.push(coordSys.dataToRect([date], false).tl);

          var points = self._getLinePointsOfOneWeek(calendarModel, date, orient);

          self._tlpoints.push(points[0]);

          self._blpoints.push(points[points.length - 1]);

          show && self._drawSplitline(points, lineStyleModel, group);
        } // render top/left line


        show && this._drawSplitline(self._getEdgesPoints(self._tlpoints, lineWidth, orient), lineStyleModel, group); // render bottom/right line

        show && this._drawSplitline(self._getEdgesPoints(self._blpoints, lineWidth, orient), lineStyleModel, group);
      }; // get points at both ends


      CalendarView.prototype._getEdgesPoints = function (points, lineWidth, orient) {
        var rs = [points[0].slice(), points[points.length - 1].slice()];
        var idx = orient === 'horizontal' ? 0 : 1; // both ends of the line are extend half lineWidth

        rs[0][idx] = rs[0][idx] - lineWidth / 2;
        rs[1][idx] = rs[1][idx] + lineWidth / 2;
        return rs;
      }; // render split line


      CalendarView.prototype._drawSplitline = function (points, lineStyle, group) {
        var poyline = new Polyline({
          z2: 20,
          shape: {
            points: points
          },
          style: lineStyle
        });
        group.add(poyline);
      }; // render month line of one week points


      CalendarView.prototype._getLinePointsOfOneWeek = function (calendarModel, date, orient) {
        var coordSys = calendarModel.coordinateSystem;
        var parsedDate = coordSys.getDateInfo(date);
        var points = [];

        for (var i = 0; i < 7; i++) {
          var tmpD = coordSys.getNextNDay(parsedDate.time, i);
          var point = coordSys.dataToRect([tmpD.time], false);
          points[2 * tmpD.day] = point.tl;
          points[2 * tmpD.day + 1] = point[orient === 'horizontal' ? 'bl' : 'tr'];
        }

        return points;
      };

      CalendarView.prototype._formatterLabel = function (formatter, params) {
        if (isString(formatter) && formatter) {
          return formatTplSimple(formatter, params);
        }

        if (isFunction(formatter)) {
          return formatter(params);
        }

        return params.nameMap;
      };

      CalendarView.prototype._yearTextPositionControl = function (textEl, point, orient, position, margin) {
        var x = point[0];
        var y = point[1];
        var aligns = ['center', 'bottom'];

        if (position === 'bottom') {
          y += margin;
          aligns = ['center', 'top'];
        } else if (position === 'left') {
          x -= margin;
        } else if (position === 'right') {
          x += margin;
          aligns = ['center', 'top'];
        } else {
          // top
          y -= margin;
        }

        var rotate = 0;

        if (position === 'left' || position === 'right') {
          rotate = Math.PI / 2;
        }

        return {
          rotation: rotate,
          x: x,
          y: y,
          style: {
            align: aligns[0],
            verticalAlign: aligns[1]
          }
        };
      }; // render year


      CalendarView.prototype._renderYearText = function (calendarModel, rangeData, orient, group) {
        var yearLabel = calendarModel.getModel('yearLabel');

        if (!yearLabel.get('show')) {
          return;
        }

        var margin = yearLabel.get('margin');
        var pos = yearLabel.get('position');

        if (!pos) {
          pos = orient !== 'horizontal' ? 'top' : 'left';
        }

        var points = [this._tlpoints[this._tlpoints.length - 1], this._blpoints[0]];
        var xc = (points[0][0] + points[1][0]) / 2;
        var yc = (points[0][1] + points[1][1]) / 2;
        var idx = orient === 'horizontal' ? 0 : 1;
        var posPoints = {
          top: [xc, points[idx][1]],
          bottom: [xc, points[1 - idx][1]],
          left: [points[1 - idx][0], yc],
          right: [points[idx][0], yc]
        };
        var name = rangeData.start.y;

        if (+rangeData.end.y > +rangeData.start.y) {
          name = name + '-' + rangeData.end.y;
        }

        var formatter = yearLabel.get('formatter');
        var params = {
          start: rangeData.start.y,
          end: rangeData.end.y,
          nameMap: name
        };

        var content = this._formatterLabel(formatter, params);

        var yearText = new ZRText({
          z2: 30,
          style: createTextStyle(yearLabel, {
            text: content
          })
        });
        yearText.attr(this._yearTextPositionControl(yearText, posPoints[pos], orient, pos, margin));
        group.add(yearText);
      };

      CalendarView.prototype._monthTextPositionControl = function (point, isCenter, orient, position, margin) {
        var align = 'left';
        var vAlign = 'top';
        var x = point[0];
        var y = point[1];

        if (orient === 'horizontal') {
          y = y + margin;

          if (isCenter) {
            align = 'center';
          }

          if (position === 'start') {
            vAlign = 'bottom';
          }
        } else {
          x = x + margin;

          if (isCenter) {
            vAlign = 'middle';
          }

          if (position === 'start') {
            align = 'right';
          }
        }

        return {
          x: x,
          y: y,
          align: align,
          verticalAlign: vAlign
        };
      }; // render month and year text


      CalendarView.prototype._renderMonthText = function (calendarModel, localeModel, orient, group) {
        var monthLabel = calendarModel.getModel('monthLabel');

        if (!monthLabel.get('show')) {
          return;
        }

        var nameMap = monthLabel.get('nameMap');
        var margin = monthLabel.get('margin');
        var pos = monthLabel.get('position');
        var align = monthLabel.get('align');
        var termPoints = [this._tlpoints, this._blpoints];

        if (!nameMap || isString(nameMap)) {
          if (nameMap) {
            // case-sensitive
            localeModel = getLocaleModel(nameMap) || localeModel;
          } // PENDING
          // for ZH locale, original form is `一月` but current form is `1月`


          nameMap = localeModel.get(['time', 'monthAbbr']) || [];
        }

        var idx = pos === 'start' ? 0 : 1;
        var axis = orient === 'horizontal' ? 0 : 1;
        margin = pos === 'start' ? -margin : margin;
        var isCenter = align === 'center';

        for (var i = 0; i < termPoints[idx].length - 1; i++) {
          var tmp = termPoints[idx][i].slice();
          var firstDay = this._firstDayOfMonth[i];

          if (isCenter) {
            var firstDayPoints = this._firstDayPoints[i];
            tmp[axis] = (firstDayPoints[axis] + termPoints[0][i + 1][axis]) / 2;
          }

          var formatter = monthLabel.get('formatter');
          var name_1 = nameMap[+firstDay.m - 1];
          var params = {
            yyyy: firstDay.y,
            yy: (firstDay.y + '').slice(2),
            MM: firstDay.m,
            M: +firstDay.m,
            nameMap: name_1
          };

          var content = this._formatterLabel(formatter, params);

          var monthText = new ZRText({
            z2: 30,
            style: extend(createTextStyle(monthLabel, {
              text: content
            }), this._monthTextPositionControl(tmp, isCenter, orient, pos, margin))
          });
          group.add(monthText);
        }
      };

      CalendarView.prototype._weekTextPositionControl = function (point, orient, position, margin, cellSize) {
        var align = 'center';
        var vAlign = 'middle';
        var x = point[0];
        var y = point[1];
        var isStart = position === 'start';

        if (orient === 'horizontal') {
          x = x + margin + (isStart ? 1 : -1) * cellSize[0] / 2;
          align = isStart ? 'right' : 'left';
        } else {
          y = y + margin + (isStart ? 1 : -1) * cellSize[1] / 2;
          vAlign = isStart ? 'bottom' : 'top';
        }

        return {
          x: x,
          y: y,
          align: align,
          verticalAlign: vAlign
        };
      }; // render weeks


      CalendarView.prototype._renderWeekText = function (calendarModel, localeModel, rangeData, orient, group) {
        var dayLabel = calendarModel.getModel('dayLabel');

        if (!dayLabel.get('show')) {
          return;
        }

        var coordSys = calendarModel.coordinateSystem;
        var pos = dayLabel.get('position');
        var nameMap = dayLabel.get('nameMap');
        var margin = dayLabel.get('margin');
        var firstDayOfWeek = coordSys.getFirstDayOfWeek();

        if (!nameMap || isString(nameMap)) {
          if (nameMap) {
            // case-sensitive
            localeModel = getLocaleModel(nameMap) || localeModel;
          } // Use the first letter of `dayOfWeekAbbr` if `dayOfWeekShort` doesn't exist in the locale file


          var dayOfWeekShort = localeModel.get(['time', 'dayOfWeekShort']);
          nameMap = dayOfWeekShort || map(localeModel.get(['time', 'dayOfWeekAbbr']), function (val) {
            return val[0];
          });
        }

        var start = coordSys.getNextNDay(rangeData.end.time, 7 - rangeData.lweek).time;
        var cellSize = [coordSys.getCellWidth(), coordSys.getCellHeight()];
        margin = parsePercent$1(margin, Math.min(cellSize[1], cellSize[0]));

        if (pos === 'start') {
          start = coordSys.getNextNDay(rangeData.start.time, -(7 + rangeData.fweek)).time;
          margin = -margin;
        }

        for (var i = 0; i < 7; i++) {
          var tmpD = coordSys.getNextNDay(start, i);
          var point = coordSys.dataToRect([tmpD.time], false).center;
          var day = i;
          day = Math.abs((i + firstDayOfWeek) % 7);
          var weekText = new ZRText({
            z2: 30,
            style: extend(createTextStyle(dayLabel, {
              text: nameMap[day]
            }), this._weekTextPositionControl(point, orient, pos, margin, cellSize))
          });
          group.add(weekText);
        }
      };

      CalendarView.type = 'calendar';
      return CalendarView;
    }(ComponentView);

    var PROXIMATE_ONE_DAY = 86400000;

    var Calendar =
    /** @class */
    function () {
      function Calendar(calendarModel, ecModel, api) {
        this.type = 'calendar';
        this.dimensions = Calendar.dimensions; // Required in createListFromData

        this.getDimensionsInfo = Calendar.getDimensionsInfo;
        this._model = calendarModel;
      }

      Calendar.getDimensionsInfo = function () {
        return [{
          name: 'time',
          type: 'time'
        }, 'value'];
      };

      Calendar.prototype.getRangeInfo = function () {
        return this._rangeInfo;
      };

      Calendar.prototype.getModel = function () {
        return this._model;
      };

      Calendar.prototype.getRect = function () {
        return this._rect;
      };

      Calendar.prototype.getCellWidth = function () {
        return this._sw;
      };

      Calendar.prototype.getCellHeight = function () {
        return this._sh;
      };

      Calendar.prototype.getOrient = function () {
        return this._orient;
      };
      /**
       * getFirstDayOfWeek
       *
       * @example
       *     0 : start at Sunday
       *     1 : start at Monday
       *
       * @return {number}
       */


      Calendar.prototype.getFirstDayOfWeek = function () {
        return this._firstDayOfWeek;
      };
      /**
       * get date info
       * }
       */


      Calendar.prototype.getDateInfo = function (date) {
        date = parseDate(date);
        var y = date.getFullYear();
        var m = date.getMonth() + 1;
        var mStr = m < 10 ? '0' + m : '' + m;
        var d = date.getDate();
        var dStr = d < 10 ? '0' + d : '' + d;
        var day = date.getDay();
        day = Math.abs((day + 7 - this.getFirstDayOfWeek()) % 7);
        return {
          y: y + '',
          m: mStr,
          d: dStr,
          day: day,
          time: date.getTime(),
          formatedDate: y + '-' + mStr + '-' + dStr,
          date: date
        };
      };

      Calendar.prototype.getNextNDay = function (date, n) {
        n = n || 0;

        if (n === 0) {
          return this.getDateInfo(date);
        }

        date = new Date(this.getDateInfo(date).time);
        date.setDate(date.getDate() + n);
        return this.getDateInfo(date);
      };

      Calendar.prototype.update = function (ecModel, api) {
        this._firstDayOfWeek = +this._model.getModel('dayLabel').get('firstDay');
        this._orient = this._model.get('orient');
        this._lineWidth = this._model.getModel('itemStyle').getItemStyle().lineWidth || 0;
        this._rangeInfo = this._getRangeInfo(this._initRangeOption());
        var weeks = this._rangeInfo.weeks || 1;
        var whNames = ['width', 'height'];

        var cellSize = this._model.getCellSize().slice();

        var layoutParams = this._model.getBoxLayoutParams();

        var cellNumbers = this._orient === 'horizontal' ? [weeks, 7] : [7, weeks];
        each([0, 1], function (idx) {
          if (cellSizeSpecified(cellSize, idx)) {
            layoutParams[whNames[idx]] = cellSize[idx] * cellNumbers[idx];
          }
        });
        var whGlobal = {
          width: api.getWidth(),
          height: api.getHeight()
        };
        var calendarRect = this._rect = getLayoutRect(layoutParams, whGlobal);
        each([0, 1], function (idx) {
          if (!cellSizeSpecified(cellSize, idx)) {
            cellSize[idx] = calendarRect[whNames[idx]] / cellNumbers[idx];
          }
        });

        function cellSizeSpecified(cellSize, idx) {
          return cellSize[idx] != null && cellSize[idx] !== 'auto';
        } // Has been calculated out number.


        this._sw = cellSize[0];
        this._sh = cellSize[1];
      };
      /**
       * Convert a time data(time, value) item to (x, y) point.
       */
      // TODO Clamp of calendar is not same with cartesian coordinate systems.
      // It will return NaN if data exceeds.


      Calendar.prototype.dataToPoint = function (data, clamp) {
        isArray(data) && (data = data[0]);
        clamp == null && (clamp = true);
        var dayInfo = this.getDateInfo(data);
        var range = this._rangeInfo;
        var date = dayInfo.formatedDate; // if not in range return [NaN, NaN]

        if (clamp && !(dayInfo.time >= range.start.time && dayInfo.time < range.end.time + PROXIMATE_ONE_DAY)) {
          return [NaN, NaN];
        }

        var week = dayInfo.day;

        var nthWeek = this._getRangeInfo([range.start.time, date]).nthWeek;

        if (this._orient === 'vertical') {
          return [this._rect.x + week * this._sw + this._sw / 2, this._rect.y + nthWeek * this._sh + this._sh / 2];
        }

        return [this._rect.x + nthWeek * this._sw + this._sw / 2, this._rect.y + week * this._sh + this._sh / 2];
      };
      /**
       * Convert a (x, y) point to time data
       */


      Calendar.prototype.pointToData = function (point) {
        var date = this.pointToDate(point);
        return date && date.time;
      };
      /**
       * Convert a time date item to (x, y) four point.
       */


      Calendar.prototype.dataToRect = function (data, clamp) {
        var point = this.dataToPoint(data, clamp);
        return {
          contentShape: {
            x: point[0] - (this._sw - this._lineWidth) / 2,
            y: point[1] - (this._sh - this._lineWidth) / 2,
            width: this._sw - this._lineWidth,
            height: this._sh - this._lineWidth
          },
          center: point,
          tl: [point[0] - this._sw / 2, point[1] - this._sh / 2],
          tr: [point[0] + this._sw / 2, point[1] - this._sh / 2],
          br: [point[0] + this._sw / 2, point[1] + this._sh / 2],
          bl: [point[0] - this._sw / 2, point[1] + this._sh / 2]
        };
      };
      /**
       * Convert a (x, y) point to time date
       *
       * @param  {Array} point point
       * @return {Object}       date
       */


      Calendar.prototype.pointToDate = function (point) {
        var nthX = Math.floor((point[0] - this._rect.x) / this._sw) + 1;
        var nthY = Math.floor((point[1] - this._rect.y) / this._sh) + 1;
        var range = this._rangeInfo.range;

        if (this._orient === 'vertical') {
          return this._getDateByWeeksAndDay(nthY, nthX - 1, range);
        }

        return this._getDateByWeeksAndDay(nthX, nthY - 1, range);
      };

      Calendar.prototype.convertToPixel = function (ecModel, finder, value) {
        var coordSys = getCoordSys$4(finder);
        return coordSys === this ? coordSys.dataToPoint(value) : null;
      };

      Calendar.prototype.convertFromPixel = function (ecModel, finder, pixel) {
        var coordSys = getCoordSys$4(finder);
        return coordSys === this ? coordSys.pointToData(pixel) : null;
      };

      Calendar.prototype.containPoint = function (point) {
        console.warn('Not implemented.');
        return false;
      };
      /**
       * initRange
       * Normalize to an [start, end] array
       */


      Calendar.prototype._initRangeOption = function () {
        var range = this._model.get('range');

        var normalizedRange; // Convert [1990] to 1990

        if (isArray(range) && range.length === 1) {
          range = range[0];
        }

        if (!isArray(range)) {
          var rangeStr = range.toString(); // One year.

          if (/^\d{4}$/.test(rangeStr)) {
            normalizedRange = [rangeStr + '-01-01', rangeStr + '-12-31'];
          } // One month


          if (/^\d{4}[\/|-]\d{1,2}$/.test(rangeStr)) {
            var start = this.getDateInfo(rangeStr);
            var firstDay = start.date;
            firstDay.setMonth(firstDay.getMonth() + 1);
            var end = this.getNextNDay(firstDay, -1);
            normalizedRange = [start.formatedDate, end.formatedDate];
          } // One day


          if (/^\d{4}[\/|-]\d{1,2}[\/|-]\d{1,2}$/.test(rangeStr)) {
            normalizedRange = [rangeStr, rangeStr];
          }
        } else {
          normalizedRange = range;
        }

        if (!normalizedRange) {
          if ("development" !== 'production') {
            logError('Invalid date range.');
          } // Not handling it.


          return range;
        }

        var tmp = this._getRangeInfo(normalizedRange);

        if (tmp.start.time > tmp.end.time) {
          normalizedRange.reverse();
        }

        return normalizedRange;
      };
      /**
       * range info
       *
       * @private
       * @param  {Array} range range ['2017-01-01', '2017-07-08']
       *  If range[0] > range[1], they will not be reversed.
       * @return {Object}       obj
       */


      Calendar.prototype._getRangeInfo = function (range) {
        var parsedRange = [this.getDateInfo(range[0]), this.getDateInfo(range[1])];
        var reversed;

        if (parsedRange[0].time > parsedRange[1].time) {
          reversed = true;
          parsedRange.reverse();
        }

        var allDay = Math.floor(parsedRange[1].time / PROXIMATE_ONE_DAY) - Math.floor(parsedRange[0].time / PROXIMATE_ONE_DAY) + 1; // Consider case1 (#11677 #10430):
        // Set the system timezone as "UK", set the range to `['2016-07-01', '2016-12-31']`
        // Consider case2:
        // Firstly set system timezone as "Time Zone: America/Toronto",
        // ```
        // let first = new Date(1478412000000 - 3600 * 1000 * 2.5);
        // let second = new Date(1478412000000);
        // let allDays = Math.floor(second / ONE_DAY) - Math.floor(first / ONE_DAY) + 1;
        // ```
        // will get wrong result because of DST. So we should fix it.

        var date = new Date(parsedRange[0].time);
        var startDateNum = date.getDate();
        var endDateNum = parsedRange[1].date.getDate();
        date.setDate(startDateNum + allDay - 1); // The bias can not over a month, so just compare date.

        var dateNum = date.getDate();

        if (dateNum !== endDateNum) {
          var sign = date.getTime() - parsedRange[1].time > 0 ? 1 : -1;

          while ((dateNum = date.getDate()) !== endDateNum && (date.getTime() - parsedRange[1].time) * sign > 0) {
            allDay -= sign;
            date.setDate(dateNum - sign);
          }
        }

        var weeks = Math.floor((allDay + parsedRange[0].day + 6) / 7);
        var nthWeek = reversed ? -weeks + 1 : weeks - 1;
        reversed && parsedRange.reverse();
        return {
          range: [parsedRange[0].formatedDate, parsedRange[1].formatedDate],
          start: parsedRange[0],
          end: parsedRange[1],
          allDay: allDay,
          weeks: weeks,
          // From 0.
          nthWeek: nthWeek,
          fweek: parsedRange[0].day,
          lweek: parsedRange[1].day
        };
      };
      /**
       * get date by nthWeeks and week day in range
       *
       * @private
       * @param  {number} nthWeek the week
       * @param  {number} day   the week day
       * @param  {Array} range [d1, d2]
       * @return {Object}
       */


      Calendar.prototype._getDateByWeeksAndDay = function (nthWeek, day, range) {
        var rangeInfo = this._getRangeInfo(range);

        if (nthWeek > rangeInfo.weeks || nthWeek === 0 && day < rangeInfo.fweek || nthWeek === rangeInfo.weeks && day > rangeInfo.lweek) {
          return null;
        }

        var nthDay = (nthWeek - 1) * 7 - rangeInfo.fweek + day;
        var date = new Date(rangeInfo.start.time);
        date.setDate(+rangeInfo.start.d + nthDay);
        return this.getDateInfo(date);
      };

      Calendar.create = function (ecModel, api) {
        var calendarList = [];
        ecModel.eachComponent('calendar', function (calendarModel) {
          var calendar = new Calendar(calendarModel, ecModel, api);
          calendarList.push(calendar);
          calendarModel.coordinateSystem = calendar;
        });
        ecModel.eachSeries(function (calendarSeries) {
          if (calendarSeries.get('coordinateSystem') === 'calendar') {
            // Inject coordinate system
            calendarSeries.coordinateSystem = calendarList[calendarSeries.get('calendarIndex') || 0];
          }
        });
        return calendarList;
      };

      Calendar.dimensions = ['time', 'value'];
      return Calendar;
    }();

    function getCoordSys$4(finder) {
      var calendarModel = finder.calendarModel;
      var seriesModel = finder.seriesModel;
      var coordSys = calendarModel ? calendarModel.coordinateSystem : seriesModel ? seriesModel.coordinateSystem : null;
      return coordSys;
    }

    function install$w(registers) {
      registers.registerComponentModel(CalendarModel);
      registers.registerComponentView(CalendarView);
      registers.registerCoordinateSystem('calendar', Calendar);
    }

    function setKeyInfoToNewElOption(resultItem, newElOption) {
      var existElOption = resultItem.existing; // 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 isSetLoc(obj, props) {
      var isSet;
      each(props, function (prop) {
        obj[prop] != null && obj[prop] !== 'auto' && (isSet = true);
      });
      return isSet;
    }

    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 ("development" !== 'production') {
            var newType = newElOption.type;
            assert(!newType || existElOption.type === newType, 'Please set $action: "replace" to change `type`');
          } // We can ensure that newElOptCopy and existElOption are not
          // the same object, so `merge` will not change newElOptCopy.


          merge(existElOption, newElOptCopy, true); // Rigid body, use ignoreSize.

          mergeLayoutParam(existElOption, newElOptCopy, {
            ignoreSize: true
          }); // Will be used in render.

          copyLayoutParams(newElOption, existElOption); // Copy transition info to new option so it can be used in the transition.
          // DO IT AFTER merge

          copyTransitionInfo(newElOption, existElOption);
          copyTransitionInfo(newElOption, existElOption, 'shape');
          copyTransitionInfo(newElOption, existElOption, 'style');
          copyTransitionInfo(newElOption, existElOption, 'extra'); // Copy clipPath

          newElOption.clipPath = existElOption.clipPath;
        } else {
          existList[index] = newElOptCopy;
        }
      } else if ($action === 'replace') {
        existList[index] = newElOptCopy;
      } else if ($action === 'remove') {
        // null will be cleaned later.
        existElOption && (existList[index] = null);
      }
    }

    var TRANSITION_PROPS_TO_COPY = ['transition', 'enterFrom', 'leaveTo'];
    var ROOT_TRANSITION_PROPS_TO_COPY = TRANSITION_PROPS_TO_COPY.concat(['enterAnimation', 'updateAnimation', 'leaveAnimation']);

    function copyTransitionInfo(target, source, targetProp) {
      if (targetProp) {
        if (!target[targetProp] && source[targetProp]) {
          // TODO avoid creating this empty object when there is no transition configuration.
          target[targetProp] = {};
        }

        target = target[targetProp];
        source = source[targetProp];
      }

      if (!target || !source) {
        return;
      }

      var props = targetProp ? TRANSITION_PROPS_TO_COPY : ROOT_TRANSITION_PROPS_TO_COPY;

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

        if (target[prop] == null && source[prop] != null) {
          target[prop] = source[prop];
        }
      }
    }

    function setLayoutInfoToExist(existItem, newElOption) {
      if (!existItem) {
        return;
      }

      existItem.hv = newElOption.hv = [// Rigid body, don't care about `width`.
      isSetLoc(newElOption, ['left', 'right']), // Rigid body, don't care about `height`.
      isSetLoc(newElOption, ['top', 'bottom'])]; // Give default group size. Otherwise layout error may occur.

      if (existItem.type === 'group') {
        var existingGroupOpt = existItem;
        var newGroupOpt = newElOption;
        existingGroupOpt.width == null && (existingGroupOpt.width = newGroupOpt.width = 0);
        existingGroupOpt.height == null && (existingGroupOpt.height = newGroupOpt.height = 0);
      }
    }

    var GraphicComponentModel =
    /** @class */
    function (_super) {
      __extends(GraphicComponentModel, _super);

      function GraphicComponentModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = GraphicComponentModel.type;
        _this.preventAutoZ = true;
        return _this;
      }

      GraphicComponentModel.prototype.mergeOption = function (option, ecModel) {
        // Prevent default merge to elements
        var elements = this.option.elements;
        this.option.elements = null;

        _super.prototype.mergeOption.call(this, option, ecModel);

        this.option.elements = elements;
      };

      GraphicComponentModel.prototype.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, null);

        var mappingResult = mappingToExists(existList, flattenedList, 'normalMerge'); // Clear elOptionsToUpdate

        var elOptionsToUpdate = this._elOptionsToUpdate = [];
        each(mappingResult, function (resultItem, index) {
          var newElOption = resultItem.newOption;

          if ("development" !== 'production') {
            assert(isObject(newElOption) || resultItem.existing, 'Empty graphic option definition');
          }

          if (!newElOption) {
            return;
          }

          elOptionsToUpdate.push(newElOption);
          setKeyInfoToNewElOption(resultItem, newElOption);
          mergeNewElOptionToExist(existList, index, newElOption);
          setLayoutInfoToExist(existList[index], newElOption);
        }, this); // Clean

        thisOption.elements = filter(existList, function (item) {
          // $action should be volatile, otherwise option gotten from
          // `getOption` will contain unexpected $action.
          item && delete item.$action;
          return item != null;
        });
      };
      /**
       * Convert
       * [{
       *  type: 'group',
       *  id: 'xx',
       *  children: [{type: 'circle'}, {type: 'polygon'}]
       * }]
       * to
       * [
       *  {type: 'group', id: 'xx'},
       *  {type: 'circle', parentId: 'xx'},
       *  {type: 'polygon', parentId: 'xx'}
       * ]
       */


      GraphicComponentModel.prototype._flatten = function (optionList, result, parentOption) {
        each(optionList, function (option) {
          if (!option) {
            return;
          }

          if (parentOption) {
            option.parentOption = parentOption;
          }

          result.push(option);
          var children = option.children; // here we don't judge if option.type is `group`
          // when new option doesn't provide `type`, it will cause that the children can't be updated.

          if (children && children.length) {
            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?


      GraphicComponentModel.prototype.useElOptionsToUpdate = function () {
        var els = this._elOptionsToUpdate; // Clear to avoid render duplicately when zooming.

        this._elOptionsToUpdate = null;
        return els;
      };

      GraphicComponentModel.type = 'graphic';
      GraphicComponentModel.defaultOption = {
        elements: [] // parentId: null

      };
      return GraphicComponentModel;
    }(ComponentModel);

    var nonShapeGraphicElements = {
      // Reserved but not supported in graphic component.
      path: null,
      compoundPath: null,
      // Supported in graphic component.
      group: Group,
      image: ZRImage,
      text: ZRText
    };
    var inner$e = makeInner(); // ------------------------
    // View
    // ------------------------

    var GraphicComponentView =
    /** @class */
    function (_super) {
      __extends(GraphicComponentView, _super);

      function GraphicComponentView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = GraphicComponentView.type;
        return _this;
      }

      GraphicComponentView.prototype.init = function () {
        this._elMap = createHashMap();
      };

      GraphicComponentView.prototype.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.
       */


      GraphicComponentView.prototype._updateElements = function (graphicModel) {
        var elOptionsToUpdate = graphicModel.useElOptionsToUpdate();

        if (!elOptionsToUpdate) {
          return;
        }

        var elMap = this._elMap;
        var rootGroup = this.group;
        var globalZ = graphicModel.get('z');
        var globalZLevel = graphicModel.get('zlevel'); // Top-down tranverse to assign graphic settings to each elements.

        each(elOptionsToUpdate, function (elOption) {
          var id = convertOptionIdName(elOption.id, null);
          var elExisting = id != null ? elMap.get(id) : null;
          var parentId = convertOptionIdName(elOption.parentId, null);
          var targetElParent = parentId != null ? elMap.get(parentId) : rootGroup;
          var elType = elOption.type;
          var elOptionStyle = elOption.style;

          if (elType === '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 = elOptionStyle.verticalAlign = elOptionStyle.align = null;
            }
          }

          var textContentOption = elOption.textContent;
          var textConfig = elOption.textConfig;

          if (elOptionStyle && isEC4CompatibleStyle(elOptionStyle, elType, !!textConfig, !!textContentOption)) {
            var convertResult = convertFromEC4CompatibleStyle(elOptionStyle, elType, true);

            if (!textConfig && convertResult.textConfig) {
              textConfig = elOption.textConfig = convertResult.textConfig;
            }

            if (!textContentOption && convertResult.textContent) {
              textContentOption = convertResult.textContent;
            }
          } // Remove unnecessary props to avoid potential problems.


          var elOptionCleaned = getCleanedElOption(elOption); // For simple, do not support parent change, otherwise reorder is needed.

          if ("development" !== 'production') {
            elExisting && assert(targetElParent === elExisting.parent, 'Changing parent is not supported.');
          }

          var $action = elOption.$action || 'merge';
          var isMerge = $action === 'merge';
          var isReplace = $action === 'replace';

          if (isMerge) {
            var isInit = !elExisting;
            var el_1 = elExisting;

            if (isInit) {
              el_1 = createEl$1(id, targetElParent, elOption.type, elMap);
            } else {
              el_1 && (inner$e(el_1).isNew = false); // Stop and restore before update any other attributes.

              stopPreviousKeyframeAnimationAndRestore(el_1);
            }

            if (el_1) {
              applyUpdateTransition(el_1, elOptionCleaned, graphicModel, {
                isInit: isInit
              });
              updateCommonAttrs(el_1, elOption, globalZ, globalZLevel);
            }
          } else if (isReplace) {
            removeEl(elExisting, elOption, elMap, graphicModel);
            var el_2 = createEl$1(id, targetElParent, elOption.type, elMap);

            if (el_2) {
              applyUpdateTransition(el_2, elOptionCleaned, graphicModel, {
                isInit: true
              });
              updateCommonAttrs(el_2, elOption, globalZ, globalZLevel);
            }
          } else if ($action === 'remove') {
            updateLeaveTo(elExisting, elOption);
            removeEl(elExisting, elOption, elMap, graphicModel);
          }

          var el = elMap.get(id);

          if (el && textContentOption) {
            if (isMerge) {
              var textContentExisting = el.getTextContent();
              textContentExisting ? textContentExisting.attr(textContentOption) : el.setTextContent(new ZRText(textContentOption));
            } else if (isReplace) {
              el.setTextContent(new ZRText(textContentOption));
            }
          }

          if (el) {
            var clipPathOption = elOption.clipPath;

            if (clipPathOption) {
              var clipPathType = clipPathOption.type;
              var clipPath = void 0;
              var isInit = false;

              if (isMerge) {
                var oldClipPath = el.getClipPath();
                isInit = !oldClipPath || inner$e(oldClipPath).type !== clipPathType;
                clipPath = isInit ? newEl(clipPathType) : oldClipPath;
              } else if (isReplace) {
                isInit = true;
                clipPath = newEl(clipPathType);
              }

              el.setClipPath(clipPath);
              applyUpdateTransition(clipPath, clipPathOption, graphicModel, {
                isInit: isInit
              });
              applyKeyframeAnimation(clipPath, clipPathOption.keyframeAnimation, graphicModel);
            }

            var elInner = inner$e(el);
            el.setTextConfig(textConfig);
            elInner.option = elOption;
            setEventData(el, graphicModel, elOption);
            setTooltipConfig({
              el: el,
              componentModel: graphicModel,
              itemName: el.name,
              itemTooltipOption: elOption.tooltip
            });
            applyKeyframeAnimation(el, elOption.keyframeAnimation, graphicModel);
          }
        });
      };
      /**
       * Locate graphic elements.
       */


      GraphicComponentView.prototype._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();
        var xy = ['x', 'y']; // Top-down to calculate percentage width/height of group

        for (var i = 0; i < elOptions.length; i++) {
          var elOption = elOptions[i];
          var id = convertOptionIdName(elOption.id, null);
          var el = id != null ? elMap.get(id) : null;

          if (!el || !el.isGroup) {
            continue;
          }

          var parentEl = el.parent;
          var isParentRoot = parentEl === rootGroup; // Like 'position:absolut' in css, default 0.

          var elInner = inner$e(el);
          var parentElInner = inner$e(parentEl);
          elInner.width = parsePercent$1(elInner.option.width, isParentRoot ? apiWidth : parentElInner.width) || 0;
          elInner.height = parsePercent$1(elInner.option.height, isParentRoot ? apiHeight : parentElInner.height) || 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 id = convertOptionIdName(elOption.id, null);
          var el = id != null ? elMap.get(id) : null;

          if (!el) {
            continue;
          }

          var parentEl = el.parent;
          var parentElInner = inner$e(parentEl);
          var containerInfo = parentEl === rootGroup ? {
            width: apiWidth,
            height: apiHeight
          } : {
            width: parentElInner.width,
            height: parentElInner.height
          }; // 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?

          var layoutPos = {};
          var layouted = positionElement(el, elOption, containerInfo, null, {
            hv: elOption.hv,
            boundingMode: elOption.bounding
          }, layoutPos);

          if (!inner$e(el).isNew && layouted) {
            var transition = elOption.transition;
            var animatePos = {};

            for (var k = 0; k < xy.length; k++) {
              var key = xy[k];
              var val = layoutPos[key];

              if (transition && (isTransitionAll(transition) || indexOf(transition, key) >= 0)) {
                animatePos[key] = val;
              } else {
                el[key] = val;
              }
            }

            updateProps(el, animatePos, graphicModel, 0);
          } else {
            el.attr(layoutPos);
          }
        }
      };
      /**
       * Clear all elements.
       */


      GraphicComponentView.prototype._clear = function () {
        var _this = this;

        var elMap = this._elMap;
        elMap.each(function (el) {
          removeEl(el, inner$e(el).option, elMap, _this._lastGraphicModel);
        });
        this._elMap = createHashMap();
      };

      GraphicComponentView.prototype.dispose = function () {
        this._clear();
      };

      GraphicComponentView.type = 'graphic';
      return GraphicComponentView;
    }(ComponentView);

    function newEl(graphicType) {
      if ("development" !== 'production') {
        assert(graphicType, 'graphic type MUST be set');
      }

      var Clz = hasOwn(nonShapeGraphicElements, graphicType) // Those graphic elements are not shapes. They should not be
      // overwritten by users, so do them first.
      ? nonShapeGraphicElements[graphicType] : getShapeClass(graphicType);

      if ("development" !== 'production') {
        assert(Clz, "graphic type " + graphicType + " can not be found");
      }

      var el = new Clz({});
      inner$e(el).type = graphicType;
      return el;
    }

    function createEl$1(id, targetElParent, graphicType, elMap) {
      var el = newEl(graphicType);
      targetElParent.add(el);
      elMap.set(id, el);
      inner$e(el).id = id;
      inner$e(el).isNew = true;
      return el;
    }

    function removeEl(elExisting, elOption, elMap, graphicModel) {
      var existElParent = elExisting && elExisting.parent;

      if (existElParent) {
        elExisting.type === 'group' && elExisting.traverse(function (el) {
          removeEl(el, elOption, elMap, graphicModel);
        });
        applyLeaveTransition(elExisting, elOption, graphicModel);
        elMap.removeKey(inner$e(elExisting).id);
      }
    }

    function updateCommonAttrs(el, elOption, defaultZ, defaultZlevel) {
      if (!el.isGroup) {
        each([['cursor', Displayable.prototype.cursor], // We should not support configure z and zlevel in the element level.
        // But seems we didn't limit it previously. So here still use it to avoid breaking.
        ['zlevel', defaultZlevel || 0], ['z', defaultZ || 0], // z2 must not be null/undefined, otherwise sort error may occur.
        ['z2', 0]], function (item) {
          var prop = item[0];

          if (hasOwn(elOption, prop)) {
            el[prop] = retrieve2(elOption[prop], item[1]);
          } else if (el[prop] == null) {
            el[prop] = item[1];
          }
        });
      }

      each(keys(elOption), function (key) {
        // Assign event handlers.
        // PENDING: should enumerate all event names or use pattern matching?
        if (key.indexOf('on') === 0) {
          var val = elOption[key];
          el[key] = isFunction(val) ? val : null;
        }
      });

      if (hasOwn(elOption, 'draggable')) {
        el.draggable = elOption.draggable;
      } // Other attributes


      elOption.name != null && (el.name = elOption.name);
      elOption.id != null && (el.id = elOption.id);
    } // Remove unnecessary props to avoid potential problems.


    function getCleanedElOption(elOption) {
      elOption = extend({}, elOption);
      each(['id', 'parentId', '$action', 'hv', 'bounding', 'textContent', 'clipPath'].concat(LOCATION_PARAMS), function (name) {
        delete elOption[name];
      });
      return elOption;
    }

    function setEventData(el, graphicModel, elOption) {
      var eventData = getECData(el).eventData; // Simple optimize for large amount of elements that no need event.

      if (!el.silent && !el.ignore && !eventData) {
        eventData = getECData(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 = elOption.info;
      }
    }

    function install$x(registers) {
      registers.registerComponentModel(GraphicComponentModel);
      registers.registerComponentView(GraphicComponentView);
      registers.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 don't
            // want that too many views are created in echarts._viewMap.)
            option.graphic = [option.graphic[0]];
          }
        } else if (graphicOption && !graphicOption.elements) {
          option.graphic = [{
            elements: [graphicOption]
          }];
        }
      });
    }

    var DATA_ZOOM_AXIS_DIMENSIONS = ['x', 'y', 'radius', 'angle', 'single']; // Supported coords.
    // FIXME: polar has been broken (but rarely used).

    var SERIES_COORDS = ['cartesian2d', 'polar', 'singleAxis'];
    function isCoordSupported(seriesModel) {
      var coordType = seriesModel.get('coordinateSystem');
      return indexOf(SERIES_COORDS, coordType) >= 0;
    }
    function getAxisMainType(axisDim) {
      if ("development" !== 'production') {
        assert(axisDim);
      }

      return axisDim + 'Axis';
    }
    /**
     * If two dataZoomModels has the same axis controlled, we say that they are 'linked'.
     * This function finds all linked dataZoomModels start from the given payload.
     */

    function findEffectedDataZooms(ecModel, payload) {
      // Key: `DataZoomAxisDimension`
      var axisRecords = createHashMap();
      var effectedModels = []; // Key: uid of dataZoomModel

      var effectedModelMap = createHashMap(); // Find the dataZooms specified by payload.

      ecModel.eachComponent({
        mainType: 'dataZoom',
        query: payload
      }, function (dataZoomModel) {
        if (!effectedModelMap.get(dataZoomModel.uid)) {
          addToEffected(dataZoomModel);
        }
      }); // Start from the given dataZoomModels, travel the graph to find
      // all of the linked dataZoom models.

      var foundNewLink;

      do {
        foundNewLink = false;
        ecModel.eachComponent('dataZoom', processSingle);
      } while (foundNewLink);

      function processSingle(dataZoomModel) {
        if (!effectedModelMap.get(dataZoomModel.uid) && isLinked(dataZoomModel)) {
          addToEffected(dataZoomModel);
          foundNewLink = true;
        }
      }

      function addToEffected(dataZoom) {
        effectedModelMap.set(dataZoom.uid, true);
        effectedModels.push(dataZoom);
        markAxisControlled(dataZoom);
      }

      function isLinked(dataZoomModel) {
        var isLink = false;
        dataZoomModel.eachTargetAxis(function (axisDim, axisIndex) {
          var axisIdxArr = axisRecords.get(axisDim);

          if (axisIdxArr && axisIdxArr[axisIndex]) {
            isLink = true;
          }
        });
        return isLink;
      }

      function markAxisControlled(dataZoomModel) {
        dataZoomModel.eachTargetAxis(function (axisDim, axisIndex) {
          (axisRecords.get(axisDim) || axisRecords.set(axisDim, []))[axisIndex] = true;
        });
      }

      return effectedModels;
    }
    /**
     * Find the first target coordinate system.
     * Available after model built.
     *
     * @return Like {
     *                  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}
     *                  ]
     *              }
     */

    function collectReferCoordSysModelInfo(dataZoomModel) {
      var ecModel = dataZoomModel.ecModel;
      var coordSysInfoWrap = {
        infoList: [],
        infoMap: createHashMap()
      };
      dataZoomModel.eachTargetAxis(function (axisDim, axisIndex) {
        var axisModel = ecModel.getComponent(getAxisMainType(axisDim), axisIndex);

        if (!axisModel) {
          return;
        }

        var coordSysModel = axisModel.getCoordSysModel();

        if (!coordSysModel) {
          return;
        }

        var coordSysUid = coordSysModel.uid;
        var coordSysInfo = coordSysInfoWrap.infoMap.get(coordSysUid);

        if (!coordSysInfo) {
          coordSysInfo = {
            model: coordSysModel,
            axisModels: []
          };
          coordSysInfoWrap.infoList.push(coordSysInfo);
          coordSysInfoWrap.infoMap.set(coordSysUid, coordSysInfo);
        }

        coordSysInfo.axisModels.push(axisModel);
      });
      return coordSysInfoWrap;
    }

    var DataZoomAxisInfo =
    /** @class */
    function () {
      function DataZoomAxisInfo() {
        this.indexList = [];
        this.indexMap = [];
      }

      DataZoomAxisInfo.prototype.add = function (axisCmptIdx) {
        // Remove duplication.
        if (!this.indexMap[axisCmptIdx]) {
          this.indexList.push(axisCmptIdx);
          this.indexMap[axisCmptIdx] = true;
        }
      };

      return DataZoomAxisInfo;
    }();

    var DataZoomModel =
    /** @class */
    function (_super) {
      __extends(DataZoomModel, _super);

      function DataZoomModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = DataZoomModel.type;
        _this._autoThrottle = true;
        _this._noTarget = 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).
         */

        _this._rangePropMode = ['percent', 'percent'];
        return _this;
      }

      DataZoomModel.prototype.init = function (option, parentModel, ecModel) {
        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.
         */

        this.settledOption = inputRawOption;
        this.mergeDefaultAndTheme(option, ecModel);

        this._doInit(inputRawOption);
      };

      DataZoomModel.prototype.mergeOption = function (newOption) {
        var inputRawOption = retrieveRawOption(newOption); // FIX #2591

        merge(this.option, newOption, true);
        merge(this.settledOption, inputRawOption, true);

        this._doInit(inputRawOption);
      };

      DataZoomModel.prototype._doInit = function (inputRawOption) {
        var thisOption = this.option;

        this._setDefaultThrottle(inputRawOption);

        this._updateRangeUse(inputRawOption);

        var settledOption = this.settledOption;
        each([['start', 'startValue'], ['end', 'endValue']], function (names, index) {
          // start/end has higher priority over startValue/endValue if they
          // both set, but we should make chart.setOption({endValue: 1000})
          // effective, rather than chart.setOption({endValue: 1000, end: null}).
          if (this._rangePropMode[index] === 'value') {
            thisOption[names[0]] = settledOption[names[0]] = null;
          } // Otherwise do nothing and use the merge result.

        }, this);

        this._resetTarget();
      };

      DataZoomModel.prototype._resetTarget = function () {
        var optionOrient = this.get('orient', true);
        var targetAxisIndexMap = this._targetAxisInfoMap = createHashMap();

        var hasAxisSpecified = this._fillSpecifiedTargetAxis(targetAxisIndexMap);

        if (hasAxisSpecified) {
          this._orient = optionOrient || this._makeAutoOrientByTargetAxis();
        } else {
          this._orient = optionOrient || 'horizontal';

          this._fillAutoTargetAxisByOrient(targetAxisIndexMap, this._orient);
        }

        this._noTarget = true;
        targetAxisIndexMap.each(function (axisInfo) {
          if (axisInfo.indexList.length) {
            this._noTarget = false;
          }
        }, this);
      };

      DataZoomModel.prototype._fillSpecifiedTargetAxis = function (targetAxisIndexMap) {
        var hasAxisSpecified = false;
        each(DATA_ZOOM_AXIS_DIMENSIONS, function (axisDim) {
          var refering = this.getReferringComponents(getAxisMainType(axisDim), MULTIPLE_REFERRING); // 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 occurred.

          if (!refering.specified) {
            return;
          }

          hasAxisSpecified = true;
          var axisInfo = new DataZoomAxisInfo();
          each(refering.models, function (axisModel) {
            axisInfo.add(axisModel.componentIndex);
          });
          targetAxisIndexMap.set(axisDim, axisInfo);
        }, this);
        return hasAxisSpecified;
      };

      DataZoomModel.prototype._fillAutoTargetAxisByOrient = function (targetAxisIndexMap, orient) {
        var ecModel = this.ecModel;
        var needAuto = true; // Find axis that parallel to dataZoom as default.

        if (needAuto) {
          var axisDim = orient === 'vertical' ? 'y' : 'x';
          var axisModels = ecModel.findComponents({
            mainType: axisDim + 'Axis'
          });
          setParallelAxis(axisModels, axisDim);
        } // Find axis that parallel to dataZoom as default.


        if (needAuto) {
          var axisModels = ecModel.findComponents({
            mainType: 'singleAxis',
            filter: function (axisModel) {
              return axisModel.get('orient', true) === orient;
            }
          });
          setParallelAxis(axisModels, 'single');
        }

        function setParallelAxis(axisModels, axisDim) {
          // At least use the first parallel axis as the target axis.
          var axisModel = axisModels[0];

          if (!axisModel) {
            return;
          }

          var axisInfo = new DataZoomAxisInfo();
          axisInfo.add(axisModel.componentIndex);
          targetAxisIndexMap.set(axisDim, axisInfo);
          needAuto = false; // Find parallel axes in the same grid.

          if (axisDim === 'x' || axisDim === 'y') {
            var gridModel_1 = axisModel.getReferringComponents('grid', SINGLE_REFERRING).models[0];
            gridModel_1 && each(axisModels, function (axModel) {
              if (axisModel.componentIndex !== axModel.componentIndex && gridModel_1 === axModel.getReferringComponents('grid', SINGLE_REFERRING).models[0]) {
                axisInfo.add(axModel.componentIndex);
              }
            });
          }
        }

        if (needAuto) {
          // If no parallel axis, find the first category axis as default. (Also consider polar).
          each(DATA_ZOOM_AXIS_DIMENSIONS, function (axisDim) {
            if (!needAuto) {
              return;
            }

            var axisModels = ecModel.findComponents({
              mainType: getAxisMainType(axisDim),
              filter: function (axisModel) {
                return axisModel.get('type', true) === 'category';
              }
            });

            if (axisModels[0]) {
              var axisInfo = new DataZoomAxisInfo();
              axisInfo.add(axisModels[0].componentIndex);
              targetAxisIndexMap.set(axisDim, axisInfo);
              needAuto = false;
            }
          }, this);
        }
      };

      DataZoomModel.prototype._makeAutoOrientByTargetAxis = function () {
        var dim; // Find the first axis

        this.eachTargetAxis(function (axisDim) {
          !dim && (dim = axisDim);
        }, this);
        return dim === 'y' ? 'vertical' : 'horizontal';
      };

      DataZoomModel.prototype._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;
        }
      };

      DataZoomModel.prototype._updateRangeUse = function (inputRawOption) {
        var rangePropMode = this._rangePropMode;
        var rangeModeInOption = this.get('rangeMode');
        each([['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.

        });
      };

      DataZoomModel.prototype.noTarget = function () {
        return this._noTarget;
      };

      DataZoomModel.prototype.getFirstTargetAxisModel = function () {
        var firstAxisModel;
        this.eachTargetAxis(function (axisDim, axisIndex) {
          if (firstAxisModel == null) {
            firstAxisModel = this.ecModel.getComponent(getAxisMainType(axisDim), axisIndex);
          }
        }, this);
        return firstAxisModel;
      };
      /**
       * @param {Function} callback param: axisModel, dimNames, axisIndex, dataZoomModel, ecModel
       */


      DataZoomModel.prototype.eachTargetAxis = function (callback, context) {
        this._targetAxisInfoMap.each(function (axisInfo, axisDim) {
          each(axisInfo.indexList, function (axisIndex) {
            callback.call(context, axisDim, axisIndex);
          });
        });
      };
      /**
       * @return If not found, return null/undefined.
       */


      DataZoomModel.prototype.getAxisProxy = function (axisDim, axisIndex) {
        var axisModel = this.getAxisModel(axisDim, axisIndex);

        if (axisModel) {
          return axisModel.__dzAxisProxy;
        }
      };
      /**
       * @return If not found, return null/undefined.
       */


      DataZoomModel.prototype.getAxisModel = function (axisDim, axisIndex) {
        if ("development" !== 'production') {
          assert(axisDim && axisIndex != null);
        }

        var axisInfo = this._targetAxisInfoMap.get(axisDim);

        if (axisInfo && axisInfo.indexMap[axisIndex]) {
          return this.ecModel.getComponent(getAxisMainType(axisDim), axisIndex);
        }
      };
      /**
       * If not specified, set to undefined.
       */


      DataZoomModel.prototype.setRawRange = function (opt) {
        var thisOption = this.option;
        var settledOption = this.settledOption;
        each([['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);

        this._updateRangeUse(opt);
      };

      DataZoomModel.prototype.setCalculatedRange = function (opt) {
        var option = this.option;
        each(['start', 'startValue', 'end', 'endValue'], function (name) {
          option[name] = opt[name];
        });
      };

      DataZoomModel.prototype.getPercentRange = function () {
        var axisProxy = this.findRepresentativeAxisProxy();

        if (axisProxy) {
          return axisProxy.getDataPercentWindow();
        }
      };
      /**
       * For example, chart.getModel().getComponent('dataZoom').getValueRange('y', 0);
       *
       * @return [startValue, endValue] value can only be '-' or finite number.
       */


      DataZoomModel.prototype.getValueRange = function (axisDim, axisIndex) {
        if (axisDim == null && axisIndex == null) {
          var axisProxy = this.findRepresentativeAxisProxy();

          if (axisProxy) {
            return axisProxy.getDataValueWindow();
          }
        } else {
          return this.getAxisProxy(axisDim, axisIndex).getDataValueWindow();
        }
      };
      /**
       * @param axisModel If axisModel given, find axisProxy
       *      corresponding to the axisModel
       */


      DataZoomModel.prototype.findRepresentativeAxisProxy = function (axisModel) {
        if (axisModel) {
          return axisModel.__dzAxisProxy;
        } // Find the first hosted axisProxy


        var firstProxy;

        var axisDimList = this._targetAxisInfoMap.keys();

        for (var i = 0; i < axisDimList.length; i++) {
          var axisDim = axisDimList[i];

          var axisInfo = this._targetAxisInfoMap.get(axisDim);

          for (var j = 0; j < axisInfo.indexList.length; j++) {
            var proxy = this.getAxisProxy(axisDim, axisInfo.indexList[j]);

            if (proxy.hostedBy(this)) {
              return proxy;
            }

            if (!firstProxy) {
              firstProxy = proxy;
            }
          }
        } // If no hosted proxy found, still need to return a proxy.
        // This case always happens in toolbox dataZoom, where axes are all hosted by
        // other dataZooms.


        return firstProxy;
      };

      DataZoomModel.prototype.getRangePropMode = function () {
        return this._rangePropMode.slice();
      };

      DataZoomModel.prototype.getOrient = function () {
        if ("development" !== 'production') {
          // Should not be called before initialized.
          assert(this._orient);
        }

        return this._orient;
      };

      DataZoomModel.type = 'dataZoom';
      DataZoomModel.dependencies = ['xAxis', 'yAxis', 'radiusAxis', 'angleAxis', 'singleAxis', 'series', 'toolbox'];
      DataZoomModel.defaultOption = {
        // zlevel: 0,
        z: 4,
        filterMode: 'filter',
        start: 0,
        end: 100
      };
      return DataZoomModel;
    }(ComponentModel);
    /**
     * Retrieve those raw params from option, which will be cached separately,
     * because they will be overwritten by normalized/calculated values in the main
     * process.
     */


    function retrieveRawOption(option) {
      var ret = {};
      each(['start', 'end', 'startValue', 'endValue', 'throttle'], function (name) {
        option.hasOwnProperty(name) && (ret[name] = option[name]);
      });
      return ret;
    }

    var SelectDataZoomModel =
    /** @class */
    function (_super) {
      __extends(SelectDataZoomModel, _super);

      function SelectDataZoomModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = SelectDataZoomModel.type;
        return _this;
      }

      SelectDataZoomModel.type = 'dataZoom.select';
      return SelectDataZoomModel;
    }(DataZoomModel);

    var DataZoomView =
    /** @class */
    function (_super) {
      __extends(DataZoomView, _super);

      function DataZoomView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = DataZoomView.type;
        return _this;
      }

      DataZoomView.prototype.render = function (dataZoomModel, ecModel, api, payload) {
        this.dataZoomModel = dataZoomModel;
        this.ecModel = ecModel;
        this.api = api;
      };

      DataZoomView.type = 'dataZoom';
      return DataZoomView;
    }(ComponentView);

    var SelectDataZoomView =
    /** @class */
    function (_super) {
      __extends(SelectDataZoomView, _super);

      function SelectDataZoomView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = SelectDataZoomView.type;
        return _this;
      }

      SelectDataZoomView.type = 'dataZoom.select';
      return SelectDataZoomView;
    }(DataZoomView);

    var each$8 = each;
    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.
     */

    var AxisProxy =
    /** @class */
    function () {
      function AxisProxy(dimName, axisIndex, dataZoomModel, ecModel) {
        this._dimName = dimName;
        this._axisIndex = axisIndex;
        this.ecModel = ecModel;
        this._dataZoomModel = dataZoomModel; // /**
        //  * @readOnly
        //  * @private
        //  */
        // this.hasSeriesStacked;
      }
      /**
       * Whether the axisProxy is hosted by dataZoomModel.
       */


      AxisProxy.prototype.hostedBy = function (dataZoomModel) {
        return this._dataZoomModel === dataZoomModel;
      };
      /**
       * @return Value can only be NaN or finite value.
       */


      AxisProxy.prototype.getDataValueWindow = function () {
        return this._valueWindow.slice();
      };
      /**
       * @return {Array.<number>}
       */


      AxisProxy.prototype.getDataPercentWindow = function () {
        return this._percentWindow.slice();
      };

      AxisProxy.prototype.getTargetSeriesModels = function () {
        var seriesModels = [];
        this.ecModel.eachSeries(function (seriesModel) {
          if (isCoordSupported(seriesModel)) {
            var axisMainType = getAxisMainType(this._dimName);
            var axisModel = seriesModel.getReferringComponents(axisMainType, SINGLE_REFERRING).models[0];

            if (axisModel && this._axisIndex === axisModel.componentIndex) {
              seriesModels.push(seriesModel);
            }
          }
        }, this);
        return seriesModels;
      };

      AxisProxy.prototype.getAxisModel = function () {
        return this.ecModel.getComponent(this._dimName + 'Axis', this._axisIndex);
      };

      AxisProxy.prototype.getMinMaxSpan = function () {
        return clone(this._minMaxSpan);
      };
      /**
       * Only calculate by given range and this._dataExtent, do not change anything.
       */


      AxisProxy.prototype.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$8(['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);
          // fallback to extent start/end when parsed value or percent is invalid


          valueWindow[idx] = boundValue == null || isNaN(boundValue) ? dataExtent[idx] : boundValue;
          percentWindow[idx] = boundPercent == null || isNaN(boundPercent) ? percentExtent[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 don't 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() is called,
       * so it is recommended to be called in "process stage" but not "model init
       * stage".
       */


      AxisProxy.prototype.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); // `calculateDataWindow` uses min/maxSpan.

        this._updateMinMaxSpan();

        var dataWindow = this.calculateDataWindow(dataZoomModel.settledOption);
        this._valueWindow = dataWindow.valueWindow;
        this._percentWindow = dataWindow.percentWindow; // Update axis setting then.

        this._setAxisModel();
      };

      AxisProxy.prototype.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.
        // let 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$8(seriesModels, function (seriesModel) {
          var seriesData = seriesModel.getData();
          var dataDims = seriesData.mapDimensionsAll(axisDim);

          if (!dataDims.length) {
            return;
          }

          if (filterMode === 'weakFilter') {
            var store_1 = seriesData.getStore();
            var dataDimIndices_1 = map(dataDims, function (dim) {
              return seriesData.getDimensionIndex(dim);
            }, seriesData);
            seriesData.filterSelf(function (dataIndex) {
              var leftOut;
              var rightOut;
              var hasValue;

              for (var i = 0; i < dataDims.length; i++) {
                var value = store_1.get(dataDimIndices_1[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$8(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$8(dataDims, function (dim) {
            seriesData.setApproximateExtent(valueWindow, dim);
          });
        });

        function isInWindow(value) {
          return value >= valueWindow[0] && value <= valueWindow[1];
        }
      };

      AxisProxy.prototype._updateMinMaxSpan = function () {
        var minMaxSpan = this._minMaxSpan = {};
        var dataZoomModel = this._dataZoomModel;
        var dataExtent = this._dataExtent;
        each$8(['min', 'max'], function (minMax) {
          var percentSpan = dataZoomModel.get(minMax + 'Span');
          var valueSpan = dataZoomModel.get(minMax + 'ValueSpan');
          valueSpan != null && (valueSpan = this.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;
        }, this);
      };

      AxisProxy.prototype._setAxisModel = function () {
        var axisModel = this.getAxisModel();
        var percentWindow = this._percentWindow;
        var valueWindow = this._valueWindow;

        if (!percentWindow) {
          return;
        } // [0, 500]: arbitrary value, guess axis extent.


        var precision = getPixelPrecision(valueWindow, [0, 500]);
        precision = Math.min(precision, 20); // 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.

        var rawExtentInfo = axisModel.axis.scale.rawExtentInfo;

        if (percentWindow[0] !== 0) {
          rawExtentInfo.setDeterminedMinMax('min', +valueWindow[0].toFixed(precision));
        }

        if (percentWindow[1] !== 100) {
          rawExtentInfo.setDeterminedMinMax('max', +valueWindow[1].toFixed(precision));
        }

        rawExtentInfo.freeze();
      };

      return AxisProxy;
    }();

    function calculateDataExtent(axisProxy, axisDim, seriesModels) {
      var dataExtent = [Infinity, -Infinity];
      each$8(seriesModels, function (seriesModel) {
        unionAxisExtentFromData(dataExtent, seriesModel.getData(), axisDim);
      }); // 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.

      var axisModel = axisProxy.getAxisModel();
      var rawExtentResult = ensureScaleRawExtentInfo(axisModel.axis.scale, axisModel, dataExtent).calculate();
      return [rawExtentResult.min, rawExtentResult.max];
    }

    var dataZoomProcessor = {
      // `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) {
        function eachAxisModel(cb) {
          ecModel.eachComponent('dataZoom', function (dataZoomModel) {
            dataZoomModel.eachTargetAxis(function (axisDim, axisIndex) {
              var axisModel = ecModel.getComponent(getAxisMainType(axisDim), axisIndex);
              cb(axisDim, axisIndex, axisModel, dataZoomModel);
            });
          });
        } // FIXME: it brings side-effect to `getTargetSeries`.
        // Prepare axis proxies.


        eachAxisModel(function (axisDim, axisIndex, axisModel, dataZoomModel) {
          // dispose all last axis proxy, in case that some axis are deleted.
          axisModel.__dzAxisProxy = null;
        });
        var proxyList = [];
        eachAxisModel(function (axisDim, axisIndex, axisModel, dataZoomModel) {
          // Different dataZooms may constrol the same axis. In that case,
          // an axisProxy serves both of them.
          if (!axisModel.__dzAxisProxy) {
            // Use the first dataZoomModel as the main model of axisProxy.
            axisModel.__dzAxisProxy = new AxisProxy(axisDim, axisIndex, dataZoomModel, ecModel);
            proxyList.push(axisModel.__dzAxisProxy);
          }
        });
        var seriesModelMap = createHashMap();
        each(proxyList, function (axisProxy) {
          each(axisProxy.getTargetSeriesModels(), function (seriesModel) {
            seriesModelMap.set(seriesModel.uid, seriesModel);
          });
        });
        return seriesModelMap;
      },
      // 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 (axisDim, axisIndex) {
            dataZoomModel.getAxisProxy(axisDim, axisIndex).reset(dataZoomModel);
          }); // 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 (axisDim, axisIndex) {
            dataZoomModel.getAxisProxy(axisDim, 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();

          if (axisProxy) {
            var percentRange = axisProxy.getDataPercentWindow();
            var valueRange = axisProxy.getDataValueWindow();
            dataZoomModel.setCalculatedRange({
              start: percentRange[0],
              end: percentRange[1],
              startValue: valueRange[0],
              endValue: valueRange[1]
            });
          }
        });
      }
    };

    function installDataZoomAction(registers) {
      registers.registerAction('dataZoom', function (payload, ecModel) {
        var effectedModels = findEffectedDataZooms(ecModel, payload);
        each(effectedModels, function (dataZoomModel) {
          dataZoomModel.setRawRange({
            start: payload.start,
            end: payload.end,
            startValue: payload.startValue,
            endValue: payload.endValue
          });
        });
      });
    }

    var installed = false;
    function installCommon(registers) {
      if (installed) {
        return;
      }

      installed = true;
      registers.registerProcessor(registers.PRIORITY.PROCESSOR.FILTER, dataZoomProcessor);
      installDataZoomAction(registers);
      registers.registerSubTypeDefaulter('dataZoom', function () {
        // Default 'slider' when no type specified.
        return 'slider';
      });
    }

    function install$y(registers) {
      registers.registerComponentModel(SelectDataZoomModel);
      registers.registerComponentView(SelectDataZoomView);
      installCommon(registers);
    }

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


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    var ToolboxFeature =
    /** @class */
    function () {
      function ToolboxFeature() {}

      return ToolboxFeature;
    }();
    var features = {};
    function registerFeature(name, ctor) {
      features[name] = ctor;
    }
    function getFeature(name) {
      return features[name];
    }

    var ToolboxModel =
    /** @class */
    function (_super) {
      __extends(ToolboxModel, _super);

      function ToolboxModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = ToolboxModel.type;
        return _this;
      }

      ToolboxModel.prototype.optionUpdated = function () {
        _super.prototype.optionUpdated.apply(this, arguments);

        var ecModel = this.ecModel;
        each(this.option.feature, function (featureOpt, featureName) {
          var Feature = getFeature(featureName);

          if (Feature) {
            if (Feature.getDefaultOption) {
              Feature.defaultOption = Feature.getDefaultOption(ecModel);
            }

            merge(featureOpt, Feature.defaultOption);
          }
        });
      };

      ToolboxModel.type = 'toolbox';
      ToolboxModel.layoutMode = {
        type: 'box',
        ignoreSize: true
      };
      ToolboxModel.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,
          position: 'bottom'
        }
      };
      return ToolboxModel;
    }(ComponentModel);

    /**
     * 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$3(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');
      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;
    }

    var ToolboxView =
    /** @class */
    function (_super) {
      __extends(ToolboxView, _super);

      function ToolboxView() {
        return _super !== null && _super.apply(this, arguments) || this;
      }

      ToolboxView.prototype.render = function (toolboxModel, ecModel, api, payload) {
        var group = this.group;
        group.removeAll();

        if (!toolboxModel.get('show')) {
          return;
        }

        var itemSize = +toolboxModel.get('itemSize');
        var isVertical = toolboxModel.get('orient') === 'vertical';
        var featureOpts = toolboxModel.get('feature') || {};
        var features = this._features || (this._features = {});
        var featureNames = [];
        each(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 = {
                onclick: featureModel.option.onclick,
                featureName: featureName
              };
            } else {
              var Feature = getFeature(featureName);

              if (!Feature) {
                return;
              }

              feature = new Feature();
            }

            features[featureName] = feature;
          } else {
            feature = features[oldName]; // If feature does not exsit.

            if (!feature) {
              return;
            }
          }

          feature.uid = getUID('toolbox-feature');
          feature.model = featureModel;
          feature.ecModel = ecModel;
          feature.api = api;
          var isToolboxFeature = feature instanceof ToolboxFeature;

          if (!featureName && oldName) {
            isToolboxFeature && feature.dispose && feature.dispose(ecModel, api);
            return;
          }

          if (!featureModel.get('show') || isToolboxFeature && feature.unusable) {
            isToolboxFeature && 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;

            if (iconPaths[iconName]) {
              (status === 'emphasis' ? enterEmphasis : leaveEmphasis)(iconPaths[iconName]);
            }
          };

          if (feature instanceof ToolboxFeature) {
            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 instanceof ToolboxFeature && feature.getIcons ? feature.getIcons() : featureModel.get('icon');
          var titles = featureModel.get('title') || {};
          var iconsMap;
          var titlesMap;

          if (isString(icons)) {
            iconsMap = {};
            iconsMap[featureName] = icons;
          } else {
            iconsMap = icons;
          }

          if (isString(titles)) {
            titlesMap = {};
            titlesMap[featureName] = titles;
          } else {
            titlesMap = titles;
          }

          var iconPaths = featureModel.iconPaths = {};
          each(iconsMap, function (iconStr, iconName) {
            var path = createIcon(iconStr, {}, {
              x: -itemSize / 2,
              y: -itemSize / 2,
              width: itemSize,
              height: itemSize
            }); // TODO handling image

            path.setStyle(iconStyleModel.getItemStyle());
            var pathEmphasisState = path.ensureState('emphasis');
            pathEmphasisState.style = iconStyleEmphasisModel.getItemStyle(); // Text position calculation

            var textContent = new ZRText({
              style: {
                text: titlesMap[iconName],
                align: iconStyleEmphasisModel.get('textAlign'),
                borderRadius: iconStyleEmphasisModel.get('textBorderRadius'),
                padding: iconStyleEmphasisModel.get('textPadding'),
                fill: null
              },
              ignore: true
            });
            path.setTextContent(textContent);
            setTooltipConfig({
              el: path,
              componentModel: toolboxModel,
              itemName: iconName,
              formatterParamsExtra: {
                title: titlesMap[iconName]
              }
            });
            path.__title = titlesMap[iconName];
            path.on('mouseover', function () {
              // Should not reuse above hoverStyle, which might be modified.
              var hoverStyle = iconStyleEmphasisModel.getItemStyle();
              var defaultTextPosition = isVertical ? toolboxModel.get('right') == null && toolboxModel.get('left') !== 'right' ? 'right' : 'left' : toolboxModel.get('bottom') == null && toolboxModel.get('top') !== 'bottom' ? 'bottom' : 'top';
              textContent.setStyle({
                fill: iconStyleEmphasisModel.get('textFill') || hoverStyle.fill || hoverStyle.stroke || '#000',
                backgroundColor: iconStyleEmphasisModel.get('textBackgroundColor')
              });
              path.setTextConfig({
                position: iconStyleEmphasisModel.get('textPosition') || defaultTextPosition
              });
              textContent.ignore = !toolboxModel.get('showTitle'); // Use enterEmphasis and leaveEmphasis provide by ec.
              // There are flags managed by the echarts.

              api.enterEmphasis(this);
            }).on('mouseout', function () {
              if (featureModel.get(['iconStatus', iconName]) !== 'emphasis') {
                api.leaveEmphasis(this);
              }

              textContent.hide();
            });
            (featureModel.get(['iconStatus', iconName]) === 'emphasis' ? enterEmphasis : leaveEmphasis)(path);
            group.add(path);
            path.on('click', bind(feature.onclick, feature, ecModel, api, iconName));
            iconPaths[iconName] = path;
          });
        }

        layout$3(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

        isVertical || group.eachChild(function (icon) {
          var titleText = icon.__title; // const hoverStyle = icon.hoverStyle;
          // TODO simplify code?

          var emphasisState = icon.ensureState('emphasis');
          var emphasisTextConfig = emphasisState.textConfig || (emphasisState.textConfig = {});
          var textContent = icon.getTextContent();
          var emphasisTextState = textContent && textContent.ensureState('emphasis'); // May be background element

          if (emphasisTextState && !isFunction(emphasisTextState) && titleText) {
            var emphasisTextStyle = emphasisTextState.style || (emphasisTextState.style = {});
            var rect = getBoundingRect(titleText, ZRText.makeFont(emphasisTextStyle));
            var offsetX = icon.x + group.x;
            var offsetY = icon.y + group.y + itemSize;
            var needPutOnTop = false;

            if (offsetY + rect.height > api.getHeight()) {
              emphasisTextConfig.position = 'top';
              needPutOnTop = true;
            }

            var topOffset = needPutOnTop ? -5 - rect.height : itemSize + 10;

            if (offsetX + rect.width / 2 > api.getWidth()) {
              emphasisTextConfig.position = ['100%', topOffset];
              emphasisTextStyle.align = 'right';
            } else if (offsetX - rect.width / 2 < 0) {
              emphasisTextConfig.position = [0, topOffset];
              emphasisTextStyle.align = 'left';
            }
          }
        });
      };

      ToolboxView.prototype.updateView = function (toolboxModel, ecModel, api, payload) {
        each(this._features, function (feature) {
          feature instanceof ToolboxFeature && feature.updateView && feature.updateView(feature.model, ecModel, api, payload);
        });
      }; // updateLayout(toolboxModel, ecModel, api, payload) {
      //     zrUtil.each(this._features, function (feature) {
      //         feature.updateLayout && feature.updateLayout(feature.model, ecModel, api, payload);
      //     });
      // },


      ToolboxView.prototype.remove = function (ecModel, api) {
        each(this._features, function (feature) {
          feature instanceof ToolboxFeature && feature.remove && feature.remove(ecModel, api);
        });
        this.group.removeAll();
      };

      ToolboxView.prototype.dispose = function (ecModel, api) {
        each(this._features, function (feature) {
          feature instanceof ToolboxFeature && feature.dispose && feature.dispose(ecModel, api);
        });
      };

      ToolboxView.type = 'toolbox';
      return ToolboxView;
    }(ComponentView);

    function isUserFeatureName(featureName) {
      return featureName.indexOf('my') === 0;
    }

    /* global window, document */

    var SaveAsImage =
    /** @class */
    function (_super) {
      __extends(SaveAsImage, _super);

      function SaveAsImage() {
        return _super !== null && _super.apply(this, arguments) || this;
      }

      SaveAsImage.prototype.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')
        });
        var browser = env.browser; // Chrome, Firefox, New Edge

        if (isFunction(MouseEvent) && (browser.newEdge || !browser.ie && !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 or old Edge
        else {
            // @ts-ignore
            if (window.navigator.msSaveOrOpenBlob || isSvg) {
              var parts = url.split(','); // data:[<mime type>][;charset=<charset>][;base64],<encoded data>

              var base64Encoded = parts[0].indexOf('base64') > -1;
              var bstr = isSvg // should decode the svg data uri first
              ? decodeURIComponent(parts[1]) : parts[1]; // only `atob` when the data uri is encoded with base64
              // otherwise, like `svg` data uri exported by zrender,
              // there will be an error, for it's not encoded with base64.
              // (just a url-encoded string through `encodeURIComponent`)

              base64Encoded && (bstr = window.atob(bstr));
              var filename = title + '.' + type; // @ts-ignore

              if (window.navigator.msSaveOrOpenBlob) {
                var n = bstr.length;
                var u8arr = new Uint8Array(n);

                while (n--) {
                  u8arr[n] = bstr.charCodeAt(n);
                }

                var blob = new Blob([u8arr]); // @ts-ignore

                window.navigator.msSaveOrOpenBlob(blob, filename);
              } else {
                var frame = document.createElement('iframe');
                document.body.appendChild(frame);
                var cw = frame.contentWindow;
                var doc = cw.document;
                doc.open('image/svg+xml', 'replace');
                doc.write(bstr);
                doc.close();
                cw.focus();
                doc.execCommand('SaveAs', true, filename);
                document.body.removeChild(frame);
              }
            } else {
              var lang = model.get('lang');
              var html = '' + '<body style="margin:0;">' + '<img src="' + url + '" style="max-width:100%;" title="' + (lang && lang[0] || '') + '" />' + '</body>';
              var tab = window.open();
              tab.document.write(html);
              tab.document.title = title;
            }
          }
      };

      SaveAsImage.getDefaultOption = function (ecModel) {
        var 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: ecModel.getLocaleModel().get(['toolbox', 'saveAsImage', 'title']),
          type: 'png',
          // Default use option.backgroundColor
          // backgroundColor: '#fff',
          connectedBackgroundColor: '#fff',
          name: '',
          excludeComponents: ['toolbox'],
          // use current pixel ratio of device by default
          // pixelRatio: 1,
          lang: ecModel.getLocaleModel().get(['toolbox', 'saveAsImage', 'lang'])
        };
        return defaultOption;
      };

      return SaveAsImage;
    }(ToolboxFeature);

    var INNER_STACK_KEYWORD = '__ec_magicType_stack__';
    var radioTypes = [['line', 'bar'], ['stack']];

    var MagicType =
    /** @class */
    function (_super) {
      __extends(MagicType, _super);

      function MagicType() {
        return _super !== null && _super.apply(this, arguments) || this;
      }

      MagicType.prototype.getIcons = function () {
        var model = this.model;
        var availableIcons = model.get('icon');
        var icons = {};
        each(model.get('type'), function (type) {
          if (availableIcons[type]) {
            icons[type] = availableIcons[type];
          }
        });
        return icons;
      };

      MagicType.getDefaultOption = function (ecModel) {
        var defaultOption = {
          show: true,
          type: [],
          // Icon group
          icon: {
            line: 'M4.1,28.9h7.1l9.3-22l7.4,38l9.7-19.7l3,12.8h14.9M4.1,58h51.4',
            bar: 'M6.7,22.9h10V48h-10V22.9zM24.9,13h10v35h-10V13zM43.2,2h10v46h-10V2zM3.1,58h53.7',
            // eslint-disable-next-line
            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

          },
          // `line`, `bar`, `stack`, `tiled`
          title: ecModel.getLocaleModel().get(['toolbox', 'magicType', 'title']),
          option: {},
          seriesIndex: {}
        };
        return defaultOption;
      };

      MagicType.prototype.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 = seriesModel.getReferringComponents(axisType, SINGLE_REFERRING).models[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(radioTypes, function (radio) {
          if (indexOf(radio, type) >= 0) {
            each(radio, function (item) {
              model.setIconStatus(item, 'normal');
            });
          }
        });
        model.setIconStatus(type, 'emphasis');
        ecModel.eachComponent({
          mainType: 'series',
          query: seriesIndex == null ? null : {
            seriesIndex: seriesIndex
          }
        }, generateNewSeriesTypes);
        var newTitle;
        var currentType = type; // Change title of stack

        if (type === 'stack') {
          // use titles in model instead of ecModel
          // as stack and tiled appears in pair, just flip them
          // no need of checking stack state
          newTitle = merge({
            stack: model.option.title.tiled,
            tiled: model.option.title.stack
          }, model.option.title);

          if (model.get(['iconStatus', type]) !== 'emphasis') {
            currentType = 'tiled';
          }
        }

        api.dispatchAction({
          type: 'changeMagicType',
          currentType: currentType,
          newOption: newOption,
          newTitle: newTitle,
          featureName: 'magicType'
        });
      };

      return MagicType;
    }(ToolboxFeature);

    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);
        }
      }
    }; // TODO: SELF REGISTERED.

    registerAction({
      type: 'changeMagicType',
      event: 'magicTypeChanged',
      update: 'prepareAndUpdate'
    }, function (payload, ecModel) {
      ecModel.mergeOption(payload.newOption);
    });

    /* global document */

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

    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')) {
          // TODO: TYPE Consider polar? Include polar may increase unecessary bundle size.
          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
     * @inner
     */


    function assembleSeriesWithCategoryAxis(groups) {
      var tables = [];
      each(groups, 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;
        })); // @ts-ignore TODO Polar

        var columns = [categoryAxis.model.getCategories()];
        each(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
     */


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

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

    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_1 = '';
        var value = void 0;
        var hasName = false;

        if (isNaN(items[0])) {
          // First item is name
          hasName = true;
          name_1 = items[0];
          items = items.slice(1);
          data[i] = {
            name: name_1,
            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
      };
    }

    function parseContents(str, blockMetaList) {
      var blocks = str.split(new RegExp('\n*' + BLOCK_SPLITER + '\n*', 'g'));
      var newOption = {
        series: []
      };
      each(blocks, function (block, idx) {
        if (isTSVFormat(block)) {
          var result = parseTSVContents(block);
          var blockMeta = blockMetaList[idx];
          var axisKey = blockMeta.axisDim + 'Axis';

          if (blockMeta) {
            newOption[axisKey] = newOption[axisKey] || [];
            newOption[axisKey][blockMeta.axisIndex] = {
              data: result.categories
            };
            newOption.series = newOption.series.concat(result.series);
          }
        } else {
          var result = parseListContents(block);
          newOption.series.push(result);
        }
      });
      return newOption;
    }

    var DataView =
    /** @class */
    function (_super) {
      __extends(DataView, _super);

      function DataView() {
        return _super !== null && _super.apply(this, arguments) || this;
      }

      DataView.prototype.onclick = function (ecModel, api) {
        // FIXME: better way?
        setTimeout(function () {
          api.dispatchAction({
            type: 'hideTip'
          });
        });
        var container = api.getDom();
        var model = this.model;

        if (this._dom) {
          container.removeChild(this._dom);
        }

        var root = document.createElement('div'); // use padding to avoid 5px whitespace

        root.style.cssText = 'position:absolute;top:0;bottom:0;left:0;right:0;padding:5px';
        root.style.backgroundColor = model.get('backgroundColor') || '#fff'; // Create elements

        var header = document.createElement('h4');
        var lang = model.get('lang') || [];
        header.innerHTML = lang[0] || model.get('title');
        header.style.cssText = 'margin:10px 20px';
        header.style.color = model.get('textColor');
        var viewMain = document.createElement('div');
        var textarea = document.createElement('textarea');
        viewMain.style.cssText = 'overflow:auto';
        var optionToContent = model.get('optionToContent');
        var contentToOption = model.get('contentToOption');
        var result = getContentFromModel(ecModel);

        if (isFunction(optionToContent)) {
          var htmlOrDom = optionToContent(api.getOption());

          if (isString(htmlOrDom)) {
            viewMain.innerHTML = htmlOrDom;
          } else if (isDom(htmlOrDom)) {
            viewMain.appendChild(htmlOrDom);
          }
        } else {
          // Use default textarea
          textarea.readOnly = model.get('readOnly');
          var style = textarea.style; // eslint-disable-next-line max-len

          style.cssText = 'display:block;width:100%;height:100%;font-family:monospace;font-size:14px;line-height:1.6rem;resize:none;box-sizing:border-box;outline:none';
          style.color = model.get('textColor');
          style.borderColor = model.get('textareaBorderColor');
          style.backgroundColor = model.get('textareaColor');
          textarea.value = result.value;
          viewMain.appendChild(textarea);
        }

        var blockMetaList = result.meta;
        var buttonContainer = document.createElement('div');
        buttonContainer.style.cssText = 'position:absolute;bottom:5px;left:0;right:0'; // eslint-disable-next-line max-len

        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 () {
          if (contentToOption == null && optionToContent != null || contentToOption != null && optionToContent == null) {
            if ("development" !== 'production') {
              // eslint-disable-next-line
              warn('It seems you have just provided one of `contentToOption` and `optionToContent` functions but missed the other one. Data change is ignored.');
            }

            close();
            return;
          }

          var newOption;

          try {
            if (isFunction(contentToOption)) {
              newOption = contentToOption(viewMain, api.getOption());
            } else {
              newOption = parseContents(textarea.value, blockMetaList);
            }
          } catch (e) {
            close();
            throw new Error('Data view format error ' + e);
          }

          if (newOption) {
            api.dispatchAction({
              type: 'changeDataView',
              newOption: newOption
            });
          }

          close();
        });
        closeButton.innerHTML = lang[1];
        refreshButton.innerHTML = lang[2];
        refreshButton.style.cssText = 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);
      };

      DataView.getDefaultOption = function (ecModel) {
        var defaultOption = {
          show: true,
          readOnly: false,
          optionToContent: null,
          contentToOption: null,
          // eslint-disable-next-line
          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: ecModel.getLocaleModel().get(['toolbox', 'dataView', 'title']),
          lang: ecModel.getLocaleModel().get(['toolbox', 'dataView', 'lang']),
          backgroundColor: '#fff',
          textColor: '#000',
          textareaColor: '#fff',
          textareaBorderColor: '#333',
          buttonColor: '#c23531',
          buttonTextColor: '#fff'
        };
        return defaultOption;
      };

      return DataView;
    }(ToolboxFeature);
    /**
     * @inner
     */


    function tryMergeDataOption(newData, originalData) {
      return map(newData, function (newVal, idx) {
        var original = originalData && originalData[idx];

        if (isObject(original) && !isArray(original)) {
          var newValIsObject = isObject(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;
        }
      });
    } // TODO: SELF REGISTERED.


    registerAction({
      type: 'changeDataView',
      event: 'dataViewChanged',
      update: 'prepareAndUpdate'
    }, function (payload, ecModel) {
      var newSeriesOptList = [];
      each(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));
    });

    var each$9 = each;
    var inner$f = makeInner();
    /**
     * @param ecModel
     * @param newSnapshot key is dataZoomId
     */

    function push(ecModel, newSnapshot) {
      var storedSnapshots = getStoreSnapshots(ecModel); // If previous dataZoom can not be found,
      // complete an range with current range.

      each$9(newSnapshot, function (batchItem, dataZoomId) {
        var i = storedSnapshots.length - 1;

        for (; i >= 0; i--) {
          var snapshot = storedSnapshots[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();
            storedSnapshots[0][dataZoomId] = {
              dataZoomId: dataZoomId,
              start: percentRange[0],
              end: percentRange[1]
            };
          }
        }
      });
      storedSnapshots.push(newSnapshot);
    }
    function pop(ecModel) {
      var storedSnapshots = getStoreSnapshots(ecModel);
      var head = storedSnapshots[storedSnapshots.length - 1];
      storedSnapshots.length > 1 && storedSnapshots.pop(); // Find top for all dataZoom.

      var snapshot = {};
      each$9(head, function (batchItem, dataZoomId) {
        for (var i = storedSnapshots.length - 1; i >= 0; i--) {
          batchItem = storedSnapshots[i][dataZoomId];

          if (batchItem) {
            snapshot[dataZoomId] = batchItem;
            break;
          }
        }
      });
      return snapshot;
    }
    function clear$1(ecModel) {
      inner$f(ecModel).snapshots = null;
    }
    function count(ecModel) {
      return getStoreSnapshots(ecModel).length;
    }
    /**
     * History length of each dataZoom may be different.
     * this._history[0] is used to store origin range.
     */

    function getStoreSnapshots(ecModel) {
      var store = inner$f(ecModel);

      if (!store.snapshots) {
        store.snapshots = [{}];
      }

      return store.snapshots;
    }

    var RestoreOption =
    /** @class */
    function (_super) {
      __extends(RestoreOption, _super);

      function RestoreOption() {
        return _super !== null && _super.apply(this, arguments) || this;
      }

      RestoreOption.prototype.onclick = function (ecModel, api) {
        clear$1(ecModel);
        api.dispatchAction({
          type: 'restore',
          from: this.uid
        });
      };

      RestoreOption.getDefaultOption = function (ecModel) {
        var defaultOption = {
          show: true,
          // eslint-disable-next-line
          icon: 'M3.8,33.4 M47,18.9h9.8V8.7 M56.3,20.1 C52.1,9,40.5,0.6,26.8,2.1C12.6,3.7,1.6,16.2,2.1,30.6 M13,41.1H3.1v10.2 M3.7,39.9c4.2,11.1,15.8,19.5,29.5,18 c14.2-1.6,25.2-14.1,24.7-28.5',
          title: ecModel.getLocaleModel().get(['toolbox', 'restore', 'title'])
        };
        return defaultOption;
      };

      return RestoreOption;
    }(ToolboxFeature); // TODO: SELF REGISTERED.


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

    // how to genarialize to more coordinate systems.

    var INCLUDE_FINDER_MAIN_TYPES = ['grid', 'xAxis', 'yAxis', 'geo', 'graph', 'polar', 'radiusAxis', 'angleAxis', 'bmap'];

    var BrushTargetManager =
    /** @class */
    function () {
      /**
       * @param finder contains Index/Id/Name of xAxis/yAxis/geo/grid
       *        Each can be {number|Array.<number>}. like: {xAxisIndex: [3, 4]}
       * @param opt.include include coordinate system types.
       */
      function BrushTargetManager(finder, ecModel, opt) {
        var _this = this;

        this._targetInfoList = [];
        var foundCpts = parseFinder$1(ecModel, finder);
        each(targetInfoBuilders, function (builder, type) {
          if (!opt || !opt.include || indexOf(opt.include, type) >= 0) {
            builder(foundCpts, _this._targetInfoList);
          }
        });
      }

      BrushTargetManager.prototype.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
            };
          }
        });
        return areas;
      };

      BrushTargetManager.prototype.matchOutputRanges = function (areas, ecModel, cb) {
        each(areas, function (area) {
          var targetInfo = this.findTargetInfo(area, ecModel);

          if (targetInfo && targetInfo !== true) {
            each(targetInfo.coordSyses, function (coordSys) {
              var result = coordConvert[area.brushType](1, coordSys, area.range, true);
              cb(area, result.values, coordSys, ecModel);
            });
          }
        }, this);
      };
      /**
       * the `areas` is `BrushModel.areas`.
       * Called in layout stage.
       * convert `area.coordRange` to global range and set panelId to `area.range`.
       */


      BrushTargetManager.prototype.setInputRanges = function (areas, ecModel) {
        each(areas, function (area) {
          var targetInfo = this.findTargetInfo(area, ecModel);

          if ("development" !== 'production') {
            assert(!targetInfo || targetInfo === true || area.coordRange, 'coordRange must be specified when coord index specified.');
            assert(!targetInfo || targetInfo !== true || area.range, 'range must be specified in global brush.');
          }

          area.range = area.range || []; // convert coordRange to global range and set panelId.

          if (targetInfo && targetInfo !== true) {
            area.panelId = targetInfo.panelId; // (1) area.range shoule always be calculate from coordRange but does
            // not keep its original value, for the sake of the dataZoom scenario,
            // where area.coordRange remains unchanged but area.range may be changed.
            // (2) Only support converting one coordRange to pixel range in brush
            // component. So do not consider `coordRanges`.
            // (3) About __rangeOffset, see comment above.

            var result = coordConvert[area.brushType](0, targetInfo.coordSys, area.coordRange);
            var rangeOffset = area.__rangeOffset;
            area.range = rangeOffset ? diffProcessor[area.brushType](result.values, rangeOffset.offset, getScales(result.xyMinMax, rangeOffset.xyMinMax)) : result.values;
          }
        }, this);
      };

      BrushTargetManager.prototype.makePanelOpts = function (api, getDefaultBrushType) {
        return map(this._targetInfoList, function (targetInfo) {
          var rect = targetInfo.getPanelRect();
          return {
            panelId: targetInfo.panelId,
            defaultBrushType: getDefaultBrushType ? getDefaultBrushType(targetInfo) : null,
            clipPath: makeRectPanelClipPath(rect),
            isTargetByCursor: makeRectIsTargetByCursor(rect, api, targetInfo.coordSysModel),
            getLinearBrushOtherExtent: makeLinearBrushOtherExtent(rect)
          };
        });
      };

      BrushTargetManager.prototype.controlSeries = function (area, seriesModel, ecModel) {
        // Check whether area is bound in coord, and series do not belong to that coord.
        // If do not do this check, some brush (like lineX) will controll all axes.
        var targetInfo = this.findTargetInfo(area, ecModel);
        return targetInfo === true || targetInfo && indexOf(targetInfo.coordSyses, seriesModel.coordinateSystem) >= 0;
      };
      /**
       * If return Object, a coord found.
       * If reutrn true, global found.
       * Otherwise nothing found.
       */


      BrushTargetManager.prototype.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 j = 0; j < targetInfoMatchers.length; j++) {
              if (targetInfoMatchers[j](foundCpts, targetInfo)) {
                return targetInfo;
              }
            }
          }
        }

        return true;
      };

      return BrushTargetManager;
    }();

    function formatMinMax(minMax) {
      minMax[0] > minMax[1] && minMax.reverse();
      return minMax;
    }

    function parseFinder$1(ecModel, finder) {
      return parseFinder(ecModel, finder, {
        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(xAxisModels, function (axisModel) {
          var gridModel = axisModel.axis.grid.model;
          gridModelMap.set(gridModel.id, gridModel);
          xAxesHas[gridModel.id] = true;
        });
        each(yAxisModels, function (axisModel) {
          var gridModel = axisModel.axis.grid.model;
          gridModelMap.set(gridModel.id, gridModel);
          yAxesHas[gridModel.id] = true;
        });
        each(gridModels, function (gridModel) {
          gridModelMap.set(gridModel.id, gridModel);
          xAxesHas[gridModel.id] = true;
          yAxesHas[gridModel.id] = true;
        });
        gridModelMap.each(function (gridModel) {
          var grid = gridModel.coordinateSystem;
          var cartesians = [];
          each(grid.getCartesians(), function (cartesian, index) {
            if (indexOf(xAxisModels, cartesian.getAxis('x').model) >= 0 || indexOf(yAxisModels, cartesian.getAxis('y').model) >= 0) {
              cartesians.push(cartesian);
            }
          });
          targetInfoList.push({
            panelId: 'grid--' + gridModel.id,
            gridModel: gridModel,
            coordSysModel: gridModel,
            // Use the first one as the representitive coordSys.
            coordSys: cartesians[0],
            coordSyses: cartesians,
            getPanelRect: panelRectBuilders.grid,
            xAxisDeclared: xAxesHas[gridModel.id],
            yAxisDeclared: yAxesHas[gridModel.id]
          });
        });
      },
      geo: function (foundCpts, targetInfoList) {
        each(foundCpts.geoModels, function (geoModel) {
          var coordSys = geoModel.coordinateSystem;
          targetInfoList.push({
            panelId: 'geo--' + geoModel.id,
            geoModel: geoModel,
            coordSysModel: geoModel,
            coordSys: coordSys,
            coordSyses: [coordSys],
            getPanelRect: panelRectBuilders.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 panelRectBuilders = {
      grid: function () {
        // grid is not Transformable.
        return this.coordSys.master.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(axisConvert, 0),
      lineY: curry(axisConvert, 1),
      rect: function (to, coordSys, rangeOrCoordRange, clamp) {
        var xminymin = to ? coordSys.pointToData([rangeOrCoordRange[0][0], rangeOrCoordRange[1][0]], clamp) : coordSys.dataToPoint([rangeOrCoordRange[0][0], rangeOrCoordRange[1][0]], clamp);
        var xmaxymax = to ? coordSys.pointToData([rangeOrCoordRange[0][1], rangeOrCoordRange[1][1]], clamp) : coordSys.dataToPoint([rangeOrCoordRange[0][1], rangeOrCoordRange[1][1]], clamp);
        var values = [formatMinMax([xminymin[0], xmaxymax[0]]), formatMinMax([xminymin[1], xmaxymax[1]])];
        return {
          values: values,
          xyMinMax: values
        };
      },
      polygon: function (to, coordSys, rangeOrCoordRange, clamp) {
        var xyMinMax = [[Infinity, -Infinity], [Infinity, -Infinity]];
        var values = map(rangeOrCoordRange, function (item) {
          var p = to ? coordSys.pointToData(item, clamp) : coordSys.dataToPoint(item, clamp);
          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 ("development" !== 'production') {
        assert(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]), true) : axis.toGlobalCoord(axis.dataToCoord(rangeOrCoordRange[i]));
      }));
      var xyMinMax = [];
      xyMinMax[axisNameIndex] = values;
      xyMinMax[1 - axisNameIndex] = [NaN, NaN];
      return {
        values: values,
        xyMinMax: xyMinMax
      };
    }

    var diffProcessor = {
      lineX: curry(axisDiffProcessor, 0),
      lineY: curry(axisDiffProcessor, 1),
      rect: function (values, refer, scales) {
        return [[values[0][0] - scales[0] * refer[0][0], values[0][1] - scales[0] * refer[0][1]], [values[1][0] - scales[1] * refer[1][0], values[1][1] - scales[1] * refer[1][1]]];
      },
      polygon: function (values, refer, scales) {
        return 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.
    // Return [0~1, 0~1]


    function getScales(xyMinMaxCurr, xyMinMaxOrigin) {
      var sizeCurr = getSize$1(xyMinMaxCurr);
      var sizeOrigin = getSize$1(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$1(xyMinMax) {
      return xyMinMax ? [xyMinMax[0][1] - xyMinMax[0][0], xyMinMax[1][1] - xyMinMax[1][0]] : [NaN, NaN];
    }

    var each$a = each;
    var DATA_ZOOM_ID_BASE = makeInternalComponentId('toolbox-dataZoom_');

    var DataZoomFeature =
    /** @class */
    function (_super) {
      __extends(DataZoomFeature, _super);

      function DataZoomFeature() {
        return _super !== null && _super.apply(this, arguments) || this;
      }

      DataZoomFeature.prototype.render = function (featureModel, ecModel, api, payload) {
        if (!this._brushController) {
          this._brushController = new BrushController(api.getZr());

          this._brushController.on('brush', bind(this._onBrush, this)).mount();
        }

        updateZoomBtnStatus(featureModel, ecModel, this, payload, api);
        updateBackBtnStatus(featureModel, ecModel);
      };

      DataZoomFeature.prototype.onclick = function (ecModel, api, type) {
        handlers$1[type].call(this);
      };

      DataZoomFeature.prototype.remove = function (ecModel, api) {
        this._brushController && this._brushController.unmount();
      };

      DataZoomFeature.prototype.dispose = function (ecModel, api) {
        this._brushController && this._brushController.dispose();
      };

      DataZoomFeature.prototype._onBrush = function (eventParam) {
        var areas = eventParam.areas;

        if (!eventParam.isEnd || !areas.length) {
          return;
        }

        var snapshot = {};
        var ecModel = this.ecModel;

        this._brushController.updateCovers([]); // remove cover


        var brushTargetManager = new BrushTargetManager(makeAxisFinder(this.model), 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;
        }
      };

      DataZoomFeature.prototype._dispatchZoomAction = function (snapshot) {
        var batch = []; // Convert from hash map to array.

        each$a(snapshot, function (batchItem, dataZoomId) {
          batch.push(clone(batchItem));
        });
        batch.length && this.api.dispatchAction({
          type: 'dataZoom',
          from: this.uid,
          batch: batch
        });
      };

      DataZoomFeature.getDefaultOption = function (ecModel) {
        var 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: ecModel.getLocaleModel().get(['toolbox', 'dataZoom', 'title']),
          brushStyle: {
            borderWidth: 0,
            color: 'rgba(210,219,238,0.2)'
          }
        };
        return defaultOption;
      };

      return DataZoomFeature;
    }(ToolboxFeature);

    var handlers$1 = {
      zoom: function () {
        var nextActive = !this._isZoomActive;
        this.api.dispatchAction({
          type: 'takeGlobalCursor',
          key: 'dataZoomSelect',
          dataZoomSelectActive: nextActive
        });
      },
      back: function () {
        this._dispatchZoomAction(pop(this.ecModel));
      }
    };

    function makeAxisFinder(dzFeatureModel) {
      var setting = {
        xAxisIndex: dzFeatureModel.get('xAxisIndex', true),
        yAxisIndex: dzFeatureModel.get('yAxisIndex', true),
        xAxisId: dzFeatureModel.get('xAxisId', true),
        yAxisId: dzFeatureModel.get('yAxisId', true)
      }; // If both `xAxisIndex` `xAxisId` not set, it means 'all'.
      // If both `yAxisIndex` `yAxisId` not set, it means 'all'.
      // Some old cases set like this below to close yAxis control but leave xAxis control:
      // `{ feature: { dataZoom: { yAxisIndex: false } }`.

      if (setting.xAxisIndex == null && setting.xAxisId == null) {
        setting.xAxisIndex = 'all';
      }

      if (setting.yAxisIndex == null && setting.yAxisId == null) {
        setting.yAxisIndex = 'all';
      }

      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(makeAxisFinder(featureModel), ecModel, {
        include: ['grid']
      });
      var panels = brushTargetManager.makePanelOpts(api, function (targetInfo) {
        return targetInfo.xAxisDeclared && !targetInfo.yAxisDeclared ? 'lineX' : !targetInfo.xAxisDeclared && targetInfo.yAxisDeclared ? 'lineY' : 'rect';
      });

      view._brushController.setPanels(panels).enableBrush(zoomActive && panels.length ? {
        brushType: 'auto',
        brushStyle: featureModel.getModel('brushStyle').getItemStyle()
      } : false);
    }

    registerInternalOptionCreator('dataZoom', function (ecModel) {
      var toolboxModel = ecModel.getComponent('toolbox', 0);
      var featureDataZoomPath = ['feature', 'dataZoom'];

      if (!toolboxModel || toolboxModel.get(featureDataZoomPath) == null) {
        return;
      }

      var dzFeatureModel = toolboxModel.getModel(featureDataZoomPath);
      var dzOptions = [];
      var finder = makeAxisFinder(dzFeatureModel);
      var finderResult = parseFinder(ecModel, finder);
      each$a(finderResult.xAxisModels, function (axisModel) {
        return buildInternalOptions(axisModel, 'xAxis', 'xAxisIndex');
      });
      each$a(finderResult.yAxisModels, function (axisModel) {
        return buildInternalOptions(axisModel, 'yAxis', 'yAxisIndex');
      });

      function buildInternalOptions(axisModel, axisMainType, axisIndexPropName) {
        var axisIndex = axisModel.componentIndex;
        var newOpt = {
          type: 'select',
          $fromToolbox: true,
          // Default to be filter
          filterMode: dzFeatureModel.get('filterMode', true) || 'filter',
          // Id for merge mapping.
          id: DATA_ZOOM_ID_BASE + axisMainType + axisIndex
        };
        newOpt[axisIndexPropName] = axisIndex;
        dzOptions.push(newOpt);
      }

      return dzOptions;
    });

    function install$z(registers) {
      registers.registerComponentModel(ToolboxModel);
      registers.registerComponentView(ToolboxView);
      registerFeature('saveAsImage', SaveAsImage);
      registerFeature('magicType', MagicType);
      registerFeature('dataView', DataView);
      registerFeature('dataZoom', DataZoomFeature);
      registerFeature('restore', RestoreOption);
      use(install$y);
    }

    var TooltipModel =
    /** @class */
    function (_super) {
      __extends(TooltipModel, _super);

      function TooltipModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = TooltipModel.type;
        return _this;
      }

      TooltipModel.type = 'tooltip';
      TooltipModel.dependencies = ['axisPointer'];
      TooltipModel.defaultOption = {
        // zlevel: 0,
        z: 60,
        show: true,
        // tooltip main content
        showContent: true,
        // 'trigger' only works on coordinate system.
        // 'item' | 'axis' | 'none'
        trigger: 'item',
        // 'click' | 'mousemove' | 'none'
        triggerOn: 'mousemove|click',
        alwaysShowContent: false,
        displayMode: 'single',
        renderMode: 'auto',
        // whether restraint content inside viewRect.
        // If renderMode: 'richText', default true.
        // If renderMode: 'html', defaut false (for backward compat).
        confine: null,
        showDelay: 0,
        hideDelay: 100,
        // Animation transition time, unit is second
        transitionDuration: 0.4,
        enterable: false,
        backgroundColor: '#fff',
        // box shadow
        shadowBlur: 10,
        shadowColor: 'rgba(0, 0, 0, .2)',
        shadowOffsetX: 1,
        shadowOffsetY: 2,
        // tooltip border radius, unit is px, default is 4
        borderRadius: 4,
        // tooltip border width, unit is px, default is 0 (no border)
        borderWidth: 1,
        // Tooltip inside padding, default is 5 for all direction
        // Array is allowed to set up, right, bottom, left, same with css
        // The default value: See `tooltip/tooltipMarkup.ts#getPaddingFromTooltipModel`.
        padding: null,
        // Extra css text
        extraCssText: '',
        // axis indicator, trigger by axis
        axisPointer: {
          // default is line
          // legal values: 'line' | 'shadow' | 'cross'
          type: 'line',
          // Valid when type is line, appoint tooltip line locate on which line. Optional
          // legal values: 'x' | 'y' | 'angle' | 'radius' | 'auto'
          // default is 'auto', chose the axis which type is category.
          // for multiply y axis, cartesian coord chose x axis, polar chose angle axis
          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: '#666',
          fontSize: 14
        }
      };
      return TooltipModel;
    }(ComponentModel);

    /* global document */

    function shouldTooltipConfine(tooltipModel) {
      var confineOption = tooltipModel.get('confine');
      return confineOption != null ? !!confineOption // In richText mode, the outside part can not be visible.
      : tooltipModel.get('renderMode') === 'richText';
    }

    function testStyle(styleProps) {
      if (!env.domSupported) {
        return;
      }

      var style = document.documentElement.style;

      for (var i = 0, len = styleProps.length; i < len; i++) {
        if (styleProps[i] in style) {
          return styleProps[i];
        }
      }
    }

    var TRANSFORM_VENDOR = testStyle(['transform', 'webkitTransform', 'OTransform', 'MozTransform', 'msTransform']);
    var TRANSITION_VENDOR = testStyle(['webkitTransition', 'transition', 'OTransition', 'MozTransition', 'msTransition']);
    function toCSSVendorPrefix(styleVendor, styleProp) {
      if (!styleVendor) {
        return styleProp;
      }

      styleProp = toCamelCase(styleProp, true);
      var idx = styleVendor.indexOf(styleProp);
      styleVendor = idx === -1 ? styleProp : "-" + styleVendor.slice(0, idx) + "-" + styleProp;
      return styleVendor.toLowerCase();
    }
    function getComputedStyle(el, style) {
      var stl = el.currentStyle || document.defaultView && document.defaultView.getComputedStyle(el);
      return stl ? style ? stl[style] : stl : null;
    }

    /* global document, window */

    var CSS_TRANSITION_VENDOR = toCSSVendorPrefix(TRANSITION_VENDOR, 'transition');
    var CSS_TRANSFORM_VENDOR = toCSSVendorPrefix(TRANSFORM_VENDOR, 'transform'); // eslint-disable-next-line

    var gCssText = "position:absolute;display:block;border-style:solid;white-space:nowrap;z-index:9999999;" + (env.transform3dSupported ? 'will-change:transform;' : '');

    function mirrorPos(pos) {
      pos = pos === 'left' ? 'right' : pos === 'right' ? 'left' : pos === 'top' ? 'bottom' : 'top';
      return pos;
    }

    function assembleArrow(tooltipModel, borderColor, arrowPosition) {
      if (!isString(arrowPosition) || arrowPosition === 'inside') {
        return '';
      }

      var backgroundColor = tooltipModel.get('backgroundColor');
      var borderWidth = tooltipModel.get('borderWidth');
      borderColor = convertToColorString(borderColor);
      var arrowPos = mirrorPos(arrowPosition);
      var arrowSize = Math.max(Math.round(borderWidth) * 1.5, 6);
      var positionStyle = '';
      var transformStyle = CSS_TRANSFORM_VENDOR + ':';
      var rotateDeg;

      if (indexOf(['left', 'right'], arrowPos) > -1) {
        positionStyle += 'top:50%';
        transformStyle += "translateY(-50%) rotate(" + (rotateDeg = arrowPos === 'left' ? -225 : -45) + "deg)";
      } else {
        positionStyle += 'left:50%';
        transformStyle += "translateX(-50%) rotate(" + (rotateDeg = arrowPos === 'top' ? 225 : 45) + "deg)";
      }

      var rotateRadian = rotateDeg * Math.PI / 180;
      var arrowWH = arrowSize + borderWidth;
      var rotatedWH = arrowWH * Math.abs(Math.cos(rotateRadian)) + arrowWH * Math.abs(Math.sin(rotateRadian));
      var arrowOffset = Math.round(((rotatedWH - Math.SQRT2 * borderWidth) / 2 + Math.SQRT2 * borderWidth - (rotatedWH - arrowWH) / 2) * 100) / 100;
      positionStyle += ";" + arrowPos + ":-" + arrowOffset + "px";
      var borderStyle = borderColor + " solid " + borderWidth + "px;";
      var styleCss = ["position:absolute;width:" + arrowSize + "px;height:" + arrowSize + "px;z-index:-1;", positionStyle + ";" + transformStyle + ";", "border-bottom:" + borderStyle, "border-right:" + borderStyle, "background-color:" + backgroundColor + ";"];
      return "<div style=\"" + styleCss.join('') + "\"></div>";
    }

    function assembleTransition(duration, onlyFade) {
      var transitionCurve = 'cubic-bezier(0.23,1,0.32,1)';
      var transitionOption = " " + duration / 2 + "s " + transitionCurve;
      var transitionText = "opacity" + transitionOption + ",visibility" + transitionOption;

      if (!onlyFade) {
        transitionOption = " " + duration + "s " + transitionCurve;
        transitionText += env.transformSupported ? "," + CSS_TRANSFORM_VENDOR + transitionOption : ",left" + transitionOption + ",top" + transitionOption;
      }

      return CSS_TRANSITION_VENDOR + ':' + transitionText;
    }

    function assembleTransform(x, y, toString) {
      // If using float on style, the final width of the dom might
      // keep changing slightly while mouse move. So `toFixed(0)` them.
      var x0 = x.toFixed(0) + 'px';
      var y0 = y.toFixed(0) + 'px'; // not support transform, use `left` and `top` instead.

      if (!env.transformSupported) {
        return toString ? "top:" + y0 + ";left:" + x0 + ";" : [['top', y0], ['left', x0]];
      } // support transform


      var is3d = env.transform3dSupported;
      var translate = "translate" + (is3d ? '3d' : '') + "(" + x0 + "," + y0 + (is3d ? ',0' : '') + ")";
      return toString ? 'top:0;left:0;' + CSS_TRANSFORM_VENDOR + ':' + translate + ';' : [['top', 0], ['left', 0], [TRANSFORM_VENDOR, translate]];
    }
    /**
     * @param {Object} textStyle
     * @return {string}
     * @inner
     */


    function assembleFont(textStyleModel) {
      var cssText = [];
      var fontSize = textStyleModel.get('fontSize');
      var color = textStyleModel.getTextColor();
      color && cssText.push('color:' + color);
      cssText.push('font:' + textStyleModel.getFont());
      fontSize // @ts-ignore, leave it to the tooltip refactor.
      && cssText.push('line-height:' + Math.round(fontSize * 3 / 2) + 'px');
      var shadowColor = textStyleModel.get('textShadowColor');
      var shadowBlur = textStyleModel.get('textShadowBlur') || 0;
      var shadowOffsetX = textStyleModel.get('textShadowOffsetX') || 0;
      var shadowOffsetY = textStyleModel.get('textShadowOffsetY') || 0;
      shadowColor && shadowBlur && cssText.push('text-shadow:' + shadowOffsetX + 'px ' + shadowOffsetY + 'px ' + shadowBlur + 'px ' + shadowColor);
      each(['decoration', 'align'], function (name) {
        var val = textStyleModel.get(name);
        val && cssText.push('text-' + name + ':' + val);
      });
      return cssText.join(';');
    }

    function assembleCssText(tooltipModel, enableTransition, onlyFade) {
      var cssText = [];
      var transitionDuration = tooltipModel.get('transitionDuration');
      var backgroundColor = tooltipModel.get('backgroundColor');
      var shadowBlur = tooltipModel.get('shadowBlur');
      var shadowColor = tooltipModel.get('shadowColor');
      var shadowOffsetX = tooltipModel.get('shadowOffsetX');
      var shadowOffsetY = tooltipModel.get('shadowOffsetY');
      var textStyleModel = tooltipModel.getModel('textStyle');
      var padding = getPaddingFromTooltipModel(tooltipModel, 'html');
      var boxShadow = shadowOffsetX + "px " + shadowOffsetY + "px " + shadowBlur + "px " + shadowColor;
      cssText.push('box-shadow:' + boxShadow); // Animation transition. Do not animate when transitionDuration is 0.

      enableTransition && transitionDuration && cssText.push(assembleTransition(transitionDuration, onlyFade));

      if (backgroundColor) {
        cssText.push('background-color:' + backgroundColor);
      } // Border style


      each(['width', 'color', 'radius'], function (name) {
        var borderName = 'border-' + name;
        var camelCase = toCamelCase(borderName);
        var val = tooltipModel.get(camelCase);
        val != null && cssText.push(borderName + ':' + val + (name === 'color' ? '' : 'px'));
      }); // Text style

      cssText.push(assembleFont(textStyleModel)); // Padding

      if (padding != null) {
        cssText.push('padding:' + 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();
      out[3] = out[1] / zr.getHeight();
    }

    var TooltipHTMLContent =
    /** @class */
    function () {
      function TooltipHTMLContent(container, api, opt) {
        this._show = false;
        this._styleCoord = [0, 0, 0, 0];
        this._enterable = true;
        this._firstShow = true;
        this._longHide = true;

        if (env.wxa) {
          return null;
        }

        var el = document.createElement('div'); // TODO: TYPE

        el.domBelongToZr = true;
        this.el = el;
        var zr = this._zr = api.getZr();
        var appendToBody = this._appendToBody = opt && opt.appendToBody;
        makeStyleCoord(this._styleCoord, zr, appendToBody, api.getWidth() / 2, api.getHeight() / 2);

        if (appendToBody) {
          document.body.appendChild(el);
        } else {
          container.appendChild(el);
        }

        this._container = container; // 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 () {
          // set `_inContent` to `false` before `hideLater`
          self._inContent = false;

          if (self._enterable) {
            if (self._show) {
              self.hideLater(self._hideDelay);
            }
          }
        };
      }
      /**
       * Update when tooltip is rendered
       */


      TooltipHTMLContent.prototype.update = function (tooltipModel) {
        // FIXME
        // Move this logic to ec main?
        var container = this._container;
        var position = getComputedStyle(container, 'position');
        var domStyle = container.style;

        if (domStyle.position !== 'absolute' && position !== 'absolute') {
          domStyle.position = 'relative';
        } // move tooltip if chart resized


        var alwaysShowContent = tooltipModel.get('alwaysShowContent');
        alwaysShowContent && this._moveIfResized(); // update className

        this.el.className = tooltipModel.get('className') || ''; // Hide the tooltip
        // PENDING
        // this.hide();
      };

      TooltipHTMLContent.prototype.show = function (tooltipModel, nearPointColor) {
        clearTimeout(this._hideTimeout);
        clearTimeout(this._longHideTimeout);
        var el = this.el;
        var style = el.style;
        var styleCoord = this._styleCoord;

        if (!el.innerHTML) {
          style.display = 'none';
        } else {
          style.cssText = gCssText + assembleCssText(tooltipModel, !this._firstShow, this._longHide) // initial transform
          + assembleTransform(styleCoord[0], styleCoord[1], true) + ("border-color:" + convertToColorString(nearPointColor) + ";") + (tooltipModel.get('extraCssText') || '') // 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.
          + (";pointer-events:" + (this._enterable ? 'auto' : 'none'));
        }

        this._show = true;
        this._firstShow = false;
        this._longHide = false;
      };

      TooltipHTMLContent.prototype.setContent = function (content, markers, tooltipModel, borderColor, arrowPosition) {
        var el = this.el;

        if (content == null) {
          el.innerHTML = '';
          return;
        }

        var arrow = '';

        if (isString(arrowPosition) && tooltipModel.get('trigger') === 'item' && !shouldTooltipConfine(tooltipModel)) {
          arrow = assembleArrow(tooltipModel, borderColor, arrowPosition);
        }

        if (isString(content)) {
          el.innerHTML = content + arrow;
        } else if (content) {
          // Clear previous
          el.innerHTML = '';

          if (!isArray(content)) {
            content = [content];
          }

          for (var i = 0; i < content.length; i++) {
            if (isDom(content[i]) && content[i].parentNode !== el) {
              el.appendChild(content[i]);
            }
          } // no arrow if empty


          if (arrow && el.childNodes.length) {
            // no need to create a new parent element, but it's not supported by IE 10 and older.
            // const arrowEl = document.createRange().createContextualFragment(arrow);
            var arrowEl = document.createElement('div');
            arrowEl.innerHTML = arrow;
            el.appendChild(arrowEl);
          }
        }
      };

      TooltipHTMLContent.prototype.setEnterable = function (enterable) {
        this._enterable = enterable;
      };

      TooltipHTMLContent.prototype.getSize = function () {
        var el = this.el;
        return [el.offsetWidth, el.offsetHeight];
      };

      TooltipHTMLContent.prototype.moveTo = function (zrX, zrY) {
        var styleCoord = this._styleCoord;
        makeStyleCoord(styleCoord, this._zr, this._appendToBody, zrX, zrY);

        if (styleCoord[0] != null && styleCoord[1] != null) {
          var style_1 = this.el.style;
          var transforms = assembleTransform(styleCoord[0], styleCoord[1]);
          each(transforms, function (transform) {
            style_1[transform[0]] = transform[1];
          });
        }
      };
      /**
       * when `alwaysShowContent` is true,
       * move the tooltip after chart resized
       */


      TooltipHTMLContent.prototype._moveIfResized = function () {
        // The ratio of left to width
        var ratioX = this._styleCoord[2]; // The ratio of top to height

        var ratioY = this._styleCoord[3];
        this.moveTo(ratioX * this._zr.getWidth(), ratioY * this._zr.getHeight());
      };

      TooltipHTMLContent.prototype.hide = function () {
        var _this = this;

        var style = this.el.style;
        style.visibility = 'hidden';
        style.opacity = '0';
        env.transform3dSupported && (style.willChange = '');
        this._show = false;
        this._longHideTimeout = setTimeout(function () {
          return _this._longHide = true;
        }, 500);
      };

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

      TooltipHTMLContent.prototype.isShow = function () {
        return this._show;
      };

      TooltipHTMLContent.prototype.dispose = function () {
        this.el.parentNode.removeChild(this.el);
      };

      return TooltipHTMLContent;
    }();

    var TooltipRichContent =
    /** @class */
    function () {
      function TooltipRichContent(api) {
        this._show = false;
        this._styleCoord = [0, 0, 0, 0];
        this._enterable = true;
        this._zr = api.getZr();
        makeStyleCoord$1(this._styleCoord, this._zr, api.getWidth() / 2, api.getHeight() / 2);
      }
      /**
       * Update when tooltip is rendered
       */


      TooltipRichContent.prototype.update = function (tooltipModel) {
        var alwaysShowContent = tooltipModel.get('alwaysShowContent');
        alwaysShowContent && this._moveIfResized();
      };

      TooltipRichContent.prototype.show = function () {
        if (this._hideTimeout) {
          clearTimeout(this._hideTimeout);
        }

        this.el.show();
        this._show = true;
      };
      /**
       * Set tooltip content
       */


      TooltipRichContent.prototype.setContent = function (content, markupStyleCreator, tooltipModel, borderColor, arrowPosition) {
        var _this = this;

        if (isObject(content)) {
          throwError("development" !== 'production' ? 'Passing DOM nodes as content is not supported in richText tooltip!' : '');
        }

        if (this.el) {
          this._zr.remove(this.el);
        }

        var textStyleModel = tooltipModel.getModel('textStyle');
        this.el = new ZRText({
          style: {
            rich: markupStyleCreator.richTextStyles,
            text: content,
            lineHeight: 22,
            borderWidth: 1,
            borderColor: borderColor,
            textShadowColor: textStyleModel.get('textShadowColor'),
            fill: tooltipModel.get(['textStyle', 'color']),
            padding: getPaddingFromTooltipModel(tooltipModel, 'richText'),
            verticalAlign: 'top',
            align: 'left'
          },
          z: tooltipModel.get('z')
        });
        each(['backgroundColor', 'borderRadius', 'shadowColor', 'shadowBlur', 'shadowOffsetX', 'shadowOffsetY'], function (propName) {
          _this.el.style[propName] = tooltipModel.get(propName);
        });
        each(['textShadowBlur', 'textShadowOffsetX', 'textShadowOffsetY'], function (propName) {
          _this.el.style[propName] = textStyleModel.get(propName) || 0;
        });

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

      TooltipRichContent.prototype.setEnterable = function (enterable) {
        this._enterable = enterable;
      };

      TooltipRichContent.prototype.getSize = function () {
        var el = this.el;
        var bounding = this.el.getBoundingRect(); // bounding rect does not include shadow. For renderMode richText,
        // if overflow, it will be cut. So calculate them accurately.

        var shadowOuterSize = calcShadowOuterSize(el.style);
        return [bounding.width + shadowOuterSize.left + shadowOuterSize.right, bounding.height + shadowOuterSize.top + shadowOuterSize.bottom];
      };

      TooltipRichContent.prototype.moveTo = function (x, y) {
        var el = this.el;

        if (el) {
          var styleCoord = this._styleCoord;
          makeStyleCoord$1(styleCoord, this._zr, x, y);
          x = styleCoord[0];
          y = styleCoord[1];
          var style = el.style;
          var borderWidth = mathMaxWith0(style.borderWidth || 0);
          var shadowOuterSize = calcShadowOuterSize(style); // rich text x, y do not include border.

          el.x = x + borderWidth + shadowOuterSize.left;
          el.y = y + borderWidth + shadowOuterSize.top;
          el.markRedraw();
        }
      };
      /**
       * when `alwaysShowContent` is true,
       * move the tooltip after chart resized
       */


      TooltipRichContent.prototype._moveIfResized = function () {
        // The ratio of left to width
        var ratioX = this._styleCoord[2]; // The ratio of top to height

        var ratioY = this._styleCoord[3];
        this.moveTo(ratioX * this._zr.getWidth(), ratioY * this._zr.getHeight());
      };

      TooltipRichContent.prototype.hide = function () {
        if (this.el) {
          this.el.hide();
        }

        this._show = false;
      };

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

      TooltipRichContent.prototype.isShow = function () {
        return this._show;
      };

      TooltipRichContent.prototype.dispose = function () {
        this._zr.remove(this.el);
      };

      return TooltipRichContent;
    }();

    function mathMaxWith0(val) {
      return Math.max(0, val);
    }

    function calcShadowOuterSize(style) {
      var shadowBlur = mathMaxWith0(style.shadowBlur || 0);
      var shadowOffsetX = mathMaxWith0(style.shadowOffsetX || 0);
      var shadowOffsetY = mathMaxWith0(style.shadowOffsetY || 0);
      return {
        left: mathMaxWith0(shadowBlur - shadowOffsetX),
        right: mathMaxWith0(shadowBlur + shadowOffsetX),
        top: mathMaxWith0(shadowBlur - shadowOffsetY),
        bottom: mathMaxWith0(shadowBlur + shadowOffsetY)
      };
    }

    function makeStyleCoord$1(out, zr, zrX, zrY) {
      out[0] = zrX;
      out[1] = zrY;
      out[2] = out[0] / zr.getWidth();
      out[3] = out[1] / zr.getHeight();
    }

    var proxyRect = new Rect({
      shape: {
        x: -1,
        y: -1,
        width: 2,
        height: 2
      }
    });

    var TooltipView =
    /** @class */
    function (_super) {
      __extends(TooltipView, _super);

      function TooltipView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = TooltipView.type;
        return _this;
      }

      TooltipView.prototype.init = function (ecModel, api) {
        if (env.node || !api.getDom()) {
          return;
        }

        var tooltipModel = ecModel.getComponent('tooltip');
        var renderMode = this._renderMode = getTooltipRenderMode(tooltipModel.get('renderMode'));
        this._tooltipContent = renderMode === 'richText' ? new TooltipRichContent(api) : new TooltipHTMLContent(api.getDom(), api, {
          appendToBody: tooltipModel.get('appendToBody', true)
        });
      };

      TooltipView.prototype.render = function (tooltipModel, ecModel, api) {
        if (env.node || !api.getDom()) {
          return;
        } // Reset


        this.group.removeAll();
        this._tooltipModel = tooltipModel;
        this._ecModel = ecModel;
        this._api = api;
        /**
         * @private
         * @type {boolean}
         */

        this._alwaysShowContent = tooltipModel.get('alwaysShowContent');
        var tooltipContent = this._tooltipContent;
        tooltipContent.update(tooltipModel);
        tooltipContent.setEnterable(tooltipModel.get('enterable'));

        this._initGlobalListener();

        this._keepShow(); // PENDING
        // `mousemove` event will be triggered very frequently when the mouse moves fast,
        // which causes that the `updatePosition` function was also called frequently.
        // In Chrome with devtools open and Firefox, tooltip looks laggy and shakes. See #14695 #16101
        // To avoid frequent triggering,
        // consider throttling it in 50ms when transition is enabled


        if (this._renderMode !== 'richText' && tooltipModel.get('transitionDuration')) {
          createOrUpdate(this, '_updatePosition', 50, 'fixRate');
        } else {
          clear(this, '_updatePosition');
        }
      };

      TooltipView.prototype._initGlobalListener = function () {
        var tooltipModel = this._tooltipModel;
        var triggerOn = tooltipModel.get('triggerOn');
        register('itemTooltip', this._api, bind(function (currTrigger, e, dispatchAction) {
          // If 'none', it is not controlled by mouse totally.
          if (triggerOn !== 'none') {
            if (triggerOn.indexOf(currTrigger) >= 0) {
              this._tryShow(e, dispatchAction);
            } else if (currTrigger === 'leave') {
              this._hide(dispatchAction);
            }
          }
        }, this));
      };

      TooltipView.prototype._keepShow = function () {
        var tooltipModel = this._tooltipModel;
        var ecModel = this._ecModel;
        var api = this._api;
        var triggerOn = tooltipModel.get('triggerOn'); // 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.
        && triggerOn !== 'none' && triggerOn !== 'click') {
          var self_1 = 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_1.manuallyShowTip(tooltipModel, ecModel, api, {
              x: self_1._lastX,
              y: self_1._lastY,
              dataByCoordSys: self_1._lastDataByCoordSys
            });
          });
        }
      };
      /**
       * Show tip manually by
       * dispatchAction({
       *     type: 'showTip',
       *     x: 10,
       *     y: 10
       * });
       * Or
       * dispatchAction({
       *      type: 'showTip',
       *      seriesIndex: 0,
       *      dataIndex or dataIndexInside or name
       * });
       *
       *  TODO Batch
       */


      TooltipView.prototype.manuallyShowTip = function (tooltipModel, ecModel, api, payload) {
        if (payload.from === this.uid || env.node || !api.getDom()) {
          return;
        }

        var dispatchAction = makeDispatchAction$1(payload, api); // Reset ticket

        this._ticket = ''; // When triggered from axisPointer.

        var dataByCoordSys = payload.dataByCoordSys;
        var cmptRef = findComponentReference(payload, ecModel, api);

        if (cmptRef) {
          var rect = cmptRef.el.getBoundingRect().clone();
          rect.applyTransform(cmptRef.el.transform);

          this._tryShow({
            offsetX: rect.x + rect.width / 2,
            offsetY: rect.y + rect.height / 2,
            target: cmptRef.el,
            position: payload.position,
            // When manully trigger, the mouse is not on the el, so we'd better to
            // position tooltip on the bottom of the el and display arrow is possible.
            positionDefault: 'bottom'
          }, dispatchAction);
        } else if (payload.tooltip && payload.x != null && payload.y != null) {
          var el = proxyRect;
          el.x = payload.x;
          el.y = payload.y;
          el.update();
          getECData(el).tooltipConfig = {
            name: null,
            option: 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: 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,
              target: pointInfo.el,
              position: payload.position,
              // When manully trigger, the mouse is not on the el, so we'd better to
              // position tooltip on the bottom of the el and display arrow is possible.
              positionDefault: 'bottom'
            }, 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);
        }
      };

      TooltipView.prototype.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 = this._lastDataByCoordSys = 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.


      TooltipView.prototype._manuallyAxisShowTip = function (tooltipModel, ecModel, api, payload) {
        var seriesIndex = payload.seriesIndex;
        var dataIndex = payload.dataIndex; // @ts-ignore

        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 tooltipCascadedModel = buildTooltipModel([data.getItemModel(dataIndex), seriesModel, (seriesModel.coordinateSystem || {}).model], this._tooltipModel);

        if (tooltipCascadedModel.get('trigger') !== 'axis') {
          return;
        }

        api.dispatchAction({
          type: 'updateAxisPointer',
          seriesIndex: seriesIndex,
          dataIndex: dataIndex,
          position: payload.position
        });
        return true;
      };

      TooltipView.prototype._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);
        } else if (el) {
          this._lastDataByCoordSys = null;
          var seriesDispatcher_1;
          var cmptDispatcher_1;
          findEventDispatcher(el, function (target) {
            // Always show item tooltip if mouse is on the element with dataIndex
            if (getECData(target).dataIndex != null) {
              seriesDispatcher_1 = target;
              return true;
            } // Tooltip provided directly. Like legend.


            if (getECData(target).tooltipConfig != null) {
              cmptDispatcher_1 = target;
              return true;
            }
          }, true);

          if (seriesDispatcher_1) {
            this._showSeriesItemTooltip(e, seriesDispatcher_1, dispatchAction);
          } else if (cmptDispatcher_1) {
            this._showComponentItemTooltip(e, cmptDispatcher_1, dispatchAction);
          } else {
            this._hide(dispatchAction);
          }
        } else {
          this._lastDataByCoordSys = null;

          this._hide(dispatchAction);
        }
      };

      TooltipView.prototype._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();
      };

      TooltipView.prototype._showAxisTooltip = function (dataByCoordSys, e) {
        var ecModel = this._ecModel;
        var globalTooltipModel = this._tooltipModel;
        var point = [e.offsetX, e.offsetY];
        var singleTooltipModel = buildTooltipModel([e.tooltipOption], globalTooltipModel);
        var renderMode = this._renderMode;
        var cbParamsList = [];
        var articleMarkup = createTooltipMarkup('section', {
          blocks: [],
          noHeader: true
        }); // Only for legacy: `Serise['formatTooltip']` returns a string.

        var markupTextArrLegacy = [];
        var markupStyleCreator = new TooltipMarkupStyleCreator();
        each(dataByCoordSys, function (itemCoordSys) {
          each(itemCoordSys.dataByAxis, function (axisItem) {
            var axisModel = ecModel.getComponent(axisItem.axisDim + 'Axis', axisItem.axisIndex);
            var axisValue = axisItem.value;

            if (!axisModel || axisValue == null) {
              return;
            }

            var axisValueLabel = getValueLabel(axisValue, axisModel.axis, ecModel, axisItem.seriesDataIndices, axisItem.valueLabelOpt);
            var axisSectionMarkup = createTooltipMarkup('section', {
              header: axisValueLabel,
              noHeader: !trim(axisValueLabel),
              sortBlocks: true,
              blocks: []
            });
            articleMarkup.blocks.push(axisSectionMarkup);
            each(axisItem.seriesDataIndices, function (idxItem) {
              var series = ecModel.getSeriesByIndex(idxItem.seriesIndex);
              var dataIndex = idxItem.dataIndexInside;
              var cbParams = series.getDataParams(dataIndex); // Can't find data.

              if (cbParams.dataIndex < 0) {
                return;
              }

              cbParams.axisDim = axisItem.axisDim;
              cbParams.axisIndex = axisItem.axisIndex;
              cbParams.axisType = axisItem.axisType;
              cbParams.axisId = axisItem.axisId;
              cbParams.axisValue = getAxisRawValue(axisModel.axis, {
                value: axisValue
              });
              cbParams.axisValueLabel = axisValueLabel; // Pre-create marker style for makers. Users can assemble richText
              // text in `formatter` callback and use those markers style.

              cbParams.marker = markupStyleCreator.makeTooltipMarker('item', convertToColorString(cbParams.color), renderMode);
              var seriesTooltipResult = normalizeTooltipFormatResult(series.formatTooltip(dataIndex, true, null));
              var frag = seriesTooltipResult.frag;

              if (frag) {
                var valueFormatter = buildTooltipModel([series], globalTooltipModel).get('valueFormatter');
                axisSectionMarkup.blocks.push(valueFormatter ? extend({
                  valueFormatter: valueFormatter
                }, frag) : frag);
              }

              if (seriesTooltipResult.text) {
                markupTextArrLegacy.push(seriesTooltipResult.text);
              }

              cbParamsList.push(cbParams);
            });
          });
        }); // In most cases, the second axis is displays upper on the first one.
        // So we reverse it to look better.

        articleMarkup.blocks.reverse();
        markupTextArrLegacy.reverse();
        var positionExpr = e.position;
        var orderMode = singleTooltipModel.get('order');
        var builtMarkupText = buildTooltipMarkup(articleMarkup, markupStyleCreator, renderMode, orderMode, ecModel.get('useUTC'), singleTooltipModel.get('textStyle'));
        builtMarkupText && markupTextArrLegacy.unshift(builtMarkupText);
        var blockBreak = renderMode === 'richText' ? '\n\n' : '<br/>';
        var allMarkupText = markupTextArrLegacy.join(blockBreak);

        this._showOrMove(singleTooltipModel, function () {
          if (this._updateContentNotChangedOnAxis(dataByCoordSys, cbParamsList)) {
            this._updatePosition(singleTooltipModel, positionExpr, point[0], point[1], this._tooltipContent, cbParamsList);
          } else {
            this._showTooltipContent(singleTooltipModel, allMarkupText, cbParamsList, Math.random() + '', point[0], point[1], positionExpr, null, markupStyleCreator);
          }
        }); // Do not trigger events here, because this branch only be entered
        // from dispatchAction.

      };

      TooltipView.prototype._showSeriesItemTooltip = function (e, dispatcher, dispatchAction) {
        var ecModel = this._ecModel;
        var ecData = getECData(dispatcher); // 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 = ecData.seriesIndex;
        var seriesModel = ecModel.getSeriesByIndex(seriesIndex); // For example, graph link.

        var dataModel = ecData.dataModel || seriesModel;
        var dataIndex = ecData.dataIndex;
        var dataType = ecData.dataType;
        var data = dataModel.getData(dataType);
        var renderMode = this._renderMode;
        var positionDefault = e.positionDefault;
        var tooltipModel = buildTooltipModel([data.getItemModel(dataIndex), dataModel, seriesModel && (seriesModel.coordinateSystem || {}).model], this._tooltipModel, positionDefault ? {
          position: positionDefault
        } : null);
        var tooltipTrigger = tooltipModel.get('trigger');

        if (tooltipTrigger != null && tooltipTrigger !== 'item') {
          return;
        }

        var params = dataModel.getDataParams(dataIndex, dataType);
        var markupStyleCreator = new TooltipMarkupStyleCreator(); // Pre-create marker style for makers. Users can assemble richText
        // text in `formatter` callback and use those markers style.

        params.marker = markupStyleCreator.makeTooltipMarker('item', convertToColorString(params.color), renderMode);
        var seriesTooltipResult = normalizeTooltipFormatResult(dataModel.formatTooltip(dataIndex, false, dataType));
        var orderMode = tooltipModel.get('order');
        var valueFormatter = tooltipModel.get('valueFormatter');
        var frag = seriesTooltipResult.frag;
        var markupText = frag ? buildTooltipMarkup(valueFormatter ? extend({
          valueFormatter: valueFormatter
        }, frag) : frag, markupStyleCreator, renderMode, orderMode, ecModel.get('useUTC'), tooltipModel.get('textStyle')) : seriesTooltipResult.text;
        var asyncTicket = 'item_' + dataModel.name + '_' + dataIndex;

        this._showOrMove(tooltipModel, function () {
          this._showTooltipContent(tooltipModel, markupText, params, asyncTicket, e.offsetX, e.offsetY, e.position, e.target, markupStyleCreator);
        }); // FIXME
        // duplicated showtip if manuallyShowTip is called from dispatchAction.


        dispatchAction({
          type: 'showTip',
          dataIndexInside: dataIndex,
          dataIndex: data.getRawIndex(dataIndex),
          seriesIndex: seriesIndex,
          from: this.uid
        });
      };

      TooltipView.prototype._showComponentItemTooltip = function (e, el, dispatchAction) {
        var ecData = getECData(el);
        var tooltipConfig = ecData.tooltipConfig;
        var tooltipOpt = tooltipConfig.option || {};

        if (isString(tooltipOpt)) {
          var content = tooltipOpt;
          tooltipOpt = {
            content: content,
            // Fixed formatter
            formatter: content
          };
        }

        var tooltipModelCascade = [tooltipOpt];

        var cmpt = this._ecModel.getComponent(ecData.componentMainType, ecData.componentIndex);

        if (cmpt) {
          tooltipModelCascade.push(cmpt);
        } // In most cases, component tooltip formatter has different params with series tooltip formatter,
        // so that they can not share the same formatter. Since the global tooltip formatter is used for series
        // by convension, we do not use it as the default formatter for component.


        tooltipModelCascade.push({
          formatter: tooltipOpt.content
        });
        var positionDefault = e.positionDefault;
        var subTooltipModel = buildTooltipModel(tooltipModelCascade, this._tooltipModel, positionDefault ? {
          position: positionDefault
        } : null);
        var defaultHtml = subTooltipModel.get('content');
        var asyncTicket = Math.random() + ''; // PENDING: this case do not support richText style yet.

        var markupStyleCreator = new TooltipMarkupStyleCreator(); // 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 () {
          // Use formatterParams from element defined in component
          // Avoid users modify it.
          var formatterParams = clone(subTooltipModel.get('formatterParams') || {});

          this._showTooltipContent(subTooltipModel, defaultHtml, formatterParams, asyncTicket, e.offsetX, e.offsetY, e.position, el, markupStyleCreator);
        }); // If not dispatch showTip, tip may be hide triggered by axis.


        dispatchAction({
          type: 'showTip',
          from: this.uid
        });
      };

      TooltipView.prototype._showTooltipContent = function ( // Use Model<TooltipOption> insteadof TooltipModel because this model may be from series or other options.
      // Instead of top level tooltip.
      tooltipModel, defaultHtml, params, asyncTicket, x, y, positionExpr, el, markupStyleCreator) {
        // Reset ticket
        this._ticket = '';

        if (!tooltipModel.get('showContent') || !tooltipModel.get('show')) {
          return;
        }

        var tooltipContent = this._tooltipContent;
        tooltipContent.setEnterable(tooltipModel.get('enterable'));
        var formatter = tooltipModel.get('formatter');
        positionExpr = positionExpr || tooltipModel.get('position');
        var html = defaultHtml;

        var nearPoint = this._getNearestPoint([x, y], params, tooltipModel.get('trigger'), tooltipModel.get('borderColor'));

        var nearPointColor = nearPoint.color;

        if (formatter) {
          if (isString(formatter)) {
            var useUTC = tooltipModel.ecModel.get('useUTC');
            var params0 = isArray(params) ? params[0] : params;
            var isTimeAxis = params0 && params0.axisType && params0.axisType.indexOf('time') >= 0;
            html = formatter;

            if (isTimeAxis) {
              html = format(params0.axisValue, html, useUTC);
            }

            html = formatTpl(html, params, true);
          } else if (isFunction(formatter)) {
            var callback = bind(function (cbTicket, html) {
              if (cbTicket === this._ticket) {
                tooltipContent.setContent(html, markupStyleCreator, tooltipModel, nearPointColor, positionExpr);

                this._updatePosition(tooltipModel, positionExpr, x, y, tooltipContent, params, el);
              }
            }, this);
            this._ticket = asyncTicket;
            html = formatter(params, asyncTicket, callback);
          } else {
            html = formatter;
          }
        }

        tooltipContent.setContent(html, markupStyleCreator, tooltipModel, nearPointColor, positionExpr);
        tooltipContent.show(tooltipModel, nearPointColor);

        this._updatePosition(tooltipModel, positionExpr, x, y, tooltipContent, params, el);
      };

      TooltipView.prototype._getNearestPoint = function (point, tooltipDataParams, trigger, borderColor) {
        if (trigger === 'axis' || isArray(tooltipDataParams)) {
          return {
            color: borderColor || (this._renderMode === 'html' ? '#fff' : 'none')
          };
        }

        if (!isArray(tooltipDataParams)) {
          return {
            color: borderColor || tooltipDataParams.color || tooltipDataParams.borderColor
          };
        }
      };

      TooltipView.prototype._updatePosition = function (tooltipModel, positionExpr, x, // Mouse x
      y, // Mouse 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 (isFunction(positionExpr)) {
          // 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$1(positionExpr[0], viewWidth);
          y = parsePercent$1(positionExpr[1], viewHeight);
        } else if (isObject(positionExpr)) {
          var boxLayoutPosition = positionExpr;
          boxLayoutPosition.width = contentSize[0];
          boxLayoutPosition.height = contentSize[1];
          var layoutRect = getLayoutRect(boxLayoutPosition, {
            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 (isString(positionExpr) && el) {
            var pos = calcTooltipPosition(positionExpr, rect, contentSize, tooltipModel.get('borderWidth'));
            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 (shouldTooltipConfine(tooltipModel)) {
          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?


      TooltipView.prototype._updateContentNotChangedOnAxis = function (dataByCoordSys, cbParamsList) {
        var lastCoordSys = this._lastDataByCoordSys;
        var lastCbParamsList = this._cbParamsList;
        var contentNotChanged = !!lastCoordSys && lastCoordSys.length === dataByCoordSys.length;
        contentNotChanged && each(lastCoordSys, function (lastItemCoordSys, indexCoordSys) {
          var lastDataByAxis = lastItemCoordSys.dataByAxis || [];
          var thisItemCoordSys = dataByCoordSys[indexCoordSys] || {};
          var thisDataByAxis = thisItemCoordSys.dataByAxis || [];
          contentNotChanged = contentNotChanged && lastDataByAxis.length === thisDataByAxis.length;
          contentNotChanged && each(lastDataByAxis, function (lastItem, indexAxis) {
            var thisItem = thisDataByAxis[indexAxis] || {};
            var lastIndices = lastItem.seriesDataIndices || [];
            var newIndices = thisItem.seriesDataIndices || [];
            contentNotChanged = contentNotChanged && lastItem.value === thisItem.value && lastItem.axisType === thisItem.axisType && lastItem.axisId === thisItem.axisId && lastIndices.length === newIndices.length;
            contentNotChanged && each(lastIndices, function (lastIdxItem, j) {
              var newIdxItem = newIndices[j];
              contentNotChanged = contentNotChanged && lastIdxItem.seriesIndex === newIdxItem.seriesIndex && lastIdxItem.dataIndex === newIdxItem.dataIndex;
            }); // check is cbParams data value changed

            lastCbParamsList && each(lastItem.seriesDataIndices, function (idxItem) {
              var seriesIdx = idxItem.seriesIndex;
              var cbParams = cbParamsList[seriesIdx];
              var lastCbParams = lastCbParamsList[seriesIdx];

              if (cbParams && lastCbParams && lastCbParams.data !== cbParams.data) {
                contentNotChanged = false;
              }
            });
          });
        });
        this._lastDataByCoordSys = dataByCoordSys;
        this._cbParamsList = cbParamsList;
        return !!contentNotChanged;
      };

      TooltipView.prototype._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
        });
      };

      TooltipView.prototype.dispose = function (ecModel, api) {
        if (env.node || !api.getDom()) {
          return;
        }

        clear(this, '_updatePosition');

        this._tooltipContent.dispose();

        unregister('itemTooltip', api);
      };

      TooltipView.type = 'tooltip';
      return TooltipView;
    }(ComponentView);
    /**
     * From top to bottom. (the last one should be globalTooltipModel);
     */


    function buildTooltipModel(modelCascade, globalTooltipModel, defaultTooltipOption) {
      // Last is always tooltip model.
      var ecModel = globalTooltipModel.ecModel;
      var resultModel;

      if (defaultTooltipOption) {
        resultModel = new Model(defaultTooltipOption, ecModel, ecModel);
        resultModel = new Model(globalTooltipModel.option, resultModel, ecModel);
      } else {
        resultModel = globalTooltipModel;
      }

      for (var i = modelCascade.length - 1; i >= 0; i--) {
        var tooltipOpt = modelCascade[i];

        if (tooltipOpt) {
          if (tooltipOpt instanceof Model) {
            tooltipOpt = tooltipOpt.get('tooltip', true);
          } // In each data item tooltip can be simply write:
          // {
          //  value: 10,
          //  tooltip: 'Something you need to know'
          // }


          if (isString(tooltipOpt)) {
            tooltipOpt = {
              formatter: tooltipOpt
            };
          }

          if (tooltipOpt) {
            resultModel = new Model(tooltipOpt, 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.getSize();
      var width = size[0];
      var height = size[1];

      if (gapH != null) {
        // Add extra 2 pixels for this case:
        // At present the "values" in defaut tooltip are using CSS `float: right`.
        // When the right edge of the tooltip box is on the right side of the
        // viewport, the `float` layout might push the "values" to the second line.
        if (x + width + gapH + 2 > 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.getSize();
      var width = size[0];
      var height = size[1];
      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, borderWidth) {
      var domWidth = contentSize[0];
      var domHeight = contentSize[1];
      var offset = Math.ceil(Math.SQRT2 * borderWidth) + 8;
      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 - offset;
          break;

        case 'bottom':
          x = rect.x + rectWidth / 2 - domWidth / 2;
          y = rect.y + rectHeight + offset;
          break;

        case 'left':
          x = rect.x - domWidth - offset;
          y = rect.y + rectHeight / 2 - domHeight / 2;
          break;

        case 'right':
          x = rect.x + rectWidth + offset;
          y = rect.y + rectHeight / 2 - domHeight / 2;
      }

      return [x, y];
    }

    function isCenterAlign(align) {
      return align === 'center' || align === 'middle';
    }
    /**
     * Find target component by payload like:
     * ```js
     * { legendId: 'some_id', name: 'xxx' }
     * { toolboxIndex: 1, name: 'xxx' }
     * { geoName: 'some_name', name: 'xxx' }
     * ```
     * PENDING: at present only
     *
     * If not found, return null/undefined.
     */


    function findComponentReference(payload, ecModel, api) {
      var queryOptionMap = preParseFinder(payload).queryOptionMap;
      var componentMainType = queryOptionMap.keys()[0];

      if (!componentMainType || componentMainType === 'series') {
        return;
      }

      var queryResult = queryReferringComponents(ecModel, componentMainType, queryOptionMap.get(componentMainType), {
        useDefault: false,
        enableAll: false,
        enableNone: false
      });
      var model = queryResult.models[0];

      if (!model) {
        return;
      }

      var view = api.getViewOfComponentModel(model);
      var el;
      view.group.traverse(function (subEl) {
        var tooltipConfig = getECData(subEl).tooltipConfig;

        if (tooltipConfig && tooltipConfig.name === payload.name) {
          el = subEl;
          return true; // stop
        }
      });

      if (el) {
        return {
          componentMainType: componentMainType,
          componentIndex: model.componentIndex,
          el: el
        };
      }
    }

    function install$A(registers) {
      use(install$s);
      registers.registerComponentModel(TooltipModel);
      registers.registerComponentView(TooltipView);
      /**
       * @action
       * @property {string} type
       * @property {number} seriesIndex
       * @property {number} dataIndex
       * @property {number} [x]
       * @property {number} [y]
       */

      registers.registerAction({
        type: 'showTip',
        event: 'showTip',
        update: 'tooltip:manuallyShowTip'
      }, noop);
      registers.registerAction({
        type: 'hideTip',
        event: 'hideTip',
        update: 'tooltip:manuallyHideTip'
      }, noop);
    }

    var DEFAULT_TOOLBOX_BTNS = ['rect', 'polygon', 'keep', 'clear'];
    function brushPreprocessor(option, isNew) {
      var brushComponents = normalizeToArray(option ? option.brush : []);

      if (!brushComponents.length) {
        return;
      }

      var brushComponentSpecifiedBtns = [];
      each(brushComponents, function (brushOpt) {
        var tbs = brushOpt.hasOwnProperty('toolbox') ? brushOpt.toolbox : [];

        if (tbs instanceof Array) {
          brushComponentSpecifiedBtns = brushComponentSpecifiedBtns.concat(tbs);
        }
      });
      var toolbox = option && option.toolbox;

      if (isArray(toolbox)) {
        toolbox = toolbox[0];
      }

      if (!toolbox) {
        toolbox = {
          feature: {}
        };
        option.toolbox = [toolbox];
      }

      var toolboxFeature = toolbox.feature || (toolbox.feature = {});
      var toolboxBrush = toolboxFeature.brush || (toolboxFeature.brush = {});
      var brushTypes = toolboxBrush.type || (toolboxBrush.type = []);
      brushTypes.push.apply(brushTypes, brushComponentSpecifiedBtns);
      removeDuplicate(brushTypes);

      if (isNew && !brushTypes.length) {
        brushTypes.push.apply(brushTypes, DEFAULT_TOOLBOX_BTNS);
      }
    }

    function removeDuplicate(arr) {
      var map = {};
      each(arr, function (val) {
        map[val] = 1;
      });
      arr.length = 0;
      each(map, function (flag, val) {
        arr.push(val);
      });
    }

    var each$b = each;

    function hasKeys(obj) {
      if (obj) {
        for (var name_1 in obj) {
          if (obj.hasOwnProperty(name_1)) {
            return true;
          }
        }
      }
    }

    function createVisualMappings(option, stateList, supplementVisualOption) {
      var visualMappings = {};
      each$b(stateList, function (state) {
        var mappings = visualMappings[state] = createMappings();
        each$b(option[state], function (visualData, visualType) {
          if (!VisualMapping.isValidType(visualType)) {
            return;
          }

          var mappingOption = {
            type: visualType,
            visual: visualData
          };
          supplementVisualOption && supplementVisualOption(mappingOption, state);
          mappings[visualType] = new VisualMapping(mappingOption); // Prepare a alpha for opacity, for some case that opacity
          // is not supported, such as rendering using gradient color.

          if (visualType === 'opacity') {
            mappingOption = clone(mappingOption);
            mappingOption.type = 'colorAlpha';
            mappings.__hidden.__alphaForOpacity = new VisualMapping(mappingOption);
          }
        });
      });
      return visualMappings;

      function createMappings() {
        var Creater = function () {}; // Make sure hidden fields will not be visited by
        // object iteration (with hasOwnProperty checking).


        Creater.prototype.__hidden = Creater.prototype;
        var obj = new Creater();
        return obj;
      }
    }
    function replaceVisualOption(thisOption, newOption, keys) {
      // Visual attributes merge is not supported, otherwise it
      // brings overcomplicated merge logic. See #2853. So if
      // newOption has anyone of these keys, all of these keys
      // will be reset. Otherwise, all keys remain.
      var has;
      each(keys, function (key) {
        if (newOption.hasOwnProperty(key) && hasKeys(newOption[key])) {
          has = true;
        }
      });
      has && each(keys, function (key) {
        if (newOption.hasOwnProperty(key) && hasKeys(newOption[key])) {
          thisOption[key] = clone(newOption[key]);
        } else {
          delete thisOption[key];
        }
      });
    }
    /**
     * @param stateList
     * @param visualMappings
     * @param list
     * @param getValueState param: valueOrIndex, return: state.
     * @param scope Scope for getValueState
     * @param dimension Concrete dimension, if used.
     */
    // ???! handle brush?

    function applyVisual(stateList, visualMappings, data, getValueState, scope, dimension) {
      var visualTypesMap = {};
      each(stateList, function (state) {
        var visualTypes = VisualMapping.prepareVisualTypes(visualMappings[state]);
        visualTypesMap[state] = visualTypes;
      });
      var dataIndex;

      function getVisual(key) {
        return getItemVisualFromData(data, dataIndex, key);
      }

      function setVisual(key, value) {
        setItemVisualFromData(data, dataIndex, key, value);
      }

      if (dimension == null) {
        data.each(eachItem);
      } else {
        data.each([dimension], eachItem);
      }

      function eachItem(valueOrIndex, index) {
        dataIndex = dimension == null ? valueOrIndex // First argument is index
        : index;
        var rawDataItem = data.getRawDataItem(dataIndex); // Consider performance
        // @ts-ignore

        if (rawDataItem && rawDataItem.visualMap === false) {
          return;
        }

        var valueState = getValueState.call(scope, valueOrIndex);
        var mappings = visualMappings[valueState];
        var visualTypes = visualTypesMap[valueState];

        for (var i = 0, len = visualTypes.length; i < len; i++) {
          var type = visualTypes[i];
          mappings[type] && mappings[type].applyVisual(valueOrIndex, getVisual, setVisual);
        }
      }
    }
    /**
     * @param data
     * @param stateList
     * @param visualMappings <state, Object.<visualType, module:echarts/visual/VisualMapping>>
     * @param getValueState param: valueOrIndex, return: state.
     * @param dim dimension or dimension index.
     */

    function incrementalApplyVisual(stateList, visualMappings, getValueState, dim) {
      var visualTypesMap = {};
      each(stateList, function (state) {
        var visualTypes = VisualMapping.prepareVisualTypes(visualMappings[state]);
        visualTypesMap[state] = visualTypes;
      });
      return {
        progress: function progress(params, data) {
          var dimIndex;

          if (dim != null) {
            dimIndex = data.getDimensionIndex(dim);
          }

          function getVisual(key) {
            return getItemVisualFromData(data, dataIndex, key);
          }

          function setVisual(key, value) {
            setItemVisualFromData(data, dataIndex, key, value);
          }

          var dataIndex;
          var store = data.getStore();

          while ((dataIndex = params.next()) != null) {
            var rawDataItem = data.getRawDataItem(dataIndex); // Consider performance
            // @ts-ignore

            if (rawDataItem && rawDataItem.visualMap === false) {
              continue;
            }

            var value = dim != null ? store.get(dimIndex, dataIndex) : dataIndex;
            var valueState = getValueState(value);
            var mappings = visualMappings[valueState];
            var visualTypes = visualTypesMap[valueState];

            for (var i = 0, len = visualTypes.length; i < len; i++) {
              var type = visualTypes[i];
              mappings[type] && mappings[type].applyVisual(value, getVisual, setVisual);
            }
          }
        }
      };
    }

    function makeBrushCommonSelectorForSeries(area) {
      var brushType = area.brushType; // Do not use function binding or curry for performance.

      var selectors = {
        point: function (itemLayout) {
          return selector[brushType].point(itemLayout, selectors, area);
        },
        rect: function (itemLayout) {
          return selector[brushType].rect(itemLayout, selectors, area);
        }
      };
      return selectors;
    }
    var selector = {
      lineX: getLineSelectors(0),
      lineY: getLineSelectors(1),
      rect: {
        point: function (itemLayout, selectors, area) {
          return itemLayout && area.boundingRect.contain(itemLayout[0], itemLayout[1]);
        },
        rect: function (itemLayout, selectors, area) {
          return itemLayout && area.boundingRect.intersect(itemLayout);
        }
      },
      polygon: {
        point: function (itemLayout, selectors, area) {
          return itemLayout && area.boundingRect.contain(itemLayout[0], itemLayout[1]) && contain$2(area.range, itemLayout[0], itemLayout[1]);
        },
        rect: function (itemLayout, selectors, area) {
          var points = area.range;

          if (!itemLayout || points.length <= 1) {
            return false;
          }

          var x = itemLayout.x;
          var y = itemLayout.y;
          var width = itemLayout.width;
          var height = itemLayout.height;
          var p = points[0];

          if (contain$2(points, x, y) || contain$2(points, x + width, y) || contain$2(points, x, y + height) || contain$2(points, x + width, y + height) || BoundingRect.create(itemLayout).contain(p[0], p[1]) || linePolygonIntersect(x, y, x + width, y, points) || linePolygonIntersect(x, y, x, y + height, points) || linePolygonIntersect(x + width, y, x + width, y + height, points) || linePolygonIntersect(x, y + height, x + width, y + height, points)) {
            return true;
          }
        }
      }
    };

    function getLineSelectors(xyIndex) {
      var xy = ['x', 'y'];
      var wh = ['width', 'height'];
      return {
        point: function (itemLayout, selectors, area) {
          if (itemLayout) {
            var range = area.range;
            var p = itemLayout[xyIndex];
            return inLineRange(p, range);
          }
        },
        rect: function (itemLayout, selectors, area) {
          if (itemLayout) {
            var range = area.range;
            var layoutRange = [itemLayout[xy[xyIndex]], itemLayout[xy[xyIndex]] + itemLayout[wh[xyIndex]]];
            layoutRange[1] < layoutRange[0] && layoutRange.reverse();
            return inLineRange(layoutRange[0], range) || inLineRange(layoutRange[1], range) || inLineRange(range[0], layoutRange) || inLineRange(range[1], layoutRange);
          }
        }
      };
    }

    function inLineRange(p, range) {
      return range[0] <= p && p <= range[1];
    }

    var STATE_LIST = ['inBrush', 'outOfBrush'];
    var DISPATCH_METHOD = '__ecBrushSelect';
    var DISPATCH_FLAG = '__ecInBrushSelectEvent';
    function layoutCovers(ecModel) {
      ecModel.eachComponent({
        mainType: 'brush'
      }, function (brushModel) {
        var brushTargetManager = brushModel.brushTargetManager = new BrushTargetManager(brushModel.option, ecModel);
        brushTargetManager.setInputRanges(brushModel.areas, ecModel);
      });
    }
    /**
     * Register the visual encoding if this modules required.
     */

    function brushVisual(ecModel, api, payload) {
      var brushSelected = [];
      var throttleType;
      var throttleDelay;
      ecModel.eachComponent({
        mainType: 'brush'
      }, function (brushModel) {
        payload && payload.type === 'takeGlobalCursor' && brushModel.setBrushOption(payload.key === 'brush' ? payload.brushOption : {
          brushType: false
        });
      });
      layoutCovers(ecModel);
      ecModel.eachComponent({
        mainType: 'brush'
      }, function (brushModel, brushIndex) {
        var thisBrushSelected = {
          brushId: brushModel.id,
          brushIndex: brushIndex,
          brushName: brushModel.name,
          areas: clone(brushModel.areas),
          selected: []
        }; // Every brush component exists in event params, convenient
        // for user to find by index.

        brushSelected.push(thisBrushSelected);
        var brushOption = brushModel.option;
        var brushLink = brushOption.brushLink;
        var linkedSeriesMap = [];
        var selectedDataIndexForLink = [];
        var rangeInfoBySeries = [];
        var hasBrushExists = false;

        if (!brushIndex) {
          // Only the first throttle setting works.
          throttleType = brushOption.throttleType;
          throttleDelay = brushOption.throttleDelay;
        } // Add boundingRect and selectors to range.


        var areas = map(brushModel.areas, function (area) {
          var builder = boundingRectBuilders[area.brushType];
          var selectableArea = defaults({
            boundingRect: builder ? builder(area) : void 0
          }, area);
          selectableArea.selectors = makeBrushCommonSelectorForSeries(selectableArea);
          return selectableArea;
        });
        var visualMappings = createVisualMappings(brushModel.option, STATE_LIST, function (mappingOption) {
          mappingOption.mappingMethod = 'fixed';
        });
        isArray(brushLink) && each(brushLink, function (seriesIndex) {
          linkedSeriesMap[seriesIndex] = 1;
        });

        function linkOthers(seriesIndex) {
          return brushLink === 'all' || !!linkedSeriesMap[seriesIndex];
        } // If no supported brush or no brush on the series,
        // all visuals should be in original state.


        function brushed(rangeInfoList) {
          return !!rangeInfoList.length;
        }
        /**
         * Logic for each series: (If the logic has to be modified one day, do it carefully!)
         *
         * ( brushed ┬ && ┬hasBrushExist ┬ && linkOthers  ) => StepA: ┬record, ┬ StepB: ┬visualByRecord.
         *   !brushed┘    ├hasBrushExist ┤                            └nothing,┘        ├visualByRecord.
         *                └!hasBrushExist┘                                              └nothing.
         * ( !brushed  && ┬hasBrushExist ┬ && linkOthers  ) => StepA:  nothing,  StepB: ┬visualByRecord.
         *                └!hasBrushExist┘                                              └nothing.
         * ( brushed ┬ &&                     !linkOthers ) => StepA:  nothing,  StepB: ┬visualByCheck.
         *   !brushed┘                                                                  └nothing.
         * ( !brushed  &&                     !linkOthers ) => StepA:  nothing,  StepB:  nothing.
         */
        // Step A


        ecModel.eachSeries(function (seriesModel, seriesIndex) {
          var rangeInfoList = rangeInfoBySeries[seriesIndex] = [];
          seriesModel.subType === 'parallel' ? stepAParallel(seriesModel, seriesIndex) : stepAOthers(seriesModel, seriesIndex, rangeInfoList);
        });

        function stepAParallel(seriesModel, seriesIndex) {
          var coordSys = seriesModel.coordinateSystem;
          hasBrushExists = hasBrushExists || coordSys.hasAxisBrushed();
          linkOthers(seriesIndex) && coordSys.eachActiveState(seriesModel.getData(), function (activeState, dataIndex) {
            activeState === 'active' && (selectedDataIndexForLink[dataIndex] = 1);
          });
        }

        function stepAOthers(seriesModel, seriesIndex, rangeInfoList) {
          if (!seriesModel.brushSelector || brushModelNotControll(brushModel, seriesIndex)) {
            return;
          }

          each(areas, function (area) {
            if (brushModel.brushTargetManager.controlSeries(area, seriesModel, ecModel)) {
              rangeInfoList.push(area);
            }

            hasBrushExists = hasBrushExists || brushed(rangeInfoList);
          });

          if (linkOthers(seriesIndex) && brushed(rangeInfoList)) {
            var data_1 = seriesModel.getData();
            data_1.each(function (dataIndex) {
              if (checkInRange(seriesModel, rangeInfoList, data_1, dataIndex)) {
                selectedDataIndexForLink[dataIndex] = 1;
              }
            });
          }
        } // Step B


        ecModel.eachSeries(function (seriesModel, seriesIndex) {
          var seriesBrushSelected = {
            seriesId: seriesModel.id,
            seriesIndex: seriesIndex,
            seriesName: seriesModel.name,
            dataIndex: []
          }; // Every series exists in event params, convenient
          // for user to find series by seriesIndex.

          thisBrushSelected.selected.push(seriesBrushSelected);
          var rangeInfoList = rangeInfoBySeries[seriesIndex];
          var data = seriesModel.getData();
          var getValueState = linkOthers(seriesIndex) ? function (dataIndex) {
            return selectedDataIndexForLink[dataIndex] ? (seriesBrushSelected.dataIndex.push(data.getRawIndex(dataIndex)), 'inBrush') : 'outOfBrush';
          } : function (dataIndex) {
            return checkInRange(seriesModel, rangeInfoList, data, dataIndex) ? (seriesBrushSelected.dataIndex.push(data.getRawIndex(dataIndex)), 'inBrush') : 'outOfBrush';
          }; // If no supported brush or no brush, all visuals are in original state.

          (linkOthers(seriesIndex) ? hasBrushExists : brushed(rangeInfoList)) && applyVisual(STATE_LIST, visualMappings, data, getValueState);
        });
      });
      dispatchAction(api, throttleType, throttleDelay, brushSelected, payload);
    }

    function dispatchAction(api, throttleType, throttleDelay, brushSelected, payload) {
      // This event will not be triggered when `setOpion`, otherwise dead lock may
      // triggered when do `setOption` in event listener, which we do not find
      // satisfactory way to solve yet. Some considered resolutions:
      // (a) Diff with prevoius selected data ant only trigger event when changed.
      // But store previous data and diff precisely (i.e., not only by dataIndex, but
      // also detect value changes in selected data) might bring complexity or fragility.
      // (b) Use spectial param like `silent` to suppress event triggering.
      // But such kind of volatile param may be weird in `setOption`.
      if (!payload) {
        return;
      }

      var zr = api.getZr();

      if (zr[DISPATCH_FLAG]) {
        return;
      }

      if (!zr[DISPATCH_METHOD]) {
        zr[DISPATCH_METHOD] = doDispatch;
      }

      var fn = createOrUpdate(zr, DISPATCH_METHOD, throttleDelay, throttleType);
      fn(api, brushSelected);
    }

    function doDispatch(api, brushSelected) {
      if (!api.isDisposed()) {
        var zr = api.getZr();
        zr[DISPATCH_FLAG] = true;
        api.dispatchAction({
          type: 'brushSelect',
          batch: brushSelected
        });
        zr[DISPATCH_FLAG] = false;
      }
    }

    function checkInRange(seriesModel, rangeInfoList, data, dataIndex) {
      for (var i = 0, len = rangeInfoList.length; i < len; i++) {
        var area = rangeInfoList[i];

        if (seriesModel.brushSelector(dataIndex, data, area.selectors, area)) {
          return true;
        }
      }
    }

    function brushModelNotControll(brushModel, seriesIndex) {
      var seriesIndices = brushModel.option.seriesIndex;
      return seriesIndices != null && seriesIndices !== 'all' && (isArray(seriesIndices) ? indexOf(seriesIndices, seriesIndex) < 0 : seriesIndex !== seriesIndices);
    }

    var boundingRectBuilders = {
      rect: function (area) {
        return getBoundingRectFromMinMax(area.range);
      },
      polygon: function (area) {
        var minMax;
        var range = area.range;

        for (var i = 0, len = range.length; i < len; i++) {
          minMax = minMax || [[Infinity, -Infinity], [Infinity, -Infinity]];
          var rg = range[i];
          rg[0] < minMax[0][0] && (minMax[0][0] = rg[0]);
          rg[0] > minMax[0][1] && (minMax[0][1] = rg[0]);
          rg[1] < minMax[1][0] && (minMax[1][0] = rg[1]);
          rg[1] > minMax[1][1] && (minMax[1][1] = rg[1]);
        }

        return minMax && getBoundingRectFromMinMax(minMax);
      }
    };

    function getBoundingRectFromMinMax(minMax) {
      return new BoundingRect(minMax[0][0], minMax[1][0], minMax[0][1] - minMax[0][0], minMax[1][1] - minMax[1][0]);
    }

    var BrushView =
    /** @class */
    function (_super) {
      __extends(BrushView, _super);

      function BrushView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = BrushView.type;
        return _this;
      }

      BrushView.prototype.init = function (ecModel, api) {
        this.ecModel = ecModel;
        this.api = api;
        this.model;
        (this._brushController = new BrushController(api.getZr())).on('brush', bind(this._onBrush, this)).mount();
      };

      BrushView.prototype.render = function (brushModel, ecModel, api, payload) {
        this.model = brushModel;

        this._updateController(brushModel, ecModel, api, payload);
      };

      BrushView.prototype.updateTransform = function (brushModel, ecModel, api, payload) {
        // PENDING: `updateTransform` is a little tricky, whose layout need
        // to be calculate mandatorily and other stages will not be performed.
        // Take care the correctness of the logic. See #11754 .
        layoutCovers(ecModel);

        this._updateController(brushModel, ecModel, api, payload);
      };

      BrushView.prototype.updateVisual = function (brushModel, ecModel, api, payload) {
        this.updateTransform(brushModel, ecModel, api, payload);
      };

      BrushView.prototype.updateView = function (brushModel, ecModel, api, payload) {
        this._updateController(brushModel, ecModel, api, payload);
      };

      BrushView.prototype._updateController = function (brushModel, ecModel, api, payload) {
        // Do not update controller when drawing.
        (!payload || payload.$from !== brushModel.id) && this._brushController.setPanels(brushModel.brushTargetManager.makePanelOpts(api)).enableBrush(brushModel.brushOption).updateCovers(brushModel.areas.slice());
      }; // updateLayout: updateController,
      // updateVisual: updateController,


      BrushView.prototype.dispose = function () {
        this._brushController.dispose();
      };

      BrushView.prototype._onBrush = function (eventParam) {
        var modelId = this.model.id;
        var areas = this.model.brushTargetManager.setOutputRanges(eventParam.areas, this.ecModel); // Action is not dispatched on drag end, because the drag end
        // emits the same params with the last drag move event, and
        // may have some delay when using touch pad, which makes
        // animation not smooth (when using debounce).

        (!eventParam.isEnd || eventParam.removeOnClick) && this.api.dispatchAction({
          type: 'brush',
          brushId: modelId,
          areas: clone(areas),
          $from: modelId
        });
        eventParam.isEnd && this.api.dispatchAction({
          type: 'brushEnd',
          brushId: modelId,
          areas: clone(areas),
          $from: modelId
        });
      };

      BrushView.type = 'brush';
      return BrushView;
    }(ComponentView);

    var DEFAULT_OUT_OF_BRUSH_COLOR = '#ddd';

    var BrushModel =
    /** @class */
    function (_super) {
      __extends(BrushModel, _super);

      function BrushModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = BrushModel.type;
        /**
         * @readOnly
         */

        _this.areas = [];
        /**
         * Current brush painting area settings.
         * @readOnly
         */

        _this.brushOption = {};
        return _this;
      }

      BrushModel.prototype.optionUpdated = function (newOption, isInit) {
        var thisOption = this.option;
        !isInit && replaceVisualOption(thisOption, newOption, ['inBrush', 'outOfBrush']);
        var inBrush = thisOption.inBrush = thisOption.inBrush || {}; // Always give default visual, consider setOption at the second time.

        thisOption.outOfBrush = thisOption.outOfBrush || {
          color: DEFAULT_OUT_OF_BRUSH_COLOR
        };

        if (!inBrush.hasOwnProperty('liftZ')) {
          // Bigger than the highlight z lift, otherwise it will
          // be effected by the highlight z when brush.
          inBrush.liftZ = 5;
        }
      };
      /**
       * If `areas` is null/undefined, range state remain.
       */


      BrushModel.prototype.setAreas = function (areas) {
        if ("development" !== 'production') {
          assert(isArray(areas));
          each(areas, function (area) {
            assert(area.brushType, 'Illegal areas');
          });
        } // If areas is null/undefined, range state remain.
        // This helps user to dispatchAction({type: 'brush'}) with no areas
        // set but just want to get the current brush select info from a `brush` event.


        if (!areas) {
          return;
        }

        this.areas = map(areas, function (area) {
          return generateBrushOption(this.option, area);
        }, this);
      };
      /**
       * Set the current painting brush option.
       */


      BrushModel.prototype.setBrushOption = function (brushOption) {
        this.brushOption = generateBrushOption(this.option, brushOption);
        this.brushType = this.brushOption.brushType;
      };

      BrushModel.type = 'brush';
      BrushModel.dependencies = ['geo', 'grid', 'xAxis', 'yAxis', 'parallel', 'series'];
      BrushModel.defaultOption = {
        seriesIndex: 'all',
        brushType: 'rect',
        brushMode: 'single',
        transformable: true,
        brushStyle: {
          borderWidth: 1,
          color: 'rgba(210,219,238,0.3)',
          borderColor: '#D2DBEE'
        },
        throttleType: 'fixRate',
        throttleDelay: 0,
        removeOnClick: true,
        z: 10000
      };
      return BrushModel;
    }(ComponentModel);

    function generateBrushOption(option, brushOption) {
      return merge({
        brushType: option.brushType,
        brushMode: option.brushMode,
        transformable: option.transformable,
        brushStyle: new Model(option.brushStyle).getItemStyle(),
        removeOnClick: option.removeOnClick,
        z: option.z
      }, brushOption, true);
    }

    var ICON_TYPES = ['rect', 'polygon', 'lineX', 'lineY', 'keep', 'clear'];

    var BrushFeature =
    /** @class */
    function (_super) {
      __extends(BrushFeature, _super);

      function BrushFeature() {
        return _super !== null && _super.apply(this, arguments) || this;
      }

      BrushFeature.prototype.render = function (featureModel, ecModel, api) {
        var brushType;
        var brushMode;
        var isBrushed;
        ecModel.eachComponent({
          mainType: 'brush'
        }, function (brushModel) {
          brushType = brushModel.brushType;
          brushMode = brushModel.brushOption.brushMode || 'single';
          isBrushed = isBrushed || !!brushModel.areas.length;
        });
        this._brushType = brushType;
        this._brushMode = brushMode;
        each(featureModel.get('type', true), function (type) {
          featureModel.setIconStatus(type, (type === 'keep' ? brushMode === 'multiple' : type === 'clear' ? isBrushed : type === brushType) ? 'emphasis' : 'normal');
        });
      };

      BrushFeature.prototype.updateView = function (featureModel, ecModel, api) {
        this.render(featureModel, ecModel, api);
      };

      BrushFeature.prototype.getIcons = function () {
        var model = this.model;
        var availableIcons = model.get('icon', true);
        var icons = {};
        each(model.get('type', true), function (type) {
          if (availableIcons[type]) {
            icons[type] = availableIcons[type];
          }
        });
        return icons;
      };

      BrushFeature.prototype.onclick = function (ecModel, api, type) {
        var brushType = this._brushType;
        var brushMode = this._brushMode;

        if (type === 'clear') {
          // Trigger parallel action firstly
          api.dispatchAction({
            type: 'axisAreaSelect',
            intervals: []
          });
          api.dispatchAction({
            type: 'brush',
            command: 'clear',
            // Clear all areas of all brush components.
            areas: []
          });
        } else {
          api.dispatchAction({
            type: 'takeGlobalCursor',
            key: 'brush',
            brushOption: {
              brushType: type === 'keep' ? brushType : brushType === type ? false : type,
              brushMode: type === 'keep' ? brushMode === 'multiple' ? 'single' : 'multiple' : brushMode
            }
          });
        }
      };

      BrushFeature.getDefaultOption = function (ecModel) {
        var defaultOption = {
          show: true,
          type: ICON_TYPES.slice(),
          icon: {
            /* eslint-disable */
            rect: 'M7.3,34.7 M0.4,10V-0.2h9.8 M89.6,10V-0.2h-9.8 M0.4,60v10.2h9.8 M89.6,60v10.2h-9.8 M12.3,22.4V10.5h13.1 M33.6,10.5h7.8 M49.1,10.5h7.8 M77.5,22.4V10.5h-13 M12.3,31.1v8.2 M77.7,31.1v8.2 M12.3,47.6v11.9h13.1 M33.6,59.5h7.6 M49.1,59.5 h7.7 M77.5,47.6v11.9h-13',
            polygon: 'M55.2,34.9c1.7,0,3.1,1.4,3.1,3.1s-1.4,3.1-3.1,3.1 s-3.1-1.4-3.1-3.1S53.5,34.9,55.2,34.9z M50.4,51c1.7,0,3.1,1.4,3.1,3.1c0,1.7-1.4,3.1-3.1,3.1c-1.7,0-3.1-1.4-3.1-3.1 C47.3,52.4,48.7,51,50.4,51z M55.6,37.1l1.5-7.8 M60.1,13.5l1.6-8.7l-7.8,4 M59,19l-1,5.3 M24,16.1l6.4,4.9l6.4-3.3 M48.5,11.6 l-5.9,3.1 M19.1,12.8L9.7,5.1l1.1,7.7 M13.4,29.8l1,7.3l6.6,1.6 M11.6,18.4l1,6.1 M32.8,41.9 M26.6,40.4 M27.3,40.2l6.1,1.6 M49.9,52.1l-5.6-7.6l-4.9-1.2',
            lineX: 'M15.2,30 M19.7,15.6V1.9H29 M34.8,1.9H40.4 M55.3,15.6V1.9H45.9 M19.7,44.4V58.1H29 M34.8,58.1H40.4 M55.3,44.4 V58.1H45.9 M12.5,20.3l-9.4,9.6l9.6,9.8 M3.1,29.9h16.5 M62.5,20.3l9.4,9.6L62.3,39.7 M71.9,29.9H55.4',
            lineY: 'M38.8,7.7 M52.7,12h13.2v9 M65.9,26.6V32 M52.7,46.3h13.2v-9 M24.9,12H11.8v9 M11.8,26.6V32 M24.9,46.3H11.8v-9 M48.2,5.1l-9.3-9l-9.4,9.2 M38.9-3.9V12 M48.2,53.3l-9.3,9l-9.4-9.2 M38.9,62.3V46.4',
            keep: 'M4,10.5V1h10.3 M20.7,1h6.1 M33,1h6.1 M55.4,10.5V1H45.2 M4,17.3v6.6 M55.6,17.3v6.6 M4,30.5V40h10.3 M20.7,40 h6.1 M33,40h6.1 M55.4,30.5V40H45.2 M21,18.9h62.9v48.6H21V18.9z',
            clear: 'M22,14.7l30.9,31 M52.9,14.7L22,45.7 M4.7,16.8V4.2h13.1 M26,4.2h7.8 M41.6,4.2h7.8 M70.3,16.8V4.2H57.2 M4.7,25.9v8.6 M70.3,25.9v8.6 M4.7,43.2v12.6h13.1 M26,55.8h7.8 M41.6,55.8h7.8 M70.3,43.2v12.6H57.2' // jshint ignore:line

            /* eslint-enable */

          },
          // `rect`, `polygon`, `lineX`, `lineY`, `keep`, `clear`
          title: ecModel.getLocaleModel().get(['toolbox', 'brush', 'title'])
        };
        return defaultOption;
      };

      return BrushFeature;
    }(ToolboxFeature);

    function install$B(registers) {
      registers.registerComponentView(BrushView);
      registers.registerComponentModel(BrushModel);
      registers.registerPreprocessor(brushPreprocessor);
      registers.registerVisual(registers.PRIORITY.VISUAL.BRUSH, brushVisual);
      registers.registerAction({
        type: 'brush',
        event: 'brush',
        update: 'updateVisual'
      }, function (payload, ecModel) {
        ecModel.eachComponent({
          mainType: 'brush',
          query: payload
        }, function (brushModel) {
          brushModel.setAreas(payload.areas);
        });
      });
      /**
       * payload: {
       *      brushComponents: [
       *          {
       *              brushId,
       *              brushIndex,
       *              brushName,
       *              series: [
       *                  {
       *                      seriesId,
       *                      seriesIndex,
       *                      seriesName,
       *                      rawIndices: [21, 34, ...]
       *                  },
       *                  ...
       *              ]
       *          },
       *          ...
       *      ]
       * }
       */

      registers.registerAction({
        type: 'brushSelect',
        event: 'brushSelected',
        update: 'none'
      }, noop);
      registers.registerAction({
        type: 'brushEnd',
        event: 'brushEnd',
        update: 'none'
      }, noop);
      registerFeature('brush', BrushFeature);
    }

    var TitleModel =
    /** @class */
    function (_super) {
      __extends(TitleModel, _super);

      function TitleModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = TitleModel.type;
        _this.layoutMode = {
          type: 'box',
          ignoreSize: true
        };
        return _this;
      }

      TitleModel.type = 'title';
      TitleModel.defaultOption = {
        // zlevel: 0,
        z: 6,
        show: true,
        text: '',
        target: 'blank',
        subtext: '',
        subtarget: 'blank',
        left: 0,
        top: 0,
        backgroundColor: 'rgba(0,0,0,0)',
        borderColor: '#ccc',
        borderWidth: 0,
        padding: 5,
        itemGap: 10,
        textStyle: {
          fontSize: 18,
          fontWeight: 'bold',
          color: '#464646'
        },
        subtextStyle: {
          fontSize: 12,
          color: '#6E7079'
        }
      };
      return TitleModel;
    }(ComponentModel); // View


    var TitleView =
    /** @class */
    function (_super) {
      __extends(TitleView, _super);

      function TitleView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = TitleView.type;
        return _this;
      }

      TitleView.prototype.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 ZRText({
          style: createTextStyle(textStyleModel, {
            text: titleModel.get('text'),
            fill: textStyleModel.getTextColor()
          }, {
            disableBox: true
          }),
          z2: 10
        });
        var textRect = textEl.getBoundingRect();
        var subText = titleModel.get('subtext');
        var subTextEl = new ZRText({
          style: createTextStyle(subtextStyleModel, {
            text: subText,
            fill: subtextStyleModel.getTextColor(),
            y: textRect.height + titleModel.get('itemGap'),
            verticalAlign: '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'));
          });
        }

        getECData(textEl).eventData = getECData(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'); // @ts-ignore

          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'); // @ts-ignore

          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.x = layoutRect.x;
        group.y = layoutRect.y;
        group.markRedraw();
        var alignStyle = {
          align: textAlign,
          verticalAlign: 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);
      };

      TitleView.type = 'title';
      return TitleView;
    }(ComponentView);

    function install$C(registers) {
      registers.registerComponentModel(TitleModel);
      registers.registerComponentView(TitleView);
    }

    var TimelineModel =
    /** @class */
    function (_super) {
      __extends(TimelineModel, _super);

      function TimelineModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = TimelineModel.type;
        _this.layoutMode = 'box';
        return _this;
      }
      /**
       * @override
       */


      TimelineModel.prototype.init = function (option, parentModel, ecModel) {
        this.mergeDefaultAndTheme(option, ecModel);

        this._initData();
      };
      /**
       * @override
       */


      TimelineModel.prototype.mergeOption = function (option) {
        _super.prototype.mergeOption.apply(this, arguments);

        this._initData();
      };

      TimelineModel.prototype.setCurrentIndex = function (currentIndex) {
        if (currentIndex == null) {
          currentIndex = this.option.currentIndex;
        }

        var count = this._data.count();

        if (this.option.loop) {
          currentIndex = (currentIndex % count + count) % count;
        } else {
          currentIndex >= count && (currentIndex = count - 1);
          currentIndex < 0 && (currentIndex = 0);
        }

        this.option.currentIndex = currentIndex;
      };
      /**
       * @return {number} currentIndex
       */


      TimelineModel.prototype.getCurrentIndex = function () {
        return this.option.currentIndex;
      };
      /**
       * @return {boolean}
       */


      TimelineModel.prototype.isIndexMax = function () {
        return this.getCurrentIndex() >= this._data.count() - 1;
      };
      /**
       * @param {boolean} state true: play, false: stop
       */


      TimelineModel.prototype.setPlayState = function (state) {
        this.option.autoPlay = !!state;
      };
      /**
       * @return {boolean} true: play, false: stop
       */


      TimelineModel.prototype.getPlayState = function () {
        return !!this.option.autoPlay;
      };
      /**
       * @private
       */


      TimelineModel.prototype._initData = function () {
        var thisOption = this.option;
        var dataArr = thisOption.data || [];
        var axisType = thisOption.axisType;
        var names = this._names = [];
        var processedDataArr;

        if (axisType === 'category') {
          processedDataArr = [];
          each(dataArr, function (item, index) {
            var value = convertOptionIdName(getDataItemValue(item), '');
            var newItem;

            if (isObject(item)) {
              newItem = clone(item);
              newItem.value = index;
            } else {
              newItem = index;
            }

            processedDataArr.push(newItem);
            names.push(value);
          });
        } else {
          processedDataArr = dataArr;
        }

        var dimType = {
          category: 'ordinal',
          time: 'time',
          value: 'number'
        }[axisType] || 'number';
        var data = this._data = new SeriesData([{
          name: 'value',
          type: dimType
        }], this);
        data.initData(processedDataArr, names);
      };

      TimelineModel.prototype.getData = function () {
        return this._data;
      };
      /**
       * @public
       * @return {Array.<string>} categoreis
       */


      TimelineModel.prototype.getCategories = function () {
        if (this.get('axisType') === 'category') {
          return this._names.slice();
        }
      };

      TimelineModel.type = 'timeline';
      /**
       * @protected
       */

      TimelineModel.defaultOption = {
        // zlevel: 0,                  // 一级层叠
        z: 4,
        show: true,
        axisType: 'time',
        realtime: true,
        left: '20%',
        top: null,
        right: '20%',
        bottom: 0,
        width: null,
        height: 40,
        padding: 5,
        controlPosition: 'left',
        autoPlay: false,
        rewind: false,
        loop: true,
        playInterval: 2000,
        currentIndex: 0,
        itemStyle: {},
        label: {
          color: '#000'
        },
        data: []
      };
      return TimelineModel;
    }(ComponentModel);

    var SliderTimelineModel =
    /** @class */
    function (_super) {
      __extends(SliderTimelineModel, _super);

      function SliderTimelineModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = SliderTimelineModel.type;
        return _this;
      }

      SliderTimelineModel.type = 'timeline.slider';
      /**
       * @protected
       */

      SliderTimelineModel.defaultOption = inheritDefaultOption(TimelineModel.defaultOption, {
        backgroundColor: 'rgba(0,0,0,0)',
        borderColor: '#ccc',
        borderWidth: 0,
        orient: 'horizontal',
        inverse: false,
        tooltip: {
          trigger: 'item' // data item may also have tootip attr.

        },
        symbol: 'circle',
        symbolSize: 12,
        lineStyle: {
          show: true,
          width: 2,
          color: '#DAE1F5'
        },
        label: {
          position: 'auto',
          // When using number, label position is not
          // restricted by viewRect.
          // positive: right/bottom, negative: left/top
          show: true,
          interval: 'auto',
          rotate: 0,
          // formatter: null,
          // 其余属性默认使用全局文本样式，详见TEXTSTYLE
          color: '#A4B1D7'
        },
        itemStyle: {
          color: '#A4B1D7',
          borderWidth: 1
        },
        checkpointStyle: {
          symbol: 'circle',
          symbolSize: 15,
          color: '#316bf3',
          borderColor: '#fff',
          borderWidth: 2,
          shadowBlur: 2,
          shadowOffsetX: 1,
          shadowOffsetY: 1,
          shadowColor: 'rgba(0, 0, 0, 0.3)',
          // borderColor: 'rgba(194,53,49, 0.5)',
          animation: true,
          animationDuration: 300,
          animationEasing: 'quinticInOut'
        },
        controlStyle: {
          show: true,
          showPlayBtn: true,
          showPrevBtn: true,
          showNextBtn: true,
          itemSize: 24,
          itemGap: 12,
          position: 'left',
          playIcon: 'path://M31.6,53C17.5,53,6,41.5,6,27.4S17.5,1.8,31.6,1.8C45.7,1.8,57.2,13.3,57.2,27.4S45.7,53,31.6,53z M31.6,3.3 C18.4,3.3,7.5,14.1,7.5,27.4c0,13.3,10.8,24.1,24.1,24.1C44.9,51.5,55.7,40.7,55.7,27.4C55.7,14.1,44.9,3.3,31.6,3.3z M24.9,21.3 c0-2.2,1.6-3.1,3.5-2l10.5,6.1c1.899,1.1,1.899,2.9,0,4l-10.5,6.1c-1.9,1.1-3.5,0.2-3.5-2V21.3z',
          stopIcon: 'path://M30.9,53.2C16.8,53.2,5.3,41.7,5.3,27.6S16.8,2,30.9,2C45,2,56.4,13.5,56.4,27.6S45,53.2,30.9,53.2z M30.9,3.5C17.6,3.5,6.8,14.4,6.8,27.6c0,13.3,10.8,24.1,24.101,24.1C44.2,51.7,55,40.9,55,27.6C54.9,14.4,44.1,3.5,30.9,3.5z M36.9,35.8c0,0.601-0.4,1-0.9,1h-1.3c-0.5,0-0.9-0.399-0.9-1V19.5c0-0.6,0.4-1,0.9-1H36c0.5,0,0.9,0.4,0.9,1V35.8z M27.8,35.8 c0,0.601-0.4,1-0.9,1h-1.3c-0.5,0-0.9-0.399-0.9-1V19.5c0-0.6,0.4-1,0.9-1H27c0.5,0,0.9,0.4,0.9,1L27.8,35.8L27.8,35.8z',
          // eslint-disable-next-line max-len
          nextIcon: 'M2,18.5A1.52,1.52,0,0,1,.92,18a1.49,1.49,0,0,1,0-2.12L7.81,9.36,1,3.11A1.5,1.5,0,1,1,3,.89l8,7.34a1.48,1.48,0,0,1,.49,1.09,1.51,1.51,0,0,1-.46,1.1L3,18.08A1.5,1.5,0,0,1,2,18.5Z',
          // eslint-disable-next-line max-len
          prevIcon: 'M10,.5A1.52,1.52,0,0,1,11.08,1a1.49,1.49,0,0,1,0,2.12L4.19,9.64,11,15.89a1.5,1.5,0,1,1-2,2.22L1,10.77A1.48,1.48,0,0,1,.5,9.68,1.51,1.51,0,0,1,1,8.58L9,.92A1.5,1.5,0,0,1,10,.5Z',
          prevBtnSize: 18,
          nextBtnSize: 18,
          color: '#A4B1D7',
          borderColor: '#A4B1D7',
          borderWidth: 1
        },
        emphasis: {
          label: {
            show: true,
            // 其余属性默认使用全局文本样式，详见TEXTSTYLE
            color: '#6f778d'
          },
          itemStyle: {
            color: '#316BF3'
          },
          controlStyle: {
            color: '#316BF3',
            borderColor: '#316BF3',
            borderWidth: 2
          }
        },
        progress: {
          lineStyle: {
            color: '#316BF3'
          },
          itemStyle: {
            color: '#316BF3'
          },
          label: {
            color: '#6f778d'
          }
        },
        data: []
      });
      return SliderTimelineModel;
    }(TimelineModel);

    mixin(SliderTimelineModel, DataFormatMixin.prototype);

    var TimelineView =
    /** @class */
    function (_super) {
      __extends(TimelineView, _super);

      function TimelineView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = TimelineView.type;
        return _this;
      }

      TimelineView.type = 'timeline';
      return TimelineView;
    }(ComponentView);

    /**
     * Extend axis 2d
     */

    var TimelineAxis =
    /** @class */
    function (_super) {
      __extends(TimelineAxis, _super);

      function TimelineAxis(dim, scale, coordExtent, axisType) {
        var _this = _super.call(this, dim, scale, coordExtent) || this;

        _this.type = axisType || 'value';
        return _this;
      }
      /**
       * @override
       */


      TimelineAxis.prototype.getLabelModel = function () {
        // Force override
        return this.model.getModel('label');
      };
      /**
       * @override
       */


      TimelineAxis.prototype.isHorizontal = function () {
        return this.model.get('orient') === 'horizontal';
      };

      return TimelineAxis;
    }(Axis);

    var PI$8 = Math.PI;
    var labelDataIndexStore = makeInner();

    var SliderTimelineView =
    /** @class */
    function (_super) {
      __extends(SliderTimelineView, _super);

      function SliderTimelineView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = SliderTimelineView.type;
        return _this;
      }

      SliderTimelineView.prototype.init = function (ecModel, api) {
        this.api = api;
      };
      /**
       * @override
       */


      SliderTimelineView.prototype.render = function (timelineModel, ecModel, api) {
        this.model = timelineModel;
        this.api = api;
        this.ecModel = ecModel;
        this.group.removeAll();

        if (timelineModel.get('show', true)) {
          var layoutInfo_1 = this._layout(timelineModel, api);

          var mainGroup_1 = this._createGroup('_mainGroup');

          var labelGroup = this._createGroup('_labelGroup');

          var axis_1 = this._axis = this._createAxis(layoutInfo_1, timelineModel);

          timelineModel.formatTooltip = function (dataIndex) {
            var name = axis_1.scale.getLabel({
              value: dataIndex
            });
            return createTooltipMarkup('nameValue', {
              noName: true,
              value: name
            });
          };

          each(['AxisLine', 'AxisTick', 'Control', 'CurrentPointer'], function (name) {
            this['_render' + name](layoutInfo_1, mainGroup_1, axis_1, timelineModel);
          }, this);

          this._renderAxisLabel(layoutInfo_1, labelGroup, axis_1, timelineModel);

          this._position(layoutInfo_1, timelineModel);
        }

        this._doPlayStop();

        this._updateTicksStatus();
      };
      /**
       * @override
       */


      SliderTimelineView.prototype.remove = function () {
        this._clearTimer();

        this.group.removeAll();
      };
      /**
       * @override
       */


      SliderTimelineView.prototype.dispose = function () {
        this._clearTimer();
      };

      SliderTimelineView.prototype._layout = function (timelineModel, api) {
        var labelPosOpt = timelineModel.get(['label', 'position']);
        var orient = timelineModel.get('orient');
        var viewRect = getViewRect$5(timelineModel, api);
        var parsedLabelPos; // Auto label offset.

        if (labelPosOpt == null || labelPosOpt === 'auto') {
          parsedLabelPos = orient === 'horizontal' ? viewRect.y + viewRect.height / 2 < api.getHeight() / 2 ? '-' : '+' : viewRect.x + viewRect.width / 2 < api.getWidth() / 2 ? '+' : '-';
        } else if (isString(labelPosOpt)) {
          parsedLabelPos = {
            horizontal: {
              top: '-',
              bottom: '+'
            },
            vertical: {
              left: '-',
              right: '+'
            }
          }[orient][labelPosOpt];
        } else {
          // is number
          parsedLabelPos = labelPosOpt;
        }

        var labelAlignMap = {
          horizontal: 'center',
          vertical: parsedLabelPos >= 0 || parsedLabelPos === '+' ? 'left' : 'right'
        };
        var labelBaselineMap = {
          horizontal: parsedLabelPos >= 0 || parsedLabelPos === '+' ? 'top' : 'bottom',
          vertical: 'middle'
        };
        var rotationMap = {
          horizontal: 0,
          vertical: PI$8 / 2
        }; // Position

        var mainLength = orient === 'vertical' ? viewRect.height : viewRect.width;
        var controlModel = timelineModel.getModel('controlStyle');
        var showControl = controlModel.get('show', true);
        var controlSize = showControl ? controlModel.get('itemSize') : 0;
        var controlGap = showControl ? controlModel.get('itemGap') : 0;
        var sizePlusGap = controlSize + controlGap; // Special label rotate.

        var labelRotation = timelineModel.get(['label', 'rotate']) || 0;
        labelRotation = labelRotation * PI$8 / 180; // To radian.

        var playPosition;
        var prevBtnPosition;
        var nextBtnPosition;
        var controlPosition = controlModel.get('position', true);
        var showPlayBtn = showControl && controlModel.get('showPlayBtn', true);
        var showPrevBtn = showControl && controlModel.get('showPrevBtn', true);
        var showNextBtn = showControl && controlModel.get('showNextBtn', true);
        var xLeft = 0;
        var xRight = mainLength; // position[0] means left, position[1] means middle.

        if (controlPosition === 'left' || controlPosition === 'bottom') {
          showPlayBtn && (playPosition = [0, 0], xLeft += sizePlusGap);
          showPrevBtn && (prevBtnPosition = [xLeft, 0], xLeft += sizePlusGap);
          showNextBtn && (nextBtnPosition = [xRight - controlSize, 0], xRight -= sizePlusGap);
        } else {
          // 'top' 'right'
          showPlayBtn && (playPosition = [xRight - controlSize, 0], xRight -= sizePlusGap);
          showPrevBtn && (prevBtnPosition = [0, 0], xLeft += sizePlusGap);
          showNextBtn && (nextBtnPosition = [xRight - controlSize, 0], xRight -= sizePlusGap);
        }

        var axisExtent = [xLeft, xRight];

        if (timelineModel.get('inverse')) {
          axisExtent.reverse();
        }

        return {
          viewRect: viewRect,
          mainLength: mainLength,
          orient: orient,
          rotation: rotationMap[orient],
          labelRotation: labelRotation,
          labelPosOpt: parsedLabelPos,
          labelAlign: timelineModel.get(['label', 'align']) || labelAlignMap[orient],
          labelBaseline: timelineModel.get(['label', 'verticalAlign']) || timelineModel.get(['label', 'baseline']) || labelBaselineMap[orient],
          // Based on mainGroup.
          playPosition: playPosition,
          prevBtnPosition: prevBtnPosition,
          nextBtnPosition: nextBtnPosition,
          axisExtent: axisExtent,
          controlSize: controlSize,
          controlGap: controlGap
        };
      };

      SliderTimelineView.prototype._position = function (layoutInfo, timelineModel) {
        // Position is be called finally, because bounding rect is needed for
        // adapt content to fill viewRect (auto adapt offset).
        // Timeline may be not all in the viewRect when 'offset' is specified
        // as a number, because it is more appropriate that label aligns at
        // 'offset' but not the other edge defined by viewRect.
        var mainGroup = this._mainGroup;
        var labelGroup = this._labelGroup;
        var viewRect = layoutInfo.viewRect;

        if (layoutInfo.orient === 'vertical') {
          // transform to horizontal, inverse rotate by left-top point.
          var m = create$1();
          var rotateOriginX = viewRect.x;
          var rotateOriginY = viewRect.y + viewRect.height;
          translate(m, m, [-rotateOriginX, -rotateOriginY]);
          rotate(m, m, -PI$8 / 2);
          translate(m, m, [rotateOriginX, rotateOriginY]);
          viewRect = viewRect.clone();
          viewRect.applyTransform(m);
        }

        var viewBound = getBound(viewRect);
        var mainBound = getBound(mainGroup.getBoundingRect());
        var labelBound = getBound(labelGroup.getBoundingRect());
        var mainPosition = [mainGroup.x, mainGroup.y];
        var labelsPosition = [labelGroup.x, labelGroup.y];
        labelsPosition[0] = mainPosition[0] = viewBound[0][0];
        var labelPosOpt = layoutInfo.labelPosOpt;

        if (labelPosOpt == null || isString(labelPosOpt)) {
          // '+' or '-'
          var mainBoundIdx = labelPosOpt === '+' ? 0 : 1;
          toBound(mainPosition, mainBound, viewBound, 1, mainBoundIdx);
          toBound(labelsPosition, labelBound, viewBound, 1, 1 - mainBoundIdx);
        } else {
          var mainBoundIdx = labelPosOpt >= 0 ? 0 : 1;
          toBound(mainPosition, mainBound, viewBound, 1, mainBoundIdx);
          labelsPosition[1] = mainPosition[1] + labelPosOpt;
        }

        mainGroup.setPosition(mainPosition);
        labelGroup.setPosition(labelsPosition);
        mainGroup.rotation = labelGroup.rotation = layoutInfo.rotation;
        setOrigin(mainGroup);
        setOrigin(labelGroup);

        function setOrigin(targetGroup) {
          targetGroup.originX = viewBound[0][0] - targetGroup.x;
          targetGroup.originY = viewBound[1][0] - targetGroup.y;
        }

        function getBound(rect) {
          // [[xmin, xmax], [ymin, ymax]]
          return [[rect.x, rect.x + rect.width], [rect.y, rect.y + rect.height]];
        }

        function toBound(fromPos, from, to, dimIdx, boundIdx) {
          fromPos[dimIdx] += to[dimIdx][boundIdx] - from[dimIdx][boundIdx];
        }
      };

      SliderTimelineView.prototype._createAxis = function (layoutInfo, timelineModel) {
        var data = timelineModel.getData();
        var axisType = timelineModel.get('axisType');
        var scale = createScaleByModel$1(timelineModel, axisType); // Customize scale. The `tickValue` is `dataIndex`.

        scale.getTicks = function () {
          return data.mapArray(['value'], function (value) {
            return {
              value: value
            };
          });
        };

        var dataExtent = data.getDataExtent('value');
        scale.setExtent(dataExtent[0], dataExtent[1]);
        scale.calcNiceTicks();
        var axis = new TimelineAxis('value', scale, layoutInfo.axisExtent, axisType);
        axis.model = timelineModel;
        return axis;
      };

      SliderTimelineView.prototype._createGroup = function (key) {
        var newGroup = this[key] = new Group();
        this.group.add(newGroup);
        return newGroup;
      };

      SliderTimelineView.prototype._renderAxisLine = function (layoutInfo, group, axis, timelineModel) {
        var axisExtent = axis.getExtent();

        if (!timelineModel.get(['lineStyle', 'show'])) {
          return;
        }

        var line = new Line({
          shape: {
            x1: axisExtent[0],
            y1: 0,
            x2: axisExtent[1],
            y2: 0
          },
          style: extend({
            lineCap: 'round'
          }, timelineModel.getModel('lineStyle').getLineStyle()),
          silent: true,
          z2: 1
        });
        group.add(line);
        var progressLine = this._progressLine = new Line({
          shape: {
            x1: axisExtent[0],
            x2: this._currentPointer ? this._currentPointer.x : axisExtent[0],
            y1: 0,
            y2: 0
          },
          style: defaults({
            lineCap: 'round',
            lineWidth: line.style.lineWidth
          }, timelineModel.getModel(['progress', 'lineStyle']).getLineStyle()),
          silent: true,
          z2: 1
        });
        group.add(progressLine);
      };

      SliderTimelineView.prototype._renderAxisTick = function (layoutInfo, group, axis, timelineModel) {
        var _this = this;

        var data = timelineModel.getData(); // Show all ticks, despite ignoring strategy.

        var ticks = axis.scale.getTicks();
        this._tickSymbols = []; // The value is dataIndex, see the customized scale.

        each(ticks, function (tick) {
          var tickCoord = axis.dataToCoord(tick.value);
          var itemModel = data.getItemModel(tick.value);
          var itemStyleModel = itemModel.getModel('itemStyle');
          var hoverStyleModel = itemModel.getModel(['emphasis', 'itemStyle']);
          var progressStyleModel = itemModel.getModel(['progress', 'itemStyle']);
          var symbolOpt = {
            x: tickCoord,
            y: 0,
            onclick: bind(_this._changeTimeline, _this, tick.value)
          };
          var el = giveSymbol(itemModel, itemStyleModel, group, symbolOpt);
          el.ensureState('emphasis').style = hoverStyleModel.getItemStyle();
          el.ensureState('progress').style = progressStyleModel.getItemStyle();
          enableHoverEmphasis(el);
          var ecData = getECData(el);

          if (itemModel.get('tooltip')) {
            ecData.dataIndex = tick.value;
            ecData.dataModel = timelineModel;
          } else {
            ecData.dataIndex = ecData.dataModel = null;
          }

          _this._tickSymbols.push(el);
        });
      };

      SliderTimelineView.prototype._renderAxisLabel = function (layoutInfo, group, axis, timelineModel) {
        var _this = this;

        var labelModel = axis.getLabelModel();

        if (!labelModel.get('show')) {
          return;
        }

        var data = timelineModel.getData();
        var labels = axis.getViewLabels();
        this._tickLabels = [];
        each(labels, function (labelItem) {
          // The tickValue is dataIndex, see the customized scale.
          var dataIndex = labelItem.tickValue;
          var itemModel = data.getItemModel(dataIndex);
          var normalLabelModel = itemModel.getModel('label');
          var hoverLabelModel = itemModel.getModel(['emphasis', 'label']);
          var progressLabelModel = itemModel.getModel(['progress', 'label']);
          var tickCoord = axis.dataToCoord(labelItem.tickValue);
          var textEl = new ZRText({
            x: tickCoord,
            y: 0,
            rotation: layoutInfo.labelRotation - layoutInfo.rotation,
            onclick: bind(_this._changeTimeline, _this, dataIndex),
            silent: false,
            style: createTextStyle(normalLabelModel, {
              text: labelItem.formattedLabel,
              align: layoutInfo.labelAlign,
              verticalAlign: layoutInfo.labelBaseline
            })
          });
          textEl.ensureState('emphasis').style = createTextStyle(hoverLabelModel);
          textEl.ensureState('progress').style = createTextStyle(progressLabelModel);
          group.add(textEl);
          enableHoverEmphasis(textEl);
          labelDataIndexStore(textEl).dataIndex = dataIndex;

          _this._tickLabels.push(textEl);
        });
      };

      SliderTimelineView.prototype._renderControl = function (layoutInfo, group, axis, timelineModel) {
        var controlSize = layoutInfo.controlSize;
        var rotation = layoutInfo.rotation;
        var itemStyle = timelineModel.getModel('controlStyle').getItemStyle();
        var hoverStyle = timelineModel.getModel(['emphasis', 'controlStyle']).getItemStyle();
        var playState = timelineModel.getPlayState();
        var inverse = timelineModel.get('inverse', true);
        makeBtn(layoutInfo.nextBtnPosition, 'next', bind(this._changeTimeline, this, inverse ? '-' : '+'));
        makeBtn(layoutInfo.prevBtnPosition, 'prev', bind(this._changeTimeline, this, inverse ? '+' : '-'));
        makeBtn(layoutInfo.playPosition, playState ? 'stop' : 'play', bind(this._handlePlayClick, this, !playState), true);

        function makeBtn(position, iconName, onclick, willRotate) {
          if (!position) {
            return;
          }

          var iconSize = parsePercent(retrieve2(timelineModel.get(['controlStyle', iconName + 'BtnSize']), controlSize), controlSize);
          var rect = [0, -iconSize / 2, iconSize, iconSize];
          var btn = makeControlIcon(timelineModel, iconName + 'Icon', rect, {
            x: position[0],
            y: position[1],
            originX: controlSize / 2,
            originY: 0,
            rotation: willRotate ? -rotation : 0,
            rectHover: true,
            style: itemStyle,
            onclick: onclick
          });
          btn.ensureState('emphasis').style = hoverStyle;
          group.add(btn);
          enableHoverEmphasis(btn);
        }
      };

      SliderTimelineView.prototype._renderCurrentPointer = function (layoutInfo, group, axis, timelineModel) {
        var data = timelineModel.getData();
        var currentIndex = timelineModel.getCurrentIndex();
        var pointerModel = data.getItemModel(currentIndex).getModel('checkpointStyle');
        var me = this;
        var callback = {
          onCreate: function (pointer) {
            pointer.draggable = true;
            pointer.drift = bind(me._handlePointerDrag, me);
            pointer.ondragend = bind(me._handlePointerDragend, me);
            pointerMoveTo(pointer, me._progressLine, currentIndex, axis, timelineModel, true);
          },
          onUpdate: function (pointer) {
            pointerMoveTo(pointer, me._progressLine, currentIndex, axis, timelineModel);
          }
        }; // Reuse when exists, for animation and drag.

        this._currentPointer = giveSymbol(pointerModel, pointerModel, this._mainGroup, {}, this._currentPointer, callback);
      };

      SliderTimelineView.prototype._handlePlayClick = function (nextState) {
        this._clearTimer();

        this.api.dispatchAction({
          type: 'timelinePlayChange',
          playState: nextState,
          from: this.uid
        });
      };

      SliderTimelineView.prototype._handlePointerDrag = function (dx, dy, e) {
        this._clearTimer();

        this._pointerChangeTimeline([e.offsetX, e.offsetY]);
      };

      SliderTimelineView.prototype._handlePointerDragend = function (e) {
        this._pointerChangeTimeline([e.offsetX, e.offsetY], true);
      };

      SliderTimelineView.prototype._pointerChangeTimeline = function (mousePos, trigger) {
        var toCoord = this._toAxisCoord(mousePos)[0];

        var axis = this._axis;
        var axisExtent = asc(axis.getExtent().slice());
        toCoord > axisExtent[1] && (toCoord = axisExtent[1]);
        toCoord < axisExtent[0] && (toCoord = axisExtent[0]);
        this._currentPointer.x = toCoord;

        this._currentPointer.markRedraw();

        var progressLine = this._progressLine;

        if (progressLine) {
          progressLine.shape.x2 = toCoord;
          progressLine.dirty();
        }

        var targetDataIndex = this._findNearestTick(toCoord);

        var timelineModel = this.model;

        if (trigger || targetDataIndex !== timelineModel.getCurrentIndex() && timelineModel.get('realtime')) {
          this._changeTimeline(targetDataIndex);
        }
      };

      SliderTimelineView.prototype._doPlayStop = function () {
        var _this = this;

        this._clearTimer();

        if (this.model.getPlayState()) {
          this._timer = setTimeout(function () {
            // Do not cache
            var timelineModel = _this.model;

            _this._changeTimeline(timelineModel.getCurrentIndex() + (timelineModel.get('rewind', true) ? -1 : 1));
          }, this.model.get('playInterval'));
        }
      };

      SliderTimelineView.prototype._toAxisCoord = function (vertex) {
        var trans = this._mainGroup.getLocalTransform();

        return applyTransform$1(vertex, trans, true);
      };

      SliderTimelineView.prototype._findNearestTick = function (axisCoord) {
        var data = this.model.getData();
        var dist = Infinity;
        var targetDataIndex;
        var axis = this._axis;
        data.each(['value'], function (value, dataIndex) {
          var coord = axis.dataToCoord(value);
          var d = Math.abs(coord - axisCoord);

          if (d < dist) {
            dist = d;
            targetDataIndex = dataIndex;
          }
        });
        return targetDataIndex;
      };

      SliderTimelineView.prototype._clearTimer = function () {
        if (this._timer) {
          clearTimeout(this._timer);
          this._timer = null;
        }
      };

      SliderTimelineView.prototype._changeTimeline = function (nextIndex) {
        var currentIndex = this.model.getCurrentIndex();

        if (nextIndex === '+') {
          nextIndex = currentIndex + 1;
        } else if (nextIndex === '-') {
          nextIndex = currentIndex - 1;
        }

        this.api.dispatchAction({
          type: 'timelineChange',
          currentIndex: nextIndex,
          from: this.uid
        });
      };

      SliderTimelineView.prototype._updateTicksStatus = function () {
        var currentIndex = this.model.getCurrentIndex();
        var tickSymbols = this._tickSymbols;
        var tickLabels = this._tickLabels;

        if (tickSymbols) {
          for (var i = 0; i < tickSymbols.length; i++) {
            tickSymbols && tickSymbols[i] && tickSymbols[i].toggleState('progress', i < currentIndex);
          }
        }

        if (tickLabels) {
          for (var i = 0; i < tickLabels.length; i++) {
            tickLabels && tickLabels[i] && tickLabels[i].toggleState('progress', labelDataIndexStore(tickLabels[i]).dataIndex <= currentIndex);
          }
        }
      };

      SliderTimelineView.type = 'timeline.slider';
      return SliderTimelineView;
    }(TimelineView);

    function createScaleByModel$1(model, axisType) {
      axisType = axisType || model.get('type');

      if (axisType) {
        switch (axisType) {
          // Buildin scale
          case 'category':
            return new OrdinalScale({
              ordinalMeta: model.getCategories(),
              extent: [Infinity, -Infinity]
            });

          case 'time':
            return new TimeScale({
              locale: model.ecModel.getLocaleModel(),
              useUTC: model.ecModel.get('useUTC')
            });

          default:
            // default to be value
            return new IntervalScale();
        }
      }
    }

    function getViewRect$5(model, api) {
      return getLayoutRect(model.getBoxLayoutParams(), {
        width: api.getWidth(),
        height: api.getHeight()
      }, model.get('padding'));
    }

    function makeControlIcon(timelineModel, objPath, rect, opts) {
      var style = opts.style;
      var icon = createIcon(timelineModel.get(['controlStyle', objPath]), opts || {}, new BoundingRect(rect[0], rect[1], rect[2], rect[3])); // TODO createIcon won't use style in opt.

      if (style) {
        icon.setStyle(style);
      }

      return icon;
    }
    /**
     * Create symbol or update symbol
     * opt: basic position and event handlers
     */


    function giveSymbol(hostModel, itemStyleModel, group, opt, symbol, callback) {
      var color = itemStyleModel.get('color');

      if (!symbol) {
        var symbolType = hostModel.get('symbol');
        symbol = createSymbol(symbolType, -1, -1, 2, 2, color);
        symbol.setStyle('strokeNoScale', true);
        group.add(symbol);
        callback && callback.onCreate(symbol);
      } else {
        symbol.setColor(color);
        group.add(symbol); // Group may be new, also need to add.

        callback && callback.onUpdate(symbol);
      } // Style


      var itemStyle = itemStyleModel.getItemStyle(['color']);
      symbol.setStyle(itemStyle); // Transform and events.

      opt = merge({
        rectHover: true,
        z2: 100
      }, opt, true);
      var symbolSize = normalizeSymbolSize(hostModel.get('symbolSize'));
      opt.scaleX = symbolSize[0] / 2;
      opt.scaleY = symbolSize[1] / 2;
      var symbolOffset = normalizeSymbolOffset(hostModel.get('symbolOffset'), symbolSize);

      if (symbolOffset) {
        opt.x = (opt.x || 0) + symbolOffset[0];
        opt.y = (opt.y || 0) + symbolOffset[1];
      }

      var symbolRotate = hostModel.get('symbolRotate');
      opt.rotation = (symbolRotate || 0) * Math.PI / 180 || 0;
      symbol.attr(opt); // FIXME
      // (1) When symbol.style.strokeNoScale is true and updateTransform is not performed,
      // getBoundingRect will return wrong result.
      // (This is supposed to be resolved in zrender, but it is a little difficult to
      // leverage performance and auto updateTransform)
      // (2) All of ancesters of symbol do not scale, so we can just updateTransform symbol.

      symbol.updateTransform();
      return symbol;
    }

    function pointerMoveTo(pointer, progressLine, dataIndex, axis, timelineModel, noAnimation) {
      if (pointer.dragging) {
        return;
      }

      var pointerModel = timelineModel.getModel('checkpointStyle');
      var toCoord = axis.dataToCoord(timelineModel.getData().get('value', dataIndex));

      if (noAnimation || !pointerModel.get('animation', true)) {
        pointer.attr({
          x: toCoord,
          y: 0
        });
        progressLine && progressLine.attr({
          shape: {
            x2: toCoord
          }
        });
      } else {
        var animationCfg = {
          duration: pointerModel.get('animationDuration', true),
          easing: pointerModel.get('animationEasing', true)
        };
        pointer.stopAnimation(null, true);
        pointer.animateTo({
          x: toCoord,
          y: 0
        }, animationCfg);
        progressLine && progressLine.animateTo({
          shape: {
            x2: toCoord
          }
        }, animationCfg);
      }
    }

    function installTimelineAction(registers) {
      registers.registerAction({
        type: 'timelineChange',
        event: 'timelineChanged',
        update: 'prepareAndUpdate'
      }, function (payload, ecModel, api) {
        var timelineModel = ecModel.getComponent('timeline');

        if (timelineModel && payload.currentIndex != null) {
          timelineModel.setCurrentIndex(payload.currentIndex);

          if (!timelineModel.get('loop', true) && timelineModel.isIndexMax() && timelineModel.getPlayState()) {
            timelineModel.setPlayState(false); // The timeline has played to the end, trigger event

            api.dispatchAction({
              type: 'timelinePlayChange',
              playState: false,
              from: payload.from
            });
          }
        } // Set normalized currentIndex to payload.


        ecModel.resetOption('timeline', {
          replaceMerge: timelineModel.get('replaceMerge', true)
        });
        return defaults({
          currentIndex: timelineModel.option.currentIndex
        }, payload);
      });
      registers.registerAction({
        type: 'timelinePlayChange',
        event: 'timelinePlayChanged',
        update: 'update'
      }, function (payload, ecModel) {
        var timelineModel = ecModel.getComponent('timeline');

        if (timelineModel && payload.playState != null) {
          timelineModel.setPlayState(payload.playState);
        }
      });
    }

    function timelinePreprocessor(option) {
      var timelineOpt = option && option.timeline;

      if (!isArray(timelineOpt)) {
        timelineOpt = timelineOpt ? [timelineOpt] : [];
      }

      each(timelineOpt, function (opt) {
        if (!opt) {
          return;
        }

        compatibleEC2(opt);
      });
    }

    function compatibleEC2(opt) {
      var type = opt.type;
      var ec2Types = {
        'number': 'value',
        'time': 'time'
      }; // Compatible with ec2

      if (ec2Types[type]) {
        opt.axisType = ec2Types[type];
        delete opt.type;
      }

      transferItem(opt);

      if (has(opt, 'controlPosition')) {
        var controlStyle = opt.controlStyle || (opt.controlStyle = {});

        if (!has(controlStyle, 'position')) {
          controlStyle.position = opt.controlPosition;
        }

        if (controlStyle.position === 'none' && !has(controlStyle, 'show')) {
          controlStyle.show = false;
          delete controlStyle.position;
        }

        delete opt.controlPosition;
      }

      each(opt.data || [], function (dataItem) {
        if (isObject(dataItem) && !isArray(dataItem)) {
          if (!has(dataItem, 'value') && has(dataItem, 'name')) {
            // In ec2, using name as value.
            dataItem.value = dataItem.name;
          }

          transferItem(dataItem);
        }
      });
    }

    function transferItem(opt) {
      var itemStyle = opt.itemStyle || (opt.itemStyle = {});
      var itemStyleEmphasis = itemStyle.emphasis || (itemStyle.emphasis = {}); // Transfer label out

      var label = opt.label || opt.label || {};
      var labelNormal = label.normal || (label.normal = {});
      var excludeLabelAttr = {
        normal: 1,
        emphasis: 1
      };
      each(label, function (value, name) {
        if (!excludeLabelAttr[name] && !has(labelNormal, name)) {
          labelNormal[name] = value;
        }
      });

      if (itemStyleEmphasis.label && !has(label, 'emphasis')) {
        label.emphasis = itemStyleEmphasis.label;
        delete itemStyleEmphasis.label;
      }
    }

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

    function install$D(registers) {
      registers.registerComponentModel(SliderTimelineModel);
      registers.registerComponentView(SliderTimelineView);
      registers.registerSubTypeDefaulter('timeline', function () {
        // Only slider now.
        return 'slider';
      });
      installTimelineAction(registers);
      registers.registerPreprocessor(timelinePreprocessor);
    }

    function checkMarkerInSeries(seriesOpts, markerType) {
      if (!seriesOpts) {
        return false;
      }

      var seriesOptArr = isArray(seriesOpts) ? seriesOpts : [seriesOpts];

      for (var idx = 0; idx < seriesOptArr.length; idx++) {
        if (seriesOptArr[idx] && seriesOptArr[idx][markerType]) {
          return true;
        }
      }

      return false;
    }

    function fillLabel(opt) {
      defaultEmphasis(opt, 'label', ['show']);
    } // { [componentType]: MarkerModel }


    var inner$g = makeInner();

    var MarkerModel =
    /** @class */
    function (_super) {
      __extends(MarkerModel, _super);

      function MarkerModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = MarkerModel.type;
        /**
         * If marker model is created by self from series
         */

        _this.createdBySelf = false;
        return _this;
      }
      /**
       * @overrite
       */


      MarkerModel.prototype.init = function (option, parentModel, ecModel) {
        if ("development" !== 'production') {
          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);
      };

      MarkerModel.prototype.isAnimationEnabled = function () {
        if (env.node) {
          return false;
        }

        var hostSeries = this.__hostSeries;
        return this.getShallow('animation') && hostSeries && hostSeries.isAnimationEnabled();
      };
      /**
       * @overrite
       */


      MarkerModel.prototype.mergeOption = function (newOpt, ecModel) {
        this._mergeOption(newOpt, ecModel, false, false);
      };

      MarkerModel.prototype._mergeOption = function (newOpt, ecModel, createdBySelf, isInit) {
        var componentType = this.mainType;

        if (!createdBySelf) {
          ecModel.eachSeries(function (seriesModel) {
            // mainType can be markPoint, markLine, markArea
            var markerOpt = seriesModel.get(this.mainType, true);
            var markerModel = inner$g(seriesModel)[componentType];

            if (!markerOpt || !markerOpt.data) {
              inner$g(seriesModel)[componentType] = null;
              return;
            }

            if (!markerModel) {
              if (isInit) {
                // Default label emphasis `position` and `show`
                fillLabel(markerOpt);
              }

              each(markerOpt.data, function (item) {
                // FIXME Overwrite fillLabel method ?
                if (item instanceof Array) {
                  fillLabel(item[0]);
                  fillLabel(item[1]);
                } else {
                  fillLabel(item);
                }
              });
              markerModel = this.createMarkerModelFromSeries(markerOpt, this, ecModel); // markerModel = new ImplementedMarkerModel(
              //     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);
            }

            inner$g(seriesModel)[componentType] = markerModel;
          }, this);
        }
      };

      MarkerModel.prototype.formatTooltip = function (dataIndex, multipleSeries, dataType) {
        var data = this.getData();
        var value = this.getRawValue(dataIndex);
        var itemName = data.getName(dataIndex);
        return createTooltipMarkup('section', {
          header: this.name,
          blocks: [createTooltipMarkup('nameValue', {
            name: itemName,
            value: value,
            noName: !itemName,
            noValue: value == null
          })]
        });
      };

      MarkerModel.prototype.getData = function () {
        return this._data;
      };

      MarkerModel.prototype.setData = function (data) {
        this._data = data;
      };

      MarkerModel.getMarkerModelFromSeries = function (seriesModel, // Support three types of markers. Strict check.
      componentType) {
        return inner$g(seriesModel)[componentType];
      };

      MarkerModel.type = 'marker';
      MarkerModel.dependencies = ['series', 'grid', 'polar', 'geo'];
      return MarkerModel;
    }(ComponentModel);

    mixin(MarkerModel, DataFormatMixin.prototype);

    var MarkPointModel =
    /** @class */
    function (_super) {
      __extends(MarkPointModel, _super);

      function MarkPointModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = MarkPointModel.type;
        return _this;
      }

      MarkPointModel.prototype.createMarkerModelFromSeries = function (markerOpt, masterMarkerModel, ecModel) {
        return new MarkPointModel(markerOpt, masterMarkerModel, ecModel);
      };

      MarkPointModel.type = 'markPoint';
      MarkPointModel.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
          }
        }
      };
      return MarkPointModel;
    }(MarkerModel);

    function hasXOrY(item) {
      return !(isNaN(parseFloat(item.x)) && isNaN(parseFloat(item.y)));
    }

    function hasXAndY(item) {
      return !isNaN(parseFloat(item.x)) && !isNaN(parseFloat(item.y));
    }

    function markerTypeCalculatorWithExtent(markerType, 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, markerType);
      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];
    } // TODO Specified percent


    var markerTypeCalculator = {
      min: curry(markerTypeCalculatorWithExtent, 'min'),
      max: curry(markerTypeCalculatorWithExtent, 'max'),
      average: curry(markerTypeCalculatorWithExtent, 'average'),
      median: curry(markerTypeCalculatorWithExtent, 'median')
    };
    /**
     * 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
     */

    function dataTransform(seriesModel, item) {
      if (!item) {
        return;
      }

      var data = seriesModel.getData();
      var coordSys = seriesModel.coordinateSystem;
      var dims = coordSys.dimensions; // 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 (!hasXAndY(item) && !isArray(item.coord) && coordSys) {
        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(dims, axisInfo.baseAxis.dim);
          var targetCoordIndex = indexOf(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.
          item.coord = [item.xAxis != null ? item.xAxis : item.radiusAxis, item.yAxis != null ? item.yAxis : item.angleAxis];
        }
      } // x y is provided


      if (item.coord == null) {
        item.coord = [];
      } else {
        // Each coord support max, min, average
        var coord = item.coord;

        for (var i = 0; i < 2; i++) {
          if (markerTypeCalculator[coord[i]]) {
            coord[i] = numCalculate(data, data.mapDimension(dims[i]), coord[i]);
          }
        }
      }

      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 dimItem = seriesModel.getData().getDimensionInfo(dataDim);
      return dimItem && dimItem.coordDim;
    }
    /**
     * Filter data which is out of coordinateSystem range
     * [dataFilter description]
     */


    function dataFilter$1( // Currently only polar and cartesian has containData.
    coordSys, item) {
      // Always return true if there is no coordSys
      return coordSys && coordSys.containData && item.coord && !hasXOrY(item) ? coordSys.containData(item.coord) : true;
    }
    function zoneFilter( // Currently only polar and cartesian has containData.
    coordSys, item1, item2) {
      // Always return true if there is no coordSys
      return coordSys && coordSys.containZone && item1.coord && item2.coord && !hasXOrY(item1) && !hasXOrY(item2) ? coordSys.containZone(item1.coord, item2.coord) : true;
    }
    function createMarkerDimValueGetter(inCoordSys, dims) {
      return inCoordSys ? function (item, dimName, dataIndex, dimIndex) {
        var rawVal = dimIndex < 2 // x, y, radius, angle
        ? item.coord && item.coord[dimIndex] : item.value;
        return parseDataValue(rawVal, dims[dimIndex]);
      } : function (item, dimName, dataIndex, dimIndex) {
        return parseDataValue(item.value, dims[dimIndex]);
      };
    }
    function numCalculate(data, valueDataDim, type) {
      if (type === 'average') {
        var sum_1 = 0;
        var count_1 = 0;
        data.each(valueDataDim, function (val, idx) {
          if (!isNaN(val)) {
            sum_1 += val;
            count_1++;
          }
        });
        return sum_1 / count_1;
      } else if (type === 'median') {
        return data.getMedian(valueDataDim);
      } else {
        // max & min
        return data.getDataExtent(valueDataDim)[type === 'max' ? 1 : 0];
      }
    }

    var inner$h = makeInner();

    var MarkerView =
    /** @class */
    function (_super) {
      __extends(MarkerView, _super);

      function MarkerView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = MarkerView.type;
        return _this;
      }

      MarkerView.prototype.init = function () {
        this.markerGroupMap = createHashMap();
      };

      MarkerView.prototype.render = function (markerModel, ecModel, api) {
        var _this = this;

        var markerGroupMap = this.markerGroupMap;
        markerGroupMap.each(function (item) {
          inner$h(item).keep = false;
        });
        ecModel.eachSeries(function (seriesModel) {
          var markerModel = MarkerModel.getMarkerModelFromSeries(seriesModel, _this.type);
          markerModel && _this.renderSeries(seriesModel, markerModel, ecModel, api);
        });
        markerGroupMap.each(function (item) {
          !inner$h(item).keep && _this.group.remove(item.group);
        });
      };

      MarkerView.prototype.markKeep = function (drawGroup) {
        inner$h(drawGroup).keep = true;
      };

      MarkerView.prototype.toggleBlurSeries = function (seriesModelList, isBlur) {
        var _this = this;

        each(seriesModelList, function (seriesModel) {
          var markerModel = MarkerModel.getMarkerModelFromSeries(seriesModel, _this.type);

          if (markerModel) {
            var data = markerModel.getData();
            data.eachItemGraphicEl(function (el) {
              if (el) {
                isBlur ? enterBlur(el) : leaveBlur(el);
              }
            });
          }
        });
      };

      MarkerView.type = 'marker';
      return MarkerView;
    }(ComponentView);

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

    var MarkPointView =
    /** @class */
    function (_super) {
      __extends(MarkPointView, _super);

      function MarkPointView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = MarkPointView.type;
        return _this;
      }

      MarkPointView.prototype.updateTransform = function (markPointModel, ecModel, api) {
        ecModel.eachSeries(function (seriesModel) {
          var mpModel = MarkerModel.getMarkerModelFromSeries(seriesModel, 'markPoint');

          if (mpModel) {
            updateMarkerLayout(mpModel.getData(), seriesModel, api);
            this.markerGroupMap.get(seriesModel.id).updateLayout();
          }
        }, this);
      };

      MarkPointView.prototype.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 = createData(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 symbolOffset = itemModel.getShallow('symbolOffset');
          var symbolKeepAspect = itemModel.getShallow('symbolKeepAspect'); // TODO: refactor needed: single data item should not support callback function

          if (isFunction(symbol) || isFunction(symbolSize) || isFunction(symbolRotate) || isFunction(symbolOffset)) {
            var rawIdx = mpModel.getRawValue(idx);
            var dataParams = mpModel.getDataParams(idx);

            if (isFunction(symbol)) {
              symbol = symbol(rawIdx, dataParams);
            }

            if (isFunction(symbolSize)) {
              // FIXME 这里不兼容 ECharts 2.x，2.x 貌似参数是整个数据？
              symbolSize = symbolSize(rawIdx, dataParams);
            }

            if (isFunction(symbolRotate)) {
              symbolRotate = symbolRotate(rawIdx, dataParams);
            }

            if (isFunction(symbolOffset)) {
              symbolOffset = symbolOffset(rawIdx, dataParams);
            }
          }

          var style = itemModel.getModel('itemStyle').getItemStyle();
          var color = getVisualFromData(seriesData, 'color');

          if (!style.fill) {
            style.fill = color;
          }

          mpData.setItemVisual(idx, {
            symbol: symbol,
            symbolSize: symbolSize,
            symbolRotate: symbolRotate,
            symbolOffset: symbolOffset,
            symbolKeepAspect: symbolKeepAspect,
            style: style
          });
        }); // 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) {
            getECData(child).dataModel = mpModel;
          });
        });
        this.markKeep(symbolDraw);
        symbolDraw.group.silent = mpModel.get('silent') || seriesModel.get('silent');
      };

      MarkPointView.type = 'markPoint';
      return MarkPointView;
    }(MarkerView);

    function createData(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 extend(extend({}, info), {
            name: coordDim,
            // DON'T use ordinalMeta to parse and collect ordinal.
            ordinalMeta: null
          });
        });
      } else {
        coordDimsInfos = [{
          name: 'value',
          type: 'float'
        }];
      }

      var mpData = new SeriesData(coordDimsInfos, mpModel);
      var dataOpt = map(mpModel.get('data'), curry(dataTransform, seriesModel));

      if (coordSys) {
        dataOpt = filter(dataOpt, curry(dataFilter$1, coordSys));
      }

      var dimValueGetter = createMarkerDimValueGetter(!!coordSys, coordDimsInfos);
      mpData.initData(dataOpt, null, dimValueGetter);
      return mpData;
    }

    function install$E(registers) {
      registers.registerComponentModel(MarkPointModel);
      registers.registerComponentView(MarkPointView);
      registers.registerPreprocessor(function (opt) {
        if (checkMarkerInSeries(opt.series, 'markPoint')) {
          // Make sure markPoint component is enabled
          opt.markPoint = opt.markPoint || {};
        }
      });
    }

    var MarkLineModel =
    /** @class */
    function (_super) {
      __extends(MarkLineModel, _super);

      function MarkLineModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = MarkLineModel.type;
        return _this;
      }

      MarkLineModel.prototype.createMarkerModelFromSeries = function (markerOpt, masterMarkerModel, ecModel) {
        return new MarkLineModel(markerOpt, masterMarkerModel, ecModel);
      };

      MarkLineModel.type = 'markLine';
      MarkLineModel.defaultOption = {
        // zlevel: 0,
        z: 5,
        symbol: ['circle', 'arrow'],
        symbolSize: [8, 16],
        // symbolRotate: 0,
        symbolOffset: 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'
      };
      return MarkLineModel;
    }(MarkerModel);

    var inner$i = makeInner();

    var markLineTransform = function (seriesModel, coordSys, mlModel, item) {
      var data = seriesModel.getData();
      var itemArray;

      if (!isArray(item)) {
        // Special type markLine like 'min', 'max', 'average', 'median'
        var mlType = item.type;

        if (mlType === 'min' || mlType === 'max' || mlType === 'average' || mlType === 'median' // In case
        // data: [{
        //   yAxis: 10
        // }]
        || item.xAxis != null || item.yAxis != null) {
          var valueAxis = void 0;
          var value = void 0;

          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; // Normized to 2d data with start and end point

          var mlFrom = clone(item);
          var mlTo = {
            coord: []
          };
          mlFrom.type = null;
          mlFrom.coord = [];
          mlFrom.coord[baseIndex] = -Infinity;
          mlTo.coord[baseIndex] = Infinity;
          var precision = mlModel.get('precision');

          if (precision >= 0 && isNumber(value)) {
            value = +value.toFixed(Math.min(precision, 20));
          }

          mlFrom.coord[valueIndex] = mlTo.coord[valueIndex] = value;
          itemArray = [mlFrom, mlTo, {
            type: mlType,
            valueIndex: item.valueIndex,
            // Force to use the value of calculated value.
            value: value
          }];
        } else {
          // Invalid data
          if ("development" !== 'production') {
            logError('Invalid markLine data.');
          }

          itemArray = [];
        }
      } else {
        itemArray = item;
      }

      var normalizedItem = [dataTransform(seriesModel, itemArray[0]), dataTransform(seriesModel, itemArray[1]), extend({}, itemArray[2])]; // Avoid line data type is extended by from(to) data type

      normalizedItem[2].type = normalizedItem[2].type || null; // Merge from option and to option into line option

      merge(normalizedItem[2], normalizedItem[0]);
      merge(normalizedItem[2], normalizedItem[1]);
      return normalizedItem;
    };

    function isInfinity(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 isInfinity(fromCoord[otherDimIndex]) && isInfinity(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 getMarkerPosition
          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 (isCoordinateSystemType(coordSys, 'cartesian2d')) {
          // TODO: TYPE ts@4.1 may still infer it as Axis instead of Axis2D. Not sure if it's a bug
          var xAxis = coordSys.getAxis('x');
          var yAxis = coordSys.getAxis('y');
          var dims = coordSys.dimensions;

          if (isInfinity(data.get(dims[0], idx))) {
            point[0] = xAxis.toGlobalCoord(xAxis.getExtent()[isFrom ? 0 : 1]);
          } else if (isInfinity(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);
    }

    var MarkLineView =
    /** @class */
    function (_super) {
      __extends(MarkLineView, _super);

      function MarkLineView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = MarkLineView.type;
        return _this;
      }

      MarkLineView.prototype.updateTransform = function (markLineModel, ecModel, api) {
        ecModel.eachSeries(function (seriesModel) {
          var mlModel = MarkerModel.getMarkerModelFromSeries(seriesModel, 'markLine');

          if (mlModel) {
            var mlData_1 = mlModel.getData();
            var fromData_1 = inner$i(mlModel).from;
            var toData_1 = inner$i(mlModel).to; // Update visual and layout of from symbol and to symbol

            fromData_1.each(function (idx) {
              updateSingleMarkerEndLayout(fromData_1, idx, true, seriesModel, api);
              updateSingleMarkerEndLayout(toData_1, idx, false, seriesModel, api);
            }); // Update layout of line

            mlData_1.each(function (idx) {
              mlData_1.setItemLayout(idx, [fromData_1.getItemLayout(idx), toData_1.getItemLayout(idx)]);
            });
            this.markerGroupMap.get(seriesModel.id).updateLayout();
          }
        }, this);
      };

      MarkLineView.prototype.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$1(coordSys, seriesModel, mlModel);
        var fromData = mlData.from;
        var toData = mlData.to;
        var lineData = mlData.line;
        inner$i(mlModel).from = fromData;
        inner$i(mlModel).to = toData; // Line data for tooltip and formatter

        mlModel.setData(lineData); // TODO
        // Functionally, `symbolSize` & `symbolOffset` can also be 2D array now.
        // But the related logic and type definition are not finished yet.
        // Finish it if required

        var symbolType = mlModel.get('symbol');
        var symbolSize = mlModel.get('symbolSize');
        var symbolRotate = mlModel.get('symbolRotate');
        var symbolOffset = mlModel.get('symbolOffset'); // TODO: support callback function like markPoint

        if (!isArray(symbolType)) {
          symbolType = [symbolType, symbolType];
        }

        if (!isArray(symbolSize)) {
          symbolSize = [symbolSize, symbolSize];
        }

        if (!isArray(symbolRotate)) {
          symbolRotate = [symbolRotate, symbolRotate];
        }

        if (!isArray(symbolOffset)) {
          symbolOffset = [symbolOffset, symbolOffset];
        } // 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 lineStyle = lineData.getItemModel(idx).getModel('lineStyle').getLineStyle(); // lineData.setItemVisual(idx, {
          //     color: lineColor || fromData.getItemVisual(idx, 'color')
          // });

          lineData.setItemLayout(idx, [fromData.getItemLayout(idx), toData.getItemLayout(idx)]);

          if (lineStyle.stroke == null) {
            lineStyle.stroke = fromData.getItemVisual(idx, 'style').fill;
          }

          lineData.setItemVisual(idx, {
            fromSymbolKeepAspect: fromData.getItemVisual(idx, 'symbolKeepAspect'),
            fromSymbolOffset: fromData.getItemVisual(idx, 'symbolOffset'),
            fromSymbolRotate: fromData.getItemVisual(idx, 'symbolRotate'),
            fromSymbolSize: fromData.getItemVisual(idx, 'symbolSize'),
            fromSymbol: fromData.getItemVisual(idx, 'symbol'),
            toSymbolKeepAspect: toData.getItemVisual(idx, 'symbolKeepAspect'),
            toSymbolOffset: toData.getItemVisual(idx, 'symbolOffset'),
            toSymbolRotate: toData.getItemVisual(idx, 'symbolRotate'),
            toSymbolSize: toData.getItemVisual(idx, 'symbolSize'),
            toSymbol: toData.getItemVisual(idx, 'symbol'),
            style: lineStyle
          });
        });
        lineDraw.updateData(lineData); // Set host model for tooltip
        // FIXME

        mlData.line.eachItemGraphicEl(function (el) {
          getECData(el).dataModel = mlModel;
          el.traverse(function (child) {
            getECData(child).dataModel = mlModel;
          });
        });

        function updateDataVisualAndLayout(data, idx, isFrom) {
          var itemModel = data.getItemModel(idx);
          updateSingleMarkerEndLayout(data, idx, isFrom, seriesModel, api);
          var style = itemModel.getModel('itemStyle').getItemStyle();

          if (style.fill == null) {
            style.fill = getVisualFromData(seriesData, 'color');
          }

          data.setItemVisual(idx, {
            symbolKeepAspect: itemModel.get('symbolKeepAspect'),
            // `0` should be considered as a valid value, so use `retrieve2` instead of `||`
            symbolOffset: retrieve2(itemModel.get('symbolOffset', true), symbolOffset[isFrom ? 0 : 1]),
            symbolRotate: retrieve2(itemModel.get('symbolRotate', true), symbolRotate[isFrom ? 0 : 1]),
            // TODO: when 2d array is supported, it should ignore parent
            symbolSize: retrieve2(itemModel.get('symbolSize'), symbolSize[isFrom ? 0 : 1]),
            symbol: retrieve2(itemModel.get('symbol', true), symbolType[isFrom ? 0 : 1]),
            style: style
          });
        }

        this.markKeep(lineDraw);
        lineDraw.group.silent = mlModel.get('silent') || seriesModel.get('silent');
      };

      MarkLineView.type = 'markLine';
      return MarkLineView;
    }(MarkerView);

    function createList$1(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 extend(extend({}, info), {
            name: coordDim,
            // DON'T use ordinalMeta to parse and collect ordinal.
            ordinalMeta: null
          });
        });
      } else {
        coordDimsInfos = [{
          name: 'value',
          type: 'float'
        }];
      }

      var fromData = new SeriesData(coordDimsInfos, mlModel);
      var toData = new SeriesData(coordDimsInfos, mlModel); // No dimensions

      var lineData = new SeriesData([], mlModel);
      var optData = map(mlModel.get('data'), curry(markLineTransform, seriesModel, coordSys, mlModel));

      if (coordSys) {
        optData = filter(optData, curry(markLineFilter, coordSys));
      }

      var dimValueGetter = createMarkerDimValueGetter(!!coordSys, coordDimsInfos);
      fromData.initData(map(optData, function (item) {
        return item[0];
      }), null, dimValueGetter);
      toData.initData(map(optData, function (item) {
        return item[1];
      }), null, dimValueGetter);
      lineData.initData(map(optData, function (item) {
        return item[2];
      }));
      lineData.hasItemOption = true;
      return {
        from: fromData,
        to: toData,
        line: lineData
      };
    }

    function install$F(registers) {
      registers.registerComponentModel(MarkLineModel);
      registers.registerComponentView(MarkLineView);
      registers.registerPreprocessor(function (opt) {
        if (checkMarkerInSeries(opt.series, 'markLine')) {
          // Make sure markLine component is enabled
          opt.markLine = opt.markLine || {};
        }
      });
    }

    var MarkAreaModel =
    /** @class */
    function (_super) {
      __extends(MarkAreaModel, _super);

      function MarkAreaModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = MarkAreaModel.type;
        return _this;
      }

      MarkAreaModel.prototype.createMarkerModelFromSeries = function (markerOpt, masterMarkerModel, ecModel) {
        return new MarkAreaModel(markerOpt, masterMarkerModel, ecModel);
      };

      MarkAreaModel.type = 'markArea';
      MarkAreaModel.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'
          }
        }
      };
      return MarkAreaModel;
    }(MarkerModel);

    var inner$j = makeInner();

    var markAreaTransform = function (seriesModel, coordSys, maModel, item) {
      // item may be null
      var item0 = item[0];
      var item1 = item[1];

      if (!item0 || !item1) {
        return;
      }

      var lt = dataTransform(seriesModel, item0);
      var rb = dataTransform(seriesModel, item1); // FIXME make sure lt is less than rb

      var ltCoord = lt.coord;
      var rbCoord = rb.coord;
      ltCoord[0] = retrieve(ltCoord[0], -Infinity);
      ltCoord[1] = retrieve(ltCoord[1], -Infinity);
      rbCoord[0] = retrieve(rbCoord[0], Infinity);
      rbCoord[1] = retrieve(rbCoord[1], Infinity); // Merge option into one

      var result = 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 isInfinity$1(val) {
      return !isNaN(val) && !isFinite(val);
    } // If a markArea has one dim


    function ifMarkAreaHasOnlyDim(dimIndex, fromCoord, toCoord, coordSys) {
      var otherDimIndex = 1 - dimIndex;
      return isInfinity$1(fromCoord[otherDimIndex]) && isInfinity$1(toCoord[otherDimIndex]);
    }

    function markAreaFilter(coordSys, item) {
      var fromCoord = item.coord[0];
      var toCoord = item.coord[1];
      var item0 = {
        coord: fromCoord,
        x: item.x0,
        y: item.y0
      };
      var item1 = {
        coord: toCoord,
        x: item.x1,
        y: item.y1
      };

      if (isCoordinateSystemType(coordSys, 'cartesian2d')) {
        // In case
        // {
        //  markArea: {
        //    data: [{ yAxis: 2 }]
        //  }
        // }
        if (fromCoord && toCoord && (ifMarkAreaHasOnlyDim(1, fromCoord, toCoord) || ifMarkAreaHasOnlyDim(0, fromCoord, toCoord))) {
          return true;
        } // Directly returning true may also do the work,
        // because markArea will not be shown automatically
        // when it's not included in coordinate system.
        // But filtering ahead can avoid keeping rendering markArea
        // when there are too many of them.


        return zoneFilter(coordSys, item0, item1);
      }

      return dataFilter$1(coordSys, item0) || dataFilter$1(coordSys, item1);
    } // 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) {
          // Consider the case that user input the right-bottom point first
          // Pick the larger x and y as 'x1' and 'y1'
          var pointValue0 = data.getValues(['x0', 'y0'], idx);
          var pointValue1 = data.getValues(['x1', 'y1'], idx);
          var clampPointValue0 = coordSys.clampData(pointValue0);
          var clampPointValue1 = coordSys.clampData(pointValue1);
          var pointValue = [];

          if (dims[0] === 'x0') {
            pointValue[0] = clampPointValue0[0] > clampPointValue1[0] ? pointValue1[0] : pointValue0[0];
          } else {
            pointValue[0] = clampPointValue0[0] > clampPointValue1[0] ? pointValue0[0] : pointValue1[0];
          }

          if (dims[1] === 'y0') {
            pointValue[1] = clampPointValue0[1] > clampPointValue1[1] ? pointValue1[1] : pointValue0[1];
          } else {
            pointValue[1] = clampPointValue0[1] > clampPointValue1[1] ? pointValue0[1] : pointValue1[1];
          } // Use the getMarkerPosition


          point = seriesModel.getMarkerPosition(pointValue, dims, true);
        } 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 (isCoordinateSystemType(coordSys, 'cartesian2d')) {
          // TODO: TYPE ts@4.1 may still infer it as Axis instead of Axis2D. Not sure if it's a bug
          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 (isInfinity$1(x)) {
            point[0] = xAxis.toGlobalCoord(xAxis.getExtent()[dims[0] === 'x0' ? 0 : 1]);
          } else if (isInfinity$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']];

    var MarkAreaView =
    /** @class */
    function (_super) {
      __extends(MarkAreaView, _super);

      function MarkAreaView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = MarkAreaView.type;
        return _this;
      }

      MarkAreaView.prototype.updateTransform = function (markAreaModel, ecModel, api) {
        ecModel.eachSeries(function (seriesModel) {
          var maModel = MarkerModel.getMarkerModelFromSeries(seriesModel, 'markArea');

          if (maModel) {
            var areaData_1 = maModel.getData();
            areaData_1.each(function (idx) {
              var points = map(dimPermutations, function (dim) {
                return getSingleMarkerEndPoint(areaData_1, idx, dim, seriesModel, api);
              }); // Layout

              areaData_1.setItemLayout(idx, points);
              var el = areaData_1.getItemGraphicEl(idx);
              el.setShape('points', points);
            });
          }
        }, this);
      };

      MarkAreaView.prototype.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);
        this.markKeep(polygonGroup);
        var areaData = createList$2(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);
          });
          var xAxisScale = coordSys.getAxis('x').scale;
          var yAxisScale = coordSys.getAxis('y').scale;
          var xAxisExtent = xAxisScale.getExtent();
          var yAxisExtent = yAxisScale.getExtent();
          var xPointExtent = [xAxisScale.parse(areaData.get('x0', idx)), xAxisScale.parse(areaData.get('x1', idx))];
          var yPointExtent = [yAxisScale.parse(areaData.get('y0', idx)), yAxisScale.parse(areaData.get('y1', idx))];
          asc(xPointExtent);
          asc(yPointExtent);
          var overlapped = !(xAxisExtent[0] > xPointExtent[1] || xAxisExtent[1] < xPointExtent[0] || yAxisExtent[0] > yPointExtent[1] || yAxisExtent[1] < yPointExtent[0]); // 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 = !overlapped;
          areaData.setItemLayout(idx, {
            points: points,
            allClipped: allClipped
          });
          var style = areaData.getItemModel(idx).getModel('itemStyle').getItemStyle();
          var color$1 = getVisualFromData(seriesData, 'color');

          if (!style.fill) {
            style.fill = color$1;

            if (isString(style.fill)) {
              style.fill = modifyAlpha(style.fill, 0.4);
            }
          }

          if (!style.stroke) {
            style.stroke = color$1;
          } // Visual


          areaData.setItemVisual(idx, 'style', style);
        });
        areaData.diff(inner$j(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 = inner$j(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 = inner$j(polygonGroup).data.getItemGraphicEl(idx);
          polygonGroup.group.remove(polygon);
        }).execute();
        areaData.eachItemGraphicEl(function (polygon, idx) {
          var itemModel = areaData.getItemModel(idx);
          var style = areaData.getItemVisual(idx, 'style');
          polygon.useStyle(areaData.getItemVisual(idx, 'style'));
          setLabelStyle(polygon, getLabelStatesModels(itemModel), {
            labelFetcher: maModel,
            labelDataIndex: idx,
            defaultText: areaData.getName(idx) || '',
            inheritColor: isString(style.fill) ? modifyAlpha(style.fill, 1) : '#000'
          });
          setStatesStylesFromModel(polygon, itemModel);
          toggleHoverEmphasis(polygon, null, null, itemModel.get(['emphasis', 'disabled']));
          getECData(polygon).dataModel = maModel;
        });
        inner$j(polygonGroup).data = areaData;
        polygonGroup.group.silent = maModel.get('silent') || seriesModel.get('silent');
      };

      MarkAreaView.type = 'markArea';
      return MarkAreaView;
    }(MarkerView);

    function createList$2(coordSys, seriesModel, maModel) {
      var areaData;
      var dataDims;
      var dims = ['x0', 'y0', 'x1', 'y1'];

      if (coordSys) {
        var coordDimsInfos_1 = 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 extend(extend({}, info), {
            name: coordDim,
            // DON'T use ordinalMeta to parse and collect ordinal.
            ordinalMeta: null
          });
        });
        dataDims = map(dims, function (dim, idx) {
          return {
            name: dim,
            type: coordDimsInfos_1[idx % 2].type
          };
        });
        areaData = new SeriesData(dataDims, maModel);
      } else {
        dataDims = [{
          name: 'value',
          type: 'float'
        }];
        areaData = new SeriesData(dataDims, maModel);
      }

      var optData = map(maModel.get('data'), curry(markAreaTransform, seriesModel, coordSys, maModel));

      if (coordSys) {
        optData = filter(optData, curry(markAreaFilter, coordSys));
      }

      var dimValueGetter = coordSys ? function (item, dimName, dataIndex, dimIndex) {
        // TODO should convert to ParsedValue?
        var rawVal = item.coord[Math.floor(dimIndex / 2)][dimIndex % 2];
        return parseDataValue(rawVal, dataDims[dimIndex]);
      } : function (item, dimName, dataIndex, dimIndex) {
        return parseDataValue(item.value, dataDims[dimIndex]);
      };
      areaData.initData(optData, null, dimValueGetter);
      areaData.hasItemOption = true;
      return areaData;
    }

    function install$G(registers) {
      registers.registerComponentModel(MarkAreaModel);
      registers.registerComponentView(MarkAreaView);
      registers.registerPreprocessor(function (opt) {
        if (checkMarkerInSeries(opt.series, 'markArea')) {
          // Make sure markArea component is enabled
          opt.markArea = opt.markArea || {};
        }
      });
    }

    var getDefaultSelectorOptions = function (ecModel, type) {
      if (type === 'all') {
        return {
          type: 'all',
          title: ecModel.getLocaleModel().get(['legend', 'selector', 'all'])
        };
      } else if (type === 'inverse') {
        return {
          type: 'inverse',
          title: ecModel.getLocaleModel().get(['legend', 'selector', 'inverse'])
        };
      }
    };

    var LegendModel =
    /** @class */
    function (_super) {
      __extends(LegendModel, _super);

      function LegendModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = LegendModel.type;
        _this.layoutMode = {
          type: 'box',
          // legend.width/height are maxWidth/maxHeight actually,
          // whereas real 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
        };
        return _this;
      }

      LegendModel.prototype.init = function (option, parentModel, ecModel) {
        this.mergeDefaultAndTheme(option, ecModel);
        option.selected = option.selected || {};

        this._updateSelector(option);
      };

      LegendModel.prototype.mergeOption = function (option, ecModel) {
        _super.prototype.mergeOption.call(this, option, ecModel);

        this._updateSelector(option);
      };

      LegendModel.prototype._updateSelector = function (option) {
        var selector = option.selector;
        var ecModel = this.ecModel;

        if (selector === true) {
          selector = option.selector = ['all', 'inverse'];
        }

        if (isArray(selector)) {
          each(selector, function (item, index) {
            isString(item) && (item = {
              type: item
            });
            selector[index] = merge(item, getDefaultSelectorOptions(ecModel, item.type));
          });
        }
      };

      LegendModel.prototype.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_1 = legendData[i].get('name');

            if (this.isSelected(name_1)) {
              // Force to unselect others
              this.select(name_1);
              hasSelected = true;
              break;
            }
          } // Try select the first if selectedMode is single


          !hasSelected && this.select(legendData[0].get('name'));
        }
      };

      LegendModel.prototype._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 is not specified in option, use availableNames as data,
        // which is convenient for user preparing option.

        var rawData = this.get('data') || potentialData;
        var legendNameMap = createHashMap();
        var legendData = map(rawData, function (dataItem) {
          // Can be string or number
          if (isString(dataItem) || isNumber(dataItem)) {
            dataItem = {
              name: dataItem
            };
          }

          if (legendNameMap.get(dataItem.name)) {
            // remove legend name duplicate
            return null;
          }

          legendNameMap.set(dataItem.name, true);
          return new Model(dataItem, this, this.ecModel);
        }, this);
        /**
         * @type {Array.<module:echarts/model/Model>}
         * @private
         */

        this._data = filter(legendData, function (item) {
          return !!item;
        });
      };

      LegendModel.prototype.getData = function () {
        return this._data;
      };

      LegendModel.prototype.select = function (name) {
        var selected = this.option.selected;
        var selectedMode = this.get('selectedMode');

        if (selectedMode === 'single') {
          var data = this._data;
          each(data, function (dataItem) {
            selected[dataItem.get('name')] = false;
          });
        }

        selected[name] = true;
      };

      LegendModel.prototype.unSelect = function (name) {
        if (this.get('selectedMode') !== 'single') {
          this.option.selected[name] = false;
        }
      };

      LegendModel.prototype.toggleSelected = function (name) {
        var selected = this.option.selected; // Default is true

        if (!selected.hasOwnProperty(name)) {
          selected[name] = true;
        }

        this[selected[name] ? 'unSelect' : 'select'](name);
      };

      LegendModel.prototype.allSelect = function () {
        var data = this._data;
        var selected = this.option.selected;
        each(data, function (dataItem) {
          selected[dataItem.get('name', true)] = true;
        });
      };

      LegendModel.prototype.inverseSelect = function () {
        var data = this._data;
        var selected = this.option.selected;
        each(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];
        });
      };

      LegendModel.prototype.isSelected = function (name) {
        var selected = this.option.selected;
        return !(selected.hasOwnProperty(name) && !selected[name]) && indexOf(this._availableNames, name) >= 0;
      };

      LegendModel.prototype.getOrient = function () {
        return this.get('orient') === 'vertical' ? {
          index: 1,
          name: 'vertical'
        } : {
          index: 0,
          name: 'horizontal'
        };
      };

      LegendModel.type = 'legend.plain';
      LegendModel.dependencies = ['series'];
      LegendModel.defaultOption = {
        // zlevel: 0,
        z: 4,
        show: true,
        orient: 'horizontal',
        left: 'center',
        // right: 'center',
        top: 0,
        // bottom: null,
        align: 'auto',
        backgroundColor: 'rgba(0,0,0,0)',
        borderColor: '#ccc',
        borderRadius: 0,
        borderWidth: 0,
        padding: 5,
        itemGap: 10,
        itemWidth: 25,
        itemHeight: 14,
        symbolRotate: 'inherit',
        symbolKeepAspect: true,
        inactiveColor: '#ccc',
        inactiveBorderColor: '#ccc',
        inactiveBorderWidth: 'auto',
        itemStyle: {
          color: 'inherit',
          opacity: 'inherit',
          borderColor: 'inherit',
          borderWidth: 'auto',
          borderCap: 'inherit',
          borderJoin: 'inherit',
          borderDashOffset: 'inherit',
          borderMiterLimit: 'inherit'
        },
        lineStyle: {
          width: 'auto',
          color: 'inherit',
          inactiveColor: '#ccc',
          inactiveWidth: 2,
          opacity: 'inherit',
          type: 'inherit',
          cap: 'inherit',
          join: 'inherit',
          dashOffset: 'inherit',
          miterLimit: 'inherit'
        },
        textStyle: {
          color: '#333'
        },
        selectedMode: true,
        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'
          }
        },
        selectorPosition: 'auto',
        selectorItemGap: 7,
        selectorButtonGap: 10,
        tooltip: {
          show: false
        }
      };
      return LegendModel;
    }(ComponentModel);

    var curry$1 = curry;
    var each$c = each;
    var Group$2 = Group;

    var LegendView =
    /** @class */
    function (_super) {
      __extends(LegendView, _super);

      function LegendView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = LegendView.type;
        _this.newlineDisabled = false;
        return _this;
      }

      LegendView.prototype.init = function () {
        this.group.add(this._contentGroup = new Group$2());
        this.group.add(this._selectorGroup = new Group$2());
        this._isFirstRender = true;
      };
      /**
       * @protected
       */


      LegendView.prototype.getContentGroup = function () {
        return this._contentGroup;
      };
      /**
       * @protected
       */


      LegendView.prototype.getSelectorGroup = function () {
        return this._selectorGroup;
      };
      /**
       * @override
       */


      LegendView.prototype.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';
        } // selector has been normalized to an array in model


        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.x = layoutRect.x - mainRect.x;
        this.group.y = layoutRect.y - mainRect.y;
        this.group.markRedraw(); // Render background after group is layout.

        this.group.add(this._backgroundEl = makeBackground(mainRect, legendModel));
      };

      LegendView.prototype.resetInner = function () {
        this.getContentGroup().removeAll();
        this._backgroundEl && this.group.remove(this._backgroundEl);
        this.getSelectorGroup().removeAll();
      };

      LegendView.prototype.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$c(legendModel.getData(), function (legendItemModel, dataIndex) {
          var name = legendItemModel.get('name'); // Use empty string or \n as a newline string

          if (!this.newlineDisabled && (name === '' || name === '\n')) {
            var g = new Group$2(); // @ts-ignore

            g.newline = true;
            contentGroup.add(g);
            return;
          } // Representitive series.


          var seriesModel = ecModel.getSeriesByName(name)[0];

          if (legendDrawnMap.get(name)) {
            // Have been drawn
            return;
          } // Legend to control series.


          if (seriesModel) {
            var data = seriesModel.getData();
            var lineVisualStyle = data.getVisual('legendLineStyle') || {};
            var legendIcon = data.getVisual('legendIcon');
            /**
             * `data.getVisual('style')` may be the color from the register
             * in series. For example, for line series,
             */

            var style = data.getVisual('style');

            var itemGroup = this._createItem(seriesModel, name, dataIndex, legendItemModel, legendModel, itemAlign, lineVisualStyle, style, legendIcon, selectMode, api);

            itemGroup.on('click', curry$1(dispatchSelectAction, name, null, api, excludeSeriesId)).on('mouseover', curry$1(dispatchHighlightAction, seriesModel.name, null, api, excludeSeriesId)).on('mouseout', curry$1(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 style = provider.getItemVisual(idx, 'style');
                var legendIcon = provider.getItemVisual(idx, 'legendIcon');
                var colorArr = parse(style.fill); // Color may be set to transparent in visualMap when data is out of range.
                // Do not show nothing.

                if (colorArr && colorArr[3] === 0) {
                  colorArr[3] = 0.2; // TODO color is set to 0, 0, 0, 0. Should show correct RGBA

                  style = extend(extend({}, style), {
                    fill: stringify(colorArr, 'rgba')
                  });
                }

                var itemGroup = this._createItem(seriesModel, name, dataIndex, legendItemModel, legendModel, itemAlign, {}, style, legendIcon, selectMode, api); // FIXME: consider different series has items with the same name.


                itemGroup.on('click', curry$1(dispatchSelectAction, null, name, api, excludeSeriesId)) // Should not specify the series name, consider legend controls
                // more than one pie series.
                .on('mouseover', curry$1(dispatchHighlightAction, null, name, api, excludeSeriesId)).on('mouseout', curry$1(dispatchDownplayAction, null, name, api, excludeSeriesId));
                legendDrawnMap.set(name, true);
              }
            }, this);
          }

          if ("development" !== 'production') {
            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);
        }
      };

      LegendView.prototype._createSelector = function (selector, legendModel, api, orient, selectorPosition) {
        var selectorGroup = this.getSelectorGroup();
        each$c(selector, function createSelectorButton(selectorItem) {
          var type = selectorItem.type;
          var labelText = new ZRText({
            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, {
            normal: labelModel,
            emphasis: emphasisLabelModel
          }, {
            defaultText: selectorItem.title
          });
          enableHoverEmphasis(labelText);
        });
      };

      LegendView.prototype._createItem = function (seriesModel, name, dataIndex, legendItemModel, legendModel, itemAlign, lineVisualStyle, itemVisualStyle, legendIcon, selectMode, api) {
        var drawType = seriesModel.visualDrawType;
        var itemWidth = legendModel.get('itemWidth');
        var itemHeight = legendModel.get('itemHeight');
        var isSelected = legendModel.isSelected(name);
        var iconRotate = legendItemModel.get('symbolRotate');
        var symbolKeepAspect = legendItemModel.get('symbolKeepAspect');
        var legendIconType = legendItemModel.get('icon');
        legendIcon = legendIconType || legendIcon || 'roundRect';
        var style = getLegendStyle(legendIcon, legendItemModel, lineVisualStyle, itemVisualStyle, drawType, isSelected, api);
        var itemGroup = new Group$2();
        var textStyleModel = legendItemModel.getModel('textStyle');

        if (isFunction(seriesModel.getLegendIcon) && (!legendIconType || legendIconType === 'inherit')) {
          // Series has specific way to define legend icon
          itemGroup.add(seriesModel.getLegendIcon({
            itemWidth: itemWidth,
            itemHeight: itemHeight,
            icon: legendIcon,
            iconRotate: iconRotate,
            itemStyle: style.itemStyle,
            lineStyle: style.lineStyle,
            symbolKeepAspect: symbolKeepAspect
          }));
        } else {
          // Use default legend icon policy for most series
          var rotate = legendIconType === 'inherit' && seriesModel.getData().getVisual('symbol') ? iconRotate === 'inherit' ? seriesModel.getData().getVisual('symbolRotate') : iconRotate : 0; // No rotation for no icon

          itemGroup.add(getDefaultLegendIcon({
            itemWidth: itemWidth,
            itemHeight: itemHeight,
            icon: legendIcon,
            iconRotate: rotate,
            itemStyle: style.itemStyle,
            lineStyle: style.lineStyle,
            symbolKeepAspect: symbolKeepAspect
          }));
        }

        var textX = itemAlign === 'left' ? itemWidth + 5 : -5;
        var textAlign = itemAlign;
        var formatter = legendModel.get('formatter');
        var content = name;

        if (isString(formatter) && formatter) {
          content = formatter.replace('{name}', name != null ? name : '');
        } else if (isFunction(formatter)) {
          content = formatter(name);
        }

        var inactiveColor = legendItemModel.get('inactiveColor');
        itemGroup.add(new ZRText({
          style: createTextStyle(textStyleModel, {
            text: content,
            x: textX,
            y: itemHeight / 2,
            fill: isSelected ? textStyleModel.getTextColor() : inactiveColor,
            align: textAlign,
            verticalAlign: 'middle'
          })
        })); // Add a invisible rect to increase the area of mouse hover

        var hitRect = new Rect({
          shape: itemGroup.getBoundingRect(),
          invisible: true
        });
        var tooltipModel = legendItemModel.getModel('tooltip');

        if (tooltipModel.get('show')) {
          setTooltipConfig({
            el: hitRect,
            componentModel: legendModel,
            itemName: name,
            itemTooltipOption: tooltipModel.option
          });
        }

        itemGroup.add(hitRect);
        itemGroup.eachChild(function (child) {
          child.silent = true;
        });
        hitRect.silent = !selectMode;
        this.getContentGroup().add(itemGroup);
        enableHoverEmphasis(itemGroup); // @ts-ignore

        itemGroup.__legendDataIndex = dataIndex;
        return itemGroup;
      };

      LegendView.prototype.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];
        selectorGroup.markRedraw();
        contentGroup.markRedraw();

        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.x = selectorPos[0];
          selectorGroup.y = selectorPos[1];
          contentGroup.x = contentPos[0];
          contentGroup.y = contentPos[1];
          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.x = contentPos[0];
          contentGroup.y = contentPos[1];
          return this.group.getBoundingRect();
        }
      };
      /**
       * @protected
       */


      LegendView.prototype.remove = function () {
        this.getContentGroup().removeAll();
        this._isFirstRender = true;
      };

      LegendView.type = 'legend.plain';
      return LegendView;
    }(ComponentView);

    function getLegendStyle(iconType, legendItemModel, lineVisualStyle, itemVisualStyle, drawType, isSelected, api) {
      /**
       * Use series style if is inherit;
       * elsewise, use legend style
       */
      function handleCommonProps(style, visualStyle) {
        // If lineStyle.width is 'auto', it is set to be 2 if series has border
        if (style.lineWidth === 'auto') {
          style.lineWidth = visualStyle.lineWidth > 0 ? 2 : 0;
        }

        each$c(style, function (propVal, propName) {
          style[propName] === 'inherit' && (style[propName] = visualStyle[propName]);
        });
      } // itemStyle


      var itemStyleModel = legendItemModel.getModel('itemStyle');
      var itemStyle = itemStyleModel.getItemStyle();
      var iconBrushType = iconType.lastIndexOf('empty', 0) === 0 ? 'fill' : 'stroke';
      var decalStyle = itemStyleModel.getShallow('decal');
      itemStyle.decal = !decalStyle || decalStyle === 'inherit' ? itemVisualStyle.decal : createOrUpdatePatternFromDecal(decalStyle, api);

      if (itemStyle.fill === 'inherit') {
        /**
         * Series with visualDrawType as 'stroke' should have
         * series stroke as legend fill
         */
        itemStyle.fill = itemVisualStyle[drawType];
      }

      if (itemStyle.stroke === 'inherit') {
        /**
         * icon type with "emptyXXX" should use fill color
         * in visual style
         */
        itemStyle.stroke = itemVisualStyle[iconBrushType];
      }

      if (itemStyle.opacity === 'inherit') {
        /**
         * Use lineStyle.opacity if drawType is stroke
         */
        itemStyle.opacity = (drawType === 'fill' ? itemVisualStyle : lineVisualStyle).opacity;
      }

      handleCommonProps(itemStyle, itemVisualStyle); // lineStyle

      var legendLineModel = legendItemModel.getModel('lineStyle');
      var lineStyle = legendLineModel.getLineStyle();
      handleCommonProps(lineStyle, lineVisualStyle); // Fix auto color to real color

      itemStyle.fill === 'auto' && (itemStyle.fill = itemVisualStyle.fill);
      itemStyle.stroke === 'auto' && (itemStyle.stroke = itemVisualStyle.fill);
      lineStyle.stroke === 'auto' && (lineStyle.stroke = itemVisualStyle.fill);

      if (!isSelected) {
        var borderWidth = legendItemModel.get('inactiveBorderWidth');
        /**
         * Since stroke is set to be inactiveBorderColor, it may occur that
         * there is no border in series but border in legend, so we need to
         * use border only when series has border if is set to be auto
         */

        var visualHasBorder = itemStyle[iconBrushType];
        itemStyle.lineWidth = borderWidth === 'auto' ? itemVisualStyle.lineWidth > 0 && visualHasBorder ? 2 : 0 : itemStyle.lineWidth;
        itemStyle.fill = legendItemModel.get('inactiveColor');
        itemStyle.stroke = legendItemModel.get('inactiveBorderColor');
        lineStyle.stroke = legendLineModel.get('inactiveColor');
        lineStyle.lineWidth = legendLineModel.get('inactiveWidth');
      }

      return {
        itemStyle: itemStyle,
        lineStyle: lineStyle
      };
    }

    function getDefaultLegendIcon(opt) {
      var symboType = opt.icon || 'roundRect';
      var icon = createSymbol(symboType, 0, 0, opt.itemWidth, opt.itemHeight, opt.itemStyle.fill, opt.symbolKeepAspect);
      icon.setStyle(opt.itemStyle);
      icon.rotation = (opt.iconRotate || 0) * Math.PI / 180;
      icon.setOrigin([opt.itemWidth / 2, opt.itemHeight / 2]);

      if (symboType.indexOf('empty') > -1) {
        icon.style.stroke = icon.style.fill;
        icon.style.fill = '#fff';
        icon.style.lineWidth = 2;
      }

      return icon;
    }

    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
      // TODO highlight immediately may cause animation loss.

      dispatchHighlightAction(seriesName, dataName, api, excludeSeriesId);
    }

    function isUseHoverLayer(api) {
      var list = api.getZr().storage.getDisplayList();
      var emphasisState;
      var i = 0;
      var len = list.length;

      while (i < len && !(emphasisState = list[i].states.emphasis)) {
        i++;
      }

      return emphasisState && emphasisState.hoverLayer;
    }

    function dispatchHighlightAction(seriesName, dataName, api, excludeSeriesId) {
      // If element hover will move to a hoverLayer.
      if (!isUseHoverLayer(api)) {
        api.dispatchAction({
          type: 'highlight',
          seriesName: seriesName,
          name: dataName,
          excludeSeriesId: excludeSeriesId
        });
      }
    }

    function dispatchDownplayAction(seriesName, dataName, api, excludeSeriesId) {
      // If element hover will move to a hoverLayer.
      if (!isUseHoverLayer(api)) {
        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.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

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

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

    function installLegendAction(registers) {
      /**
       * @event legendToggleSelect
       * @type {Object}
       * @property {string} type 'legendToggleSelect'
       * @property {string} [from]
       * @property {string} name Series name or data item name
       */
      registers.registerAction('legendToggleSelect', 'legendselectchanged', curry(legendSelectActionHandler, 'toggleSelected'));
      registers.registerAction('legendAllSelect', 'legendselectall', curry(legendSelectActionHandler, 'allSelect'));
      registers.registerAction('legendInverseSelect', 'legendinverseselect', curry(legendSelectActionHandler, 'inverseSelect'));
      /**
       * @event legendSelect
       * @type {Object}
       * @property {string} type 'legendSelect'
       * @property {string} name Series name or data item name
       */

      registers.registerAction('legendSelect', 'legendselected', curry(legendSelectActionHandler, 'select'));
      /**
       * @event legendUnSelect
       * @type {Object}
       * @property {string} type 'legendUnSelect'
       * @property {string} name Series name or data item name
       */

      registers.registerAction('legendUnSelect', 'legendunselected', curry(legendSelectActionHandler, 'unSelect'));
    }

    function install$H(registers) {
      registers.registerComponentModel(LegendModel);
      registers.registerComponentView(LegendView);
      registers.registerProcessor(registers.PRIORITY.PROCESSOR.SERIES_FILTER, legendFilter);
      registers.registerSubTypeDefaulter('legend', function () {
        return 'plain';
      });
      installLegendAction(registers);
    }

    var ScrollableLegendModel =
    /** @class */
    function (_super) {
      __extends(ScrollableLegendModel, _super);

      function ScrollableLegendModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = ScrollableLegendModel.type;
        return _this;
      }
      /**
       * @param {number} scrollDataIndex
       */


      ScrollableLegendModel.prototype.setScrollDataIndex = function (scrollDataIndex) {
        this.option.scrollDataIndex = scrollDataIndex;
      };

      ScrollableLegendModel.prototype.init = function (option, parentModel, ecModel) {
        var inputPositionParams = getLayoutParams(option);

        _super.prototype.init.call(this, option, parentModel, ecModel);

        mergeAndNormalizeLayoutParams$1(this, option, inputPositionParams);
      };
      /**
       * @override
       */


      ScrollableLegendModel.prototype.mergeOption = function (option, ecModel) {
        _super.prototype.mergeOption.call(this, option, ecModel);

        mergeAndNormalizeLayoutParams$1(this, this.option, option);
      };

      ScrollableLegendModel.type = 'legend.scroll';
      ScrollableLegendModel.defaultOption = inheritDefaultOption(LegendModel.defaultOption, {
        scrollDataIndex: 0,
        pageButtonItemGap: 5,
        pageButtonGap: null,
        pageButtonPosition: 'end',
        pageFormatter: '{current}/{total}',
        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,
        pageTextStyle: {
          color: '#333'
        },
        animationDurationUpdate: 800
      });
      return ScrollableLegendModel;
    }(LegendModel);

    function mergeAndNormalizeLayoutParams$1(legendModel, target, raw) {
      var orient = legendModel.getOrient();
      var ignoreSize = [1, 1];
      ignoreSize[orient.index] = 0;
      mergeLayoutParam(target, raw, {
        type: 'box',
        ignoreSize: !!ignoreSize
      });
    }

    var Group$3 = Group;
    var WH$1 = ['width', 'height'];
    var XY$1 = ['x', 'y'];

    var ScrollableLegendView =
    /** @class */
    function (_super) {
      __extends(ScrollableLegendView, _super);

      function ScrollableLegendView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = ScrollableLegendView.type;
        _this.newlineDisabled = true;
        _this._currentIndex = 0;
        return _this;
      }

      ScrollableLegendView.prototype.init = function () {
        _super.prototype.init.call(this);

        this.group.add(this._containerGroup = new Group$3());

        this._containerGroup.add(this.getContentGroup());

        this.group.add(this._controllerGroup = new Group$3());
      };
      /**
       * @override
       */


      ScrollableLegendView.prototype.resetInner = function () {
        _super.prototype.resetInner.call(this);

        this._controllerGroup.removeAll();

        this._containerGroup.removeClipPath();

        this._containerGroup.__rectSize = null;
      };
      /**
       * @override
       */


      ScrollableLegendView.prototype.renderInner = function (itemAlign, legendModel, ecModel, api, selector, orient, selectorPosition) {
        var self = this; // Render content items.

        _super.prototype.renderInner.call(this, 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);
        var pageIconSizeArr = isArray(pageIconSize) ? pageIconSize : [pageIconSize, pageIconSize];
        createPageButton('pagePrev', 0);
        var pageTextStyleModel = legendModel.getModel('pageTextStyle');
        controllerGroup.add(new ZRText({
          name: 'pageText',
          style: {
            // Placeholder to calculate a proper layout.
            text: 'xx/xx',
            fill: pageTextStyleModel.getTextColor(),
            font: pageTextStyleModel.getFont(),
            verticalAlign: 'middle',
            align: '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(self._pageGo, self, pageDataIndexName, legendModel, api)
          }, {
            x: -pageIconSizeArr[0] / 2,
            y: -pageIconSizeArr[1] / 2,
            width: pageIconSizeArr[0],
            height: pageIconSizeArr[1]
          });
          icon.name = name;
          controllerGroup.add(icon);
        }
      };
      /**
       * @override
       */


      ScrollableLegendView.prototype.layoutInner = function (legendModel, itemAlign, maxSize, isFirstRender, selector, selectorPosition) {
        var selectorGroup = this.getSelectorGroup();
        var orientIdx = legendModel.getOrient().index;
        var wh = WH$1[orientIdx];
        var xy = XY$1[orientIdx];
        var hw = WH$1[1 - orientIdx];
        var yx = XY$1[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, xy);

        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.x = selectorPos[0];
          selectorGroup.y = selectorPos[1];
          selectorGroup.markRedraw();
        }

        return mainRect;
      };

      ScrollableLegendView.prototype._layoutContentAndController = function (legendModel, isFirstRender, maxSize, orientIdx, wh, hw, yx, xy) {
        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]; // In case that the inner elements of contentGroup layout do not based on [0, 0]

        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[xy];
        } // 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.setPosition(contentPos);
        containerGroup.setPosition(containerPos);
        controllerGroup.setPosition(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, {
          x: pageInfo.contentPosition[0],
          y: pageInfo.contentPosition[1]
        }, // When switch from "show controller" to "not show controller", view should be
        // updated immediately without animation, otherwise causes weird effect.
        showController ? legendModel : null);

        this._updatePageInfoView(legendModel, pageInfo);

        return mainRect;
      };

      ScrollableLegendView.prototype._pageGo = function (to, legendModel, api) {
        var scrollDataIndex = this._getPageInfo(legendModel)[to];

        scrollDataIndex != null && api.dispatchAction({
          type: 'legendScroll',
          scrollDataIndex: scrollDataIndex,
          legendId: legendModel.id
        });
      };

      ScrollableLegendView.prototype._updatePageInfoView = function (legendModel, pageInfo) {
        var controllerGroup = this._controllerGroup;
        each(['pagePrev', 'pageNext'], function (name) {
          var key = name + 'DataIndex';
          var canJump = pageInfo[key] != 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 == null ? '' : current + '').replace('{total}', total == null ? '' : total + '') : pageFormatter({
          current: current,
          total: total
        }));
      };
      /**
       *  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.
       * }
       */


      ScrollableLegendView.prototype._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$1[orientIdx];
        var xy = XY$1[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.x, contentGroup.y],
          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[xy];
            return {
              s: start,
              e: start + itemRect[wh],
              i: el.__legendDataIndex
            };
          }
        }

        function intersect(itemInfo, winStart) {
          return itemInfo.e >= winStart && itemInfo.s <= winStart + containerRectSize;
        }
      };

      ScrollableLegendView.prototype._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;
      };

      ScrollableLegendView.type = 'legend.scroll';
      return ScrollableLegendView;
    }(LegendView);

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


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * 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 installScrollableLegendAction(registers) {
      /**
       * @event legendScroll
       * @type {Object}
       * @property {string} type 'legendScroll'
       * @property {string} scrollDataIndex
       */
      registers.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);
        });
      });
    }

    function install$I(registers) {
      use(install$H);
      registers.registerComponentModel(ScrollableLegendModel);
      registers.registerComponentView(ScrollableLegendView);
      installScrollableLegendAction(registers);
    }

    function install$J(registers) {
      use(install$H);
      use(install$I);
    }

    var InsideZoomModel =
    /** @class */
    function (_super) {
      __extends(InsideZoomModel, _super);

      function InsideZoomModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = InsideZoomModel.type;
        return _this;
      }

      InsideZoomModel.type = 'dataZoom.inside';
      InsideZoomModel.defaultOption = inheritDefaultOption(DataZoomModel.defaultOption, {
        disabled: false,
        zoomLock: false,
        zoomOnMouseWheel: true,
        moveOnMouseMove: true,
        moveOnMouseWheel: false,
        preventDefaultMouseMove: true
      });
      return InsideZoomModel;
    }(DataZoomModel);

    var inner$k = makeInner();
    function setViewInfoToCoordSysRecord(api, dataZoomModel, getRange) {
      inner$k(api).coordSysRecordMap.each(function (coordSysRecord) {
        var dzInfo = coordSysRecord.dataZoomInfoMap.get(dataZoomModel.uid);

        if (dzInfo) {
          dzInfo.getRange = getRange;
        }
      });
    }
    function disposeCoordSysRecordIfNeeded(api, dataZoomModel) {
      var coordSysRecordMap = inner$k(api).coordSysRecordMap;
      var coordSysKeyArr = coordSysRecordMap.keys();

      for (var i = 0; i < coordSysKeyArr.length; i++) {
        var coordSysKey = coordSysKeyArr[i];
        var coordSysRecord = coordSysRecordMap.get(coordSysKey);
        var dataZoomInfoMap = coordSysRecord.dataZoomInfoMap;

        if (dataZoomInfoMap) {
          var dzUid = dataZoomModel.uid;
          var dzInfo = dataZoomInfoMap.get(dzUid);

          if (dzInfo) {
            dataZoomInfoMap.removeKey(dzUid);

            if (!dataZoomInfoMap.keys().length) {
              disposeCoordSysRecord(coordSysRecordMap, coordSysRecord);
            }
          }
        }
      }
    }

    function disposeCoordSysRecord(coordSysRecordMap, coordSysRecord) {
      if (coordSysRecord) {
        coordSysRecordMap.removeKey(coordSysRecord.model.uid);
        var controller = coordSysRecord.controller;
        controller && controller.dispose();
      }
    }

    function createCoordSysRecord(api, coordSysModel) {
      // These init props will never change after record created.
      var coordSysRecord = {
        model: coordSysModel,
        containsPoint: curry(containsPoint, coordSysModel),
        dispatchAction: curry(dispatchAction$1, api),
        dataZoomInfoMap: null,
        controller: null
      }; // Must not do anything depends on coordSysRecord outside the event handler here,
      // because coordSysRecord not completed yet.

      var controller = coordSysRecord.controller = new RoamController(api.getZr());
      each(['pan', 'zoom', 'scrollMove'], function (eventName) {
        controller.on(eventName, function (event) {
          var batch = [];
          coordSysRecord.dataZoomInfoMap.each(function (dzInfo) {
            // Check whether the behaviors (zoomOnMouseWheel, moveOnMouseMove,
            // moveOnMouseWheel, ...) enabled.
            if (!event.isAvailableBehavior(dzInfo.model.option)) {
              return;
            }

            var method = (dzInfo.getRange || {})[eventName];
            var range = method && method(dzInfo.dzReferCoordSysInfo, coordSysRecord.model.mainType, coordSysRecord.controller, event);
            !dzInfo.model.get('disabled', true) && range && batch.push({
              dataZoomId: dzInfo.model.id,
              start: range[0],
              end: range[1]
            });
          });
          batch.length && coordSysRecord.dispatchAction(batch);
        });
      });
      return coordSysRecord;
    }
    /**
     * This action will be throttled.
     */


    function dispatchAction$1(api, batch) {
      if (!api.isDisposed()) {
        api.dispatchAction({
          type: 'dataZoom',
          animation: {
            easing: 'cubicOut',
            duration: 100
          },
          batch: batch
        });
      }
    }

    function containsPoint(coordSysModel, e, x, y) {
      return coordSysModel.coordinateSystem.containPoint([x, y]);
    }
    /**
     * Merge roamController settings when multiple dataZooms share one roamController.
     */


    function mergeControllerParams(dataZoomInfoMap) {
      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;
      dataZoomInfoMap.each(function (dataZoomInfo) {
        var dataZoomModel = dataZoomInfo.model;
        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 = 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
        }
      };
    }

    function installDataZoomRoamProcessor(registers) {
      registers.registerProcessor(registers.PRIORITY.PROCESSOR.FILTER, function (ecModel, api) {
        var apiInner = inner$k(api);
        var coordSysRecordMap = apiInner.coordSysRecordMap || (apiInner.coordSysRecordMap = createHashMap());
        coordSysRecordMap.each(function (coordSysRecord) {
          // `coordSysRecordMap` always exists (because it holds the `roam controller`, which should
          // better not re-create each time), but clear `dataZoomInfoMap` each round of the workflow.
          coordSysRecord.dataZoomInfoMap = null;
        });
        ecModel.eachComponent({
          mainType: 'dataZoom',
          subType: 'inside'
        }, function (dataZoomModel) {
          var dzReferCoordSysWrap = collectReferCoordSysModelInfo(dataZoomModel);
          each(dzReferCoordSysWrap.infoList, function (dzCoordSysInfo) {
            var coordSysUid = dzCoordSysInfo.model.uid;
            var coordSysRecord = coordSysRecordMap.get(coordSysUid) || coordSysRecordMap.set(coordSysUid, createCoordSysRecord(api, dzCoordSysInfo.model));
            var dataZoomInfoMap = coordSysRecord.dataZoomInfoMap || (coordSysRecord.dataZoomInfoMap = createHashMap()); // Notice these props might be changed each time for a single dataZoomModel.

            dataZoomInfoMap.set(dataZoomModel.uid, {
              dzReferCoordSysInfo: dzCoordSysInfo,
              model: dataZoomModel,
              getRange: null
            });
          });
        }); // (1) Merge dataZoom settings for each coord sys and set to the roam controller.
        // (2) Clear coord sys if not refered by any dataZoom.

        coordSysRecordMap.each(function (coordSysRecord) {
          var controller = coordSysRecord.controller;
          var firstDzInfo;
          var dataZoomInfoMap = coordSysRecord.dataZoomInfoMap;

          if (dataZoomInfoMap) {
            var firstDzKey = dataZoomInfoMap.keys()[0];

            if (firstDzKey != null) {
              firstDzInfo = dataZoomInfoMap.get(firstDzKey);
            }
          }

          if (!firstDzInfo) {
            disposeCoordSysRecord(coordSysRecordMap, coordSysRecord);
            return;
          }

          var controllerParams = mergeControllerParams(dataZoomInfoMap);
          controller.enable(controllerParams.controlType, controllerParams.opt);
          controller.setPointerChecker(coordSysRecord.containsPoint);
          createOrUpdate(coordSysRecord, 'dispatchAction', firstDzInfo.model.get('throttle', true), 'fixRate');
        });
      });
    }

    var InsideZoomView =
    /** @class */
    function (_super) {
      __extends(InsideZoomView, _super);

      function InsideZoomView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = 'dataZoom.inside';
        return _this;
      }

      InsideZoomView.prototype.render = function (dataZoomModel, ecModel, api) {
        _super.prototype.render.apply(this, arguments);

        if (dataZoomModel.noTarget()) {
          this._clear();

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

        setViewInfoToCoordSysRecord(api, dataZoomModel, {
          pan: bind(getRangeHandlers.pan, this),
          zoom: bind(getRangeHandlers.zoom, this),
          scrollMove: bind(getRangeHandlers.scrollMove, this)
        });
      };

      InsideZoomView.prototype.dispose = function () {
        this._clear();

        _super.prototype.dispose.apply(this, arguments);
      };

      InsideZoomView.prototype._clear = function () {
        disposeCoordSysRecordIfNeeded(this.api, this.dataZoomModel);
        this.range = null;
      };

      InsideZoomView.type = 'dataZoom.inside';
      return InsideZoomView;
    }(DataZoomView);

    var getRangeHandlers = {
      zoom: function (coordSysInfo, coordSysMainType, controller, e) {
        var lastRange = this.range;
        var range = lastRange.slice(); // Calculate transform by the first axis.

        var axisModel = coordSysInfo.axisModels[0];

        if (!axisModel) {
          return;
        }

        var directionInfo = getDirectionInfo[coordSysMainType](null, [e.originX, e.originY], axisModel, controller, coordSysInfo);
        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;
        }
      },
      pan: makeMover(function (range, axisModel, coordSysInfo, coordSysMainType, controller, e) {
        var directionInfo = getDirectionInfo[coordSysMainType]([e.oldX, e.oldY], [e.newX, e.newY], axisModel, controller, coordSysInfo);
        return directionInfo.signal * (range[1] - range[0]) * directionInfo.pixel / directionInfo.pixelLength;
      }),
      scrollMove: makeMover(function (range, axisModel, coordSysInfo, coordSysMainType, controller, e) {
        var directionInfo = getDirectionInfo[coordSysMainType]([0, 0], [e.scrollDelta, e.scrollDelta], axisModel, controller, coordSysInfo);
        return directionInfo.signal * (range[1] - range[0]) * e.scrollDelta;
      })
    };

    function makeMover(getPercentDelta) {
      return function (coordSysInfo, coordSysMainType, controller, e) {
        var lastRange = this.range;
        var range = lastRange.slice(); // Calculate transform by the first axis.

        var axisModel = coordSysInfo.axisModels[0];

        if (!axisModel) {
          return;
        }

        var percentDelta = getPercentDelta(range, axisModel, coordSysInfo, coordSysMainType, 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, coordSysInfo) {
        var axis = axisModel.axis;
        var ret = {};
        var rect = coordSysInfo.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, coordSysInfo) {
        var axis = axisModel.axis;
        var ret = {};
        var polar = coordSysInfo.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, coordSysInfo) {
        var axis = axisModel.axis;
        var rect = coordSysInfo.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;
      }
    };

    function install$K(registers) {
      installCommon(registers);
      registers.registerComponentModel(InsideZoomModel);
      registers.registerComponentView(InsideZoomView);
      installDataZoomRoamProcessor(registers);
    }

    var SliderZoomModel =
    /** @class */
    function (_super) {
      __extends(SliderZoomModel, _super);

      function SliderZoomModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = SliderZoomModel.type;
        return _this;
      }

      SliderZoomModel.type = 'dataZoom.slider';
      SliderZoomModel.layoutMode = 'box';
      SliderZoomModel.defaultOption = inheritDefaultOption(DataZoomModel.defaultOption, {
        show: true,
        // deault value can only be drived in view stage.
        right: 'ph',
        top: 'ph',
        width: 'ph',
        height: 'ph',
        left: null,
        bottom: null,
        borderColor: '#d2dbee',
        borderRadius: 3,
        backgroundColor: 'rgba(47,69,84,0)',
        // dataBackgroundColor: '#ddd',
        dataBackground: {
          lineStyle: {
            color: '#d2dbee',
            width: 0.5
          },
          areaStyle: {
            color: '#d2dbee',
            opacity: 0.2
          }
        },
        selectedDataBackground: {
          lineStyle: {
            color: '#8fb0f7',
            width: 0.5
          },
          areaStyle: {
            color: '#8fb0f7',
            opacity: 0.2
          }
        },
        // Color of selected window.
        fillerColor: 'rgba(135,175,274,0.2)',
        handleIcon: 'path://M-9.35,34.56V42m0-40V9.5m-2,0h4a2,2,0,0,1,2,2v21a2,2,0,0,1-2,2h-4a2,2,0,0,1-2-2v-21A2,2,0,0,1-11.35,9.5Z',
        // Percent of the slider height
        handleSize: '100%',
        handleStyle: {
          color: '#fff',
          borderColor: '#ACB8D1'
        },
        moveHandleSize: 7,
        moveHandleIcon: 'path://M-320.9-50L-320.9-50c18.1,0,27.1,9,27.1,27.1V85.7c0,18.1-9,27.1-27.1,27.1l0,0c-18.1,0-27.1-9-27.1-27.1V-22.9C-348-41-339-50-320.9-50z M-212.3-50L-212.3-50c18.1,0,27.1,9,27.1,27.1V85.7c0,18.1-9,27.1-27.1,27.1l0,0c-18.1,0-27.1-9-27.1-27.1V-22.9C-239.4-41-230.4-50-212.3-50z M-103.7-50L-103.7-50c18.1,0,27.1,9,27.1,27.1V85.7c0,18.1-9,27.1-27.1,27.1l0,0c-18.1,0-27.1-9-27.1-27.1V-22.9C-130.9-41-121.8-50-103.7-50z',
        moveHandleStyle: {
          color: '#D2DBEE',
          opacity: 0.7
        },
        showDetail: true,
        showDataShadow: 'auto',
        realtime: true,
        zoomLock: false,
        textStyle: {
          color: '#6E7079'
        },
        brushSelect: true,
        brushStyle: {
          color: 'rgba(135,175,274,0.15)'
        },
        emphasis: {
          handleStyle: {
            borderColor: '#8FB0F7'
          },
          moveHandleStyle: {
            color: '#8FB0F7'
          }
        }
      });
      return SliderZoomModel;
    }(DataZoomModel);

    var Rect$2 = Rect; // Constants

    var DEFAULT_LOCATION_EDGE_GAP = 7;
    var DEFAULT_FRAME_BORDER_WIDTH = 1;
    var DEFAULT_FILLER_SIZE = 30;
    var DEFAULT_MOVE_HANDLE_SIZE = 7;
    var HORIZONTAL = 'horizontal';
    var VERTICAL = 'vertical';
    var LABEL_GAP = 5;
    var SHOW_DATA_SHADOW_SERIES_TYPE = ['line', 'bar', 'candlestick', 'scatter'];
    var REALTIME_ANIMATION_CONFIG = {
      easing: 'cubicOut',
      duration: 100,
      delay: 0
    };

    var SliderZoomView =
    /** @class */
    function (_super) {
      __extends(SliderZoomView, _super);

      function SliderZoomView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = SliderZoomView.type;
        _this._displayables = {};
        return _this;
      }

      SliderZoomView.prototype.init = function (ecModel, api) {
        this.api = api; // A unique handler for each dataZoom component

        this._onBrush = bind(this._onBrush, this);
        this._onBrushEnd = bind(this._onBrushEnd, this);
      };

      SliderZoomView.prototype.render = function (dataZoomModel, ecModel, api, payload) {
        _super.prototype.render.apply(this, arguments);

        createOrUpdate(this, '_dispatchZoomAction', dataZoomModel.get('throttle'), 'fixRate');
        this._orient = dataZoomModel.getOrient();

        if (dataZoomModel.get('show') === false) {
          this.group.removeAll();
          return;
        }

        if (dataZoomModel.noTarget()) {
          this._clear();

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

      SliderZoomView.prototype.dispose = function () {
        this._clear();

        _super.prototype.dispose.apply(this, arguments);
      };

      SliderZoomView.prototype._clear = function () {
        clear(this, '_dispatchZoomAction');
        var zr = this.api.getZr();
        zr.off('mousemove', this._onBrush);
        zr.off('mouseup', this._onBrushEnd);
      };

      SliderZoomView.prototype._buildView = function () {
        var thisGroup = this.group;
        thisGroup.removeAll();
        this._brushing = false;
        this._displayables.brushRect = null;

        this._resetLocation();

        this._resetInterval();

        var barGroup = this._displayables.sliderGroup = new Group();

        this._renderBackground();

        this._renderHandle();

        this._renderDataShadow();

        thisGroup.add(barGroup);

        this._positionGroup();
      };

      SliderZoomView.prototype._resetLocation = function () {
        var dataZoomModel = this.dataZoomModel;
        var api = this.api;
        var showMoveHandle = dataZoomModel.get('brushSelect');
        var moveHandleSize = showMoveHandle ? DEFAULT_MOVE_HANDLE_SIZE : 0; // 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 - moveHandleSize,
          width: coordRect.width,
          height: DEFAULT_FILLER_SIZE
        } : {
          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(['right', 'top', 'width', 'height'], function (name) {
          if (layoutParams[name] === 'ph') {
            layoutParams[name] = positionInfo[name];
          }
        });
        var layoutRect = getLayoutRect(layoutParams, ecSize);
        this._location = {
          x: layoutRect.x,
          y: layoutRect.y
        };
        this._size = [layoutRect.width, layoutRect.height];
        this._orient === VERTICAL && this._size.reverse();
      };

      SliderZoomView.prototype._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 sliderGroup = this._displayables.sliderGroup;
        var otherAxisInverse = (this._dataShadowInfo || {}).otherAxisInverse; // Transform barGroup.

        sliderGroup.attr(orient === HORIZONTAL && !inverse ? {
          scaleY: otherAxisInverse ? 1 : -1,
          scaleX: 1
        } : orient === HORIZONTAL && inverse ? {
          scaleY: otherAxisInverse ? 1 : -1,
          scaleX: -1
        } : orient === VERTICAL && !inverse ? {
          scaleY: otherAxisInverse ? -1 : 1,
          scaleX: 1,
          rotation: Math.PI / 2
        } // Dont use Math.PI, considering shadow direction.
        : {
          scaleY: otherAxisInverse ? -1 : 1,
          scaleX: -1,
          rotation: Math.PI / 2
        }); // Position barGroup

        var rect = thisGroup.getBoundingRect([sliderGroup]);
        thisGroup.x = location.x - rect.x;
        thisGroup.y = location.y - rect.y;
        thisGroup.markRedraw();
      };

      SliderZoomView.prototype._getViewExtent = function () {
        return [0, this._size[0]];
      };

      SliderZoomView.prototype._renderBackground = function () {
        var dataZoomModel = this.dataZoomModel;
        var size = this._size;
        var barGroup = this._displayables.sliderGroup;
        var brushSelect = dataZoomModel.get('brushSelect');
        barGroup.add(new Rect$2({
          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.

        var clickPanel = new Rect$2({
          shape: {
            x: 0,
            y: 0,
            width: size[0],
            height: size[1]
          },
          style: {
            fill: 'transparent'
          },
          z2: 0,
          onclick: bind(this._onClickPanel, this)
        });
        var zr = this.api.getZr();

        if (brushSelect) {
          clickPanel.on('mousedown', this._onBrushStart, this);
          clickPanel.cursor = 'crosshair';
          zr.on('mousemove', this._onBrush);
          zr.on('mouseup', this._onBrushEnd);
        } else {
          zr.off('mousemove', this._onBrush);
          zr.off('mouseup', this._onBrushEnd);
        }

        barGroup.add(clickPanel);
      };

      SliderZoomView.prototype._renderDataShadow = function () {
        var info = this._dataShadowInfo = this._prepareDataShadowInfo();

        this._displayables.dataShadowSegs = [];

        if (!info) {
          return;
        }

        var size = this._size;
        var oldSize = this._shadowSize || [];
        var seriesModel = info.series;
        var data = seriesModel.getRawData();
        var candlestickDim = seriesModel.getShadowDim && seriesModel.getShadowDim();
        var otherDim = candlestickDim && data.getDimensionInfo(candlestickDim) ? seriesModel.getShadowDim() // @see candlestick
        : info.otherDim;

        if (otherDim == null) {
          return;
        }

        var polygonPts = this._shadowPolygonPts;
        var polylinePts = this._shadowPolylinePts; // Not re-render if data doesn't change.

        if (data !== this._shadowData || otherDim !== this._shadowDim || size[0] !== oldSize[0] || size[1] !== oldSize[1]) {
          var otherDataExtent_1 = data.getDataExtent(otherDim); // Nice extent.

          var otherOffset = (otherDataExtent_1[1] - otherDataExtent_1[0]) * 0.3;
          otherDataExtent_1 = [otherDataExtent_1[0] - otherOffset, otherDataExtent_1[1] + otherOffset];
          var otherShadowExtent_1 = [0, size[1]];
          var thisShadowExtent = [0, size[0]];
          var areaPoints_1 = [[size[0], 0], [0, 0]];
          var linePoints_1 = [];
          var step_1 = thisShadowExtent[1] / (data.count() - 1);
          var thisCoord_1 = 0; // Optimize for large data shadow

          var stride_1 = Math.round(data.count() / size[0]);
          var lastIsEmpty_1;
          data.each([otherDim], function (value, index) {
            if (stride_1 > 0 && index % stride_1) {
              thisCoord_1 += step_1;
              return;
            } // FIXME
            // Should consider axis.min/axis.max when drawing dataShadow.
            // FIXME
            // 应该使用统一的空判断？还是在list里进行空判断？


            var isEmpty = value == null || isNaN(value) || value === ''; // See #4235.

            var otherCoord = isEmpty ? 0 : linearMap(value, otherDataExtent_1, otherShadowExtent_1, true); // Attempt to draw data shadow precisely when there are empty value.

            if (isEmpty && !lastIsEmpty_1 && index) {
              areaPoints_1.push([areaPoints_1[areaPoints_1.length - 1][0], 0]);
              linePoints_1.push([linePoints_1[linePoints_1.length - 1][0], 0]);
            } else if (!isEmpty && lastIsEmpty_1) {
              areaPoints_1.push([thisCoord_1, 0]);
              linePoints_1.push([thisCoord_1, 0]);
            }

            areaPoints_1.push([thisCoord_1, otherCoord]);
            linePoints_1.push([thisCoord_1, otherCoord]);
            thisCoord_1 += step_1;
            lastIsEmpty_1 = isEmpty;
          });
          polygonPts = this._shadowPolygonPts = areaPoints_1;
          polylinePts = this._shadowPolylinePts = linePoints_1;
        }

        this._shadowData = data;
        this._shadowDim = otherDim;
        this._shadowSize = [size[0], size[1]];
        var dataZoomModel = this.dataZoomModel;

        function createDataShadowGroup(isSelectedArea) {
          var model = dataZoomModel.getModel(isSelectedArea ? 'selectedDataBackground' : 'dataBackground');
          var group = new Group();
          var polygon = new Polygon({
            shape: {
              points: polygonPts
            },
            segmentIgnoreThreshold: 1,
            style: model.getModel('areaStyle').getAreaStyle(),
            silent: true,
            z2: -20
          });
          var polyline = new Polyline({
            shape: {
              points: polylinePts
            },
            segmentIgnoreThreshold: 1,
            style: model.getModel('lineStyle').getLineStyle(),
            silent: true,
            z2: -19
          });
          group.add(polygon);
          group.add(polyline);
          return group;
        } // let dataBackgroundModel = dataZoomModel.getModel('dataBackground');


        for (var i = 0; i < 3; i++) {
          var group = createDataShadowGroup(i === 1);

          this._displayables.sliderGroup.add(group);

          this._displayables.dataShadowSegs.push(group);
        }
      };

      SliderZoomView.prototype._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 (axisDim, axisIndex) {
          var seriesModels = dataZoomModel.getAxisProxy(axisDim, axisIndex).getTargetSeriesModels();
          each(seriesModels, function (seriesModel) {
            if (result) {
              return;
            }

            if (showDataShadow !== true && indexOf(SHOW_DATA_SHADOW_SERIES_TYPE, seriesModel.get('type')) < 0) {
              return;
            }

            var thisAxis = ecModel.getComponent(getAxisMainType(axisDim), axisIndex).axis;
            var otherDim = getOtherDim(axisDim);
            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: axisDim,
              otherDim: otherDim,
              otherAxisInverse: otherAxisInverse
            };
          }, this);
        }, this);
        return result;
      };

      SliderZoomView.prototype._renderHandle = function () {
        var thisGroup = this.group;
        var displayables = this._displayables;
        var handles = displayables.handles = [null, null];
        var handleLabels = displayables.handleLabels = [null, null];
        var sliderGroup = this._displayables.sliderGroup;
        var size = this._size;
        var dataZoomModel = this.dataZoomModel;
        var api = this.api;
        var borderRadius = dataZoomModel.get('borderRadius') || 0;
        var brushSelect = dataZoomModel.get('brushSelect');
        var filler = displayables.filler = new Rect$2({
          silent: brushSelect,
          style: {
            fill: dataZoomModel.get('fillerColor')
          },
          textConfig: {
            position: 'inside'
          }
        });
        sliderGroup.add(filler); // Frame border.

        sliderGroup.add(new Rect$2({
          silent: true,
          subPixelOptimize: true,
          shape: {
            x: 0,
            y: 0,
            width: size[0],
            height: size[1],
            r: borderRadius
          },
          style: {
            // deprecated option
            stroke: dataZoomModel.get('dataBackgroundColor') || dataZoomModel.get('borderColor'),
            lineWidth: DEFAULT_FRAME_BORDER_WIDTH,
            fill: 'rgba(0,0,0,0)'
          }
        })); // Left and right handle to resize

        each([0, 1], function (handleIndex) {
          var iconStr = dataZoomModel.get('handleIcon');

          if (!symbolBuildProxies[iconStr] && iconStr.indexOf('path://') < 0 && iconStr.indexOf('image://') < 0) {
            // Compatitable with the old icon parsers. Which can use a path string without path://
            iconStr = 'path://' + iconStr;

            if ("development" !== 'production') {
              deprecateLog('handleIcon now needs \'path://\' prefix when using a path string');
            }
          }

          var path = createSymbol(iconStr, -1, 0, 2, 2, null, true);
          path.attr({
            cursor: getCursor(this._orient),
            draggable: true,
            drift: bind(this._onDragMove, this, handleIndex),
            ondragend: bind(this._onDragEnd, this),
            onmouseover: bind(this._showDataInfo, this, true),
            onmouseout: bind(this._showDataInfo, this, false),
            z2: 5
          });
          var bRect = path.getBoundingRect();
          var handleSize = dataZoomModel.get('handleSize');
          this._handleHeight = parsePercent$1(handleSize, this._size[1]);
          this._handleWidth = bRect.width / bRect.height * this._handleHeight;
          path.setStyle(dataZoomModel.getModel('handleStyle').getItemStyle());
          path.style.strokeNoScale = true;
          path.rectHover = true;
          path.ensureState('emphasis').style = dataZoomModel.getModel(['emphasis', 'handleStyle']).getItemStyle();
          enableHoverEmphasis(path);
          var handleColor = dataZoomModel.get('handleColor'); // deprecated option
          // Compatitable with previous version

          if (handleColor != null) {
            path.style.fill = handleColor;
          }

          sliderGroup.add(handles[handleIndex] = path);
          var textStyleModel = dataZoomModel.getModel('textStyle');
          thisGroup.add(handleLabels[handleIndex] = new ZRText({
            silent: true,
            invisible: true,
            style: createTextStyle(textStyleModel, {
              x: 0,
              y: 0,
              text: '',
              verticalAlign: 'middle',
              align: 'center',
              fill: textStyleModel.getTextColor(),
              font: textStyleModel.getFont()
            }),
            z2: 10
          }));
        }, this); // Handle to move. Only visible when brushSelect is set true.

        var actualMoveZone = filler;

        if (brushSelect) {
          var moveHandleHeight = parsePercent$1(dataZoomModel.get('moveHandleSize'), size[1]);
          var moveHandle_1 = displayables.moveHandle = new Rect({
            style: dataZoomModel.getModel('moveHandleStyle').getItemStyle(),
            silent: true,
            shape: {
              r: [0, 0, 2, 2],
              y: size[1] - 0.5,
              height: moveHandleHeight
            }
          });
          var iconSize = moveHandleHeight * 0.8;
          var moveHandleIcon = displayables.moveHandleIcon = createSymbol(dataZoomModel.get('moveHandleIcon'), -iconSize / 2, -iconSize / 2, iconSize, iconSize, '#fff', true);
          moveHandleIcon.silent = true;
          moveHandleIcon.y = size[1] + moveHandleHeight / 2 - 0.5;
          moveHandle_1.ensureState('emphasis').style = dataZoomModel.getModel(['emphasis', 'moveHandleStyle']).getItemStyle();
          var moveZoneExpandSize = Math.min(size[1] / 2, Math.max(moveHandleHeight, 10));
          actualMoveZone = displayables.moveZone = new Rect({
            invisible: true,
            shape: {
              y: size[1] - moveZoneExpandSize,
              height: moveHandleHeight + moveZoneExpandSize
            }
          });
          actualMoveZone.on('mouseover', function () {
            api.enterEmphasis(moveHandle_1);
          }).on('mouseout', function () {
            api.leaveEmphasis(moveHandle_1);
          });
          sliderGroup.add(moveHandle_1);
          sliderGroup.add(moveHandleIcon);
          sliderGroup.add(actualMoveZone);
        }

        actualMoveZone.attr({
          draggable: true,
          cursor: getCursor(this._orient),
          drift: bind(this._onDragMove, this, 'all'),
          ondragstart: bind(this._showDataInfo, this, true),
          ondragend: bind(this._onDragEnd, this),
          onmouseover: bind(this._showDataInfo, this, true),
          onmouseout: bind(this._showDataInfo, this, false)
        });
      };

      SliderZoomView.prototype._resetInterval = function () {
        var range = this._range = this.dataZoomModel.getPercentRange();

        var viewExtent = this._getViewExtent();

        this._handleEnds = [linearMap(range[0], [0, 100], viewExtent, true), linearMap(range[1], [0, 100], viewExtent, true)];
      };

      SliderZoomView.prototype._updateInterval = function (handleIndex, delta) {
        var dataZoomModel = this.dataZoomModel;
        var handleEnds = this._handleEnds;

        var viewExtend = this._getViewExtent();

        var minMaxSpan = dataZoomModel.findRepresentativeAxisProxy().getMinMaxSpan();
        var percentExtent = [0, 100];
        sliderMove(delta, handleEnds, viewExtend, dataZoomModel.get('zoomLock') ? 'all' : handleIndex, minMaxSpan.minSpan != null ? linearMap(minMaxSpan.minSpan, percentExtent, viewExtend, true) : null, minMaxSpan.maxSpan != null ? linearMap(minMaxSpan.maxSpan, percentExtent, viewExtend, true) : null);
        var lastRange = this._range;
        var range = this._range = asc([linearMap(handleEnds[0], viewExtend, percentExtent, true), linearMap(handleEnds[1], viewExtend, percentExtent, true)]);
        return !lastRange || lastRange[0] !== range[0] || lastRange[1] !== range[1];
      };

      SliderZoomView.prototype._updateView = function (nonRealtime) {
        var displaybles = this._displayables;
        var handleEnds = this._handleEnds;
        var handleInterval = asc(handleEnds.slice());
        var size = this._size;
        each([0, 1], function (handleIndex) {
          // Handles
          var handle = displaybles.handles[handleIndex];
          var handleHeight = this._handleHeight;
          handle.attr({
            scaleX: handleHeight / 2,
            scaleY: handleHeight / 2,
            // This is a trick, by adding an extra tiny offset to let the default handle's end point align to the drag window.
            // NOTE: It may affect some custom shapes a bit. But we prefer to have better result by default.
            x: handleEnds[handleIndex] + (handleIndex ? -1 : 1),
            y: size[1] / 2 - handleHeight / 2
          });
        }, this); // Filler

        displaybles.filler.setShape({
          x: handleInterval[0],
          y: 0,
          width: handleInterval[1] - handleInterval[0],
          height: size[1]
        });
        var viewExtent = {
          x: handleInterval[0],
          width: handleInterval[1] - handleInterval[0]
        }; // Move handle

        if (displaybles.moveHandle) {
          displaybles.moveHandle.setShape(viewExtent);
          displaybles.moveZone.setShape(viewExtent); // Force update path on the invisible object

          displaybles.moveZone.getBoundingRect();
          displaybles.moveHandleIcon && displaybles.moveHandleIcon.attr('x', viewExtent.x + viewExtent.width / 2);
        } // update clip path of shadow.


        var dataShadowSegs = displaybles.dataShadowSegs;
        var segIntervals = [0, handleInterval[0], handleInterval[1], size[0]];

        for (var i = 0; i < dataShadowSegs.length; i++) {
          var segGroup = dataShadowSegs[i];
          var clipPath = segGroup.getClipPath();

          if (!clipPath) {
            clipPath = new Rect();
            segGroup.setClipPath(clipPath);
          }

          clipPath.setShape({
            x: segIntervals[i],
            y: 0,
            width: segIntervals[i + 1] - segIntervals[i],
            height: size[1]
          });
        }

        this._updateDataInfo(nonRealtime);
      };

      SliderZoomView.prototype._updateDataInfo = function (nonRealtime) {
        var dataZoomModel = this.dataZoomModel;
        var displaybles = this._displayables;
        var handleLabels = displaybles.handleLabels;
        var orient = this._orient;
        var labelTexts = ['', '']; // FIXME
        // date型，支持formatter，autoformatter（ec2 date.getAutoFormatter）

        if (dataZoomModel.get('showDetail')) {
          var axisProxy = dataZoomModel.findRepresentativeAxisProxy();

          if (axisProxy) {
            var axis = axisProxy.getAxisModel().axis;
            var range = this._range;
            var dataInterval = nonRealtime // See #4434, data and axis are not processed and reset yet in non-realtime mode.
            ? axisProxy.calculateDataWindow({
              start: range[0],
              end: range[1]
            }).valueWindow : axisProxy.getDataValueWindow();
            labelTexts = [this._formatLabel(dataInterval[0], axis), this._formatLabel(dataInterval[1], axis)];
          }
        }

        var orderedHandleEnds = asc(this._handleEnds.slice());
        setLabel.call(this, 0);
        setLabel.call(this, 1);

        function setLabel(handleIndex) {
          // Label
          // Text should not transform by barGroup.
          // Ignore handlers transform
          var barTransform = 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],
            verticalAlign: orient === HORIZONTAL ? 'middle' : direction,
            align: orient === HORIZONTAL ? direction : 'center',
            text: labelTexts[handleIndex]
          });
        }
      };

      SliderZoomView.prototype._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({
          value: Math.round(value)
        }) // param of toFixed should less then 20.
        : value.toFixed(Math.min(labelPrecision, 20));
        return isFunction(labelFormatter) ? labelFormatter(value, valueStr) : isString(labelFormatter) ? labelFormatter.replace('{value}', valueStr) : valueStr;
      };
      /**
       * @param showOrHide true: show, false: hide
       */


      SliderZoomView.prototype._showDataInfo = function (showOrHide) {
        // Always show when drgging.
        showOrHide = this._dragging || showOrHide;
        var displayables = this._displayables;
        var handleLabels = displayables.handleLabels;
        handleLabels[0].attr('invisible', !showOrHide);
        handleLabels[1].attr('invisible', !showOrHide); // Highlight move handle

        displayables.moveHandle && this.api[showOrHide ? 'enterEmphasis' : 'leaveEmphasis'](displayables.moveHandle, 1);
      };

      SliderZoomView.prototype._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.sliderGroup.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(true);
      };

      SliderZoomView.prototype._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(false);
      };

      SliderZoomView.prototype._onClickPanel = function (e) {
        var size = this._size;

        var localPoint = this._displayables.sliderGroup.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(false);
      };

      SliderZoomView.prototype._onBrushStart = function (e) {
        var x = e.offsetX;
        var y = e.offsetY;
        this._brushStart = new Point(x, y);
        this._brushing = true;
        this._brushStartTime = +new Date(); // this._updateBrushRect(x, y);
      };

      SliderZoomView.prototype._onBrushEnd = function (e) {
        if (!this._brushing) {
          return;
        }

        var brushRect = this._displayables.brushRect;
        this._brushing = false;

        if (!brushRect) {
          return;
        }

        brushRect.attr('ignore', true);
        var brushShape = brushRect.shape;
        var brushEndTime = +new Date(); // console.log(brushEndTime - this._brushStartTime);

        if (brushEndTime - this._brushStartTime < 200 && Math.abs(brushShape.width) < 5) {
          // Will treat it as a click
          return;
        }

        var viewExtend = this._getViewExtent();

        var percentExtent = [0, 100];
        this._range = asc([linearMap(brushShape.x, viewExtend, percentExtent, true), linearMap(brushShape.x + brushShape.width, viewExtend, percentExtent, true)]);
        this._handleEnds = [brushShape.x, brushShape.x + brushShape.width];

        this._updateView();

        this._dispatchZoomAction(false);
      };

      SliderZoomView.prototype._onBrush = function (e) {
        if (this._brushing) {
          // For mobile device, prevent screen slider on the button.
          stop(e.event);

          this._updateBrushRect(e.offsetX, e.offsetY);
        }
      };

      SliderZoomView.prototype._updateBrushRect = function (mouseX, mouseY) {
        var displayables = this._displayables;
        var dataZoomModel = this.dataZoomModel;
        var brushRect = displayables.brushRect;

        if (!brushRect) {
          brushRect = displayables.brushRect = new Rect$2({
            silent: true,
            style: dataZoomModel.getModel('brushStyle').getItemStyle()
          });
          displayables.sliderGroup.add(brushRect);
        }

        brushRect.attr('ignore', false);
        var brushStart = this._brushStart;
        var sliderGroup = this._displayables.sliderGroup;
        var endPoint = sliderGroup.transformCoordToLocal(mouseX, mouseY);
        var startPoint = sliderGroup.transformCoordToLocal(brushStart.x, brushStart.y);
        var size = this._size;
        endPoint[0] = Math.max(Math.min(size[0], endPoint[0]), 0);
        brushRect.setShape({
          x: startPoint[0],
          y: 0,
          width: endPoint[0] - startPoint[0],
          height: size[1]
        });
      };
      /**
       * This action will be throttled.
       */


      SliderZoomView.prototype._dispatchZoomAction = function (realtime) {
        var range = this._range;
        this.api.dispatchAction({
          type: 'dataZoom',
          from: this.uid,
          dataZoomId: this.dataZoomModel.id,
          animation: realtime ? REALTIME_ANIMATION_CONFIG : null,
          start: range[0],
          end: range[1]
        });
      };

      SliderZoomView.prototype._findCoordRect = function () {
        // Find the grid coresponding to the first axis referred by dataZoom.
        var rect;
        var coordSysInfoList = collectReferCoordSysModelInfo(this.dataZoomModel).infoList;

        if (!rect && coordSysInfoList.length) {
          var coordSys = coordSysInfoList[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;
      };

      SliderZoomView.type = 'dataZoom.slider';
      return SliderZoomView;
    }(DataZoomView);

    function getOtherDim(thisDim) {
      // FIXME
      // 这个逻辑和getOtherAxis里一致，但是写在这里是否不好
      var map = {
        x: 'y',
        y: 'x',
        radius: 'angle',
        angle: 'radius'
      };
      return map[thisDim];
    }

    function getCursor(orient) {
      return orient === 'vertical' ? 'ns-resize' : 'ew-resize';
    }

    function install$L(registers) {
      registers.registerComponentModel(SliderZoomModel);
      registers.registerComponentView(SliderZoomView);
      installCommon(registers);
    }

    function install$M(registers) {
      use(install$K);
      use(install$L); // Do not install './dataZoomSelect',
      // since it only work for toolbox dataZoom.
    }

    var visualDefault = {
      /**
       * @public
       */
      get: function (visualType, key, isCategory) {
        var value = clone((defaultOption$1[visualType] || {})[key]);
        return isCategory ? isArray(value) ? value[value.length - 1] : value : value;
      }
    };
    var defaultOption$1 = {
      color: {
        active: ['#006edd', '#e0ffff'],
        inactive: ['rgba(0,0,0,0)']
      },
      colorHue: {
        active: [0, 360],
        inactive: [0, 0]
      },
      colorSaturation: {
        active: [0.3, 1],
        inactive: [0, 0]
      },
      colorLightness: {
        active: [0.9, 0.5],
        inactive: [0, 0]
      },
      colorAlpha: {
        active: [0.3, 1],
        inactive: [0, 0]
      },
      opacity: {
        active: [0.3, 1],
        inactive: [0, 0]
      },
      symbol: {
        active: ['circle', 'roundRect', 'diamond'],
        inactive: ['none']
      },
      symbolSize: {
        active: [10, 50],
        inactive: [0, 0]
      }
    };

    var mapVisual$1 = VisualMapping.mapVisual;
    var eachVisual = VisualMapping.eachVisual;
    var isArray$1 = isArray;
    var each$d = each;
    var asc$2 = asc;
    var linearMap$1 = linearMap;

    var VisualMapModel =
    /** @class */
    function (_super) {
      __extends(VisualMapModel, _super);

      function VisualMapModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = VisualMapModel.type;
        _this.stateList = ['inRange', 'outOfRange'];
        _this.replacableOptionKeys = ['inRange', 'outOfRange', 'target', 'controller', 'color'];
        _this.layoutMode = {
          type: 'box',
          ignoreSize: true
        };
        /**
         * [lowerBound, upperBound]
         */

        _this.dataBound = [-Infinity, Infinity];
        _this.targetVisuals = {};
        _this.controllerVisuals = {};
        return _this;
      }

      VisualMapModel.prototype.init = function (option, parentModel, ecModel) {
        this.mergeDefaultAndTheme(option, ecModel);
      };
      /**
       * @protected
       */


      VisualMapModel.prototype.optionUpdated = function (newOption, isInit) {
        var thisOption = this.option;
        !isInit && replaceVisualOption(thisOption, newOption, this.replacableOptionKeys);
        this.textStyleModel = this.getModel('textStyle');
        this.resetItemSize();
        this.completeVisualOption();
      };
      /**
       * @protected
       */


      VisualMapModel.prototype.resetVisual = function (supplementVisualOption) {
        var stateList = this.stateList;
        supplementVisualOption = bind(supplementVisualOption, this);
        this.controllerVisuals = createVisualMappings(this.option.controller, stateList, supplementVisualOption);
        this.targetVisuals = createVisualMappings(this.option.target, stateList, supplementVisualOption);
      };
      /**
       * @public
       */


      VisualMapModel.prototype.getItemSymbol = function () {
        return null;
      };
      /**
       * @protected
       * @return {Array.<number>} An array of series indices.
       */


      VisualMapModel.prototype.getTargetSeriesIndices = function () {
        var optionSeriesIndex = this.option.seriesIndex;
        var seriesIndices = [];

        if (optionSeriesIndex == null || optionSeriesIndex === 'all') {
          this.ecModel.eachSeries(function (seriesModel, index) {
            seriesIndices.push(index);
          });
        } else {
          seriesIndices = normalizeToArray(optionSeriesIndex);
        }

        return seriesIndices;
      };
      /**
       * @public
       */


      VisualMapModel.prototype.eachTargetSeries = function (callback, context) {
        each(this.getTargetSeriesIndices(), function (seriesIndex) {
          var seriesModel = this.ecModel.getSeriesByIndex(seriesIndex);

          if (seriesModel) {
            callback.call(context, seriesModel);
          }
        }, this);
      };
      /**
       * @pubilc
       */


      VisualMapModel.prototype.isTargetSeries = function (seriesModel) {
        var is = false;
        this.eachTargetSeries(function (model) {
          model === seriesModel && (is = true);
        });
        return is;
      };
      /**
       * @example
       * this.formatValueText(someVal); // format single numeric value to text.
       * this.formatValueText(someVal, true); // format single category value to text.
       * this.formatValueText([min, max]); // format numeric min-max to text.
       * this.formatValueText([this.dataBound[0], max]); // using data lower bound.
       * this.formatValueText([min, this.dataBound[1]]); // using data upper bound.
       *
       * @param value Real value, or this.dataBound[0 or 1].
       * @param isCategory Only available when value is number.
       * @param edgeSymbols Open-close symbol when value is interval.
       * @protected
       */


      VisualMapModel.prototype.formatValueText = function (value, isCategory, edgeSymbols) {
        var option = this.option;
        var precision = option.precision;
        var dataBound = this.dataBound;
        var formatter = option.formatter;
        var isMinMax;
        edgeSymbols = edgeSymbols || ['<', '>'];

        if (isArray(value)) {
          value = value.slice();
          isMinMax = true;
        }

        var textValue = isCategory ? value // Value is string when isCategory
        : isMinMax ? [toFixed(value[0]), toFixed(value[1])] : toFixed(value);

        if (isString(formatter)) {
          return formatter.replace('{value}', isMinMax ? textValue[0] : textValue).replace('{value2}', isMinMax ? textValue[1] : textValue);
        } else if (isFunction(formatter)) {
          return isMinMax ? formatter(value[0], value[1]) : formatter(value);
        }

        if (isMinMax) {
          if (value[0] === dataBound[0]) {
            return edgeSymbols[0] + ' ' + textValue[1];
          } else if (value[1] === dataBound[1]) {
            return edgeSymbols[1] + ' ' + textValue[0];
          } else {
            return textValue[0] + ' - ' + textValue[1];
          }
        } else {
          // Format single value (includes category case).
          return textValue;
        }

        function toFixed(val) {
          return val === dataBound[0] ? 'min' : val === dataBound[1] ? 'max' : (+val).toFixed(Math.min(precision, 20));
        }
      };
      /**
       * @protected
       */


      VisualMapModel.prototype.resetExtent = function () {
        var thisOption = this.option; // Can not calculate data extent by data here.
        // Because series and data may be modified in processing stage.
        // So we do not support the feature "auto min/max".

        var extent = asc$2([thisOption.min, thisOption.max]);
        this._dataExtent = extent;
      };
      /**
       * PENDING:
       * delete this method if no outer usage.
       *
       * Return  Concrete dimention. If return null/undefined, no dimension used.
       */
      // getDataDimension(data: SeriesData) {
      //     const optDim = this.option.dimension;
      //     if (optDim != null) {
      //         return data.getDimension(optDim);
      //     }
      //     const dimNames = data.dimensions;
      //     for (let i = dimNames.length - 1; i >= 0; i--) {
      //         const dimName = dimNames[i];
      //         const dimInfo = data.getDimensionInfo(dimName);
      //         if (!dimInfo.isCalculationCoord) {
      //             return dimName;
      //         }
      //     }
      // }


      VisualMapModel.prototype.getDataDimensionIndex = function (data) {
        var optDim = this.option.dimension;

        if (optDim != null) {
          return data.getDimensionIndex(optDim);
        }

        var dimNames = data.dimensions;

        for (var i = dimNames.length - 1; i >= 0; i--) {
          var dimName = dimNames[i];
          var dimInfo = data.getDimensionInfo(dimName);

          if (!dimInfo.isCalculationCoord) {
            return dimInfo.storeDimIndex;
          }
        }
      };

      VisualMapModel.prototype.getExtent = function () {
        return this._dataExtent.slice();
      };

      VisualMapModel.prototype.completeVisualOption = function () {
        var ecModel = this.ecModel;
        var thisOption = this.option;
        var base = {
          inRange: thisOption.inRange,
          outOfRange: thisOption.outOfRange
        };
        var target = thisOption.target || (thisOption.target = {});
        var controller = thisOption.controller || (thisOption.controller = {});
        merge(target, base); // Do not override

        merge(controller, base); // Do not override

        var isCategory = this.isCategory();
        completeSingle.call(this, target);
        completeSingle.call(this, controller);
        completeInactive.call(this, target, 'inRange', 'outOfRange'); // completeInactive.call(this, target, 'outOfRange', 'inRange');

        completeController.call(this, controller);

        function completeSingle(base) {
          // Compatible with ec2 dataRange.color.
          // The mapping order of dataRange.color is: [high value, ..., low value]
          // whereas inRange.color and outOfRange.color is [low value, ..., high value]
          // Notice: ec2 has no inverse.
          if (isArray$1(thisOption.color) // If there has been inRange: {symbol: ...}, adding color is a mistake.
          // So adding color only when no inRange defined.
          && !base.inRange) {
            base.inRange = {
              color: thisOption.color.slice().reverse()
            };
          } // Compatible with previous logic, always give a defautl color, otherwise
          // simple config with no inRange and outOfRange will not work.
          // Originally we use visualMap.color as the default color, but setOption at
          // the second time the default color will be erased. So we change to use
          // constant DEFAULT_COLOR.
          // If user do not want the default color, set inRange: {color: null}.


          base.inRange = base.inRange || {
            color: ecModel.get('gradientColor')
          };
        }

        function completeInactive(base, stateExist, stateAbsent) {
          var optExist = base[stateExist];
          var optAbsent = base[stateAbsent];

          if (optExist && !optAbsent) {
            optAbsent = base[stateAbsent] = {};
            each$d(optExist, function (visualData, visualType) {
              if (!VisualMapping.isValidType(visualType)) {
                return;
              }

              var defa = visualDefault.get(visualType, 'inactive', isCategory);

              if (defa != null) {
                optAbsent[visualType] = defa; // Compatibable with ec2:
                // Only inactive color to rgba(0,0,0,0) can not
                // make label transparent, so use opacity also.

                if (visualType === 'color' && !optAbsent.hasOwnProperty('opacity') && !optAbsent.hasOwnProperty('colorAlpha')) {
                  optAbsent.opacity = [0, 0];
                }
              }
            });
          }
        }

        function completeController(controller) {
          var symbolExists = (controller.inRange || {}).symbol || (controller.outOfRange || {}).symbol;
          var symbolSizeExists = (controller.inRange || {}).symbolSize || (controller.outOfRange || {}).symbolSize;
          var inactiveColor = this.get('inactiveColor');
          var itemSymbol = this.getItemSymbol();
          var defaultSymbol = itemSymbol || 'roundRect';
          each$d(this.stateList, function (state) {
            var itemSize = this.itemSize;
            var visuals = controller[state]; // Set inactive color for controller if no other color
            // attr (like colorAlpha) specified.

            if (!visuals) {
              visuals = controller[state] = {
                color: isCategory ? inactiveColor : [inactiveColor]
              };
            } // Consistent symbol and symbolSize if not specified.


            if (visuals.symbol == null) {
              visuals.symbol = symbolExists && clone(symbolExists) || (isCategory ? defaultSymbol : [defaultSymbol]);
            }

            if (visuals.symbolSize == null) {
              visuals.symbolSize = symbolSizeExists && clone(symbolSizeExists) || (isCategory ? itemSize[0] : [itemSize[0], itemSize[0]]);
            } // Filter none


            visuals.symbol = mapVisual$1(visuals.symbol, function (symbol) {
              return symbol === 'none' ? defaultSymbol : symbol;
            }); // Normalize symbolSize

            var symbolSize = visuals.symbolSize;

            if (symbolSize != null) {
              var max_1 = -Infinity; // symbolSize can be object when categories defined.

              eachVisual(symbolSize, function (value) {
                value > max_1 && (max_1 = value);
              });
              visuals.symbolSize = mapVisual$1(symbolSize, function (value) {
                return linearMap$1(value, [0, max_1], [0, itemSize[0]], true);
              });
            }
          }, this);
        }
      };

      VisualMapModel.prototype.resetItemSize = function () {
        this.itemSize = [parseFloat(this.get('itemWidth')), parseFloat(this.get('itemHeight'))];
      };

      VisualMapModel.prototype.isCategory = function () {
        return !!this.option.categories;
      };
      /**
       * @public
       * @abstract
       */


      VisualMapModel.prototype.setSelected = function (selected) {};

      VisualMapModel.prototype.getSelected = function () {
        return null;
      };
      /**
       * @public
       * @abstract
       */


      VisualMapModel.prototype.getValueState = function (value) {
        return null;
      };
      /**
       * FIXME
       * Do not publish to thirt-part-dev temporarily
       * util the interface is stable. (Should it return
       * a function but not visual meta?)
       *
       * @pubilc
       * @abstract
       * @param getColorVisual
       *        params: value, valueState
       *        return: color
       * @return {Object} visualMeta
       *        should includes {stops, outerColors}
       *        outerColor means [colorBeyondMinValue, colorBeyondMaxValue]
       */


      VisualMapModel.prototype.getVisualMeta = function (getColorVisual) {
        return null;
      };

      VisualMapModel.type = 'visualMap';
      VisualMapModel.dependencies = ['series'];
      VisualMapModel.defaultOption = {
        show: true,
        // zlevel: 0,
        z: 4,
        seriesIndex: 'all',
        min: 0,
        max: 200,
        left: 0,
        right: null,
        top: null,
        bottom: 0,
        itemWidth: null,
        itemHeight: null,
        inverse: false,
        orient: 'vertical',
        backgroundColor: 'rgba(0,0,0,0)',
        borderColor: '#ccc',
        contentColor: '#5793f3',
        inactiveColor: '#aaa',
        borderWidth: 0,
        padding: 5,
        // 接受数组分别设定上右下左边距，同css
        textGap: 10,
        precision: 0,
        textStyle: {
          color: '#333' // 值域文字颜色

        }
      };
      return VisualMapModel;
    }(ComponentModel);

    var DEFAULT_BAR_BOUND = [20, 140];

    var ContinuousModel =
    /** @class */
    function (_super) {
      __extends(ContinuousModel, _super);

      function ContinuousModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = ContinuousModel.type;
        return _this;
      }
      /**
       * @override
       */


      ContinuousModel.prototype.optionUpdated = function (newOption, isInit) {
        _super.prototype.optionUpdated.apply(this, arguments);

        this.resetExtent();
        this.resetVisual(function (mappingOption) {
          mappingOption.mappingMethod = 'linear';
          mappingOption.dataExtent = this.getExtent();
        });

        this._resetRange();
      };
      /**
       * @protected
       * @override
       */


      ContinuousModel.prototype.resetItemSize = function () {
        _super.prototype.resetItemSize.apply(this, arguments);

        var itemSize = this.itemSize;
        (itemSize[0] == null || isNaN(itemSize[0])) && (itemSize[0] = DEFAULT_BAR_BOUND[0]);
        (itemSize[1] == null || isNaN(itemSize[1])) && (itemSize[1] = DEFAULT_BAR_BOUND[1]);
      };
      /**
       * @private
       */


      ContinuousModel.prototype._resetRange = function () {
        var dataExtent = this.getExtent();
        var range = this.option.range;

        if (!range || range.auto) {
          // `range` should always be array (so we dont use other
          // value like 'auto') for user-friend. (consider getOption).
          dataExtent.auto = 1;
          this.option.range = dataExtent;
        } else if (isArray(range)) {
          if (range[0] > range[1]) {
            range.reverse();
          }

          range[0] = Math.max(range[0], dataExtent[0]);
          range[1] = Math.min(range[1], dataExtent[1]);
        }
      };
      /**
       * @protected
       * @override
       */


      ContinuousModel.prototype.completeVisualOption = function () {
        _super.prototype.completeVisualOption.apply(this, arguments);

        each(this.stateList, function (state) {
          var symbolSize = this.option.controller[state].symbolSize;

          if (symbolSize && symbolSize[0] !== symbolSize[1]) {
            symbolSize[0] = symbolSize[1] / 3; // For good looking.
          }
        }, this);
      };
      /**
       * @override
       */


      ContinuousModel.prototype.setSelected = function (selected) {
        this.option.range = selected.slice();

        this._resetRange();
      };
      /**
       * @public
       */


      ContinuousModel.prototype.getSelected = function () {
        var dataExtent = this.getExtent();
        var dataInterval = asc((this.get('range') || []).slice()); // Clamp

        dataInterval[0] > dataExtent[1] && (dataInterval[0] = dataExtent[1]);
        dataInterval[1] > dataExtent[1] && (dataInterval[1] = dataExtent[1]);
        dataInterval[0] < dataExtent[0] && (dataInterval[0] = dataExtent[0]);
        dataInterval[1] < dataExtent[0] && (dataInterval[1] = dataExtent[0]);
        return dataInterval;
      };
      /**
       * @override
       */


      ContinuousModel.prototype.getValueState = function (value) {
        var range = this.option.range;
        var dataExtent = this.getExtent(); // When range[0] === dataExtent[0], any value larger than dataExtent[0] maps to 'inRange'.
        // range[1] is processed likewise.

        return (range[0] <= dataExtent[0] || range[0] <= value) && (range[1] >= dataExtent[1] || value <= range[1]) ? 'inRange' : 'outOfRange';
      };

      ContinuousModel.prototype.findTargetDataIndices = function (range) {
        var result = [];
        this.eachTargetSeries(function (seriesModel) {
          var dataIndices = [];
          var data = seriesModel.getData();
          data.each(this.getDataDimensionIndex(data), function (value, dataIndex) {
            range[0] <= value && value <= range[1] && dataIndices.push(dataIndex);
          }, this);
          result.push({
            seriesId: seriesModel.id,
            dataIndex: dataIndices
          });
        }, this);
        return result;
      };
      /**
       * @implement
       */


      ContinuousModel.prototype.getVisualMeta = function (getColorVisual) {
        var oVals = getColorStopValues(this, 'outOfRange', this.getExtent());
        var iVals = getColorStopValues(this, 'inRange', this.option.range.slice());
        var stops = [];

        function setStop(value, valueState) {
          stops.push({
            value: value,
            color: getColorVisual(value, valueState)
          });
        } // Format to: outOfRange -- inRange -- outOfRange.


        var iIdx = 0;
        var oIdx = 0;
        var iLen = iVals.length;
        var oLen = oVals.length;

        for (; oIdx < oLen && (!iVals.length || oVals[oIdx] <= iVals[0]); oIdx++) {
          // If oVal[oIdx] === iVals[iIdx], oVal[oIdx] should be ignored.
          if (oVals[oIdx] < iVals[iIdx]) {
            setStop(oVals[oIdx], 'outOfRange');
          }
        }

        for (var first = 1; iIdx < iLen; iIdx++, first = 0) {
          // If range is full, value beyond min, max will be clamped.
          // make a singularity
          first && stops.length && setStop(iVals[iIdx], 'outOfRange');
          setStop(iVals[iIdx], 'inRange');
        }

        for (var first = 1; oIdx < oLen; oIdx++) {
          if (!iVals.length || iVals[iVals.length - 1] < oVals[oIdx]) {
            // make a singularity
            if (first) {
              stops.length && setStop(stops[stops.length - 1].value, 'outOfRange');
              first = 0;
            }

            setStop(oVals[oIdx], 'outOfRange');
          }
        }

        var stopsLen = stops.length;
        return {
          stops: stops,
          outerColors: [stopsLen ? stops[0].color : 'transparent', stopsLen ? stops[stopsLen - 1].color : 'transparent']
        };
      };

      ContinuousModel.type = 'visualMap.continuous';
      ContinuousModel.defaultOption = inheritDefaultOption(VisualMapModel.defaultOption, {
        align: 'auto',
        calculable: false,
        hoverLink: true,
        realtime: true,
        handleIcon: 'path://M-11.39,9.77h0a3.5,3.5,0,0,1-3.5,3.5h-22a3.5,3.5,0,0,1-3.5-3.5h0a3.5,3.5,0,0,1,3.5-3.5h22A3.5,3.5,0,0,1-11.39,9.77Z',
        handleSize: '120%',
        handleStyle: {
          borderColor: '#fff',
          borderWidth: 1
        },
        indicatorIcon: 'circle',
        indicatorSize: '50%',
        indicatorStyle: {
          borderColor: '#fff',
          borderWidth: 2,
          shadowBlur: 2,
          shadowOffsetX: 1,
          shadowOffsetY: 1,
          shadowColor: 'rgba(0,0,0,0.2)'
        } // emphasis: {
        //     handleStyle: {
        //         shadowBlur: 3,
        //         shadowOffsetX: 1,
        //         shadowOffsetY: 1,
        //         shadowColor: 'rgba(0,0,0,0.2)'
        //     }
        // }

      });
      return ContinuousModel;
    }(VisualMapModel);

    function getColorStopValues(visualMapModel, valueState, dataExtent) {
      if (dataExtent[0] === dataExtent[1]) {
        return dataExtent.slice();
      } // When using colorHue mapping, it is not linear color any more.
      // Moreover, canvas gradient seems not to be accurate linear.
      // FIXME
      // Should be arbitrary value 100? or based on pixel size?


      var count = 200;
      var step = (dataExtent[1] - dataExtent[0]) / count;
      var value = dataExtent[0];
      var stopValues = [];

      for (var i = 0; i <= count && value < dataExtent[1]; i++) {
        stopValues.push(value);
        value += step;
      }

      stopValues.push(dataExtent[1]);
      return stopValues;
    }

    var VisualMapView =
    /** @class */
    function (_super) {
      __extends(VisualMapView, _super);

      function VisualMapView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = VisualMapView.type;
        _this.autoPositionValues = {
          left: 1,
          right: 1,
          top: 1,
          bottom: 1
        };
        return _this;
      }

      VisualMapView.prototype.init = function (ecModel, api) {
        this.ecModel = ecModel;
        this.api = api;
      };
      /**
       * @protected
       */


      VisualMapView.prototype.render = function (visualMapModel, ecModel, api, payload // TODO: TYPE
      ) {
        this.visualMapModel = visualMapModel;

        if (visualMapModel.get('show') === false) {
          this.group.removeAll();
          return;
        }

        this.doRender(visualMapModel, ecModel, api, payload);
      };
      /**
       * @protected
       */


      VisualMapView.prototype.renderBackground = function (group) {
        var visualMapModel = this.visualMapModel;
        var padding = normalizeCssArray$1(visualMapModel.get('padding') || 0);
        var rect = group.getBoundingRect();
        group.add(new Rect({
          z2: -1,
          silent: true,
          shape: {
            x: rect.x - padding[3],
            y: rect.y - padding[0],
            width: rect.width + padding[3] + padding[1],
            height: rect.height + padding[0] + padding[2]
          },
          style: {
            fill: visualMapModel.get('backgroundColor'),
            stroke: visualMapModel.get('borderColor'),
            lineWidth: visualMapModel.get('borderWidth')
          }
        }));
      };
      /**
       * @protected
       * @param targetValue can be Infinity or -Infinity
       * @param visualCluster Only can be 'color' 'opacity' 'symbol' 'symbolSize'
       * @param opts
       * @param opts.forceState Specify state, instead of using getValueState method.
       * @param opts.convertOpacityToAlpha For color gradient in controller widget.
       * @return {*} Visual value.
       */


      VisualMapView.prototype.getControllerVisual = function (targetValue, visualCluster, opts) {
        opts = opts || {};
        var forceState = opts.forceState;
        var visualMapModel = this.visualMapModel;
        var visualObj = {}; // Default values.

        if (visualCluster === 'color') {
          var defaultColor = visualMapModel.get('contentColor');
          visualObj.color = defaultColor;
        }

        function getter(key) {
          return visualObj[key];
        }

        function setter(key, value) {
          visualObj[key] = value;
        }

        var mappings = visualMapModel.controllerVisuals[forceState || visualMapModel.getValueState(targetValue)];
        var visualTypes = VisualMapping.prepareVisualTypes(mappings);
        each(visualTypes, function (type) {
          var visualMapping = mappings[type];

          if (opts.convertOpacityToAlpha && type === 'opacity') {
            type = 'colorAlpha';
            visualMapping = mappings.__alphaForOpacity;
          }

          if (VisualMapping.dependsOn(type, visualCluster)) {
            visualMapping && visualMapping.applyVisual(targetValue, getter, setter);
          }
        });
        return visualObj[visualCluster];
      };

      VisualMapView.prototype.positionGroup = function (group) {
        var model = this.visualMapModel;
        var api = this.api;
        positionElement(group, model.getBoxLayoutParams(), {
          width: api.getWidth(),
          height: api.getHeight()
        });
      };

      VisualMapView.prototype.doRender = function (visualMapModel, ecModel, api, payload) {};

      VisualMapView.type = 'visualMap';
      return VisualMapView;
    }(ComponentView);

    var paramsSet = [['left', 'right', 'width'], ['top', 'bottom', 'height']];
    /**
     * @param visualMapModel
     * @param api
     * @param itemSize always [short, long]
     * @return {string} 'left' or 'right' or 'top' or 'bottom'
     */

    function getItemAlign(visualMapModel, api, itemSize) {
      var modelOption = visualMapModel.option;
      var itemAlign = modelOption.align;

      if (itemAlign != null && itemAlign !== 'auto') {
        return itemAlign;
      } // Auto decision align.


      var ecSize = {
        width: api.getWidth(),
        height: api.getHeight()
      };
      var realIndex = modelOption.orient === 'horizontal' ? 1 : 0;
      var reals = paramsSet[realIndex];
      var fakeValue = [0, null, 10];
      var layoutInput = {};

      for (var i = 0; i < 3; i++) {
        layoutInput[paramsSet[1 - realIndex][i]] = fakeValue[i];
        layoutInput[reals[i]] = i === 2 ? itemSize[0] : modelOption[reals[i]];
      }

      var rParam = [['x', 'width', 3], ['y', 'height', 0]][realIndex];
      var rect = getLayoutRect(layoutInput, ecSize, modelOption.padding);
      return reals[(rect.margin[rParam[2]] || 0) + rect[rParam[0]] + rect[rParam[1]] * 0.5 < ecSize[rParam[1]] * 0.5 ? 0 : 1];
    }
    /**
     * Prepare dataIndex for outside usage, where dataIndex means rawIndex, and
     * dataIndexInside means filtered index.
     */
    // TODO: TYPE more specified payload types.

    function makeHighDownBatch(batch, visualMapModel) {
      each(batch || [], function (batchItem) {
        if (batchItem.dataIndex != null) {
          batchItem.dataIndexInside = batchItem.dataIndex;
          batchItem.dataIndex = null;
        }

        batchItem.highlightKey = 'visualMap' + (visualMapModel ? visualMapModel.componentIndex : '');
      });
      return batch;
    }

    var linearMap$2 = linearMap;
    var each$e = each;
    var mathMin$a = Math.min;
    var mathMax$a = Math.max; // Arbitrary value

    var HOVER_LINK_SIZE = 12;
    var HOVER_LINK_OUT = 6; // Notice:
    // Any "interval" should be by the order of [low, high].
    // "handle0" (handleIndex === 0) maps to
    // low data value: this._dataInterval[0] and has low coord.
    // "handle1" (handleIndex === 1) maps to
    // high data value: this._dataInterval[1] and has high coord.
    // The logic of transform is implemented in this._createBarGroup.

    var ContinuousView =
    /** @class */
    function (_super) {
      __extends(ContinuousView, _super);

      function ContinuousView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = ContinuousView.type;
        _this._shapes = {};
        _this._dataInterval = [];
        _this._handleEnds = [];
        _this._hoverLinkDataIndices = [];
        return _this;
      }

      ContinuousView.prototype.doRender = function (visualMapModel, ecModel, api, payload) {
        this._api = api;

        if (!payload || payload.type !== 'selectDataRange' || payload.from !== this.uid) {
          this._buildView();
        }
      };

      ContinuousView.prototype._buildView = function () {
        this.group.removeAll();
        var visualMapModel = this.visualMapModel;
        var thisGroup = this.group;
        this._orient = visualMapModel.get('orient');
        this._useHandle = visualMapModel.get('calculable');

        this._resetInterval();

        this._renderBar(thisGroup);

        var dataRangeText = visualMapModel.get('text');

        this._renderEndsText(thisGroup, dataRangeText, 0);

        this._renderEndsText(thisGroup, dataRangeText, 1); // Do this for background size calculation.


        this._updateView(true); // After updating view, inner shapes is built completely,
        // and then background can be rendered.


        this.renderBackground(thisGroup); // Real update view

        this._updateView();

        this._enableHoverLinkToSeries();

        this._enableHoverLinkFromSeries();

        this.positionGroup(thisGroup);
      };

      ContinuousView.prototype._renderEndsText = function (group, dataRangeText, endsIndex) {
        if (!dataRangeText) {
          return;
        } // Compatible with ec2, text[0] map to high value, text[1] map low value.


        var text = dataRangeText[1 - endsIndex];
        text = text != null ? text + '' : '';
        var visualMapModel = this.visualMapModel;
        var textGap = visualMapModel.get('textGap');
        var itemSize = visualMapModel.itemSize;
        var barGroup = this._shapes.mainGroup;

        var position = this._applyTransform([itemSize[0] / 2, endsIndex === 0 ? -textGap : itemSize[1] + textGap], barGroup);

        var align = this._applyTransform(endsIndex === 0 ? 'bottom' : 'top', barGroup);

        var orient = this._orient;
        var textStyleModel = this.visualMapModel.textStyleModel;
        this.group.add(new ZRText({
          style: createTextStyle(textStyleModel, {
            x: position[0],
            y: position[1],
            verticalAlign: orient === 'horizontal' ? 'middle' : align,
            align: orient === 'horizontal' ? align : 'center',
            text: text
          })
        }));
      };

      ContinuousView.prototype._renderBar = function (targetGroup) {
        var visualMapModel = this.visualMapModel;
        var shapes = this._shapes;
        var itemSize = visualMapModel.itemSize;
        var orient = this._orient;
        var useHandle = this._useHandle;
        var itemAlign = getItemAlign(visualMapModel, this.api, itemSize);

        var mainGroup = shapes.mainGroup = this._createBarGroup(itemAlign);

        var gradientBarGroup = new Group();
        mainGroup.add(gradientBarGroup); // Bar

        gradientBarGroup.add(shapes.outOfRange = createPolygon());
        gradientBarGroup.add(shapes.inRange = createPolygon(null, useHandle ? getCursor$1(this._orient) : null, bind(this._dragHandle, this, 'all', false), bind(this._dragHandle, this, 'all', true))); // A border radius clip.

        gradientBarGroup.setClipPath(new Rect({
          shape: {
            x: 0,
            y: 0,
            width: itemSize[0],
            height: itemSize[1],
            r: 3
          }
        }));
        var textRect = visualMapModel.textStyleModel.getTextRect('国');
        var textSize = mathMax$a(textRect.width, textRect.height); // Handle

        if (useHandle) {
          shapes.handleThumbs = [];
          shapes.handleLabels = [];
          shapes.handleLabelPoints = [];

          this._createHandle(visualMapModel, mainGroup, 0, itemSize, textSize, orient);

          this._createHandle(visualMapModel, mainGroup, 1, itemSize, textSize, orient);
        }

        this._createIndicator(visualMapModel, mainGroup, itemSize, textSize, orient);

        targetGroup.add(mainGroup);
      };

      ContinuousView.prototype._createHandle = function (visualMapModel, mainGroup, handleIndex, itemSize, textSize, orient) {
        var onDrift = bind(this._dragHandle, this, handleIndex, false);
        var onDragEnd = bind(this._dragHandle, this, handleIndex, true);
        var handleSize = parsePercent(visualMapModel.get('handleSize'), itemSize[0]);
        var handleThumb = createSymbol(visualMapModel.get('handleIcon'), -handleSize / 2, -handleSize / 2, handleSize, handleSize, null, true);
        var cursor = getCursor$1(this._orient);
        handleThumb.attr({
          cursor: cursor,
          draggable: true,
          drift: onDrift,
          ondragend: onDragEnd,
          onmousemove: function (e) {
            stop(e.event);
          }
        });
        handleThumb.x = itemSize[0] / 2;
        handleThumb.useStyle(visualMapModel.getModel('handleStyle').getItemStyle());
        handleThumb.setStyle({
          strokeNoScale: true,
          strokeFirst: true
        });
        handleThumb.style.lineWidth *= 2;
        handleThumb.ensureState('emphasis').style = visualMapModel.getModel(['emphasis', 'handleStyle']).getItemStyle();
        setAsHighDownDispatcher(handleThumb, true);
        mainGroup.add(handleThumb); // Text is always horizontal layout but should not be effected by
        // transform (orient/inverse). So label is built separately but not
        // use zrender/graphic/helper/RectText, and is located based on view
        // group (according to handleLabelPoint) but not barGroup.

        var textStyleModel = this.visualMapModel.textStyleModel;
        var handleLabel = new ZRText({
          cursor: cursor,
          draggable: true,
          drift: onDrift,
          onmousemove: function (e) {
            // Fot mobile devicem, prevent screen slider on the button.
            stop(e.event);
          },
          ondragend: onDragEnd,
          style: createTextStyle(textStyleModel, {
            x: 0,
            y: 0,
            text: ''
          })
        });
        handleLabel.ensureState('blur').style = {
          opacity: 0.1
        };
        handleLabel.stateTransition = {
          duration: 200
        };
        this.group.add(handleLabel);
        var handleLabelPoint = [handleSize, 0];
        var shapes = this._shapes;
        shapes.handleThumbs[handleIndex] = handleThumb;
        shapes.handleLabelPoints[handleIndex] = handleLabelPoint;
        shapes.handleLabels[handleIndex] = handleLabel;
      };

      ContinuousView.prototype._createIndicator = function (visualMapModel, mainGroup, itemSize, textSize, orient) {
        var scale = parsePercent(visualMapModel.get('indicatorSize'), itemSize[0]);
        var indicator = createSymbol(visualMapModel.get('indicatorIcon'), -scale / 2, -scale / 2, scale, scale, null, true);
        indicator.attr({
          cursor: 'move',
          invisible: true,
          silent: true,
          x: itemSize[0] / 2
        });
        var indicatorStyle = visualMapModel.getModel('indicatorStyle').getItemStyle();

        if (indicator instanceof ZRImage) {
          var pathStyle = indicator.style;
          indicator.useStyle(extend({
            // TODO other properties like x, y ?
            image: pathStyle.image,
            x: pathStyle.x,
            y: pathStyle.y,
            width: pathStyle.width,
            height: pathStyle.height
          }, indicatorStyle));
        } else {
          indicator.useStyle(indicatorStyle);
        }

        mainGroup.add(indicator);
        var textStyleModel = this.visualMapModel.textStyleModel;
        var indicatorLabel = new ZRText({
          silent: true,
          invisible: true,
          style: createTextStyle(textStyleModel, {
            x: 0,
            y: 0,
            text: ''
          })
        });
        this.group.add(indicatorLabel);
        var indicatorLabelPoint = [(orient === 'horizontal' ? textSize / 2 : HOVER_LINK_OUT) + itemSize[0] / 2, 0];
        var shapes = this._shapes;
        shapes.indicator = indicator;
        shapes.indicatorLabel = indicatorLabel;
        shapes.indicatorLabelPoint = indicatorLabelPoint;
        this._firstShowIndicator = true;
      };

      ContinuousView.prototype._dragHandle = function (handleIndex, isEnd, // dx is event from ondragend if isEnd is true. It's not used
      dx, dy) {
        if (!this._useHandle) {
          return;
        }

        this._dragging = !isEnd;

        if (!isEnd) {
          // Transform dx, dy to bar coordination.
          var vertex = this._applyTransform([dx, dy], this._shapes.mainGroup, true);

          this._updateInterval(handleIndex, vertex[1]);

          this._hideIndicator(); // Considering realtime, update view should be executed
          // before dispatch action.


          this._updateView();
        } // dragEnd do not dispatch action when realtime.


        if (isEnd === !this.visualMapModel.get('realtime')) {
          // jshint ignore:line
          this.api.dispatchAction({
            type: 'selectDataRange',
            from: this.uid,
            visualMapId: this.visualMapModel.id,
            selected: this._dataInterval.slice()
          });
        }

        if (isEnd) {
          !this._hovering && this._clearHoverLinkToSeries();
        } else if (useHoverLinkOnHandle(this.visualMapModel)) {
          this._doHoverLinkToSeries(this._handleEnds[handleIndex], false);
        }
      };

      ContinuousView.prototype._resetInterval = function () {
        var visualMapModel = this.visualMapModel;
        var dataInterval = this._dataInterval = visualMapModel.getSelected();
        var dataExtent = visualMapModel.getExtent();
        var sizeExtent = [0, visualMapModel.itemSize[1]];
        this._handleEnds = [linearMap$2(dataInterval[0], dataExtent, sizeExtent, true), linearMap$2(dataInterval[1], dataExtent, sizeExtent, true)];
      };
      /**
       * @private
       * @param {(number|string)} handleIndex 0 or 1 or 'all'
       * @param {number} dx
       * @param {number} dy
       */


      ContinuousView.prototype._updateInterval = function (handleIndex, delta) {
        delta = delta || 0;
        var visualMapModel = this.visualMapModel;
        var handleEnds = this._handleEnds;
        var sizeExtent = [0, visualMapModel.itemSize[1]];
        sliderMove(delta, handleEnds, sizeExtent, handleIndex, // cross is forbiden
        0);
        var dataExtent = visualMapModel.getExtent(); // Update data interval.

        this._dataInterval = [linearMap$2(handleEnds[0], sizeExtent, dataExtent, true), linearMap$2(handleEnds[1], sizeExtent, dataExtent, true)];
      };

      ContinuousView.prototype._updateView = function (forSketch) {
        var visualMapModel = this.visualMapModel;
        var dataExtent = visualMapModel.getExtent();
        var shapes = this._shapes;
        var outOfRangeHandleEnds = [0, visualMapModel.itemSize[1]];
        var inRangeHandleEnds = forSketch ? outOfRangeHandleEnds : this._handleEnds;

        var visualInRange = this._createBarVisual(this._dataInterval, dataExtent, inRangeHandleEnds, 'inRange');

        var visualOutOfRange = this._createBarVisual(dataExtent, dataExtent, outOfRangeHandleEnds, 'outOfRange');

        shapes.inRange.setStyle({
          fill: visualInRange.barColor // opacity: visualInRange.opacity

        }).setShape('points', visualInRange.barPoints);
        shapes.outOfRange.setStyle({
          fill: visualOutOfRange.barColor // opacity: visualOutOfRange.opacity

        }).setShape('points', visualOutOfRange.barPoints);

        this._updateHandle(inRangeHandleEnds, visualInRange);
      };

      ContinuousView.prototype._createBarVisual = function (dataInterval, dataExtent, handleEnds, forceState) {
        var opts = {
          forceState: forceState,
          convertOpacityToAlpha: true
        };

        var colorStops = this._makeColorGradient(dataInterval, opts);

        var symbolSizes = [this.getControllerVisual(dataInterval[0], 'symbolSize', opts), this.getControllerVisual(dataInterval[1], 'symbolSize', opts)];

        var barPoints = this._createBarPoints(handleEnds, symbolSizes);

        return {
          barColor: new LinearGradient(0, 0, 0, 1, colorStops),
          barPoints: barPoints,
          handlesColor: [colorStops[0].color, colorStops[colorStops.length - 1].color]
        };
      };

      ContinuousView.prototype._makeColorGradient = function (dataInterval, opts) {
        // Considering colorHue, which is not linear, so we have to sample
        // to calculate gradient color stops, but not only caculate head
        // and tail.
        var sampleNumber = 100; // Arbitrary value.

        var colorStops = [];
        var step = (dataInterval[1] - dataInterval[0]) / sampleNumber;
        colorStops.push({
          color: this.getControllerVisual(dataInterval[0], 'color', opts),
          offset: 0
        });

        for (var i = 1; i < sampleNumber; i++) {
          var currValue = dataInterval[0] + step * i;

          if (currValue > dataInterval[1]) {
            break;
          }

          colorStops.push({
            color: this.getControllerVisual(currValue, 'color', opts),
            offset: i / sampleNumber
          });
        }

        colorStops.push({
          color: this.getControllerVisual(dataInterval[1], 'color', opts),
          offset: 1
        });
        return colorStops;
      };

      ContinuousView.prototype._createBarPoints = function (handleEnds, symbolSizes) {
        var itemSize = this.visualMapModel.itemSize;
        return [[itemSize[0] - symbolSizes[0], handleEnds[0]], [itemSize[0], handleEnds[0]], [itemSize[0], handleEnds[1]], [itemSize[0] - symbolSizes[1], handleEnds[1]]];
      };

      ContinuousView.prototype._createBarGroup = function (itemAlign) {
        var orient = this._orient;
        var inverse = this.visualMapModel.get('inverse');
        return new Group(orient === 'horizontal' && !inverse ? {
          scaleX: itemAlign === 'bottom' ? 1 : -1,
          rotation: Math.PI / 2
        } : orient === 'horizontal' && inverse ? {
          scaleX: itemAlign === 'bottom' ? -1 : 1,
          rotation: -Math.PI / 2
        } : orient === 'vertical' && !inverse ? {
          scaleX: itemAlign === 'left' ? 1 : -1,
          scaleY: -1
        } : {
          scaleX: itemAlign === 'left' ? 1 : -1
        });
      };

      ContinuousView.prototype._updateHandle = function (handleEnds, visualInRange) {
        if (!this._useHandle) {
          return;
        }

        var shapes = this._shapes;
        var visualMapModel = this.visualMapModel;
        var handleThumbs = shapes.handleThumbs;
        var handleLabels = shapes.handleLabels;
        var itemSize = visualMapModel.itemSize;
        var dataExtent = visualMapModel.getExtent();
        each$e([0, 1], function (handleIndex) {
          var handleThumb = handleThumbs[handleIndex];
          handleThumb.setStyle('fill', visualInRange.handlesColor[handleIndex]);
          handleThumb.y = handleEnds[handleIndex];
          var val = linearMap$2(handleEnds[handleIndex], [0, itemSize[1]], dataExtent, true);
          var symbolSize = this.getControllerVisual(val, 'symbolSize');
          handleThumb.scaleX = handleThumb.scaleY = symbolSize / itemSize[0];
          handleThumb.x = itemSize[0] - symbolSize / 2; // Update handle label position.

          var textPoint = applyTransform$1(shapes.handleLabelPoints[handleIndex], getTransform(handleThumb, this.group));
          handleLabels[handleIndex].setStyle({
            x: textPoint[0],
            y: textPoint[1],
            text: visualMapModel.formatValueText(this._dataInterval[handleIndex]),
            verticalAlign: 'middle',
            align: this._orient === 'vertical' ? this._applyTransform('left', shapes.mainGroup) : 'center'
          });
        }, this);
      };

      ContinuousView.prototype._showIndicator = function (cursorValue, textValue, rangeSymbol, halfHoverLinkSize) {
        var visualMapModel = this.visualMapModel;
        var dataExtent = visualMapModel.getExtent();
        var itemSize = visualMapModel.itemSize;
        var sizeExtent = [0, itemSize[1]];
        var shapes = this._shapes;
        var indicator = shapes.indicator;

        if (!indicator) {
          return;
        }

        indicator.attr('invisible', false);
        var opts = {
          convertOpacityToAlpha: true
        };
        var color = this.getControllerVisual(cursorValue, 'color', opts);
        var symbolSize = this.getControllerVisual(cursorValue, 'symbolSize');
        var y = linearMap$2(cursorValue, dataExtent, sizeExtent, true);
        var x = itemSize[0] - symbolSize / 2;
        var oldIndicatorPos = {
          x: indicator.x,
          y: indicator.y
        }; // Update handle label position.

        indicator.y = y;
        indicator.x = x;
        var textPoint = applyTransform$1(shapes.indicatorLabelPoint, getTransform(indicator, this.group));
        var indicatorLabel = shapes.indicatorLabel;
        indicatorLabel.attr('invisible', false);

        var align = this._applyTransform('left', shapes.mainGroup);

        var orient = this._orient;
        var isHorizontal = orient === 'horizontal';
        indicatorLabel.setStyle({
          text: (rangeSymbol ? rangeSymbol : '') + visualMapModel.formatValueText(textValue),
          verticalAlign: isHorizontal ? align : 'middle',
          align: isHorizontal ? 'center' : align
        });
        var indicatorNewProps = {
          x: x,
          y: y,
          style: {
            fill: color
          }
        };
        var labelNewProps = {
          style: {
            x: textPoint[0],
            y: textPoint[1]
          }
        };

        if (visualMapModel.ecModel.isAnimationEnabled() && !this._firstShowIndicator) {
          var animationCfg = {
            duration: 100,
            easing: 'cubicInOut',
            additive: true
          };
          indicator.x = oldIndicatorPos.x;
          indicator.y = oldIndicatorPos.y;
          indicator.animateTo(indicatorNewProps, animationCfg);
          indicatorLabel.animateTo(labelNewProps, animationCfg);
        } else {
          indicator.attr(indicatorNewProps);
          indicatorLabel.attr(labelNewProps);
        }

        this._firstShowIndicator = false;
        var handleLabels = this._shapes.handleLabels;

        if (handleLabels) {
          for (var i = 0; i < handleLabels.length; i++) {
            // Fade out handle labels.
            // NOTE: Must use api enter/leave on emphasis/blur/select state. Or the global states manager will change it.
            this._api.enterBlur(handleLabels[i]);
          }
        }
      };

      ContinuousView.prototype._enableHoverLinkToSeries = function () {
        var self = this;

        this._shapes.mainGroup.on('mousemove', function (e) {
          self._hovering = true;

          if (!self._dragging) {
            var itemSize = self.visualMapModel.itemSize;

            var pos = self._applyTransform([e.offsetX, e.offsetY], self._shapes.mainGroup, true, true); // For hover link show when hover handle, which might be
            // below or upper than sizeExtent.


            pos[1] = mathMin$a(mathMax$a(0, pos[1]), itemSize[1]);

            self._doHoverLinkToSeries(pos[1], 0 <= pos[0] && pos[0] <= itemSize[0]);
          }
        }).on('mouseout', function () {
          // When mouse is out of handle, hoverLink still need
          // to be displayed when realtime is set as false.
          self._hovering = false;
          !self._dragging && self._clearHoverLinkToSeries();
        });
      };

      ContinuousView.prototype._enableHoverLinkFromSeries = function () {
        var zr = this.api.getZr();

        if (this.visualMapModel.option.hoverLink) {
          zr.on('mouseover', this._hoverLinkFromSeriesMouseOver, this);
          zr.on('mouseout', this._hideIndicator, this);
        } else {
          this._clearHoverLinkFromSeries();
        }
      };

      ContinuousView.prototype._doHoverLinkToSeries = function (cursorPos, hoverOnBar) {
        var visualMapModel = this.visualMapModel;
        var itemSize = visualMapModel.itemSize;

        if (!visualMapModel.option.hoverLink) {
          return;
        }

        var sizeExtent = [0, itemSize[1]];
        var dataExtent = visualMapModel.getExtent(); // For hover link show when hover handle, which might be below or upper than sizeExtent.

        cursorPos = mathMin$a(mathMax$a(sizeExtent[0], cursorPos), sizeExtent[1]);
        var halfHoverLinkSize = getHalfHoverLinkSize(visualMapModel, dataExtent, sizeExtent);
        var hoverRange = [cursorPos - halfHoverLinkSize, cursorPos + halfHoverLinkSize];
        var cursorValue = linearMap$2(cursorPos, sizeExtent, dataExtent, true);
        var valueRange = [linearMap$2(hoverRange[0], sizeExtent, dataExtent, true), linearMap$2(hoverRange[1], sizeExtent, dataExtent, true)]; // Consider data range is out of visualMap range, see test/visualMap-continuous.html,
        // where china and india has very large population.

        hoverRange[0] < sizeExtent[0] && (valueRange[0] = -Infinity);
        hoverRange[1] > sizeExtent[1] && (valueRange[1] = Infinity); // Do not show indicator when mouse is over handle,
        // otherwise labels overlap, especially when dragging.

        if (hoverOnBar) {
          if (valueRange[0] === -Infinity) {
            this._showIndicator(cursorValue, valueRange[1], '< ', halfHoverLinkSize);
          } else if (valueRange[1] === Infinity) {
            this._showIndicator(cursorValue, valueRange[0], '> ', halfHoverLinkSize);
          } else {
            this._showIndicator(cursorValue, cursorValue, '≈ ', halfHoverLinkSize);
          }
        } // When realtime is set as false, handles, which are in barGroup,
        // also trigger hoverLink, which help user to realize where they
        // focus on when dragging. (see test/heatmap-large.html)
        // When realtime is set as true, highlight will not show when hover
        // handle, because the label on handle, which displays a exact value
        // but not range, might mislead users.


        var oldBatch = this._hoverLinkDataIndices;
        var newBatch = [];

        if (hoverOnBar || useHoverLinkOnHandle(visualMapModel)) {
          newBatch = this._hoverLinkDataIndices = visualMapModel.findTargetDataIndices(valueRange);
        }

        var resultBatches = compressBatches(oldBatch, newBatch);

        this._dispatchHighDown('downplay', makeHighDownBatch(resultBatches[0], visualMapModel));

        this._dispatchHighDown('highlight', makeHighDownBatch(resultBatches[1], visualMapModel));
      };

      ContinuousView.prototype._hoverLinkFromSeriesMouseOver = function (e) {
        var ecData;
        findEventDispatcher(e.target, function (target) {
          var currECData = getECData(target);

          if (currECData.dataIndex != null) {
            ecData = currECData;
            return true;
          }
        }, true);

        if (!ecData) {
          return;
        }

        var dataModel = this.ecModel.getSeriesByIndex(ecData.seriesIndex);
        var visualMapModel = this.visualMapModel;

        if (!visualMapModel.isTargetSeries(dataModel)) {
          return;
        }

        var data = dataModel.getData(ecData.dataType);
        var value = data.getStore().get(visualMapModel.getDataDimensionIndex(data), ecData.dataIndex);

        if (!isNaN(value)) {
          this._showIndicator(value, value);
        }
      };

      ContinuousView.prototype._hideIndicator = function () {
        var shapes = this._shapes;
        shapes.indicator && shapes.indicator.attr('invisible', true);
        shapes.indicatorLabel && shapes.indicatorLabel.attr('invisible', true);
        var handleLabels = this._shapes.handleLabels;

        if (handleLabels) {
          for (var i = 0; i < handleLabels.length; i++) {
            // Fade out handle labels.
            // NOTE: Must use api enter/leave on emphasis/blur/select state. Or the global states manager will change it.
            this._api.leaveBlur(handleLabels[i]);
          }
        }
      };

      ContinuousView.prototype._clearHoverLinkToSeries = function () {
        this._hideIndicator();

        var indices = this._hoverLinkDataIndices;

        this._dispatchHighDown('downplay', makeHighDownBatch(indices, this.visualMapModel));

        indices.length = 0;
      };

      ContinuousView.prototype._clearHoverLinkFromSeries = function () {
        this._hideIndicator();

        var zr = this.api.getZr();
        zr.off('mouseover', this._hoverLinkFromSeriesMouseOver);
        zr.off('mouseout', this._hideIndicator);
      };

      ContinuousView.prototype._applyTransform = function (vertex, element, inverse, global) {
        var transform = getTransform(element, global ? null : this.group);
        return isArray(vertex) ? applyTransform$1(vertex, transform, inverse) : transformDirection(vertex, transform, inverse);
      }; // TODO: TYPE more specified payload types.


      ContinuousView.prototype._dispatchHighDown = function (type, batch) {
        batch && batch.length && this.api.dispatchAction({
          type: type,
          batch: batch
        });
      };
      /**
       * @override
       */


      ContinuousView.prototype.dispose = function () {
        this._clearHoverLinkFromSeries();

        this._clearHoverLinkToSeries();
      };
      /**
       * @override
       */


      ContinuousView.prototype.remove = function () {
        this._clearHoverLinkFromSeries();

        this._clearHoverLinkToSeries();
      };

      ContinuousView.type = 'visualMap.continuous';
      return ContinuousView;
    }(VisualMapView);

    function createPolygon(points, cursor, onDrift, onDragEnd) {
      return new Polygon({
        shape: {
          points: points
        },
        draggable: !!onDrift,
        cursor: cursor,
        drift: onDrift,
        onmousemove: function (e) {
          // Fot mobile devicem, prevent screen slider on the button.
          stop(e.event);
        },
        ondragend: onDragEnd
      });
    }

    function getHalfHoverLinkSize(visualMapModel, dataExtent, sizeExtent) {
      var halfHoverLinkSize = HOVER_LINK_SIZE / 2;
      var hoverLinkDataSize = visualMapModel.get('hoverLinkDataSize');

      if (hoverLinkDataSize) {
        halfHoverLinkSize = linearMap$2(hoverLinkDataSize, dataExtent, sizeExtent, true) / 2;
      }

      return halfHoverLinkSize;
    }

    function useHoverLinkOnHandle(visualMapModel) {
      var hoverLinkOnHandle = visualMapModel.get('hoverLinkOnHandle');
      return !!(hoverLinkOnHandle == null ? visualMapModel.get('realtime') : hoverLinkOnHandle);
    }

    function getCursor$1(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.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * 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 visualMapActionInfo = {
      type: 'selectDataRange',
      event: 'dataRangeSelected',
      // FIXME use updateView appears wrong
      update: 'update'
    };
    var visualMapActionHander = function (payload, ecModel) {
      ecModel.eachComponent({
        mainType: 'visualMap',
        query: payload
      }, function (model) {
        model.setSelected(payload.selected);
      });
    };

    var visualMapEncodingHandlers = [{
      createOnAllSeries: true,
      reset: function (seriesModel, ecModel) {
        var resetDefines = [];
        ecModel.eachComponent('visualMap', function (visualMapModel) {
          var pipelineContext = seriesModel.pipelineContext;

          if (!visualMapModel.isTargetSeries(seriesModel) || pipelineContext && pipelineContext.large) {
            return;
          }

          resetDefines.push(incrementalApplyVisual(visualMapModel.stateList, visualMapModel.targetVisuals, bind(visualMapModel.getValueState, visualMapModel), visualMapModel.getDataDimensionIndex(seriesModel.getData())));
        });
        return resetDefines;
      }
    }, // Only support color.
    {
      createOnAllSeries: true,
      reset: function (seriesModel, ecModel) {
        var data = seriesModel.getData();
        var visualMetaList = [];
        ecModel.eachComponent('visualMap', function (visualMapModel) {
          if (visualMapModel.isTargetSeries(seriesModel)) {
            var visualMeta = visualMapModel.getVisualMeta(bind(getColorVisual, null, seriesModel, visualMapModel)) || {
              stops: [],
              outerColors: []
            };
            var dimIdx = visualMapModel.getDataDimensionIndex(data);

            if (dimIdx >= 0) {
              // visualMeta.dimension should be dimension index, but not concrete dimension.
              visualMeta.dimension = dimIdx;
              visualMetaList.push(visualMeta);
            }
          }
        }); // console.log(JSON.stringify(visualMetaList.map(a => a.stops)));

        seriesModel.getData().setVisual('visualMeta', visualMetaList);
      }
    }]; // FIXME
    // performance and export for heatmap?
    // value can be Infinity or -Infinity

    function getColorVisual(seriesModel, visualMapModel, value, valueState) {
      var mappings = visualMapModel.targetVisuals[valueState];
      var visualTypes = VisualMapping.prepareVisualTypes(mappings);
      var resultVisual = {
        color: getVisualFromData(seriesModel.getData(), 'color') // default color.

      };

      for (var i = 0, len = visualTypes.length; i < len; i++) {
        var type = visualTypes[i];
        var mapping = mappings[type === 'opacity' ? '__alphaForOpacity' : type];
        mapping && mapping.applyVisual(value, getVisual, setVisual);
      }

      return resultVisual.color;

      function getVisual(key) {
        return resultVisual[key];
      }

      function setVisual(key, value) {
        resultVisual[key] = value;
      }
    }

    var each$f = each;
    function visualMapPreprocessor(option) {
      var visualMap = option && option.visualMap;

      if (!isArray(visualMap)) {
        visualMap = visualMap ? [visualMap] : [];
      }

      each$f(visualMap, function (opt) {
        if (!opt) {
          return;
        } // rename splitList to pieces


        if (has$1(opt, 'splitList') && !has$1(opt, 'pieces')) {
          opt.pieces = opt.splitList;
          delete opt.splitList;
        }

        var pieces = opt.pieces;

        if (pieces && isArray(pieces)) {
          each$f(pieces, function (piece) {
            if (isObject(piece)) {
              if (has$1(piece, 'start') && !has$1(piece, 'min')) {
                piece.min = piece.start;
              }

              if (has$1(piece, 'end') && !has$1(piece, 'max')) {
                piece.max = piece.end;
              }
            }
          });
        }
      });
    }

    function has$1(obj, name) {
      return obj && obj.hasOwnProperty && obj.hasOwnProperty(name);
    }

    var installed$1 = false;
    function installCommon$1(registers) {
      if (installed$1) {
        return;
      }

      installed$1 = true;
      registers.registerSubTypeDefaulter('visualMap', function (option) {
        // Compatible with ec2, when splitNumber === 0, continuous visualMap will be used.
        return !option.categories && (!(option.pieces ? option.pieces.length > 0 : option.splitNumber > 0) || option.calculable) ? 'continuous' : 'piecewise';
      });
      registers.registerAction(visualMapActionInfo, visualMapActionHander);
      each(visualMapEncodingHandlers, function (handler) {
        registers.registerVisual(registers.PRIORITY.VISUAL.COMPONENT, handler);
      });
      registers.registerPreprocessor(visualMapPreprocessor);
    }

    function install$N(registers) {
      registers.registerComponentModel(ContinuousModel);
      registers.registerComponentView(ContinuousView);
      installCommon$1(registers);
    }

    var PiecewiseModel =
    /** @class */
    function (_super) {
      __extends(PiecewiseModel, _super);

      function PiecewiseModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = PiecewiseModel.type;
        /**
         * The order is always [low, ..., high].
         * [{text: string, interval: Array.<number>}, ...]
         */

        _this._pieceList = [];
        return _this;
      }

      PiecewiseModel.prototype.optionUpdated = function (newOption, isInit) {
        _super.prototype.optionUpdated.apply(this, arguments);

        this.resetExtent();

        var mode = this._mode = this._determineMode();

        this._pieceList = [];

        resetMethods[this._mode].call(this, this._pieceList);

        this._resetSelected(newOption, isInit);

        var categories = this.option.categories;
        this.resetVisual(function (mappingOption, state) {
          if (mode === 'categories') {
            mappingOption.mappingMethod = 'category';
            mappingOption.categories = clone(categories);
          } else {
            mappingOption.dataExtent = this.getExtent();
            mappingOption.mappingMethod = 'piecewise';
            mappingOption.pieceList = map(this._pieceList, function (piece) {
              piece = clone(piece);

              if (state !== 'inRange') {
                // FIXME
                // outOfRange do not support special visual in pieces.
                piece.visual = null;
              }

              return piece;
            });
          }
        });
      };
      /**
       * @protected
       * @override
       */


      PiecewiseModel.prototype.completeVisualOption = function () {
        // Consider this case:
        // visualMap: {
        //      pieces: [{symbol: 'circle', lt: 0}, {symbol: 'rect', gte: 0}]
        // }
        // where no inRange/outOfRange set but only pieces. So we should make
        // default inRange/outOfRange for this case, otherwise visuals that only
        // appear in `pieces` will not be taken into account in visual encoding.
        var option = this.option;
        var visualTypesInPieces = {};
        var visualTypes = VisualMapping.listVisualTypes();
        var isCategory = this.isCategory();
        each(option.pieces, function (piece) {
          each(visualTypes, function (visualType) {
            if (piece.hasOwnProperty(visualType)) {
              visualTypesInPieces[visualType] = 1;
            }
          });
        });
        each(visualTypesInPieces, function (v, visualType) {
          var exists = false;
          each(this.stateList, function (state) {
            exists = exists || has(option, state, visualType) || has(option.target, state, visualType);
          }, this);
          !exists && each(this.stateList, function (state) {
            (option[state] || (option[state] = {}))[visualType] = visualDefault.get(visualType, state === 'inRange' ? 'active' : 'inactive', isCategory);
          });
        }, this);

        function has(obj, state, visualType) {
          return obj && obj[state] && obj[state].hasOwnProperty(visualType);
        }

        _super.prototype.completeVisualOption.apply(this, arguments);
      };

      PiecewiseModel.prototype._resetSelected = function (newOption, isInit) {
        var thisOption = this.option;
        var pieceList = this._pieceList; // Selected do not merge but all override.

        var selected = (isInit ? thisOption : newOption).selected || {};
        thisOption.selected = selected; // Consider 'not specified' means true.

        each(pieceList, function (piece, index) {
          var key = this.getSelectedMapKey(piece);

          if (!selected.hasOwnProperty(key)) {
            selected[key] = true;
          }
        }, this);

        if (thisOption.selectedMode === 'single') {
          // Ensure there is only one selected.
          var hasSel_1 = false;
          each(pieceList, function (piece, index) {
            var key = this.getSelectedMapKey(piece);

            if (selected[key]) {
              hasSel_1 ? selected[key] = false : hasSel_1 = true;
            }
          }, this);
        } // thisOption.selectedMode === 'multiple', default: all selected.

      };
      /**
       * @public
       */


      PiecewiseModel.prototype.getItemSymbol = function () {
        return this.get('itemSymbol');
      };
      /**
       * @public
       */


      PiecewiseModel.prototype.getSelectedMapKey = function (piece) {
        return this._mode === 'categories' ? piece.value + '' : piece.index + '';
      };
      /**
       * @public
       */


      PiecewiseModel.prototype.getPieceList = function () {
        return this._pieceList;
      };
      /**
       * @return {string}
       */


      PiecewiseModel.prototype._determineMode = function () {
        var option = this.option;
        return option.pieces && option.pieces.length > 0 ? 'pieces' : this.option.categories ? 'categories' : 'splitNumber';
      };
      /**
       * @override
       */


      PiecewiseModel.prototype.setSelected = function (selected) {
        this.option.selected = clone(selected);
      };
      /**
       * @override
       */


      PiecewiseModel.prototype.getValueState = function (value) {
        var index = VisualMapping.findPieceIndex(value, this._pieceList);
        return index != null ? this.option.selected[this.getSelectedMapKey(this._pieceList[index])] ? 'inRange' : 'outOfRange' : 'outOfRange';
      };
      /**
       * @public
       * @param pieceIndex piece index in visualMapModel.getPieceList()
       */


      PiecewiseModel.prototype.findTargetDataIndices = function (pieceIndex) {
        var result = [];
        var pieceList = this._pieceList;
        this.eachTargetSeries(function (seriesModel) {
          var dataIndices = [];
          var data = seriesModel.getData();
          data.each(this.getDataDimensionIndex(data), function (value, dataIndex) {
            // Should always base on model pieceList, because it is order sensitive.
            var pIdx = VisualMapping.findPieceIndex(value, pieceList);
            pIdx === pieceIndex && dataIndices.push(dataIndex);
          }, this);
          result.push({
            seriesId: seriesModel.id,
            dataIndex: dataIndices
          });
        }, this);
        return result;
      };
      /**
       * @private
       * @param piece piece.value or piece.interval is required.
       * @return  Can be Infinity or -Infinity
       */


      PiecewiseModel.prototype.getRepresentValue = function (piece) {
        var representValue;

        if (this.isCategory()) {
          representValue = piece.value;
        } else {
          if (piece.value != null) {
            representValue = piece.value;
          } else {
            var pieceInterval = piece.interval || [];
            representValue = pieceInterval[0] === -Infinity && pieceInterval[1] === Infinity ? 0 : (pieceInterval[0] + pieceInterval[1]) / 2;
          }
        }

        return representValue;
      };

      PiecewiseModel.prototype.getVisualMeta = function (getColorVisual) {
        // Do not support category. (category axis is ordinal, numerical)
        if (this.isCategory()) {
          return;
        }

        var stops = [];
        var outerColors = ['', ''];
        var visualMapModel = this;

        function setStop(interval, valueState) {
          var representValue = visualMapModel.getRepresentValue({
            interval: interval
          }); // Not category

          if (!valueState) {
            valueState = visualMapModel.getValueState(representValue);
          }

          var color = getColorVisual(representValue, valueState);

          if (interval[0] === -Infinity) {
            outerColors[0] = color;
          } else if (interval[1] === Infinity) {
            outerColors[1] = color;
          } else {
            stops.push({
              value: interval[0],
              color: color
            }, {
              value: interval[1],
              color: color
            });
          }
        } // Suplement


        var pieceList = this._pieceList.slice();

        if (!pieceList.length) {
          pieceList.push({
            interval: [-Infinity, Infinity]
          });
        } else {
          var edge = pieceList[0].interval[0];
          edge !== -Infinity && pieceList.unshift({
            interval: [-Infinity, edge]
          });
          edge = pieceList[pieceList.length - 1].interval[1];
          edge !== Infinity && pieceList.push({
            interval: [edge, Infinity]
          });
        }

        var curr = -Infinity;
        each(pieceList, function (piece) {
          var interval = piece.interval;

          if (interval) {
            // Fulfill gap.
            interval[0] > curr && setStop([curr, interval[0]], 'outOfRange');
            setStop(interval.slice());
            curr = interval[1];
          }
        }, this);
        return {
          stops: stops,
          outerColors: outerColors
        };
      };

      PiecewiseModel.type = 'visualMap.piecewise';
      PiecewiseModel.defaultOption = inheritDefaultOption(VisualMapModel.defaultOption, {
        selected: null,
        minOpen: false,
        maxOpen: false,
        align: 'auto',
        itemWidth: 20,
        itemHeight: 14,
        itemSymbol: 'roundRect',
        pieces: null,
        categories: null,
        splitNumber: 5,
        selectedMode: 'multiple',
        itemGap: 10,
        hoverLink: true // Enable hover highlight.

      });
      return PiecewiseModel;
    }(VisualMapModel);
    /**
     * Key is this._mode
     * @type {Object}
     * @this {module:echarts/component/viusalMap/PiecewiseMode}
     */

    var resetMethods = {
      splitNumber: function (outPieceList) {
        var thisOption = this.option;
        var precision = Math.min(thisOption.precision, 20);
        var dataExtent = this.getExtent();
        var splitNumber = thisOption.splitNumber;
        splitNumber = Math.max(parseInt(splitNumber, 10), 1);
        thisOption.splitNumber = splitNumber;
        var splitStep = (dataExtent[1] - dataExtent[0]) / splitNumber; // Precision auto-adaption

        while (+splitStep.toFixed(precision) !== splitStep && precision < 5) {
          precision++;
        }

        thisOption.precision = precision;
        splitStep = +splitStep.toFixed(precision);

        if (thisOption.minOpen) {
          outPieceList.push({
            interval: [-Infinity, dataExtent[0]],
            close: [0, 0]
          });
        }

        for (var index = 0, curr = dataExtent[0]; index < splitNumber; curr += splitStep, index++) {
          var max = index === splitNumber - 1 ? dataExtent[1] : curr + splitStep;
          outPieceList.push({
            interval: [curr, max],
            close: [1, 1]
          });
        }

        if (thisOption.maxOpen) {
          outPieceList.push({
            interval: [dataExtent[1], Infinity],
            close: [0, 0]
          });
        }

        reformIntervals(outPieceList);
        each(outPieceList, function (piece, index) {
          piece.index = index;
          piece.text = this.formatValueText(piece.interval);
        }, this);
      },
      categories: function (outPieceList) {
        var thisOption = this.option;
        each(thisOption.categories, function (cate) {
          // FIXME category模式也使用pieceList，但在visualMapping中不是使用pieceList。
          // 是否改一致。
          outPieceList.push({
            text: this.formatValueText(cate, true),
            value: cate
          });
        }, this); // See "Order Rule".

        normalizeReverse(thisOption, outPieceList);
      },
      pieces: function (outPieceList) {
        var thisOption = this.option;
        each(thisOption.pieces, function (pieceListItem, index) {
          if (!isObject(pieceListItem)) {
            pieceListItem = {
              value: pieceListItem
            };
          }

          var item = {
            text: '',
            index: index
          };

          if (pieceListItem.label != null) {
            item.text = pieceListItem.label;
          }

          if (pieceListItem.hasOwnProperty('value')) {
            var value = item.value = pieceListItem.value;
            item.interval = [value, value];
            item.close = [1, 1];
          } else {
            // `min` `max` is legacy option.
            // `lt` `gt` `lte` `gte` is recommanded.
            var interval = item.interval = [];
            var close_1 = item.close = [0, 0];
            var closeList = [1, 0, 1];
            var infinityList = [-Infinity, Infinity];
            var useMinMax = [];

            for (var lg = 0; lg < 2; lg++) {
              var names = [['gte', 'gt', 'min'], ['lte', 'lt', 'max']][lg];

              for (var i = 0; i < 3 && interval[lg] == null; i++) {
                interval[lg] = pieceListItem[names[i]];
                close_1[lg] = closeList[i];
                useMinMax[lg] = i === 2;
              }

              interval[lg] == null && (interval[lg] = infinityList[lg]);
            }

            useMinMax[0] && interval[1] === Infinity && (close_1[0] = 0);
            useMinMax[1] && interval[0] === -Infinity && (close_1[1] = 0);

            if ("development" !== 'production') {
              if (interval[0] > interval[1]) {
                console.warn('Piece ' + index + 'is illegal: ' + interval + ' lower bound should not greater then uppper bound.');
              }
            }

            if (interval[0] === interval[1] && close_1[0] && close_1[1]) {
              // Consider: [{min: 5, max: 5, visual: {...}}, {min: 0, max: 5}],
              // we use value to lift the priority when min === max
              item.value = interval[0];
            }
          }

          item.visual = VisualMapping.retrieveVisuals(pieceListItem);
          outPieceList.push(item);
        }, this); // See "Order Rule".

        normalizeReverse(thisOption, outPieceList); // Only pieces

        reformIntervals(outPieceList);
        each(outPieceList, function (piece) {
          var close = piece.close;
          var edgeSymbols = [['<', '≤'][close[1]], ['>', '≥'][close[0]]];
          piece.text = piece.text || this.formatValueText(piece.value != null ? piece.value : piece.interval, false, edgeSymbols);
        }, this);
      }
    };

    function normalizeReverse(thisOption, pieceList) {
      var inverse = thisOption.inverse;

      if (thisOption.orient === 'vertical' ? !inverse : inverse) {
        pieceList.reverse();
      }
    }

    var PiecewiseVisualMapView =
    /** @class */
    function (_super) {
      __extends(PiecewiseVisualMapView, _super);

      function PiecewiseVisualMapView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = PiecewiseVisualMapView.type;
        return _this;
      }

      PiecewiseVisualMapView.prototype.doRender = function () {
        var thisGroup = this.group;
        thisGroup.removeAll();
        var visualMapModel = this.visualMapModel;
        var textGap = visualMapModel.get('textGap');
        var textStyleModel = visualMapModel.textStyleModel;
        var textFont = textStyleModel.getFont();
        var textFill = textStyleModel.getTextColor();

        var itemAlign = this._getItemAlign();

        var itemSize = visualMapModel.itemSize;

        var viewData = this._getViewData();

        var endsText = viewData.endsText;
        var showLabel = retrieve(visualMapModel.get('showLabel', true), !endsText);
        endsText && this._renderEndsText(thisGroup, endsText[0], itemSize, showLabel, itemAlign);
        each(viewData.viewPieceList, function (item) {
          var piece = item.piece;
          var itemGroup = new Group();
          itemGroup.onclick = bind(this._onItemClick, this, piece);

          this._enableHoverLink(itemGroup, item.indexInModelPieceList); // TODO Category


          var representValue = visualMapModel.getRepresentValue(piece);

          this._createItemSymbol(itemGroup, representValue, [0, 0, itemSize[0], itemSize[1]]);

          if (showLabel) {
            var visualState = this.visualMapModel.getValueState(representValue);
            itemGroup.add(new ZRText({
              style: {
                x: itemAlign === 'right' ? -textGap : itemSize[0] + textGap,
                y: itemSize[1] / 2,
                text: piece.text,
                verticalAlign: 'middle',
                align: itemAlign,
                font: textFont,
                fill: textFill,
                opacity: visualState === 'outOfRange' ? 0.5 : 1
              }
            }));
          }

          thisGroup.add(itemGroup);
        }, this);
        endsText && this._renderEndsText(thisGroup, endsText[1], itemSize, showLabel, itemAlign);
        box(visualMapModel.get('orient'), thisGroup, visualMapModel.get('itemGap'));
        this.renderBackground(thisGroup);
        this.positionGroup(thisGroup);
      };

      PiecewiseVisualMapView.prototype._enableHoverLink = function (itemGroup, pieceIndex) {
        var _this = this;

        itemGroup.on('mouseover', function () {
          return onHoverLink('highlight');
        }).on('mouseout', function () {
          return onHoverLink('downplay');
        });

        var onHoverLink = function (method) {
          var visualMapModel = _this.visualMapModel; // TODO: TYPE More detailed action types

          visualMapModel.option.hoverLink && _this.api.dispatchAction({
            type: method,
            batch: makeHighDownBatch(visualMapModel.findTargetDataIndices(pieceIndex), visualMapModel)
          });
        };
      };

      PiecewiseVisualMapView.prototype._getItemAlign = function () {
        var visualMapModel = this.visualMapModel;
        var modelOption = visualMapModel.option;

        if (modelOption.orient === 'vertical') {
          return getItemAlign(visualMapModel, this.api, visualMapModel.itemSize);
        } else {
          // horizontal, most case left unless specifying right.
          var align = modelOption.align;

          if (!align || align === 'auto') {
            align = 'left';
          }

          return align;
        }
      };

      PiecewiseVisualMapView.prototype._renderEndsText = function (group, text, itemSize, showLabel, itemAlign) {
        if (!text) {
          return;
        }

        var itemGroup = new Group();
        var textStyleModel = this.visualMapModel.textStyleModel;
        itemGroup.add(new ZRText({
          style: createTextStyle(textStyleModel, {
            x: showLabel ? itemAlign === 'right' ? itemSize[0] : 0 : itemSize[0] / 2,
            y: itemSize[1] / 2,
            verticalAlign: 'middle',
            align: showLabel ? itemAlign : 'center',
            text: text
          })
        }));
        group.add(itemGroup);
      };
      /**
       * @private
       * @return {Object} {peiceList, endsText} The order is the same as screen pixel order.
       */


      PiecewiseVisualMapView.prototype._getViewData = function () {
        var visualMapModel = this.visualMapModel;
        var viewPieceList = map(visualMapModel.getPieceList(), function (piece, index) {
          return {
            piece: piece,
            indexInModelPieceList: index
          };
        });
        var endsText = visualMapModel.get('text'); // Consider orient and inverse.

        var orient = visualMapModel.get('orient');
        var inverse = visualMapModel.get('inverse'); // Order of model pieceList is always [low, ..., high]

        if (orient === 'horizontal' ? inverse : !inverse) {
          viewPieceList.reverse();
        } // Origin order of endsText is [high, low]
        else if (endsText) {
            endsText = endsText.slice().reverse();
          }

        return {
          viewPieceList: viewPieceList,
          endsText: endsText
        };
      };

      PiecewiseVisualMapView.prototype._createItemSymbol = function (group, representValue, shapeParam) {
        group.add(createSymbol( // symbol will be string
        this.getControllerVisual(representValue, 'symbol'), shapeParam[0], shapeParam[1], shapeParam[2], shapeParam[3], // color will be string
        this.getControllerVisual(representValue, 'color')));
      };

      PiecewiseVisualMapView.prototype._onItemClick = function (piece) {
        var visualMapModel = this.visualMapModel;
        var option = visualMapModel.option;
        var selectedMode = option.selectedMode;

        if (!selectedMode) {
          return;
        }

        var selected = clone(option.selected);
        var newKey = visualMapModel.getSelectedMapKey(piece);

        if (selectedMode === 'single' || selectedMode === true) {
          selected[newKey] = true;
          each(selected, function (o, key) {
            selected[key] = key === newKey;
          });
        } else {
          selected[newKey] = !selected[newKey];
        }

        this.api.dispatchAction({
          type: 'selectDataRange',
          from: this.uid,
          visualMapId: this.visualMapModel.id,
          selected: selected
        });
      };

      PiecewiseVisualMapView.type = 'visualMap.piecewise';
      return PiecewiseVisualMapView;
    }(VisualMapView);

    function install$O(registers) {
      registers.registerComponentModel(PiecewiseModel);
      registers.registerComponentView(PiecewiseVisualMapView);
      installCommon$1(registers);
    }

    function install$P(registers) {
      use(install$N);
      use(install$O); // Do not install './dataZoomSelect',
      // since it only work for toolbox dataZoom.
    }

    var DEFAULT_OPTION = {
      label: {
        enabled: true
      },
      decal: {
        show: false
      }
    };
    var inner$l = makeInner();
    var decalPaletteScope = {};
    function ariaVisual(ecModel, api) {
      var ariaModel = ecModel.getModel('aria'); // See "area enabled" detection code in `GlobalModel.ts`.

      if (!ariaModel.get('enabled')) {
        return;
      }

      var defaultOption = clone(DEFAULT_OPTION);
      merge(defaultOption.label, ecModel.getLocaleModel().get('aria'), false);
      merge(ariaModel.option, defaultOption, false);
      setDecal();
      setLabel();

      function setDecal() {
        var decalModel = ariaModel.getModel('decal');
        var useDecal = decalModel.get('show');

        if (useDecal) {
          // Each type of series use one scope.
          // Pie and funnel are using different scopes.
          var paletteScopeGroupByType_1 = createHashMap();
          ecModel.eachSeries(function (seriesModel) {
            if (seriesModel.isColorBySeries()) {
              return;
            }

            var decalScope = paletteScopeGroupByType_1.get(seriesModel.type);

            if (!decalScope) {
              decalScope = {};
              paletteScopeGroupByType_1.set(seriesModel.type, decalScope);
            }

            inner$l(seriesModel).scope = decalScope;
          });
          ecModel.eachRawSeries(function (seriesModel) {
            if (ecModel.isSeriesFiltered(seriesModel)) {
              return;
            }

            if (isFunction(seriesModel.enableAriaDecal)) {
              // Let series define how to use decal palette on data
              seriesModel.enableAriaDecal();
              return;
            }

            var data = seriesModel.getData();

            if (!seriesModel.isColorBySeries()) {
              var dataAll_1 = seriesModel.getRawData();
              var idxMap_1 = {};
              var decalScope_1 = inner$l(seriesModel).scope;
              data.each(function (idx) {
                var rawIdx = data.getRawIndex(idx);
                idxMap_1[rawIdx] = idx;
              });
              var dataCount_1 = dataAll_1.count();
              dataAll_1.each(function (rawIdx) {
                var idx = idxMap_1[rawIdx];
                var name = dataAll_1.getName(rawIdx) || rawIdx + '';
                var paletteDecal = getDecalFromPalette(seriesModel.ecModel, name, decalScope_1, dataCount_1);
                var specifiedDecal = data.getItemVisual(idx, 'decal');
                data.setItemVisual(idx, 'decal', mergeDecal(specifiedDecal, paletteDecal));
              });
            } else {
              var paletteDecal = getDecalFromPalette(seriesModel.ecModel, seriesModel.name, decalPaletteScope, ecModel.getSeriesCount());
              var specifiedDecal = data.getVisual('decal');
              data.setVisual('decal', mergeDecal(specifiedDecal, paletteDecal));
            }

            function mergeDecal(specifiedDecal, paletteDecal) {
              // Merge decal from palette to decal from itemStyle.
              // User do not need to specify all of the decal props.
              var resultDecal = specifiedDecal ? extend(extend({}, paletteDecal), specifiedDecal) : paletteDecal;
              resultDecal.dirty = true;
              return resultDecal;
            }
          });
        }
      }

      function setLabel() {
        var labelLocale = ecModel.getLocaleModel().get('aria');
        var labelModel = ariaModel.getModel('label');
        labelModel.option = defaults(labelModel.option, labelLocale);

        if (!labelModel.get('enabled')) {
          return;
        }

        var dom = api.getZr().dom;

        if (labelModel.get('description')) {
          dom.setAttribute('aria-label', labelModel.get('description'));
          return;
        }

        var seriesCnt = ecModel.getSeriesCount();
        var maxDataCnt = labelModel.get(['data', 'maxCount']) || 10;
        var maxSeriesCnt = labelModel.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) {
            var withTitle = labelModel.get(['general', 'withTitle']);
            ariaLabel = replace(withTitle, {
              title: title
            });
          } else {
            ariaLabel = labelModel.get(['general', 'withoutTitle']);
          }

          var seriesLabels_1 = [];
          var prefix = seriesCnt > 1 ? labelModel.get(['series', 'multiple', 'prefix']) : labelModel.get(['series', 'single', 'prefix']);
          ariaLabel += replace(prefix, {
            seriesCount: seriesCnt
          });
          ecModel.eachSeries(function (seriesModel, idx) {
            if (idx < displaySeriesCnt) {
              var seriesLabel = void 0;
              var seriesName = seriesModel.get('name');
              var withName = seriesName ? 'withName' : 'withoutName';
              seriesLabel = seriesCnt > 1 ? labelModel.get(['series', 'multiple', withName]) : labelModel.get(['series', 'single', withName]);
              seriesLabel = replace(seriesLabel, {
                seriesId: seriesModel.seriesIndex,
                seriesName: seriesModel.get('name'),
                seriesType: getSeriesTypeName(seriesModel.subType)
              });
              var data = seriesModel.getData();

              if (data.count() > maxDataCnt) {
                // Show part of data
                var partialLabel = labelModel.get(['data', 'partialData']);
                seriesLabel += replace(partialLabel, {
                  displayCnt: maxDataCnt
                });
              } else {
                seriesLabel += labelModel.get(['data', 'allData']);
              }

              var middleSeparator_1 = labelModel.get(['data', 'separator', 'middle']);
              var endSeparator_1 = labelModel.get(['data', 'separator', 'end']);
              var dataLabels = [];

              for (var i = 0; i < data.count(); i++) {
                if (i < maxDataCnt) {
                  var name_1 = data.getName(i);
                  var value = data.getValues(i);
                  var dataLabel = labelModel.get(['data', name_1 ? 'withName' : 'withoutName']);
                  dataLabels.push(replace(dataLabel, {
                    name: name_1,
                    value: value.join(middleSeparator_1)
                  }));
                }
              }

              seriesLabel += dataLabels.join(middleSeparator_1) + endSeparator_1;
              seriesLabels_1.push(seriesLabel);
            }
          });
          var separatorModel = labelModel.getModel(['series', 'multiple', 'separator']);
          var middleSeparator = separatorModel.get('middle');
          var endSeparator = separatorModel.get('end');
          ariaLabel += seriesLabels_1.join(middleSeparator) + endSeparator;
          dom.setAttribute('aria-label', ariaLabel);
        }
      }

      function replace(str, keyValues) {
        if (!isString(str)) {
          return str;
        }

        var result = str;
        each(keyValues, function (value, key) {
          result = result.replace(new RegExp('\\{\\s*' + key + '\\s*\\}', 'g'), value);
        });
        return result;
      }

      function getTitle() {
        var title = ecModel.get('title');

        if (title && title.length) {
          title = title[0];
        }

        return title && title.text;
      }

      function getSeriesTypeName(type) {
        return ecModel.getLocaleModel().get(['series', 'typeNames'])[type] || '自定义图';
      }
    }

    function ariaPreprocessor(option) {
      if (!option || !option.aria) {
        return;
      }

      var aria = option.aria; // aria.show is deprecated and should use aria.enabled instead

      if (aria.show != null) {
        aria.enabled = aria.show;
      }

      aria.label = aria.label || {}; // move description, general, series, data to be under aria.label

      each(['description', 'general', 'series', 'data'], function (name) {
        if (aria[name] != null) {
          aria.label[name] = aria[name];
        }
      });
    }

    function install$Q(registers) {
      registers.registerPreprocessor(ariaPreprocessor);
      registers.registerVisual(registers.PRIORITY.VISUAL.ARIA, ariaVisual);
    }

    var RELATIONAL_EXPRESSION_OP_ALIAS_MAP = {
      value: 'eq',
      // PENDING: not good for literal semantic?
      '<': 'lt',
      '<=': 'lte',
      '>': 'gt',
      '>=': 'gte',
      '=': 'eq',
      '!=': 'ne',
      '<>': 'ne' // Might be misleading for sake of the difference between '==' and '===',
      // so don't support them.
      // '==': 'eq',
      // '===': 'seq',
      // '!==': 'sne'
      // PENDING: Whether support some common alias "ge", "le", "neq"?
      // ge: 'gte',
      // le: 'lte',
      // neq: 'ne',

    }; // type RelationalExpressionOpEvaluate = (tarVal: unknown, condVal: unknown) => boolean;

    var RegExpEvaluator =
    /** @class */
    function () {
      function RegExpEvaluator(rVal) {
        // Support condVal: RegExp | string
        var condValue = this._condVal = isString(rVal) ? new RegExp(rVal) : isRegExp(rVal) ? rVal : null;

        if (condValue == null) {
          var errMsg = '';

          if ("development" !== 'production') {
            errMsg = makePrintable('Illegal regexp', rVal, 'in');
          }

          throwError(errMsg);
        }
      }

      RegExpEvaluator.prototype.evaluate = function (lVal) {
        var type = typeof lVal;
        return isString(type) ? this._condVal.test(lVal) : isNumber(type) ? this._condVal.test(lVal + '') : false;
      };

      return RegExpEvaluator;
    }();

    var ConstConditionInternal =
    /** @class */
    function () {
      function ConstConditionInternal() {}

      ConstConditionInternal.prototype.evaluate = function () {
        return this.value;
      };

      return ConstConditionInternal;
    }();

    var AndConditionInternal =
    /** @class */
    function () {
      function AndConditionInternal() {}

      AndConditionInternal.prototype.evaluate = function () {
        var children = this.children;

        for (var i = 0; i < children.length; i++) {
          if (!children[i].evaluate()) {
            return false;
          }
        }

        return true;
      };

      return AndConditionInternal;
    }();

    var OrConditionInternal =
    /** @class */
    function () {
      function OrConditionInternal() {}

      OrConditionInternal.prototype.evaluate = function () {
        var children = this.children;

        for (var i = 0; i < children.length; i++) {
          if (children[i].evaluate()) {
            return true;
          }
        }

        return false;
      };

      return OrConditionInternal;
    }();

    var NotConditionInternal =
    /** @class */
    function () {
      function NotConditionInternal() {}

      NotConditionInternal.prototype.evaluate = function () {
        return !this.child.evaluate();
      };

      return NotConditionInternal;
    }();

    var RelationalConditionInternal =
    /** @class */
    function () {
      function RelationalConditionInternal() {}

      RelationalConditionInternal.prototype.evaluate = function () {
        var needParse = !!this.valueParser; // Call getValue with no `this`.

        var getValue = this.getValue;
        var tarValRaw = getValue(this.valueGetterParam);
        var tarValParsed = needParse ? this.valueParser(tarValRaw) : null; // Relational cond follow "and" logic internally.

        for (var i = 0; i < this.subCondList.length; i++) {
          if (!this.subCondList[i].evaluate(needParse ? tarValParsed : tarValRaw)) {
            return false;
          }
        }

        return true;
      };

      return RelationalConditionInternal;
    }();

    function parseOption(exprOption, getters) {
      if (exprOption === true || exprOption === false) {
        var cond = new ConstConditionInternal();
        cond.value = exprOption;
        return cond;
      }

      var errMsg = '';

      if (!isObjectNotArray(exprOption)) {
        if ("development" !== 'production') {
          errMsg = makePrintable('Illegal config. Expect a plain object but actually', exprOption);
        }

        throwError(errMsg);
      }

      if (exprOption.and) {
        return parseAndOrOption('and', exprOption, getters);
      } else if (exprOption.or) {
        return parseAndOrOption('or', exprOption, getters);
      } else if (exprOption.not) {
        return parseNotOption(exprOption, getters);
      }

      return parseRelationalOption(exprOption, getters);
    }

    function parseAndOrOption(op, exprOption, getters) {
      var subOptionArr = exprOption[op];
      var errMsg = '';

      if ("development" !== 'production') {
        errMsg = makePrintable('"and"/"or" condition should only be `' + op + ': [...]` and must not be empty array.', 'Illegal condition:', exprOption);
      }

      if (!isArray(subOptionArr)) {
        throwError(errMsg);
      }

      if (!subOptionArr.length) {
        throwError(errMsg);
      }

      var cond = op === 'and' ? new AndConditionInternal() : new OrConditionInternal();
      cond.children = map(subOptionArr, function (subOption) {
        return parseOption(subOption, getters);
      });

      if (!cond.children.length) {
        throwError(errMsg);
      }

      return cond;
    }

    function parseNotOption(exprOption, getters) {
      var subOption = exprOption.not;
      var errMsg = '';

      if ("development" !== 'production') {
        errMsg = makePrintable('"not" condition should only be `not: {}`.', 'Illegal condition:', exprOption);
      }

      if (!isObjectNotArray(subOption)) {
        throwError(errMsg);
      }

      var cond = new NotConditionInternal();
      cond.child = parseOption(subOption, getters);

      if (!cond.child) {
        throwError(errMsg);
      }

      return cond;
    }

    function parseRelationalOption(exprOption, getters) {
      var errMsg = '';
      var valueGetterParam = getters.prepareGetValue(exprOption);
      var subCondList = [];
      var exprKeys = keys(exprOption);
      var parserName = exprOption.parser;
      var valueParser = parserName ? getRawValueParser(parserName) : null;

      for (var i = 0; i < exprKeys.length; i++) {
        var keyRaw = exprKeys[i];

        if (keyRaw === 'parser' || getters.valueGetterAttrMap.get(keyRaw)) {
          continue;
        }

        var op = hasOwn(RELATIONAL_EXPRESSION_OP_ALIAS_MAP, keyRaw) ? RELATIONAL_EXPRESSION_OP_ALIAS_MAP[keyRaw] : keyRaw;
        var condValueRaw = exprOption[keyRaw];
        var condValueParsed = valueParser ? valueParser(condValueRaw) : condValueRaw;
        var evaluator = createFilterComparator(op, condValueParsed) || op === 'reg' && new RegExpEvaluator(condValueParsed);

        if (!evaluator) {
          if ("development" !== 'production') {
            errMsg = makePrintable('Illegal relational operation: "' + keyRaw + '" in condition:', exprOption);
          }

          throwError(errMsg);
        }

        subCondList.push(evaluator);
      }

      if (!subCondList.length) {
        if ("development" !== 'production') {
          errMsg = makePrintable('Relational condition must have at least one operator.', 'Illegal condition:', exprOption);
        } // No relational operator always disabled in case of dangers result.


        throwError(errMsg);
      }

      var cond = new RelationalConditionInternal();
      cond.valueGetterParam = valueGetterParam;
      cond.valueParser = valueParser;
      cond.getValue = getters.getValue;
      cond.subCondList = subCondList;
      return cond;
    }

    function isObjectNotArray(val) {
      return isObject(val) && !isArrayLike(val);
    }

    var ConditionalExpressionParsed =
    /** @class */
    function () {
      function ConditionalExpressionParsed(exprOption, getters) {
        this._cond = parseOption(exprOption, getters);
      }

      ConditionalExpressionParsed.prototype.evaluate = function () {
        return this._cond.evaluate();
      };

      return ConditionalExpressionParsed;
    }();
    function parseConditionalExpression(exprOption, getters) {
      return new ConditionalExpressionParsed(exprOption, getters);
    }

    var filterTransform = {
      type: 'echarts:filter',
      // PEDING: enhance to filter by index rather than create new data
      transform: function (params) {
        // [Caveat] Fail-Fast:
        // Do not return the whole dataset unless user config indicate it explicitly.
        // For example, if no condition specified by mistake, return an empty result
        // is better than return the entire raw soruce for user to find the mistake.
        var upstream = params.upstream;
        var rawItem;
        var condition = parseConditionalExpression(params.config, {
          valueGetterAttrMap: createHashMap({
            dimension: true
          }),
          prepareGetValue: function (exprOption) {
            var errMsg = '';
            var dimLoose = exprOption.dimension;

            if (!hasOwn(exprOption, 'dimension')) {
              if ("development" !== 'production') {
                errMsg = makePrintable('Relation condition must has prop "dimension" specified.', 'Illegal condition:', exprOption);
              }

              throwError(errMsg);
            }

            var dimInfo = upstream.getDimensionInfo(dimLoose);

            if (!dimInfo) {
              if ("development" !== 'production') {
                errMsg = makePrintable('Can not find dimension info via: ' + dimLoose + '.\n', 'Existing dimensions: ', upstream.cloneAllDimensionInfo(), '.\n', 'Illegal condition:', exprOption, '.\n');
              }

              throwError(errMsg);
            }

            return {
              dimIdx: dimInfo.index
            };
          },
          getValue: function (param) {
            return upstream.retrieveValueFromItem(rawItem, param.dimIdx);
          }
        });
        var resultData = [];

        for (var i = 0, len = upstream.count(); i < len; i++) {
          rawItem = upstream.getRawDataItem(i);

          if (condition.evaluate()) {
            resultData.push(rawItem);
          }
        }

        return {
          data: resultData
        };
      }
    };

    var sampleLog = '';

    if ("development" !== 'production') {
      sampleLog = ['Valid config is like:', '{ dimension: "age", order: "asc" }', 'or [{ dimension: "age", order: "asc"], { dimension: "date", order: "desc" }]'].join(' ');
    }

    var sortTransform = {
      type: 'echarts:sort',
      transform: function (params) {
        var upstream = params.upstream;
        var config = params.config;
        var errMsg = ''; // Normalize
        // const orderExprList: OrderExpression[] = isArray(config[0])
        //     ? config as OrderExpression[]
        //     : [config as OrderExpression];

        var orderExprList = normalizeToArray(config);

        if (!orderExprList.length) {
          if ("development" !== 'production') {
            errMsg = 'Empty `config` in sort transform.';
          }

          throwError(errMsg);
        }

        var orderDefList = [];
        each(orderExprList, function (orderExpr) {
          var dimLoose = orderExpr.dimension;
          var order = orderExpr.order;
          var parserName = orderExpr.parser;
          var incomparable = orderExpr.incomparable;

          if (dimLoose == null) {
            if ("development" !== 'production') {
              errMsg = 'Sort transform config must has "dimension" specified.' + sampleLog;
            }

            throwError(errMsg);
          }

          if (order !== 'asc' && order !== 'desc') {
            if ("development" !== 'production') {
              errMsg = 'Sort transform config must has "order" specified.' + sampleLog;
            }

            throwError(errMsg);
          }

          if (incomparable && incomparable !== 'min' && incomparable !== 'max') {
            var errMsg_1 = '';

            if ("development" !== 'production') {
              errMsg_1 = 'incomparable must be "min" or "max" rather than "' + incomparable + '".';
            }

            throwError(errMsg_1);
          }

          if (order !== 'asc' && order !== 'desc') {
            var errMsg_2 = '';

            if ("development" !== 'production') {
              errMsg_2 = 'order must be "asc" or "desc" rather than "' + order + '".';
            }

            throwError(errMsg_2);
          }

          var dimInfo = upstream.getDimensionInfo(dimLoose);

          if (!dimInfo) {
            if ("development" !== 'production') {
              errMsg = makePrintable('Can not find dimension info via: ' + dimLoose + '.\n', 'Existing dimensions: ', upstream.cloneAllDimensionInfo(), '.\n', 'Illegal config:', orderExpr, '.\n');
            }

            throwError(errMsg);
          }

          var parser = parserName ? getRawValueParser(parserName) : null;

          if (parserName && !parser) {
            if ("development" !== 'production') {
              errMsg = makePrintable('Invalid parser name ' + parserName + '.\n', 'Illegal config:', orderExpr, '.\n');
            }

            throwError(errMsg);
          }

          orderDefList.push({
            dimIdx: dimInfo.index,
            parser: parser,
            comparator: new SortOrderComparator(order, incomparable)
          });
        }); // TODO: support it?

        var sourceFormat = upstream.sourceFormat;

        if (sourceFormat !== SOURCE_FORMAT_ARRAY_ROWS && sourceFormat !== SOURCE_FORMAT_OBJECT_ROWS) {
          if ("development" !== 'production') {
            errMsg = 'sourceFormat "' + sourceFormat + '" is not supported yet';
          }

          throwError(errMsg);
        } // Other upstream format are all array.


        var resultData = [];

        for (var i = 0, len = upstream.count(); i < len; i++) {
          resultData.push(upstream.getRawDataItem(i));
        }

        resultData.sort(function (item0, item1) {
          for (var i = 0; i < orderDefList.length; i++) {
            var orderDef = orderDefList[i];
            var val0 = upstream.retrieveValueFromItem(item0, orderDef.dimIdx);
            var val1 = upstream.retrieveValueFromItem(item1, orderDef.dimIdx);

            if (orderDef.parser) {
              val0 = orderDef.parser(val0);
              val1 = orderDef.parser(val1);
            }

            var result = orderDef.comparator.evaluate(val0, val1);

            if (result !== 0) {
              return result;
            }
          }

          return 0;
        });
        return {
          data: resultData
        };
      }
    };

    function install$R(registers) {
      registers.registerTransform(filterTransform);
      registers.registerTransform(sortTransform);
    }

    var DatasetModel =
    /** @class */
    function (_super) {
      __extends(DatasetModel, _super);

      function DatasetModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = 'dataset';
        return _this;
      }

      DatasetModel.prototype.init = function (option, parentModel, ecModel) {
        _super.prototype.init.call(this, option, parentModel, ecModel);

        this._sourceManager = new SourceManager(this);
        disableTransformOptionMerge(this);
      };

      DatasetModel.prototype.mergeOption = function (newOption, ecModel) {
        _super.prototype.mergeOption.call(this, newOption, ecModel);

        disableTransformOptionMerge(this);
      };

      DatasetModel.prototype.optionUpdated = function () {
        this._sourceManager.dirty();
      };

      DatasetModel.prototype.getSourceManager = function () {
        return this._sourceManager;
      };

      DatasetModel.type = 'dataset';
      DatasetModel.defaultOption = {
        seriesLayoutBy: SERIES_LAYOUT_BY_COLUMN
      };
      return DatasetModel;
    }(ComponentModel);

    var DatasetView =
    /** @class */
    function (_super) {
      __extends(DatasetView, _super);

      function DatasetView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = 'dataset';
        return _this;
      }

      DatasetView.type = 'dataset';
      return DatasetView;
    }(ComponentView);

    function install$S(registers) {
      registers.registerComponentModel(DatasetModel);
      registers.registerComponentView(DatasetView);
    }

    var CMD$4 = PathProxy.CMD;
    function aroundEqual(a, b) {
        return Math.abs(a - b) < 1e-5;
    }
    function pathToBezierCurves(path) {
        var data = path.data;
        var len = path.len();
        var bezierArrayGroups = [];
        var currentSubpath;
        var xi = 0;
        var yi = 0;
        var x0 = 0;
        var y0 = 0;
        function createNewSubpath(x, y) {
            if (currentSubpath && currentSubpath.length > 2) {
                bezierArrayGroups.push(currentSubpath);
            }
            currentSubpath = [x, y];
        }
        function addLine(x0, y0, x1, y1) {
            if (!(aroundEqual(x0, x1) && aroundEqual(y0, y1))) {
                currentSubpath.push(x0, y0, x1, y1, x1, y1);
            }
        }
        function addArc(startAngle, endAngle, cx, cy, rx, ry) {
            var delta = Math.abs(endAngle - startAngle);
            var len = Math.tan(delta / 4) * 4 / 3;
            var dir = endAngle < startAngle ? -1 : 1;
            var c1 = Math.cos(startAngle);
            var s1 = Math.sin(startAngle);
            var c2 = Math.cos(endAngle);
            var s2 = Math.sin(endAngle);
            var x1 = c1 * rx + cx;
            var y1 = s1 * ry + cy;
            var x4 = c2 * rx + cx;
            var y4 = s2 * ry + cy;
            var hx = rx * len * dir;
            var hy = ry * len * dir;
            currentSubpath.push(x1 - hx * s1, y1 + hy * c1, x4 + hx * s2, y4 - hy * c2, x4, y4);
        }
        var x1;
        var y1;
        var x2;
        var y2;
        for (var i = 0; i < len;) {
            var cmd = data[i++];
            var isFirst = i === 1;
            if (isFirst) {
                xi = data[i];
                yi = data[i + 1];
                x0 = xi;
                y0 = yi;
                if (cmd === CMD$4.L || cmd === CMD$4.C || cmd === CMD$4.Q) {
                    currentSubpath = [x0, y0];
                }
            }
            switch (cmd) {
                case CMD$4.M:
                    xi = x0 = data[i++];
                    yi = y0 = data[i++];
                    createNewSubpath(x0, y0);
                    break;
                case CMD$4.L:
                    x1 = data[i++];
                    y1 = data[i++];
                    addLine(xi, yi, x1, y1);
                    xi = x1;
                    yi = y1;
                    break;
                case CMD$4.C:
                    currentSubpath.push(data[i++], data[i++], data[i++], data[i++], xi = data[i++], yi = data[i++]);
                    break;
                case CMD$4.Q:
                    x1 = data[i++];
                    y1 = data[i++];
                    x2 = data[i++];
                    y2 = data[i++];
                    currentSubpath.push(xi + 2 / 3 * (x1 - xi), yi + 2 / 3 * (y1 - yi), x2 + 2 / 3 * (x1 - x2), y2 + 2 / 3 * (y1 - y2), x2, y2);
                    xi = x2;
                    yi = y2;
                    break;
                case CMD$4.A:
                    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;
                    i += 1;
                    var anticlockwise = !data[i++];
                    x1 = Math.cos(startAngle) * rx + cx;
                    y1 = Math.sin(startAngle) * ry + cy;
                    if (isFirst) {
                        x0 = x1;
                        y0 = y1;
                        createNewSubpath(x0, y0);
                    }
                    else {
                        addLine(xi, yi, x1, y1);
                    }
                    xi = Math.cos(endAngle) * rx + cx;
                    yi = Math.sin(endAngle) * ry + cy;
                    var step = (anticlockwise ? -1 : 1) * Math.PI / 2;
                    for (var angle = startAngle; anticlockwise ? angle > endAngle : angle < endAngle; angle += step) {
                        var nextAngle = anticlockwise ? Math.max(angle + step, endAngle)
                            : Math.min(angle + step, endAngle);
                        addArc(angle, nextAngle, cx, cy, rx, ry);
                    }
                    break;
                case CMD$4.R:
                    x0 = xi = data[i++];
                    y0 = yi = data[i++];
                    x1 = x0 + data[i++];
                    y1 = y0 + data[i++];
                    createNewSubpath(x1, y0);
                    addLine(x1, y0, x1, y1);
                    addLine(x1, y1, x0, y1);
                    addLine(x0, y1, x0, y0);
                    addLine(x0, y0, x1, y0);
                    break;
                case CMD$4.Z:
                    currentSubpath && addLine(xi, yi, x0, y0);
                    xi = x0;
                    yi = y0;
                    break;
            }
        }
        if (currentSubpath && currentSubpath.length > 2) {
            bezierArrayGroups.push(currentSubpath);
        }
        return bezierArrayGroups;
    }
    function adpativeBezier(x0, y0, x1, y1, x2, y2, x3, y3, out, scale) {
        if (aroundEqual(x0, x1) && aroundEqual(y0, y1) && aroundEqual(x2, x3) && aroundEqual(y2, y3)) {
            out.push(x3, y3);
            return;
        }
        var PIXEL_DISTANCE = 2 / scale;
        var PIXEL_DISTANCE_SQR = PIXEL_DISTANCE * PIXEL_DISTANCE;
        var dx = x3 - x0;
        var dy = y3 - y0;
        var d = Math.sqrt(dx * dx + dy * dy);
        dx /= d;
        dy /= d;
        var dx1 = x1 - x0;
        var dy1 = y1 - y0;
        var dx2 = x2 - x3;
        var dy2 = y2 - y3;
        var cp1LenSqr = dx1 * dx1 + dy1 * dy1;
        var cp2LenSqr = dx2 * dx2 + dy2 * dy2;
        if (cp1LenSqr < PIXEL_DISTANCE_SQR && cp2LenSqr < PIXEL_DISTANCE_SQR) {
            out.push(x3, y3);
            return;
        }
        var projLen1 = dx * dx1 + dy * dy1;
        var projLen2 = -dx * dx2 - dy * dy2;
        var d1Sqr = cp1LenSqr - projLen1 * projLen1;
        var d2Sqr = cp2LenSqr - projLen2 * projLen2;
        if (d1Sqr < PIXEL_DISTANCE_SQR && projLen1 >= 0
            && d2Sqr < PIXEL_DISTANCE_SQR && projLen2 >= 0) {
            out.push(x3, y3);
            return;
        }
        var tmpSegX = [];
        var tmpSegY = [];
        cubicSubdivide(x0, x1, x2, x3, 0.5, tmpSegX);
        cubicSubdivide(y0, y1, y2, y3, 0.5, tmpSegY);
        adpativeBezier(tmpSegX[0], tmpSegY[0], tmpSegX[1], tmpSegY[1], tmpSegX[2], tmpSegY[2], tmpSegX[3], tmpSegY[3], out, scale);
        adpativeBezier(tmpSegX[4], tmpSegY[4], tmpSegX[5], tmpSegY[5], tmpSegX[6], tmpSegY[6], tmpSegX[7], tmpSegY[7], out, scale);
    }
    function pathToPolygons(path, scale) {
        var bezierArrayGroups = pathToBezierCurves(path);
        var polygons = [];
        scale = scale || 1;
        for (var i = 0; i < bezierArrayGroups.length; i++) {
            var beziers = bezierArrayGroups[i];
            var polygon = [];
            var x0 = beziers[0];
            var y0 = beziers[1];
            polygon.push(x0, y0);
            for (var k = 2; k < beziers.length;) {
                var x1 = beziers[k++];
                var y1 = beziers[k++];
                var x2 = beziers[k++];
                var y2 = beziers[k++];
                var x3 = beziers[k++];
                var y3 = beziers[k++];
                adpativeBezier(x0, y0, x1, y1, x2, y2, x3, y3, polygon, scale);
                x0 = x3;
                y0 = y3;
            }
            polygons.push(polygon);
        }
        return polygons;
    }

    function getDividingGrids(dimSize, rowDim, count) {
        var rowSize = dimSize[rowDim];
        var columnSize = dimSize[1 - rowDim];
        var ratio = Math.abs(rowSize / columnSize);
        var rowCount = Math.ceil(Math.sqrt(ratio * count));
        var columnCount = Math.floor(count / rowCount);
        if (columnCount === 0) {
            columnCount = 1;
            rowCount = count;
        }
        var grids = [];
        for (var i = 0; i < rowCount; i++) {
            grids.push(columnCount);
        }
        var currentCount = rowCount * columnCount;
        var remained = count - currentCount;
        if (remained > 0) {
            for (var i = 0; i < remained; i++) {
                grids[i % rowCount] += 1;
            }
        }
        return grids;
    }
    function divideSector(sectorShape, count, outShapes) {
        var r0 = sectorShape.r0;
        var r = sectorShape.r;
        var startAngle = sectorShape.startAngle;
        var endAngle = sectorShape.endAngle;
        var angle = Math.abs(endAngle - startAngle);
        var arcLen = angle * r;
        var deltaR = r - r0;
        var isAngleRow = arcLen > Math.abs(deltaR);
        var grids = getDividingGrids([arcLen, deltaR], isAngleRow ? 0 : 1, count);
        var rowSize = (isAngleRow ? angle : deltaR) / grids.length;
        for (var row = 0; row < grids.length; row++) {
            var columnSize = (isAngleRow ? deltaR : angle) / grids[row];
            for (var column = 0; column < grids[row]; column++) {
                var newShape = {};
                if (isAngleRow) {
                    newShape.startAngle = startAngle + rowSize * row;
                    newShape.endAngle = startAngle + rowSize * (row + 1);
                    newShape.r0 = r0 + columnSize * column;
                    newShape.r = r0 + columnSize * (column + 1);
                }
                else {
                    newShape.startAngle = startAngle + columnSize * column;
                    newShape.endAngle = startAngle + columnSize * (column + 1);
                    newShape.r0 = r0 + rowSize * row;
                    newShape.r = r0 + rowSize * (row + 1);
                }
                newShape.clockwise = sectorShape.clockwise;
                newShape.cx = sectorShape.cx;
                newShape.cy = sectorShape.cy;
                outShapes.push(newShape);
            }
        }
    }
    function divideRect(rectShape, count, outShapes) {
        var width = rectShape.width;
        var height = rectShape.height;
        var isHorizontalRow = width > height;
        var grids = getDividingGrids([width, height], isHorizontalRow ? 0 : 1, count);
        var rowSizeDim = isHorizontalRow ? 'width' : 'height';
        var columnSizeDim = isHorizontalRow ? 'height' : 'width';
        var rowDim = isHorizontalRow ? 'x' : 'y';
        var columnDim = isHorizontalRow ? 'y' : 'x';
        var rowSize = rectShape[rowSizeDim] / grids.length;
        for (var row = 0; row < grids.length; row++) {
            var columnSize = rectShape[columnSizeDim] / grids[row];
            for (var column = 0; column < grids[row]; column++) {
                var newShape = {};
                newShape[rowDim] = row * rowSize;
                newShape[columnDim] = column * columnSize;
                newShape[rowSizeDim] = rowSize;
                newShape[columnSizeDim] = columnSize;
                newShape.x += rectShape.x;
                newShape.y += rectShape.y;
                outShapes.push(newShape);
            }
        }
    }
    function crossProduct2d$1(x1, y1, x2, y2) {
        return x1 * y2 - x2 * y1;
    }
    function lineLineIntersect$1(a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y) {
        var mx = a2x - a1x;
        var my = a2y - a1y;
        var nx = b2x - b1x;
        var ny = b2y - b1y;
        var nmCrossProduct = crossProduct2d$1(nx, ny, mx, my);
        if (Math.abs(nmCrossProduct) < 1e-6) {
            return null;
        }
        var b1a1x = a1x - b1x;
        var b1a1y = a1y - b1y;
        var p = crossProduct2d$1(b1a1x, b1a1y, nx, ny) / nmCrossProduct;
        if (p < 0 || p > 1) {
            return null;
        }
        return new Point(p * mx + a1x, p * my + a1y);
    }
    function projPtOnLine(pt, lineA, lineB) {
        var dir = new Point();
        Point.sub(dir, lineB, lineA);
        dir.normalize();
        var dir2 = new Point();
        Point.sub(dir2, pt, lineA);
        var len = dir2.dot(dir);
        return len;
    }
    function addToPoly(poly, pt) {
        var last = poly[poly.length - 1];
        if (last && last[0] === pt[0] && last[1] === pt[1]) {
            return;
        }
        poly.push(pt);
    }
    function splitPolygonByLine(points, lineA, lineB) {
        var len = points.length;
        var intersections = [];
        for (var i = 0; i < len; i++) {
            var p0 = points[i];
            var p1 = points[(i + 1) % len];
            var intersectionPt = lineLineIntersect$1(p0[0], p0[1], p1[0], p1[1], lineA.x, lineA.y, lineB.x, lineB.y);
            if (intersectionPt) {
                intersections.push({
                    projPt: projPtOnLine(intersectionPt, lineA, lineB),
                    pt: intersectionPt,
                    idx: i
                });
            }
        }
        if (intersections.length < 2) {
            return [{ points: points }, { points: points }];
        }
        intersections.sort(function (a, b) {
            return a.projPt - b.projPt;
        });
        var splitPt0 = intersections[0];
        var splitPt1 = intersections[intersections.length - 1];
        if (splitPt1.idx < splitPt0.idx) {
            var tmp = splitPt0;
            splitPt0 = splitPt1;
            splitPt1 = tmp;
        }
        var splitPt0Arr = [splitPt0.pt.x, splitPt0.pt.y];
        var splitPt1Arr = [splitPt1.pt.x, splitPt1.pt.y];
        var newPolyA = [splitPt0Arr];
        var newPolyB = [splitPt1Arr];
        for (var i = splitPt0.idx + 1; i <= splitPt1.idx; i++) {
            addToPoly(newPolyA, points[i].slice());
        }
        addToPoly(newPolyA, splitPt1Arr);
        addToPoly(newPolyA, splitPt0Arr);
        for (var i = splitPt1.idx + 1; i <= splitPt0.idx + len; i++) {
            addToPoly(newPolyB, points[i % len].slice());
        }
        addToPoly(newPolyB, splitPt0Arr);
        addToPoly(newPolyB, splitPt1Arr);
        return [{
                points: newPolyA
            }, {
                points: newPolyB
            }];
    }
    function binaryDividePolygon(polygonShape) {
        var points = polygonShape.points;
        var min = [];
        var max = [];
        fromPoints(points, min, max);
        var boundingRect = new BoundingRect(min[0], min[1], max[0] - min[0], max[1] - min[1]);
        var width = boundingRect.width;
        var height = boundingRect.height;
        var x = boundingRect.x;
        var y = boundingRect.y;
        var pt0 = new Point();
        var pt1 = new Point();
        if (width > height) {
            pt0.x = pt1.x = x + width / 2;
            pt0.y = y;
            pt1.y = y + height;
        }
        else {
            pt0.y = pt1.y = y + height / 2;
            pt0.x = x;
            pt1.x = x + width;
        }
        return splitPolygonByLine(points, pt0, pt1);
    }
    function binaryDivideRecursive(divider, shape, count, out) {
        if (count === 1) {
            out.push(shape);
        }
        else {
            var mid = Math.floor(count / 2);
            var sub = divider(shape);
            binaryDivideRecursive(divider, sub[0], mid, out);
            binaryDivideRecursive(divider, sub[1], count - mid, out);
        }
        return out;
    }
    function clone$4(path, count) {
        var paths = [];
        for (var i = 0; i < count; i++) {
            paths.push(clonePath(path));
        }
        return paths;
    }
    function copyPathProps(source, target) {
        target.setStyle(source.style);
        target.z = source.z;
        target.z2 = source.z2;
        target.zlevel = source.zlevel;
    }
    function polygonConvert(points) {
        var out = [];
        for (var i = 0; i < points.length;) {
            out.push([points[i++], points[i++]]);
        }
        return out;
    }
    function split(path, count) {
        var outShapes = [];
        var shape = path.shape;
        var OutShapeCtor;
        switch (path.type) {
            case 'rect':
                divideRect(shape, count, outShapes);
                OutShapeCtor = Rect;
                break;
            case 'sector':
                divideSector(shape, count, outShapes);
                OutShapeCtor = Sector;
                break;
            case 'circle':
                divideSector({
                    r0: 0, r: shape.r, startAngle: 0, endAngle: Math.PI * 2,
                    cx: shape.cx, cy: shape.cy
                }, count, outShapes);
                OutShapeCtor = Sector;
                break;
            default:
                var m = path.getComputedTransform();
                var scale = m ? Math.sqrt(Math.max(m[0] * m[0] + m[1] * m[1], m[2] * m[2] + m[3] * m[3])) : 1;
                var polygons = map(pathToPolygons(path.getUpdatedPathProxy(), scale), function (poly) { return polygonConvert(poly); });
                var polygonCount = polygons.length;
                if (polygonCount === 0) {
                    binaryDivideRecursive(binaryDividePolygon, {
                        points: polygons[0]
                    }, count, outShapes);
                }
                else if (polygonCount === count) {
                    for (var i = 0; i < polygonCount; i++) {
                        outShapes.push({
                            points: polygons[i]
                        });
                    }
                }
                else {
                    var totalArea_1 = 0;
                    var items = map(polygons, function (poly) {
                        var min = [];
                        var max = [];
                        fromPoints(poly, min, max);
                        var area = (max[1] - min[1]) * (max[0] - min[0]);
                        totalArea_1 += area;
                        return { poly: poly, area: area };
                    });
                    items.sort(function (a, b) { return b.area - a.area; });
                    var left = count;
                    for (var i = 0; i < polygonCount; i++) {
                        var item = items[i];
                        if (left <= 0) {
                            break;
                        }
                        var selfCount = i === polygonCount - 1
                            ? left
                            : Math.ceil(item.area / totalArea_1 * count);
                        if (selfCount < 0) {
                            continue;
                        }
                        binaryDivideRecursive(binaryDividePolygon, {
                            points: item.poly
                        }, selfCount, outShapes);
                        left -= selfCount;
                    }
                }
                OutShapeCtor = Polygon;
                break;
        }
        if (!OutShapeCtor) {
            return clone$4(path, count);
        }
        var out = [];
        for (var i = 0; i < outShapes.length; i++) {
            var subPath = new OutShapeCtor();
            subPath.setShape(outShapes[i]);
            copyPathProps(path, subPath);
            out.push(subPath);
        }
        return out;
    }

    function alignSubpath(subpath1, subpath2) {
        var len1 = subpath1.length;
        var len2 = subpath2.length;
        if (len1 === len2) {
            return [subpath1, subpath2];
        }
        var tmpSegX = [];
        var tmpSegY = [];
        var shorterPath = len1 < len2 ? subpath1 : subpath2;
        var shorterLen = Math.min(len1, len2);
        var diff = Math.abs(len2 - len1) / 6;
        var shorterBezierCount = (shorterLen - 2) / 6;
        var eachCurveSubDivCount = Math.ceil(diff / shorterBezierCount) + 1;
        var newSubpath = [shorterPath[0], shorterPath[1]];
        var remained = diff;
        for (var i = 2; i < shorterLen;) {
            var x0 = shorterPath[i - 2];
            var y0 = shorterPath[i - 1];
            var x1 = shorterPath[i++];
            var y1 = shorterPath[i++];
            var x2 = shorterPath[i++];
            var y2 = shorterPath[i++];
            var x3 = shorterPath[i++];
            var y3 = shorterPath[i++];
            if (remained <= 0) {
                newSubpath.push(x1, y1, x2, y2, x3, y3);
                continue;
            }
            var actualSubDivCount = Math.min(remained, eachCurveSubDivCount - 1) + 1;
            for (var k = 1; k <= actualSubDivCount; k++) {
                var p = k / actualSubDivCount;
                cubicSubdivide(x0, x1, x2, x3, p, tmpSegX);
                cubicSubdivide(y0, y1, y2, y3, p, tmpSegY);
                x0 = tmpSegX[3];
                y0 = tmpSegY[3];
                newSubpath.push(tmpSegX[1], tmpSegY[1], tmpSegX[2], tmpSegY[2], x0, y0);
                x1 = tmpSegX[5];
                y1 = tmpSegY[5];
                x2 = tmpSegX[6];
                y2 = tmpSegY[6];
            }
            remained -= actualSubDivCount - 1;
        }
        return shorterPath === subpath1 ? [newSubpath, subpath2] : [subpath1, newSubpath];
    }
    function createSubpath(lastSubpathSubpath, otherSubpath) {
        var len = lastSubpathSubpath.length;
        var lastX = lastSubpathSubpath[len - 2];
        var lastY = lastSubpathSubpath[len - 1];
        var newSubpath = [];
        for (var i = 0; i < otherSubpath.length;) {
            newSubpath[i++] = lastX;
            newSubpath[i++] = lastY;
        }
        return newSubpath;
    }
    function alignBezierCurves(array1, array2) {
        var _a;
        var lastSubpath1;
        var lastSubpath2;
        var newArray1 = [];
        var newArray2 = [];
        for (var i = 0; i < Math.max(array1.length, array2.length); i++) {
            var subpath1 = array1[i];
            var subpath2 = array2[i];
            var newSubpath1 = void 0;
            var newSubpath2 = void 0;
            if (!subpath1) {
                newSubpath1 = createSubpath(lastSubpath1 || subpath2, subpath2);
                newSubpath2 = subpath2;
            }
            else if (!subpath2) {
                newSubpath2 = createSubpath(lastSubpath2 || subpath1, subpath1);
                newSubpath1 = subpath1;
            }
            else {
                _a = alignSubpath(subpath1, subpath2), newSubpath1 = _a[0], newSubpath2 = _a[1];
                lastSubpath1 = newSubpath1;
                lastSubpath2 = newSubpath2;
            }
            newArray1.push(newSubpath1);
            newArray2.push(newSubpath2);
        }
        return [newArray1, newArray2];
    }
    function centroid$1(array) {
        var signedArea = 0;
        var cx = 0;
        var cy = 0;
        var len = array.length;
        for (var i = 0, j = len - 2; i < len; j = i, i += 2) {
            var x0 = array[j];
            var y0 = array[j + 1];
            var x1 = array[i];
            var y1 = array[i + 1];
            var a = x0 * y1 - x1 * y0;
            signedArea += a;
            cx += (x0 + x1) * a;
            cy += (y0 + y1) * a;
        }
        if (signedArea === 0) {
            return [array[0] || 0, array[1] || 0];
        }
        return [cx / signedArea / 3, cy / signedArea / 3, signedArea];
    }
    function findBestRingOffset(fromSubBeziers, toSubBeziers, fromCp, toCp) {
        var bezierCount = (fromSubBeziers.length - 2) / 6;
        var bestScore = Infinity;
        var bestOffset = 0;
        var len = fromSubBeziers.length;
        var len2 = len - 2;
        for (var offset = 0; offset < bezierCount; offset++) {
            var cursorOffset = offset * 6;
            var score = 0;
            for (var k = 0; k < len; k += 2) {
                var idx = k === 0 ? cursorOffset : ((cursorOffset + k - 2) % len2 + 2);
                var x0 = fromSubBeziers[idx] - fromCp[0];
                var y0 = fromSubBeziers[idx + 1] - fromCp[1];
                var x1 = toSubBeziers[k] - toCp[0];
                var y1 = toSubBeziers[k + 1] - toCp[1];
                var dx = x1 - x0;
                var dy = y1 - y0;
                score += dx * dx + dy * dy;
            }
            if (score < bestScore) {
                bestScore = score;
                bestOffset = offset;
            }
        }
        return bestOffset;
    }
    function reverse(array) {
        var newArr = [];
        var len = array.length;
        for (var i = 0; i < len; i += 2) {
            newArr[i] = array[len - i - 2];
            newArr[i + 1] = array[len - i - 1];
        }
        return newArr;
    }
    function findBestMorphingRotation(fromArr, toArr, searchAngleIteration, searchAngleRange) {
        var result = [];
        var fromNeedsReverse;
        for (var i = 0; i < fromArr.length; i++) {
            var fromSubpathBezier = fromArr[i];
            var toSubpathBezier = toArr[i];
            var fromCp = centroid$1(fromSubpathBezier);
            var toCp = centroid$1(toSubpathBezier);
            if (fromNeedsReverse == null) {
                fromNeedsReverse = fromCp[2] < 0 !== toCp[2] < 0;
            }
            var newFromSubpathBezier = [];
            var newToSubpathBezier = [];
            var bestAngle = 0;
            var bestScore = Infinity;
            var tmpArr = [];
            var len = fromSubpathBezier.length;
            if (fromNeedsReverse) {
                fromSubpathBezier = reverse(fromSubpathBezier);
            }
            var offset = findBestRingOffset(fromSubpathBezier, toSubpathBezier, fromCp, toCp) * 6;
            var len2 = len - 2;
            for (var k = 0; k < len2; k += 2) {
                var idx = (offset + k) % len2 + 2;
                newFromSubpathBezier[k + 2] = fromSubpathBezier[idx] - fromCp[0];
                newFromSubpathBezier[k + 3] = fromSubpathBezier[idx + 1] - fromCp[1];
            }
            newFromSubpathBezier[0] = fromSubpathBezier[offset] - fromCp[0];
            newFromSubpathBezier[1] = fromSubpathBezier[offset + 1] - fromCp[1];
            if (searchAngleIteration > 0) {
                var step = searchAngleRange / searchAngleIteration;
                for (var angle = -searchAngleRange / 2; angle <= searchAngleRange / 2; angle += step) {
                    var sa = Math.sin(angle);
                    var ca = Math.cos(angle);
                    var score = 0;
                    for (var k = 0; k < fromSubpathBezier.length; k += 2) {
                        var x0 = newFromSubpathBezier[k];
                        var y0 = newFromSubpathBezier[k + 1];
                        var x1 = toSubpathBezier[k] - toCp[0];
                        var y1 = toSubpathBezier[k + 1] - toCp[1];
                        var newX1 = x1 * ca - y1 * sa;
                        var newY1 = x1 * sa + y1 * ca;
                        tmpArr[k] = newX1;
                        tmpArr[k + 1] = newY1;
                        var dx = newX1 - x0;
                        var dy = newY1 - y0;
                        score += dx * dx + dy * dy;
                    }
                    if (score < bestScore) {
                        bestScore = score;
                        bestAngle = angle;
                        for (var m = 0; m < tmpArr.length; m++) {
                            newToSubpathBezier[m] = tmpArr[m];
                        }
                    }
                }
            }
            else {
                for (var i_1 = 0; i_1 < len; i_1 += 2) {
                    newToSubpathBezier[i_1] = toSubpathBezier[i_1] - toCp[0];
                    newToSubpathBezier[i_1 + 1] = toSubpathBezier[i_1 + 1] - toCp[1];
                }
            }
            result.push({
                from: newFromSubpathBezier,
                to: newToSubpathBezier,
                fromCp: fromCp,
                toCp: toCp,
                rotation: -bestAngle
            });
        }
        return result;
    }
    function isCombineMorphing(path) {
        return path.__isCombineMorphing;
    }
    var SAVED_METHOD_PREFIX = '__mOriginal_';
    function saveAndModifyMethod(obj, methodName, modifiers) {
        var savedMethodName = SAVED_METHOD_PREFIX + methodName;
        var originalMethod = obj[savedMethodName] || obj[methodName];
        if (!obj[savedMethodName]) {
            obj[savedMethodName] = obj[methodName];
        }
        var replace = modifiers.replace;
        var after = modifiers.after;
        var before = modifiers.before;
        obj[methodName] = function () {
            var args = arguments;
            var res;
            before && before.apply(this, args);
            if (replace) {
                res = replace.apply(this, args);
            }
            else {
                res = originalMethod.apply(this, args);
            }
            after && after.apply(this, args);
            return res;
        };
    }
    function restoreMethod(obj, methodName) {
        var savedMethodName = SAVED_METHOD_PREFIX + methodName;
        if (obj[savedMethodName]) {
            obj[methodName] = obj[savedMethodName];
            obj[savedMethodName] = null;
        }
    }
    function applyTransformOnBeziers(bezierCurves, mm) {
        for (var i = 0; i < bezierCurves.length; i++) {
            var subBeziers = bezierCurves[i];
            for (var k = 0; k < subBeziers.length;) {
                var x = subBeziers[k];
                var y = subBeziers[k + 1];
                subBeziers[k++] = mm[0] * x + mm[2] * y + mm[4];
                subBeziers[k++] = mm[1] * x + mm[3] * y + mm[5];
            }
        }
    }
    function prepareMorphPath(fromPath, toPath) {
        var fromPathProxy = fromPath.getUpdatedPathProxy();
        var toPathProxy = toPath.getUpdatedPathProxy();
        var _a = alignBezierCurves(pathToBezierCurves(fromPathProxy), pathToBezierCurves(toPathProxy)), fromBezierCurves = _a[0], toBezierCurves = _a[1];
        var fromPathTransform = fromPath.getComputedTransform();
        var toPathTransform = toPath.getComputedTransform();
        function updateIdentityTransform() {
            this.transform = null;
        }
        fromPathTransform && applyTransformOnBeziers(fromBezierCurves, fromPathTransform);
        toPathTransform && applyTransformOnBeziers(toBezierCurves, toPathTransform);
        saveAndModifyMethod(toPath, 'updateTransform', { replace: updateIdentityTransform });
        toPath.transform = null;
        var morphingData = findBestMorphingRotation(fromBezierCurves, toBezierCurves, 10, Math.PI);
        var tmpArr = [];
        saveAndModifyMethod(toPath, 'buildPath', { replace: function (path) {
                var t = toPath.__morphT;
                var onet = 1 - t;
                var newCp = [];
                for (var i = 0; i < morphingData.length; i++) {
                    var item = morphingData[i];
                    var from = item.from;
                    var to = item.to;
                    var angle = item.rotation * t;
                    var fromCp = item.fromCp;
                    var toCp = item.toCp;
                    var sa = Math.sin(angle);
                    var ca = Math.cos(angle);
                    lerp(newCp, fromCp, toCp, t);
                    for (var m = 0; m < from.length; m += 2) {
                        var x0_1 = from[m];
                        var y0_1 = from[m + 1];
                        var x1 = to[m];
                        var y1 = to[m + 1];
                        var x = x0_1 * onet + x1 * t;
                        var y = y0_1 * onet + y1 * t;
                        tmpArr[m] = (x * ca - y * sa) + newCp[0];
                        tmpArr[m + 1] = (x * sa + y * ca) + newCp[1];
                    }
                    var x0 = tmpArr[0];
                    var y0 = tmpArr[1];
                    path.moveTo(x0, y0);
                    for (var m = 2; m < from.length;) {
                        var x1 = tmpArr[m++];
                        var y1 = tmpArr[m++];
                        var x2 = tmpArr[m++];
                        var y2 = tmpArr[m++];
                        var x3 = tmpArr[m++];
                        var y3 = tmpArr[m++];
                        if (x0 === x1 && y0 === y1 && x2 === x3 && y2 === y3) {
                            path.lineTo(x3, y3);
                        }
                        else {
                            path.bezierCurveTo(x1, y1, x2, y2, x3, y3);
                        }
                        x0 = x3;
                        y0 = y3;
                    }
                }
            } });
    }
    function morphPath(fromPath, toPath, animationOpts) {
        if (!fromPath || !toPath) {
            return toPath;
        }
        var oldDone = animationOpts.done;
        var oldDuring = animationOpts.during;
        prepareMorphPath(fromPath, toPath);
        toPath.__morphT = 0;
        function restoreToPath() {
            restoreMethod(toPath, 'buildPath');
            restoreMethod(toPath, 'updateTransform');
            toPath.__morphT = -1;
            toPath.createPathProxy();
            toPath.dirtyShape();
        }
        toPath.animateTo({
            __morphT: 1
        }, defaults({
            during: function (p) {
                toPath.dirtyShape();
                oldDuring && oldDuring(p);
            },
            done: function () {
                restoreToPath();
                oldDone && oldDone();
            }
        }, animationOpts));
        return toPath;
    }
    function hilbert(x, y, minX, minY, maxX, maxY) {
        var bits = 16;
        x = (maxX === minX) ? 0 : Math.round(32767 * (x - minX) / (maxX - minX));
        y = (maxY === minY) ? 0 : Math.round(32767 * (y - minY) / (maxY - minY));
        var d = 0;
        var tmp;
        for (var s = (1 << bits) / 2; s > 0; s /= 2) {
            var rx = 0;
            var ry = 0;
            if ((x & s) > 0) {
                rx = 1;
            }
            if ((y & s) > 0) {
                ry = 1;
            }
            d += s * s * ((3 * rx) ^ ry);
            if (ry === 0) {
                if (rx === 1) {
                    x = s - 1 - x;
                    y = s - 1 - y;
                }
                tmp = x;
                x = y;
                y = tmp;
            }
        }
        return d;
    }
    function sortPaths(pathList) {
        var xMin = Infinity;
        var yMin = Infinity;
        var xMax = -Infinity;
        var yMax = -Infinity;
        var cps = map(pathList, function (path) {
            var rect = path.getBoundingRect();
            var m = path.getComputedTransform();
            var x = rect.x + rect.width / 2 + (m ? m[4] : 0);
            var y = rect.y + rect.height / 2 + (m ? m[5] : 0);
            xMin = Math.min(x, xMin);
            yMin = Math.min(y, yMin);
            xMax = Math.max(x, xMax);
            yMax = Math.max(y, yMax);
            return [x, y];
        });
        var items = map(cps, function (cp, idx) {
            return {
                cp: cp,
                z: hilbert(cp[0], cp[1], xMin, yMin, xMax, yMax),
                path: pathList[idx]
            };
        });
        return items.sort(function (a, b) { return a.z - b.z; }).map(function (item) { return item.path; });
    }
    function defaultDividePath(param) {
        return split(param.path, param.count);
    }
    function createEmptyReturn() {
        return {
            fromIndividuals: [],
            toIndividuals: [],
            count: 0
        };
    }
    function combineMorph(fromList, toPath, animationOpts) {
        var fromPathList = [];
        function addFromPath(fromList) {
            for (var i = 0; i < fromList.length; i++) {
                var from = fromList[i];
                if (isCombineMorphing(from)) {
                    addFromPath(from.childrenRef());
                }
                else if (from instanceof Path) {
                    fromPathList.push(from);
                }
            }
        }
        addFromPath(fromList);
        var separateCount = fromPathList.length;
        if (!separateCount) {
            return createEmptyReturn();
        }
        var dividePath = animationOpts.dividePath || defaultDividePath;
        var toSubPathList = dividePath({
            path: toPath, count: separateCount
        });
        if (toSubPathList.length !== separateCount) {
            console.error('Invalid morphing: unmatched splitted path');
            return createEmptyReturn();
        }
        fromPathList = sortPaths(fromPathList);
        toSubPathList = sortPaths(toSubPathList);
        var oldDone = animationOpts.done;
        var oldDuring = animationOpts.during;
        var individualDelay = animationOpts.individualDelay;
        var identityTransform = new Transformable();
        for (var i = 0; i < separateCount; i++) {
            var from = fromPathList[i];
            var to = toSubPathList[i];
            to.parent = toPath;
            to.copyTransform(identityTransform);
            if (!individualDelay) {
                prepareMorphPath(from, to);
            }
        }
        toPath.__isCombineMorphing = true;
        toPath.childrenRef = function () {
            return toSubPathList;
        };
        function addToSubPathListToZr(zr) {
            for (var i = 0; i < toSubPathList.length; i++) {
                toSubPathList[i].addSelfToZr(zr);
            }
        }
        saveAndModifyMethod(toPath, 'addSelfToZr', {
            after: function (zr) {
                addToSubPathListToZr(zr);
            }
        });
        saveAndModifyMethod(toPath, 'removeSelfFromZr', {
            after: function (zr) {
                for (var i = 0; i < toSubPathList.length; i++) {
                    toSubPathList[i].removeSelfFromZr(zr);
                }
            }
        });
        function restoreToPath() {
            toPath.__isCombineMorphing = false;
            toPath.__morphT = -1;
            toPath.childrenRef = null;
            restoreMethod(toPath, 'addSelfToZr');
            restoreMethod(toPath, 'removeSelfFromZr');
        }
        var toLen = toSubPathList.length;
        if (individualDelay) {
            var animating_1 = toLen;
            var eachDone = function () {
                animating_1--;
                if (animating_1 === 0) {
                    restoreToPath();
                    oldDone && oldDone();
                }
            };
            for (var i = 0; i < toLen; i++) {
                var indivdualAnimationOpts = individualDelay ? defaults({
                    delay: (animationOpts.delay || 0) + individualDelay(i, toLen, fromPathList[i], toSubPathList[i]),
                    done: eachDone
                }, animationOpts) : animationOpts;
                morphPath(fromPathList[i], toSubPathList[i], indivdualAnimationOpts);
            }
        }
        else {
            toPath.__morphT = 0;
            toPath.animateTo({
                __morphT: 1
            }, defaults({
                during: function (p) {
                    for (var i = 0; i < toLen; i++) {
                        var child = toSubPathList[i];
                        child.__morphT = toPath.__morphT;
                        child.dirtyShape();
                    }
                    oldDuring && oldDuring(p);
                },
                done: function () {
                    restoreToPath();
                    for (var i = 0; i < fromList.length; i++) {
                        restoreMethod(fromList[i], 'updateTransform');
                    }
                    oldDone && oldDone();
                }
            }, animationOpts));
        }
        if (toPath.__zr) {
            addToSubPathListToZr(toPath.__zr);
        }
        return {
            fromIndividuals: fromPathList,
            toIndividuals: toSubPathList,
            count: toLen
        };
    }
    function separateMorph(fromPath, toPathList, animationOpts) {
        var toLen = toPathList.length;
        var fromPathList = [];
        var dividePath = animationOpts.dividePath || defaultDividePath;
        function addFromPath(fromList) {
            for (var i = 0; i < fromList.length; i++) {
                var from = fromList[i];
                if (isCombineMorphing(from)) {
                    addFromPath(from.childrenRef());
                }
                else if (from instanceof Path) {
                    fromPathList.push(from);
                }
            }
        }
        if (isCombineMorphing(fromPath)) {
            addFromPath(fromPath.childrenRef());
            var fromLen = fromPathList.length;
            if (fromLen < toLen) {
                var k = 0;
                for (var i = fromLen; i < toLen; i++) {
                    fromPathList.push(clonePath(fromPathList[k++ % fromLen]));
                }
            }
            fromPathList.length = toLen;
        }
        else {
            fromPathList = dividePath({ path: fromPath, count: toLen });
            var fromPathTransform = fromPath.getComputedTransform();
            for (var i = 0; i < fromPathList.length; i++) {
                fromPathList[i].setLocalTransform(fromPathTransform);
            }
            if (fromPathList.length !== toLen) {
                console.error('Invalid morphing: unmatched splitted path');
                return createEmptyReturn();
            }
        }
        fromPathList = sortPaths(fromPathList);
        toPathList = sortPaths(toPathList);
        var individualDelay = animationOpts.individualDelay;
        for (var i = 0; i < toLen; i++) {
            var indivdualAnimationOpts = individualDelay ? defaults({
                delay: (animationOpts.delay || 0) + individualDelay(i, toLen, fromPathList[i], toPathList[i])
            }, animationOpts) : animationOpts;
            morphPath(fromPathList[i], toPathList[i], indivdualAnimationOpts);
        }
        return {
            fromIndividuals: fromPathList,
            toIndividuals: toPathList,
            count: toPathList.length
        };
    }

    function isMultiple(elements) {
      return isArray(elements[0]);
    }

    function prepareMorphBatches(one, many) {
      var batches = [];
      var batchCount = one.length;

      for (var i = 0; i < batchCount; i++) {
        batches.push({
          one: one[i],
          many: []
        });
      }

      for (var i = 0; i < many.length; i++) {
        var len = many[i].length;
        var k = void 0;

        for (k = 0; k < len; k++) {
          batches[k % batchCount].many.push(many[i][k]);
        }
      }

      var off = 0; // If one has more paths than each one of many. average them.

      for (var i = batchCount - 1; i >= 0; i--) {
        if (!batches[i].many.length) {
          var moveFrom = batches[off].many;

          if (moveFrom.length <= 1) {
            // Not enough
            // Start from the first one.
            if (off) {
              off = 0;
            } else {
              return batches;
            }
          }

          var len = moveFrom.length;
          var mid = Math.ceil(len / 2);
          batches[i].many = moveFrom.slice(mid, len);
          batches[off].many = moveFrom.slice(0, mid);
          off++;
        }
      }

      return batches;
    }

    var pathDividers = {
      clone: function (params) {
        var ret = []; // Fitting the alpha

        var approxOpacity = 1 - Math.pow(1 - params.path.style.opacity, 1 / params.count);

        for (var i = 0; i < params.count; i++) {
          var cloned = clonePath(params.path);
          cloned.setStyle('opacity', approxOpacity);
          ret.push(cloned);
        }

        return ret;
      },
      // Use the default divider
      split: null
    };
    function applyMorphAnimation(from, to, divideShape, seriesModel, dataIndex, animateOtherProps) {
      if (!from.length || !to.length) {
        return;
      }

      var updateAnimationCfg = getAnimationConfig('update', seriesModel, dataIndex);

      if (!(updateAnimationCfg && updateAnimationCfg.duration > 0)) {
        return;
      }

      var animationDelay = seriesModel.getModel('universalTransition').get('delay');
      var animationCfg = Object.assign({
        // Need to setToFinal so the further calculation based on the style can be correct.
        // Like emphasis color.
        setToFinal: true
      }, updateAnimationCfg);
      var many;
      var one;

      if (isMultiple(from)) {
        // manyToOne
        many = from;
        one = to;
      }

      if (isMultiple(to)) {
        // oneToMany
        many = to;
        one = from;
      }

      function morphOneBatch(batch, fromIsMany, animateIndex, animateCount, forceManyOne) {
        var batchMany = batch.many;
        var batchOne = batch.one;

        if (batchMany.length === 1 && !forceManyOne) {
          // Is one to one
          var batchFrom = fromIsMany ? batchMany[0] : batchOne;
          var batchTo = fromIsMany ? batchOne : batchMany[0];

          if (isCombineMorphing(batchFrom)) {
            // Keep doing combine animation.
            morphOneBatch({
              many: [batchFrom],
              one: batchTo
            }, true, animateIndex, animateCount, true);
          } else {
            var individualAnimationCfg = animationDelay ? defaults({
              delay: animationDelay(animateIndex, animateCount)
            }, animationCfg) : animationCfg;
            morphPath(batchFrom, batchTo, individualAnimationCfg);
            animateOtherProps(batchFrom, batchTo, batchFrom, batchTo, individualAnimationCfg);
          }
        } else {
          var separateAnimationCfg = defaults({
            dividePath: pathDividers[divideShape],
            individualDelay: animationDelay && function (idx, count, fromPath, toPath) {
              return animationDelay(idx + animateIndex, animateCount);
            }
          }, animationCfg);

          var _a = fromIsMany ? combineMorph(batchMany, batchOne, separateAnimationCfg) : separateMorph(batchOne, batchMany, separateAnimationCfg),
              fromIndividuals = _a.fromIndividuals,
              toIndividuals = _a.toIndividuals;

          var count = fromIndividuals.length;

          for (var k = 0; k < count; k++) {
            var individualAnimationCfg = animationDelay ? defaults({
              delay: animationDelay(k, count)
            }, animationCfg) : animationCfg;
            animateOtherProps(fromIndividuals[k], toIndividuals[k], fromIsMany ? batchMany[k] : batch.one, fromIsMany ? batch.one : batchMany[k], individualAnimationCfg);
          }
        }
      }

      var fromIsMany = many ? many === from // Is one to one. If the path number not match. also needs do merge and separate morphing.
      : from.length > to.length;
      var morphBatches = many ? prepareMorphBatches(one, many) : prepareMorphBatches(fromIsMany ? to : from, [fromIsMany ? from : to]);
      var animateCount = 0;

      for (var i = 0; i < morphBatches.length; i++) {
        animateCount += morphBatches[i].many.length;
      }

      var animateIndex = 0;

      for (var i = 0; i < morphBatches.length; i++) {
        morphOneBatch(morphBatches[i], fromIsMany, animateIndex, animateCount);
        animateIndex += morphBatches[i].many.length;
      }
    }
    function getPathList(elements) {
      if (!elements) {
        return [];
      }

      if (isArray(elements)) {
        var pathList_1 = [];

        for (var i = 0; i < elements.length; i++) {
          pathList_1.push(getPathList(elements[i]));
        }

        return pathList_1;
      }

      var pathList = [];
      elements.traverse(function (el) {
        if (el instanceof Path && !el.disableMorphing && !el.invisible && !el.ignore) {
          pathList.push(el);
        }
      });
      return pathList;
    }

    var DATA_COUNT_THRESHOLD = 1e4;
    var getUniversalTransitionGlobalStore = makeInner();

    function getGroupIdDimension(data) {
      var dimensions = data.dimensions;

      for (var i = 0; i < dimensions.length; i++) {
        var dimInfo = data.getDimensionInfo(dimensions[i]);

        if (dimInfo && dimInfo.otherDims.itemGroupId === 0) {
          return dimensions[i];
        }
      }
    }

    function flattenDataDiffItems(list) {
      var items = [];
      each(list, function (seriesInfo) {
        var data = seriesInfo.data;

        if (data.count() > DATA_COUNT_THRESHOLD) {
          if ("development" !== 'production') {
            warn('Universal transition is disabled on large data > 10k.');
          }

          return;
        }

        var indices = data.getIndices();
        var groupDim = getGroupIdDimension(data);

        for (var dataIndex = 0; dataIndex < indices.length; dataIndex++) {
          items.push({
            dataGroupId: seriesInfo.dataGroupId,
            data: data,
            dim: seriesInfo.dim || groupDim,
            divide: seriesInfo.divide,
            dataIndex: dataIndex
          });
        }
      });
      return items;
    }

    function fadeInElement(newEl, newSeries, newIndex) {
      newEl.traverse(function (el) {
        if (el instanceof Path) {
          // TODO use fade in animation for target element.
          initProps(el, {
            style: {
              opacity: 0
            }
          }, newSeries, {
            dataIndex: newIndex,
            isFrom: true
          });
        }
      });
    }

    function removeEl$1(el) {
      if (el.parent) {
        // Bake parent transform to element.
        // So it can still have proper transform to transition after it's removed.
        var computedTransform = el.getComputedTransform();
        el.setLocalTransform(computedTransform);
        el.parent.remove(el);
      }
    }

    function stopAnimation(el) {
      el.stopAnimation();

      if (el.isGroup) {
        el.traverse(function (child) {
          child.stopAnimation();
        });
      }
    }

    function animateElementStyles(el, dataIndex, seriesModel) {
      var animationConfig = getAnimationConfig('update', seriesModel, dataIndex);
      animationConfig && el.traverse(function (child) {
        if (child instanceof Displayable) {
          var oldStyle = getOldStyle(child);

          if (oldStyle) {
            child.animateFrom({
              style: oldStyle
            }, animationConfig);
          }
        }
      });
    }

    function isAllIdSame(oldDiffItems, newDiffItems) {
      var len = oldDiffItems.length;

      if (len !== newDiffItems.length) {
        return false;
      }

      for (var i = 0; i < len; i++) {
        var oldItem = oldDiffItems[i];
        var newItem = newDiffItems[i];

        if (oldItem.data.getId(oldItem.dataIndex) !== newItem.data.getId(newItem.dataIndex)) {
          return false;
        }
      }

      return true;
    }

    function transitionBetween(oldList, newList, api) {
      var oldDiffItems = flattenDataDiffItems(oldList);
      var newDiffItems = flattenDataDiffItems(newList);

      function updateMorphingPathProps(from, to, rawFrom, rawTo, animationCfg) {
        if (rawFrom || from) {
          to.animateFrom({
            style: rawFrom && rawFrom !== from ? // dividingMethod like clone may override the style(opacity)
            // So extend it to raw style.
            extend(extend({}, rawFrom.style), from.style) : from.style
          }, animationCfg);
        }
      }

      function findKeyDim(items) {
        for (var i = 0; i < items.length; i++) {
          if (items[i].dim) {
            return items[i].dim;
          }
        }
      }

      var oldKeyDim = findKeyDim(oldDiffItems);
      var newKeyDim = findKeyDim(newDiffItems);
      var hasMorphAnimation = false;

      function createKeyGetter(isOld, onlyGetId) {
        return function (diffItem) {
          var data = diffItem.data;
          var dataIndex = diffItem.dataIndex; // TODO if specified dim

          if (onlyGetId) {
            return data.getId(dataIndex);
          } // Use group id as transition key by default.
          // So we can achieve multiple to multiple animation like drilldown / up naturally.
          // If group id not exits. Use id instead. If so, only one to one transition will be applied.


          var dataGroupId = diffItem.dataGroupId; // If specified key dimension(itemGroupId by default). Use this same dimension from other data.
          // PENDING: If only use key dimension of newData.

          var keyDim = isOld ? oldKeyDim || newKeyDim : newKeyDim || oldKeyDim;
          var dimInfo = keyDim && data.getDimensionInfo(keyDim);
          var dimOrdinalMeta = dimInfo && dimInfo.ordinalMeta;

          if (dimInfo) {
            // Get from encode.itemGroupId.
            var key = data.get(dimInfo.name, dataIndex);

            if (dimOrdinalMeta) {
              return dimOrdinalMeta.categories[key] || key + '';
            }

            return key + '';
          } // Get groupId from raw item. { groupId: '' }


          var itemVal = data.getRawDataItem(dataIndex);

          if (itemVal && itemVal.groupId) {
            return itemVal.groupId + '';
          }

          return dataGroupId || data.getId(dataIndex);
        };
      } // Use id if it's very likely to be an one to one animation
      // It's more robust than groupId
      // TODO Check if key dimension is specified.


      var useId = isAllIdSame(oldDiffItems, newDiffItems);
      var isElementStillInChart = {};

      if (!useId) {
        // We may have different diff strategy with basicTransition if we use other dimension as key.
        // If so, we can't simply check if oldEl is same with newEl. We need a map to check if oldEl is still being used in the new chart.
        // We can't use the elements that already being morphed. Let it keep it's original basic transition.
        for (var i = 0; i < newDiffItems.length; i++) {
          var newItem = newDiffItems[i];
          var el = newItem.data.getItemGraphicEl(newItem.dataIndex);

          if (el) {
            isElementStillInChart[el.id] = true;
          }
        }
      }

      function updateOneToOne(newIndex, oldIndex) {
        var oldItem = oldDiffItems[oldIndex];
        var newItem = newDiffItems[newIndex];
        var newSeries = newItem.data.hostModel; // TODO Mark this elements is morphed and don't morph them anymore

        var oldEl = oldItem.data.getItemGraphicEl(oldItem.dataIndex);
        var newEl = newItem.data.getItemGraphicEl(newItem.dataIndex); // Can't handle same elements.

        if (oldEl === newEl) {
          newEl && animateElementStyles(newEl, newItem.dataIndex, newSeries);
          return;
        }

        if ( // We can't use the elements that already being morphed
        oldEl && isElementStillInChart[oldEl.id]) {
          return;
        }

        if (newEl) {
          // TODO: If keep animating the group in case
          // some of the elements don't want to be morphed.
          // TODO Label?
          stopAnimation(newEl);

          if (oldEl) {
            stopAnimation(oldEl); // If old element is doing leaving animation. stop it and remove it immediately.

            removeEl$1(oldEl);
            hasMorphAnimation = true;
            applyMorphAnimation(getPathList(oldEl), getPathList(newEl), newItem.divide, newSeries, newIndex, updateMorphingPathProps);
          } else {
            fadeInElement(newEl, newSeries, newIndex);
          }
        } // else keep oldEl leaving animation.

      }

      new DataDiffer(oldDiffItems, newDiffItems, createKeyGetter(true, useId), createKeyGetter(false, useId), null, 'multiple').update(updateOneToOne).updateManyToOne(function (newIndex, oldIndices) {
        var newItem = newDiffItems[newIndex];
        var newData = newItem.data;
        var newSeries = newData.hostModel;
        var newEl = newData.getItemGraphicEl(newItem.dataIndex);
        var oldElsList = filter(map(oldIndices, function (idx) {
          return oldDiffItems[idx].data.getItemGraphicEl(oldDiffItems[idx].dataIndex);
        }), function (oldEl) {
          return oldEl && oldEl !== newEl && !isElementStillInChart[oldEl.id];
        });

        if (newEl) {
          stopAnimation(newEl);

          if (oldElsList.length) {
            // If old element is doing leaving animation. stop it and remove it immediately.
            each(oldElsList, function (oldEl) {
              stopAnimation(oldEl);
              removeEl$1(oldEl);
            });
            hasMorphAnimation = true;
            applyMorphAnimation(getPathList(oldElsList), getPathList(newEl), newItem.divide, newSeries, newIndex, updateMorphingPathProps);
          } else {
            fadeInElement(newEl, newSeries, newItem.dataIndex);
          }
        } // else keep oldEl leaving animation.

      }).updateOneToMany(function (newIndices, oldIndex) {
        var oldItem = oldDiffItems[oldIndex];
        var oldEl = oldItem.data.getItemGraphicEl(oldItem.dataIndex); // We can't use the elements that already being morphed

        if (oldEl && isElementStillInChart[oldEl.id]) {
          return;
        }

        var newElsList = filter(map(newIndices, function (idx) {
          return newDiffItems[idx].data.getItemGraphicEl(newDiffItems[idx].dataIndex);
        }), function (el) {
          return el && el !== oldEl;
        });
        var newSeris = newDiffItems[newIndices[0]].data.hostModel;

        if (newElsList.length) {
          each(newElsList, function (newEl) {
            return stopAnimation(newEl);
          });

          if (oldEl) {
            stopAnimation(oldEl); // If old element is doing leaving animation. stop it and remove it immediately.

            removeEl$1(oldEl);
            hasMorphAnimation = true;
            applyMorphAnimation(getPathList(oldEl), getPathList(newElsList), oldItem.divide, // Use divide on old.
            newSeris, newIndices[0], updateMorphingPathProps);
          } else {
            each(newElsList, function (newEl) {
              return fadeInElement(newEl, newSeris, newIndices[0]);
            });
          }
        } // else keep oldEl leaving animation.

      }).updateManyToMany(function (newIndices, oldIndices) {
        // If two data are same and both have groupId.
        // Normally they should be diff by id.
        new DataDiffer(oldIndices, newIndices, function (rawIdx) {
          return oldDiffItems[rawIdx].data.getId(oldDiffItems[rawIdx].dataIndex);
        }, function (rawIdx) {
          return newDiffItems[rawIdx].data.getId(newDiffItems[rawIdx].dataIndex);
        }).update(function (newIndex, oldIndex) {
          // Use the original index
          updateOneToOne(newIndices[newIndex], oldIndices[oldIndex]);
        }).execute();
      }).execute();

      if (hasMorphAnimation) {
        each(newList, function (_a) {
          var data = _a.data;
          var seriesModel = data.hostModel;
          var view = seriesModel && api.getViewOfSeriesModel(seriesModel);
          var animationCfg = getAnimationConfig('update', seriesModel, 0); // use 0 index.

          if (view && seriesModel.isAnimationEnabled() && animationCfg && animationCfg.duration > 0) {
            view.group.traverse(function (el) {
              if (el instanceof Path && !el.animators.length) {
                // We can't accept there still exists element that has no animation
                // if universalTransition is enabled
                el.animateFrom({
                  style: {
                    opacity: 0
                  }
                }, animationCfg);
              }
            });
          }
        });
      }
    }

    function getSeriesTransitionKey(series) {
      var seriesKey = series.getModel('universalTransition').get('seriesKey');

      if (!seriesKey) {
        // Use series id by default.
        return series.id;
      }

      return seriesKey;
    }

    function convertArraySeriesKeyToString(seriesKey) {
      if (isArray(seriesKey)) {
        // Order independent.
        return seriesKey.sort().join(',');
      }

      return seriesKey;
    }

    function getDivideShapeFromData(data) {
      if (data.hostModel) {
        return data.hostModel.getModel('universalTransition').get('divideShape');
      }
    }

    function findTransitionSeriesBatches(globalStore, params) {
      var updateBatches = createHashMap();
      var oldDataMap = createHashMap(); // Map that only store key in array seriesKey.
      // Which is used to query the old data when transition from one to multiple series.

      var oldDataMapForSplit = createHashMap();
      each(globalStore.oldSeries, function (series, idx) {
        var oldDataGroupId = globalStore.oldDataGroupIds[idx];
        var oldData = globalStore.oldData[idx];
        var transitionKey = getSeriesTransitionKey(series);
        var transitionKeyStr = convertArraySeriesKeyToString(transitionKey);
        oldDataMap.set(transitionKeyStr, {
          dataGroupId: oldDataGroupId,
          data: oldData
        });

        if (isArray(transitionKey)) {
          // Same key can't in different array seriesKey.
          each(transitionKey, function (key) {
            oldDataMapForSplit.set(key, {
              key: transitionKeyStr,
              dataGroupId: oldDataGroupId,
              data: oldData
            });
          });
        }
      });

      function checkTransitionSeriesKeyDuplicated(transitionKeyStr) {
        if (updateBatches.get(transitionKeyStr)) {
          warn("Duplicated seriesKey in universalTransition " + transitionKeyStr);
        }
      }

      each(params.updatedSeries, function (series) {
        if (series.isUniversalTransitionEnabled() && series.isAnimationEnabled()) {
          var newDataGroupId = series.get('dataGroupId');
          var newData = series.getData();
          var transitionKey = getSeriesTransitionKey(series);
          var transitionKeyStr = convertArraySeriesKeyToString(transitionKey); // Only transition between series with same id.

          var oldData = oldDataMap.get(transitionKeyStr); // string transition key is the best match.

          if (oldData) {
            if ("development" !== 'production') {
              checkTransitionSeriesKeyDuplicated(transitionKeyStr);
            } // TODO check if data is same?


            updateBatches.set(transitionKeyStr, {
              oldSeries: [{
                dataGroupId: oldData.dataGroupId,
                divide: getDivideShapeFromData(oldData.data),
                data: oldData.data
              }],
              newSeries: [{
                dataGroupId: newDataGroupId,
                divide: getDivideShapeFromData(newData),
                data: newData
              }]
            });
          } else {
            // Transition from multiple series.
            if (isArray(transitionKey)) {
              if ("development" !== 'production') {
                checkTransitionSeriesKeyDuplicated(transitionKeyStr);
              }

              var oldSeries_1 = [];
              each(transitionKey, function (key) {
                var oldData = oldDataMap.get(key);

                if (oldData.data) {
                  oldSeries_1.push({
                    dataGroupId: oldData.dataGroupId,
                    divide: getDivideShapeFromData(oldData.data),
                    data: oldData.data
                  });
                }
              });

              if (oldSeries_1.length) {
                updateBatches.set(transitionKeyStr, {
                  oldSeries: oldSeries_1,
                  newSeries: [{
                    dataGroupId: newDataGroupId,
                    data: newData,
                    divide: getDivideShapeFromData(newData)
                  }]
                });
              }
            } else {
              // Try transition to multiple series.
              var oldData_1 = oldDataMapForSplit.get(transitionKey);

              if (oldData_1) {
                var batch = updateBatches.get(oldData_1.key);

                if (!batch) {
                  batch = {
                    oldSeries: [{
                      dataGroupId: oldData_1.dataGroupId,
                      data: oldData_1.data,
                      divide: getDivideShapeFromData(oldData_1.data)
                    }],
                    newSeries: []
                  };
                  updateBatches.set(oldData_1.key, batch);
                }

                batch.newSeries.push({
                  dataGroupId: newDataGroupId,
                  data: newData,
                  divide: getDivideShapeFromData(newData)
                });
              }
            }
          }
        }
      });
      return updateBatches;
    }

    function querySeries(series, finder) {
      for (var i = 0; i < series.length; i++) {
        var found = finder.seriesIndex != null && finder.seriesIndex === series[i].seriesIndex || finder.seriesId != null && finder.seriesId === series[i].id;

        if (found) {
          return i;
        }
      }
    }

    function transitionSeriesFromOpt(transitionOpt, globalStore, params, api) {
      var from = [];
      var to = [];
      each(normalizeToArray(transitionOpt.from), function (finder) {
        var idx = querySeries(globalStore.oldSeries, finder);

        if (idx >= 0) {
          from.push({
            dataGroupId: globalStore.oldDataGroupIds[idx],
            data: globalStore.oldData[idx],
            // TODO can specify divideShape in transition.
            divide: getDivideShapeFromData(globalStore.oldData[idx]),
            dim: finder.dimension
          });
        }
      });
      each(normalizeToArray(transitionOpt.to), function (finder) {
        var idx = querySeries(params.updatedSeries, finder);

        if (idx >= 0) {
          var data = params.updatedSeries[idx].getData();
          to.push({
            dataGroupId: globalStore.oldDataGroupIds[idx],
            data: data,
            divide: getDivideShapeFromData(data),
            dim: finder.dimension
          });
        }
      });

      if (from.length > 0 && to.length > 0) {
        transitionBetween(from, to, api);
      }
    }

    function installUniversalTransition(registers) {
      registers.registerUpdateLifecycle('series:beforeupdate', function (ecMOdel, api, params) {
        each(normalizeToArray(params.seriesTransition), function (transOpt) {
          each(normalizeToArray(transOpt.to), function (finder) {
            var series = params.updatedSeries;

            for (var i = 0; i < series.length; i++) {
              if (finder.seriesIndex != null && finder.seriesIndex === series[i].seriesIndex || finder.seriesId != null && finder.seriesId === series[i].id) {
                series[i][SERIES_UNIVERSAL_TRANSITION_PROP] = true;
              }
            }
          });
        });
      });
      registers.registerUpdateLifecycle('series:transition', function (ecModel, api, params) {
        // TODO api provide an namespace that can save stuff per instance
        var globalStore = getUniversalTransitionGlobalStore(api); // TODO multiple to multiple series.

        if (globalStore.oldSeries && params.updatedSeries && params.optionChanged) {
          // Use give transition config if its' give;
          var transitionOpt = params.seriesTransition;

          if (transitionOpt) {
            each(normalizeToArray(transitionOpt), function (opt) {
              transitionSeriesFromOpt(opt, globalStore, params, api);
            });
          } else {
            // Else guess from series based on transition series key.
            var updateBatches_1 = findTransitionSeriesBatches(globalStore, params);
            each(updateBatches_1.keys(), function (key) {
              var batch = updateBatches_1.get(key);
              transitionBetween(batch.oldSeries, batch.newSeries, api);
            });
          } // Reset


          each(params.updatedSeries, function (series) {
            // Reset;
            if (series[SERIES_UNIVERSAL_TRANSITION_PROP]) {
              series[SERIES_UNIVERSAL_TRANSITION_PROP] = false;
            }
          });
        } // Save all series of current update. Not only the updated one.


        var allSeries = ecModel.getSeries();
        var savedSeries = globalStore.oldSeries = [];
        var savedDataGroupIds = globalStore.oldDataGroupIds = [];
        var savedData = globalStore.oldData = [];

        for (var i = 0; i < allSeries.length; i++) {
          var data = allSeries[i].getData(); // Only save the data that can have transition.
          // Avoid large data costing too much extra memory

          if (data.count() < DATA_COUNT_THRESHOLD) {
            savedSeries.push(allSeries[i]);
            savedDataGroupIds.push(allSeries[i].get('dataGroupId'));
            savedData.push(data);
          }
        }
      });
    }

    // Render engines
    // -----------------
    // Render via Canvas.
    // echarts.init(dom, null, { renderer: 'canvas' })

    use([install$1]); // Render via SVG.
    // echarts.init(dom, null, { renderer: 'svg' })

    use([install]); // ----------------
    // Charts (series)
    // ----------------
    // All of the series types, for example:
    // chart.setOption({
    //     series: [{
    //         type: 'line' // or 'bar', 'pie', ...
    //     }]
    // });

    use([install$2, install$3, install$4, install$6, install$8, install$a, install$b, install$c, install$d, install$e, install$f, install$h, install$i, install$j, install$k, install$l, install$m, install$n, install$o, install$p, install$q, install$r]); // -------------------
    // Coordinate systems
    // -------------------
    // All of the axis modules have been included in the
    // coordinate system module below, do not need to
    // make extra import.
    // `cartesian` coordinate system. For some historical
    // reasons, it is named as grid, for example:
    // chart.setOption({
    //     grid: {...},
    //     xAxis: {...},
    //     yAxis: {...},
    //     series: [{...}]
    // });

    use(install$t); // `polar` coordinate system, for example:
    // chart.setOption({
    //     polar: {...},
    //     radiusAxis: {...},
    //     angleAxis: {...},
    //     series: [{
    //         coordinateSystem: 'polar'
    //     }]
    // });

    use(install$u); // `geo` coordinate system, for example:
    // chart.setOption({
    //     geo: {...},
    //     series: [{
    //         coordinateSystem: 'geo'
    //     }]
    // });

    use(install$9); // `singleAxis` coordinate system (notice, it is a coordinate system
    // with only one axis, work for chart like theme river), for example:
    // chart.setOption({
    //     singleAxis: {...}
    //     series: [{type: 'themeRiver', ...}]
    // });

    use(install$v); // `parallel` coordinate system, only work for parallel series, for example:
    // chart.setOption({
    //     parallel: {...},
    //     parallelAxis: [{...}, ...],
    //     series: [{
    //         type: 'parallel'
    //     }]
    // });

    use(install$g); // `calendar` coordinate system. for example,
    // chart.setOptionp({
    //     calendar: {...},
    //     series: [{
    //         coordinateSystem: 'calendar'
    //     }]
    // );

    use(install$w); // ------------------
    // Other components
    // ------------------
    // `graphic` component, for example:
    // chart.setOption({
    //     graphic: {...}
    // });

    use(install$x); // `toolbox` component, for example:
    // chart.setOption({
    //     toolbox: {...}
    // });

    use(install$z); // `tooltip` component, for example:
    // chart.setOption({
    //     tooltip: {...}
    // });

    use(install$A); // `axisPointer` component, for example:
    // chart.setOption({
    //     tooltip: {axisPointer: {...}, ...}
    // });
    // Or
    // chart.setOption({
    //     axisPointer: {...}
    // });

    use(install$s); // `brush` component, for example:
    // chart.setOption({
    //     brush: {...}
    // });
    // Or
    // chart.setOption({
    //     tooltip: {feature: {brush: {...}}
    // })

    use(install$B); // `title` component, for example:
    // chart.setOption({
    //     title: {...}
    // });

    use(install$C); // `timeline` component, for example:
    // chart.setOption({
    //     timeline: {...}
    // });

    use(install$D); // `markPoint` component, for example:
    // chart.setOption({
    //     series: [{markPoint: {...}}]
    // });

    use(install$E); // `markLine` component, for example:
    // chart.setOption({
    //     series: [{markLine: {...}}]
    // });

    use(install$F); // `markArea` component, for example:
    // chart.setOption({
    //     series: [{markArea: {...}}]
    // });

    use(install$G); // `legend` component not scrollable. for example:
    // chart.setOption({
    //     legend: {...}
    // });

    use(install$J); // `dataZoom` component including both `dataZoomInside` and `dataZoomSlider`.

    use(install$M); // `dataZoom` component providing drag, pinch, wheel behaviors
    // inside coodinate system, for example:
    // chart.setOption({
    //     dataZoom: {type: 'inside'}
    // });

    use(install$K); // `dataZoom` component providing a slider bar, for example:
    // chart.setOption({
    //     dataZoom: {type: 'slider'}
    // });

    use(install$L); // `visualMap` component including both `visualMapContinuous` and `visualMapPiecewise`.

    use(install$P); // `visualMap` component providing continuous bar, for example:
    // chart.setOption({
    //     visualMap: {type: 'continuous'}
    // });

    use(install$N); // `visualMap` component providing pieces bar, for example:
    // chart.setOption({
    //     visualMap: {type: 'piecewise'}
    // });

    use(install$O); // `aria` component providing aria, for example:
    // chart.setOption({
    //     aria: {...}
    // });

    use(install$Q); // dataset transform
    // chart.setOption({
    //     dataset: {
    //          transform: []
    //     }
    // });

    use(install$R);
    use(install$S); // universal transition
    // chart.setOption({
    //     series: {
    //         universalTransition: { enabled: true }
    //     }
    // })

    use(installUniversalTransition); // label layout
    // chart.setOption({
    //     series: {
    //         labelLayout: { hideOverlap: true }
    //     }
    // })

    use(installLabelLayout);

    exports.Axis = Axis;
    exports.ChartView = ChartView;
    exports.ComponentModel = ComponentModel;
    exports.ComponentView = ComponentView;
    exports.List = SeriesData;
    exports.Model = Model;
    exports.PRIORITY = PRIORITY;
    exports.SeriesModel = SeriesModel;
    exports.color = color;
    exports.connect = connect;
    exports.dataTool = dataTool;
    exports.dependencies = dependencies;
    exports.disConnect = disConnect;
    exports.disconnect = disconnect;
    exports.dispose = dispose$1;
    exports.env = env;
    exports.extendChartView = extendChartView;
    exports.extendComponentModel = extendComponentModel;
    exports.extendComponentView = extendComponentView;
    exports.extendSeriesModel = extendSeriesModel;
    exports.format = format$1;
    exports.getCoordinateSystemDimensions = getCoordinateSystemDimensions;
    exports.getInstanceByDom = getInstanceByDom;
    exports.getInstanceById = getInstanceById;
    exports.getMap = getMap;
    exports.graphic = graphic$1;
    exports.helper = helper;
    exports.init = init$1;
    exports.innerDrawElementOnCanvas = brushSingle;
    exports.matrix = matrix;
    exports.number = number;
    exports.parseGeoJSON = parseGeoJSON;
    exports.parseGeoJson = parseGeoJSON;
    exports.registerAction = registerAction;
    exports.registerCoordinateSystem = registerCoordinateSystem;
    exports.registerLayout = registerLayout;
    exports.registerLoading = registerLoading;
    exports.registerLocale = registerLocale;
    exports.registerMap = registerMap;
    exports.registerPostInit = registerPostInit;
    exports.registerPostUpdate = registerPostUpdate;
    exports.registerPreprocessor = registerPreprocessor;
    exports.registerProcessor = registerProcessor;
    exports.registerTheme = registerTheme;
    exports.registerTransform = registerTransform;
    exports.registerUpdateLifecycle = registerUpdateLifecycle;
    exports.registerVisual = registerVisual;
    exports.setCanvasCreator = setCanvasCreator;
    exports.setPlatformAPI = setPlatformAPI;
    exports.throttle = throttle;
    exports.time = time;
    exports.use = use;
    exports.util = util$1;
    exports.vector = vector;
    exports.version = version$1;
    exports.zrUtil = util;
    exports.zrender = zrender;

    Object.defineProperty(exports, '__esModule', { value: true });

})));
//# sourceMappingURL=echarts.js.map
