
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT 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.3';

    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 isAlphabeticLetter(ch) {
        var code = ch.charCodeAt(0);
        return code >= 0x20 && code <= 0x24F
            || code >= 0x370 && code <= 0x10FF
            || code >= 0x1200 && code <= 0x13FF
            || code >= 0x1E00 && code <= 0x206F;
    }
    var breakCharMap = reduce(',&?/;] '.split(''), function (obj, ch) {
        obj[ch] = true;
        return obj;
    }, {});
    function isWordBreakChar(ch) {
        if (isAlphabeticLetter(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) {
        return keys(obj);
      }
    } // 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 until 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 choose the one that `diff >= 0` in this case.
            // 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 triangle 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" usually happens repeatedly when mouse is moving and
        // a tooltip is displayed. 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 is not specified, do not show a header line with only '-'.
        // This case always happens 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 repeat 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);
          }

      }
    }

    // Includes: 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.2';
    var dependencies = {
      zrender: '5.4.3'
    };
    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, text = el.text;
            return createElementOpen(tag, attrs)
                + (tag !== 'style' ? encodeHTML(text) : 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 = !ecModel.ssr && seriesModel.isAnimationEnabled();
        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 seriesDelay = seriesModel.get('animationDelay') || 0;
        var seriesDelayValue = isFunction(seriesDelay) ? seriesDelay(null) : seriesDelay;
        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(seriesDelay) ? seriesDelay(idx) : seriesDuration * ratio + seriesDelayValue;
            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 clampData_1 = coordSys.clampData(value);
          var pt_1 = coordSys.dataToPoint(clampData_1);

          if (startingAtTick) {
            each(coordSys.getAxes(), function (axis, idx) {
              // If axis type is category, use tick coords instead
              if (axis.type === 'category' && dims != null) {
                var tickCoords = axis.getTicksCoords();
                var targetTickId = clampData_1[idx]; // The index of rightmost tick of markArea is 1 larger than x1/y1 index

                var isEnd = dims[idx] === 'x1' || dims[idx] === 'y1';

                if (isEnd) {
                  targetTickId += 1;
                } // The only contains one tick, tickCoords is
                // like [{coord: 0, tickValue: 0}, {coord: 0}]
                // to the length should always be larger than 1


                if (tickCoords.length < 2) {
                  return;
                } else if (tickCoords.length === 2) {
                  // The left value and right value of the axis are
                  // the same. coord is 0 in both items. Use the max
                  // value of the axis as the coord
                  pt_1[idx] = axis.toGlobalCoord(axis.getExtent()[isEnd ? 1 : 0]);
                  return;
                }

                var leftCoord = void 0;
                var coord = void 0;
                var stepTickValue = 1;

                for (var i = 0; i < tickCoords.length; i++) {
                  var tickCoord = tickCoords[i].coord; // The last item of tickCoords doesn't contain
                  // tickValue

                  var tickValue = i === tickCoords.length - 1 ? tickCoords[i - 1].tickValue + stepTickValue : tickCoords[i].tickValue;

                  if (tickValue === targetTickId) {
                    coord = tickCoord;
                    break;
                  } else if (tickValue < targetTickId) {
                    leftCoord = tickCoord;
                  } else if (leftCoord != null && tickValue > targetTickId) {
                    coord = (tickCoord + leftCoord) / 2;
                    break;
                  }

                  if (i === 1) {
                    // Here we assume the step of category axes is
                    // the same
                    stepTickValue = tickValue - tickCoords[0].tickValue;
                  }
                }

                if (coord == null) {
                  if (!leftCoord) {
                    // targetTickId is smaller than all tick ids in the
                    // visible area, use the leftmost tick coord
                    coord = tickCoords[0].coord;
                  } else if (leftCoord) {
                    // targetTickId is larger than all tick ids in the
                    // visible area, use the rightmost tick coord
                    coord = tickCoords[tickCoords.length - 1].coord;
                  }
                }

                pt_1[idx] = axis.toGlobalCoord(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);
    }

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

    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);
          } else {
            bgEl.setShape('cornerRadius', 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);
              } else {
                bgEl.setShape('cornerRadius', 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 ? layout.r0 : 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) {
        var borderRadius = itemModel.get(['itemStyle', 'borderRadius']) || 0;
        el.setShape('r', borderRadius);
      } else if (!seriesModel.get('roundCap')) {
        var sectorShape = el.shape;
        var cornerRadius = getSectorCornerRadius(itemModel.getModel('itemStyle'), sectorShape, true);
        extend(sectorShape, cornerRadius);
        el.setShape(sectorShape);
      }

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

    /**
     * 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 separate 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 replace ','. 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 convenient way to show axisPointer
        // for user. So we enable setting 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; // Compatible with previous behavior, tooltip axis does not show label by default.
      // Only these properties can be overridden 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 support 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 support `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 whether to 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: DON'T 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; // PENDING

        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 forbidden.

          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 should 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;
          initProps(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 = normalizeRadian(-midAngle);

            if (rotate > Math.PI / 2 && rotate < Math.PI * 1.5) {
              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 repeatedly 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) {// Should 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) {
              // For mobile device, 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
        }),
        // Label 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
      // convenient to fetch payload.seriesIndex and payload.dataIndex
      // directly. 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 should 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 exist.

            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 multiple icons, they are organized 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 should 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 return 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._alwaysShowContent = false;
        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 alwaysShowContent

        this._alwaysShowContent = alwaysShowContent; // 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) && !this._alwaysShowContent) {
          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._alwaysShowContent = false;
        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(); // update alwaysShowContent

        this._alwaysShowContent = alwaysShowContent;
      };

      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) && !this._alwaysShowContent) {
          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;
        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._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 cannot share the same formatter. Since the global tooltip formatter is used for series
        // by convention, 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 default 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 && 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) && isArray(dims)) {
        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 || !isArray(dims)) {
        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
        } // Don't 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 corresponding 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 dimension. If null/undefined is returned, no dimension is 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 default 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 don't 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) {
            // For mobile device, 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 forbidden
        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 calculate 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) {
          // For mobile device, 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 recommended.
            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',
      // PENDING: 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 indicates it explicitly.
        // For example, if no condition is specified by mistake, returning an empty result
        // is better than returning the entire raw source for the 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
